From 492827eb82a0f7a3cacd88c82135c54a0a08825f Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Thu, 19 Jul 2012 10:01:41 +0000 Subject: DbEditorPP: changed folder structure git-svn-id: http://svn.miranda-ng.org/main/trunk@1037 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/DbEditorPP/src/Version.h | 20 + plugins/DbEditorPP/src/addeditsettingsdlg.cpp | 458 +++++++++ plugins/DbEditorPP/src/copymodule.cpp | 197 ++++ plugins/DbEditorPP/src/deletemodule.cpp | 148 +++ plugins/DbEditorPP/src/exportimport.cpp | 745 +++++++++++++++ plugins/DbEditorPP/src/findwindow.cpp | 725 ++++++++++++++ plugins/DbEditorPP/src/headers.h | 260 +++++ plugins/DbEditorPP/src/icons.cpp | 143 +++ plugins/DbEditorPP/src/knownmodules.cpp | 84 ++ plugins/DbEditorPP/src/main.cpp | 669 +++++++++++++ plugins/DbEditorPP/src/main_window.cpp | 673 +++++++++++++ plugins/DbEditorPP/src/modsettingenum.cpp | 88 ++ plugins/DbEditorPP/src/modsettingenum.h | 17 + plugins/DbEditorPP/src/modules.cpp | 109 +++ plugins/DbEditorPP/src/moduletree.cpp | 1132 ++++++++++++++++++++++ plugins/DbEditorPP/src/options.cpp | 94 ++ plugins/DbEditorPP/src/resource.h | 157 +++ plugins/DbEditorPP/src/settinglist.cpp | 1261 +++++++++++++++++++++++++ plugins/DbEditorPP/src/threads.cpp | 48 + plugins/DbEditorPP/src/watchedvars.cpp | 358 +++++++ 20 files changed, 7386 insertions(+) create mode 100644 plugins/DbEditorPP/src/Version.h create mode 100644 plugins/DbEditorPP/src/addeditsettingsdlg.cpp create mode 100644 plugins/DbEditorPP/src/copymodule.cpp create mode 100644 plugins/DbEditorPP/src/deletemodule.cpp create mode 100644 plugins/DbEditorPP/src/exportimport.cpp create mode 100644 plugins/DbEditorPP/src/findwindow.cpp create mode 100644 plugins/DbEditorPP/src/headers.h create mode 100644 plugins/DbEditorPP/src/icons.cpp create mode 100644 plugins/DbEditorPP/src/knownmodules.cpp create mode 100644 plugins/DbEditorPP/src/main.cpp create mode 100644 plugins/DbEditorPP/src/main_window.cpp create mode 100644 plugins/DbEditorPP/src/modsettingenum.cpp create mode 100644 plugins/DbEditorPP/src/modsettingenum.h create mode 100644 plugins/DbEditorPP/src/modules.cpp create mode 100644 plugins/DbEditorPP/src/moduletree.cpp create mode 100644 plugins/DbEditorPP/src/options.cpp create mode 100644 plugins/DbEditorPP/src/resource.h create mode 100644 plugins/DbEditorPP/src/settinglist.cpp create mode 100644 plugins/DbEditorPP/src/threads.cpp create mode 100644 plugins/DbEditorPP/src/watchedvars.cpp (limited to 'plugins/DbEditorPP/src') diff --git a/plugins/DbEditorPP/src/Version.h b/plugins/DbEditorPP/src/Version.h new file mode 100644 index 0000000000..565dddb582 --- /dev/null +++ b/plugins/DbEditorPP/src/Version.h @@ -0,0 +1,20 @@ +#define __MAJOR_VERSION 3 +#define __MINOR_VERSION 2 +#define __RELEASE_NUM 0 +#define __BUILD_NUM 0 + +#define __FILEVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM +#define __FILEVERSION_DOTS __MAJOR_VERSION.__MINOR_VERSION.__RELEASE_NUM.__BUILD_NUM + +#define __STRINGIFY_IMPL(x) #x +#define __STRINGIFY(x) __STRINGIFY_IMPL(x) +#define __VERSION_STRING __STRINGIFY(__FILEVERSION_DOTS) + +#define __PLUGIN_NAME "Database Editor++" +#define __INTERNAL_NAME "DBEditor" +#define __FILENAME "Svc_dbepp.dll" +#define __DESCRIPTION "Advanced Database Editor." +#define __AUTHOR "Bio, Jonathan Gordon" +#define __AUTHOREMAIL "bio@msx.ru, jdgordy@gmail.com" +#define __AUTHORWEB "http://addons.miranda-im.org/details.php?action=viewfile&id=2957" +#define __COPYRIGHT "© 2003-2011 Bio, Jonathan Gordon" diff --git a/plugins/DbEditorPP/src/addeditsettingsdlg.cpp b/plugins/DbEditorPP/src/addeditsettingsdlg.cpp new file mode 100644 index 0000000000..6c21fe498c --- /dev/null +++ b/plugins/DbEditorPP/src/addeditsettingsdlg.cpp @@ -0,0 +1,458 @@ +#include "headers.h" + + +static BOOL Convert(HANDLE hContact, char* module, char* setting, int value, int toType) // 0 = byte, 1 = word, 2 = dword, 3 = string +{ + int Result = 1; + char temp[64]; + + switch (toType) + { + case 0: + if (value > 0xFF) + Result = 0; + else + DBWriteContactSettingByte(hContact, module, setting, (BYTE)value); + break; + case 1: + if (value > 0xFFFF) + Result = 0; + else + DBWriteContactSettingWord(hContact, module, setting, (WORD)value); + break; + case 2: + DBWriteContactSettingDword(hContact, module, setting, (DWORD)value); + break; + case 3: + DBDeleteContactSetting(hContact, module, setting); + DBWriteContactSettingString(hContact, module, setting, itoa(value,temp,10)); + break; + } + return Result; +} + + +BOOL convertSetting(HANDLE hContact, char* module, char* setting, int toType) // 0 = byte, 1 = word, 2 = dword, 3 = string, 4 = unicode +{ + DBVARIANT dbv = {0}; + BOOL Result = 0; + + if (!GetSetting(hContact, module, setting, &dbv)) + { + switch (dbv.type) + { + case DBVT_BYTE: + Result = Convert(hContact, module, setting, dbv.bVal, toType); + break; + + case DBVT_WORD: + Result = Convert(hContact, module, setting, dbv.wVal, toType); + break; + + case DBVT_DWORD: + Result = Convert(hContact, module, setting, dbv.dVal, toType); + break; + + case DBVT_ASCIIZ: + if (toType == 4) // convert to UNICODE + { + int len = (int)strlen(dbv.pszVal) + 1; + WCHAR *wc = (WCHAR*)_alloca(len*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, dbv.pszVal, -1, wc, len); + Result = !DBWriteContactSettingWString(hContact, module, setting, wc); + } + else + if (strlen(dbv.pszVal) < 11 && toType != 3) + { + int val = atoi(dbv.pszVal); + if (val == 0 && dbv.pszVal[0] != '0') + break; + + Result = Convert(hContact, module, setting, val, toType); + } + break; + case DBVT_UTF8: + if (toType == 3 && UOS) // convert to ANSI + { + int len = (int)strlen(dbv.pszVal) + 1; + char *sz = (char*)_alloca(len*3); + WCHAR *wc = (WCHAR*)_alloca(len*sizeof(WCHAR)); + MultiByteToWideChar(CP_UTF8, 0, dbv.pszVal, -1, wc, len); + WideCharToMultiByte(CP_ACP, 0, wc, -1, sz, len, NULL, NULL); + Result = !DBWriteContactSettingString(hContact, module, setting, sz); + } + break; + } + + if (!Result) + msg(Translate("Cannot Convert!"), modFullname); + + DBFreeVariant(&dbv); + } + + return Result; +} + + +int saveAsType(HWND hwnd) +{ + if(IsDlgButtonChecked(hwnd, CHK_BYTE)) + return 0; + else if(IsDlgButtonChecked(hwnd, CHK_WORD)) + return 1; + else if(IsDlgButtonChecked(hwnd, CHK_DWORD)) + return 2; + else if(IsDlgButtonChecked(hwnd, CHK_STRING)) + return 3; + return 3; +} + + +INT_PTR CALLBACK EditSettingDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + char tmp[32]; + SetWindowLongPtr(hwnd,GWLP_USERDATA,(LPARAM)lParam); + switch (((struct DBsetting*)lParam)->dbv.type) + { + case DBVT_BYTE: + ShowWindow(GetDlgItem(hwnd, IDC_STRING),SW_HIDE); + if (!((struct DBsetting*)lParam)->setting[0]) + { + SetWindowText(hwnd, Translate("New BYTE value")); + } + else + { + SetWindowText(hwnd, Translate("Edit BYTE value")); + SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting); + SetDlgItemText(hwnd, IDC_SETTINGVALUE, itoa(((struct DBsetting*)lParam)->dbv.bVal, tmp, 10)); + } + CheckRadioButton(hwnd, CHK_HEX, CHK_DECIMAL, CHK_DECIMAL); + CheckRadioButton(hwnd, CHK_BYTE, CHK_STRING, CHK_BYTE); + break; + case DBVT_WORD: + ShowWindow(GetDlgItem(hwnd, IDC_STRING),SW_HIDE); + if (!((struct DBsetting*)lParam)->setting[0]) + { + SetWindowText(hwnd, Translate("New WORD value")); + } + else + { + SetWindowText(hwnd, Translate("Edit WORD value")); + SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting); + SetDlgItemText(hwnd, IDC_SETTINGVALUE, itoa(((struct DBsetting*)lParam)->dbv.wVal, tmp, 10)); + } + CheckRadioButton(hwnd, CHK_HEX, CHK_DECIMAL, CHK_DECIMAL); + CheckRadioButton(hwnd, CHK_BYTE, CHK_STRING, CHK_WORD); + break; + case DBVT_DWORD: + ShowWindow(GetDlgItem(hwnd, IDC_STRING),SW_HIDE); + if (!((struct DBsetting*)lParam)->setting[0]) + { + SetWindowText(hwnd, Translate("New DWORD value")); + } + else + { + char text[32]; + SetWindowText(hwnd, Translate("Edit DWORD value")); + SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting); + mir_snprintf(text, SIZEOF(text), "%X", ((struct DBsetting*)lParam)->dbv.dVal); + SetDlgItemText(hwnd, IDC_SETTINGVALUE, text); + } + CheckRadioButton(hwnd, CHK_HEX, CHK_DECIMAL, CHK_HEX); + CheckRadioButton(hwnd, CHK_BYTE, CHK_STRING, CHK_DWORD); + break; + case DBVT_ASCIIZ: + ShowWindow(GetDlgItem(hwnd, IDC_STRING),SW_SHOW); + ShowWindow(GetDlgItem(hwnd, IDC_SETTINGVALUE),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_HEX),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_DECIMAL),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, GRP_BASE),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, GRP_TYPE),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_BYTE),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_WORD),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_DWORD),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_STRING),SW_HIDE); + if (!((struct DBsetting*)lParam)->setting[0]) + { + SetWindowText(hwnd, Translate("New STRING value")); + } + else + { + SetWindowText(hwnd, Translate("Edit STRING value")); + SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting); + SetDlgItemText(hwnd, IDC_STRING, ((struct DBsetting*)lParam)->dbv.pszVal); + } + break; + case DBVT_UTF8: + ShowWindow(GetDlgItem(hwnd, IDC_STRING),SW_SHOW); + ShowWindow(GetDlgItem(hwnd, IDC_SETTINGVALUE),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_HEX),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_DECIMAL),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, GRP_BASE),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, GRP_TYPE),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_BYTE),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_WORD),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_DWORD),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_STRING),SW_HIDE); + if (!((struct DBsetting*)lParam)->setting[0]) + { + SetWindowText(hwnd, Translate("New UNICODE value")); + } + else + { + char *tmp = (((struct DBsetting*)lParam)->dbv.pszVal); + if (UOS) + { + int length = (int)strlen(tmp) + 1; + WCHAR *wc = (WCHAR*)_alloca(length*sizeof(WCHAR)); + MultiByteToWideChar(CP_UTF8, 0, tmp, -1, wc, length); + SendMessageW(GetDlgItem(hwnd, IDC_STRING), WM_SETTEXT, 0, (LPARAM)wc); + } + else { + // convert from UTF8 + SetDlgItemText(hwnd, IDC_STRING, tmp); + } + SetWindowText(hwnd, Translate("Edit UNICODE value")); + SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting); + } + break; + case DBVT_BLOB: + { + ShowWindow(GetDlgItem(hwnd, IDC_STRING),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, IDC_SETTINGVALUE),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, IDC_BLOB),SW_SHOW); + + if (!((struct DBsetting*)lParam)->setting[0]) + { + SetWindowText(hwnd, Translate("New BLOB value")); + } + else + { + int j; + char tmp[16]; + int len = ((struct DBsetting*)lParam)->dbv.cpbVal; + char *data = (char*)_alloca(3*(len+1)+10); + BYTE *p = ((struct DBsetting*)lParam)->dbv.pbVal; + + if (!data) return TRUE; + data[0] = '\0'; + + for(j=0; jsetting); + SetDlgItemText(hwnd, IDC_BLOB, data); + } + ShowWindow(GetDlgItem(hwnd, CHK_HEX),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_DECIMAL),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, GRP_BASE),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, GRP_TYPE),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_BYTE),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_WORD),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_DWORD),SW_HIDE); + ShowWindow(GetDlgItem(hwnd, CHK_STRING),SW_HIDE); + } + break; + default: return TRUE; + } + TranslateDialogDefault(hwnd); + } + return TRUE; + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case CHK_BYTE: + case CHK_WORD: + case CHK_DWORD: + EnableWindow(GetDlgItem(hwnd, CHK_HEX),1); + EnableWindow(GetDlgItem(hwnd, CHK_DECIMAL),1); + CheckRadioButton(hwnd, CHK_BYTE, CHK_STRING, LOWORD(wParam)); + break; + case CHK_STRING: + EnableWindow(GetDlgItem(hwnd, CHK_HEX),0); + EnableWindow(GetDlgItem(hwnd, CHK_DECIMAL),0); + CheckRadioButton(hwnd, CHK_BYTE, CHK_STRING, LOWORD(wParam)); + break; + + case CHK_HEX: + case CHK_DECIMAL: + CheckRadioButton(hwnd,CHK_HEX, CHK_DECIMAL, LOWORD(wParam)); + { + char *setting, temp[32]; + int settingLength, tmp; + settingLength = GetWindowTextLength(GetDlgItem(hwnd, IDC_SETTINGVALUE)); + if (settingLength) + { + setting = (char*)_alloca(settingLength + 1); + if (setting) + { + // havta convert it with sprintf() + GetWindowText(GetDlgItem(hwnd, IDC_SETTINGVALUE), setting, settingLength+1); + if (LOWORD(wParam) == CHK_DECIMAL && IsDlgButtonChecked(hwnd, CHK_DECIMAL)) + { + sscanf(setting, "%X", &tmp); + mir_snprintf(temp, SIZEOF(temp), "%ld", tmp); + } + else + { + sscanf(setting, "%d", &tmp); + mir_snprintf(temp, SIZEOF(temp), "%X", tmp); + } + SetWindowText(GetDlgItem(hwnd, IDC_SETTINGVALUE), temp); + } + } + } + break; + case IDOK: + { + struct DBsetting *dbsetting = (struct DBsetting*)GetWindowLongPtr(hwnd,GWLP_USERDATA); + char *setting, *value; + int settingLength, valueLength, valueID = IDC_SETTINGVALUE; + settingLength = GetWindowTextLength(GetDlgItem(hwnd, IDC_SETTINGNAME)); + + if (IsWindowVisible(GetDlgItem(hwnd,IDC_STRING))) + valueID = IDC_STRING; + else + if (IsWindowVisible(GetDlgItem(hwnd,IDC_SETTINGVALUE))) + valueID = IDC_SETTINGVALUE; + else + if (IsWindowVisible(GetDlgItem(hwnd,IDC_BLOB))) + valueID = IDC_BLOB; + else + break; + + valueLength = GetWindowTextLength(GetDlgItem(hwnd, valueID)); + + if (dbsetting->dbv.type == DBVT_UTF8 && UOS) + valueLength *= sizeof(WCHAR); + + if (settingLength) + { + int settingValue; + setting = (char*)_alloca(settingLength + 1); + + if (valueLength) + value = (char*)_alloca(valueLength + 2); + else + value = (char*)_alloca(2); + + if (!setting || !value) + { + msg(Translate("Couldnt allocate enough memory!"), modFullname); + DestroyWindow(hwnd); + break; + } + + GetWindowText(GetDlgItem(hwnd, IDC_SETTINGNAME), setting, settingLength+1); + + if (valueLength) + { + if (dbsetting->dbv.type == DBVT_UTF8 && UOS) + SendMessageW(GetDlgItem(hwnd, valueID), WM_GETTEXT, valueLength+2, (LPARAM)value); + else + GetWindowText(GetDlgItem(hwnd, valueID), value, valueLength+1); + } + else + if (IsWindowVisible(GetDlgItem(hwnd,IDC_STRING)) || (saveAsType(hwnd)==3)) + memcpy(value,"\0\0",2); + else + strcpy(value,"0"); + + // delete the old setting + if (mir_strcmp(setting, dbsetting->setting) && dbsetting->setting && (dbsetting->setting)[0] != 0) + DBDeleteContactSetting(dbsetting->hContact, dbsetting->module, dbsetting->setting); + + // delete the setting if we are saving as a different type + switch (dbsetting->dbv.type) + { + case DBVT_BYTE: + if (saveAsType(hwnd) != 0) DBDeleteContactSetting(dbsetting->hContact, dbsetting->module, setting); + break; + case DBVT_WORD: + if (saveAsType(hwnd) != 1) DBDeleteContactSetting(dbsetting->hContact, dbsetting->module, setting); + break; + case DBVT_DWORD: + if (saveAsType(hwnd) != 2) DBDeleteContactSetting(dbsetting->hContact, dbsetting->module, setting); + break; + //case DBVT_ASCIIZ: + //DBWriteContactSettingString(dbsetting->hContact, dbsetting->module, setting, value); + //break; + } + // write the setting + switch (saveAsType(hwnd)) + { + case 0: + if (IsDlgButtonChecked(hwnd, CHK_HEX)) sscanf(value, "%x", &settingValue); + else sscanf(value, "%d", &settingValue); + DBWriteContactSettingByte(dbsetting->hContact, dbsetting->module, setting, (BYTE)settingValue); + break; + case 1: + if (IsDlgButtonChecked(hwnd, CHK_HEX)) sscanf(value, "%x", &settingValue); + else sscanf(value, "%d", &settingValue); + DBWriteContactSettingWord(dbsetting->hContact, dbsetting->module, setting, (WORD)settingValue); + break; + case 2: + if (IsDlgButtonChecked(hwnd, CHK_HEX)) sscanf(value, "%x", &settingValue); + else sscanf(value, "%d", &settingValue); + DBWriteContactSettingDword(dbsetting->hContact, dbsetting->module, setting, (DWORD)settingValue); + break; + case 3: + if (dbsetting->dbv.type == DBVT_UTF8) + { + if (UOS) + DBWriteContactSettingWString(dbsetting->hContact, dbsetting->module, setting, (WCHAR*)value); + else + DBWriteContactSettingStringUtf(dbsetting->hContact, dbsetting->module, setting, value); + } + else + if (dbsetting->dbv.type == DBVT_BLOB) + WriteBlobFromString(dbsetting->hContact,dbsetting->module,setting,value,valueLength); + else + if (dbsetting->dbv.type == DBVT_ASCIIZ) + DBWriteContactSettingString(dbsetting->hContact, dbsetting->module, setting, value); + break; + } + + } + } // fall through + case IDCANCEL: + { + struct DBsetting *dbsetting = (struct DBsetting*)GetWindowLongPtr(hwnd,GWLP_USERDATA); + mir_free(dbsetting->module); + mir_free(dbsetting->setting); + mir_free(dbsetting); + DestroyWindow(hwnd); + } + break; + } + break; + } + return 0; +} + +void editSetting(HANDLE hContact, char* module, char* setting) +{ + DBVARIANT dbv = {0}; // freed in the dialog + if (!GetSetting(hContact,module, setting, &dbv)) + { + struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets free()ed in the window proc + + dbsetting->dbv = dbv; // freed in the dialog + dbsetting->hContact = hContact; + dbsetting->module = mir_tstrdup(module); + dbsetting->setting = mir_tstrdup(setting); + + if (dbv.type == DBVT_UTF8 && UOS) + CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_EDIT_SETTING), hwnd2mainWindow, EditSettingDlgProc, (LPARAM)dbsetting); + else + CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_EDIT_SETTING), hwnd2mainWindow, EditSettingDlgProc, (LPARAM)dbsetting); + } +} \ No newline at end of file diff --git a/plugins/DbEditorPP/src/copymodule.cpp b/plugins/DbEditorPP/src/copymodule.cpp new file mode 100644 index 0000000000..25489a7f52 --- /dev/null +++ b/plugins/DbEditorPP/src/copymodule.cpp @@ -0,0 +1,197 @@ +#include "headers.h" + +void copyModule(char* module, HANDLE hContactFrom, HANDLE hContactTo) +{ + ModuleSettingLL msll; + struct ModSetLinkLinkItem *setting; + + EnumSettings(hContactFrom,module, &msll); + + setting = msll.first; + while(setting) + { + DBVARIANT dbv; + if (!GetSetting(hContactFrom, module, setting->name, &dbv)) + { + switch (dbv.type) + { + case DBVT_BYTE: + DBWriteContactSettingByte(hContactTo, module, setting->name, dbv.bVal); + break; + case DBVT_WORD: + DBWriteContactSettingWord(hContactTo, module, setting->name, dbv.wVal); + break; + case DBVT_DWORD: + DBWriteContactSettingDword(hContactTo, module, setting->name, dbv.dVal); + break; + case DBVT_ASCIIZ: + DBWriteContactSettingString(hContactTo, module, setting->name, dbv.pszVal); + break; + case DBVT_UTF8: + DBWriteContactSettingStringUtf(hContactTo, module, setting->name, dbv.pszVal); + break; + case DBVT_BLOB: + DBWriteContactSettingBlob(hContactTo, module, setting->name, dbv.pbVal, dbv.cpbVal); + break; + } + } + DBFreeVariant(&dbv); + setting = (struct ModSetLinkLinkItem *)setting->next; + } + FreeModuleSettingLL(&msll); +} + +INT_PTR CALLBACK copyModDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + ModuleAndContact *mac = (ModuleAndContact *)GetWindowLongPtr(hwnd,GWLP_USERDATA); + if (msg == WM_INITDIALOG) + { + int index, loaded; + char szProto[256]; + HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + + while (hContact) + { + if (GetValue(hContact,"Protocol","p",szProto,SIZEOF(szProto))) + loaded = IsProtocolLoaded(szProto); + else + loaded = 0; + + // filter + if ((loaded && Mode == MODE_UNLOADED) || (!loaded && Mode == MODE_LOADED)) + { + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + continue; + } + + // contacts name + if (UOS) + { + DBVARIANT dbv ={0}; + WCHAR nick[256]; + WCHAR protoW[256]; // unicode proto + + if (szProto[0]) + a2u(szProto, protoW, SIZEOF(protoW)); + else + protoW[0] = 0; + + if (!szProto[0] || !loaded) + { + if (protoW) + { + if (Order) + mir_snwprintf(nick, SIZEOF(nick), L"(%s) %s %s", protoW, GetContactName(hContact, szProto, 1), L"(UNLOADED)"); + else + mir_snwprintf(nick, SIZEOF(nick), L"%s (%s) %s", GetContactName(hContact, szProto, 1), protoW, L"(UNLOADED)"); + } + else + wcscpy(nick, nick_unknownW); + } + else + { + if (Order) + mir_snwprintf(nick, SIZEOF(nick), L"(%s) %s", protoW, GetContactName(hContact, szProto, 1)); + else + mir_snwprintf(nick, SIZEOF(nick), L"%s (%s)", GetContactName(hContact, szProto, 1), protoW); + } + + index = SendMessageW(GetDlgItem(hwnd, IDC_CONTACTS), CB_ADDSTRING, 0, (LPARAM)nick); + SendMessageW(GetDlgItem(hwnd, IDC_CONTACTS), CB_SETITEMDATA, index, (LPARAM)hContact); + } + else + { + char nick[256]; + + if (!szProto[0] || !loaded) + { + if (szProto[0]) + { + if (Order) + mir_snprintf(nick, SIZEOF(nick), "(%s) %s %s", szProto, (char*)GetContactName(hContact, szProto, 0), "(UNLOADED)"); + else + mir_snprintf(nick, SIZEOF(nick), "%s (%s) %s", (char*)GetContactName(hContact, szProto, 0), szProto, "(UNLOADED)"); + } + else + strcpy(nick, nick_unknown); + } + else + { + if (Order) + mir_snprintf(nick, SIZEOF(nick), "(%s) %s", szProto, (char*)GetContactName(hContact, szProto, 0)); + else + mir_snprintf(nick, SIZEOF(nick), "%s (%s)", (char*)GetContactName(hContact, szProto, 0), szProto); + } + + index = SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_ADDSTRING, 0, (LPARAM)nick); + SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_SETITEMDATA, index, (LPARAM)hContact); + } + + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)(HANDLE)hContact, 0); + } + + index = (int)SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_INSERTSTRING, 0, (LPARAM)(char*)Translate("Settings")); + SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_SETITEMDATA, index, (LPARAM)0); + SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_SETCURSEL, index, 0); + + SetWindowLongPtr(hwnd,GWLP_USERDATA,lParam); + TranslateDialogDefault(hwnd); + } + else + if (msg == WM_COMMAND) + { + switch(LOWORD(wParam)) + { + case CHK_COPY2ALL: + EnableWindow(GetDlgItem(hwnd, IDC_CONTACTS),!IsDlgButtonChecked(hwnd,CHK_COPY2ALL)); + break; + case IDOK: + { + HANDLE hContact; + + if (!IsDlgButtonChecked(hwnd,CHK_COPY2ALL)) + { + hContact = (HANDLE)SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_GETITEMDATA, SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_GETCURSEL, 0, 0), 0); + copyModule(mac->module, mac->hContact, hContact); + } + else + { + SetCursor(LoadCursor(NULL,IDC_WAIT)); + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + + while (hContact) + { + copyModule(mac->module, mac->hContact, hContact); + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)(HANDLE)hContact, 0); + } + + SetCursor(LoadCursor(NULL,IDC_ARROW)); + } + mir_free(mac); + refreshTree(1); + DestroyWindow(hwnd); + } + break; + case IDCANCEL: + { + mir_free(mac); + DestroyWindow(hwnd); + } + break; + } + } + return 0; +} + +void copyModuleMenuItem(char* module, HANDLE hContact) +{ + HWND hwnd; + ModuleAndContact *mac = (ModuleAndContact *)mir_calloc(sizeof(ModuleAndContact)); + mac->hContact = hContact; + strncpy(mac->module, module, 255); + + if (UOS) + hwnd = CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_COPY_MOD), 0, copyModDlgProc, (LPARAM)mac); + else + hwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_COPY_MOD), 0, copyModDlgProc, (LPARAM)mac); +} \ No newline at end of file diff --git a/plugins/DbEditorPP/src/deletemodule.cpp b/plugins/DbEditorPP/src/deletemodule.cpp new file mode 100644 index 0000000000..a0eddf73a1 --- /dev/null +++ b/plugins/DbEditorPP/src/deletemodule.cpp @@ -0,0 +1,148 @@ +#include "headers.h" + +static int working; +static HWND hwnd2Delete = NULL; + +int deleteModule(char* module, HANDLE hContact, int fromMenu) +{ + char msg[1024]; + ModuleSettingLL settinglist; + struct ModSetLinkLinkItem *setting; + + if (!module) return 0; + + if (!fromMenu) + { + mir_snprintf(msg, SIZEOF(msg), Translate("Are you sure you want to delete module \"%s\"?"), module); + if (DBGetContactSettingByte(NULL,modname, "WarnOnDelete",1)) + { + if (MessageBox(0,msg, Translate("Confirm Module Deletion"), MB_YESNO|MB_ICONEXCLAMATION) == IDNO) + return 0; + } + } + + if (!EnumSettings(hContact,module,&settinglist)) return 0; + + setting = settinglist.first; + while (setting) + { + DBDeleteContactSetting(hContact, module, setting->name); + setting = (struct ModSetLinkLinkItem *)setting->next; + } + FreeModuleSettingLL(&settinglist); + return 1; +} + +void __cdecl PopulateModuleDropListThreadFunc(LPVOID di) +{ + HWND hwnd = (HWND)di; + ModuleSettingLL msll; + struct ModSetLinkLinkItem *module; + HANDLE hContact; + int moduleEmpty; + if (!EnumModules(&msll)) DestroyWindow(hwnd); + module = msll.first; + while (module && working) + { + moduleEmpty = 1; + // check the null + if (!IsModuleEmpty(NULL,module->name)) + { + SendDlgItemMessage(hwnd,IDC_CONTACTS,CB_ADDSTRING,0,(LPARAM)module->name); + moduleEmpty = 0; + module = (struct ModSetLinkLinkItem *)module->next; + continue; + } + for (hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);moduleEmpty && hContact;hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) + { + if (!IsModuleEmpty(hContact,module->name)) + { + SendDlgItemMessage(hwnd,IDC_CONTACTS,CB_ADDSTRING,0,(LPARAM)module->name); + moduleEmpty = 0; + break; + } + } + + module = (struct ModSetLinkLinkItem *)module->next; + SendDlgItemMessage(hwnd,IDC_CONTACTS,CB_SETCURSEL,0,0); + } + SendDlgItemMessage(hwnd,IDC_CONTACTS,CB_SETCURSEL,0,0); + FreeModuleSettingLL(&msll); + SetWindowText(hwnd,Translate("Delete module from Database")); + EnableWindow(GetDlgItem(hwnd,IDC_CONTACTS),1); + EnableWindow(GetDlgItem(hwnd,IDOK),1); + EnableWindow(GetDlgItem(hwnd,IDCANCEL),1); + + if (!working) + PostMessage(hwnd, WM_COMMAND, (WPARAM)IDCANCEL, 0); + else + working = 2; +} + +INT_PTR CALLBACK DeleteModuleDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + SetWindowText(hwnd,Translate("Delete module from Database... Loading")); + EnableWindow(GetDlgItem(hwnd,IDC_CONTACTS),0); + EnableWindow(GetDlgItem(hwnd,IDOK),0); + SetDlgItemText(hwnd,IDC_INFOTEXT,"Delete module from Database"); + SetDlgItemText(hwnd,CHK_COPY2ALL,"Delete module from all contacts (Includes Setting)"); + EnableWindow(GetDlgItem(hwnd,CHK_COPY2ALL),0); + CheckDlgButton(hwnd,CHK_COPY2ALL,1); + TranslateDialogDefault(hwnd); + working = 1; + forkthread(PopulateModuleDropListThreadFunc,0,hwnd); + } + return TRUE; + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDOK: + { + char text[128]; + HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + GetDlgItemText(hwnd,IDC_CONTACTS,text,128); + SetCursor(LoadCursor(NULL,IDC_WAIT)); + while (hContact) + { + deleteModule(text,hContact,1); + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + } + // do the null + deleteModule(text,NULL,1); + SetCursor(LoadCursor(NULL,IDC_ARROW)); + refreshTree(1); + } + // fall through + case IDCANCEL: + { + if (working == 1) + { + working = 0; + EnableWindow(GetDlgItem(hwnd,IDCANCEL),0); + } + else + DestroyWindow(hwnd); + } + break; + } + break; + case WM_DESTROY: + hwnd2Delete = NULL; + break; + } + return 0; +} + + + +void deleteModuleGui() +{ + if (!hwnd2Delete) + hwnd2Delete = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_COPY_MOD), hwnd2mainWindow, DeleteModuleDlgProc, (LPARAM)0); + else + SetForegroundWindow(hwnd2Delete); +} \ No newline at end of file diff --git a/plugins/DbEditorPP/src/exportimport.cpp b/plugins/DbEditorPP/src/exportimport.cpp new file mode 100644 index 0000000000..ad9f508a21 --- /dev/null +++ b/plugins/DbEditorPP/src/exportimport.cpp @@ -0,0 +1,745 @@ +#include "headers.h" + +int Mode; +HWND hwnd2importWindow; + +int Openfile(char *outputFile, const char *module) +{ + OPENFILENAME ofn = {0}; + char filename[MAX_PATH] = ""; + char filter[MAX_PATH]; + mir_snprintf(filter, SIZEOF(filter), "%s%c*.ini%c%s%c*.*%c", Translate("INI Files"), 0, 0, Translate("All Files"), 0, 0); + char *title = Translate("Export to file"); + + if (module) + { + int n = 0; + mir_strncpy(filename, module, MAX_PATH); + + while(filename[n]) + { + switch(filename[n]) + { + case '*': + case ':': + case '/': + case '?': + case '|': + case '\\': + filename[n] = '_'; + break; + } + n++; + } + } + + ofn.lStructSize = sizeof(ofn); + ofn.lpstrFile = filename; + ofn.lpstrFilter = filter; + ofn.Flags = OFN_HIDEREADONLY | OFN_SHAREAWARE | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT; + ofn.lpstrTitle = title; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrDefExt = "ini"; + + if (!GetSaveFileName(&ofn)) + return 0; + lstrcpy(outputFile,filename); + return 1; +} + +char* StrReplace (char* Search, char* Replace, char* Resource) +{ + int i = 0; + int SearchLen = (int)_tcslen(Search); + char* Work = mir_tstrdup(Replace); + int ReplaceLen = (int)_tcslen(Work); + + char* Pointer = _tcsstr(Resource, Search); + + while (Pointer != NULL) + { + int PointerLen = (int)_tcslen(Pointer); + int ResourceLen = (int)_tcslen(Resource); + + char* NewText = (char*)mir_calloc((ResourceLen - SearchLen + ReplaceLen + 1)*sizeof(char)); + + _tcsncpy(NewText, Resource, ResourceLen - PointerLen); + _tcscat(NewText, Work); + _tcscat(NewText, Pointer + SearchLen); + + Resource = (char*)mir_realloc(Resource, (ResourceLen - SearchLen + ReplaceLen + 1)*sizeof(char)); + + for (i = 0; i < (ResourceLen - SearchLen + ReplaceLen); i++) + Resource[i] = NewText[i]; + Resource[i] = 0; + mir_free(NewText); + + Pointer = _tcsstr(Resource + (ResourceLen - PointerLen + ReplaceLen), Search); + } + mir_free(Work); + + return Resource; +} + +void exportModule(HANDLE hContact, char* module, FILE* file) +{ + char tmp[32]; + ModuleSettingLL settinglist; + struct ModSetLinkLinkItem *setting; + + EnumSettings(hContact,module,&settinglist); + + // print the module header.. + fprintf(file, "\n[%s]", module); + setting = settinglist.first; + while(setting) + { + DBVARIANT dbv; + if (!GetSetting(hContact, module, setting->name, &dbv)) + { + switch (dbv.type) + { + case DBVT_BYTE: + fprintf(file, "\n%s=b%s", setting->name, itoa(dbv.bVal,tmp,10)); + DBFreeVariant(&dbv); + break; + case DBVT_WORD: + fprintf(file, "\n%s=w%s", setting->name, itoa(dbv.wVal,tmp,10)); + DBFreeVariant(&dbv); + break; + case DBVT_DWORD: + fprintf(file, "\n%s=d%s", setting->name, itoa(dbv.dVal,tmp,10)); + DBFreeVariant(&dbv); + break; + case DBVT_ASCIIZ: + case DBVT_UTF8: + if (strchr(dbv.pszVal, '\r')) + { + char *end = StrReplace("\\", "\\\\", dbv.pszVal); + end = StrReplace("\r", "\\r", end); + end = StrReplace("\n", "\\n", end); + fprintf(file, "\n%s=g%s", setting->name, end); + break; + } + if (dbv.type == DBVT_UTF8) + fprintf(file, "\n%s=u%s", setting->name, dbv.pszVal); + else + fprintf(file, "\n%s=s%s", setting->name, dbv.pszVal); + DBFreeVariant(&dbv); + break; + case DBVT_BLOB: + { + int j; + char *data = NULL; + if (!(data = (char*)mir_alloc( 3*(dbv.cpbVal+1)*sizeof(char)))) + break; + data[0] = '\0'; + for (j=0; jname , data); + mir_free(data); + } + DBFreeVariant(&dbv); + break; + } + } + setting = (struct ModSetLinkLinkItem *)setting->next; + } + FreeModuleSettingLL(&settinglist); +} + + +char *NickFromHContact(HANDLE hContact) +{ + static char nick[512] = ""; + + if (hContact) + { + char szProto[256]; + int loaded = 0; + + if (GetValue(hContact,"Protocol","p",szProto,SIZEOF(szProto))) + loaded = IsProtocolLoaded(szProto); + + if (!szProto[0] || !loaded) + { + char name[256]; + + if (szProto[0]) + { + if (GetValue(hContact,szProto,"Nick",name,SIZEOF(name))) + mir_snprintf(nick, SIZEOF(nick),"%s (%s)", name, szProto); + else + mir_snprintf(nick, SIZEOF(nick),"(UNKNOWN) (%s)", szProto); + } + else + mir_snprintf(nick, SIZEOF(nick),"(UNKNOWN)"); + } + else + { + char *uid; + char szUID[256]; + + uid = (char*)CallProtoService(szProto,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0); + if ((int)uid!=CALLSERVICE_NOTFOUND && uid) + { + GetValue(hContact, szProto, uid, szUID, SIZEOF(szUID)); + mir_snprintf(nick, SIZEOF(nick), "%s *(%s)*<%s>*{%s}*", (char*)GetContactName(hContact,szProto,0), szProto, uid, szUID); + } + else + mir_snprintf(nick, SIZEOF(nick), "%s (%s)", (char*)GetContactName(hContact,szProto,0), szProto); + } + } + + return nick; +} + + +void exportDB(HANDLE hContact, char* module) // hContact == -1 export entire db. module == NULL export entire contact. +{ // hContact == -1, module == "" - all contacts + FILE* file = NULL; + char fileName[MAX_PATH]; + int nullcontactDone = 0; + ModuleSettingLL modlist; + struct ModSetLinkLinkItem *mod; + + // enum all the modules + if (!EnumModules(&modlist)) { msg(Translate("Error Loading Module List"),modFullname); return;} + + if (Openfile(fileName, ((int)hContact==-1)?NULL:module)) + { + if (!(file = fopen(fileName, "wt"))) { msg(Translate("Couldn't open file for writing"), modFullname); return; } + + SetCursor(LoadCursor(NULL,IDC_WAIT)); + + // exporting entire db + if (hContact == INVALID_HANDLE_VALUE) + { + hContact = NULL; + + if (module == NULL) + { + fprintf(file, "SETTINGS:\n"); + mod = modlist.first; + while(mod) + { + if (IsModuleEmpty(hContact, mod->name)) + { + mod = (struct ModSetLinkLinkItem *)mod->next; + continue; + } + exportModule(hContact, mod->name, file); + mod = (struct ModSetLinkLinkItem *)mod->next; + if (mod) + fprintf(file, "\n"); + } + } + else + { + if (module == "") module = NULL; // reset module for all contacts export + } + + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + + while (hContact) + { + if (!hContact) continue; + + // filter + if (Mode != MODE_ALL) + { + char szProto[256]; + int loaded = 0; + + if (GetValue(hContact,"Protocol","p",szProto,SIZEOF(szProto))) + loaded = IsProtocolLoaded(szProto); + + if ((loaded && Mode == MODE_UNLOADED) || (!loaded && Mode == MODE_LOADED)) + { + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + continue; + } + } + + fprintf(file, "CONTACT: %s\n", NickFromHContact(hContact)); + + if (module == NULL) // export all modules + { + mod = modlist.first; + while(mod) + { + if (IsModuleEmpty(hContact, mod->name)) + { + mod = (struct ModSetLinkLinkItem *)mod->next; + continue; + } + exportModule(hContact, mod->name, file); + mod = (struct ModSetLinkLinkItem *)mod->next; + if (mod) + fprintf(file, "\n"); + } + } + else // export module + { + exportModule(hContact, module, file); + } + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)(HANDLE)hContact, 0); + } + } + // exporting a contact + else + { + if (!module) // exporting every module + { + if (hContact) + fprintf(file, "CONTACT: %s\n", NickFromHContact(hContact)); + else + fprintf(file, "SETTINGS:\n"); + + mod = modlist.first; + while(mod) + { + if (IsModuleEmpty(hContact, mod->name)) + { + mod = (struct ModSetLinkLinkItem *)mod->next; + continue; + } + exportModule(hContact, mod->name, file); + mod = (struct ModSetLinkLinkItem *)mod->next; + if (mod) + fprintf(file, "\n"); + } + } + else + { + if (hContact) + fprintf(file, "FROM CONTACT: %s\n", NickFromHContact(hContact)); + else + fprintf(file, "SETTINGS:\n"); + + exportModule(hContact, module, file); + } + } + fclose(file); + + SetCursor(LoadCursor(NULL,IDC_ARROW)); + } + + FreeModuleSettingLL(&modlist); +} + + +HANDLE CheckNewContact(char *myProto, char *uid, char *myName) +{ + char szProto[256], szName[256]; + HANDLE resultHandle = INVALID_HANDLE_VALUE; + HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + + while (hContact) + { + //szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + if (DBGetContactSettingStringStatic(hContact, "Protocol", "p", szProto, 256)) + { + if (!mir_strcmp(szProto, myProto)) + { + if (GetValue(hContact, szProto, uid, szName, SIZEOF(szName)) && + !mir_strcmp(szName, myName)) + { + //char msg[1024]; + //_snprintf(msg, 1024, Translate("Do you want to overwrite it \"%s\"?"), szName); + //if (MessageBox(0,msg, Translate("Contact already exists"), MB_YESNO|MB_ICONEXCLAMATION) == IDYES) + resultHandle = hContact; + break; + } + } + } + + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + } + + return resultHandle; + +} + +HANDLE Clist_GroupExists(WCHAR *tszGroup) +{ + unsigned int i = 0; + WCHAR* _t = 0; + char str[10]; + INT_PTR result = 0; + DBVARIANT dbv = {0}; + int match; + + do { + _itoa(i, str, 10); + result = DBGetContactSettingTString(0, "CListGroups", str, &dbv); + if (!result) { + match = (!lstrcmpW(tszGroup, (LPCWSTR)&dbv.ptszVal[1]) && (lstrlenW(tszGroup) == lstrlenW((LPCWSTR)&dbv.ptszVal[1]))); + DBFreeVariant(&dbv); + if(match) + return((HANDLE)(i + 1)); + } + i++; + } + while(result == 0); + return(0); +} + +void importSettings(HANDLE hContact, char *importstring ) +{ + char module[256] = "", setting[256] = "", *end; + int i=0, value, type; + importstring = strtok(importstring, "\n"); + + SetCursor(LoadCursor(NULL,IDC_WAIT)); + + while (importstring != NULL) + { + i=0; + rtrim(importstring); + if (importstring[i] == '\0') + { + importstring = strtok(NULL, "\n"); + continue; + } + else if (!strncmp(&importstring[i],"SETTINGS:",strlen("SETTINGS:"))) + { + importstring = strtok(NULL, "\n"); + continue; + } + else if (!strncmp(&importstring[i],"CONTACT:", strlen("CONTACT:"))) + { + int len, add = 1; + hContact = INVALID_HANDLE_VALUE; + + i = i + (int)strlen("CONTACT:"); + len = (int)strlen(&importstring[i]); + + if (len > 10) + { + char uid[256]="",szUID[256]="",szProto[512]=""; + char *p1,*p2; + + p1 = strrchr(&importstring[i], '>*{'); + p2 = strrchr(&importstring[i], '}*'); + + if (p1 && p2 && p1+3 < p2 && p2-p1 < SIZEOF(szUID)) + { + strncpy(szUID, p1+1, p2-p1-2); + + p1 = strrchr(&importstring[i], ')*<'); + p2 = strrchr(&importstring[i], '>*{'); + + if (p1 && p2 && p1+3 < p2 && p2-p1 < SIZEOF(uid)) + { + strncpy(uid, p1+1, p2-p1-3); + + p1 = strrchr(&importstring[i], ' *('); + p2 = strrchr(&importstring[i], ')*<'); + + if (p1 && p2 && p1+3 < p2 && p2-p1 < SIZEOF(szProto)) + { + char *protouid; + strncpy(szProto, p1+1, p2-p1-3); + + protouid = (char*)CallProtoService(szProto,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0); + if ((int)protouid!=CALLSERVICE_NOTFOUND) + { + if (!mir_strcmp(protouid, uid)) + hContact = CheckNewContact(szProto, uid, szUID); + } + else + hContact = CheckNewContact(szProto, uid, szUID); + } + } + } + } + + if (hContact == INVALID_HANDLE_VALUE) + { + HANDLE temp = (HANDLE)CallService(MS_DB_CONTACT_ADD,0,0); + if (temp) + hContact = temp; + } + } + else if (importstring[i] == '[' && !strchr(&importstring[i+1],'='))// get the module + { + if (end = strpbrk(&importstring[i+1], "]")) { + if ((end+1) != '\0') *end = '\0'; + strcpy(module, &importstring[i+1]); + } + } + else if (importstring[i] == '-' && importstring[i+1] == '[' && + !strchr(&importstring[i+2],'='))// get the module + { + if (end = strpbrk(&importstring[i+2], "]")) { + if ((end+1) != '\0') *end = '\0'; + strcpy(module, &importstring[i+2]); + deleteModule(module, hContact, 1); + } + } + else if (strstr(&importstring[i], "=") && module[0]) // get the setting + { + if (end = strpbrk(&importstring[i+1], "=")) { + if ((end+1) != '\0') *end = '\0'; + strcpy(setting, &importstring[i]); + + // get the type + type = *(end+1); + if (lstrcmp(module, "CList") == 0 && lstrcmp(setting, "Group") == 0) + { + WCHAR* GroupName = mir_a2u(end+2); + if (!GroupName) + continue; + HANDLE GroupHandle = Clist_GroupExists(GroupName); + if(GroupHandle == 0) { + GroupHandle = (HANDLE)CallService(MS_CLIST_GROUPCREATE, 0, (LPARAM)GroupName); + + if(GroupHandle) { + CallService(MS_CLUI_GROUPADDED, (WPARAM)GroupHandle, 0); + CallService(MS_CLIST_GROUPSETEXPANDED, (WPARAM)GroupHandle, 1); + } + } + mir_free(GroupName); + } + switch (type) + { + case 'b': + case 'B': + if (sscanf((end+2), "%d", &value) == 1) + DBWriteContactSettingByte(hContact, module, setting, (BYTE)value); + break; + case 'w': + case 'W': + if (sscanf((end+2), "%d", &value) == 1) + DBWriteContactSettingWord(hContact, module, setting, (WORD)value); + break; + case 'd': + case 'D': + if (sscanf((end+2), "%d", &value) == 1) + DBWriteContactSettingDword(hContact, module, setting, (DWORD)value); + break; + case 's': + case 'S': + DBWriteContactSettingString(hContact,module, setting, (end+2)); + break; + case 'g': + case 'G': + { char *pstr; + for(pstr=end+2;*pstr;pstr++) { + if (*pstr=='\\') { + switch(pstr[1]) { + case 'n': *pstr='\n'; break; + case 't': *pstr='\t'; break; + case 'r': *pstr='\r'; break; + default: *pstr=pstr[1]; break; + } + MoveMemory(pstr+1,pstr+2,lstrlenA(pstr+2)+1); + } } } + case 'u': + case 'U': + DBWriteContactSettingStringUtf(hContact,module, setting, (end+2)); + break; + case 'l': + case 'L': + DBDeleteContactSetting(hContact, module, setting); + break; + case 'n': + case 'N': + WriteBlobFromString(hContact, module, setting, (end+2), (int)strlen((end+2))); + break; + } + } + } + importstring = strtok(NULL, "\n"); + } + SetCursor(LoadCursor(NULL,IDC_ARROW)); +} + +INT_PTR CALLBACK ImportDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + hwnd2importWindow = hwnd; + SetWindowLongPtr(hwnd,GWLP_USERDATA,lParam); + TranslateDialogDefault(hwnd); + SendDlgItemMessage(hwnd, IDC_TEXT, EM_LIMITTEXT, (WPARAM)sizeof(TCHAR)*0x7FFFFFFF, 0); + } + break; + + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case IDC_CRLF: + { + int length = GetWindowTextLength(GetDlgItem(hwnd, IDC_TEXT)); + char *string = (char*)_alloca(length+3); + int Pos = 2; + + if (length) + { + int Range = SendDlgItemMessage(hwnd,IDC_TEXT,EM_GETSEL,0,0); + int Min = LOWORD(Range); + int Max = HIWORD(Range); + + + GetDlgItemText(hwnd, IDC_TEXT, string, length+1); + + if (Min == -1) + memcpy(string, crlf_string, SIZEOF(crlf_string)); + else + if (Max == -1 || Max >= length) + memcpy(&string[Min], crlf_string, SIZEOF(crlf_string)); + else + if (Max-Min > 2) + { + memcpy(&string[Min], crlf_string, SIZEOF(crlf_string)); + memmove(&string[Min+2], &string[Max], length - Max + 1); + } + else + { + memmove(&string[Min+2], &string[Max], length - Max + 1); + memcpy(&string[Min], crlf_string, SIZEOF(crlf_string)); + } + + if (Min) Pos += Min; + } + else + memcpy(string, crlf_string, SIZEOF(crlf_string)); + + SetDlgItemText(hwnd, IDC_TEXT, string); + SendDlgItemMessage(hwnd,IDC_TEXT,EM_SETSEL,Pos,Pos); + SetFocus(GetDlgItem(hwnd, IDC_TEXT)); + } + break; + + case IDOK: + { + HANDLE hContact = (HANDLE)GetWindowLongPtr(hwnd,GWLP_USERDATA); + int length = GetWindowTextLength(GetDlgItem(hwnd, IDC_TEXT)); + char *string; + if (length) + { + string = (char*)_alloca(length+1); + if (!string) {msg(Translate("Couldnt allocate enough memory!"), modFullname); DestroyWindow(hwnd); } + GetDlgItemText(hwnd, IDC_TEXT, string, length+1); + importSettings(hContact, string); + refreshTree(1); + } + } + break; + + case IDCANCEL: + DestroyWindow(hwnd); + hwnd2importWindow = 0; + break; + } + } + break; + } + return 0; +} + +void ImportSettingsMenuItem(HANDLE hContact) +{ + if (hwnd2importWindow) + DestroyWindow(hwnd2importWindow); + + CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_IMPORT), 0, ImportDlgProc, (LPARAM)hContact); +} + +int Openfile2Import(char *outputFiles) +{ + OPENFILENAME ofn = {0}; + char filter[MAX_PATH]; + mir_snprintf(filter, SIZEOF(filter), "%s%c*.ini%c%s%c*.*%c", Translate("INI Files"), 0, 0, Translate("All Files"), 0, 0); + char *title = Translate("Import from files"); + + ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; + ofn.lpstrFilter = filter; + ofn.hwndOwner = 0; + ofn.lpstrFile = outputFiles; + ofn.nMaxFile = MAX_PATH*10; + ofn.nMaxFileTitle = MAX_PATH; + ofn.Flags = OFN_HIDEREADONLY | OFN_SHAREAWARE | OFN_PATHMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_EXPLORER; + ofn.lpstrTitle = title; + if (!GetOpenFileName(&ofn)) + return 0; + + return ofn.nFileOffset; +} + +BOOL Exists(LPCTSTR strName) +{ + return GetFileAttributes(strName) != INVALID_FILE_ATTRIBUTES; +} + +void ImportSettingsFromFileMenuItem(HANDLE hContact, char* FilePath) +{ + char szFileNames[MAX_PATH*10] = {0}; + char szPath[MAX_PATH] = ""; + char szFile[MAX_PATH]; + int index = 0; + HANDLE hFile, hMap; + PBYTE pFile = NULL; + DWORD offset = 0; + if (lstrcmp(FilePath, "") == 0) + offset = Openfile2Import(szFileNames); + else + { + if(Exists(FilePath)) + lstrcpy(szFileNames, FilePath); + else + lstrcpy(szFileNames, ""); + } + + if (!lstrcmp(szFileNames, "") == 0) + { + if ((DWORD)lstrlenA(szFileNames) < offset) + { + index += offset; + strncpy(szPath, szFileNames, offset); + strcat(szPath, "\\"); + } + + while(szFileNames[index]) + { + strcpy(szFile, szPath); + strcat(szFile, &szFileNames[index]); + index += (int)strlen(&szFileNames[index])+1; + + hFile = CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hFile != INVALID_HANDLE_VALUE) + { + if (GetFileSize(hFile, NULL) > 0) + { + hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); + + if (hMap) { + pFile = (PBYTE)MapViewOfFile(hMap, FILE_MAP_COPY, 0, 0 ,0); + + if (pFile) { + importSettings(hContact, (char*)pFile); + UnmapViewOfFile(pFile); + } + CloseHandle(hMap); + } + + } + CloseHandle(hFile); + } + else + break; + + } + if (lstrcmp(FilePath, "") == 0) + refreshTree(1); + } +} diff --git a/plugins/DbEditorPP/src/findwindow.cpp b/plugins/DbEditorPP/src/findwindow.cpp new file mode 100644 index 0000000000..b9957cd246 --- /dev/null +++ b/plugins/DbEditorPP/src/findwindow.cpp @@ -0,0 +1,725 @@ +#include "headers.h" + +void __cdecl FindSettings(LPVOID di); + +static int working; +static int replace; + +#define FW_CASE 1 +#define FW_EXACT 2 +#define FW_MODNAME 4 +#define FW_SETNAME 8 +#define FW_SETVAL 16 + +#define FW_REPLACED 0x100 +#define FW_DELETED 0x200 + +#define RW_MODULE 1 +#define RW_SETNAME 2 +#define RW_SETVAL 4 +#define RW_FOUND 8 + +#define RW_FULL 0x100 +#define RW_CASE 0x200 + +typedef struct { + HWND hwnd; // hwnd 2 item list + char* text; // text to find + int options; // or'd about items + char* replace; // text to replace + int mode; // replace mode +} FindInfo; + + +int FindDialogResize(HWND hwnd,LPARAM lParam,UTILRESIZECONTROL *urc) +{ + switch(urc->wId) { + case IDC_LIST: + return RD_ANCHORX_WIDTH|RD_ANCHORY_HEIGHT; + case IDC_SBAR: + return RD_ANCHORX_WIDTH|RD_ANCHORY_BOTTOM; + default: + return RD_ANCHORX_LEFT|RD_ANCHORY_TOP; + } +} + + +void freeItems(HWND hwnd) +{ + int i; + ItemInfo *ii; + for (i=0;ihwnd = GetDlgItem(hwnd,IDC_LIST); + fi->options = (IsDlgButtonChecked(hwnd,IDC_CASESENSITIVE)?FW_CASE:0)| + (IsDlgButtonChecked(hwnd,IDC_EXACT)?FW_EXACT:0)| + (IsDlgButtonChecked(hwnd,IDC_MODNAME)?FW_MODNAME:0)| + (IsDlgButtonChecked(hwnd,IDC_SETTINGNAME)?FW_SETNAME:0)| + (IsDlgButtonChecked(hwnd,IDC_SETTINGVALUE)?FW_SETVAL:0); + + if (GetWindowLongPtr(GetDlgItem(hwnd,IDC_REPLACE),GWLP_USERDATA)) + { + if (IsDlgButtonChecked(hwnd,IDC_FOUND)) + fi->mode = RW_FOUND; + else + if (IsDlgButtonChecked(hwnd,IDC_MODNAME2)) + fi->mode = RW_MODULE; + else + if (IsDlgButtonChecked(hwnd,IDC_SETTINGNAME2)) + fi->mode = RW_SETNAME; + else + if (IsDlgButtonChecked(hwnd,IDC_SETTINGVALUE2)) + fi->mode = RW_SETVAL; + + if (IsDlgButtonChecked(hwnd,IDC_ENTIRELY)) + fi->mode |= RW_FULL; + + fi->replace = mir_tstrdup(replace); + + SetWindowText(GetDlgItem(hwnd,IDOK),Translate("Stop")); + EnableWindow(GetDlgItem(hwnd,IDC_SEARCH),0); + + if (IsDlgButtonChecked(hwnd,IDC_CASESENSITIVE)) + fi->mode |= RW_CASE; + } + else + { + SetWindowText(GetDlgItem(hwnd,IDC_SEARCH),Translate("Stop")); + EnableWindow(GetDlgItem(hwnd,IDOK),0); + } + + fi->text = mir_tstrdup(text); + + SendDlgItemMessage(hwnd,IDC_LIST,LB_RESETCONTENT,0,0); + SetWindowLongPtr(GetDlgItem(hwnd,IDC_SEARCH),GWLP_USERDATA,1); + + EnableWindow(GetDlgItem(hwnd,IDCANCEL),0); + forkthread(FindSettings,0,fi); + } + } + break; + case IDCANCEL: + DestroyWindow(hwnd); + break; + case IDC_LIST: + if (HIWORD(wParam) == LBN_DBLCLK) + { + int i = SendDlgItemMessage(hwnd,IDC_LIST,LB_GETCURSEL,0,0); + ItemInfo *ii =(ItemInfo*)SendDlgItemMessage(hwnd,IDC_LIST,LB_GETITEMDATA,i,0); + if (!ii) break; + SendMessage(GetParent(hwnd),WM_FINDITEM,(WPARAM)ii,0); + } + break; + } + break; + case WM_GETMINMAXINFO: + { + MINMAXINFO *mmi=(MINMAXINFO*)lParam; + mmi->ptMinTrackSize.x=520; + mmi->ptMinTrackSize.y=300; + return 0; + } + case WM_SIZE: + { + UTILRESIZEDIALOG urd; + ZeroMemory(&urd,sizeof(urd)); + urd.cbSize=sizeof(urd); + urd.hInstance=hInst; + urd.hwndDlg=hwnd; + urd.lpTemplate=MAKEINTRESOURCE(IDD_FIND); + urd.pfnResizer=FindDialogResize; + CallService(MS_UTILS_RESIZEDIALOG,0,(LPARAM)&urd); + } + break; + case WM_DESTROY: + freeItems(hwnd); + break; + } + return 0; +} + + +void ItemFound(HWND hwnd, HANDLE hContact,const char *module,const char *setting,const char* value,int type) +{ + ItemInfo *ii = (ItemInfo*)mir_calloc(sizeof(ItemInfo)); + int index; + char text[256] = ""; + int result = 0; + char szValue[256]; + char *name, *mode; + + if (!ii) return; + + if (type & FW_REPLACED) + mode = Translate("Replaced with"); + else + if (type & FW_DELETED) + mode = Translate("Deleted"); + else + mode = Translate("Found"); + + name = hContact?(char*)GetContactName(hContact,NULL,0):Translate("Settings"); + + switch (type & 0xFF) + { + case FW_MODULE: + ii->type = FW_MODULE; + mir_snprintf(text, SIZEOF(text), Translate("%s Module \"%s\" in contact \"%s\""), mode, module, name); + break; + case FW_SETTINGNAME: + mir_strncpy(ii->setting,setting,256); + ii->type = FW_SETTINGNAME; + if (GetValue(hContact,module,setting, szValue, SIZEOF(szValue))) + mir_snprintf(text, SIZEOF(text), Translate("%s Setting \"%s\" in module \"%s\" in contact \"%s\" - \"%s\""), mode, setting, module, name, szValue); + else + mir_snprintf(text, SIZEOF(text), Translate("%s Setting \"%s\" in module \"%s\" in contact \"%s\""), mode, setting, module, name); + break; + case FW_SETTINGVALUE: + mir_strncpy(ii->setting,setting,256); + ii->type = FW_SETTINGVALUE; + mir_snprintf(text, SIZEOF(text), Translate("%s \"%s\" in Setting \"%s\" in module \"%s\" in contact \"%s\""), mode, value, setting, module, name); + break; + } + + index = SendMessage(hwnd,LB_ADDSTRING,0,(LPARAM)text); + if (type & FW_DELETED) + { + SendMessage(hwnd,LB_SETITEMDATA,index,0); + mir_free(ii); + } + else + { + ii->hContact= hContact; + mir_strncpy(ii->module,module,256); + SendMessage(hwnd,LB_SETITEMDATA,index,(LPARAM)ii); + } +} + + +char *multiReplace(const char* value, const char *find, const char *replace, int cs) +{ + char *head, *temp, *string; + + int len = (int)strlen(find); + int replen = (int)strlen(replace); + + if (head = (char*)(cs?strstr(value, find):StrStrI(value, find))) // only should be 1 '=' sign there... + { + string = (char*)value; + temp = (char*)mir_alloc(1*sizeof(char)); + temp[0] = '\0'; + + while (head) + { + temp = (char*)mir_realloc(temp, strlen(temp) + strlen(string) + replen + 1); + if (!temp) mir_tstrdup(value); + + strncat(temp, string, (head - string)); + string = head + len; + strcat(temp, replace); + + head = (cs?strstr(string, find):StrStrI(string, find)); + } + strcat(temp, string); + + return temp; + } + + return mir_tstrdup(value); +} + + +int replaceValue(HWND hwnd, HANDLE hContact, const char *module, const char *setting, DBVARIANT *dbv, const char *find, const char *replace, int mode) +{ + + int count = 0; + + DWORD num = 0; + BOOL write = 0; + int isNumeric; + char *myreplace = NULL; + DBCONTACTWRITESETTING cws = {0}; + + if (!dbv->type || dbv->type == DBVT_BLOB) + return 0; + + if (!replace[0]) + isNumeric = 1; + else + isNumeric = sscanf(replace,"%d",&num); + + cws.szModule=module; + cws.szSetting=setting; + cws.value.type=dbv->type; + + switch(dbv->type) + { + case DBVT_UTF8: + case DBVT_ASCIIZ: + if (mode & RW_FULL) + cws.value.pszVal = (char*)replace; + else + { + myreplace = multiReplace(dbv->pszVal, find, replace, mode & RW_CASE); + cws.value.pszVal=myreplace; + } + break; + + case DBVT_BYTE: + if (isNumeric && num < 0x100) + cws.value.bVal = (BYTE)num; + else + return 0; + break; + + case DBVT_WORD: + if (isNumeric && num < 0x10000) + cws.value.wVal = (WORD)num; + else + return 0; + break; + + case DBVT_DWORD: + if (isNumeric) + cws.value.dVal = num; + else + return 0; + break; + + default: + return 0; + } + + if ((!cws.value.pszVal && !replace[0]) || (cws.value.pszVal && !cws.value.pszVal[0])) + { + ItemFound(hwnd,hContact,module,setting,NULL,FW_SETTINGNAME|FW_DELETED); + DBDeleteContactSetting(hContact,module,setting); + mir_free(myreplace); + return 1; + } + + if (!CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)hContact,(LPARAM)&cws)) + { + count++; + ItemFound(hwnd,hContact,module,setting,myreplace?myreplace:(char*)replace,FW_SETTINGVALUE|FW_REPLACED); + } + + mir_free(myreplace); + + return count; +} + + +int replaceSetting(HWND hwnd, HANDLE hContact, const char *module, const char *setting, DBVARIANT *dbv, const char *find, const char *replace, int mode) +{ + DBCONTACTWRITESETTING cws; + char *myreplace = NULL; + int count = 0; + DBVARIANT dbv2; + + if (!dbv->type) return 0; + + if (mode & RW_FULL) + cws.szSetting = (char*)replace; + else + { + myreplace = multiReplace(setting, find, replace, mode & RW_CASE); + cws.szSetting = myreplace; + } + + if (cws.szSetting[0]==0) + { + ItemFound(hwnd,hContact,module,setting,NULL,FW_SETTINGNAME|FW_DELETED); + DBDeleteContactSetting(hContact,module,setting); + mir_free(myreplace); + return 1; + } + + // check & write + if (GetSetting(hContact, module, myreplace, &dbv2)) + { + cws.szModule=module; + cws.value.type=dbv->type; + cws.value.pszVal=dbv->pszVal; + cws.value.bVal=dbv->bVal; + cws.value.wVal=dbv->wVal; + cws.value.dVal=dbv->dVal; + cws.value.pbVal = dbv->pbVal; + cws.value.cpbVal = dbv->cpbVal; + + if (!CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)hContact,(LPARAM)&cws)) + { + count++; + DBDeleteContactSetting(hContact,module,setting); + ItemFound(hwnd,hContact,module,cws.szSetting,NULL,FW_SETTINGNAME|FW_REPLACED); + } + } + else + DBFreeVariant(&dbv2); + + mir_free(myreplace); + + return count; +} + + +int replaceModule(HWND hwnd, HANDLE hContact, const char *module, const char *find, const char *replace, int mode) +{ + + ModuleSettingLL msll; + struct ModSetLinkLinkItem *setting; + char *myreplace = NULL; + char *newModule; + int count = 0; + + if (mode & RW_FULL) + newModule = (char*)replace; + else + { + myreplace = multiReplace(module, find, replace, mode & RW_CASE); + newModule = myreplace; + } + + if (newModule[0]==0) + { + ItemFound(hwnd,hContact,module,NULL,NULL,FW_MODULE|FW_DELETED); + deleteModule((char*)module, hContact, 1); + replaceTreeItem(GetDlgItem(hwnd2mainWindow,IDC_MODULES), hContact, module, NULL); + mir_free(myreplace); + return 1; + } + + if (!IsModuleEmpty(hContact, newModule)) + return 0; + + if (EnumSettings(hContact,(char*)module,&msll)) + { + setting = msll.first; + + while(setting) + { + DBVARIANT dbv; + + if (!GetSetting(hContact, module, setting->name, &dbv)) + { + switch (dbv.type) + { + case DBVT_BYTE: + DBWriteContactSettingByte(hContact, newModule, setting->name, dbv.bVal); + break; + case DBVT_WORD: + DBWriteContactSettingWord(hContact, newModule, setting->name, dbv.wVal); + break; + case DBVT_DWORD: + DBWriteContactSettingDword(hContact, newModule, setting->name, dbv.dVal); + break; + case DBVT_ASCIIZ: + DBWriteContactSettingString(hContact, newModule, setting->name, dbv.pszVal); + break; + case DBVT_UTF8: + DBWriteContactSettingStringUtf(hContact, newModule, setting->name, dbv.pszVal); + break; + case DBVT_BLOB: + DBWriteContactSettingBlob(hContact, newModule, setting->name, dbv.pbVal, dbv.cpbVal); + break; + } + + DBFreeVariant(&dbv); + DBDeleteContactSetting(hContact, module, setting->name); + } + + setting = (struct ModSetLinkLinkItem *)setting->next; + } + FreeModuleSettingLL(&msll); + + replaceTreeItem(GetDlgItem(hwnd2mainWindow,IDC_MODULES), hContact, module, newModule); + + ItemFound(hwnd,hContact,newModule,NULL,NULL,FW_MODULE|FW_REPLACED); + count++; + } + + mir_free(myreplace); + + return count; +} + + +char* stringToUpper(char* in, char* out, int maxlen) +{ + int i; + int len; + + if (maxlen>0) + len = maxlen - 1; + else + len = 0x10000; + + for (i=0;in[i] && i='a' && in[i]<='z')?toupper(in[i]):in[i]; + out[i] = '\0'; + + return out; +} + + +void __cdecl FindSettings(LPVOID di) +{ + char* text = ((FindInfo*)di)->text; + char* replace = ((FindInfo*)di)->replace; + int mode = ((FindInfo*)di)->mode; + HWND hwnd = ((FindInfo*)di)->hwnd; + HWND prnthwnd = GetParent(hwnd); + int options = ((FindInfo*)di)->options; + ModuleSettingLL ModuleList, SettingList; + struct ModSetLinkLinkItem *module, *setting; + HANDLE hContact; + DBVARIANT dbv = {0}; + int caseSensitive = options&FW_CASE; + int exactMatch = options&FW_EXACT; + int inModuleName = options&FW_MODNAME; + int inSettingName = options&FW_SETNAME; + int inSettingValue = options&FW_SETVAL; + int foundCount = 0; + int replaceCount = 0; + char szTmp[128]; + int settingValue, isNumber, NULLContactDone = 0; + + freeItems(hwnd); + if (!text) return; + + if (!EnumModules(&ModuleList)) { msg(Translate("Error Loading Module List"),modFullname); mir_free(di); return;} + + SendMessage(GetDlgItem(GetParent(hwnd),IDC_SBAR),SB_SETTEXT,0,(LPARAM)Translate("Searching...")); + + hContact = 0; + + isNumber = sscanf(text,"%d",&settingValue); + + while (GetWindowLongPtr(GetDlgItem(prnthwnd,IDC_SEARCH),GWLP_USERDATA)) + { + if (!hContact) + { + if (NULLContactDone) break; + else + { + NULLContactDone = 1; + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + } + } + else hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + + module = ModuleList.first; + while (module) + { + if (IsModuleEmpty(hContact, module->name)) + { + module = (struct ModSetLinkLinkItem *)module->next; + continue; + } + + if (!EnumSettings(hContact,module->name,&SettingList)) + { + msg(Translate("Error Loading Setting List"),modFullname); + mir_free(text); + mir_free(di); + FreeModuleSettingLL(&ModuleList); + return; + } + setting = SettingList.first; + + // check in settings value + while (setting) + { + if (inSettingValue) + { + dbv.type = 0; + // check the setting value + if (!GetSetting(hContact,module->name,setting->name,&dbv)) + { + switch (dbv.type) + { + case DBVT_UTF8: // no conversion atm + case DBVT_ASCIIZ: + if ((exactMatch && !(caseSensitive?strcmp(dbv.pszVal,text):strcmpi(dbv.pszVal,text))) || (!exactMatch && (caseSensitive?strstr(dbv.pszVal,text):StrStrI(dbv.pszVal,text)))) + { + if ((mode & RW_FOUND) || (mode & RW_SETVAL)) + replaceCount += replaceValue(hwnd, hContact, module->name, setting->name, &dbv, text, replace, mode); + else + ItemFound(hwnd,hContact,module->name,setting->name,dbv.pszVal,FW_SETTINGVALUE); + + foundCount++; + } + break; + + case DBVT_BYTE: + if (isNumber && settingValue == dbv.bVal) + { + if ((mode & RW_FOUND) || (mode & RW_SETVAL)) + replaceCount += replaceValue(hwnd, hContact, module->name, setting->name, &dbv, NULL, replace, mode); + else + ItemFound(hwnd,hContact,module->name,setting->name,text,FW_SETTINGVALUE); + foundCount++; + } + break; + + case DBVT_WORD: + if (isNumber && settingValue == dbv.wVal) + { + if ((mode & RW_FOUND) || (mode & RW_SETVAL)) + replaceCount += replaceValue(hwnd, hContact, module->name, setting->name, &dbv, NULL, replace, mode); + else + ItemFound(hwnd,hContact,module->name,setting->name,text,FW_SETTINGVALUE); + foundCount++; + } + break; + + case DBVT_DWORD: + if (isNumber && settingValue == (int)dbv.dVal) + { + if ((mode & RW_FOUND) || (mode & RW_SETVAL)) + replaceCount += replaceValue(hwnd, hContact, module->name, setting->name, &dbv, NULL, replace, mode); + else + ItemFound(hwnd,hContact,module->name,setting->name,text,FW_SETTINGVALUE); + foundCount++; + } + break; + + } + DBFreeVariant(&dbv); + } + } + + // check in setting name + if (inSettingName) + { + if ((exactMatch && !(caseSensitive?strcmp(setting->name,text):strcmpi(setting->name,text))) || (!exactMatch && (caseSensitive?StrStrI(setting->name,text):StrStrI(setting->name,text)))) + { + if ((mode & RW_FOUND) || (mode & RW_SETNAME)) + { + if (!GetSetting(hContact,module->name,setting->name,&dbv)) + { + replaceCount += replaceSetting(hwnd, hContact, module->name, setting->name, &dbv, text, replace, mode); + DBFreeVariant(&dbv); + } + } + else + ItemFound(hwnd,hContact,module->name,setting->name, NULL, FW_SETTINGNAME); + foundCount++; + } + } + + setting = (struct ModSetLinkLinkItem *)setting->next; + } + + // check in module name + if (inModuleName) + { + if ((exactMatch && !(caseSensitive?strcmp(module->name,text):strcmpi(module->name,text))) || (!exactMatch && (caseSensitive?strstr(module->name,text):StrStrI(module->name,text)))) + { + if ((mode & RW_FOUND) || (mode & RW_MODULE)) + replaceCount += replaceModule(hwnd, hContact, module->name, text, replace, mode); + else + ItemFound(hwnd,hContact,module->name,0, 0, FW_MODULE); + foundCount++; + } + } + + FreeModuleSettingLL(&SettingList); + module = (struct ModSetLinkLinkItem *)module->next; + } + } + + if (mode) + { + if (!replace[0]) + mir_snprintf(szTmp, SIZEOF(szTmp), Translate("Finished. %d items were found, %d items were deleted."), foundCount, replaceCount); + else + mir_snprintf(szTmp, SIZEOF(szTmp), Translate("Finished. %d items were found, %d items were replaced."), foundCount, replaceCount); + } + else + mir_snprintf(szTmp, SIZEOF(szTmp), Translate("Finished. %d items were found."), foundCount); + + SendMessage(GetDlgItem(prnthwnd,IDC_SBAR),SB_SETTEXT,0,(LPARAM)szTmp); + + SetWindowLongPtr(GetDlgItem(prnthwnd,IDC_SEARCH),GWLP_USERDATA,0); + + if (GetWindowLongPtr(GetDlgItem(prnthwnd,IDC_REPLACE),GWLP_USERDATA)) + { + SetWindowLongPtr(GetDlgItem(prnthwnd,IDC_REPLACE),GWLP_USERDATA, 0); + EnableWindow(GetDlgItem(prnthwnd,IDC_SEARCH),1); + SetWindowText(GetDlgItem(prnthwnd,IDOK),Translate("&Replace")); + } + else + { + SetWindowText(GetDlgItem(prnthwnd,IDC_SEARCH),Translate("&Search")); + EnableWindow(GetDlgItem(prnthwnd,IDOK),1); + } + + mir_free(replace); + mir_free(text); + mir_free(di); + FreeModuleSettingLL(&ModuleList); + + EnableWindow(GetDlgItem(prnthwnd,IDCANCEL),1); + +} diff --git a/plugins/DbEditorPP/src/headers.h b/plugins/DbEditorPP/src/headers.h new file mode 100644 index 0000000000..488d190f16 --- /dev/null +++ b/plugins/DbEditorPP/src/headers.h @@ -0,0 +1,260 @@ +#ifndef _COMMONHEADERS_H +#define _COMMONHEADERS_H +//===================================================== +// Includes +//===================================================== + +#define _CRT_SECURE_NO_WARNINGS +#define _CRT_NONSTDC_NO_DEPRECATE + +#define _WIN32_WINNT 0x0501 +#define MIRANDA_VER 0x0A00 + +#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 +#include +#include +#include +#include + +#include "m_toptoolbar.h" + +#include "resource.h" +#include "Version.h" +#include "modsettingenum.h" + +#define DEF_ICON 7 +#define crlf_string "\r\n\0" + +/////// icons support + +void addIcons(TCHAR* szModuleFileName); +HICON LoadSkinnedDBEIcon(int icon); +int AddIconToList(HIMAGELIST hil, HICON hIcon); +void AddProtoIconsToList(HIMAGELIST hil, int newshift); +int GetProtoIcon(char *szProto); +extern HANDLE hRestore; +extern HANDLE hUserMenu; +///////////////////// + +#ifndef NDEBUG + #define new new(_NORMAL_BLOCK, __FILE__, __LINE__) +#endif + +//======================================================= +// Definitions +//======================================================= +#define modname "DBEditorpp" +#define modFullname "Database Editor++" +#define msg(a,b) MessageBoxA(0,a,b,MB_OK) +#define nick_unknown "(UNKNOWN)" +#define nick_unknownW L"(UNKNOWN)" + + +#define WM_FINDITEM (WM_USER+1) // onyl for the main window, wparam is ItemIfno* lparam is 0 + +#define mir_strlen(ptr) ((ptr==NULL)?0:(int)strlen(ptr)) +#define mir_strncpy(dst, src, len) strncpy(dst, src, len)[len-1]=0; +#define mir_strcmp(ptr1, ptr2) ((ptr1 && ptr2)?strcmp(ptr1, ptr2):1) // (ptr1||ptr2) + +#define ListView_SetItemTextW(hwndLV, i, iSubItem_, pszText_) \ +{ LV_ITEMW _ms_lvi;\ + _ms_lvi.iSubItem = iSubItem_;\ + _ms_lvi.pszText = pszText_;\ + SendMessageW((hwndLV), LVM_SETITEMTEXTW, (WPARAM)(i), (LPARAM)(LV_ITEMW *)&_ms_lvi);\ +} + +#define ListView_InsertItemW(hwnd, pitem) \ + SendMessageW((hwnd), LVM_INSERTITEMW, 0, (LPARAM)(const LV_ITEMW *)(pitem)) + + +#define TreeView_InsertItemW(hwnd, lpis) \ + (HTREEITEM)SendMessageW((hwnd), TVM_INSERTITEMW, 0, (LPARAM)(LPTV_INSERTSTRUCTW)(lpis)) + +/*********************** + ModuleTreeInfoStruct + this gets dumped as the lparam for each module tree item +************************/ +// types +#define CONTACT_ROOT_ITEM 0 +#define CONTACT 1 +#define MODULE 0x2 +#define KNOWN_MODULE 2 +#define UNKNOWN_MODULE 3 +#define STUB 4 +#define EMPTY 8 + +typedef struct { + int type; // from above types + HANDLE hContact; +} ModuleTreeInfoStruct; + +typedef struct { + HANDLE hContact; + char* module; + HWND hwnd2Edit; + int selectedItem; // item that is currently selected + int clicks; // set to 0 when selection changes, 1 after another click.. cant edit till this is 1 +} SettingListInfo; + +#define WATCH_MODULE 1 +#define WATCH_SETTING 0 + +struct DBsetting { + DBVARIANT dbv; + HANDLE hContact; + char *module; + char *setting; + int WatchModule; // above defines +}; + +typedef struct { + char module[256]; + HANDLE hContact; +} ModuleAndContact; + +// find window +#define FW_MODULE 0 +#define FW_SETTINGNAME 1 +#define FW_SETTINGVALUE 2 + +typedef struct { + int type; // above types + HANDLE hContact; + char module[256]; + char setting[256]; +} ItemInfo; + +// watchwindow +struct WatchListArrayStruct{ + struct DBsetting *item; // gotta malloc this + int count; + int size; +}; +extern WatchListArrayStruct WatchListArray; + +//======================================================= +// Variables +//======================================================= +extern HINSTANCE hInst; +extern HWND hwnd2mainWindow, hwnd2watchedVarsWindow, hwnd2importWindow; +extern HIMAGELIST himl; +extern HIMAGELIST himl2; +extern int Mode; +extern int Hex; +extern int Order; +extern BOOL UDB, UOS; + +extern BOOL usePopUps; + +#define NAMEORDERCOUNT 8 + +#define MODE_UNLOADED 1 +#define MODE_LOADED 2 +#define MODE_ALL 3 + +#define HEX_BYTE 1 +#define HEX_WORD 2 +#define HEX_DWORD 4 + +//main.c +int DBGetContactSettingStringStatic(HANDLE hContact, char* szModule, char* szSetting, char* value, int maxLength); +int WriteBlobFromString(HANDLE hContact,const char *szModule,const char *szSetting, const char *Value, int len); +int GetSetting(HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv); +int GetValue(HANDLE hContact, const char* szModule, const char* szSetting, char* Value, int length); +int GetValueW(HANDLE hContact, const char* szModule, const char* szSetting, WCHAR* Value, int length); +char* u2a( wchar_t* src ); +wchar_t *a2u( char* src , wchar_t *buffer, int len ); +int mir_snwprintf(WCHAR *buffer, size_t count, const WCHAR* fmt, ...); +WCHAR *GetContactName(HANDLE hContact, const char *szProto, int unicode); +BOOL IsProtocolLoaded(char* pszProtocolName); + +// main_window.c +INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +// modules.c +int deleteModule(char* module, HANDLE hContact, int fromMenu); +void deleteModuleGui(); +void renameModule(char* oldName, char* newName, HANDLE hContact); +INT_PTR CALLBACK AddModDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +int CloneContact(HANDLE hContact); + +// moduletree.c +void replaceTreeItem(HWND hwnd, HANDLE hContact, const char *module, const char *newModule); +void refreshTree(BOOL restore); +void __cdecl PopulateModuleTreeThreadFunc(LPVOID di); +void freeTree(HWND hwnd2Tree, HANDLE hContact); +int findItemInTree(HWND hwnd2Tree, HANDLE hContact, char* module); + +// settinglist.c +void setupSettingsList(HWND hwnd2List); +void saveListSettings(HWND hwnd2List); +void ClearListview(HWND hwnd2Settings); +void DeleteSettingsFromList(HWND hSettings, HANDLE hContact, char *module, char *setting); +void PopulateSettings(HWND hwnd2Settings, HANDLE hContact, char* module); +void SelectSetting(char* setting); + +// addeditsettingsdlg.c +INT_PTR CALLBACK EditSettingDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +void editSetting(HANDLE hContact, char* module, char* setting); +BOOL convertSetting(HANDLE hContact, char* module, char* setting, int toType); // 0 = byte, 1 = word, 2 = dword, 3 = string + +// exportimport.c +void exportDB(HANDLE hContact, char* module); // hContact == -1 export entire db. module == NULL export entire contact +void ImportSettingsMenuItem(HANDLE hContact); +void ImportSettingsFromFileMenuItem(HANDLE hContact, char* FilePath); + +// find window.c +INT_PTR CALLBACK FindWindowDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +// knownmodules.c +extern BYTE UseKnownModList; +INT_PTR RegisterModule(WPARAM wParam, LPARAM lParam); +INT_PTR RegisterSingleModule(WPARAM wParam, LPARAM lParam); +void FreeKnownModuleList(); +int IsModuleKnown(char* moduleName); +void doOldKnownModulesList(); + +// copymodule.c +void copyModuleMenuItem(char* module, HANDLE hContact); +void copyModule(char* module, HANDLE hContactFrom, HANDLE hContactTo); + +// options.c +int OptInit(WPARAM wParam,LPARAM lParam); + +// watchlist +int addSettingToWatchList(HANDLE hContact, char* module, char* setting); +void freeWatchListItem(int item); +void PopulateWatchedWindow(HWND hwnd); +void freeAllWatches(); +INT_PTR CALLBACK WatchDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +void popupWatchedVar(HANDLE hContact,const char* module,const char* setting); + +#endif //_COMMONHEADERS_H \ No newline at end of file diff --git a/plugins/DbEditorPP/src/icons.cpp b/plugins/DbEditorPP/src/icons.cpp new file mode 100644 index 0000000000..6da3723bfe --- /dev/null +++ b/plugins/DbEditorPP/src/icons.cpp @@ -0,0 +1,143 @@ +#include "headers.h" + +HIMAGELIST himl; + +void addIcons(TCHAR* szModuleFileName) +{ + SKINICONDESC sid={0}; + char name[32]; + sid.cbSize = sizeof(sid); + sid.ptszSection = _T(modFullname); + sid.ptszDefaultFile = szModuleFileName; + sid.flags = SIDF_ALL_TCHAR; + + // closed known module + sid.ptszDescription = LPGENT("Closed Known Module"); + mir_snprintf(name, SIZEOF(name), "DBE++_%d", ICO_KNOWN); + sid.pszName = name; + sid.iDefaultIndex = -ICO_KNOWN; + Skin_AddIcon(&sid); + + // open known module + sid.ptszDescription = LPGENT("Open Known Module"); + mir_snprintf(name, SIZEOF(name), "DBE++_%d", ICO_KNOWNOPEN); + sid.pszName = name; + sid.iDefaultIndex = -ICO_KNOWNOPEN; + Skin_AddIcon(&sid); + + // closed unknown module + sid.ptszDescription = LPGENT("Closed Unknown Module"); + mir_snprintf(name, SIZEOF(name), "DBE++_%d", ICO_UNKNOWN); + sid.pszName = name; + sid.iDefaultIndex = -ICO_UNKNOWN; + Skin_AddIcon(&sid); + + // open unknown module + sid.ptszDescription = LPGENT("Open Unknown Module"); + mir_snprintf(name, SIZEOF(name), "DBE++_%d", ICO_UNKNOWNOPEN); + sid.pszName = name; + sid.iDefaultIndex = -ICO_UNKNOWNOPEN; + Skin_AddIcon(&sid); + + // settings contact + sid.ptszDescription = LPGENT("Settings"); + mir_snprintf(name, SIZEOF(name), "DBE++_%d", ICO_SETTINGS); + sid.pszName = name; + sid.iDefaultIndex = -ICO_SETTINGS; + Skin_AddIcon(&sid); + + // contact group + sid.ptszDescription = LPGENT("Contacts Group"); + mir_snprintf(name, SIZEOF(name), "DBE++_%d", ICO_CONTACTS); + sid.pszName = name; + sid.iDefaultIndex = -ICO_CONTACTS; + Skin_AddIcon(&sid); + + // unknwon contact + sid.ptszDescription = LPGENT("Unknown Contact"); + mir_snprintf(name, SIZEOF(name), "DBE++_%d", ICO_OFFLINE); + sid.pszName = name; + sid.iDefaultIndex = -ICO_OFFLINE; + Skin_AddIcon(&sid); + + // known contact + sid.ptszDescription = LPGENT("Known Contact"); + mir_snprintf(name, SIZEOF(name), "DBE++_%d", ICO_ONLINE); + sid.pszName = name; + sid.iDefaultIndex = -ICO_ONLINE; + Skin_AddIcon(&sid); +} + +HICON LoadSkinnedDBEIcon(int icon) +{ + char name[32]; + mir_snprintf(name, SIZEOF(name), "DBE++_%d", icon); + HICON hIcon = (HICON)CallService(MS_SKIN2_GETICON,0,(LPARAM)name); + return (hIcon) ? hIcon : LoadIcon(hInst, MAKEINTRESOURCE(icon)); +} + + +int AddIconToList(HIMAGELIST hil, HICON hIcon) +{ + if (!hIcon || !hil) + return 0; + + ImageList_AddIcon(hil, hIcon); + return 1; +} + +static PROTOCOLDESCRIPTOR **protocols = NULL; +static int protoCount = 0; +static int shift = 0; + +void AddProtoIconsToList(HIMAGELIST hil, int newshift) +{ + shift = newshift; + + CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM)&protoCount,(LPARAM)&protocols); + + for (int i = 0; i < protoCount; i++) { + if (protocols[i]->type != PROTOTYPE_PROTOCOL) + continue; + + HICON hIcon; + if (hIcon=LoadSkinnedProtoIcon(protocols[i]->szName, ID_STATUS_ONLINE)) + AddIconToList(hil, hIcon); + else + AddIconToList(himl, LoadSkinnedDBEIcon(ICO_ONLINE)); + } +} + +int GetProtoIcon(char *szProto) +{ + if ( !protoCount || !protocols || !szProto) + return DEF_ICON; + + int n = 0; + + for (int i = 0; i < protoCount; i++) { + if (protocols[i]->type != PROTOTYPE_PROTOCOL) + continue; + + if (!mir_strcmp(protocols[i]->szName, szProto)) + return n + shift; + + n++; + } + + return DEF_ICON; +} + +BOOL IsProtocolLoaded(char* pszProtocolName) +{ + if (protoCount) + for(int i = 0; i < protoCount; i++) { + if (protocols[i]->type != PROTOTYPE_PROTOCOL) + continue; + + if (!mir_strcmp(protocols[i]->szName, pszProtocolName)) + return TRUE; + } + + return FALSE; +} diff --git a/plugins/DbEditorPP/src/knownmodules.cpp b/plugins/DbEditorPP/src/knownmodules.cpp new file mode 100644 index 0000000000..13c4379f6b --- /dev/null +++ b/plugins/DbEditorPP/src/knownmodules.cpp @@ -0,0 +1,84 @@ +#include "headers.h" + +BYTE UseKnownModList; + +#define MAXMODS 1024 +char *KnownModules[MAXMODS]; +int KnownModulesCount = 0; + +INT_PTR RegisterModule(WPARAM wParam, LPARAM lParam) +{ + char **mods = (char**)wParam; + int count = lParam; + int i; + for (i=0;iname,&dbv) && dbv.type == DBVT_ASCIIZ) + { + temp = (char*)mir_alloc((strlen(dbv.pszVal)+5)*sizeof(char)); + if (!temp) break; + strcpy(temp,dbv.pszVal); + strcat(temp,",\0"); + var = strtok(temp,", "); + while (var) + { + if (KnownModulesCountnext; + } + FreeModuleSettingLL(&msll); + + UseKnownModList = DBGetContactSettingByte(NULL,modname,"UseKnownModList",0); +} diff --git a/plugins/DbEditorPP/src/main.cpp b/plugins/DbEditorPP/src/main.cpp new file mode 100644 index 0000000000..51c64d0ae7 --- /dev/null +++ b/plugins/DbEditorPP/src/main.cpp @@ -0,0 +1,669 @@ +#include "headers.h" + +// {A8A417EF-07AA-4f37-869F-7BFD74886534} +#define MIID_DBEDITOR {0xa8a417ef, 0x7aa, 0x4f37, { 0x86, 0x9f, 0x7b, 0xfd, 0x74, 0x88, 0x65, 0x34}} + + +HINSTANCE hInst = NULL; + +HANDLE hTTBButt = NULL; +BOOL bServiceMode = FALSE; +BOOL usePopUps; +HWND hwnd2watchedVarsWindow; +int UDB; +int hLangpack; +BYTE nameOrder[NAMEORDERCOUNT]; +HANDLE hUserMenu; +HANDLE hRestore; +WatchListArrayStruct WatchListArray; +HANDLE sMenuCommand, sRegisterModule, sRegisterSingleModule, sImport, sServicemodeLaunch; +HANDLE hModulesLoadedHook = NULL, hSettingsChangedHook=NULL, hOptInitHook=NULL, hPreShutdownHook=NULL, hTTBHook = NULL; + +//======================== +// MirandaPluginInfo +//======================== +PLUGININFOEX pluginInfoEx={ + sizeof(PLUGININFOEX), + __PLUGIN_NAME, + PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), + __DESCRIPTION, + __AUTHOR, + __AUTHOREMAIL, + __COPYRIGHT, + __AUTHORWEB, + UNICODE_AWARE, + MIID_DBEDITOR +}; + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfoEx; +} + +// we implement service mode interface +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_SERVICEMODE, MIID_LAST}; + +//======================== +// WINAPI DllMain +//======================== +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + hInst=hinstDLL; + return TRUE; +} + +void settingChanged(HWND hwnd2Settings, HANDLE hContact, char* module, char* setting); + +int DBSettingChanged(WPARAM wParam,LPARAM lParam) +{ + DBCONTACTWRITESETTING *cws=(DBCONTACTWRITESETTING*)lParam; + HANDLE hContact = (HANDLE)wParam; + char *setting; + int i; + SettingListInfo* info; + + if (hwnd2mainWindow) + { + HWND hwnd2Settings = GetDlgItem(hwnd2mainWindow, IDC_SETTINGS); + if (info = (SettingListInfo*)GetWindowLongPtr(hwnd2Settings,GWLP_USERDATA)) + { + if ((hContact == info->hContact) && !mir_strcmp(info->module, cws->szModule)) + { + setting = mir_strdup(cws->szSetting); + if (cws->value.type == DBVT_DELETED) + { + LVFINDINFO lvfi; + int index; + lvfi.flags = LVFI_STRING; + lvfi.psz = setting; + lvfi.vkDirection = VK_DOWN; + index = ListView_FindItem(hwnd2Settings,-1,&lvfi); + if (index > -1) + ListView_DeleteItem(hwnd2Settings, index); + mir_free(setting); + return 0; + } + settingChanged(hwnd2Settings, hContact, info->module, setting); + mir_free(setting); + } + } + } + // watch list + if (!hwnd2watchedVarsWindow && !usePopUps) return 0; + + for (i=0; iszModule, WatchListArray.item[i].module)) + { + if (!WatchListArray.item[i].setting || !mir_strcmp(cws->szSetting, WatchListArray.item[i].setting)) + { + if (usePopUps) + popupWatchedVar(hContact, cws->szModule, cws->szSetting); + if (hwnd2watchedVarsWindow) + PopulateWatchedWindow(GetDlgItem(hwnd2watchedVarsWindow, IDC_VARS)); + break; + } + } + } + } + return 0; +} + +INT_PTR DBEditorppMenuCommand(WPARAM wParam, LPARAM lParam) +{ + + if (!hwnd2mainWindow) // so only opens 1 at a time + { + hRestore = (HANDLE)wParam; + SetCursor(LoadCursor(NULL,IDC_WAIT)); + CreateDialog(hInst, MAKEINTRESOURCE(IDD_MAIN), 0, MainDlgProc); + } + else + { + ShowWindow(hwnd2mainWindow, SW_RESTORE); + SetForegroundWindow(hwnd2mainWindow); + if (!hRestore && wParam) { + hRestore = (HANDLE)wParam; + refreshTree(4); + } + } + + if (hTTBButt) + CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)hTTBButt, (LPARAM)(TTBST_RELEASED)); + + return 0; +} + +BOOL IsCP_UTF8(void) +{ + CPINFO CPInfo; + + return GetCPInfo(CP_UTF8, &CPInfo); +} + +static int OnTTBLoaded(WPARAM wParam,LPARAM lParam) +{ + TTBButton ttbb = {0}; + HICON ico = LoadIcon(hInst, MAKEINTRESOURCE(ICO_DBE_BUTT)); + UnhookEvent(hTTBHook); + + ttbb.cbSize = sizeof(ttbb); + ttbb.dwFlags = TTBBF_VISIBLE | TTBBF_SHOWTOOLTIP; + ttbb.pszService = "DBEditorpp/MenuCommand"; + ttbb.name = LPGEN("Database Editor++"); + ttbb.hIconUp = ico; + ttbb.pszTooltipUp = LPGEN("Show DataBase Editor"); + hTTBButt = TopToolbar_AddButton(&ttbb); + return 0; +} + +int ModulesLoaded(WPARAM wParam,LPARAM lParam) +{ + DBVARIANT dbv; + char *coreMods = ""; + char *mods; + char mod[64] = ""; + TCHAR szModuleFileName[MAX_PATH]; + int i=0, len; + if (!DBGetContactSetting(NULL,modname,"CoreModules",&dbv) && dbv.type == DBVT_ASCIIZ) + mods = dbv.pszVal; + else + { + DBWriteContactSettingString(NULL,modname,"CoreModules",coreMods); + mods = coreMods; + } + + len = (int)strlen(mods); + while (i < len) + { + if (mods[i] == '\\' && mods[i+1] == ' ') + { + strcat(mod," "); + i++; + } + else if (mods[i] == ' ' || mods[i] == ',' || mods[i] == '\r' || mods[i] == '\n'|| mods[i] == '\0') + { + if (mod[0]) + CallService("DBEditorpp/RegisterSingleModule",(WPARAM)mod,0); + mod[0] = '\0'; + } + else strncat(mod,&mods[i],1); + i++; + } + if (mod[0]) CallService("DBEditorpp/RegisterSingleModule",(WPARAM)mod,0); + + doOldKnownModulesList(); // add the old plugins which havnt been changed over yet.. + + // icons + if (GetModuleFileName(hInst, szModuleFileName, MAX_PATH)) + addIcons(szModuleFileName); + + DBFreeVariant(&dbv); + UnhookEvent(hModulesLoadedHook); + + usePopUps = DBGetContactSettingByte(NULL,modname,"UsePopUps",0); + + // Load the name order + for(i=0;i='0' && b<='9') || + (b>='A' && b<='F') || + (b>='a' && b<='f')) + { + if (sscanf(&szValue[j], "%02X", &tmp) == 1) + { + data[i++] = (BYTE)tmp; + j++; + } + } + j++; + } + + if (i) + return DBWriteContactSettingBlob(hContact,szModule,szSetting, data, (WORD)i); + + return 0; +} + + +int GetSetting(HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv) +{ + DBCONTACTGETSETTING cgs; + + cgs.szModule=szModule; + cgs.szSetting=szSetting; + cgs.pValue=dbv; + dbv->type = 0; + + if (UDB) + return CallService(MS_DB_CONTACT_GETSETTING_STR,(WPARAM)hContact,(LPARAM)&cgs); + else + { + int rr = CallService(MS_DB_CONTACT_GETSETTING,(WPARAM)hContact,(LPARAM)&cgs); + + if (dbv->type != DBVT_UTF8) + return rr; + else + return 1; + } +} + + +int GetValue(HANDLE hContact, const char* szModule, const char* szSetting, char* Value, int length) +{ + DBVARIANT dbv = {0}; + + if (Value && length >= 10 && !GetSetting(hContact, szModule, szSetting, &dbv)) + { + switch(dbv.type) { + case DBVT_UTF8: + if (UOS) + { + int len = (int)strlen(dbv.pszVal)+1; + char *sz = (char*)_alloca(len*3); + WCHAR *wc = (WCHAR*)_alloca(len*sizeof(WCHAR)); + MultiByteToWideChar(CP_UTF8, 0, dbv.pszVal, -1, wc, len); + WideCharToMultiByte(CP_ACP, 0, wc, -1, sz, len, NULL, NULL); + strncpy(Value, sz, length); + break; + }// else fall through + case DBVT_ASCIIZ: + strncpy(Value, dbv.pszVal, length); + break; + case DBVT_DWORD: + _itoa(dbv.dVal,Value,10); + break; + case DBVT_BYTE: + _itoa(dbv.bVal,Value,10); + break; + case DBVT_WORD: + _itoa(dbv.wVal,Value,10); + break; + } + + DBFreeVariant(&dbv); + + Value[length-1] = 0; + return 1; + } + + if (Value) + Value[0] = 0; + + return 0; +} + + +int GetValueW(HANDLE hContact, const char* szModule, const char* szSetting, WCHAR* Value, int length) +{ + DBVARIANT dbv ={0}; + + if (Value && length >= 10 && !GetSetting(hContact, szModule, szSetting, &dbv)) + { + switch(dbv.type) { + case DBVT_UTF8: + { + int len = (int)strlen(dbv.pszVal) + 1; + WCHAR *wc = (WCHAR*)_alloca(length*sizeof(WCHAR)); + MultiByteToWideChar(CP_UTF8, 0, dbv.pszVal, -1, wc, len); + wcsncpy((WCHAR*)Value, wc, length); + } + break; + case DBVT_ASCIIZ: + { + int len = (int)strlen(dbv.pszVal) + 1; + WCHAR *wc = (WCHAR*)_alloca(len*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, dbv.pszVal, -1, wc, len); + wcsncpy((WCHAR*)Value, wc, length); + } + break; + case DBVT_DWORD: + _itow(dbv.dVal,Value,10); + break; + case DBVT_BYTE: + _itow(dbv.bVal,Value,10); + break; + case DBVT_WORD: + _itow(dbv.wVal,Value,10); + break; + } + + DBFreeVariant(&dbv); + + Value[length-1] = 0; + return 1; + } + + if (Value) + Value[0] = 0; + + return 0; +} + + +char *u2a( wchar_t* src ) +{ + if (src) + { + int cbLen = WideCharToMultiByte( CP_ACP, 0, src, -1, NULL, 0, NULL, NULL ); + char* result = (char*)mir_calloc((cbLen+1)*sizeof(char)); + if ( result == NULL ) + return NULL; + + WideCharToMultiByte( CP_ACP, 0, src, -1, result, cbLen, NULL, NULL ); + result[ cbLen ] = 0; + return result; + } + else + return NULL; +} + + +wchar_t *a2u( char* src , wchar_t *buffer, int len ) +{ + wchar_t *result = buffer; + if ( result == NULL || len < 3) + return NULL; + + MultiByteToWideChar( CP_ACP, 0, src, -1, result, len - 1 ); + result[ len - 1 ] = 0; + + return result; +} + +int mir_snwprintf(WCHAR *buffer, size_t count, const WCHAR* fmt, ...) +{ + va_list va; + int len; + + va_start(va, fmt); + len = _vsnwprintf(buffer, count-1, fmt, va); + va_end(va); + + buffer[count-1] = 0; + + return len; +} + + +int GetDatabaseString(HANDLE hContact, const char *szModule, const char* szSetting, WCHAR *Value, int length, BOOL unicode) +{ + if (unicode) + return GetValueW(hContact, szModule, szSetting, Value, length); + else + return GetValue(hContact, szModule, szSetting, (char*)Value, length); +} + + +WCHAR *GetContactName(HANDLE hContact, const char *szProto, int unicode) +{ + + int i, r = 0; + static WCHAR res[512]; + char *proto = (char*)szProto; + char name[256]; + + if (hContact && !proto) + { + if (GetValue(hContact,"Protocol","p",name,SIZEOF(name))) + proto = name; + } + + if (proto) + { + + for(i=0;i 1) + r |= GetDatabaseString(hContact,proto,"LastName",&res[len],SIZEOF(res)-len,unicode); + + break; + } + } + + if (r) return res; + } + } + + if (unicode) + return nick_unknownW; + else + return (WCHAR*)nick_unknown; +} diff --git a/plugins/DbEditorPP/src/main_window.cpp b/plugins/DbEditorPP/src/main_window.cpp new file mode 100644 index 0000000000..d7fdb75256 --- /dev/null +++ b/plugins/DbEditorPP/src/main_window.cpp @@ -0,0 +1,673 @@ +#include "headers.h" + +HWND hwnd2mainWindow; +int Order; +HIMAGELIST himl2; +int Hex; + +#define GC_SPLITTERMOVED (WM_USER+101) + +extern BOOL bServiceMode; + +static WNDPROC SettingListSubClass, ModuleTreeSubClass, SplitterSubClass; + +void moduleListWM_NOTIFY(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam); +void SettingsListWM_NOTIFY(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam); + +int DialogResize(HWND hwnd,LPARAM lParam,UTILRESIZECONTROL *urc) +{ + switch(urc->wId) + { + case IDC_MODULES: + urc->rcItem.right = lParam-3; + urc->rcItem.top = 0; + urc->rcItem.left = 0; + urc->rcItem.bottom = urc->dlgNewSize.cy; + return RD_ANCHORX_CUSTOM|RD_ANCHORY_CUSTOM; + case IDC_SPLITTER: + urc->rcItem.top = 0; + urc->rcItem.bottom = urc->dlgNewSize.cy; + urc->rcItem.right = lParam; + urc->rcItem.left = lParam-3; + return RD_ANCHORX_CUSTOM|RD_ANCHORY_CUSTOM; + case IDC_SETTINGS: + urc->rcItem.top = 0; + urc->rcItem.bottom = urc->dlgNewSize.cy; + urc->rcItem.left = lParam; + urc->rcItem.right = urc->dlgNewSize.cx; + return RD_ANCHORX_CUSTOM|RD_ANCHORY_CUSTOM; + case IDC_VARS: + urc->rcItem.top = 0; + urc->rcItem.bottom = urc->dlgNewSize.cy; + urc->rcItem.left = 0; + urc->rcItem.right = urc->dlgNewSize.cx; + return RD_ANCHORY_CUSTOM|RD_ANCHORX_CUSTOM; + } + return RD_ANCHORX_LEFT|RD_ANCHORY_TOP; + +} + +static LRESULT CALLBACK SplitterSubclassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) +{ + switch(msg) { + case WM_NCHITTEST: + return HTCLIENT; + case WM_SETCURSOR: + { RECT rc; + GetClientRect(hwnd,&rc); + SetCursor(rc.right>rc.bottom?LoadCursor(NULL, IDC_SIZENS):LoadCursor(NULL, IDC_SIZEWE)); + return TRUE; + } + case WM_LBUTTONDOWN: + SetCapture(hwnd); + return 0; + case WM_MOUSEMOVE: + if(GetCapture()==hwnd) { + RECT rc; + GetClientRect(hwnd,&rc); + SendMessage(GetParent(hwnd),GC_SPLITTERMOVED,rc.right>rc.bottom?(short)HIWORD(GetMessagePos())+rc.bottom/2:(short)LOWORD(GetMessagePos())+rc.right/2,(LPARAM)hwnd); + } + return 0; + case WM_LBUTTONUP: + ReleaseCapture(); + return 0; + } + return CallWindowProc(SplitterSubClass,hwnd,msg,wParam,lParam); +} +LRESULT CALLBACK ModuleTreeSubclassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) +{ + switch(msg) { + case WM_RBUTTONDOWN: + { + TVHITTESTINFO hti; + hti.pt.x=(short)LOWORD(GetMessagePos()); + hti.pt.y=(short)HIWORD(GetMessagePos()); + ScreenToClient(hwnd,&hti.pt); + + if(TreeView_HitTest(hwnd,&hti)) + { + if(hti.flags&TVHT_ONITEM) + TreeView_SelectItem(hwnd, hti.hItem); + } + } + break; + case WM_CHAR: + if (GetKeyState(VK_CONTROL)&0x8000 && wParam == 6) + CreateDialog(hInst, MAKEINTRESOURCE(IDD_FIND), hwnd, FindWindowDlgProc); + break; + case WM_KEYUP: + { + if (wParam == VK_DELETE || + wParam == VK_F2 || + //wParam == VK_UP || + //wParam == VK_DOWN || + wParam == VK_F5 || + wParam == VK_F3) + + { + TVITEM tvi; + char module[256]; + tvi.mask=TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT; + tvi.hItem=TreeView_GetSelection(hwnd); + tvi.pszText = module; + tvi.cchTextMax = 255; + if (TreeView_GetItem(hwnd,&tvi) && tvi.lParam) + { + ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct*)tvi.lParam; + HANDLE hContact = mtis->hContact; + if (wParam == VK_DELETE) + { + if ((mtis->type) & MODULE) + { + if (deleteModule(module, hContact,0)) + { + mir_free(mtis); + TreeView_DeleteItem(hwnd,tvi.hItem); + } + } + else if ((mtis->type == CONTACT) && hContact) + { + if (DBGetContactSettingByte(NULL,"CList", "ConfirmDelete",1)) + { + char msg[1024]; + mir_snprintf(msg, SIZEOF(msg), Translate("Are you sure you want to delete contact \"%s\"?"), module); + if (MessageBox(0,msg, Translate("Confirm Contact Delete"), MB_YESNO|MB_ICONEXCLAMATION) == IDNO) + break; + } + CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact,0); + freeTree(hwnd,mtis->hContact); + TreeView_DeleteItem(hwnd,tvi.hItem); + } + } + else if (wParam == VK_F2 && (mtis->type == MODULE || mtis->type == UNKNOWN_MODULE)) + TreeView_EditLabel(hwnd,tvi.hItem); + else if (wParam == VK_F5) + { + refreshTree(1); + break; + } + + else if (wParam == VK_F3) + { + CreateDialog(hInst, MAKEINTRESOURCE(IDD_FIND), hwnd, FindWindowDlgProc); + break; + } + } + } + } + break; + default:break; + } + return CallWindowProc(ModuleTreeSubClass,hwnd,msg,wParam,lParam); +} +static LRESULT CALLBACK SettingListSubclassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) +{ + switch(msg) { + case WM_CHAR: + if (GetKeyState(VK_CONTROL)&0x8000 && wParam == 6) + CreateDialog(hInst, MAKEINTRESOURCE(IDD_FIND), hwnd, FindWindowDlgProc); + break; + case WM_KEYDOWN: + if (wParam == VK_DELETE || wParam == VK_F5 || (wParam == VK_F2 && ListView_GetSelectedCount(hwnd) == 1)) + { + char *module, setting[256]; + HANDLE hContact; + SettingListInfo* sli = (SettingListInfo*)GetWindowLongPtr(hwnd,GWLP_USERDATA); + if (!sli) break; + hContact = sli->hContact; + module = sli->module; + ListView_GetItemText(hwnd, ListView_GetSelectionMark(hwnd), 0, setting, 256); + + if (wParam == VK_F2) + editSetting(hContact,module, setting); + else if (wParam == VK_F5) + { + char *szModule = mir_tstrdup(module); // need to do this, otheriwse the setlist stays empty + PopulateSettings(hwnd,hContact,szModule); + mir_free(szModule); + } + else if (wParam == VK_DELETE) + DeleteSettingsFromList(hwnd, hContact, module, setting); + + return 0; + } + else if (wParam == VK_F3) + CreateDialog(hInst, MAKEINTRESOURCE(IDD_FIND), hwnd, FindWindowDlgProc); + break; + + default: break; + } + return CallWindowProc(SettingListSubClass,hwnd,msg,wParam,lParam); +} + +INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + int i; + HMENU hMenu = GetMenu(hwnd); + + hwnd2mainWindow = hwnd; + // do the icon + SendMessage(hwnd,WM_SETICON,ICON_BIG,(LPARAM)LoadIcon(hInst,MAKEINTRESOURCE(ICO_REGEDIT))); + if (UOS) + SetWindowText(hwnd, Translate("Database Editor++ (unicode mode)")); + else + SetWindowText(hwnd, Translate("Database Editor++ (ansi mode)")); + // setup the splitter + SetWindowLongPtr(GetDlgItem(hwnd,IDC_SPLITTER),GWLP_USERDATA,(LPARAM)DBGetContactSettingWord(NULL, modname, "Splitter", 300)); + SendMessage(hwnd, GC_SPLITTERMOVED, 0,0); + SplitterSubClass=(WNDPROC)SetWindowLongPtr(GetDlgItem(hwnd,IDC_SPLITTER),GWLP_WNDPROC,(LONG)SplitterSubclassProc); + // module tree + TreeView_SetUnicodeFormat(GetDlgItem(hwnd,IDC_MODULES), UOS); + ModuleTreeSubClass=(WNDPROC)SetWindowLongPtr(GetDlgItem(hwnd,IDC_MODULES),GWLP_WNDPROC,(LONG)ModuleTreeSubclassProc); + //setting list + setupSettingsList(GetDlgItem(hwnd,IDC_SETTINGS)); + SettingListSubClass=(WNDPROC)SetWindowLongPtr(GetDlgItem(hwnd,IDC_SETTINGS),GWLP_WNDPROC,(LONG)SettingListSubclassProc); + // traslation stuff + TranslateDialogDefault(hwnd); + TranslateMenu(hMenu); + + for (i=0;i<6;i++) + { + TranslateMenu(GetSubMenu(hMenu,i)); + } + + // move the dialog to the users position + MoveWindow(hwnd,DBGetContactSettingDword(NULL,modname,"x",0),DBGetContactSettingDword(NULL,modname,"y",0),DBGetContactSettingDword(NULL,modname,"width",500),DBGetContactSettingDword(NULL,modname,"height",250),0); + if (DBGetContactSettingByte(NULL,modname,"Maximised",0)) + { + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + wp.flags = WPF_RESTORETOMAXIMIZED; + wp.showCmd = SW_SHOWMAXIMIZED; + + SetWindowPlacement(hwnd,&wp); + } + SetCursor(LoadCursor(NULL,IDC_ARROW)); + + Mode = MODE_ALL; + CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_ALL,MF_BYCOMMAND|MF_CHECKED); + + Hex = DBGetContactSettingByte(NULL,modname,"HexMode",0); + CheckMenuItem(GetSubMenu(hMenu,5),MENU_BYTE_HEX,MF_BYCOMMAND|((Hex & HEX_BYTE)?MF_CHECKED:MF_UNCHECKED)); + CheckMenuItem(GetSubMenu(hMenu,5),MENU_WORD_HEX,MF_BYCOMMAND|((Hex & HEX_WORD)?MF_CHECKED:MF_UNCHECKED)); + CheckMenuItem(GetSubMenu(hMenu,5),MENU_DWORD_HEX,MF_BYCOMMAND|((Hex & HEX_DWORD)?MF_CHECKED:MF_UNCHECKED)); + + CheckMenuItem(GetSubMenu(GetMenu(hwnd),5),MENU_SAVE_POSITION,MF_BYCOMMAND|(DBGetContactSettingByte(NULL,modname,"RestoreOnOpen",1)?MF_CHECKED:MF_UNCHECKED)); + + Order = DBGetContactSettingByte(NULL,modname,"SortMode",1); + CheckMenuItem(GetSubMenu(GetMenu(hwnd),5),MENU_SORT_ORDER,MF_BYCOMMAND|(Order?MF_CHECKED:MF_UNCHECKED)); + + + + // image list + { + int numberOfIcons = 0; + himl = NULL; + + if (himl = ImageList_Create(16, 16, IsWinVerXPPlus() ? ILC_COLOR32 | ILC_MASK : ILC_COLOR8 | ILC_MASK, 10, 0)) + { + if (AddIconToList(himl, LoadSkinnedDBEIcon(ICO_SETTINGS))) + numberOfIcons++; + if (AddIconToList(himl, LoadSkinnedDBEIcon(ICO_KNOWN))) + numberOfIcons++; + if (AddIconToList(himl, LoadSkinnedDBEIcon(ICO_KNOWNOPEN))) + numberOfIcons++; + if (AddIconToList(himl, LoadSkinnedDBEIcon(ICO_CONTACTS))) + numberOfIcons++; + if (AddIconToList(himl, LoadSkinnedDBEIcon(ICO_OFFLINE))) + numberOfIcons++; + if (AddIconToList(himl, LoadSkinnedDBEIcon(ICO_UNKNOWN))) + numberOfIcons++; + if (AddIconToList(himl, LoadSkinnedDBEIcon(ICO_UNKNOWNOPEN))) + numberOfIcons++; + if (AddIconToList(himl, LoadSkinnedDBEIcon(ICO_ONLINE))) + numberOfIcons++; + + if (numberOfIcons < DEF_ICON + 1) + { + if (numberOfIcons) + ImageList_Destroy(himl); + himl = NULL; + } + + AddProtoIconsToList(himl, numberOfIcons); + + } + + himl2 = NULL; + numberOfIcons = 0; + + if (himl2 = ImageList_Create(16, 16, IsWinVerXPPlus() ? ILC_COLOR32 | ILC_MASK : ILC_COLOR8 | ILC_MASK, 5, 0)) + { + + if (AddIconToList(himl2, LoadIcon(hInst, MAKEINTRESOURCE(ICO_BINARY)))) + numberOfIcons++; + if (AddIconToList(himl2, LoadIcon(hInst, MAKEINTRESOURCE(ICO_BYTE)))) + numberOfIcons++; + if (AddIconToList(himl2, LoadIcon(hInst, MAKEINTRESOURCE(ICO_WORD)))) + numberOfIcons++; + if (AddIconToList(himl2, LoadIcon(hInst, MAKEINTRESOURCE(ICO_DWORD)))) + numberOfIcons++; + if (AddIconToList(himl2, LoadIcon(hInst, MAKEINTRESOURCE(ICO_STRING)))) + numberOfIcons++; + if (AddIconToList(himl2, LoadIcon(hInst, MAKEINTRESOURCE(ICO_UNICODE)))) + numberOfIcons++; + if (AddIconToList(himl2, LoadIcon(hInst, MAKEINTRESOURCE(ICO_HANDLE)))) + numberOfIcons++; + + if (numberOfIcons < 7) + { + if (numberOfIcons) + ImageList_Destroy(himl2); + himl2 = NULL; + } + } + } + + { + int restore; + + if (hRestore) + restore = 3; + else + if (DBGetContactSettingByte(NULL,modname,"RestoreOnOpen",1)) + restore = 2; + else + restore = 0; + + refreshTree(restore); + } + + } + return TRUE; + case GC_SPLITTERMOVED: + { + POINT pt; + RECT rc; + RECT rc2; + + int splitterPos = GetWindowLongPtr(GetDlgItem(hwnd,IDC_SPLITTER),GWLP_USERDATA); + + GetWindowRect(hwnd,&rc2); + + if ((HWND)lParam==GetDlgItem(hwnd,IDC_SPLITTER)) + { + GetClientRect(hwnd,&rc); + pt.x=wParam; pt.y=0; + ScreenToClient(hwnd,&pt); + + splitterPos=rc.left+pt.x+1; + if (splitterPos<65) splitterPos=65; + if (splitterPos > rc2.right-rc2.left-65) splitterPos=rc2.right-rc2.left-65; + SetWindowLongPtr(GetDlgItem(hwnd,IDC_SPLITTER),GWLP_USERDATA, splitterPos); + DBWriteContactSettingWord(NULL, modname, "Splitter",(WORD)splitterPos); + } + PostMessage(hwnd,WM_SIZE,0,0); + } + break; + case WM_GETMINMAXINFO: + { + MINMAXINFO *mmi=(MINMAXINFO*)lParam; + int splitterPos = GetWindowLongPtr(GetDlgItem(hwnd,IDC_SPLITTER),GWLP_USERDATA); + + if(splitterPos+40 > 200) + mmi->ptMinTrackSize.x=splitterPos+65; + else + mmi->ptMinTrackSize.x=200; + mmi->ptMinTrackSize.y=150; + return 0; + } + case WM_MOVE: + case WM_SIZE: + { + UTILRESIZEDIALOG urd; + + ZeroMemory(&urd,sizeof(urd)); + urd.cbSize=sizeof(urd); + urd.hInstance=hInst; + urd.hwndDlg=hwnd; + urd.lParam=(LPARAM)GetWindowLongPtr(GetDlgItem(hwnd,IDC_SPLITTER),GWLP_USERDATA); + urd.lpTemplate=MAKEINTRESOURCE(IDD_MAIN); + urd.pfnResizer=DialogResize; + CallService(MS_UTILS_RESIZEDIALOG,0,(LPARAM)&urd); + + if (msg == WM_SIZE && wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED) + { + DBWriteContactSettingByte(NULL,modname,"Maximised",1); + } + else if (msg == WM_SIZE && wParam == SIZE_RESTORED) + { + DBWriteContactSettingByte(NULL,modname,"Maximised",0); + } + + } + break; + case WM_DESTROY: // free our shit! + + if (DBGetContactSettingByte(NULL,modname,"RestoreOnOpen",1)) + { + HTREEITEM item; + HWND hwnd2Tree = GetDlgItem(hwnd,IDC_MODULES); + char module[256] = {0}; + if (item = TreeView_GetSelection(hwnd2Tree)) + { + int type = MODULE; + TVITEM tvi = {0}; + HANDLE hContact = NULL; + tvi.mask=TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT; + tvi.pszText = module; + tvi.cchTextMax = 255; + tvi.hItem=item; + + if (TreeView_GetItem(hwnd2Tree, &tvi)) + { + if (tvi.lParam) + { + ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)tvi.lParam; + hContact = mtis->hContact; + type = mtis->type; + } + + DBWriteContactSettingDword(NULL,modname,"LastContact",(DWORD)hContact); + + if (type == CONTACT) + DBWriteContactSettingString(NULL,modname,"LastModule",""); + else + DBWriteContactSettingString(NULL,modname,"LastModule",module); + } + else + { + DBDeleteContactSetting(NULL,modname,"LastContact"); + DBDeleteContactSetting(NULL,modname,"LastModule"); + } + + // setting list + { + HWND hwnd2Settings = GetDlgItem(hwnd, IDC_SETTINGS); + int pos = ListView_GetSelectionMark(hwnd2Settings); + + if (pos != -1) + { + char text[256]; + + ListView_GetItemText(hwnd2Settings, pos, 0, text, SIZEOF(text)); + + DBWriteContactSettingString(NULL,modname,"LastSetting",text); + } + else + DBDeleteContactSetting(NULL,modname,"LastSetting"); + } + } + } + DBWriteContactSettingByte(NULL,modname,"HexMode",(byte)Hex); + DBWriteContactSettingByte(NULL,modname,"SortMode",(byte)Order); + saveListSettings(GetDlgItem(hwnd,IDC_SETTINGS)); + hwnd2mainWindow = 0; + ClearListview(GetDlgItem(hwnd,IDC_SETTINGS)); + freeTree(GetDlgItem(hwnd,IDC_MODULES),0); + if (himl) + ImageList_Destroy(himl); + if (himl2) + ImageList_Destroy(himl2); + SetWindowLongPtr(GetDlgItem(hwnd,IDC_SETTINGS),GWLP_WNDPROC,(LONG)SettingListSubClass); + SetWindowLongPtr(GetDlgItem(hwnd,IDC_MODULES),GWLP_WNDPROC,(LONG)ModuleTreeSubClass); + SetWindowLongPtr(GetDlgItem(hwnd,IDC_SPLITTER),GWLP_WNDPROC,(LONG)SplitterSubClass); + if (!DBGetContactSettingByte(NULL,modname,"Maximised",0)) + { + RECT rc; + GetWindowRect(hwnd,&rc); + DBWriteContactSettingDword(NULL,modname,"x",rc.left); + DBWriteContactSettingDword(NULL,modname,"y",rc.top); + DBWriteContactSettingDword(NULL,modname,"width",rc.right-rc.left); + DBWriteContactSettingDword(NULL,modname,"height",rc.bottom-rc.top); + } + if (hwnd2importWindow) { + DestroyWindow(hwnd2importWindow); + hwnd2importWindow = 0; + } + if ( bServiceMode ) { + PostQuitMessage(0); + } + + return 0; + case WM_COMMAND: + if (GetKeyState(VK_ESCAPE) & 0x8000) return TRUE; // this needs to be changed to c if htere is a label edit happening.. + switch(LOWORD(wParam)) + { + case MENU_REFRESH_MODS: + refreshTree(1); + break; + case MENU_REFRESH_SETS: + { + TVITEM tvi; + ModuleTreeInfoStruct *mtis; + char module[256]; + tvi.mask=TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT; + tvi.hItem=TreeView_GetSelection(GetDlgItem(hwnd, IDC_MODULES)); + tvi.pszText = module; + tvi.cchTextMax = 255; + if (!TreeView_GetItem(GetDlgItem(hwnd, IDC_MODULES),&tvi)) break; + if (tvi.lParam) + { + mtis = (ModuleTreeInfoStruct *)tvi.lParam; + if (mtis->type == MODULE || mtis->type == UNKNOWN_MODULE) + PopulateSettings(GetDlgItem(hwnd, IDC_SETTINGS), mtis->hContact, module); + else ClearListview(GetDlgItem(hwnd, IDC_SETTINGS)); + } + else ClearListview(GetDlgItem(hwnd, IDC_SETTINGS)); + } + break; + ///////////////////////// // watches + case MENU_VIEW_WATCHES: + { + if (!hwnd2watchedVarsWindow) // so only opens 1 at a time + hwnd2watchedVarsWindow = CreateDialog(hInst, MAKEINTRESOURCE(IDD_WATCH_DIAG), 0, WatchDlgProc); + else SetForegroundWindow(hwnd2watchedVarsWindow); + } + break; + case MENU_REMALL_WATCHES: + freeAllWatches(); + break; + case MENU_EXPORTDB: // all db + exportDB(INVALID_HANDLE_VALUE,0); + break; + case MENU_EXPORTCONTACT: // all contacts + exportDB(INVALID_HANDLE_VALUE, ""); + break; + case MENU_EXPORTMODULE: // all settings + exportDB(NULL, 0); + break; + case MENU_IMPORTFROMFILE: + ImportSettingsFromFileMenuItem(NULL, ""); + break; + case MENU_IMPORTFROMTEXT: + ImportSettingsMenuItem(NULL); + break; + case MENU_EXIT: + case IDCANCEL: + DestroyWindow(hwnd); + break; + case MENU_DELETE: + deleteModuleGui(); + break; + case MENU_FINDANDREPLACE: + CreateDialog(hInst, MAKEINTRESOURCE(IDD_FIND), hwnd, FindWindowDlgProc); + break; + case MENU_FILTER_ALL: + if (Mode != MODE_ALL) + { + HMENU hMenu = GetMenu(hwnd); + CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_ALL,MF_BYCOMMAND|MF_CHECKED); + CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_LOADED,MF_BYCOMMAND|MF_UNCHECKED); + CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_UNLOADED,MF_BYCOMMAND|MF_UNCHECKED); + Mode = MODE_ALL; + refreshTree(1); + } + break; + case MENU_FILTER_LOADED: + if (Mode != MODE_LOADED) + { + HMENU hMenu = GetMenu(hwnd); + CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_ALL,MF_BYCOMMAND|MF_UNCHECKED); + CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_LOADED,MF_BYCOMMAND|MF_CHECKED); + CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_UNLOADED,MF_BYCOMMAND|MF_UNCHECKED); + Mode = MODE_LOADED; + refreshTree(1); + } + break; + case MENU_FILTER_UNLOADED: + if (Mode != MODE_UNLOADED) + { + HMENU hMenu = GetMenu(hwnd); + CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_ALL,MF_BYCOMMAND|MF_UNCHECKED); + CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_LOADED,MF_BYCOMMAND|MF_UNCHECKED); + CheckMenuItem(GetSubMenu(hMenu,5),MENU_FILTER_UNLOADED,MF_BYCOMMAND|MF_CHECKED); + Mode = MODE_UNLOADED; + refreshTree(1); + } + break; + case MENU_BYTE_HEX: + { + Hex ^= HEX_BYTE; + CheckMenuItem(GetSubMenu(GetMenu(hwnd),5),MENU_BYTE_HEX,MF_BYCOMMAND|((Hex & HEX_BYTE)?MF_CHECKED:MF_UNCHECKED)); + } + break; + case MENU_WORD_HEX: + { + Hex ^= HEX_WORD; + CheckMenuItem(GetSubMenu(GetMenu(hwnd),5),MENU_WORD_HEX,MF_BYCOMMAND|((Hex & HEX_WORD)?MF_CHECKED:MF_UNCHECKED)); + } + break; + case MENU_DWORD_HEX: + { + Hex ^= HEX_DWORD; + CheckMenuItem(GetSubMenu(GetMenu(hwnd),5),MENU_DWORD_HEX,MF_BYCOMMAND|((Hex & HEX_DWORD)?MF_CHECKED:MF_UNCHECKED)); + } + break; + case MENU_SAVE_POSITION: + { + BOOL save = !DBGetContactSettingByte(NULL,modname,"RestoreOnOpen",1); + CheckMenuItem(GetSubMenu(GetMenu(hwnd),5),MENU_SAVE_POSITION,MF_BYCOMMAND|(save?MF_CHECKED:MF_UNCHECKED)); + DBWriteContactSettingByte(NULL,modname,"RestoreOnOpen", (byte)save); + } + break; + case MENU_SORT_ORDER: + Order = !Order; + CheckMenuItem(GetSubMenu(GetMenu(hwnd),5),MENU_SORT_ORDER,MF_BYCOMMAND|(Order?MF_CHECKED:MF_UNCHECKED)); + refreshTree(1); + break; + case MENU_OPEN_OPTIONS: + OPENOPTIONSDIALOG odp = {0}; + odp.cbSize = sizeof(odp); + odp.pszGroup = "Services"; + odp.pszPage = modFullname; + odp.pszTab = 0; + CallService(MS_OPT_OPENOPTIONS,0,(LPARAM)&odp); + break; + } + return TRUE; // case WM_COMMAND + case WM_NOTIFY: + switch(LOWORD(wParam)) + { + case IDC_MODULES: + moduleListWM_NOTIFY(hwnd,msg,wParam,lParam); + break; + case IDC_SETTINGS: + SettingsListWM_NOTIFY(hwnd,msg,wParam,lParam); + break; + } + return TRUE; // case WM_NOTIFY + case WM_FINDITEM: + { + ItemInfo *ii = (ItemInfo*)wParam; + HWND hwnd2Settings = GetDlgItem(hwnd,IDC_SETTINGS); + int hItem = findItemInTree(GetDlgItem(hwnd,IDC_MODULES),ii->hContact,ii->module); + + if (hItem != -1) + { + TreeView_SelectItem(GetDlgItem(hwnd,IDC_MODULES), (HTREEITEM)hItem); + if (ii->type != FW_MODULE) + { + LVITEM lvItem; + LVFINDINFO lvfi; + + lvfi.flags = LVFI_STRING; + lvfi.psz = ii->setting; + lvfi.vkDirection = VK_DOWN; + + lvItem.mask = LVIF_TEXT|LVIF_IMAGE; + lvItem.iItem = ListView_FindItem(hwnd2Settings,-1,&lvfi); + lvItem.iSubItem = 0; + if (lvItem.iItem >= 0) + ListView_SetItemState(hwnd2Settings,lvItem.iItem, LVIS_SELECTED, LVIS_SELECTED); + } + } + } + break; + } // switch(msg) + return 0; +} diff --git a/plugins/DbEditorPP/src/modsettingenum.cpp b/plugins/DbEditorPP/src/modsettingenum.cpp new file mode 100644 index 0000000000..7eaecdd1a0 --- /dev/null +++ b/plugins/DbEditorPP/src/modsettingenum.cpp @@ -0,0 +1,88 @@ +#include "headers.h" + +void FreeModuleSettingLL(ModuleSettingLL* msll) +{ + if (msll) + { + + struct ModSetLinkLinkItem *item = msll->first; + struct ModSetLinkLinkItem *temp; + + while (item) + { + mir_free(item->name); + temp = item; + item = (struct ModSetLinkLinkItem *)item->next; + mir_free(temp); + } + + msll->first = 0; + msll->last = 0; + } +} + +int enumModulesSettingsProc( const char *szName , DWORD ofsModuleName , LPARAM lParam) +{ + ModuleSettingLL *msll = (ModuleSettingLL *)lParam; + if (!msll->first) + { + msll->first = (struct ModSetLinkLinkItem *)mir_alloc(sizeof(struct ModSetLinkLinkItem)); + if (!msll->first) return 1; + msll->first->name = mir_tstrdup(szName); + msll->first->next = 0; + msll->last = msll->first; + } + else + { + struct ModSetLinkLinkItem *item = (struct ModSetLinkLinkItem *)mir_alloc(sizeof(struct ModSetLinkLinkItem)); + if (!item) return 1; + msll->last->next = (BYTE*)item; + msll->last = (struct ModSetLinkLinkItem *)item; + item->name = mir_tstrdup(szName); + item->next = 0; + } + return 0; +} + +int EnumModules(ModuleSettingLL *msll) // 1 = success, 0 = fail +{ + msll->first = 0; + msll->last = 0; + return !CallService(MS_DB_MODULES_ENUM, (WPARAM)msll,(WPARAM)enumModulesSettingsProc); +} + + +int enumSettingsProc(const char *szSetting,LPARAM lParam) +{ + return enumModulesSettingsProc(szSetting,0,lParam); +} + + +int EnumSettings(HANDLE hContact, char* module, ModuleSettingLL *msll) +{ + DBCONTACTENUMSETTINGS dbces; + // enum all setting the contact has for the module + dbces.pfnEnumProc = enumSettingsProc; + dbces.szModule = module; + dbces.lParam = (LPARAM)msll; + msll->first = 0; + msll->last = 0; + return !CallService(MS_DB_CONTACT_ENUMSETTINGS, (WPARAM)hContact,(LPARAM)&dbces); +} + +int CheckIfModuleIsEmptyProc(const char *szSetting,LPARAM lParam) +{ + return 1; +} + +int IsModuleEmpty(HANDLE hContact, char* szModule) +{ + DBCONTACTENUMSETTINGS dbces; + int retVal; + dbces.pfnEnumProc = CheckIfModuleIsEmptyProc; + dbces.szModule = szModule; + retVal = CallService(MS_DB_CONTACT_ENUMSETTINGS, (WPARAM)hContact,(LPARAM)&dbces); + if (retVal >= 0) + return 0; + else return 1; +} \ No newline at end of file diff --git a/plugins/DbEditorPP/src/modsettingenum.h b/plugins/DbEditorPP/src/modsettingenum.h new file mode 100644 index 0000000000..0ef32f8cc5 --- /dev/null +++ b/plugins/DbEditorPP/src/modsettingenum.h @@ -0,0 +1,17 @@ +struct ModSetLinkLinkItem { + char *name; + BYTE *next; //struct ModSetLinkLinkItem + int known; +}; + +typedef struct { + struct ModSetLinkLinkItem *first; + struct ModSetLinkLinkItem *last; +} ModuleSettingLL; + +int EnumModules(ModuleSettingLL *msll); +int EnumSettings(HANDLE hContact, char* module, ModuleSettingLL *msll); + +void FreeModuleSettingLL(ModuleSettingLL *msll); + +int IsModuleEmpty(HANDLE hContact, char* szModule); \ No newline at end of file diff --git a/plugins/DbEditorPP/src/modules.cpp b/plugins/DbEditorPP/src/modules.cpp new file mode 100644 index 0000000000..4053180038 --- /dev/null +++ b/plugins/DbEditorPP/src/modules.cpp @@ -0,0 +1,109 @@ +#include "headers.h" + + +void renameModule(char* oldName, char* newName, HANDLE hContact) +{ + DBVARIANT dbv; + ModuleSettingLL settinglist; + struct ModSetLinkLinkItem *setting; + + if (!EnumSettings(hContact,oldName,&settinglist)) { msg(Translate("Error Loading Setting List"),modFullname); return;} + + setting = settinglist.first; + while (setting) + { + if (!GetSetting(hContact,oldName,setting->name,&dbv)) + { + switch (dbv.type) + { + case DBVT_BYTE: + DBWriteContactSettingByte(hContact, newName, setting->name, dbv.bVal); + break; + case DBVT_WORD: + DBWriteContactSettingWord(hContact, newName, setting->name, dbv.wVal); + break; + case DBVT_DWORD: + DBWriteContactSettingDword(hContact, newName, setting->name, dbv.dVal); + break; + case DBVT_ASCIIZ: + DBWriteContactSettingString(hContact, newName, setting->name, dbv.pszVal); + break; + case DBVT_UTF8: + DBWriteContactSettingStringUtf(hContact, newName, setting->name, dbv.pszVal); + break; + case DBVT_BLOB: + DBWriteContactSettingBlob(hContact, newName, setting->name, dbv.pbVal, dbv.cpbVal); + break; + + } + DBDeleteContactSetting(hContact, oldName, setting->name); + } + DBFreeVariant(&dbv); + setting = (struct ModSetLinkLinkItem *)setting->next; + } + FreeModuleSettingLL(&settinglist); +} + +INT_PTR CALLBACK AddModDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg == WM_INITDIALOG) + { + SetWindowLongPtr(hwnd,GWLP_USERDATA,lParam); + TranslateDialogDefault(hwnd); + } + if (msg == WM_COMMAND) + { + switch(LOWORD(wParam)) + { + case IDOK: + { + if (GetWindowTextLength(GetDlgItem(hwnd, IDC_MODNAME))) + { + char modulename[256]; + GetDlgItemText(hwnd, IDC_MODNAME, modulename, 256); + if (IsDlgButtonChecked(hwnd,CHK_ADD2ALL)) + { + HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + // null contact + DBWriteContactSettingByte(NULL, modulename, "(Default)", 0); + while (hContact) + { + DBWriteContactSettingByte(hContact, modulename, "(Default)", 0); + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)(HANDLE)hContact, 0); + } + } + else + { + DBWriteContactSettingByte((HANDLE)GetWindowLongPtr(hwnd,GWLP_USERDATA), modulename, "(Default)", 0); + } + refreshTree(1); + } + } + // fall through + case IDCANCEL: + DestroyWindow(hwnd); + break; + } + } + return 0; +} + +int CloneContact(HANDLE hContact) +{ + HANDLE newContact = (HANDLE)CallService(MS_DB_CONTACT_ADD,0,0); + + ModuleSettingLL modlist; + struct ModSetLinkLinkItem *mod; + if (!newContact) return 0; + // enum all the modules + if (!EnumModules(&modlist)) { msg(Translate("Error Loading Module List"),modFullname); return 0;} + + mod = modlist.first; + while (mod) + { + copyModule(mod->name,hContact,newContact); + mod = (struct ModSetLinkLinkItem *)mod->next; + } + FreeModuleSettingLL(&modlist); + return 1; +} \ No newline at end of file diff --git a/plugins/DbEditorPP/src/moduletree.cpp b/plugins/DbEditorPP/src/moduletree.cpp new file mode 100644 index 0000000000..b5554cabc5 --- /dev/null +++ b/plugins/DbEditorPP/src/moduletree.cpp @@ -0,0 +1,1132 @@ +#include "headers.h" + +static BOOL populating = 0; +int Select = 0; +static ModuleTreeInfoStruct contacts_mtis = {CONTACT_ROOT_ITEM, 0}; +static ModuleTreeInfoStruct settings_mtis = {CONTACT, 0}; + + +int doContacts(HWND hwnd2Tree,HTREEITEM contactsRoot,ModuleSettingLL *modlist, HANDLE hSelectedContact, char *SelectedModule, char *SelectedSetting) +{ + TVINSERTSTRUCT tvi; + char szProto[256]; + HANDLE hContact; + HTREEITEM contact; + ModuleTreeInfoStruct *lParam; + struct ModSetLinkLinkItem *module; + int count = CallService(MS_DB_CONTACT_GETCOUNT, 0, 0); + int itemscount = 0; + int loaded, i = 0, icon = 0; + HWND hwnd = GetParent(hwnd2Tree); + int hItem = -1; + +// char percent[96], title[64]; +// mir_snprintf(title, sizeof(title),Translate("Loading contacts...")); + SetWindowText(hwnd2mainWindow, Translate("Loading contacts...")); + + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + + tvi.hInsertAfter = TVI_SORT; + tvi.item.cChildren = 1; + + while (hContact && hwnd2mainWindow) // break after null contact + { + + if (GetValue(hContact,"Protocol","p",szProto,SIZEOF(szProto))) + { + icon = GetProtoIcon(szProto); + loaded = (icon != DEF_ICON); + } + else + { + icon = DEF_ICON; + loaded = 0; + } + + i++; + + // filter + if ((loaded && Mode == MODE_UNLOADED) || (!loaded && Mode == MODE_LOADED)) + { + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + continue; + } + + // Caption +// mir_snprintf(percent,sizeof(percent),"%s %d%%",title,(int)(100*i/count)); +// SetWindowText(hwnd2mainWindow, percent); + + // add the contact + lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct)); + lParam->hContact = hContact; + lParam->type = CONTACT; + tvi.item.mask = TVIF_TEXT|TVIF_CHILDREN|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE; + tvi.item.lParam = (LPARAM)lParam; + tvi.hParent = contactsRoot; + + if (hSelectedContact != hContact) + lParam->type |= EMPTY; + + // contacts name + if (UOS) + { + DBVARIANT dbv ={0}; + WCHAR nick[256]; + WCHAR protoW[256]; // unicode proto + + if (szProto[0]) + a2u(szProto, protoW, SIZEOF(protoW)); + else + protoW[0] = 0; + + if (!szProto[0] || !loaded) + { + tvi.item.iSelectedImage = (tvi.item.iImage = 4); + + if (protoW) + { + if (Order) + mir_snwprintf(nick, SIZEOF(nick), L"(%s) %s %s", protoW, GetContactName(hContact, szProto, 1), L"(UNLOADED)"); + else + mir_snwprintf(nick, SIZEOF(nick), L"%s (%s) %s", GetContactName(hContact, szProto, 1), protoW, L"(UNLOADED)"); + } + else + wcscpy(nick, nick_unknownW); + } + else + { + tvi.item.iSelectedImage = (tvi.item.iImage = icon); //GetProtoIcon(szProto, 7)); + if (Order) + mir_snwprintf(nick, SIZEOF(nick), L"(%s) %s", protoW, GetContactName(hContact, szProto, 1)); + else + mir_snwprintf(nick, SIZEOF(nick), L"%s (%s)", GetContactName(hContact, szProto, 1), protoW); + } + + tvi.item.pszText = (char*)nick; + contact = TreeView_InsertItemW(hwnd2Tree, &tvi); + } + else + { + char nick[256]; + + if (!szProto[0] || !loaded) + { + tvi.item.iSelectedImage = (tvi.item.iImage = 4); + + if (szProto[0]) + { + if (Order) + mir_snprintf(nick, SIZEOF(nick), "(%s) %s %s", szProto, (char*)GetContactName(hContact, szProto, 0), "(UNLOADED)"); + else + mir_snprintf(nick, SIZEOF(nick), "%s (%s) %s", (char*)GetContactName(hContact, szProto, 0), szProto, "(UNLOADED)"); + } + else + strcpy(nick, nick_unknown); + } + else + { + tvi.item.iSelectedImage = (tvi.item.iImage = icon); //GetProtoIcon(szProto, 7)); + if (Order) + mir_snprintf(nick, SIZEOF(nick), "(%s) %s", szProto, (char*)GetContactName(hContact, szProto, 0)); + else + mir_snprintf(nick, SIZEOF(nick), "%s (%s)", (char*)GetContactName(hContact, szProto, 0), szProto); + } + + tvi.item.pszText = nick; + contact = TreeView_InsertItem(hwnd2Tree, &tvi); + } + + itemscount++; + + if (hSelectedContact == hContact) + { + + module = modlist->first; + while(module && hwnd2mainWindow) + { + if (module->name[0] && !IsModuleEmpty(hContact,module->name)) + { + tvi.hParent = contact; + tvi.hInsertAfter = TVI_SORT; + tvi.item.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM; + tvi.item.pszText = module->name; + + lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct)); + lParam->hContact = hContact; + + if (!module->known) + { + tvi.item.iImage = 5; + tvi.item.iSelectedImage = 6; + lParam->type = UNKNOWN_MODULE; + } + else + { + tvi.item.iImage = 1; + tvi.item.iSelectedImage = 2; + lParam->type = KNOWN_MODULE; + } + + tvi.item.lParam = (LPARAM)lParam; + TreeView_InsertItem(hwnd2Tree, &tvi); + } + module = (struct ModSetLinkLinkItem *)module->next; + } + + hItem = findItemInTree(hwnd2Tree, hSelectedContact, SelectedModule); + + } + + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + } + + + if (hItem != -1) + { + TreeView_SelectItem(hwnd2Tree, (HTREEITEM)hItem); + TreeView_Expand(hwnd2Tree,hItem,TVE_EXPAND); + if (SelectedSetting[0]) SelectSetting(SelectedSetting); + } + +// if (UOS) +// SetWindowText(hwnd, Translate("Database Editor++ (unicode mode)")); +// else +// SetWindowText(hwnd, Translate("Database Editor++ (ansi mode)")); + + + return itemscount; +} + + + +void doItems(HWND hwnd2Tree,ModuleSettingLL *modlist, int count) +{ + TVINSERTSTRUCT tvi; + TVITEM item ={0}; + HANDLE hContact; + HTREEITEM contact; + ModuleTreeInfoStruct *lParam; + struct ModSetLinkLinkItem *module; + char percent[96], title[64]; + HWND hwnd = GetParent(hwnd2Tree); + int i = 0; + + mir_snprintf(title, SIZEOF(title), Translate("Loading modules...")); + + item.mask = TVIF_STATE|TVIF_PARAM; + + contact = TreeView_GetChild( hwnd2Tree, TVI_ROOT ); + contact = TreeView_GetNextSibling(hwnd2Tree, contact); + contact = TreeView_GetChild(hwnd2Tree, contact); + + while (contact && hwnd2mainWindow) + { + i++; + item.hItem = contact; + contact = TreeView_GetNextSibling(hwnd2Tree, contact); + + if (TreeView_GetItem( hwnd2Tree, &item ) && + item.lParam) // && item.state != TVE_EXPAND) + { + ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)item.lParam; + hContact = mtis->hContact; + if (hContact == NULL || mtis->type != (CONTACT|EMPTY)) + continue; + else + mtis->type = CONTACT; + } + else continue; + + // Caption + mir_snprintf(percent, SIZEOF(percent), "%s %d%%", title, (int)(100*i/count)); + SetWindowText(hwnd, percent); + + module = modlist->first; + while(module && hwnd2mainWindow) + { + if (module->name[0] && !IsModuleEmpty(hContact,module->name)) + { + tvi.hParent = item.hItem; + tvi.hInsertAfter = TVI_SORT; + tvi.item.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM; + tvi.item.pszText = module->name; + + lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct)); + lParam->hContact = hContact; + + if (!module->known) + { + tvi.item.iImage = 5; + tvi.item.iSelectedImage = 6; + lParam->type = UNKNOWN_MODULE; + } + else + { + tvi.item.iImage = 1; + tvi.item.iSelectedImage = 2; + lParam->type = KNOWN_MODULE; + } + + tvi.item.lParam = (LPARAM)lParam; + TreeView_InsertItem(hwnd2Tree, &tvi); + } + module = (struct ModSetLinkLinkItem *)module->next; + } + + } + + if (UOS) + SetWindowText(hwnd, Translate("Database Editor++ (unicode mode)")); + else + SetWindowText(hwnd, Translate("Database Editor++ (ansi mode)")); + + +} + + +int findItemInTree(HWND hwnd2Tree, HANDLE hContact, char* module) +/* the following code to go through the whole tree is nicked from codeguru.. +http://www.codeguru.com/Cpp/controls/treeview/treetraversal/comments.php/c683/?thread=7680 */ +{ + TVITEM item; + char text[265]; + HTREEITEM lastItem; + if (!TreeView_GetCount(hwnd2Tree)) return 0; + + item.mask = TVIF_STATE|TVIF_PARAM|TVIF_TEXT; + item.hItem = TVI_ROOT; + item.pszText = text; + item.cchTextMax = 264; + do + { + do + { + lastItem = item.hItem; + if (lastItem != TVI_ROOT) + { +/* these next 2 lines are not from code guru..... */ + if (TreeView_GetItem( hwnd2Tree, &item) && item.lParam) + { + if ((hContact == ((ModuleTreeInfoStruct *)item.lParam)->hContact) && (!module[0] || !mir_strcmp(module,text))) + { + //TreeView_SelectItem(hwnd2Tree,item.hItem); + return (int)item.hItem; + } + } +/* back to coduguru's code*/ + } + } while ( (item.hItem = TreeView_GetChild( hwnd2Tree, lastItem ))); + while ( (! (item.hItem = TreeView_GetNextSibling( hwnd2Tree, lastItem ))) && (lastItem = item.hItem = TreeView_GetParent( hwnd2Tree, lastItem ))) {} + + } while ( item.hItem ); +/*****************************************************************************/ + + return -1; +} + +void freeTree(HWND hwnd2Tree, HANDLE hContact) +/* the following code to go through the whole tree is nicked from codeguru.. +http://www.codeguru.com/Cpp/controls/treeview/treetraversal/comments.php/c683/?thread=7680 */ +{ + TVITEM item; + HTREEITEM lastItem; + if (!TreeView_GetCount(hwnd2Tree)) return; + + item.mask = TVIF_STATE|TVIF_PARAM; + item.hItem = TVI_ROOT; + do + { + do + { + lastItem = item.hItem; + if (lastItem != TVI_ROOT) + { + TreeView_GetItem( hwnd2Tree, &item ); +/* these next 2 lines are not from code guru..... */ + if (item.lParam) + { + ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)item.lParam; + + if (!hContact || (hContact == mtis->hContact)) + { + if (hContact != NULL) { + TreeView_DeleteItem(hwnd2Tree,item.hItem); + mir_free(mtis); + } else + mtis->type = STUB; + } + } +/* back to coduguru's code*/ + } + } while ( (item.hItem = TreeView_GetChild( hwnd2Tree, lastItem ))); + while ( (! (item.hItem = TreeView_GetNextSibling( hwnd2Tree, lastItem ))) && (lastItem = item.hItem = TreeView_GetParent( hwnd2Tree, lastItem ))) {} + + } while ( item.hItem ); +/*****************************************************************************/ +} + +BOOL findAndRemoveDuplicates(HWND hwnd2Tree, HANDLE hContact, char* module) +/* the following code to go through the whole tree is nicked from codeguru.. +http://www.codeguru.com/Cpp/controls/treeview/treetraversal/comments.php/c683/?thread=7680 */ +{ + TVITEM item; + HTREEITEM lastItem, prelastItem; + BOOL Result = 0; + char text[265]; + if (!TreeView_GetCount(hwnd2Tree)) return Result; + + item.mask = TVIF_STATE|TVIF_PARAM|TVIF_TEXT; + item.hItem = TVI_ROOT; + item.pszText = text; + item.cchTextMax = 264; + prelastItem = item.hItem; + + do + { + do + { + lastItem = item.hItem; + if (lastItem != TVI_ROOT) + { + TreeView_GetItem( hwnd2Tree, &item ); +/* these next lines are not from code guru..... */ + if (item.lParam) + { + ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)item.lParam; + if (hContact == mtis->hContact && !mir_strcmp(text,module)) + { + mir_free(mtis); + TreeView_DeleteItem(hwnd2Tree,item.hItem); + lastItem = prelastItem; + Result = 1; + } + else + prelastItem = lastItem; + } +/* back to coduguru's code*/ + } + } while ( (item.hItem = TreeView_GetChild( hwnd2Tree, lastItem ))); + while ( (! (item.hItem = TreeView_GetNextSibling( hwnd2Tree, lastItem ))) && (lastItem = item.hItem = TreeView_GetParent( hwnd2Tree, lastItem ))) {} + + } while ( item.hItem ); +/*****************************************************************************/ + + return Result; +} + + +void replaceTreeItem(HWND hwnd, HANDLE hContact, const char *module, const char *newModule) +{ + int hItem = findItemInTree(hwnd, hContact, (char*)module); + HTREEITEM hParent; + + if (hItem == -1) return; + + hParent = TreeView_GetParent(hwnd,(HTREEITEM)hItem); + + { + TVITEM item; + item.mask = TVIF_PARAM; + item.hItem = (HTREEITEM)hItem; + + if (TreeView_GetItem(hwnd, &item)) + mir_free((ModuleTreeInfoStruct *)item.lParam); + TreeView_DeleteItem(hwnd,item.hItem); + } + + if (hParent && newModule) + { + TVINSERTSTRUCT tvi = {0}; + ModuleTreeInfoStruct *lParam; + + tvi.hParent = hParent; + tvi.hInsertAfter = TVI_SORT; + tvi.item.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM; + tvi.item.pszText = (char*)newModule; + + lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct)); + lParam->hContact = hContact; + lParam->type = IsModuleKnown((char*)newModule)?KNOWN_MODULE:UNKNOWN_MODULE; + if (lParam->type == UNKNOWN_MODULE) + { + tvi.item.iImage = 5; + tvi.item.iSelectedImage = 6; + } + else + { + tvi.item.iImage = 1; + tvi.item.iSelectedImage = 2; + } + + tvi.item.lParam = (LPARAM)lParam; + + TreeView_InsertItem(hwnd, &tvi); + } +} + +void refreshTree(int restore) +{ + UseKnownModList = DBGetContactSettingByte(NULL,modname,"UseKnownModList",0); + if (populating) return; + populating = 1; + forkthread(PopulateModuleTreeThreadFunc,0,(HWND)restore); +} + +void __cdecl PopulateModuleTreeThreadFunc(LPVOID di) +{ + TVINSERTSTRUCT tvi; + HWND hwnd2Tree = GetDlgItem(hwnd2mainWindow,IDC_MODULES); + char SelectedModule[256] = {0}; + char SelectedSetting[256] = {0}; + HANDLE hSelectedContact = hRestore; + HANDLE hContact; + HTREEITEM contact, contactsRoot; + int count; + + // item lParams + ModuleTreeInfoStruct *lParam; + + // module list + struct ModSetLinkLinkItem *module; + ModuleSettingLL modlist; + + hRestore = NULL; + + if (!hwnd2Tree) { msg(Translate("Module tree not found"),modFullname); return;} + + Select = 0; + + switch((int)di) { + case 1: // restore after rebuild + { + HTREEITEM item; + if (item = TreeView_GetSelection(hwnd2Tree)) + { + TVITEM tvi = {0}; + + tvi.mask=TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT; + tvi.pszText = SelectedModule; + tvi.cchTextMax = 255; + tvi.hItem=item; + + TreeView_GetItem(hwnd2Tree, &tvi); + if (tvi.lParam) + { + ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)tvi.lParam; + hSelectedContact = mtis->hContact; + if (mtis->type == CONTACT) SelectedModule[0] = 0; + Select = 1; + } + } + break; + } + case 2: // restore saved + if (GetValue(NULL,modname,"LastModule",SelectedModule,SIZEOF(SelectedModule))) + { + hSelectedContact = (HANDLE)DBGetContactSettingDword(NULL,modname,"LastContact",(DWORD)INVALID_HANDLE_VALUE); + if (hSelectedContact != INVALID_HANDLE_VALUE) + Select = 1; + GetValue(NULL,modname,"LastSetting",SelectedSetting,SIZEOF(SelectedSetting)); + } + break; + case 3: // restore from user menu + case 4: // jump from user menu + { + if (hSelectedContact && hSelectedContact != INVALID_HANDLE_VALUE) + { + Select = 1; + } + break; + } + } // switch + + if ((int)di != 4) // do not rebuild on just going to another setting + { + + if (!EnumModules(&modlist)) { msg(Translate("Error Loading Module List"),modFullname); return;} + + // remove all items (incase there are items there... + freeTree(hwnd2Tree,0); + TreeView_DeleteAllItems(hwnd2Tree); + TreeView_SelectItem(hwnd2Tree,0); + + //image list + TreeView_SetImageList(hwnd2Tree, himl, TVSIL_NORMAL); + + /// contact root item + contacts_mtis.type = CONTACT_ROOT_ITEM; + tvi.item.lParam = (LPARAM)&contacts_mtis; + tvi.hParent = NULL; + tvi.item.mask = TVIF_TEXT|TVIF_CHILDREN|TVIF_STATE|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE; + tvi.item.state = TVIS_BOLD; + tvi.item.stateMask = TVIS_BOLD; + tvi.item.cChildren = 1; + tvi.hInsertAfter = TVI_FIRST; + + tvi.item.pszText = Translate("Contacts"); + tvi.item.iImage = 3; + tvi.item.iSelectedImage = 3; + contactsRoot = TreeView_InsertItem(hwnd2Tree, &tvi); + + // add the settings item + settings_mtis.type = STUB; + tvi.item.lParam = (LPARAM)&settings_mtis; + tvi.item.mask = TVIF_TEXT|TVIF_CHILDREN|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE; + tvi.item.cChildren = 1; + tvi.hParent = NULL; + tvi.hInsertAfter = TVI_FIRST; + tvi.item.pszText = Translate("Settings"); + tvi.item.iSelectedImage = (tvi.item.iImage = 0); + contact = TreeView_InsertItem(hwnd2Tree, &tvi); + + // to fix bug with CHANGE NOTIFY on window activation + TreeView_SelectItem(hwnd2Tree, contact); + settings_mtis.type = CONTACT; + + hContact = 0; + module = modlist.first; + while (module) + { + // set the module status type for the icon + module->known = IsModuleKnown(module->name); + + if (!IsModuleEmpty(hContact,module->name)) + { + tvi.hParent = contact; + tvi.hInsertAfter = TVI_SORT; + tvi.item.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM; + tvi.item.pszText = module->name; + + lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct)); + lParam->hContact = hContact; + if (!module->known) + { + tvi.item.iImage = 5; + tvi.item.iSelectedImage = 6; + lParam->type = UNKNOWN_MODULE; + } + else + { + tvi.item.iImage = 1; + tvi.item.iSelectedImage = 2; + lParam->type = KNOWN_MODULE; + } + + tvi.item.lParam = (LPARAM)lParam; + + TreeView_InsertItem(hwnd2Tree, &tvi); + } + module = (struct ModSetLinkLinkItem *)module->next; + } + + if (DBGetContactSettingByte(NULL,modname,"ExpandSettingsOnOpen",0)) + TreeView_Expand(hwnd2Tree,contact,TVE_EXPAND); + + if (Select && hSelectedContact == NULL) + { + int hItem = findItemInTree(hwnd2Tree, hSelectedContact, SelectedModule); + if (hItem != -1) + { + TreeView_SelectItem(hwnd2Tree, (HTREEITEM)hItem); + TreeView_Expand(hwnd2Tree,hItem,TVE_EXPAND); + if (SelectedSetting[0]) SelectSetting(SelectedSetting); + } + Select = 0; + } + + count = doContacts(hwnd2Tree,contactsRoot,&modlist, Select?hSelectedContact:NULL, SelectedModule, SelectedSetting); + Select = 0; + doItems(hwnd2Tree,&modlist,count); + + FreeModuleSettingLL(&modlist); + } + + if (Select) + { + int hItem = findItemInTree(hwnd2Tree, hSelectedContact, SelectedModule); + if (hItem != -1) + { + TreeView_SelectItem(hwnd2Tree, (HTREEITEM)hItem); + TreeView_Expand(hwnd2Tree,hItem,TVE_EXPAND); + if (SelectedSetting[0]) SelectSetting(SelectedSetting); + } + } + + populating = 0; + +} + + +static WNDPROC ModuleTreeLabelEditSubClass; + +static LRESULT CALLBACK ModuleTreeLabelEditSubClassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) +{ + switch(msg) { + case WM_KEYUP: + switch (wParam) + { + case VK_RETURN: + TreeView_EndEditLabelNow(GetParent(hwnd),0); + return 0; + case VK_ESCAPE: + TreeView_EndEditLabelNow(GetParent(hwnd),1); + return 0; + } + break; + } + return CallWindowProc(ModuleTreeLabelEditSubClass,hwnd,msg,wParam,lParam); +} +void moduleListRightClick(HWND hwnd, WPARAM wParam,LPARAM lParam); + +void moduleListWM_NOTIFY(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)// hwnd here is to the main window, NOT the treview +{ + switch(((NMHDR*)lParam)->code) + { + case TVN_ITEMEXPANDINGA: + case TVN_ITEMEXPANDINGW: + if (populating && ((LPNMTREEVIEW)lParam)->action == TVE_EXPAND) + { + ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)((LPNMTREEVIEW)lParam)->itemNew.lParam; + if (mtis && (mtis->type == (CONTACT | EMPTY))) + { + TVINSERTSTRUCT tvi; + HTREEITEM item = {0}; + ModuleTreeInfoStruct *_lParam; + HWND hwnd2Tree = GetDlgItem(hwnd2mainWindow,IDC_MODULES); + struct ModSetLinkLinkItem *module; + ModuleSettingLL modlist; + HANDLE hContact = mtis->hContact; + + mtis->type = CONTACT; + + if (!EnumModules(&modlist)) { msg(Translate("Error Loading Module List"),modFullname); break;} + + module = modlist.first; + while(module && hwnd2mainWindow) + { + if (module->name[0] && !IsModuleEmpty(hContact,module->name)) + { + tvi.hParent = ((LPNMTREEVIEW)lParam)->itemNew.hItem; + tvi.hInsertAfter = TVI_SORT; + tvi.item.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM; + tvi.item.pszText = module->name; + + _lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct)); + _lParam->hContact = hContact; + + if (IsModuleKnown(module->name)) + { + tvi.item.iImage = 5; + tvi.item.iSelectedImage = 6; + _lParam->type = KNOWN_MODULE; + } + else + { + tvi.item.iImage = 1; + tvi.item.iSelectedImage = 2; + _lParam->type = UNKNOWN_MODULE; + } + + tvi.item.lParam = (LPARAM)_lParam; + TreeView_InsertItem(hwnd2Tree, &tvi); + } + module = (struct ModSetLinkLinkItem *)module->next; + } + + FreeModuleSettingLL(&modlist); + } + + } + break; + + case TVN_SELCHANGEDA: + case TVN_SELCHANGEDW: + { + ModuleTreeInfoStruct *mtis; + LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; + TVITEM tvi = {0}; + char text[264]; + HANDLE hContact; + HWND hwnd2Settings = GetDlgItem(hwnd, IDC_SETTINGS); + tvi.mask = TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT; + tvi.hItem = pnmtv->itemNew.hItem; + tvi.pszText = text; + tvi.cchTextMax = 264; + TreeView_GetItem(pnmtv->hdr.hwndFrom,&tvi); + + if (tvi.lParam) + { + mtis = (ModuleTreeInfoStruct *)tvi.lParam; + hContact = mtis->hContact; + + if (mtis->type == STUB) break; + + if (populating) Select = 0; + + if (mtis->type == MODULE || mtis->type == UNKNOWN_MODULE) + { + SettingListInfo *info = (SettingListInfo*)GetWindowLongPtr(hwnd2Settings,GWLP_USERDATA); + BOOL refresh = 1; + + if (info) + { + if (info->hContact == hContact && + !mir_strcmp(info->module, text)) + refresh = 0; + } + + if (refresh) + PopulateSettings(hwnd2Settings, hContact, text); + } + else + if (((mtis->type & CONTACT) == CONTACT && hContact) || + (mtis->type == CONTACT_ROOT_ITEM && !hContact)) + { + char data[32], szProto[256]; + int index, loaded, multi = 0; + LVITEM lvi = {0}; + lvi.mask = LVIF_IMAGE|LVIF_TEXT|LVIF_PARAM; + lvi.iImage = 6; + + ClearListview(hwnd2Settings); + SetWindowLongPtr(hwnd2Settings,GWLP_USERDATA, (LONG)NULL); + if (himl2) ListView_SetImageList(hwnd2Settings, himl2, LVSIL_SMALL); + + if (mtis->type == CONTACT_ROOT_ITEM && !hContact) + { + multi = 1; + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + } + + while(hContact && hwnd2mainWindow) + { + if (multi) + { + // filter + if (GetValue(hContact,"Protocol","p",szProto,SIZEOF(szProto))) + loaded = IsProtocolLoaded(szProto); + else + loaded = 0; + + if ((loaded && Mode == MODE_UNLOADED) || (!loaded && Mode == MODE_LOADED)) + { + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + continue; + } + } + + lvi.iItem = 0; + lvi.pszText = (char*)GetContactName(hContact,NULL,UOS); + + if (UOS) + index = ListView_InsertItemW(hwnd2Settings,&lvi); + else + index = ListView_InsertItem(hwnd2Settings,&lvi); + + mir_snprintf(data, SIZEOF(data), "0x%08X (%ld)", hContact, hContact); + + ListView_SetItemText(hwnd2Settings,index,1,data); + ListView_SetItemText(hwnd2Settings,index,2,Translate("HANDLE")); + ListView_SetItemText(hwnd2Settings,index,3,"0x0004 (4)"); + + if (!multi) break; + + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + } + + } + else + ClearListview(hwnd2Settings); + } + else + { + // clear any settings that may be there... + ClearListview(hwnd2Settings); + } + } + break; //TVN_SELCHANGED: + case NM_RCLICK: + if (((NMHDR*)lParam)->code == NM_RCLICK) + moduleListRightClick(hwnd,wParam,lParam); + break; + case TVN_BEGINLABELEDITA: // subclass it.. + case TVN_BEGINLABELEDITW: + { + LPNMTVDISPINFO ptvdi = (LPNMTVDISPINFO) lParam; + ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)ptvdi->item.lParam; + HWND hwnd2Edit = TreeView_GetEditControl(GetDlgItem(hwnd, IDC_MODULES)); + if (!mtis->type || (mtis->type == CONTACT)) + { + SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE); + break; + } + ModuleTreeLabelEditSubClass = (WNDPROC)SetWindowLongPtr(hwnd2Edit, GWLP_WNDPROC, (LONG)ModuleTreeLabelEditSubClassProc); + SetWindowLongPtr(hwnd, DWLP_MSGRESULT, FALSE); + } + break; + case TVN_ENDLABELEDITA: + case TVN_ENDLABELEDITW: + { + LPNMTVDISPINFO ptvdi = (LPNMTVDISPINFO) lParam; + TVITEM tvi = {0}; + char text[264]; + char *newtext; + ModuleTreeInfoStruct *mtis; + tvi.mask=TVIF_HANDLE|TVIF_TEXT|TVIF_PARAM; + tvi.hItem=ptvdi->item.hItem; + tvi.pszText = text; + tvi.cchTextMax = 264; + TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom,&tvi); + mtis = (ModuleTreeInfoStruct *)ptvdi->item.lParam; + + if (UOS) + newtext = u2a((WCHAR*)ptvdi->item.pszText); + else + newtext = mir_tstrdup(ptvdi->item.pszText); + + if (!newtext || // edit control failed + !mtis->type || // its a root item + mtis->type == CONTACT || // its a contact + *newtext == 0) // empty string + SetWindowLongPtr(hwnd, DWLP_MSGRESULT, FALSE); + else + { + if (mir_strcmp(tvi.pszText, newtext)) + { + renameModule(tvi.pszText, newtext, mtis->hContact); + + findAndRemoveDuplicates(((LPNMHDR)lParam)->hwndFrom,mtis->hContact,newtext); + + if (TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom,&tvi)) + { + tvi.mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE; + if (!IsModuleKnown(newtext)) + { + tvi.iImage = 5; + tvi.iSelectedImage = 6; + } + else + { + tvi.iImage = 1; + tvi.iSelectedImage = 2; + } + TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); + + PopulateSettings(GetDlgItem(hwnd, IDC_SETTINGS), mtis->hContact, newtext); + } + } + SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE); + } + + mir_free(newtext); + } + break; + } +} + +void moduleListRightClick(HWND hwnd, WPARAM wParam,LPARAM lParam) // hwnd here is to the main window, NOT the treview +{ + TVHITTESTINFO hti; + hti.pt.x=(short)LOWORD(GetMessagePos()); + hti.pt.y=(short)HIWORD(GetMessagePos()); + ScreenToClient(((LPNMHDR)lParam)->hwndFrom,&hti.pt); + + if(TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom,&hti)) + { + if(hti.flags&TVHT_ONITEM) + { + TVITEM tvi = {0}; + HMENU hMenu,hSubMenu; + int menuNumber; + char module[256]; + tvi.mask=TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT; + tvi.hItem=hti.hItem; + tvi.pszText = module; + tvi.cchTextMax = 255; + TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom,&tvi); + if (tvi.lParam) + { + ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)tvi.lParam; + HANDLE hContact = mtis->hContact; + GetCursorPos(&(hti.pt)); + hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXTMENU)); + TranslateMenu(hMenu); + if (mtis->type == CONTACT && hContact) menuNumber = 2; + else if ((mtis->type == MODULE || mtis->type == UNKNOWN_MODULE) && !hContact) menuNumber = 1; + else if (mtis->type == CONTACT && !hContact) menuNumber = 3; + else if (mtis->type == CONTACT_ROOT_ITEM && !hContact) menuNumber = 4; + else if ((mtis->type == MODULE || mtis->type == UNKNOWN_MODULE) && hContact) menuNumber = 5; + else return; + hSubMenu = GetSubMenu(hMenu, menuNumber); + + TranslateMenu(hSubMenu); + switch (menuNumber) + { + case 1: // null module + case 5: // contact module + { + // check if we r already watching the module + int i; + int watching = 0; + // check if the setting is being watched and if it is then check the menu item + if (WatchListArray.item) + for (i=0; ihwndFrom,hti.hItem); + mir_free(mtis); + } + break; + case MENU_COPY_MOD: + copyModuleMenuItem(module, hContact); + break; +////////////////////////////////////////////////////////////////////// divider + case MENU_WATCH_ITEM: + if (!watching) + addSettingToWatchList(hContact,module,0); + else freeWatchListItem(i); + if (hwnd2watchedVarsWindow) + PopulateWatchedWindow(GetDlgItem(hwnd2watchedVarsWindow, IDC_VARS)); + break; + case MENU_EXPORTMODULE: + exportDB(hContact, module); + break; + case MENU_EXPORTDB: + exportDB(INVALID_HANDLE_VALUE, module); + break; + case MENU_ADDKNOWN: + { + DBVARIANT dbv; + char *moduletemp = (char*)_alloca(strlen(module)*3); + unsigned int i; + moduletemp[0] = '\0'; + for(i=0;ihwndFrom,hContact); + TreeView_DeleteItem(((LPNMHDR)lParam)->hwndFrom,tvi.hItem); + } + } + else + { + CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact,0); + freeTree(((LPNMHDR)lParam)->hwndFrom,hContact); + TreeView_DeleteItem(((LPNMHDR)lParam)->hwndFrom,tvi.hItem); + } + break; +////////////////////////////////////////////////////////////////////// divider + case MENU_EXPORTCONTACT: + exportDB(hContact, 0); + break; + case MENU_IMPORTFROMTEXT: + ImportSettingsMenuItem(hContact); + break; + case MENU_IMPORTFROMFILE: + ImportSettingsFromFileMenuItem(hContact, ""); + break; +////////////////////////////////////////////////////////////////////// divider + case MENU_ADD_MODULE: + { + HWND AddModhwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_ADD_MODULE), hwnd, AddModDlgProc, (LPARAM)hContact); + char msg[1024]; + mir_snprintf(msg, SIZEOF(msg), Translate("Add module to contact \"%s\""), module); + SetWindowText(AddModhwnd, module); + } + break; + } + break; + case 3: // NULL contact + switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, hti.pt.x, hti.pt.y, 0, hwnd, NULL)) + { + case MENU_ADD_MODULE: + { + HWND AddModhwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_ADD_MODULE), hwnd, AddModDlgProc, (LPARAM)hContact); + char msg[1024]; + mir_snprintf(msg, SIZEOF(msg), Translate("Add module to contact \"%s\""), module); + SetWindowText(AddModhwnd, module); + } + break; + case MENU_EXPORTCONTACT: + exportDB(NULL, 0); + break; + case MENU_IMPORTFROMTEXT: + ImportSettingsMenuItem(NULL); + break; + case MENU_IMPORTFROMFILE: + ImportSettingsFromFileMenuItem(NULL, ""); + break; + } + break; + case 4: // Contacts root + switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, hti.pt.x, hti.pt.y, 0, hwnd, NULL)) + { + case MENU_EXPORTCONTACT: + exportDB(INVALID_HANDLE_VALUE, ""); + break; + case MENU_IMPORTFROMTEXT: + ImportSettingsMenuItem(NULL); + break; + case MENU_IMPORTFROMFILE: + ImportSettingsFromFileMenuItem(NULL, ""); + break; + } + break; + } + DestroyMenu(hMenu); + } + } // if (tvi.lParam) + } // if(hti.flags&TVHT_ONITEM) +} \ No newline at end of file diff --git a/plugins/DbEditorPP/src/options.cpp b/plugins/DbEditorPP/src/options.cpp new file mode 100644 index 0000000000..0630fa353c --- /dev/null +++ b/plugins/DbEditorPP/src/options.cpp @@ -0,0 +1,94 @@ +#include "headers.h" + +INT_PTR CALLBACK DlgProcOpts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + DBVARIANT dbv; + CheckDlgButton(hwnd,IDC_EXPANDSETTINGS,DBGetContactSettingByte(NULL,modname,"ExpandSettingsOnOpen",0)); + CheckDlgButton(hwnd,IDC_RESTORESETTINGS,DBGetContactSettingByte(NULL,modname,"RestoreOnOpen",1)); + CheckDlgButton(hwnd,IDC_USEKNOWNMODS,DBGetContactSettingByte(NULL,modname,"UseKnownModList",0)); + CheckDlgButton(hwnd,IDC_WARNONDEL,DBGetContactSettingByte(NULL,modname,"WarnOnDelete",1)); + CheckDlgButton(hwnd,IDC_MENU,DBGetContactSettingByte(NULL,modname,"UserMenuItem",0)); + CheckDlgButton(hwnd,IDC_POPUPS,usePopUps); + if (!DBGetContactSetting(NULL,modname,"CoreModules",&dbv) && dbv.type == DBVT_ASCIIZ) + SetDlgItemText(hwnd,IDC_MODULES,dbv.pszVal); + DBFreeVariant(&dbv); + SetDlgItemInt(hwnd,IDC_POPUPTIMEOUT,DBGetContactSettingWord(NULL,modname,"PopupDelay",4),0); + SendDlgItemMessage(hwnd, IDC_COLOUR, CPM_SETCOLOUR, 0, (LPARAM)DBGetContactSettingDword(NULL,modname,"PopupColour",RGB(255,0,0))); + TranslateDialogDefault(hwnd); + } + return TRUE; + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_RESTORESETTINGS: + case IDC_EXPANDSETTINGS: + case IDC_USEKNOWNMODS: + case IDC_MODULES: + case IDC_MENU: + case IDC_POPUPS: + case IDC_WARNONDEL: + case IDC_COLOUR: + case IDC_POPUPTIMEOUT: + SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); + break; + } + break; + case WM_NOTIFY: + switch(((LPNMHDR)lParam)->idFrom) + { + case 0: + switch (((LPNMHDR)lParam)->code) + { + case PSN_APPLY: + { + CLISTMENUITEM mi = {0}; + char mods[4096]; + DBWriteContactSettingByte(NULL,modname,"ExpandSettingsOnOpen",(BYTE)IsDlgButtonChecked(hwnd,IDC_EXPANDSETTINGS)); + DBWriteContactSettingByte(NULL,modname,"RestoreOnOpen",(BYTE)IsDlgButtonChecked(hwnd,IDC_RESTORESETTINGS)); + DBWriteContactSettingByte(NULL,modname,"WarnOnDelete",(BYTE)IsDlgButtonChecked(hwnd,IDC_WARNONDEL)); + DBWriteContactSettingByte(NULL,modname,"UserMenuItem",(BYTE)IsDlgButtonChecked(hwnd,IDC_MENU)); + DBWriteContactSettingByte(NULL,modname,"UseKnownModList",(BYTE)IsDlgButtonChecked(hwnd,IDC_USEKNOWNMODS)); + usePopUps = IsDlgButtonChecked(hwnd,IDC_POPUPS); + DBWriteContactSettingByte(NULL,modname,"UsePopUps",(BYTE)usePopUps); + if (GetDlgItemText(hwnd,IDC_MODULES,mods,4096)) + DBWriteContactSettingString(NULL,modname,"CoreModules",mods); + DBWriteContactSettingWord(NULL,modname,"PopupDelay",(WORD)GetDlgItemInt(hwnd,IDC_POPUPTIMEOUT,NULL,0)); + DBWriteContactSettingDword(NULL,modname,"PopupColour",(DWORD)SendDlgItemMessage(hwnd, IDC_COLOUR, CPM_GETCOLOUR, 0, 0)); + + mi.cbSize = sizeof(mi); + + if (!IsDlgButtonChecked(hwnd,IDC_MENU)) + mi.flags = CMIM_FLAGS | CMIF_HIDDEN; + else + mi.flags = CMIM_FLAGS; + + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) hUserMenu, (LPARAM) & mi); + + } + return TRUE; + } + break; + } + break; + } + return FALSE; +} + +INT OptInit(WPARAM wParam,LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp = { 0 }; + odp.cbSize = sizeof(odp); + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCE(IDD_OPTIONS); + odp.pszGroup = LPGEN("Services"); + odp.pszTitle = modFullname; + odp.pfnDlgProc = DlgProcOpts; + odp.flags = ODPF_BOLDGROUPS; + Options_AddPage(wParam, &odp); + + return 0; +} \ No newline at end of file diff --git a/plugins/DbEditorPP/src/resource.h b/plugins/DbEditorPP/src/resource.h new file mode 100644 index 0000000000..c32d146126 --- /dev/null +++ b/plugins/DbEditorPP/src/resource.h @@ -0,0 +1,157 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// +#define ICO_REGEDIT 1 +#define ICO_UNICODE 2 +#define ICO_DBE_BUTT 3 +#define ICO_REGUSER 4 +#define ICO_STRING 5 +#define ICO_BINARY 6 +#define ICO_DWORD 7 +#define ICO_BYTE 8 +#define ICO_WORD 9 +#define ICO_HANDLE 10 +#define IDD_MAIN 101 +#define IDR_MAINMENU 103 +#define IDR_CONTEXTMENU 104 +#define ICO_CONTACTS 106 +#define ICO_OFFLINE 107 +#define IDD_ADD_MODULE 108 +#define IDD_EDIT_SETTING 109 +#define IDD_WATCH_DIAG 110 +#define IDR_WATCHWINDOWMENU 112 +#define ICO_UNLOADED 115 +#define IDD_COPY_MOD 116 +#define IDD_IMPORT 118 +#define IDD_CHANGE_ARRAYSIZE 120 +#define IDD_FIND 121 +#define IDD_OPTIONS 122 +#define ICO_KNOWN 124 +#define ICO_KNOWNOPEN 125 +#define ICO_UNKNOWNOPEN 126 +#define ICO_UNKNOWN 127 +#define ICO_SETTINGS 128 +#define ICO_ONLINE 129 +#define IDC_MODULES 1000 +#define IDC_SETTINGS 1001 +#define IDC_MENU 1002 +#define IDC_MODNAME 1004 +#define CHK_ADD2ALL 1005 +#define IDC_MODNAME2 1005 +#define IDC_SETTINGNAME 1006 +#define IDC_SPLITTER 1006 +#define IDC_STRING 1007 +#define IDC_SETTINGNAME2 1007 +#define GRP_BASE 1008 +#define CHK_HEX 1009 +#define CHK_DECIMAL 1010 +#define IDC_SETTINGVALUE 1011 +#define GRP_TYPE 1012 +#define IDC_SETTINGVALUE2 1012 +#define CHK_BYTE 1013 +#define IDC_SETTINGVALUE3 1013 +#define CHK_WORD 1014 +#define CHK_DWORD 1015 +#define CHK_STRING 1016 +#define IDC_VARS 1017 +#define IDC_ADDMODNAMESTATIC 1020 +#define IDC_CONTACTS 1021 +#define CHK_COPY2ALL 1022 +#define IDC_TEXT 1025 +#define IDC_FIND 1026 +#define IDC_REPLACE 1027 +#define IDC_CASE_SENSITIVE 1027 +#define IDC_REQUIRED 1028 +#define IDC_ARRAYSIZE 1030 +#define IDC_CURRENTSIZE 1032 +#define IDC_INFOTEXT 1033 +#define IDC_CRLF 1035 +#define IDC_CASESENSITIVE 1040 +#define IDC_LIST 1041 +#define IDC_SEARCH 1042 +#define IDC_EXACT 1043 +#define IDC_EXPANDSETTINGS 1044 +#define IDC_USEKNOWNMODS 1045 +#define IDC_WARNONDEL 1047 +#define IDC_POPUPS 1048 +#define IDC_POPUPTIMEOUT 1049 +#define IDC_COLOUR 1050 +#define IDC_RESTORESETTINGS 1051 +#define IDC_BLOB 1052 +#define IDC_FOUND 1056 +#define IDC_SBAR 1057 +#define IDC_ENTIRELY 1058 +#define MENU_REFRESH_MODS 40001 +#define MENU_REFRESH_SETS 40002 +#define MENU_EXIT 40003 +#define MENU_CHANGE2UNICODE 40004 +#define MENU_ADD_UNICODE 40005 +#define MENU_RENAME_SET 40006 +#define MENU_EDIT_SET 40007 +#define MENU_CHANGE2BYTE 40008 +#define MENU_CHANGE2WORD 40009 +#define MENU_CHANGE2DWORD 40010 +#define MENU_CHANGE2STRING 40011 +#define MENU_DELETE_SET 40012 +#define MENU_DELETE_MOD 40013 +#define MENU_CREATE_MOD 40014 +#define MENU_VIEW_WATCHES 40016 +#define MENU_REMALL_WATCHES 40017 +#define MENU_ADD_WATCH 40018 +#define MENU_WATCH_ITEM 40018 +#define MENU_WATCH_MOD 40019 +#define MENU_ADD_BLOB 40020 +#define MENU_CLONE_CONTACT 40021 +#define MENU_DELETE_CONTACT 40022 +#define MENU_ADD_MODULE 40023 +#define MENU_ADD_BYTE 40024 +#define MENU_ADD_WORD 40025 +#define MENU_ADD_DWORD 40026 +#define MENU_ADD_STRING 40027 +#define MENU_SAVE_WATCHES 40028 +#define MENU_RENAME_MOD 40030 +#define MENU_COPY_MOD 40032 +#define MENU_USE_MODLIST 40033 +#define MENU_USE_POPUPS 40034 +#define MENU_SORT_ORDER 40035 +#define MENU_EXPORTDB 40036 +#define MENU_EXPORTMODULE 40037 +#define MENU_EXPORTCONTACT 40038 +#define MENU_SAVE_POSITION 40039 +#define MENU_IMPORTSETTINGS 40040 +#define MENU_ADDCONTACT 40041 +#define MENU_WARNONDEL 40042 +#define MENU_LOAD_WATCHES 40043 +#define MENU_WORD_HEX 40044 +#define MENU_DECRYPT 40045 +#define MENU_ENCRYPT 40046 +#define MENU_VIEWDECRYPT 40047 +#define MENU_VIEWENCRYPT 40048 +#define MENU_LOGTODISK 40049 +#define MENU_FINDANDREPLACE 40050 +#define MENU_FINDMODSETTING 40051 +#define MENU_DWORD_HEX 40052 +#define MENU_IMPORTFROMFILE 40053 +#define MENU_IMPORTFROMTEXT 40054 +#define MENU_CHANGEARRAYSIZE 40055 +#define MENU_OPTIONS 40056 +#define MENU_DELETE 40057 +#define MENU_REFRESH 40058 +#define MENU_ADDKNOWN 40059 +#define MENU_FILTER_ALL 40060 +#define MENU_FILTER_LOADED 40061 +#define MENU_FILTER_UNLOADED 40062 +#define MENU_BYTE_HEX 40063 +#define MENU_OPEN_OPTIONS 40064 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 131 +#define _APS_NEXT_COMMAND_VALUE 40065 +#define _APS_NEXT_CONTROL_VALUE 1059 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/DbEditorPP/src/settinglist.cpp b/plugins/DbEditorPP/src/settinglist.cpp new file mode 100644 index 0000000000..5fff4fed21 --- /dev/null +++ b/plugins/DbEditorPP/src/settinglist.cpp @@ -0,0 +1,1261 @@ +#include "headers.h" + +int UOS; + +void setupSettingsList(HWND hwnd2List) +{ + LVCOLUMN sLC; + + ListView_SetUnicodeFormat(hwnd2List, UOS); + + sLC.fmt = LVCFMT_LEFT; + ListView_SetExtendedListViewStyle(hwnd2List, 32|LVS_EX_SUBITEMIMAGES); //LVS_EX_FULLROWSELECT + sLC.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH; + + sLC.pszText = Translate("Name"); + sLC.cx = DBGetContactSettingWord(NULL, modname, "Column0width", 145); + ListView_InsertColumn(hwnd2List,0,&sLC); + sLC.pszText = Translate("Data"); + sLC.cx = DBGetContactSettingWord(NULL, modname, "Column1width", 145); + ListView_InsertColumn(hwnd2List,1,&sLC); + sLC.pszText = Translate("Type"); + sLC.cx = DBGetContactSettingWord(NULL, modname, "Column2width", 60); + ListView_InsertColumn(hwnd2List,2,&sLC); + sLC.pszText = Translate("Size"); + sLC.cx = DBGetContactSettingWord(NULL, modname, "Column3width", 80); + ListView_InsertColumn(hwnd2List,3,&sLC); +} + + +void saveListSettings(HWND hwnd2List) +{ + int i; + LVCOLUMN sLC = {0}; + char tmp[33]; tmp[32] = 0; + + sLC.mask = LVCF_WIDTH; + + for (i=0; i <= 3; i++) + if (ListView_GetColumn(hwnd2List,i,&sLC)) + { + mir_snprintf(tmp, SIZEOF(tmp), "Column%dwidth", i); + DBWriteContactSettingWord(NULL, modname, tmp, (WORD)sLC.cx); + } + +} + + +void ClearListview(HWND hwnd2Settings) +{ + SettingListInfo *info = (SettingListInfo*)GetWindowLongPtr(hwnd2Settings,GWLP_USERDATA); + if (info && ListView_GetItemCount(hwnd2Settings)) + { + mir_free(info->module); + if (info->hwnd2Edit) + { + SendMessage(info->hwnd2Edit,WM_COMMAND,MAKEWPARAM(IDCANCEL,0),0); + info->hwnd2Edit = NULL; + } + mir_free(info); + SetWindowLongPtr(hwnd2Settings,GWLP_USERDATA, 0); + } + ListView_DeleteAllItems(hwnd2Settings); +} + +void DeleteSettingsFromList(HWND hSettings, HANDLE hContact, char *module, char *setting) +{ + int count = ListView_GetSelectedCount(hSettings); + + if (!count) return; + else + if (count == 1) + { + DBDeleteContactSetting(hContact,module,setting); + } + else + { + int items = ListView_GetItemCount(hSettings); + int i = 0; + char text[256]; + + while(i")); + ListView_SetItemText(hwnd2Settings,index,2,Translate("UNICODE")); + ListView_SetItemText(hwnd2Settings,index,3,Translate("")); + } + else + ListView_DeleteItem(hwnd2Settings,index); + + DBFreeVariant(&dbv); + mir_free(data); +} + +void PopulateSettings(HWND hwnd2Settings, HANDLE hContact, char* module) +{ + SettingListInfo* info = (SettingListInfo*)mir_calloc(sizeof(SettingListInfo)); + LVITEM lvItem; + + struct ModSetLinkLinkItem *setting; + ModuleSettingLL setlist; + if (!EnumSettings(hContact,module,&setlist)) { msg(Translate("Error Loading Setting List"),modFullname); mir_free(info); return;} + + // clear any settings that may be there... + ClearListview(hwnd2Settings); + + info->hContact = hContact; + info->module = mir_tstrdup(module); + SetWindowLongPtr(hwnd2Settings,GWLP_USERDATA, (LONG)info); + + // icons + if (himl2) ListView_SetImageList(hwnd2Settings, himl2, LVSIL_SMALL); + + lvItem.mask = LVIF_TEXT; + lvItem.iItem = 0; + lvItem.iSubItem = 0; + setting = setlist.first; + + while (setting) + { + lvItem.pszText = setting->name; + additem(hwnd2Settings,hContact,module, setting->name, ListView_InsertItem(hwnd2Settings,&lvItem)); + setting = (struct ModSetLinkLinkItem *)setting->next; + } + + FreeModuleSettingLL(&setlist); +} + + +void SelectSetting(char* setting) +{ + LVITEM lvItem; + LVFINDINFO lvfi; + HWND hwnd2Settings = GetDlgItem(hwnd2mainWindow,IDC_SETTINGS); + + lvfi.flags = LVFI_STRING; + lvfi.psz = setting; + lvfi.vkDirection = VK_DOWN; + + lvItem.mask = LVIF_TEXT; + lvItem.iItem = ListView_FindItem(hwnd2Settings,-1,&lvfi); + if (lvItem.iItem != -1) + { + lvItem.mask = LVIF_STATE; + lvItem.state = LVIS_SELECTED | LVIS_FOCUSED; + lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED; + ListView_SetItem(hwnd2Settings,&lvItem); + } +} + +void settingChanged(HWND hwnd2Settings, HANDLE hContact, char* module, char* setting) +{ + LVITEM lvItem; + LVFINDINFO lvfi; + + lvfi.flags = LVFI_STRING; + lvfi.psz = setting; + lvfi.vkDirection = VK_DOWN; + + lvItem.mask = LVIF_TEXT|LVIF_IMAGE; + lvItem.iItem = ListView_FindItem(hwnd2Settings,-1,&lvfi); + lvItem.iSubItem = 0; + + if (lvItem.iItem == -1) + { + lvItem.iItem = 0; + lvItem.pszText = setting; + lvItem.cchTextMax = mir_strlen(setting); + lvItem.iItem = ListView_InsertItem(hwnd2Settings,&lvItem); + } + additem(hwnd2Settings,hContact,module, setting,lvItem.iItem); +} + +static WNDPROC SettingLabelEditSubClass; + +typedef struct { + HANDLE hContact; + char module[256]; + char setting[256]; + int item; + int subitem; + HWND hwnd; + int unicode; +} EditLabelInfoStruct; + +void writeStandardTextfromLabel(EditLabelInfoStruct* info, char* value, WCHAR *wc, int type) +{ + if (type != DBVT_ASCIIZ && type != DBVT_UTF8) + DBDeleteContactSetting(info->hContact,info->module,info->setting); + if (type == DBVT_UTF8 && wc) + { + DBWriteContactSettingWString(info->hContact,info->module,info->setting,wc); + mir_free(wc); + } + else + DBWriteContactSettingString(info->hContact,info->module,info->setting,value); + +} + +static LRESULT CALLBACK SettingLabelEditSubClassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) +{ + EditLabelInfoStruct* info = (EditLabelInfoStruct*)GetWindowLongPtr(hwnd,GWLP_USERDATA); + switch(msg) { + case WM_KEYDOWN: + switch (wParam) + { + case VK_RETURN: + if (GetKeyState(VK_CONTROL)&0x8000) // ctrl is pressed + break; + SendMessage(hwnd,WM_COMMAND,MAKEWPARAM(IDOK,0),0); + return 0; + case VK_ESCAPE: + SendMessage(hwnd,WM_COMMAND,MAKEWPARAM(IDCANCEL,0),0); + return 0; + } + break; + case WM_USER: + SetWindowLongPtr(hwnd,GWLP_USERDATA,lParam); + SetFocus(hwnd); + SendMessage(hwnd, WM_SETFONT, SendMessage(GetParent(hwnd), WM_GETFONT, 0, 0), 1); + info = ((EditLabelInfoStruct*)lParam); + if (info->subitem) + SendMessage(hwnd, EM_LIMITTEXT, (WPARAM)65535, 0); + else + SendMessage(hwnd, EM_LIMITTEXT, (WPARAM)255, 0); + SendMessage(hwnd, EM_SETSEL,0,-1); + break; + case WM_PAINT: + break; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + { + int len = GetWindowTextLength(hwnd)+1; + char *value = (char*)_alloca(len); + WCHAR *wc = NULL; + DBVARIANT dbv = {0}; + + GetWindowText(hwnd,value,len); + + if (info->unicode) + wc = mir_a2u(value); + + if (len <= 1 || GetSetting(info->hContact,info->module,info->setting,&dbv)) + { + SendMessage(hwnd,WM_COMMAND,MAKEWPARAM(IDCANCEL,0),0); + return 0; + } + + switch (info->subitem) + { + case 0:// setting name + if (!mir_strcmp(info->setting,value) || mir_strlen(value)>255) + { + DBFreeVariant(&dbv); + SendMessage(hwnd,WM_COMMAND,MAKEWPARAM(IDCANCEL,0),0); + return 0; + } + switch (dbv.type) + { + case DBVT_UTF8: + DBWriteContactSettingStringUtf(info->hContact,info->module,value,dbv.pszVal); + break; + case DBVT_ASCIIZ: + DBWriteContactSettingString(info->hContact,info->module,value,dbv.pszVal); + break; + case DBVT_BYTE: + DBWriteContactSettingByte(info->hContact,info->module,value,dbv.bVal); + break; + case DBVT_WORD: + DBWriteContactSettingWord(info->hContact,info->module,value,dbv.wVal); + break; + case DBVT_DWORD: + DBWriteContactSettingDword(info->hContact,info->module,value,dbv.dVal); + break; + case DBVT_BLOB: + DBWriteContactSettingBlob(info->hContact,info->module,value,dbv.pbVal,dbv.cpbVal); + break; + } + DBDeleteContactSetting(info->hContact,info->module,info->setting); + { + LVFINDINFO lvfi; + int item; + + lvfi.flags = LVFI_STRING; + lvfi.psz = info->setting; + lvfi.vkDirection = VK_DOWN; + + item = ListView_FindItem(info->hwnd,-1,&lvfi); + ListView_DeleteItem(info->hwnd,item); + } + break; + case 1: // value + { + int val; + int i = 0; + + if (dbv.type == DBVT_BLOB) + { + WriteBlobFromString(info->hContact,info->module,info->setting,value,len); + break; + } + + switch (value[0]) + { + case 'b': + case 'B': + if (value[1] == '0' && (value[2] == 'x' || value[2] == 'X')) + sscanf(&value[3],"%x",&val); + else if (value[1] >= '0' && value[1] <= '9') + { + val = atoi(&value[1]); + if (dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_UTF8) + DBDeleteContactSetting(info->hContact,info->module,info->setting); + + DBWriteContactSettingByte(info->hContact,info->module,info->setting,(BYTE)val); + } + else + writeStandardTextfromLabel(info, value, wc, dbv.type); + break; + case 'w': + case 'W': + if (value[1] == '0' && (value[2] == 'x' || value[2] == 'X')) + sscanf(&value[3],"%x",&val); + else if (value[1] >= '0' && value[1] <= '9') + { + val = atoi(&value[1]); + if (dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_UTF8) + DBDeleteContactSetting(info->hContact,info->module,info->setting); + DBWriteContactSettingWord(info->hContact,info->module,info->setting,(WORD)val); + } + else + writeStandardTextfromLabel(info, value, wc, dbv.type); + break; + case 'd': + case 'D': + if (value[1] == '0' && (value[2] == 'x' || value[2] == 'X')) + sscanf(&value[3],"%x",&val); + else if (value[1] >= '0' && value[1] <= '9') + { + val = atoi(&value[1]); + if (dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_UTF8) + DBDeleteContactSetting(info->hContact,info->module,info->setting); + DBWriteContactSettingDword(info->hContact,info->module,info->setting,val); + } + else + writeStandardTextfromLabel(info, value, wc, dbv.type); + break; + case '0': + i=1; + case 'x': + case 'X': + if (value[i] == 'x' || value[i] == 'X') + { + + sscanf(&value[i+1],"%x",&val); + switch (dbv.type) + { + case DBVT_UTF8: + case DBVT_ASCIIZ: + writeStandardTextfromLabel(info, value, wc, dbv.type); + break; + case DBVT_BYTE: + DBWriteContactSettingByte(info->hContact,info->module,info->setting,(BYTE)val); + break; + case DBVT_WORD: + DBWriteContactSettingWord(info->hContact,info->module,info->setting,(WORD)val); + break; + case DBVT_DWORD: + DBWriteContactSettingDword(info->hContact,info->module,info->setting,(DWORD)val); + break; + } + } + else + { + val = atoi(value); + switch (dbv.type) + { + case DBVT_ASCIIZ: + case DBVT_UTF8: + writeStandardTextfromLabel(info, value, wc, dbv.type); + break; + case DBVT_BYTE: + DBWriteContactSettingByte(info->hContact,info->module,info->setting,(BYTE)val); + break; + case DBVT_WORD: + DBWriteContactSettingWord(info->hContact,info->module,info->setting,(WORD)val); + break; + case DBVT_DWORD: + DBWriteContactSettingDword(info->hContact,info->module,info->setting,(DWORD)val); + break; + } + } + break; + case '\"': + case '\'': + { + int nlen = mir_strlen(value); + int sh = 0; + if (nlen > 3) + { + if (value[nlen-1] == value[0]) + { + value[nlen-1] = '\0'; + sh = 1; + } + } + writeStandardTextfromLabel(info, &value[sh], wc, dbv.type); + } + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + val = atoi(value); + switch (dbv.type) + { + case DBVT_ASCIIZ: + case DBVT_UTF8: + writeStandardTextfromLabel(info, value, wc, dbv.type); + break; + case DBVT_BYTE: + DBWriteContactSettingByte(info->hContact,info->module,info->setting,(BYTE)val); + break; + case DBVT_WORD: + DBWriteContactSettingWord(info->hContact,info->module,info->setting,(WORD)val); + break; + case DBVT_DWORD: + DBWriteContactSettingDword(info->hContact,info->module,info->setting,(DWORD)val); + break; + } + break; + default: + writeStandardTextfromLabel(info, value, wc, dbv.type); + break; + } // switch (value[0]) + } + break; // case 1: + } + DBFreeVariant(&dbv); + } // fall through + case IDCANCEL: + { + SettingListInfo *sli = (SettingListInfo*)GetWindowLongPtr(info->hwnd,GWLP_USERDATA); + + if (sli && sli->hwnd2Edit==hwnd) + sli->hwnd2Edit = NULL; + + mir_free(info); + DestroyWindow(hwnd); + } + return 0; + } + break; // wm_command + case WM_GETDLGCODE: + return DLGC_WANTALLKEYS; + } + if (UOS) + return CallWindowProcW(SettingLabelEditSubClass,hwnd,msg,wParam,lParam); + else + return CallWindowProc(SettingLabelEditSubClass,hwnd,msg,wParam,lParam); +} + + +void EditLabel(HWND hwnd2List, int item, int subitem) +{ + RECT rc; + LVITEM lvi; + char setting[256], value[16] = {0}; + DBVARIANT dbv; + SettingListInfo* info = (SettingListInfo*)GetWindowLongPtr(hwnd2List,GWLP_USERDATA); + EditLabelInfoStruct *data = (EditLabelInfoStruct*)mir_calloc(sizeof(EditLabelInfoStruct)); + if (!data || !info) return; + if (info->hwnd2Edit) + { + SendMessage(info->hwnd2Edit,WM_COMMAND,MAKEWPARAM(IDCANCEL,0),0); // ignore the new value of the last edit + info->hwnd2Edit = NULL; + } + lvi.mask = LVIF_TEXT; + lvi.iItem = item; + lvi.iSubItem = 0; + lvi.pszText = setting; + lvi.cchTextMax = 256; + + if (!ListView_GetItem(hwnd2List, &lvi) || + !ListView_GetSubItemRect + (hwnd2List,item,subitem,LVIR_LABEL,&rc) || + GetSetting(info->hContact,info->module,setting,&dbv)) + { + mir_free(data); + return; + } + + data->hContact = info->hContact; + strcpy(data->module, info->module); + strcpy(data->setting, setting); + data->item = item; + data->subitem = subitem; + data->hwnd = hwnd2List; + + // fix size for long strings + + switch (dbv.type) + { + case DBVT_UTF8: + if (subitem && UOS) + { + int len = mir_strlen(dbv.pszVal)+1; + WCHAR *wc = (WCHAR*)_alloca(len*sizeof(WCHAR)); + MultiByteToWideChar(CP_UTF8, 0, dbv.pszVal, -1, wc, len); + data->unicode = 1; + info->hwnd2Edit = CreateWindowW(L"EDIT",wc,WS_BORDER|WS_VISIBLE|WS_CHILD|WS_VSCROLL|ES_MULTILINE|ES_AUTOHSCROLL, rc.left,rc.top,(int)((rc.right - rc.left)*1.5),(rc.bottom - rc.top)*3,hwnd2List, 0,hInst,0); + break; + } + // fall through + case DBVT_ASCIIZ: + if (subitem) { + // convert from UTF8 + info->hwnd2Edit = CreateWindow("EDIT",dbv.pszVal,WS_BORDER|WS_VISIBLE|WS_CHILD|WS_VSCROLL|ES_MULTILINE|ES_AUTOHSCROLL, rc.left,rc.top,(int)((rc.right - rc.left)*1.5),(rc.bottom - rc.top)*3,hwnd2List, 0,hInst,0); + } + else + info->hwnd2Edit = CreateWindow("EDIT",setting,WS_BORDER|WS_VISIBLE|WS_CHILD|ES_AUTOHSCROLL, rc.left,rc.top,(rc.right - rc.left),(rc.bottom - rc.top),hwnd2List, 0,hInst,0); + break; + case DBVT_BYTE: + if (Hex&HEX_BYTE) + mir_snprintf(value, SIZEOF(value), "0x%02X", dbv.bVal); + else + itoa(dbv.bVal,value,10); + info->hwnd2Edit = CreateWindow("EDIT",!subitem?setting:value,WS_BORDER|WS_VISIBLE|WS_CHILD|ES_AUTOHSCROLL, rc.left,rc.top,(rc.right - rc.left),(rc.bottom - rc.top),hwnd2List, 0,hInst,0); + break; + case DBVT_WORD: + if (Hex&HEX_WORD) + mir_snprintf(value, SIZEOF(value), "0x%04X", dbv.wVal); + else + itoa(dbv.wVal,value,10); + info->hwnd2Edit = CreateWindow("EDIT",!subitem?setting:value,WS_BORDER|WS_VISIBLE|WS_CHILD|ES_AUTOHSCROLL, rc.left,rc.top,(rc.right - rc.left),(rc.bottom - rc.top),hwnd2List, 0,hInst,0); + break; + case DBVT_DWORD: + if (Hex&HEX_DWORD) + mir_snprintf(value, SIZEOF(value), "0x%08X", dbv.dVal); + else + itoa(dbv.dVal,value,10); + info->hwnd2Edit = CreateWindow("EDIT",!subitem?setting:value,WS_BORDER|WS_VISIBLE|WS_CHILD|ES_AUTOHSCROLL, rc.left,rc.top,(rc.right - rc.left),(rc.bottom - rc.top),hwnd2List, 0,hInst,0); + break; + case DBVT_BLOB: + if (!subitem) + info->hwnd2Edit = CreateWindow("EDIT",setting,WS_BORDER|WS_VISIBLE|WS_CHILD|ES_AUTOHSCROLL, rc.left,rc.top,(rc.right - rc.left),(rc.bottom - rc.top),hwnd2List, 0,hInst,0); + else + { + int j; + char tmp[16]; + char *data = (char*)_alloca(3*(dbv.cpbVal+1)+10); + + if (!data) {msg(Translate("Couldnt allocate enough memory!"), modFullname); return;} + data[0] = '\0'; + + for(j=0; jhwnd2Edit = CreateWindow("EDIT",data,WS_BORDER|WS_VISIBLE|WS_CHILD|WS_VSCROLL|ES_MULTILINE, rc.left,rc.top,(int)((rc.right - rc.left)*1.5),(rc.bottom - rc.top)*3,hwnd2List,0,hInst,0); + } + break; + default: return; + } + + DBFreeVariant(&dbv); + + if (UOS) + SettingLabelEditSubClass=(WNDPROC)SetWindowLongPtrW(info->hwnd2Edit,GWLP_WNDPROC,(LONG)SettingLabelEditSubClassProc); + else + SettingLabelEditSubClass=(WNDPROC)SetWindowLongPtr(info->hwnd2Edit,GWLP_WNDPROC,(LONG)SettingLabelEditSubClassProc); + + SendMessage(info->hwnd2Edit,WM_USER,0,(LPARAM)data); +} + +static int test; +void SettingsListRightClick(HWND hwnd, WPARAM wParam,LPARAM lParam); +static int lastColumn = -1; + +struct SettingsSortParams{ + HWND hList; + int column; +}; + +INT_PTR CALLBACK SettingsCompare(LPARAM lParam1, LPARAM lParam2, LPARAM myParam) +{ + SettingsSortParams params = *(SettingsSortParams *) myParam; + const int maxSize = 1024; + TCHAR text1[maxSize]; + TCHAR text2[maxSize]; + ListView_GetItemText(params.hList, (int) lParam1, params.column, text1, maxSize); + ListView_GetItemText(params.hList, (int) lParam2, params.column, text2, maxSize); + + int res = _tcsicmp(text1, text2); + res = (params.column == lastColumn) ? -res : res; + return res; +} + +void SettingsListWM_NOTIFY(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) +{ + switch(((NMHDR*)lParam)->code) + { + case NM_CLICK: + { + SettingListInfo* info = (SettingListInfo*)GetWindowLongPtr(GetDlgItem(hwnd,IDC_SETTINGS),GWLP_USERDATA); + + LVHITTESTINFO hti; + hti.pt=((NMLISTVIEW*)lParam)->ptAction; + if (DBGetContactSettingByte(NULL,modname,"DontAllowInLineEdit",0) || !IsWinVer2000Plus()) /* fix for TioDuke and win98 */ + break; + if (info && ListView_SubItemHitTest(GetDlgItem(hwnd,IDC_SETTINGS),&hti) >-1) + { + if (hti.iSubItem < 2 && hti.flags != LVHT_ONITEMICON) + { + if (info->selectedItem == hti.iItem) + EditLabel(GetDlgItem(hwnd,IDC_SETTINGS),hti.iItem,hti.iSubItem); + else if (info->hwnd2Edit) + { + SendMessage(info->hwnd2Edit,WM_COMMAND,MAKEWPARAM(IDOK,0),0); + info->hwnd2Edit = NULL; + info->selectedItem = hti.iItem; + } + else info->selectedItem = hti.iItem; + } + else + { + if (info->hwnd2Edit) + { + SendMessage(info->hwnd2Edit,WM_COMMAND,MAKEWPARAM(IDOK,0),0); + info->hwnd2Edit = NULL; + } + info->selectedItem = hti.iItem; + } + } + else if (info && info->hwnd2Edit) + { + SendMessage(info->hwnd2Edit,WM_COMMAND,MAKEWPARAM(IDOK,0),0); + info->hwnd2Edit = NULL; + info->selectedItem = 0; + } + break; + } + + case NM_DBLCLK: + { + SettingListInfo* info = (SettingListInfo*)GetWindowLongPtr(GetDlgItem(hwnd,IDC_SETTINGS),GWLP_USERDATA); + + LVHITTESTINFO hti; + + hti.pt=((NMLISTVIEW*)lParam)->ptAction; + if (info && ListView_SubItemHitTest(GetDlgItem(hwnd,IDC_SETTINGS),&hti) >-1) + { + if ((hti.iSubItem > 1 || hti.flags == LVHT_ONITEMICON) || (DBGetContactSettingByte(NULL,modname,"DontAllowInLineEdit",0) || !IsWinVer2000Plus()/* fix for TioDuke and win98 */ )) + { + char setting[256]; + SendMessage(info->hwnd2Edit,WM_COMMAND,MAKEWPARAM(IDOK,0),0); + info->hwnd2Edit = NULL; + ListView_GetItemText(GetDlgItem(hwnd, IDC_SETTINGS), hti.iItem, 0, setting, 256); + editSetting(info->hContact,info->module, setting); + } + else EditLabel(GetDlgItem(hwnd,IDC_SETTINGS),hti.iItem,hti.iSubItem); + } + break; + } + + case NM_RCLICK: + SettingsListRightClick(hwnd,wParam,lParam); + break; + + case LVN_COLUMNCLICK: + { + LPNMLISTVIEW lv = (LPNMLISTVIEW) lParam; + SettingsSortParams params = {0}; + params.hList = GetDlgItem(hwnd, IDC_SETTINGS); + params.column = lv->iSubItem; + ListView_SortItemsEx(params.hList, SettingsCompare, (LPARAM) ¶ms); + lastColumn = (params.column == lastColumn) ? -1 : params.column; + break; + } + + } // switch(((NMHDR*)lParam)->code) +} + +void SettingsListRightClick(HWND hwnd, WPARAM wParam,LPARAM lParam) // hwnd here is to the main window, NOT the listview +{ + HWND hSettings = GetDlgItem(hwnd,IDC_SETTINGS); + SettingListInfo* info = (SettingListInfo*)GetWindowLongPtr(hSettings,GWLP_USERDATA); + char setting[256], *module; + HANDLE hContact; + LVHITTESTINFO hti; + POINT pt; + HMENU hMenu, hSubMenu; + + if (!info) return; + module = info->module; + hContact = info->hContact; + + hti.pt=((NMLISTVIEW*)lParam)->ptAction; + if (ListView_SubItemHitTest(hSettings,&hti) == -1) + { + // nowhere.. new item menu + GetCursorPos(&pt); + hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXTMENU)); + hSubMenu = GetSubMenu(hMenu, 6); + TranslateMenu(hSubMenu); + + if (!UDB) + RemoveMenu(hSubMenu, MENU_ADD_UNICODE, MF_BYCOMMAND); + + switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, NULL)) + { + case MENU_ADD_BYTE: + { + struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc + DBVARIANT dbv = {0}; // freed in the dialog + dbv.type = DBVT_BYTE; + dbsetting->dbv = dbv; + dbsetting->hContact = hContact; + dbsetting->module = mir_tstrdup(module); + dbsetting->setting = mir_tstrdup(""); + CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting); + } + break; + case MENU_ADD_WORD: + { + struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc + DBVARIANT dbv = {0}; // freed in the dialog + dbv.type = DBVT_WORD; + dbsetting->dbv = dbv; + dbsetting->hContact = hContact; + dbsetting->module = mir_tstrdup(module); + dbsetting->setting = mir_tstrdup(""); + CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting); + } + break; + case MENU_ADD_DWORD: + { + struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc + DBVARIANT dbv = {0}; // freed in the dialog + dbv.type = DBVT_DWORD; + dbsetting->dbv = dbv; + dbsetting->hContact = hContact; + dbsetting->module = mir_tstrdup(module); + dbsetting->setting = mir_tstrdup(""); + CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting); + } + break; + case MENU_ADD_STRING: + { + struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc + DBVARIANT dbv = {0}; // freed in the dialog + dbv.type = DBVT_ASCIIZ; + dbsetting->dbv = dbv; + dbsetting->hContact = hContact; + dbsetting->module = mir_tstrdup(module); + dbsetting->setting = mir_tstrdup(""); + CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting); + } + break; + case MENU_ADD_UNICODE: + if (UDB) + { + struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc + DBVARIANT dbv = {0}; // freed in the dialog + dbv.type = DBVT_UTF8; + dbsetting->dbv = dbv; + dbsetting->hContact = hContact; + dbsetting->module = mir_tstrdup(module); + dbsetting->setting = mir_tstrdup(""); + if (UOS) + CreateDialogParamW(hInst,MAKEINTRESOURCEW(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting); + else + CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting); + } + break; + case MENU_ADD_BLOB: + { + struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc + DBVARIANT dbv = {0}; // freed in the dialog + dbv.type = DBVT_BLOB; + dbsetting->dbv = dbv; + dbsetting->hContact = hContact; + dbsetting->module = mir_tstrdup(module); + dbsetting->setting = mir_tstrdup(""); + CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting); + } + break; + + } // switch + } + else // on item + { + char type[8]; + LVITEM lvi; + int i; + int watching = 0; + GetCursorPos(&pt); + hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXTMENU)); + hSubMenu = GetSubMenu(hMenu, 0); + TranslateMenu(hSubMenu); + + lvi.mask = LVIF_IMAGE|LVIF_TEXT; + lvi.iItem = hti.iItem; + lvi.iSubItem = 0; + lvi.pszText = setting; + lvi.cchTextMax = 256; + + ListView_GetItem(hSettings,&lvi); + ListView_GetItemText(hSettings, hti.iItem, 2, type, 8); + + if (!UDB) + { + RemoveMenu(hSubMenu, MENU_ADD_UNICODE, MF_BYCOMMAND); + RemoveMenu(hSubMenu, MENU_CHANGE2UNICODE, MF_BYCOMMAND); + } + + switch(lvi.iImage) { + case 4: // STRING + RemoveMenu(hSubMenu, MENU_CHANGE2STRING, MF_BYCOMMAND); + break; + case 1: // BYTE + RemoveMenu(hSubMenu, 4, MF_BYPOSITION); + RemoveMenu(hSubMenu, MENU_CHANGE2BYTE, MF_BYCOMMAND); + RemoveMenu(hSubMenu, MENU_CHANGE2UNICODE, MF_BYCOMMAND); + break; + case 2: // WORD + RemoveMenu(hSubMenu, 4, MF_BYPOSITION); + RemoveMenu(hSubMenu, MENU_CHANGE2WORD, MF_BYCOMMAND); + RemoveMenu(hSubMenu, MENU_CHANGE2UNICODE, MF_BYCOMMAND); + break; + case 3: // DWORD + RemoveMenu(hSubMenu, 4, MF_BYPOSITION); + RemoveMenu(hSubMenu, MENU_CHANGE2DWORD, MF_BYCOMMAND); + RemoveMenu(hSubMenu, MENU_CHANGE2UNICODE, MF_BYCOMMAND); + break; + case 0: // BLOB + RemoveMenu(hSubMenu, 3, MF_BYPOSITION); + RemoveMenu(hSubMenu, 1, MF_BYPOSITION); + RemoveMenu(hSubMenu, 2, MF_BYPOSITION); + RemoveMenu(hSubMenu, MENU_EDIT_SET, MF_BYCOMMAND); + break; + case 5: // UTF8 + RemoveMenu(hSubMenu, 4, MF_BYPOSITION); + RemoveMenu(hSubMenu, MENU_CHANGE2DWORD, MF_BYCOMMAND); + RemoveMenu(hSubMenu, MENU_CHANGE2WORD, MF_BYCOMMAND); + RemoveMenu(hSubMenu, MENU_CHANGE2BYTE, MF_BYCOMMAND); + if (!UDB) + { + RemoveMenu(hSubMenu, 3, MF_BYPOSITION); + RemoveMenu(hSubMenu, 1, MF_BYPOSITION); + RemoveMenu(hSubMenu, 2, MF_BYPOSITION); + RemoveMenu(hSubMenu, MENU_EDIT_SET, MF_BYCOMMAND); + RemoveMenu(hSubMenu, MENU_WATCH_ITEM, MF_BYCOMMAND); + } + else + RemoveMenu(hSubMenu, MENU_CHANGE2UNICODE, MF_BYCOMMAND); + break; + } + + // watch list stuff + + if (ListView_GetSelectedCount(hSettings) >1) + { + RemoveMenu(hSubMenu, 3, MF_BYPOSITION); + RemoveMenu(hSubMenu, 1, MF_BYPOSITION); + RemoveMenu(hSubMenu, 3, MF_BYPOSITION); + RemoveMenu(hSubMenu, MENU_EDIT_SET, MF_BYCOMMAND); + } + + // check if the setting is being watched and if it is then check the menu item + for (i=0; ihContact,info->module, setting); + break; +///////////////////////// divider +//////////////////////// NEW item submenu + case MENU_ADD_BYTE: + { + struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc + DBVARIANT dbv = {0}; // freed in the dialog + dbv.type = DBVT_BYTE; + dbsetting->dbv = dbv; + dbsetting->hContact = hContact; + dbsetting->module = mir_tstrdup(module); + dbsetting->setting = mir_tstrdup(""); + CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting); + } + break; + case MENU_ADD_WORD: + { + struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc + DBVARIANT dbv = {0}; // freed in the dialog + dbv.type = DBVT_WORD; + dbsetting->dbv = dbv; + dbsetting->hContact = hContact; + dbsetting->module = mir_tstrdup(module); + dbsetting->setting = mir_tstrdup(""); + CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting); + } + break; + case MENU_ADD_DWORD: + { + struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc + DBVARIANT dbv = {0}; // freed in the dialog + dbv.type = DBVT_DWORD; + dbsetting->dbv = dbv; + dbsetting->hContact = hContact; + dbsetting->module = mir_tstrdup(module); + dbsetting->setting = mir_tstrdup(""); + CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting); + } + break; + case MENU_ADD_STRING: + { + struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc + DBVARIANT dbv = {0}; // freed in the dialog + dbv.type = DBVT_ASCIIZ; + dbsetting->dbv = dbv; + dbsetting->hContact = hContact; + dbsetting->module = mir_tstrdup(module); + dbsetting->setting = mir_tstrdup(""); + CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting); + } + break; + case MENU_ADD_UNICODE: + if (UDB) + { + struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc + DBVARIANT dbv = {0}; // freed in the dialog + dbv.type = DBVT_UTF8; + dbsetting->dbv = dbv; + dbsetting->hContact = hContact; + dbsetting->module = mir_tstrdup(module); + dbsetting->setting = mir_tstrdup(""); + if (UOS) + CreateDialogParamW(hInst,MAKEINTRESOURCEW(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting); + else + CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting); + } + break; + case MENU_ADD_BLOB: + { + struct DBsetting *dbsetting = (struct DBsetting *)mir_alloc(sizeof(struct DBsetting)); // gets safe_free()ed in the window proc + DBVARIANT dbv = {0}; // freed in the dialog + dbv.type = DBVT_BLOB; + dbsetting->dbv = dbv; + dbsetting->hContact = hContact; + dbsetting->module = mir_tstrdup(module); + dbsetting->setting = mir_tstrdup(""); + CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_EDIT_SETTING),hwnd,EditSettingDlgProc, (LPARAM)dbsetting); + } + break; +///////////////////////// convert to submenu + case MENU_CHANGE2BYTE: + if (convertSetting(hContact, module, setting, 0)) + { + lvi.iImage = 1; + ListView_SetItem(hSettings,&lvi); + } + break; + case MENU_CHANGE2WORD: + if (convertSetting(hContact, module, setting, 1)) + { + lvi.iImage = 2; + ListView_SetItem(hSettings,&lvi); + } + break; + case MENU_CHANGE2DWORD: + if (convertSetting(hContact, module, setting, 2)) + { + lvi.iImage = 3; + ListView_SetItem(hSettings,&lvi); + } + break; + case MENU_CHANGE2STRING: + if (convertSetting(hContact, module, setting, 3)) + { + lvi.iImage = 4; + ListView_SetItem(hSettings,&lvi); + } + break; + case MENU_CHANGE2UNICODE: + if (convertSetting(hContact, module, setting, 4)) + { + lvi.iImage = 5; + ListView_SetItem(hSettings,&lvi); + } + break; +///////////////////////// convert to submenu + case MENU_VIEWDECRYPT: + { + DBVARIANT dbv; + if (!DBGetContactSetting(hContact,module,setting,&dbv) && dbv.type==DBVT_ASCIIZ) + { + if (lstrcmpA(setting, "LoginPassword")) + { + char *text = mir_strdup(dbv.pszVal); + CallService(MS_DB_CRYPT_DECODESTRING, (WPARAM)lstrlenA(dbv.pszVal)+1, (LPARAM)text); + msg(text, Translate("Decoded string..")); + mir_free(text); + } + else + { + char *str = mir_strdup(dbv.pszVal); + char *str1 = str; + for (;*str1; ++str1) + { + const char c = *str1 ^ 0xc3; + if (c) *str1 = c; + } + if (UOS) + { + WCHAR *res = mir_utf8decodeW(str); + MessageBoxW(0, res, TranslateW(L"Decoded string.."),MB_OK); + mir_free(res); + } + else + { + mir_utf8decode(str, NULL); + MessageBoxA(0, str, Translate("Decoded string.."),MB_OK); + } + mir_free(str); + } + } + DBFreeVariant(&dbv); + } + break; + case MENU_VIEWENCRYPT: + { + DBVARIANT dbv; + char *text; + if (!DBGetContactSetting(hContact,module,setting,&dbv) && dbv.type==DBVT_ASCIIZ) + { + text = mir_tstrdup(dbv.pszVal); + CallService(MS_DB_CRYPT_ENCODESTRING, (WPARAM)strlen(dbv.pszVal)+1, (LPARAM)text); + msg(text, Translate("Encoded string..")); + mir_free(text); + } + DBFreeVariant(&dbv); + } + break; + case MENU_DECRYPT: + { + DBVARIANT dbv; + char *text; + if (!DBGetContactSetting(hContact,module,setting,&dbv) && dbv.type==DBVT_ASCIIZ) + { + text = mir_tstrdup(dbv.pszVal); + CallService(MS_DB_CRYPT_DECODESTRING, (WPARAM)strlen(dbv.pszVal)+1, (LPARAM)text); + DBWriteContactSettingString(hContact,module,setting,text); + mir_free(text); + } + DBFreeVariant(&dbv); + } + break; + case MENU_ENCRYPT: + { + DBVARIANT dbv; + char *text; + if (!DBGetContactSetting(hContact,module,setting,&dbv) && dbv.type==DBVT_ASCIIZ) + { + text = mir_tstrdup(dbv.pszVal); + CallService(MS_DB_CRYPT_ENCODESTRING, (WPARAM)strlen(dbv.pszVal)+1, (LPARAM)text); + DBWriteContactSettingString(hContact,module,setting,text); + mir_free(text); + } + DBFreeVariant(&dbv); + } + break; +///////////////////////// divider + case MENU_WATCH_ITEM: + + if (!watching) + { + addSettingToWatchList(hContact,module,setting); + } + else freeWatchListItem(i); + if (hwnd2watchedVarsWindow) + PopulateWatchedWindow(GetDlgItem(hwnd2watchedVarsWindow, IDC_VARS)); + break; + case MENU_DELETE_SET: + DeleteSettingsFromList(hSettings, hContact, module, setting); + break; + } + } +} \ No newline at end of file diff --git a/plugins/DbEditorPP/src/threads.cpp b/plugins/DbEditorPP/src/threads.cpp new file mode 100644 index 0000000000..7ac144adc4 --- /dev/null +++ b/plugins/DbEditorPP/src/threads.cpp @@ -0,0 +1,48 @@ +#include "headers.h" + +// thread stuff + +struct FORK_ARG { + HANDLE hEvent; + void (__cdecl *threadcode)(void*); + unsigned (__stdcall *threadcodeex)(void*); + void *arg; +}; + +void __cdecl forkthread_r(void *param) +{ + struct FORK_ARG *fa=(struct FORK_ARG*)param; + void (*callercode)(void*)=fa->threadcode; + void *arg=fa->arg; + + CallService(MS_SYSTEM_THREAD_PUSH,0,0); + + SetEvent(fa->hEvent); + + __try { + callercode(arg); + } __finally { + CallService(MS_SYSTEM_THREAD_POP,0,0); + } + + return; +} + +unsigned long forkthread ( void (__cdecl *threadcode)(void*),unsigned long stacksize,void *arg) +{ + unsigned long rc; + struct FORK_ARG fa; + + fa.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL); + fa.threadcode=threadcode; + fa.arg=arg; + + rc=_beginthread(forkthread_r,stacksize,&fa); + + if ((unsigned long)-1L != rc) { + WaitForSingleObject(fa.hEvent,INFINITE); + } + CloseHandle(fa.hEvent); + + return rc; +} diff --git a/plugins/DbEditorPP/src/watchedvars.cpp b/plugins/DbEditorPP/src/watchedvars.cpp new file mode 100644 index 0000000000..b7d2cf6b73 --- /dev/null +++ b/plugins/DbEditorPP/src/watchedvars.cpp @@ -0,0 +1,358 @@ +#include "headers.h" + +int addSettingToWatchList(HANDLE hContact, char* module, char* setting) +{ + if (WatchListArray.count == WatchListArray.size) + { + WatchListArray.size += 32; + WatchListArray.item = (struct DBsetting*)mir_realloc(WatchListArray.item, sizeof(struct DBsetting)*WatchListArray.size); + } + if (!WatchListArray.item) return 0; + if (setting && DBGetContactSetting(hContact,module, setting, &(WatchListArray.item[WatchListArray.count].dbv))) return 0; + WatchListArray.item[WatchListArray.count].hContact = hContact; + WatchListArray.item[WatchListArray.count].module = mir_tstrdup(module); + if (setting) WatchListArray.item[WatchListArray.count].setting = mir_tstrdup(setting); + else WatchListArray.item[WatchListArray.count].setting = 0; + + WatchListArray.item[WatchListArray.count].WatchModule = setting?WATCH_SETTING:WATCH_MODULE; + WatchListArray.count++; + return 1; +} + +void freeWatchListItem(int item) +{ + if (WatchListArray.item[item].module) mir_free(WatchListArray.item[item].module); + WatchListArray.item[item].module = 0; + if (WatchListArray.item[item].setting) mir_free(WatchListArray.item[item].setting); + WatchListArray.item[item].setting = 0; + DBFreeVariant(&(WatchListArray.item[item].dbv)); + WatchListArray.item[item].hContact = 0; +} + + +void addwatchtolist(HWND hwnd2list, struct DBsetting *lParam) +{ + LVITEM lvItem; + int index; + char data[32], tmp[32]; + DBVARIANT *dbv = &(lParam->dbv); + HANDLE hContact = lParam->hContact; + char *module = lParam->module; + char *setting = lParam->setting; + if (!module) return; + lvItem.lParam = (LPARAM)lParam->hContact; + lvItem.mask = LVIF_TEXT|LVIF_PARAM; + lvItem.iItem = 0; + lvItem.iSubItem = 0; + + if (!setting || (int)(lParam->setting) == WATCH_MODULE) // add every item in the module and return + { + ModuleSettingLL settinglist; + struct DBsetting dummy; + struct ModSetLinkLinkItem *setting; + if (!EnumSettings(hContact,module,&settinglist)) return; + dummy.hContact = hContact; + dummy.module = mir_tstrdup(module); + setting = settinglist.first; + while (setting) + { + dummy.setting = setting->name; + addwatchtolist(hwnd2list, &dummy); + setting = (struct ModSetLinkLinkItem *)setting->next; + } + mir_free(dummy.module); + FreeModuleSettingLL(&settinglist); + return; + } + DBFreeVariant(&(lParam->dbv)); + if (GetSetting(hContact, module, setting, &(lParam->dbv))) return; + + if (!hContact) + lvItem.pszText = "NULL"; + else + lvItem.pszText = (char*)GetContactName(hContact,NULL,UOS); + + index = ListView_InsertItem(hwnd2list,&lvItem); + + if (UOS) + { + WCHAR* ptszText = mir_a2u(lvItem.pszText); + ListView_SetItemTextW(hwnd2list, index, 0, ptszText); + mir_free(ptszText); + } + + ListView_SetItemText(hwnd2list,index,1,module); + ListView_SetItemText(hwnd2list,index,2,setting); + + switch (dbv->type) + { + case DBVT_BLOB: + { + int j; + char *data = NULL; + if (!(data = (char*)mir_realloc(data, 3*(dbv->cpbVal+1)) )) + return; + data[0] = '\0'; + for (j=0; jcpbVal; j++) + { + char tmp[16]; + mir_snprintf(tmp, SIZEOF(tmp), "%02X ", (BYTE)dbv->pbVal[j]); + strcat(data, tmp); + } + ListView_SetItemText(hwnd2list,index,4,data); + ListView_SetItemText(hwnd2list,index,3,"BLOB"); + mir_free(data); + } + break; + case DBVT_BYTE: + mir_snprintf(data, 32, "0x%02X (%s)", dbv->bVal, itoa(dbv->bVal,tmp,10)); + ListView_SetItemText(hwnd2list,index,4,data); + ListView_SetItemText(hwnd2list,index,3,"BYTE"); + break; + case DBVT_WORD: + mir_snprintf(data, 32, "0x%04X (%s)", dbv->wVal, itoa(dbv->wVal,tmp,10)); + ListView_SetItemText(hwnd2list,index,4,data); + ListView_SetItemText(hwnd2list,index,3,"WORD"); + break; + case DBVT_DWORD: + mir_snprintf(data, 32, "0x%08X (%s)", dbv->dVal, itoa(dbv->dVal,tmp,10)); + ListView_SetItemText(hwnd2list,index,4,data); + ListView_SetItemText(hwnd2list,index,3,"DWORD"); + break; + case DBVT_ASCIIZ: + ListView_SetItemText(hwnd2list,index,4,dbv->pszVal); + ListView_SetItemText(hwnd2list,index,3,"STRING"); + break; + case DBVT_UTF8: + { + if (UOS) + { + int length = (int)strlen(dbv->pszVal) + 1; + WCHAR *wc = (WCHAR*)_alloca(length*sizeof(WCHAR)); + MultiByteToWideChar(CP_UTF8, 0, dbv->pszVal, -1, wc, length); + ListView_SetItemTextW(hwnd2list,index,4,wc); + } + else { + // convert from UTF8 + ListView_SetItemText(hwnd2list,index,4,dbv->pszVal); + } + ListView_SetItemText(hwnd2list,index,3,"UNICODE"); + } + break; + + } +} + +void PopulateWatchedWindow(HWND hwnd) +{ + int i; + ListView_DeleteAllItems(hwnd); + for (i=0;iwId) + { + case IDC_VARS: + urc->rcItem.top = 0; + urc->rcItem.bottom = urc->dlgNewSize.cy; + urc->rcItem.left = 0; + urc->rcItem.right = urc->dlgNewSize.cx; + return RD_ANCHORY_CUSTOM|RD_ANCHORX_CUSTOM; + } + return RD_ANCHORX_LEFT|RD_ANCHORY_TOP; +} + +INT_PTR CALLBACK WatchDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + // setup the list... + LVCOLUMN sLC; + + sLC.fmt = LVCFMT_LEFT; + ListView_SetExtendedListViewStyle(GetDlgItem(hwnd, IDC_VARS), 32|LVS_EX_SUBITEMIMAGES); //LVS_EX_FULLROWSELECT + sLC.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH; + + sLC.pszText = Translate("Contact"); sLC.cx = 80; + ListView_InsertColumn(GetDlgItem(hwnd, IDC_VARS),0,&sLC); + sLC.pszText = Translate("Module"); sLC.cx = 80; + ListView_InsertColumn(GetDlgItem(hwnd, IDC_VARS),1,&sLC); + sLC.pszText = Translate("Setting"); sLC.cx = 80; + ListView_InsertColumn(GetDlgItem(hwnd, IDC_VARS),2,&sLC); + sLC.pszText = Translate("Type"); sLC.cx = 60; + ListView_InsertColumn(GetDlgItem(hwnd, IDC_VARS),3,&sLC); + sLC.pszText = Translate("Data"); sLC.cx = 300; + ListView_InsertColumn(GetDlgItem(hwnd, IDC_VARS),4,&sLC); + + PopulateWatchedWindow(GetDlgItem(hwnd, IDC_VARS)); + + TranslateMenu(GetMenu(hwnd)); + TranslateMenu(GetSubMenu(GetMenu(hwnd),0)); + TranslateDialogDefault(hwnd); + // do the icon + SendMessage(hwnd,WM_SETICON,ICON_BIG,(LPARAM)LoadIcon(hInst,MAKEINTRESOURCE(ICO_REGEDIT))); + } + return TRUE; + // for the resize + case WM_GETMINMAXINFO: + { + MINMAXINFO *mmi=(MINMAXINFO*)lParam; + mmi->ptMinTrackSize.x=200; + mmi->ptMinTrackSize.y=90; + return 0; + } + case WM_SIZE: + { + UTILRESIZEDIALOG urd; + ZeroMemory(&urd,sizeof(urd)); + urd.cbSize=sizeof(urd); + urd.hInstance=hInst; + urd.hwndDlg=hwnd; + urd.lParam=(LPARAM)0; + urd.lpTemplate=MAKEINTRESOURCE(IDD_WATCH_DIAG); + urd.pfnResizer=WatchDialogResize; + CallService(MS_UTILS_RESIZEDIALOG,0,(LPARAM)&urd); + break; + + } + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case MENU_REMALL_WATCHES: + freeAllWatches(); + ListView_DeleteAllItems(GetDlgItem(hwnd, IDC_VARS)); + break; + case MENU_EXIT: + case IDCANCEL: + hwnd2watchedVarsWindow = 0; + DestroyWindow(hwnd); + break; + case MENU_REFRESH: + PopulateWatchedWindow(GetDlgItem(hwnd, IDC_VARS)); + } + break; + + case WM_NOTIFY: + switch(LOWORD(wParam)) + { + case IDC_VARS: + switch(((NMHDR*)lParam)->code) + { + case NM_DBLCLK: + { + LVHITTESTINFO hti; + LVITEM lvi; + hti.pt=((NMLISTVIEW*)lParam)->ptAction; + if (ListView_SubItemHitTest(GetDlgItem(hwnd,IDC_VARS),&hti) >-1) + { + if (hti.flags&LVHT_ONITEM) + { + lvi.mask = LVIF_PARAM; + lvi.iItem = hti.iItem; + lvi.iSubItem = 0; + if (ListView_GetItem(GetDlgItem(hwnd,IDC_VARS),&lvi)) + { + ItemInfo ii; + ii.hContact = (HANDLE)lvi.lParam; + ListView_GetItemText(GetDlgItem(hwnd,IDC_VARS),hti.iItem,1,ii.module,128); + ListView_GetItemText(GetDlgItem(hwnd,IDC_VARS),hti.iItem,2,ii.setting,128); + ii.type = FW_SETTINGNAME; + SendMessage(hwnd2mainWindow,WM_FINDITEM,(WPARAM)&ii,0); + } + } + } + } + break; + } + break; + } + break; + } + return 0; +} + + +void popupWatchedVar(HANDLE hContact,const char* module,const char* setting) +{ + POPUPDATAEX ppd = {0}; + HICON hIcon = LoadIcon(hInst, MAKEINTRESOURCE(ICO_REGEDIT)); + char lpzContactName[MAX_CONTACTNAME]; + char lpzText[MAX_SECONDLINE]; + COLORREF colorBack = DBGetContactSettingDword(NULL,modname,"PopupColour",RGB(255,0,0)); + COLORREF colorText = RGB(0,0,0); + DBVARIANT dbv; + int timeout = DBGetContactSettingByte(NULL,modname,"PopupDelay",3); + + if (hContact) + { + // contacts nick + char szProto[256]; + if (GetValue(hContact,"Protocol","p",szProto,SIZEOF(szProto))) + mir_snprintf(lpzContactName, MAX_SECONDLINE, "%s (%s)", (char*)GetContactName(hContact, szProto, 0), szProto); + else + mir_snprintf(lpzContactName, MAX_SECONDLINE, nick_unknown); + } + else + { + strcpy(lpzContactName,Translate("Settings")); + } + // 2nd line + if (!GetSetting(hContact, module, setting, &dbv)) + { + switch (dbv.type) + { + case DBVT_BYTE: + mir_snprintf(lpzText, SIZEOF(lpzText), Translate("Database Setting Changed: \nModule: \"%s\" , Setting: \"%s\"\nNew Value: (BYTE) %d"), module, setting, dbv.bVal); + break; + case DBVT_WORD: + mir_snprintf(lpzText, SIZEOF(lpzText), Translate("Database Setting Changed: \nModule: \"%s\" , Setting: \"%s\"\nNew Value: (WORD) %d"), module, setting, dbv.wVal); + break; + case DBVT_DWORD: + mir_snprintf(lpzText, SIZEOF(lpzText), Translate("Database Setting Changed: \nModule: \"%s\" , Setting: \"%s\"\nNew Value: (DWORD) 0x%X"), module, setting, dbv.dVal); + break; + case DBVT_ASCIIZ: + mir_snprintf(lpzText, SIZEOF(lpzText), Translate("Database Setting Changed: \nModule: \"%s\" , Setting: \"%s\"\nNew Value: \"%s\""), module, setting, dbv.pszVal); + break; + case DBVT_UTF8: + mir_snprintf(lpzText, SIZEOF(lpzText), Translate("Database Setting Changed: \nModule: \"%s\" , Setting: \"%s\"\nNew Value (UTF8): \"%s\""), module, setting, dbv.pszVal); + break; + default: + return; + } + } + else return; + + DBFreeVariant(&dbv); + + ppd.lchContact = (HANDLE)hContact; + ppd.lchIcon = hIcon; + lstrcpyn(ppd.lpzContactName, lpzContactName,MAX_CONTACTNAME); + lstrcpyn(ppd.lpzText, lpzText,MAX_SECONDLINE); + ppd.colorBack = colorBack; + ppd.colorText = colorText; + ppd.PluginWindowProc = NULL; + ppd.PluginData = NULL; + ppd.iSeconds = timeout?timeout:-1; + + //Now that every field has been filled, we want to see the popup. + CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0); +} -- cgit v1.2.3