/* Miranda plugin template, originally by Richard Hughes http://miranda-icq.sourceforge.net/ This file is placed in the public domain. Anybody is free to use or modify it as they wish with no restriction. There is no warranty. */ #include "stdafx.h" bool IsSuitableProto(PROTOACCOUNT *pa) { if (pa == nullptr) return false; if (pa->bDynDisabled || !pa->bIsEnabled) return false; if (!(CallProtoService(pa->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_IMRECV)) return false; return true; } class COptionsDlg : public CDlgBase { CCtrlBase label; CCtrlCheck chkIgnore; CCtrlCombo comboAcc, comboUser; CCtrlButton btnTest, btnReset, btnChoose; XSN_Data* ObtainData() { LPARAM hContact = comboUser.GetItemData(comboUser.GetCurSel()); if (hContact == -1) { PROTOACCOUNT *pa = (PROTOACCOUNT *)comboAcc.GetItemData(comboAcc.GetCurSel()); XSN_Data *p = XSN_Users.find((XSN_Data *)&pa->szModuleName); if (p == nullptr) XSN_Users.insert(p = new XSN_Data(pa->szModuleName, chkIgnore.GetState())); return p; } XSN_Data *p = XSN_Users.find((XSN_Data *)&hContact); if (p == nullptr) XSN_Users.insert(p = new XSN_Data(hContact, chkIgnore.GetState())); return p; } public: COptionsDlg() : CDlgBase(g_plugin, IDD_OPTIONS), label(this, IDC_OPT_LABEL_SOUND), btnTest(this, IDC_OPT_BUTTON_TEST_PLAY), btnReset(this, IDC_OPT_BUTTON_RESET_SOUND), btnChoose(this, IDC_OPT_BUTTON_CHOOSE_SOUND), chkIgnore(this, IDC_OPT_IGNORE_SOUND), comboAcc(this, IDC_OPT_COMBO_PROTO), comboUser(this, IDC_OPT_COMBO_USERS) { btnTest.OnClick = Callback(this, &COptionsDlg::onClick_Test); btnReset.OnClick = Callback(this, &COptionsDlg::onClick_Reset); btnChoose.OnClick = Callback(this, &COptionsDlg::onClick_Choose); comboAcc.OnSelChanged = Callback(this, &COptionsDlg::onSelChanged_Proto); comboUser.OnSelChanged = Callback(this, &COptionsDlg::onSelChanged_Users); chkIgnore.OnChange = Callback(this, &COptionsDlg::onChange_Ignore); } bool OnInitDialog() override { for (auto &pa : Accounts()) if (IsSuitableProto(pa)) comboAcc.AddString(pa->tszAccountName, (LPARAM)pa); return true; } bool OnApply() override { for (auto &it : XSN_Users) { if (it->path[0] != 0) { wchar_t shortpath[MAX_PATH]; PathToRelativeW(it->path, shortpath); if (it->bIsContact) g_plugin.setWString(it->hContact, SETTINGSKEY, shortpath); else g_plugin.setWString((LPCSTR)it->hContact, shortpath); } else g_plugin.delSetting(it->hContact, SETTINGSKEY); if (it->bIsContact) g_plugin.setByte(it->hContact, SETTINGSIGNOREKEY, it->bIgnore); else { size_t value_max_len = mir_strlen((const char *)it->hContact) + 8; char *value = (char *)mir_alloc(sizeof(char) * value_max_len); mir_snprintf(value, value_max_len, "%s_ignore", (const char *)it->hContact); g_plugin.setByte(value, it->bIgnore); mir_free(value); } } return true; } void onSelChanged_Proto(CCtrlCombo *) { comboUser.Enable(); comboUser.ResetContent(); btnTest.Disable(); btnReset.Disable(); chkIgnore.Disable(); chkIgnore.SetState(false); label.SetText(TranslateT("Not set")); int cursel = comboAcc.GetCurSel(); PROTOACCOUNT *pa = (PROTOACCOUNT *)comboAcc.GetItemData(cursel); comboUser.AddString(TranslateT("All contacts"), -1); for (auto &hContact : Contacts(pa->szModuleName)) { ptrW uid(Contact_GetInfo(CNF_UNIQUEID, hContact)); CMStringW value(FORMAT, L"%s (%s)", Clist_GetContactDisplayName(hContact), uid.get()); comboUser.AddString(value, hContact); } } void onSelChanged_Users(CCtrlCombo *) { btnChoose.Enable(); chkIgnore.Enable(); LPARAM hContact = comboUser.GetItemData(comboUser.GetCurSel()); if (hContact == -1) { PROTOACCOUNT *pa = (PROTOACCOUNT *)comboAcc.GetItemData(comboAcc.GetCurSel()); ptrW wszText(g_plugin.getWStringA(pa->szModuleName)); if (wszText) { btnTest.Enable(); btnReset.Enable(); label.SetText(PathFindFileNameW(wszText)); } else { btnTest.Disable(); btnReset.Disable(); label.SetText(TranslateT("Not set")); } size_t value_max_len = mir_strlen(pa->szModuleName) + 8; char *value = (char *)mir_alloc(sizeof(char) * value_max_len); mir_snprintf(value, value_max_len, "%s_ignore", pa->szModuleName); chkIgnore.SetState(g_plugin.getByte(value, 0)); mir_free(value); } else { ptrW wszPath(g_plugin.getWStringA(hContact, SETTINGSKEY)); if (wszPath) { btnTest.Enable(); btnReset.Enable(); label.SetText(PathFindFileNameW(wszPath)); } else { btnTest.Disable(); btnReset.Disable(); label.SetText(TranslateT("Not set")); } chkIgnore.SetState(g_plugin.getByte(hContact, SETTINGSIGNOREKEY, 0)); } } void onClick_Test(CCtrlButton*) { isIgnoreSound = 0; auto *p = ObtainData(); wchar_t longpath[MAX_PATH]; PathToAbsoluteW(p->path, longpath); Skin_PlaySoundFile(longpath); } void onChange_Ignore(CCtrlCheck *) { auto *p = ObtainData(); p->bIgnore = chkIgnore.GetState(); NotifyChange(); } void onClick_Choose(CCtrlButton *) { wchar_t tmp[MAX_PATH]; if (GetModuleHandle(L"bass_interface.dll")) mir_snwprintf(tmp, L"%s (*.wav, *.mp3, *.ogg)%c*.wav;*.mp3;*.ogg%c%c", TranslateT("Sound files"), 0, 0, 0); else mir_snwprintf(tmp, L"%s (*.wav)%c*.wav%c%c", TranslateT("WAV files"), 0, 0, 0); wchar_t FileName[MAX_PATH]; FileName[0] = '\0'; ptrW tszMirDir(Utils_ReplaceVarsW(L"%miranda_path%")); OPENFILENAME ofn = { 0 }; ofn.lStructSize = sizeof(ofn); ofn.lpstrFilter = tmp; ofn.hwndOwner = nullptr; ofn.lpstrFile = FileName; ofn.nMaxFile = MAX_PATH; ofn.nMaxFileTitle = MAX_PATH; ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST; ofn.lpstrInitialDir = tszMirDir; ofn.lpstrDefExt = L""; if (!GetOpenFileName(&ofn)) return; label.SetText(PathFindFileNameW(FileName)); auto *p = ObtainData(); wcsncpy_s(p->path, FileName, _TRUNCATE); p->bIgnore = chkIgnore.GetState(); btnTest.Enable(); btnReset.Enable(); NotifyChange(); } void onClick_Reset(CCtrlButton *) { btnTest.Disable(); btnReset.Disable(); chkIgnore.SetState(false); label.SetText(TranslateT("Not set")); LPARAM hContact = comboUser.GetItemData(comboUser.GetCurSel()); if (hContact == -1) { PROTOACCOUNT *pa = (PROTOACCOUNT *)comboAcc.GetItemData(comboAcc.GetCurSel()); XSN_Data *p = XSN_Users.find((XSN_Data *)&pa->szModuleName); if (p != nullptr) { XSN_Users.remove(p); delete p; NotifyChange(); } g_plugin.delSetting(pa->szModuleName); size_t value_max_len = mir_strlen(pa->szModuleName) + 8; char *value = (char *)mir_alloc(sizeof(char) * value_max_len); mir_snprintf(value, value_max_len, "%s_ignore", pa->szModuleName); g_plugin.delSetting(value); mir_free(value); } else { XSN_Data *p = XSN_Users.find((XSN_Data *)&hContact); if (p != nullptr) { XSN_Users.remove(p); delete p; NotifyChange(); } g_plugin.delSetting(hContact, SETTINGSKEY); g_plugin.delSetting(hContact, SETTINGSIGNOREKEY); } } }; INT OptInit(WPARAM wParam, LPARAM) { OPTIONSDIALOGPAGE odp = {}; odp.position = 100000000; odp.flags = ODPF_BOLDGROUPS | ODPF_UNICODE; odp.szGroup.w = LPGENW("Sounds"); odp.szTitle.w = LPGENW("XSound Notify"); odp.pDialog = new COptionsDlg(); g_plugin.addOptions(wParam, &odp); return 0; }