From 9ba730bc48e44630b418f4214aee57c7b7c987bd Mon Sep 17 00:00:00 2001 From: Szymon Tokarz Date: Tue, 31 May 2016 21:41:30 +0000 Subject: [MirFox] Immediately refresh data in Firefox menu when Miranda contact or account is added, renamed, deleted, enabled or disabled, hide or unhide. Add "Add acount to contact name" option. git-svn-id: http://svn.miranda-ng.org/main/trunk@16892 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- .../MirFoxCommons/MirFoxCommons_sharedMemory.cpp | 124 +++++- .../src/MirFoxCommons/MirFoxCommons_sharedMemory.h | 10 + plugins/MirFox/src/MirandaInterface.cpp | 62 +++ plugins/MirFox/src/MirandaOptions.cpp | 76 ++-- plugins/MirFox/src/MirandaUtils.cpp | 50 ++- plugins/MirFox/src/MirandaUtils.h | 2 + plugins/MirFox/src/MirfoxData.cpp | 420 ++++++++++++++++----- plugins/MirFox/src/MirfoxData.h | 125 +++--- plugins/MirFox/src/MirfoxMiranda.cpp | 156 +++++++- plugins/MirFox/src/MirfoxMiranda.h | 18 + plugins/MirFox/src/common.h | 1 + plugins/MirFox/src/resource.h | 10 +- plugins/MirFox/src/version.h | 4 +- 13 files changed, 851 insertions(+), 207 deletions(-) (limited to 'plugins/MirFox/src') diff --git a/plugins/MirFox/src/MirFoxCommons/MirFoxCommons_sharedMemory.cpp b/plugins/MirFox/src/MirFoxCommons/MirFoxCommons_sharedMemory.cpp index 7f30a49f4c..18fafa241e 100644 --- a/plugins/MirFox/src/MirFoxCommons/MirFoxCommons_sharedMemory.cpp +++ b/plugins/MirFox/src/MirFoxCommons/MirFoxCommons_sharedMemory.cpp @@ -64,7 +64,7 @@ const boost::interprocess::offset_t SMUCONST_MSM_RECORDS_OFFSET = SMUCONST_M const boost::interprocess::offset_t SMUCONST_MSM_RECORD_TYPE_RECOFFSET = 0; const std::size_t SMUCONST_MSM_RECORD_TYPE_SIZE = sizeof(char); //1B - // [O]Option, [T]Translation, [A]Account, [G]Group, [C]Contact + // [O]Option, [T]Translation, [A]Account, [G]Group, [C]Contact, [D]Deleted item const boost::interprocess::offset_t SMUCONST_MSM_RECORD_HANDLE_RECOFFSET = SMUCONST_MSM_RECORD_TYPE_RECOFFSET + SMUCONST_MSM_RECORD_TYPE_SIZE; const std::size_t SMUCONST_MSM_RECORD_HANDLE_SIZE = sizeof(uint64_t); //8B // {AGC} miranda HANDLE to account/group/contact - HANDLE 32/64b, {O} option id, {T} translation id @@ -189,6 +189,128 @@ SharedMemoryUtils::addContactToSM(uint64_t mirandaContactHandle, uint64_t mirand } + + +void +SharedMemoryUtils::refreshMsm_Add(char type, uint64_t mirandaId, std::wstring& displayName) +{ + logger->log_p(L"SharedMemoryUtils.refreshMsm_Add type=[%c], mirandaId=[%I64u]", type, mirandaId); + + if (type == 'A'){ + addAccountToSM(mirandaId, displayName); + } else if (type == 'C'){ + addContactToSM(mirandaId, (uint64_t)NULL, (uint64_t)1, displayName); + } + + return; +} + +void +SharedMemoryUtils::refreshMsm_Edit(char type, uint64_t mirandaId, std::wstring& displayName) +{ + logger->log_p(L"SharedMemoryUtils.refreshMsm_Edit type=[%c], mirandaId=[%I64u]", type, mirandaId); + + boost::ptr_list::iterator msmListIter; + for (msmListIter = msmList.begin(); msmListIter != msmList.end(); msmListIter++){ + + for (int recordNo = 0; recordNo < SMUCONST_MSM_RECORDS_COUNT; recordNo++ ){ + + boost::interprocess::mapped_region region1( + *msmListIter, + boost::interprocess::read_only, + SMUCONST_MSM_HEADER_SIZE + (recordNo * SMUCONST_MSM_RECORD_SIZE) + SMUCONST_MSM_RECORD_TYPE_RECOFFSET, + SMUCONST_MSM_RECORD_TYPE_SIZE + ); + char* recordTypePtr = static_cast(region1.get_address()); + + if (*recordTypePtr == type){ + + boost::interprocess::mapped_region region2( + *msmListIter, + boost::interprocess::read_only, + SMUCONST_MSM_HEADER_SIZE + (recordNo * SMUCONST_MSM_RECORD_SIZE) + SMUCONST_MSM_RECORD_HANDLE_RECOFFSET, + SMUCONST_MSM_RECORD_HANDLE_SIZE + ); + uint64_t* agcHandlePtr = static_cast(region2.get_address()); + + if (*agcHandlePtr == mirandaId){ + + boost::interprocess::mapped_region region3( + *msmListIter, + boost::interprocess::read_write, + SMUCONST_MSM_HEADER_SIZE + (recordNo * SMUCONST_MSM_RECORD_SIZE) + SMUCONST_MSM_RECORD_DNAME_RECOFFSET, + SMUCONST_MSM_RECORD_DNAME_SIZE + ); + wchar_t* recordValuePtr = static_cast(region3.get_address()); + wcsncpy_s(recordValuePtr, SMUCONST_MSM_RECORD_DNAME_SIZEC, displayName.c_str(), _TRUNCATE); + + logger->log(L"SharedMemoryUtils::refreshMsm_Edit record found and edited"); + + // unique record found and edited + return; + } + + } + + } + + } + + return; +} + + + +void +SharedMemoryUtils::refreshMsm_Delete(char type, uint64_t mirandaId) +{ + logger->log_p(L"SharedMemoryUtils.refreshMsm_Delete type=[%c], mirandaId=[%I64u]", type, mirandaId); + + boost::ptr_list::iterator msmListIter; + for (msmListIter = msmList.begin(); msmListIter != msmList.end(); msmListIter++){ + + for (int recordNo = 0; recordNo < SMUCONST_MSM_RECORDS_COUNT; recordNo++ ){ + + boost::interprocess::mapped_region region1( + *msmListIter, + boost::interprocess::read_write, + SMUCONST_MSM_HEADER_SIZE + (recordNo * SMUCONST_MSM_RECORD_SIZE) + SMUCONST_MSM_RECORD_TYPE_RECOFFSET, + SMUCONST_MSM_RECORD_TYPE_SIZE + ); + char* recordTypePtr = static_cast(region1.get_address()); + + if (*recordTypePtr == type){ + + boost::interprocess::mapped_region region2( + *msmListIter, + boost::interprocess::read_only, + SMUCONST_MSM_HEADER_SIZE + (recordNo * SMUCONST_MSM_RECORD_SIZE) + SMUCONST_MSM_RECORD_HANDLE_RECOFFSET, + SMUCONST_MSM_RECORD_HANDLE_SIZE + ); + uint64_t* agcHandlePtr = static_cast(region2.get_address()); + + if (*agcHandlePtr == mirandaId){ + + *recordTypePtr = 'D'; //[D] deleted - will not be read by other sm clients (even older) + + logger->log(L"SharedMemoryUtils::refreshMsm_Delete record found and deleted"); + + // unique record found and edited + return; + } + + } + + } + + } + + return; +} + + + + int SharedMemoryUtils::commitSM() { diff --git a/plugins/MirFox/src/MirFoxCommons/MirFoxCommons_sharedMemory.h b/plugins/MirFox/src/MirFoxCommons/MirFoxCommons_sharedMemory.h index 8ccc1494cf..8bed5e1624 100644 --- a/plugins/MirFox/src/MirFoxCommons/MirFoxCommons_sharedMemory.h +++ b/plugins/MirFox/src/MirFoxCommons/MirFoxCommons_sharedMemory.h @@ -93,6 +93,16 @@ public: //call after openOrCreateSM and after creating sm thread int commitSM(); + + // new functions to support refresh data in SM (compatible with v.4 SM version) + // add record in working Miranda shared memory + void refreshMsm_Add(char type, uint64_t mirandaId, std::wstring& displayName); + // edit record in working Miranda shared memory + void refreshMsm_Edit(char type, uint64_t mirandaId, std::wstring& displayName); + // remove record in working Miranda shared memory + void refreshMsm_Delete(char type, uint64_t mirandaId); + + //delete returned sm object after use boost::interprocess::windows_shared_memory* getSmById(const char* smName, std::size_t smSize); diff --git a/plugins/MirFox/src/MirandaInterface.cpp b/plugins/MirFox/src/MirandaInterface.cpp index 8b1b7a0e74..299a3635d6 100644 --- a/plugins/MirFox/src/MirandaInterface.cpp +++ b/plugins/MirFox/src/MirandaInterface.cpp @@ -46,6 +46,60 @@ extern "C" __declspec (dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirand } + + + +static int __cdecl onAccListChanged(WPARAM wParam, LPARAM lParam) +{ + if (mirfoxMiranda.getMirfoxData().Plugin_Terminated) return 0; + mirfoxMiranda.onAccListChanged(wParam, lParam); + return 0; +} + +static int __cdecl onContactAdded(WPARAM wParam, LPARAM) +{ + if (mirfoxMiranda.getMirfoxData().Plugin_Terminated) return 0; + OnContactAsyncThreadArgStruct* onContactAsyncThreadArgStruct = new(OnContactAsyncThreadArgStruct); + onContactAsyncThreadArgStruct->hContact = wParam; + onContactAsyncThreadArgStruct->mirfoxMiranda = &mirfoxMiranda; + mir_forkthread(CMirfoxMiranda::onContactAdded_async, onContactAsyncThreadArgStruct); + return 0; +} + +static int __cdecl onContactDeleted(WPARAM wParam, LPARAM) +{ + if (mirfoxMiranda.getMirfoxData().Plugin_Terminated) return 0; + mirfoxMiranda.onContactDeleted(wParam); + return 0; +} + +static int __cdecl onContactSettingChanged(WPARAM hContact, LPARAM lParam){ + + if (mirfoxMiranda.getMirfoxData().Plugin_Terminated) + return 0; + if (hContact == NULL || lParam == NULL) + return 0; + + DBCONTACTWRITESETTING* cws = (DBCONTACTWRITESETTING*)lParam; + if (!strcmp(cws->szModule, "CList")) { + + if (!strcmp(cws->szSetting, "Hidden")) { + mirfoxMiranda.onContactSettingChanged(hContact, lParam); + } + + if (!strcmp(cws->szSetting, "MyHandle")) { + OnContactAsyncThreadArgStruct* onContactAsyncThreadArgStruct = new(OnContactAsyncThreadArgStruct); + onContactAsyncThreadArgStruct->hContact = hContact; + onContactAsyncThreadArgStruct->mirfoxMiranda = &mirfoxMiranda; + mir_forkthread(CMirfoxMiranda::onContactSettingChanged_async, onContactAsyncThreadArgStruct); + } + } + + return 0; +} + + + /* * hook on ME_SYSTEM_MODULESLOADED at Load() */ @@ -72,6 +126,14 @@ static int onModulesLoaded(WPARAM, LPARAM) puc.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON_PE)); hPopupError = Popup_RegisterClass(&puc); + + //init refresh hooks + HookEvent(ME_PROTO_ACCLISTCHANGED, onAccListChanged); + HookEvent(ME_DB_CONTACT_ADDED, onContactAdded); + HookEvent(ME_DB_CONTACT_DELETED, onContactDeleted); + HookEvent(ME_DB_CONTACT_SETTINGCHANGED, onContactSettingChanged); + + return 0; } diff --git a/plugins/MirFox/src/MirandaOptions.cpp b/plugins/MirFox/src/MirandaOptions.cpp index 405cf4923f..b9dea187de 100644 --- a/plugins/MirFox/src/MirandaOptions.cpp +++ b/plugins/MirFox/src/MirandaOptions.cpp @@ -15,7 +15,7 @@ INT_PTR CALLBACK DlgProcOpts_Tab1(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM case WM_INITDIALOG: { //executed once, during each tab initialization during each miranda options open - mirfoxMiranda.getMirfoxData().setTab1OptionsState(MFENUM_OPTIONS_INIT); + mirfoxMiranda.getMirfoxData().tab1OptionsState = MFENUM_OPTIONS_INIT; TranslateDialogDefault(hwndDlg); @@ -41,6 +41,12 @@ INT_PTR CALLBACK DlgProcOpts_Tab1(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM //other options initialization + if (mirfoxMiranda.getMirfoxData().getAddAccountToContactNameCheckbox()){ + CheckDlgButton(hwndDlg, IDC1_CHECK2, BST_CHECKED); + } else { + CheckDlgButton(hwndDlg, IDC1_CHECK2, BST_UNCHECKED); + } + SetDlgItemText(hwndDlg, IDC1_EDIT1, mirfoxMiranda.getMirfoxData().getClientsProfilesFilterStringPtr()->c_str()); if (mirfoxMiranda.getMirfoxData().getClientsProfilesFilterCheckbox()){ @@ -50,32 +56,26 @@ INT_PTR CALLBACK DlgProcOpts_Tab1(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM CheckDlgButton(hwndDlg, IDC1_CHECK1, BST_UNCHECKED); EnableWindow(GetDlgItem(hwndDlg, IDC1_EDIT1), FALSE); } - //other options initialization - end + //other options initialization - end - mirfoxMiranda.getMirfoxData().setTab1OptionsState(MFENUM_OPTIONS_WORK); + mirfoxMiranda.getMirfoxData().tab1OptionsState = MFENUM_OPTIONS_WORK; return FALSE; } case WM_COMMAND: { - if (mirfoxMiranda.getMirfoxData().getTab1OptionsState() != MFENUM_OPTIONS_WORK){ + if (mirfoxMiranda.getMirfoxData().tab1OptionsState != MFENUM_OPTIONS_WORK){ break; //options not inited yet } //if user changed some options controls, send info to miranda to activate ok button if ( - ( ((HIWORD(wParam) == EN_CHANGE) && (HWND)lParam == GetFocus()) //edit control AND control from message has focus now || ((HIWORD(wParam) == BN_CLICKED) && (HWND)lParam == GetFocus()) //button or checkbox clicked AND control from message has focus now || (HIWORD(wParam) == CBN_DROPDOWN) //COMBOBOX clicked ) - && - ( - LOWORD(wParam) != IDC1_BUTTON_INVALIDATE //invalidate button click doesn't activate [Apply] button. - ) - ) { SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); } @@ -90,11 +90,6 @@ INT_PTR CALLBACK DlgProcOpts_Tab1(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM } - //if (LOWORD(wParam) == IDC1_BUTTON_INVALIDATE && HIWORD(wParam) == BN_CLICKED){ - //TODO invalidate button clicked - refresh MSM's (now this button has visable=false at .rc file) - //break; - //} - break; } case WM_NOTIFY: @@ -102,7 +97,7 @@ INT_PTR CALLBACK DlgProcOpts_Tab1(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM //executed on each move to another options tab or after [OK] - if (mirfoxMiranda.getMirfoxData().getTab1OptionsState() != MFENUM_OPTIONS_WORK){ + if (mirfoxMiranda.getMirfoxData().tab1OptionsState != MFENUM_OPTIONS_WORK){ break; //options not inited yet } @@ -126,6 +121,19 @@ INT_PTR CALLBACK DlgProcOpts_Tab1(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM db_set_b(0, PLUGIN_DB_ID, "clientsProfilesFilterCheckbox", 2); } + if (IsDlgButtonChecked(hwndDlg, IDC1_CHECK2) == BST_CHECKED){ + if (mirfoxMiranda.getMirfoxData().getAddAccountToContactNameCheckbox() != true){ + mirfoxMiranda.getMirfoxData().setAddAccountToContactNameCheckbox(true); + db_set_b(0, PLUGIN_DB_ID, "addAccountToContactNameCheckbox", 1); + mirfoxMiranda.getMirfoxData().updateAllMirandaContactsNames(mirfoxMiranda.getSharedMemoryUtils()); + } + } else { + if (mirfoxMiranda.getMirfoxData().getAddAccountToContactNameCheckbox() != false){ + mirfoxMiranda.getMirfoxData().setAddAccountToContactNameCheckbox(false); + db_set_b(0, PLUGIN_DB_ID, "addAccountToContactNameCheckbox", 2); + mirfoxMiranda.getMirfoxData().updateAllMirandaContactsNames(mirfoxMiranda.getSharedMemoryUtils()); + } + } int opt2Len = SendDlgItemMessage(hwndDlg, IDC1_EDIT1, WM_GETTEXTLENGTH, 0, 0); wchar_t * opt2Buffer = new WCHAR[opt2Len+1]; @@ -303,7 +311,7 @@ static void setAllChildIcons(HWND hwndList, HANDLE hFirstItem, int iColumn, int */ static void resetListOptions(HWND hwndList) { - SetWindowLongPtr(hwndList, GWL_STYLE, GetWindowLongPtr(hwndList,GWL_STYLE)|CLS_SHOWHIDDEN); + SetWindowLongPtr(hwndList, GWL_STYLE, GetWindowLongPtr(hwndList, GWL_STYLE) & ~CLS_SHOWHIDDEN); } @@ -323,7 +331,7 @@ INT_PTR CALLBACK DlgProcOpts_Tab2(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM { TranslateDialogDefault(hwndDlg); - mirfoxMiranda.getMirfoxData().setTab2OptionsState(MFENUM_OPTIONS_INIT); + mirfoxMiranda.getMirfoxData().tab2OptionsState = MFENUM_OPTIONS_INIT; //load icons HIMAGELIST hIml; @@ -359,7 +367,7 @@ INT_PTR CALLBACK DlgProcOpts_Tab2(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM setListGroupIcons(GetDlgItem(hwndDlg, IDC2_CONTACTS_LIST), (HANDLE)SendDlgItemMessage(hwndDlg, IDC2_CONTACTS_LIST, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll, NULL); - mirfoxMiranda.getMirfoxData().setTab2OptionsState(MFENUM_OPTIONS_WORK); + mirfoxMiranda.getMirfoxData().tab2OptionsState = MFENUM_OPTIONS_WORK; return FALSE; } @@ -370,7 +378,7 @@ INT_PTR CALLBACK DlgProcOpts_Tab2(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM case WM_NOTIFY: - if (mirfoxMiranda.getMirfoxData().getTab2OptionsState() != MFENUM_OPTIONS_WORK){ + if (mirfoxMiranda.getMirfoxData().tab2OptionsState != MFENUM_OPTIONS_WORK){ break; //options not inited yet } @@ -474,10 +482,7 @@ INT_PTR CALLBACK DlgProcOpts_Tab2(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM } //save to mirfoxData - int result = mirfoxMiranda.getMirfoxData().updateMirandaContactState(hContact, contactState); - if (result != 0){ - //todo errors handling - } + mirfoxMiranda.getMirfoxData().updateMirandaContactState(mirfoxMiranda.getSharedMemoryUtils(), hContact, contactState); //save to db 1 - on, 2 - off if (contactState == MFENUM_MIRANDACONTACT_STATE_OFF){ @@ -534,13 +539,13 @@ INT_PTR CALLBACK DlgProcOpts_Tab3(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM { //executed once during init of each tab, on each enter to miranda options - mirfoxMiranda.getMirfoxData().setTab3OptionsState(MFENUM_OPTIONS_INIT); + mirfoxMiranda.getMirfoxData().tab3OptionsState = MFENUM_OPTIONS_INIT; TranslateDialogDefault(hwndDlg); //protocol list initialization HWND hAccountsList = GetDlgItem(hwndDlg, IDC3_PROTOCOLS_LIST); - + ListView_DeleteAllItems(hAccountsList); ListView_SetExtendedListViewStyleEx(hAccountsList, LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES, LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES); LVCOLUMN lvCol = {0}; @@ -562,26 +567,26 @@ INT_PTR CALLBACK DlgProcOpts_Tab3(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lvItem.pszText = mirandaAccountsIter->tszAccountName; //http://www.experts-exchange.com/Programming/Languages/CPP/Q_20175412.html - must duplicate string lvItem.lParam = (LPARAM)_strdup(mirandaAccountsIter->szModuleName); - ListView_InsertItem(hAccountsList,&lvItem);//winapi function + int newItem = ListView_InsertItem(hAccountsList, &lvItem);//winapi function MFENUM_MIRANDAACCOUNT_STATE accountState = mirandaAccountsIter->accountState; if (accountState == MFENUM_MIRANDAACCOUNT_STATE_ON){ - ListView_SetCheckState(hAccountsList, lvItem.iItem, 1 ); + ListView_SetCheckState(hAccountsList, newItem, TRUE ); } else { - ListView_SetCheckState(hAccountsList, lvItem.iItem, 0 ); + ListView_SetCheckState(hAccountsList, newItem, FALSE ); } lvItem.iItem++; } - //protocol list initialization - end + //protocol list initialization - end - mirfoxMiranda.getMirfoxData().setTab3OptionsState(MFENUM_OPTIONS_WORK); + mirfoxMiranda.getMirfoxData().tab3OptionsState = MFENUM_OPTIONS_WORK; return FALSE; } case WM_COMMAND: { - if (mirfoxMiranda.getMirfoxData().getTab3OptionsState() != MFENUM_OPTIONS_WORK){ + if (mirfoxMiranda.getMirfoxData().tab3OptionsState != MFENUM_OPTIONS_WORK){ break; //options not inited yet } @@ -592,7 +597,7 @@ INT_PTR CALLBACK DlgProcOpts_Tab3(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM //executed on each change tab at options or after [OK] - if (mirfoxMiranda.getMirfoxData().getTab3OptionsState() != MFENUM_OPTIONS_WORK){ + if (mirfoxMiranda.getMirfoxData().tab3OptionsState != MFENUM_OPTIONS_WORK){ break; //options not inited yet } @@ -633,10 +638,7 @@ INT_PTR CALLBACK DlgProcOpts_Tab3(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM } //save to mirfoxData - int result = mirfoxMiranda.getMirfoxData().updateMirandaAccountState(accountId, accountState); - if (result != 0){ - //todo errors handling - } + mirfoxMiranda.getMirfoxData().updateMirandaAccountState(mirfoxMiranda.getSharedMemoryUtils(), accountId, accountState); //save to db 1 - on, 2 - off std::string mirandaAccountDBKey("ACCOUNTSTATE_"); diff --git a/plugins/MirFox/src/MirandaUtils.cpp b/plugins/MirFox/src/MirandaUtils.cpp index f442e52536..5743be7a08 100644 --- a/plugins/MirFox/src/MirandaUtils.cpp +++ b/plugins/MirFox/src/MirandaUtils.cpp @@ -199,7 +199,11 @@ void MirandaUtils::sendMessage(ActionThreadArgStruct* args, MFENUM_SEND_MESSAGE_ //show notyfication popup (only in SMM_ONLY_SEND mode) wchar_t* buffer = new wchar_t[1024 * sizeof(wchar_t)]; if (contactNameW != NULL && tszAccountName != NULL) - mir_sntprintf(buffer, 1024, TranslateT("Message sent to %s (%s)"), contactNameW, tszAccountName); + if (args->mirfoxDataPtr->getAddAccountToContactNameCheckbox()){ + mir_sntprintf(buffer, 1024, TranslateT("Message sent to %s"), contactNameW); + } else { + mir_sntprintf(buffer, 1024, TranslateT("Message sent to %s (%s)"), contactNameW, tszAccountName); + } else mir_sntprintf(buffer, 1024, TranslateT("Message sent")); @@ -213,10 +217,7 @@ void MirandaUtils::sendMessage(ActionThreadArgStruct* args, MFENUM_SEND_MESSAGE_ else if (mode == MFENUM_SMM_SEND_AND_SHOW_MW){ //notify hook to open window if (args->mirfoxDataPtr != NULL && args->mirfoxDataPtr->hhook_EventOpenMW != NULL){ - OnHookOpenMvStruct* onHookOpenMv = new(OnHookOpenMvStruct); - onHookOpenMv->targetHandle = args->targetHandle; - onHookOpenMv->msgBuffer = NULL; - NotifyEventHooks(args->mirfoxDataPtr->hhook_EventOpenMW, (WPARAM)onHookOpenMv, 0); + notifyHookToOpenMsgWindow(args, false); } else logger->log(L"SMTC: ERROR1 args->mirfoxDataPtr == NULL || args->mirfoxDataPtr->hhook_EventOpenMW == NULL"); } @@ -254,6 +255,14 @@ void MirandaUtils::sendMessage(ActionThreadArgStruct* args, MFENUM_SEND_MESSAGE_ PUShowMessageT(buffer, SM_WARNING); } + //if MFENUM_SMM_SEND_AND_SHOW_MW, even if error sending message - notify hook to open window + if (mode == MFENUM_SMM_SEND_AND_SHOW_MW){ + if (args->mirfoxDataPtr != NULL && args->mirfoxDataPtr->hhook_EventOpenMW != NULL){ + notifyHookToOpenMsgWindow(args, true); + } + else logger->log(L"SMTC: ERROR2 args->mirfoxDataPtr == NULL || args->mirfoxDataPtr->hhook_EventOpenMW == NULL"); + } + delete[] buffer; } @@ -267,19 +276,11 @@ void MirandaUtils::sendMessage(ActionThreadArgStruct* args, MFENUM_SEND_MESSAGE_ LeaveCriticalSection(&ackMapCs); } else if (mode == MFENUM_SMM_ONLY_SHOW_MW) { - //notify hook to open window + //notify hook to open msg window if (args->mirfoxDataPtr != NULL && args->mirfoxDataPtr->hhook_EventOpenMW != NULL){ - - OnHookOpenMvStruct* onHookOpenMv = new(OnHookOpenMvStruct); - onHookOpenMv->targetHandle = args->targetHandle; - //adding newline to message in Message Window, only in this mode - std::wstring* msgBuffer = new std::wstring(); //deleted at on_hook_OpenMW - msgBuffer->append(args->userActionSelection); - msgBuffer->append(L"\r\n"); - onHookOpenMv->msgBuffer = msgBuffer; - NotifyEventHooks(args->mirfoxDataPtr->hhook_EventOpenMW, (WPARAM)onHookOpenMv, 0); + notifyHookToOpenMsgWindow(args, true); } - else logger->log(L"SMTC: ERROR1 args->mirfoxDataPtr == NULL || args->mirfoxDataPtr->hhook_EventOpenMW == NULL"); + else logger->log(L"SMTC: ERROR3 args->mirfoxDataPtr == NULL || args->mirfoxDataPtr->hhook_EventOpenMW == NULL"); } } @@ -301,6 +302,23 @@ void MirandaUtils::addMessageToDB(MCONTACT hContact, char* msgBuffer, std::size_ db_event_add(hContact, &dbei); } +void MirandaUtils::notifyHookToOpenMsgWindow(ActionThreadArgStruct* args, bool showMessageToSend) +{ + OnHookOpenMvStruct* onHookOpenMv = new(OnHookOpenMvStruct); + onHookOpenMv->targetHandle = args->targetHandle; + if (showMessageToSend){ + //adding newline to message in Message Window, only in this mode + std::wstring* msgBuffer = new std::wstring(); //deleted at on_hook_OpenMW + msgBuffer->append(args->userActionSelection); + msgBuffer->append(L"\r\n"); + onHookOpenMv->msgBuffer = msgBuffer; + } else { + onHookOpenMv->msgBuffer = NULL; + } + + NotifyEventHooks(args->mirfoxDataPtr->hhook_EventOpenMW, (WPARAM)onHookOpenMv, 0); +} + //http://www.shloemi.com/2012/09/solved-setforegroundwindow-win32-api-not-always-works/ void MirandaUtils::ForceForegroundWindow(HWND hWnd) diff --git a/plugins/MirFox/src/MirandaUtils.h b/plugins/MirFox/src/MirandaUtils.h index f43c7c0f67..f08b90da5f 100644 --- a/plugins/MirFox/src/MirandaUtils.h +++ b/plugins/MirFox/src/MirandaUtils.h @@ -82,6 +82,8 @@ private: void addMessageToDB(MCONTACT hContact, char* msgBuffer, std::size_t bufSize, char* targetHandleSzProto); + void notifyHookToOpenMsgWindow(ActionThreadArgStruct* args, bool showMessageToSend); + void setStatusOnAccount(ActionThreadArgStruct* args); void onProtoAckOnInstance(ACKDATA* ack); diff --git a/plugins/MirFox/src/MirfoxData.cpp b/plugins/MirFox/src/MirfoxData.cpp index de8c16b1dd..22eb70e504 100644 --- a/plugins/MirFox/src/MirfoxData.cpp +++ b/plugins/MirFox/src/MirfoxData.cpp @@ -16,6 +16,7 @@ MirfoxData::MirfoxData(void) pluginState = MFENUM_PLUGIN_STATE_NEW; tab1OptionsState = MFENUM_OPTIONS_NEW; tab2OptionsState = MFENUM_OPTIONS_NEW; + tab3OptionsState = MFENUM_OPTIONS_NEW; Plugin_Terminated = false; workerThreadsCount = 0; @@ -27,6 +28,11 @@ MirfoxData::MirfoxData(void) middleClickSendMode = MFENUM_SMM_ONLY_SEND; processCsmId = 0; + hhook_EventOpenMW = NULL; + hhook_OpenMW = NULL; + + mirfoxAccountIdPool = 1; + maxAccountIOrder = 0; } MirfoxData::~MirfoxData(void) @@ -49,14 +55,22 @@ void MirfoxData::clearMirandaContacts(){ } int -MirfoxData::updateMirandaContactState(MCONTACT contactHandle, MFENUM_MIRANDACONTACT_STATE & contactState) +MirfoxData::updateMirandaContactState(SharedMemoryUtils& sharedMemoryUtils, MCONTACT contactHandle, MFENUM_MIRANDACONTACT_STATE & contactState) { boost::ptr_list* mirandaContactsPtr = getMirandaContacts(); boost::ptr_list::iterator mirandaContactsIter; for (mirandaContactsIter = mirandaContactsPtr->begin(); mirandaContactsIter != mirandaContactsPtr->end(); mirandaContactsIter++){ if (mirandaContactsIter->contactHandle == contactHandle ){ + MFENUM_MIRANDACONTACT_STATE oldState = mirandaContactsIter->contactState; mirandaContactsIter->contactState = contactState; + if (contactState != oldState ){ + if (contactState == MFENUM_MIRANDACONTACT_STATE_ON){ + sharedMemoryUtils.refreshMsm_Add('C', (uint64_t)mirandaContactsIter->contactHandle, mirandaContactsIter->contactNameW); + } else { + sharedMemoryUtils.refreshMsm_Delete('C', (uint64_t)mirandaContactsIter->contactHandle); + } + } return 0; } } @@ -64,6 +78,26 @@ MirfoxData::updateMirandaContactState(MCONTACT contactHandle, MFENUM_MIRANDACONT } +int +MirfoxData::updateAllMirandaContactsNames(SharedMemoryUtils& sharedMemoryUtils) +{ + + boost::ptr_list* mirandaContactsPtr = getMirandaContacts(); + boost::ptr_list::iterator mirandaContactsIter; + for (mirandaContactsIter = mirandaContactsPtr->begin(); mirandaContactsIter != mirandaContactsPtr->end(); mirandaContactsIter++){ + + setContactDisplayName(mirandaContactsIter->getObjectPtr()); + + if (mirandaContactsIter->contactState == MFENUM_MIRANDACONTACT_STATE_ON){ + sharedMemoryUtils.refreshMsm_Edit('C', (uint64_t)mirandaContactsIter->contactHandle, mirandaContactsIter->contactNameW); + } + + } + return 0; + +} + + MirandaContact* MirfoxData::getMirandaContactPtrByHandle(MCONTACT contactHandle){ @@ -89,6 +123,31 @@ MirfoxData::getMirandaContactPtrByHandle(MCONTACT contactHandle){ } +void +MirfoxData::setContactDisplayName(MirandaContact* mirandaContact){ + + if (mirandaContact->mirandaAccountPtr != NULL && strcmp(mirandaContact->mirandaAccountPtr->szProtoName, "Twitter") == 0){ + // hack for Twitter protocol + DBVARIANT dbv; + if (!db_get_s(mirandaContact->contactHandle, mirandaContact->mirandaAccountPtr->szModuleName, "Username", &dbv, DBVT_WCHAR)) { + mirandaContact->contactNameW = std::wstring(dbv.pwszVal); + db_free(&dbv); + } + } else { + // standard miranda way for another protocols + mirandaContact->contactNameW = pcli->pfnGetContactDisplayName(mirandaContact->contactHandle, 0); + } + + if (getAddAccountToContactNameCheckbox()){ + mirandaContact->contactNameW = mirandaContact->contactNameW.append(L" (").append(mirandaContact->mirandaAccountPtr->tszAccountName).append(L")"); + + } + + MFLogger::getInstance()->log_p(L"initializeMirandaContacts: got name for hContact = [" SCNuPTR L"] is: [%s]", mirandaContact->contactHandle, + &(mirandaContact->contactNameW)==NULL ? L"" : mirandaContact->contactNameW.c_str()); + +} + //Accounts @@ -105,14 +164,23 @@ void MirfoxData::clearMirandaAccounts(){ } int -MirfoxData::updateMirandaAccountState(char* szModuleName, MFENUM_MIRANDAACCOUNT_STATE& accountState) +MirfoxData::updateMirandaAccountState(SharedMemoryUtils& sharedMemoryUtils, char* szModuleName, MFENUM_MIRANDAACCOUNT_STATE& accountState) { boost::ptr_list* mirandaAccountsPtr = getMirandaAccounts(); boost::ptr_list::iterator mirandaAccountsIter; for (mirandaAccountsIter = mirandaAccountsPtr->begin(); mirandaAccountsIter != mirandaAccountsPtr->end(); mirandaAccountsIter++){ if (strcmp(mirandaAccountsIter->szModuleName, szModuleName) == 0 ){ + MFENUM_MIRANDAACCOUNT_STATE oldState = mirandaAccountsIter->accountState; mirandaAccountsIter->accountState = accountState; + if (accountState != oldState ){ + if (accountState == MFENUM_MIRANDAACCOUNT_STATE_ON){ + std::wstring tszAccountNameW = mirandaAccountsIter->tszAccountName; + sharedMemoryUtils.refreshMsm_Add('A', (uint64_t)mirandaAccountsIter->id, tszAccountNameW); + } else { + sharedMemoryUtils.refreshMsm_Delete('A', (uint64_t)mirandaAccountsIter->id); + } + } return 0; } } @@ -174,6 +242,187 @@ MirfoxData::getMirandaAccountPtrBySzModuleName(char* szModuleName) + +// refresh support + +void MirfoxData::refreshAccount_Add(SharedMemoryUtils& sharedMemoryUtils, char* szModuleName, TCHAR* tszAccountName, char* szProtoName) +{ + MFLogger* logger = MFLogger::getInstance(); + logger->log_p(L"MirfoxData::refreshAccount_Add proto [%S]", szModuleName); + + //add proto to mirandaAccounts + mirfoxAccountIdPool++; + maxAccountIOrder++; + + MirandaAccount* mirandaAccountItemPtr = new MirandaAccount( + mirfoxAccountIdPool, + szModuleName, + tszAccountName, + szProtoName, + maxAccountIOrder + ); + + mirandaAccountItemPtr->accountState = createOrGetAccountStateFromDB(mirandaAccountItemPtr); + + /* + MFENUM_MIRANDAACCOUNT_STATE getOrCreateAccountStateInDB(char* szModuleName); + std::string mirandaAccountDBKey("ACCOUNTSTATE_"); + mirandaAccountDBKey += szModuleName; + int keyValue = db_get_b(0, PLUGIN_DB_ID, mirandaAccountDBKey.c_str(), 0); + if (keyValue == 1 || keyValue == 2){ + //setting exist + if (keyValue == 1){ + mirandaAccountItemPtr->accountState = MFENUM_MIRANDAACCOUNT_STATE_ON; //1 + } else { + mirandaAccountItemPtr->accountState = MFENUM_MIRANDAACCOUNT_STATE_OFF; //2 + } + } else { + //setting does not exist, or is invalid -> save default setting (1 - ON) + if (getAccountDefaultState(mirandaAccountItemPtr) == 1){ //on = 1 + mirandaAccountItemPtr->accountState = MFENUM_MIRANDAACCOUNT_STATE_ON; //1 + db_set_b(0, PLUGIN_DB_ID, mirandaAccountDBKey.c_str(), 1); + } else { //off = 2 + mirandaAccountItemPtr->accountState = MFENUM_MIRANDAACCOUNT_STATE_OFF; //2 + db_set_b(0, PLUGIN_DB_ID, mirandaAccountDBKey.c_str(), 2); + } + } + */ + addMirandaAccount(mirandaAccountItemPtr); + + //add proto to SM + std::wstring tszAccountNameW = mirandaAccountItemPtr->tszAccountName; + sharedMemoryUtils.refreshMsm_Add('A', mirandaAccountItemPtr->id, tszAccountNameW); + + return; +} + +void MirfoxData::refreshAccount_Edit(SharedMemoryUtils& sharedMemoryUtils, char* szModuleName, TCHAR* tszAccountName) +{ + MFLogger* logger = MFLogger::getInstance(); + logger->log_p(L"MirfoxData::refreshAccount_Edit proto [%S]", szModuleName); + + //edit proto in mirandaAccounts + MirandaAccount* mirandaAccount = getMirandaAccountPtrBySzModuleName(szModuleName); + if (!mirandaAccount){ + logger->log(L"MirfoxData::refreshAccount_Edit edit proto not found in mirandaAccounts"); + return; + } + + mirandaAccount->tszAccountName = tszAccountName; + + //edit proto in SM + std::wstring tszAccountNameW = mirandaAccount->tszAccountName; + sharedMemoryUtils.refreshMsm_Edit('A', mirandaAccount->id, tszAccountNameW); + + return; +} + +void MirfoxData::refreshAccount_Delete(SharedMemoryUtils& sharedMemoryUtils, char* szModuleName) +{ + MFLogger* logger = MFLogger::getInstance(); + logger->log_p(L"MirfoxData::refreshAccount_Delete proto [%S]", szModuleName); + + uint64_t deletedId; + + //del proto in mirandaAccounts + boost::ptr_list* mirandaAccountsPtr = getMirandaAccounts(); + boost::ptr_list::iterator mirandaAccountsIter; + for (mirandaAccountsIter = mirandaAccountsPtr->begin(); mirandaAccountsIter != mirandaAccountsPtr->end(); mirandaAccountsIter++){ + if (mirandaAccountsIter->szModuleName != NULL && strcmp(mirandaAccountsIter->szModuleName, szModuleName) == 0){ + deletedId = mirandaAccountsIter->id; + mirandaAccountsPtr->erase(mirandaAccountsIter); + break; + } + } + + std::string mirandaAccountDBKey("ACCOUNTSTATE_"); + mirandaAccountDBKey += szModuleName; + db_unset(0, PLUGIN_DB_ID, mirandaAccountDBKey.c_str()); + + //del proto from SM + sharedMemoryUtils.refreshMsm_Delete('A', deletedId); + + return; +} + +void MirfoxData::refreshContact_Add(SharedMemoryUtils& sharedMemoryUtils, MCONTACT hContact) +{ + MFLogger* logger = MFLogger::getInstance(); + logger->log_p(L"MirfoxData::refreshContact_Add hContact [" SCNuPTR L"]", hContact); + + //add contact to mirandaContacts + MirandaContact* mirandaContactItemPtr = new MirandaContact( + hContact //handle to contact in miranda + ); + + char *szModuleName = Proto_GetBaseAccountName(mirandaContactItemPtr->contactHandle); + if (szModuleName != NULL) + mirandaContactItemPtr->mirandaAccountPtr = getMirandaAccountPtrBySzModuleName(szModuleName); + + // Always getting '(Unknown Contact)' here if called from HookEvent ME_DB_CONTACT_ADDED, (updated to proper via ME_DB_CONTACT_SETTINGCHANGED) + setContactDisplayName(mirandaContactItemPtr); + + mirandaContactItemPtr->contactState = createOrGetContactStateFromDB(mirandaContactItemPtr); + + addMirandaContact(mirandaContactItemPtr); + + + //add contact to SM + sharedMemoryUtils.refreshMsm_Add('C', (uint64_t)mirandaContactItemPtr->contactHandle, mirandaContactItemPtr->contactNameW); + + + return; +} + +void MirfoxData::refreshContact_Edit(SharedMemoryUtils& sharedMemoryUtils, MCONTACT hContact) +{ + MFLogger* logger = MFLogger::getInstance(); + logger->log_p(L"MirfoxData::refreshContact_Edit hContact [" SCNuPTR L"]", hContact); + + + MirandaContact* mirandaContact = getMirandaContactPtrByHandle(hContact); + + if (!mirandaContact){ + logger->log(L"refreshContact_Edit edited contact not found in mirandaContactss"); + return; + } + + setContactDisplayName(mirandaContact); + + + // edit contact in SM + sharedMemoryUtils.refreshMsm_Edit('C', (uint64_t)mirandaContact->contactHandle, mirandaContact->contactNameW); + + + return; +} + +void MirfoxData::refreshContact_Delete(SharedMemoryUtils& sharedMemoryUtils, MCONTACT hContact) +{ + MFLogger* logger = MFLogger::getInstance(); + logger->log_p(L"MirfoxData::refreshContact_Delete hContact [" SCNuPTR L"]", hContact); + + //del contact from mirandaContacts + boost::ptr_list* mirandaContactsPtr = getMirandaContacts(); + boost::ptr_list::iterator mirandaContactsIter; + for (mirandaContactsIter = mirandaContactsPtr->begin(); mirandaContactsIter != mirandaContactsPtr->end(); mirandaContactsIter++){ + if (mirandaContactsIter->contactHandle == hContact ){ + mirandaContactsPtr->erase(mirandaContactsIter); + break; + } + } + + + //del contact from SM + sharedMemoryUtils.refreshMsm_Delete('C', (uint64_t)hContact); + + + return; +} + + + + //options //get ptr to clientsProfilesFilterWString std::string @@ -202,9 +451,9 @@ void MirfoxData::initializeMirfoxData() { + initializeOptions(); initializeMirandaAccounts(); //must be before initializeMirandaContacts initializeMirandaContacts(); - initializeOptions(); } @@ -272,12 +521,61 @@ MirfoxData::getContactDefaultState(MirandaContact* contact) if (!shouldProtoBeActiveByName(contact->mirandaAccountPtr->szProtoName)) return 2; - if (db_get_b(contact->contactHandle, "CList", "Hidden", 0) == 1 || db_get_b(contact->contactHandle, "CList", "NotOnList", 0) == 1 ) - return 2; - return 1; } + +MFENUM_MIRANDAACCOUNT_STATE +MirfoxData::createOrGetAccountStateFromDB(MirandaAccount* mirandaAccount){ + + std::string mirandaAccountDBKey("ACCOUNTSTATE_"); + mirandaAccountDBKey += mirandaAccount->szModuleName; + int keyValue = db_get_b(0, PLUGIN_DB_ID, mirandaAccountDBKey.c_str(), 0); + if (keyValue == 1 || keyValue == 2){ + //setting exist + if (keyValue == 1){ + return MFENUM_MIRANDAACCOUNT_STATE_ON; //1 + } else { + return MFENUM_MIRANDAACCOUNT_STATE_OFF; //2 + } + } else { + //setting does not exist, or is invalid -> save default setting (1 - ON) + if (getAccountDefaultState(mirandaAccount) == 1){ //on = 1 + db_set_b(0, PLUGIN_DB_ID, mirandaAccountDBKey.c_str(), 1); + return MFENUM_MIRANDAACCOUNT_STATE_ON; //1 + } else { //off = 2 + db_set_b(0, PLUGIN_DB_ID, mirandaAccountDBKey.c_str(), 2); + return MFENUM_MIRANDAACCOUNT_STATE_OFF; //2 + } + } + +} + +MFENUM_MIRANDACONTACT_STATE +MirfoxData::createOrGetContactStateFromDB(MirandaContact* mirandaContact){ + + int keyValue = db_get_b(mirandaContact->contactHandle, PLUGIN_DB_ID, "state", 0); + if (keyValue == 1 || keyValue == 2){ + //setting exist + if (keyValue == 1){ + return MFENUM_MIRANDACONTACT_STATE_ON; //1 + } else { + return MFENUM_MIRANDACONTACT_STATE_OFF; //2 + } + } else { + //setting does not exist, or is invalid -> save default setting (1 - ON) + if (MirfoxData::getContactDefaultState(mirandaContact->getObjectPtr()) == 1){ //on = 1 + db_set_b(mirandaContact->contactHandle, PLUGIN_DB_ID, "state", 1); + return MFENUM_MIRANDACONTACT_STATE_ON; //1 + } else { //off = 2 + db_set_b(mirandaContact->contactHandle, PLUGIN_DB_ID, "state", 2); + return MFENUM_MIRANDACONTACT_STATE_OFF; //2 + } + } + +} + + void MirfoxData::initializeMirandaAccounts() { @@ -288,8 +586,6 @@ MirfoxData::initializeMirandaAccounts() PROTOACCOUNT **accounts; Proto_EnumAccounts(&accountsCount, &accounts); - uint64_t protocolId = 1; - for(int i=0; iszModuleName, accounts[i]->tszAccountName, accounts[i]->szProtoName, @@ -312,29 +608,10 @@ MirfoxData::initializeMirandaAccounts() MFLogger* logger = MFLogger::getInstance(); logger->log_p(L"initializeMirandaAccounts: tszAccountName: [%s] protocol: [%S]", accounts[i]->tszAccountName, accounts[i]->szProtoName ); - protocolId++; + mirfoxAccountIdPool++; + if (accounts[i]->iOrder > maxAccountIOrder) maxAccountIOrder = accounts[i]->iOrder; - std::string mirandaAccountDBKey("ACCOUNTSTATE_"); - mirandaAccountDBKey += accounts[i]->szModuleName; - - int keyValue = db_get_b(0, PLUGIN_DB_ID, mirandaAccountDBKey.c_str(), 0); - if (keyValue == 1 || keyValue == 2){ - //setting exist - if (keyValue == 1){ - mirandaAccountItemPtr->accountState = MFENUM_MIRANDAACCOUNT_STATE_ON; //1 - } else { - mirandaAccountItemPtr->accountState = MFENUM_MIRANDAACCOUNT_STATE_OFF; //2 - } - } else { - //setting does not exist, or is invalid -> save default setting (1 - ON) - if (MirfoxData::getAccountDefaultState(mirandaAccountItemPtr) == 1){ //on = 1 - mirandaAccountItemPtr->accountState = MFENUM_MIRANDAACCOUNT_STATE_ON; //1 - db_set_b(0, PLUGIN_DB_ID, mirandaAccountDBKey.c_str(), 1); - } else { //off = 2 - mirandaAccountItemPtr->accountState = MFENUM_MIRANDAACCOUNT_STATE_OFF; //2 - db_set_b(0, PLUGIN_DB_ID, mirandaAccountDBKey.c_str(), 2); - } - } + mirandaAccountItemPtr->accountState = createOrGetAccountStateFromDB(mirandaAccountItemPtr); addMirandaAccount(mirandaAccountItemPtr); @@ -355,11 +632,16 @@ void MirfoxData::initializeMirandaContacts() //get contects from miranda for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)){ - //add to list + + //"Hidden" contacts not allowed in MirfoxData and SM, "NotOnList" contacts allowed and enabled + if (db_get_b(hContact, "CList", "Hidden", 0) == 1) continue; + + //add to MirfoxData list MirandaContact* mirandaContactItemPtr = new MirandaContact( hContact //handle to contact in miranda ); addMirandaContact(mirandaContactItemPtr); + } @@ -376,75 +658,39 @@ void MirfoxData::initializeMirandaContacts() continue; //mirandaContactsIter->mirandaAccountPtr will be NULL mirandaContactsIter->mirandaAccountPtr = getMirandaAccountPtrBySzModuleName(szModuleName); - } - - //determine contact's name - for (mirandaContactsIter = mirandaContactsPtr->begin(); mirandaContactsIter != mirandaContactsPtr->end(); mirandaContactsIter++){ + //determine contact's name + setContactDisplayName(mirandaContactsIter->getObjectPtr()); - logger->log_p(L"initializeMirandaContacts: try to get name for hContact = [" SCNuPTR L"]", mirandaContactsIter->contactHandle); - - if (mirandaContactsIter->mirandaAccountPtr != NULL){ - if (strcmp(mirandaContactsIter->mirandaAccountPtr->szProtoName, "Twitter") == 0){ - // hack for Twitter protocol - - DBVARIANT dbv; - if (!db_get_s(mirandaContactsIter->contactHandle, mirandaContactsIter->mirandaAccountPtr->szModuleName, "Username", &dbv, DBVT_WCHAR)) { - mirandaContactsIter->contactNameW = std::wstring(dbv.pwszVal); - db_free(&dbv); - } - } - else // standard miranda way for another protocols - mirandaContactsIter->contactNameW = pcli->pfnGetContactDisplayName(mirandaContactsIter->contactHandle, 0); - } + //determine contact's state + mirandaContactsIter->contactState = createOrGetContactStateFromDB(mirandaContactsIter->getObjectPtr()); - if (mirandaContactsIter->contactNameW.size() == 0) - // last chance (if some hack didn't work or mirandaContactsIter->mirandaAccountPtr is NULL) - mirandaContactsIter->contactNameW = pcli->pfnGetContactDisplayName(mirandaContactsIter->contactHandle, 0); + } - logger->log_p(L"initializeMirandaContacts: got name for hContact = [" SCNuPTR L"] is: [%s]", mirandaContactsIter->contactHandle, - &(mirandaContactsIter->contactNameW)==NULL ? L"" : mirandaContactsIter->contactNameW.c_str()); +} - } - //determine contact's state - for (mirandaContactsIter = mirandaContactsPtr->begin(); mirandaContactsIter != mirandaContactsPtr->end(); mirandaContactsIter++){ - logger->log_p(L"initializeMirandaContacts: try to get state for hContact = [" SCNuPTR L"]", mirandaContactsIter->contactHandle); +void MirfoxData::initializeOptions() +{ - int keyValue = db_get_b(mirandaContactsIter->contactHandle, PLUGIN_DB_ID, "state", 0); - if (keyValue == 1 || keyValue == 2){ - //setting exist - if (keyValue == 1){ - mirandaContactsIter->contactState = MFENUM_MIRANDACONTACT_STATE_ON; //1 - } else { - mirandaContactsIter->contactState = MFENUM_MIRANDACONTACT_STATE_OFF; //2 - } + //addAccountToContactNameCheckbox + int opt2KeyValue = db_get_b(0, PLUGIN_DB_ID, "addAccountToContactNameCheckbox", 0); + if (opt2KeyValue == 1 || opt2KeyValue == 2){ + //setting exist + if (opt2KeyValue == 1){ + setAddAccountToContactNameCheckbox(true); //1 } else { - //setting does not exist, or is invalid -> save default setting (1 - ON) - if (MirfoxData::getContactDefaultState(mirandaContactsIter->getObjectPtr()) == 1){ //on = 1 - mirandaContactsIter->contactState = MFENUM_MIRANDACONTACT_STATE_ON; //1 - db_set_b(mirandaContactsIter->contactHandle, PLUGIN_DB_ID, "state", 1); - } else { //off = 2 - mirandaContactsIter->contactState = MFENUM_MIRANDACONTACT_STATE_OFF; //2 - db_set_b(mirandaContactsIter->contactHandle, PLUGIN_DB_ID, "state", 2); - } + setAddAccountToContactNameCheckbox(false); //2 } - + } else { + //setting does not exist, or is invalid -> save default setting (2 - false) + setAddAccountToContactNameCheckbox(false); //2 + db_set_b(0, PLUGIN_DB_ID, "addAccountToContactNameCheckbox", 2); } - -} - - - - - -void MirfoxData::initializeOptions() -{ - //clientsProfilesFilterCheckbox int opt1KeyValue = db_get_b(0, PLUGIN_DB_ID, "clientsProfilesFilterCheckbox", 0); if (opt1KeyValue == 1 || opt1KeyValue == 2){ diff --git a/plugins/MirFox/src/MirfoxData.h b/plugins/MirFox/src/MirfoxData.h index 746abb0d82..4806745396 100644 --- a/plugins/MirFox/src/MirfoxData.h +++ b/plugins/MirFox/src/MirfoxData.h @@ -78,83 +78,38 @@ public: pluginState = pluginStateL; } - //inline - //get current tab1 options state MFENUM_OPTIONS_STATE - MFENUM_OPTIONS_STATE getTab1OptionsState() const { - return tab1OptionsState; - } - //inline - //set current tab1 options state MFENUM_OPTIONS_STATE - void setTab1OptionsState(MFENUM_OPTIONS_STATE tab1OptionsStateL){ - tab1OptionsState = tab1OptionsStateL; - } - //inline - //get current tab2 options state MFENUM_OPTIONS_STATE - MFENUM_OPTIONS_STATE getTab2OptionsState() const { - return tab2OptionsState; - } - //inline - //set current tab2 options state MFENUM_OPTIONS_STATE - void setTab2OptionsState(MFENUM_OPTIONS_STATE tab2OptionsStateL){ - tab2OptionsState = tab2OptionsStateL; - } - //inline - //get current tab1 options state MFENUM_OPTIONS_STATE - MFENUM_OPTIONS_STATE getTab3OptionsState() const { - return tab3OptionsState; - } - //inline - //set current tab1 options state MFENUM_OPTIONS_STATE - void setTab3OptionsState(MFENUM_OPTIONS_STATE tab3OptionsStateL){ - tab3OptionsState = tab3OptionsStateL; - } - - - static bool shouldProtoBeActiveByName(std::string protoName); - - int getAccountDefaultState(MirandaAccount* account); - - int getContactDefaultState(MirandaContact* hContact); //Contacts - //add MirandaContact item to list of MirandaContacts - void addMirandaContact(MirandaContact* mirandaContactL); //get list of MirandaAContacts boost::ptr_list* getMirandaContacts(); - //clears list of MirandaContacts - void clearMirandaContacts(); - //update MirandaContact's state by id //return 0 - ok, - int updateMirandaContactState(MCONTACT contactHandle, MFENUM_MIRANDACONTACT_STATE & contactState); + int updateMirandaContactState(SharedMemoryUtils& sharedMemoryUtils, MCONTACT contactHandle, MFENUM_MIRANDACONTACT_STATE & contactState); + + //update All MirandaContact's names + //return 0 - ok, + int updateAllMirandaContactsNames(SharedMemoryUtils& sharedMemoryUtils); //return MirandaContact* by HANDLE MirandaContact* getMirandaContactPtrByHandle(MCONTACT contactHandle); - - //Accounts - //add MirandaAccount item to list of MirandaAccounts - void addMirandaAccount(MirandaAccount* mirandaAccountL); //get list of MirandaAccounts boost::ptr_list* getMirandaAccounts(); - //clears list of MirandaAccounts - void clearMirandaAccounts(); - //update MirandaAccount's state by id //return 0 - ok, - int updateMirandaAccountState(char* szModuleName, MFENUM_MIRANDAACCOUNT_STATE& accountState); + int updateMirandaAccountState(SharedMemoryUtils& sharedMemoryUtils, char* szModuleName, MFENUM_MIRANDAACCOUNT_STATE& accountState); //you MUST delete returned char* (if it is not NULL) char* getAccountSzModuleNameById(uint64_t id); @@ -162,8 +117,21 @@ public: //return MirandaAccount* by szModuleName MirandaAccount* getMirandaAccountPtrBySzModuleName(char* szModuleName); + //refresh data support + void refreshAccount_Add(SharedMemoryUtils& sharedMemoryUtils, char* szModuleName, TCHAR* tszAccountName, char* szProtoName); + void refreshAccount_Edit(SharedMemoryUtils& sharedMemoryUtils, char* szModuleName, TCHAR* tszAccountName); + void refreshAccount_Delete(SharedMemoryUtils& sharedMemoryUtils, char* szModuleName); + void refreshContact_Add(SharedMemoryUtils& sharedMemoryUtils, MCONTACT hContact); + void refreshContact_Edit(SharedMemoryUtils& sharedMemoryUtils, MCONTACT hContact); + void refreshContact_Delete(SharedMemoryUtils& sharedMemoryUtils, MCONTACT hContact); + //options + + MFENUM_OPTIONS_STATE tab1OptionsState; + MFENUM_OPTIONS_STATE tab2OptionsState; + MFENUM_OPTIONS_STATE tab3OptionsState; + //inline //get clientsProfilesFilterCheckbox bool bool getClientsProfilesFilterCheckbox() const { @@ -182,6 +150,19 @@ public: //normalize clientsProfilesFilterString void normalizeClientsProfilesFilterString(std::size_t maxCSize); + //inline + //get addAccountToContactNameCheckbox bool + bool getAddAccountToContactNameCheckbox() const { + return addAccountToContactNameCheckbox; + } + + //inline + //set addAccountToContactNameCheckbox bool + void setAddAccountToContactNameCheckbox(bool addAccountToContactNameCheckboxL){ + addAccountToContactNameCheckbox = addAccountToContactNameCheckboxL; + } + + //id of process record in csm uint16_t processCsmId; @@ -193,7 +174,6 @@ public: void initializeMirfoxData(); - void releaseMirfoxData(); @@ -204,10 +184,6 @@ private: // @see MFENUM_PLUGINSTATE MFENUM_PLUGIN_STATE pluginState; - MFENUM_OPTIONS_STATE tab1OptionsState; - MFENUM_OPTIONS_STATE tab2OptionsState; - MFENUM_OPTIONS_STATE tab3OptionsState; - // list of pointers to MirandaAccount class instances boost::ptr_list mirandaAccounts; @@ -215,6 +191,15 @@ private: //initialize accounts list void initializeMirandaAccounts(); + uint64_t mirfoxAccountIdPool; + int maxAccountIOrder; + + //add MirandaAccount item to list of MirandaAccounts + void addMirandaAccount(MirandaAccount* mirandaAccountL); + + //clears list of MirandaAccounts + void clearMirandaAccounts(); + // list of pointers to MirandaContact class instances boost::ptr_list mirandaContacts; @@ -222,13 +207,37 @@ private: //initialize contacts list void initializeMirandaContacts(); + //add MirandaContact item to list of MirandaContacts + void addMirandaContact(MirandaContact* mirandaContactL); + + //clears list of MirandaContacts + void clearMirandaContacts(); + + //set contactNameW at MirandaContact to contact display name + void setContactDisplayName(MirandaContact* mirandaContact); + + + MFENUM_MIRANDAACCOUNT_STATE createOrGetAccountStateFromDB(MirandaAccount* mirandaAccount); + + MFENUM_MIRANDACONTACT_STATE createOrGetContactStateFromDB(MirandaContact* mirandaContact); + + + static bool shouldProtoBeActiveByName(std::string protoName); + + int getAccountDefaultState(MirandaAccount* account); + + int getContactDefaultState(MirandaContact* contact); + //options bool clientsProfilesFilterCheckbox; std::wstring clientsProfilesFilterString; + bool addAccountToContactNameCheckbox; + void initializeOptions(); + }; @@ -260,10 +269,10 @@ public: ~MirandaContact(void); MirandaContact* getObjectPtr(); - MCONTACT contactHandle; //HANDLE to contact in miranda (unikalne) + MCONTACT contactHandle; //HANDLE to contact in miranda (unique) std::wstring contactNameW; //presented name MFENUM_MIRANDACONTACT_STATE contactState; //state in options - MirandaAccount* mirandaAccountPtr; //account of hContact + MirandaAccount* mirandaAccountPtr; //contact's account }; diff --git a/plugins/MirFox/src/MirfoxMiranda.cpp b/plugins/MirFox/src/MirfoxMiranda.cpp index 5d5e851cc1..da140c8d17 100644 --- a/plugins/MirFox/src/MirfoxMiranda.cpp +++ b/plugins/MirFox/src/MirfoxMiranda.cpp @@ -21,6 +21,11 @@ MirfoxData& CMirfoxMiranda::getMirfoxData(){ return mirfoxData; } +SharedMemoryUtils& CMirfoxMiranda::getSharedMemoryUtils(){ + return *sharedMemoryUtils; +} + + int CMirfoxMiranda::onMirandaInterfaceLoad() { @@ -53,6 +58,155 @@ int CMirfoxMiranda::onMirandaInterfaceLoad() } +void CMirfoxMiranda::onAccListChanged(WPARAM wParam, LPARAM lParam) +{ + PROTOACCOUNT *acc = (PROTOACCOUNT*)lParam; + + switch (wParam) { + case PRAC_ADDED: + if (acc != NULL) { + //checking account + if(acc->bIsEnabled == 0 || acc->bDynDisabled != 0){ + return; + } + mirfoxData.refreshAccount_Add(getSharedMemoryUtils(), acc->szModuleName, acc->tszAccountName, acc->szProtoName); + } + break; + + case PRAC_UPGRADED: + case PRAC_CHANGED: + if (acc != NULL) { + //checking account + if(acc->bIsEnabled == 0 || acc->bDynDisabled != 0){ + return; + } + mirfoxData.refreshAccount_Edit(getSharedMemoryUtils(), acc->szModuleName, acc->tszAccountName); + } + break; + + case PRAC_REMOVED: + mirfoxData.refreshAccount_Delete(getSharedMemoryUtils(), acc->szModuleName); + break; + + case PRAC_CHECKED: + if (acc != NULL) { + if (acc->bIsEnabled) { + //checking account + if(acc->bDynDisabled != 0){ + return; + } + mirfoxData.refreshAccount_Add(getSharedMemoryUtils(), acc->szModuleName, acc->tszAccountName, acc->szProtoName); + } else { + mirfoxData.refreshAccount_Delete(getSharedMemoryUtils(), acc->szModuleName); + } + } + break; + } + + return; +} + + +void CMirfoxMiranda::onContactAdded_async(void* threadArg) +{ + Thread_Push(0); + OnContactAsyncThreadArgStruct* onContactAsyncThreadArgStruct = (OnContactAsyncThreadArgStruct*)threadArg; + CMirfoxMiranda* mirfoxMiranda = onContactAsyncThreadArgStruct->mirfoxMiranda; + MFLogger* logger = MFLogger::getInstance(); + + // ME_DB_CONTACT_ADDED is fired when only hContact is known, wait some time for finish creating contact + // wait some time for finish contact creation + SleepEx(300, TRUE); + logger->log_p(L"CMirfoxMiranda::onContactAdded_async AFTER wait [" SCNuPTR L"]", onContactAsyncThreadArgStruct->hContact); + bool canAdd = true; + + // ceck miranda + if (Miranda_Terminated() || mirfoxMiranda->getMirfoxData().Plugin_Terminated) + canAdd = false; + + // check if hContact still exist + if (canAdd && !CallService(MS_DB_CONTACT_IS, onContactAsyncThreadArgStruct->hContact, 0)) + canAdd = false; + + // execute + if (canAdd && db_get_b(onContactAsyncThreadArgStruct->hContact, "CList", "Hidden", 0) == 1) + canAdd = false; + + // add + if (canAdd) + mirfoxMiranda->getMirfoxData().refreshContact_Add(mirfoxMiranda->getSharedMemoryUtils(), onContactAsyncThreadArgStruct->hContact); + + // clean + delete onContactAsyncThreadArgStruct; + Thread_Pop(); + return; +} + + +void CMirfoxMiranda::onContactDeleted(MCONTACT hContact) +{ + + mirfoxData.refreshContact_Delete(getSharedMemoryUtils(), hContact); + + return; +} + + +void CMirfoxMiranda::onContactSettingChanged(MCONTACT hContact, LPARAM lParam) +{ + + DBCONTACTWRITESETTING* cws = (DBCONTACTWRITESETTING*)lParam; + logger->log_p(L"onContactSettingChanged CList Hidden hContact [" SCNuPTR L"]", hContact); + + if (cws->value.bVal > 0){ + mirfoxData.refreshContact_Delete(getSharedMemoryUtils(), hContact); + } else { //unset + mirfoxData.refreshContact_Add(getSharedMemoryUtils(), hContact); + } + + return; +} + +void CMirfoxMiranda::onContactSettingChanged_async(void* threadArg){ + + Thread_Push(0); + OnContactAsyncThreadArgStruct* onContactAsyncThreadArgStruct = (OnContactAsyncThreadArgStruct*)threadArg; + CMirfoxMiranda* mirfoxMiranda = onContactAsyncThreadArgStruct->mirfoxMiranda; + MFLogger* logger = MFLogger::getInstance(); + + // this ME_DB_CONTACT_SETTINGCHANGED hook can be added after ME_DB_CONTACT_ADDED + // if we delay ME_DB_CONTACT_ADDED routines, we must also delay this + // wait some time for finish contact creation + SleepEx(300+100, TRUE); + logger->log_p(L"CMirfoxMiranda::onContactSettingChanged_async AFTER wait [" SCNuPTR L"]", onContactAsyncThreadArgStruct->hContact); + bool canAdd = true; + + // ceck miranda + if (Miranda_Terminated() || mirfoxMiranda->getMirfoxData().Plugin_Terminated) + canAdd = false; + + // check if hContact still exist + if (canAdd && !CallService(MS_DB_CONTACT_IS, onContactAsyncThreadArgStruct->hContact, 0)) + canAdd = false; + + // edit + if (canAdd &&db_get_b(onContactAsyncThreadArgStruct->hContact, "CList", "Hidden", 0) == 1) + canAdd = false; + + + if (canAdd) + mirfoxMiranda->getMirfoxData().refreshContact_Edit(mirfoxMiranda->getSharedMemoryUtils(), onContactAsyncThreadArgStruct->hContact); + + // clean + delete onContactAsyncThreadArgStruct; + Thread_Pop(); + return; +} + + + + + int CMirfoxMiranda::onMirandaInterfaceUnload() { @@ -403,4 +557,4 @@ void CMirfoxMiranda::msgQueueThread(void* threadArg) mirfoxDataPtr->workerThreadsCount--; Thread_Pop(); return; -} \ No newline at end of file +} diff --git a/plugins/MirFox/src/MirfoxMiranda.h b/plugins/MirFox/src/MirfoxMiranda.h index 0bcce0cf99..31cb61f99c 100644 --- a/plugins/MirFox/src/MirfoxMiranda.h +++ b/plugins/MirFox/src/MirfoxMiranda.h @@ -5,6 +5,14 @@ #include "MirandaUtils.h" +class CMirfoxMiranda; + + +struct OnContactAsyncThreadArgStruct { + MCONTACT hContact; + CMirfoxMiranda* mirfoxMiranda; +}; + class CMirfoxMiranda { @@ -18,10 +26,20 @@ public: MirfoxData& getMirfoxData(); + SharedMemoryUtils& getSharedMemoryUtils(); + int onMirandaInterfaceLoad(); int onMirandaInterfaceUnload(); + //hooks support - to refresh data + void onAccListChanged(WPARAM wParam, LPARAM lParam); + static void onContactAdded_async(void* threadArg); //at async new thread + void onContactDeleted(MCONTACT hContact); + void onContactSettingChanged(MCONTACT hContact, LPARAM lParam); + static void onContactSettingChanged_async(void* threadArg); //at async new thread + + //csm maintanance thread function (threadArg - pointer to this CMirfoxMiranda class instance) static void csmThread(void* threadArg); diff --git a/plugins/MirFox/src/common.h b/plugins/MirFox/src/common.h index 05375dbad5..f894436813 100644 --- a/plugins/MirFox/src/common.h +++ b/plugins/MirFox/src/common.h @@ -16,6 +16,7 @@ #include #include #include +#include #define PLUGIN_DB_ID "MirFox" diff --git a/plugins/MirFox/src/resource.h b/plugins/MirFox/src/resource.h index cd73d322ad..94dc8d7f87 100644 --- a/plugins/MirFox/src/resource.h +++ b/plugins/MirFox/src/resource.h @@ -23,13 +23,13 @@ #define IDC1_CHECK1 1110 #define IDC1_EDIT1 1111 #define IDC1_STATIC_G3 1112 -#define IDC1_STATIC_INVALIDATE 1113 -#define IDC1_BUTTON_INVALIDATE 1114 +#define IDC1_CHECK2 1113 + //@IDD_OPT2 -#define IDC2_LABEL1 1201 +#define IDC2_STATIC_G1 1201 #define IDC2_CONTACTS_LIST 1202 + //@IDD_OPT3 #define IDC3_STATIC_G1 1301 -#define IDC3_LABEL1 1302 -#define IDC3_PROTOCOLS_LIST 1303 +#define IDC3_PROTOCOLS_LIST 1302 diff --git a/plugins/MirFox/src/version.h b/plugins/MirFox/src/version.h index eb83e97856..5c456c358a 100644 --- a/plugins/MirFox/src/version.h +++ b/plugins/MirFox/src/version.h @@ -1,6 +1,6 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 5 -#define __RELEASE_NUM 0 +#define __RELEASE_NUM 1 #define __BUILD_NUM 0 #include @@ -11,4 +11,4 @@ #define __AUTHOR "Szymon Tokarz" #define __AUTHOREMAIL "wsx22@o2.pl" #define __AUTHORWEB "http://miranda-ng.org/p/MirFox/" -#define __COPYRIGHT "© 2013 Szymon Tokarz" +#define __COPYRIGHT "© 2013 - 2016 Szymon Tokarz" -- cgit v1.2.3