diff options
author | George Hazan <george.hazan@gmail.com> | 2025-03-05 14:14:04 +0300 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2025-03-05 14:14:04 +0300 |
commit | 0f33881cd257910f73b550112f35cd50061325c2 (patch) | |
tree | ccb27a0960363e5660194e709fd1057809b3429d /src | |
parent | f3adc14797ee6889a0134b8f8ebff39436af3a95 (diff) |
module renamed & moved to the appropriate folder
Diffstat (limited to 'src')
-rw-r--r-- | src/mir_app/mir_app.vcxproj | 2 | ||||
-rw-r--r-- | src/mir_app/mir_app.vcxproj.filters | 6 | ||||
-rw-r--r-- | src/mir_app/src/clistcontacts.cpp (renamed from src/mir_app/src/contacts.cpp) | 890 |
3 files changed, 449 insertions, 449 deletions
diff --git a/src/mir_app/mir_app.vcxproj b/src/mir_app/mir_app.vcxproj index a5d477b179..85bcd1d071 100644 --- a/src/mir_app/mir_app.vcxproj +++ b/src/mir_app/mir_app.vcxproj @@ -56,7 +56,7 @@ <ClCompile Include="src\CMPluginBase.cpp" />
<ClCompile Include="src\colorchooser.cpp" />
<ClCompile Include="src\clccontact.cpp" />
- <ClCompile Include="src\contacts.cpp" />
+ <ClCompile Include="src\clistcontacts.cpp" />
<ClCompile Include="src\database.cpp" />
<ClCompile Include="src\db_events.cpp" />
<ClCompile Include="src\db_ini.cpp" />
diff --git a/src/mir_app/mir_app.vcxproj.filters b/src/mir_app/mir_app.vcxproj.filters index 89c02483c7..5586935271 100644 --- a/src/mir_app/mir_app.vcxproj.filters +++ b/src/mir_app/mir_app.vcxproj.filters @@ -11,9 +11,6 @@ <ClCompile Include="src\button.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="src\contacts.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="src\descbutton.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -434,6 +431,9 @@ <ClCompile Include="src\searchresults.cpp">
<Filter>Source Files\FindAdd</Filter>
</ClCompile>
+ <ClCompile Include="src\clistcontacts.cpp">
+ <Filter>Source Files\Contact list</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\filter.h">
diff --git a/src/mir_app/src/contacts.cpp b/src/mir_app/src/clistcontacts.cpp index 250cd71304..759bce6f52 100644 --- a/src/mir_app/src/contacts.cpp +++ b/src/mir_app/src/clistcontacts.cpp @@ -1,445 +1,445 @@ -/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-25 Miranda NG team (https://miranda-ng.org),
-Copyright (c) 2000-12 Miranda IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "stdafx.h"
-
-static wchar_t* nameOrderDescr[] =
-{
- LPGENW("My custom name (not movable)"),
- LPGENW("Nick"),
- LPGENW("FirstName"),
- LPGENW("E-mail"),
- LPGENW("LastName"),
- LPGENW("Username"),
- LPGENW("FirstName LastName"),
- LPGENW("LastName FirstName"),
- LPGENW("'(Unknown contact)' (not movable)")
-};
-
-uint8_t nameOrder[_countof(nameOrderDescr)];
-
-static wchar_t* ProcessDatabaseValueDefault(MCONTACT hContact, const char *szProto, const char *szSetting)
-{
- DBVARIANT dbv;
- if (db_get(hContact, szProto, szSetting, &dbv))
- return nullptr;
-
- wchar_t *ret;
- wchar_t buf[40];
- switch (dbv.type) {
- case DBVT_BYTE:
- ret = _itow(dbv.bVal, buf, 10);
- break;
- case DBVT_WORD:
- ret = _itow(dbv.wVal, buf, 10);
- break;
- case DBVT_DWORD:
- ret = _itow(dbv.dVal, buf, 10);
- break;
- case DBVT_BLOB:
- if (dbv.cpbVal == 8)
- ret = _i64tow(*(__int64*)dbv.pbVal, buf, 10);
- else
- ret = bin2hexW(dbv.pbVal, min(int(dbv.cpbVal), 19), buf);
- break;
- case DBVT_ASCIIZ:
- ret = mir_a2u(dbv.pszVal);
- break;
- case DBVT_UTF8:
- ret = mir_utf8decodeW(dbv.pszVal);
- break;
- case DBVT_WCHAR:
- return dbv.pwszVal; // no need to free dbv
- default:
- ret = nullptr;
- }
-
- db_free(&dbv);
- return mir_wstrdup(ret);
-}
-
-MIR_APP_DLL(wchar_t*) Contact::GetInfo(int type, MCONTACT hContact, const char *szProto)
-{
- if (hContact == 0 && szProto == nullptr)
- return nullptr;
-
- if (szProto == nullptr)
- if (auto *pa = Proto_GetContactAccount(hContact))
- szProto = pa->szModuleName;
-
- if (szProto == nullptr)
- return nullptr;
-
- wchar_t *res;
- DBVARIANT dbv;
- switch (type) {
- case CNF_FIRSTNAME: return ProcessDatabaseValueDefault(hContact, szProto, "FirstName");
- case CNF_LASTNAME: return ProcessDatabaseValueDefault(hContact, szProto, "LastName");
- case CNF_NICK: return ProcessDatabaseValueDefault(hContact, szProto, "Nick");
- case CNF_EMAIL: return ProcessDatabaseValueDefault(hContact, szProto, "e-mail");
- case CNF_CITY: return ProcessDatabaseValueDefault(hContact, szProto, "City");
- case CNF_STATE: return ProcessDatabaseValueDefault(hContact, szProto, "State");
- case CNF_PHONE: return ProcessDatabaseValueDefault(hContact, szProto, "Phone");
- case CNF_HOMEPAGE: return ProcessDatabaseValueDefault(hContact, szProto, "Homepage");
- case CNF_ABOUT: return ProcessDatabaseValueDefault(hContact, szProto, "About");
- case CNF_AGE: return ProcessDatabaseValueDefault(hContact, szProto, "Age");
- case CNF_GENDER: return ProcessDatabaseValueDefault(hContact, szProto, "Gender");
- case CNF_FAX: return ProcessDatabaseValueDefault(hContact, szProto, "Fax");
- case CNF_CELLULAR: return ProcessDatabaseValueDefault(hContact, szProto, "Cellular");
- case CNF_BIRTHDAY: return ProcessDatabaseValueDefault(hContact, szProto, "BirthDay");
- case CNF_BIRTHMONTH: return ProcessDatabaseValueDefault(hContact, szProto, "BirthMonth");
- case CNF_BIRTHYEAR: return ProcessDatabaseValueDefault(hContact, szProto, "BirthYear");
- case CNF_STREET: return ProcessDatabaseValueDefault(hContact, szProto, "Street");
- case CNF_ZIP: return ProcessDatabaseValueDefault(hContact, szProto, "ZIP");
- case CNF_LANGUAGE1: return ProcessDatabaseValueDefault(hContact, szProto, "Language1");
- case CNF_LANGUAGE2: return ProcessDatabaseValueDefault(hContact, szProto, "Language2");
- case CNF_LANGUAGE3: return ProcessDatabaseValueDefault(hContact, szProto, "Language3");
- case CNF_CONAME: return ProcessDatabaseValueDefault(hContact, szProto, "Company");
- case CNF_CODEPT: return ProcessDatabaseValueDefault(hContact, szProto, "CompanyDepartment");
- case CNF_COPOSITION: return ProcessDatabaseValueDefault(hContact, szProto, "CompanyPosition");
- case CNF_COSTREET: return ProcessDatabaseValueDefault(hContact, szProto, "CompanyStreet");
- case CNF_COCITY: return ProcessDatabaseValueDefault(hContact, szProto, "CompanyCity");
- case CNF_COSTATE: return ProcessDatabaseValueDefault(hContact, szProto, "CompanyState");
- case CNF_COZIP: return ProcessDatabaseValueDefault(hContact, szProto, "CompanyZIP");
- case CNF_COHOMEPAGE: return ProcessDatabaseValueDefault(hContact, szProto, "CompanyHomepage");
- case CNF_CUSTOMNICK:
- if (hContact)
- return ProcessDatabaseValueDefault(hContact, "CList", "MyHandle");
- return ProcessDatabaseValueDefault(0, szProto, "MyHandle");
-
- case CNF_COUNTRY:
- case CNF_COCOUNTRY:
- if (!db_get_ws(hContact, szProto, type == CNF_COUNTRY ? "CountryName" : "CompanyCountryName", &dbv))
- return dbv.pwszVal;
-
- if (!db_get(hContact, szProto, type == CNF_COUNTRY ? "Country" : "CompanyCountry", &dbv)) {
- if (dbv.type == DBVT_WORD) {
- int countryCount;
- struct CountryListEntry *countries;
- CallService(MS_UTILS_GETCOUNTRYLIST, (WPARAM)&countryCount, (LPARAM)&countries);
- for (int i = 0; i < countryCount; i++)
- if (countries[i].id == dbv.wVal)
- return mir_a2u(countries[i].szName);
- }
- else {
- db_free(&dbv);
- return ProcessDatabaseValueDefault(hContact, szProto, type == CNF_COUNTRY ? "Country" : "CompanyCountry");
- }
- }
- break;
-
- case CNF_FIRSTLAST:
- if (!db_get_ws(hContact, szProto, "FirstName", &dbv)) {
- DBVARIANT dbv2;
- if (!db_get_ws(hContact, szProto, "LastName", &dbv2)) {
- size_t len = mir_wstrlen(dbv.pwszVal) + mir_wstrlen(dbv2.pwszVal) + 2;
- wchar_t *buf = (wchar_t*)mir_alloc(sizeof(wchar_t)*len);
- if (buf != nullptr)
- mir_wstrcat(mir_wstrcat(mir_wstrcpy(buf, dbv.pwszVal), L" "), dbv2.pwszVal);
- db_free(&dbv);
- db_free(&dbv2);
- return buf;
- }
- return dbv.pwszVal;
- }
- break;
-
- case CNF_UNIQUEID:
- if (db_mc_isMeta(hContact)) {
- wchar_t buf[40];
- _itow(hContact, buf, 10);
- return mir_wstrdup(buf);
- }
-
- if (auto *uid = Proto_GetUniqueId(szProto))
- return ProcessDatabaseValueDefault(hContact, szProto, uid);
- break;
-
- case CNF_DISPLAYUID:
- if (res = ProcessDatabaseValueDefault(hContact, szProto, "display_uid"))
- return res;
-
- if (auto *uid = Proto_GetUniqueId(szProto))
- return ProcessDatabaseValueDefault(hContact, szProto, uid);
- break;
-
- case CNF_DISPLAYNC:
- case CNF_DISPLAY:
- for (auto &it : nameOrder) {
- switch (it) {
- case 0: // custom name
- // make sure we aren't in CNF_DISPLAYNC mode
- // don't get custom name for nullptr contact
- if (type == CNF_DISPLAY)
- if (res = ProcessDatabaseValueDefault(hContact, (hContact != 0) ? "CList" : szProto, "MyHandle"))
- return res;
- break;
-
- case 1:
- if (res = ProcessDatabaseValueDefault(hContact, szProto, "Nick")) // nick
- return res;
- break;
- case 2:
- if (res = ProcessDatabaseValueDefault(hContact, szProto, "FirstName")) // First Name
- return res;
- break;
- case 3:
- if (res = ProcessDatabaseValueDefault(hContact, szProto, "e-mail")) // E-mail
- return res;
- break;
- case 4:
- if (res = ProcessDatabaseValueDefault(hContact, szProto, "LastName")) // Last Name
- return res;
- break;
-
- case 5: // Unique id
- // protocol must define a PFLAG_UNIQUEIDSETTING
- if (auto *uid = Proto_GetUniqueId(szProto)) {
- if (!db_get_ws(hContact, szProto, uid, &dbv)) {
- if (dbv.type == DBVT_BYTE || dbv.type == DBVT_WORD || dbv.type == DBVT_DWORD) {
- long value = (dbv.type == DBVT_BYTE) ? dbv.bVal : (dbv.type == DBVT_WORD ? dbv.wVal : dbv.dVal);
- wchar_t buf[40];
- _ltow(value, buf, 10);
- return mir_wstrdup(buf);
- }
- return dbv.pwszVal;
- }
- }
- break;
-
- case 6: // first + last name
- case 7: // last + first name
- if (!db_get_ws(hContact, szProto, it == 6 ? "FirstName" : "LastName", &dbv)) {
- DBVARIANT dbv2;
- if (!db_get_ws(hContact, szProto, it == 6 ? "LastName" : "FirstName", &dbv2)) {
- size_t len = mir_wstrlen(dbv.pwszVal) + mir_wstrlen(dbv2.pwszVal) + 2;
- wchar_t *buf = (wchar_t*)mir_alloc(sizeof(wchar_t)*len);
- if (buf != nullptr)
- mir_wstrcat(mir_wstrcat(mir_wstrcpy(buf, dbv.pwszVal), L" "), dbv2.pwszVal);
-
- db_free(&dbv);
- db_free(&dbv2);
- return buf;
- }
- db_free(&dbv);
- }
- break;
-
- case 8:
- return mir_wstrdup(TranslateT("'(Unknown contact)'"));
- }
- }
- break;
-
- case CNF_MYNOTES:
- return ProcessDatabaseValueDefault(hContact, "UserInfo", "MyNotes");
-
- case CNF_TIMEZONE:
- HANDLE hTz = TimeZone_CreateByContact(hContact, nullptr, TZF_KNOWNONLY);
- if (hTz) {
- LPTIME_ZONE_INFORMATION tzi = TimeZone_GetInfo(hTz);
- int offset = tzi->Bias + tzi->StandardBias;
-
- char str[80];
- mir_snprintf(str, offset ? "UTC%+d:%02d" : "UTC", offset / -60, abs(offset % 60));
- return mir_a2u(str);
- }
- break;
- }
-
- return nullptr;
-}
-
-MIR_APP_DLL(int) Contact::GetStatus(MCONTACT hContact)
-{
- if (hContact == 0)
- return ID_STATUS_OFFLINE;
-
- const char *szProto = Proto_GetBaseAccountName(hContact);
- if (szProto == nullptr)
- return ID_STATUS_OFFLINE;
-
- return db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-MIR_APP_DLL(bool) Contact::IsGroupChat(MCONTACT hContact, const char *szProto)
-{
- if (szProto == nullptr) {
- szProto = Proto_GetBaseAccountName(hContact);
- if (szProto == nullptr)
- return false;
- }
-
- return db_get_b(hContact, szProto, "ChatRoom") != 0;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-MIR_APP_DLL(bool) Contact::IsHidden(MCONTACT hContact)
-{
- return db_get_b(hContact, "CList", "Hidden") != 0;
-}
-
-MIR_APP_DLL(void) Contact::Hide(MCONTACT hContact, bool bHidden)
-{
- if (bHidden)
- db_set_b(hContact, "CList", "Hidden", 1);
- else
- db_unset(hContact, "CList", "Hidden");
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-MIR_APP_DLL(bool) Contact::IsReadonly(MCONTACT hContact)
-{
- return db_get_b(hContact, "CList", "ReadOnly") != 0;
-}
-
-MIR_APP_DLL(void) Contact::Readonly(MCONTACT hContact, bool bReadOnly)
-{
- if (bReadOnly)
- db_set_b(hContact, "CList", "ReadOnly", 1);
- else
- db_unset(hContact, "CList", "ReadOnly");
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-MIR_APP_DLL(bool) Contact::OnList(MCONTACT hContact)
-{
- return db_get_b(hContact, "CList", "NotOnList", 0) == 0;
-}
-
-MIR_APP_DLL(void) Contact::PutOnList(MCONTACT hContact)
-{
- db_unset(hContact, "CList", "NotOnList");
-}
-
-MIR_APP_DLL(void) Contact::RemoveFromList(MCONTACT hContact)
-{
- db_set_b(hContact, "CList", "NotOnList", 1);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Options dialog
-
-class CContactOptsDlg : public CDlgBase
-{
- CCtrlTreeView m_nameOrder;
-
-public:
- CContactOptsDlg() :
- CDlgBase(g_plugin, IDD_OPT_CONTACT),
- m_nameOrder(this, IDC_NAMEORDER)
- {
- m_nameOrder.SetFlags(MTREE_DND);
- m_nameOrder.OnBeginDrag = BCallback(this, &CContactOptsDlg::OnBeginDrag);
- m_nameOrder.OnEndDrag = BCallback(this, &CContactOptsDlg::OnEndDrag);
- }
-
- bool OnInitDialog() override
- {
- TVINSERTSTRUCT tvis;
- tvis.hParent = nullptr;
- tvis.hInsertAfter = TVI_LAST;
- tvis.item.mask = TVIF_TEXT | TVIF_PARAM;
- for (int i = 0; i < _countof(nameOrderDescr); i++) {
- tvis.item.lParam = nameOrder[i];
- tvis.item.pszText = TranslateW(nameOrderDescr[nameOrder[i]]);
- m_nameOrder.InsertItem(&tvis);
- }
- return true;
- }
-
- bool OnApply() override
- {
- TVITEMEX tvi;
- tvi.hItem = m_nameOrder.GetRoot();
- int i = 0;
- while (tvi.hItem != nullptr) {
- tvi.mask = TVIF_PARAM | TVIF_HANDLE;
- m_nameOrder.GetItem(&tvi);
- nameOrder[i++] = (uint8_t)tvi.lParam;
- tvi.hItem = m_nameOrder.GetNextSibling(tvi.hItem);
- }
- db_set_blob(0, "Contact", "NameOrder", nameOrder, _countof(nameOrderDescr));
- g_clistApi.pfnInvalidateDisplayNameCacheEntry(INVALID_CONTACT_ID);
- return true;
- }
-
- bool OnBeginDrag(CCtrlTreeView::TEventInfo *evt)
- {
- LPNMTREEVIEW pNotify = evt->nmtv;
- return (pNotify->itemNew.lParam != 0 && pNotify->itemNew.lParam != _countof(nameOrderDescr)-1);
- }
-
- bool OnEndDrag(CCtrlTreeView::TEventInfo *evt)
- {
- auto &hti = *evt->ntvhi;
-
- // do not allow to move selection over the first item
- if (hti.flags & TVHT_ABOVE)
- return false;
-
- // do not allow to move selection below the last item either
- TVITEMEX tvi;
- tvi.mask = TVIF_HANDLE | TVIF_PARAM;
- tvi.hItem = hti.hItem;
- m_nameOrder.GetItem(&tvi);
- if (tvi.lParam == _countof(nameOrderDescr) - 1)
- return false;
-
- return true;
- }
-};
-
-static int ContactOptInit(WPARAM wParam, LPARAM)
-{
- OPTIONSDIALOGPAGE odp = {};
- odp.position = -1000000000;
- odp.szGroup.a = LPGEN("Contact list");
- odp.szTitle.a = LPGEN("Contact names");
- odp.pDialog = new CContactOptsDlg();
- odp.flags = ODPF_BOLDGROUPS;
- g_plugin.addOptions(wParam, &odp);
-
- return PopupOptionsInit(wParam);
-}
-
-int LoadContactsModule(void)
-{
- for (uint8_t i = 0; i < _countof(nameOrder); i++)
- nameOrder[i] = i;
-
- DBVARIANT dbv;
- if (!db_get(0, "Contact", "NameOrder", &dbv)) {
- memcpy(nameOrder, dbv.pbVal, dbv.cpbVal);
- db_free(&dbv);
- }
-
- HookEvent(ME_OPT_INITIALISE, ContactOptInit);
- return 0;
-}
+/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (C) 2012-25 Miranda NG team (https://miranda-ng.org), +Copyright (c) 2000-12 Miranda IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "stdafx.h" + +static wchar_t* nameOrderDescr[] = +{ + LPGENW("My custom name (not movable)"), + LPGENW("Nick"), + LPGENW("FirstName"), + LPGENW("E-mail"), + LPGENW("LastName"), + LPGENW("Username"), + LPGENW("FirstName LastName"), + LPGENW("LastName FirstName"), + LPGENW("'(Unknown contact)' (not movable)") +}; + +uint8_t nameOrder[_countof(nameOrderDescr)]; + +static wchar_t* ProcessDatabaseValueDefault(MCONTACT hContact, const char *szProto, const char *szSetting) +{ + DBVARIANT dbv; + if (db_get(hContact, szProto, szSetting, &dbv)) + return nullptr; + + wchar_t *ret; + wchar_t buf[40]; + switch (dbv.type) { + case DBVT_BYTE: + ret = _itow(dbv.bVal, buf, 10); + break; + case DBVT_WORD: + ret = _itow(dbv.wVal, buf, 10); + break; + case DBVT_DWORD: + ret = _itow(dbv.dVal, buf, 10); + break; + case DBVT_BLOB: + if (dbv.cpbVal == 8) + ret = _i64tow(*(__int64*)dbv.pbVal, buf, 10); + else + ret = bin2hexW(dbv.pbVal, min(int(dbv.cpbVal), 19), buf); + break; + case DBVT_ASCIIZ: + ret = mir_a2u(dbv.pszVal); + break; + case DBVT_UTF8: + ret = mir_utf8decodeW(dbv.pszVal); + break; + case DBVT_WCHAR: + return dbv.pwszVal; // no need to free dbv + default: + ret = nullptr; + } + + db_free(&dbv); + return mir_wstrdup(ret); +} + +MIR_APP_DLL(wchar_t*) Contact::GetInfo(int type, MCONTACT hContact, const char *szProto) +{ + if (hContact == 0 && szProto == nullptr) + return nullptr; + + if (szProto == nullptr) + if (auto *pa = Proto_GetContactAccount(hContact)) + szProto = pa->szModuleName; + + if (szProto == nullptr) + return nullptr; + + wchar_t *res; + DBVARIANT dbv; + switch (type) { + case CNF_FIRSTNAME: return ProcessDatabaseValueDefault(hContact, szProto, "FirstName"); + case CNF_LASTNAME: return ProcessDatabaseValueDefault(hContact, szProto, "LastName"); + case CNF_NICK: return ProcessDatabaseValueDefault(hContact, szProto, "Nick"); + case CNF_EMAIL: return ProcessDatabaseValueDefault(hContact, szProto, "e-mail"); + case CNF_CITY: return ProcessDatabaseValueDefault(hContact, szProto, "City"); + case CNF_STATE: return ProcessDatabaseValueDefault(hContact, szProto, "State"); + case CNF_PHONE: return ProcessDatabaseValueDefault(hContact, szProto, "Phone"); + case CNF_HOMEPAGE: return ProcessDatabaseValueDefault(hContact, szProto, "Homepage"); + case CNF_ABOUT: return ProcessDatabaseValueDefault(hContact, szProto, "About"); + case CNF_AGE: return ProcessDatabaseValueDefault(hContact, szProto, "Age"); + case CNF_GENDER: return ProcessDatabaseValueDefault(hContact, szProto, "Gender"); + case CNF_FAX: return ProcessDatabaseValueDefault(hContact, szProto, "Fax"); + case CNF_CELLULAR: return ProcessDatabaseValueDefault(hContact, szProto, "Cellular"); + case CNF_BIRTHDAY: return ProcessDatabaseValueDefault(hContact, szProto, "BirthDay"); + case CNF_BIRTHMONTH: return ProcessDatabaseValueDefault(hContact, szProto, "BirthMonth"); + case CNF_BIRTHYEAR: return ProcessDatabaseValueDefault(hContact, szProto, "BirthYear"); + case CNF_STREET: return ProcessDatabaseValueDefault(hContact, szProto, "Street"); + case CNF_ZIP: return ProcessDatabaseValueDefault(hContact, szProto, "ZIP"); + case CNF_LANGUAGE1: return ProcessDatabaseValueDefault(hContact, szProto, "Language1"); + case CNF_LANGUAGE2: return ProcessDatabaseValueDefault(hContact, szProto, "Language2"); + case CNF_LANGUAGE3: return ProcessDatabaseValueDefault(hContact, szProto, "Language3"); + case CNF_CONAME: return ProcessDatabaseValueDefault(hContact, szProto, "Company"); + case CNF_CODEPT: return ProcessDatabaseValueDefault(hContact, szProto, "CompanyDepartment"); + case CNF_COPOSITION: return ProcessDatabaseValueDefault(hContact, szProto, "CompanyPosition"); + case CNF_COSTREET: return ProcessDatabaseValueDefault(hContact, szProto, "CompanyStreet"); + case CNF_COCITY: return ProcessDatabaseValueDefault(hContact, szProto, "CompanyCity"); + case CNF_COSTATE: return ProcessDatabaseValueDefault(hContact, szProto, "CompanyState"); + case CNF_COZIP: return ProcessDatabaseValueDefault(hContact, szProto, "CompanyZIP"); + case CNF_COHOMEPAGE: return ProcessDatabaseValueDefault(hContact, szProto, "CompanyHomepage"); + case CNF_CUSTOMNICK: + if (hContact) + return ProcessDatabaseValueDefault(hContact, "CList", "MyHandle"); + return ProcessDatabaseValueDefault(0, szProto, "MyHandle"); + + case CNF_COUNTRY: + case CNF_COCOUNTRY: + if (!db_get_ws(hContact, szProto, type == CNF_COUNTRY ? "CountryName" : "CompanyCountryName", &dbv)) + return dbv.pwszVal; + + if (!db_get(hContact, szProto, type == CNF_COUNTRY ? "Country" : "CompanyCountry", &dbv)) { + if (dbv.type == DBVT_WORD) { + int countryCount; + struct CountryListEntry *countries; + CallService(MS_UTILS_GETCOUNTRYLIST, (WPARAM)&countryCount, (LPARAM)&countries); + for (int i = 0; i < countryCount; i++) + if (countries[i].id == dbv.wVal) + return mir_a2u(countries[i].szName); + } + else { + db_free(&dbv); + return ProcessDatabaseValueDefault(hContact, szProto, type == CNF_COUNTRY ? "Country" : "CompanyCountry"); + } + } + break; + + case CNF_FIRSTLAST: + if (!db_get_ws(hContact, szProto, "FirstName", &dbv)) { + DBVARIANT dbv2; + if (!db_get_ws(hContact, szProto, "LastName", &dbv2)) { + size_t len = mir_wstrlen(dbv.pwszVal) + mir_wstrlen(dbv2.pwszVal) + 2; + wchar_t *buf = (wchar_t*)mir_alloc(sizeof(wchar_t)*len); + if (buf != nullptr) + mir_wstrcat(mir_wstrcat(mir_wstrcpy(buf, dbv.pwszVal), L" "), dbv2.pwszVal); + db_free(&dbv); + db_free(&dbv2); + return buf; + } + return dbv.pwszVal; + } + break; + + case CNF_UNIQUEID: + if (db_mc_isMeta(hContact)) { + wchar_t buf[40]; + _itow(hContact, buf, 10); + return mir_wstrdup(buf); + } + + if (auto *uid = Proto_GetUniqueId(szProto)) + return ProcessDatabaseValueDefault(hContact, szProto, uid); + break; + + case CNF_DISPLAYUID: + if (res = ProcessDatabaseValueDefault(hContact, szProto, "display_uid")) + return res; + + if (auto *uid = Proto_GetUniqueId(szProto)) + return ProcessDatabaseValueDefault(hContact, szProto, uid); + break; + + case CNF_DISPLAYNC: + case CNF_DISPLAY: + for (auto &it : nameOrder) { + switch (it) { + case 0: // custom name + // make sure we aren't in CNF_DISPLAYNC mode + // don't get custom name for nullptr contact + if (type == CNF_DISPLAY) + if (res = ProcessDatabaseValueDefault(hContact, (hContact != 0) ? "CList" : szProto, "MyHandle")) + return res; + break; + + case 1: + if (res = ProcessDatabaseValueDefault(hContact, szProto, "Nick")) // nick + return res; + break; + case 2: + if (res = ProcessDatabaseValueDefault(hContact, szProto, "FirstName")) // First Name + return res; + break; + case 3: + if (res = ProcessDatabaseValueDefault(hContact, szProto, "e-mail")) // E-mail + return res; + break; + case 4: + if (res = ProcessDatabaseValueDefault(hContact, szProto, "LastName")) // Last Name + return res; + break; + + case 5: // Unique id + // protocol must define a PFLAG_UNIQUEIDSETTING + if (auto *uid = Proto_GetUniqueId(szProto)) { + if (!db_get_ws(hContact, szProto, uid, &dbv)) { + if (dbv.type == DBVT_BYTE || dbv.type == DBVT_WORD || dbv.type == DBVT_DWORD) { + long value = (dbv.type == DBVT_BYTE) ? dbv.bVal : (dbv.type == DBVT_WORD ? dbv.wVal : dbv.dVal); + wchar_t buf[40]; + _ltow(value, buf, 10); + return mir_wstrdup(buf); + } + return dbv.pwszVal; + } + } + break; + + case 6: // first + last name + case 7: // last + first name + if (!db_get_ws(hContact, szProto, it == 6 ? "FirstName" : "LastName", &dbv)) { + DBVARIANT dbv2; + if (!db_get_ws(hContact, szProto, it == 6 ? "LastName" : "FirstName", &dbv2)) { + size_t len = mir_wstrlen(dbv.pwszVal) + mir_wstrlen(dbv2.pwszVal) + 2; + wchar_t *buf = (wchar_t*)mir_alloc(sizeof(wchar_t)*len); + if (buf != nullptr) + mir_wstrcat(mir_wstrcat(mir_wstrcpy(buf, dbv.pwszVal), L" "), dbv2.pwszVal); + + db_free(&dbv); + db_free(&dbv2); + return buf; + } + db_free(&dbv); + } + break; + + case 8: + return mir_wstrdup(TranslateT("'(Unknown contact)'")); + } + } + break; + + case CNF_MYNOTES: + return ProcessDatabaseValueDefault(hContact, "UserInfo", "MyNotes"); + + case CNF_TIMEZONE: + HANDLE hTz = TimeZone_CreateByContact(hContact, nullptr, TZF_KNOWNONLY); + if (hTz) { + LPTIME_ZONE_INFORMATION tzi = TimeZone_GetInfo(hTz); + int offset = tzi->Bias + tzi->StandardBias; + + char str[80]; + mir_snprintf(str, offset ? "UTC%+d:%02d" : "UTC", offset / -60, abs(offset % 60)); + return mir_a2u(str); + } + break; + } + + return nullptr; +} + +MIR_APP_DLL(int) Contact::GetStatus(MCONTACT hContact) +{ + if (hContact == 0) + return ID_STATUS_OFFLINE; + + const char *szProto = Proto_GetBaseAccountName(hContact); + if (szProto == nullptr) + return ID_STATUS_OFFLINE; + + return db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); +} + +/////////////////////////////////////////////////////////////////////////////// + +MIR_APP_DLL(bool) Contact::IsGroupChat(MCONTACT hContact, const char *szProto) +{ + if (szProto == nullptr) { + szProto = Proto_GetBaseAccountName(hContact); + if (szProto == nullptr) + return false; + } + + return db_get_b(hContact, szProto, "ChatRoom") != 0; +} + +/////////////////////////////////////////////////////////////////////////////// + +MIR_APP_DLL(bool) Contact::IsHidden(MCONTACT hContact) +{ + return db_get_b(hContact, "CList", "Hidden") != 0; +} + +MIR_APP_DLL(void) Contact::Hide(MCONTACT hContact, bool bHidden) +{ + if (bHidden) + db_set_b(hContact, "CList", "Hidden", 1); + else + db_unset(hContact, "CList", "Hidden"); +} + +/////////////////////////////////////////////////////////////////////////////// + +MIR_APP_DLL(bool) Contact::IsReadonly(MCONTACT hContact) +{ + return db_get_b(hContact, "CList", "ReadOnly") != 0; +} + +MIR_APP_DLL(void) Contact::Readonly(MCONTACT hContact, bool bReadOnly) +{ + if (bReadOnly) + db_set_b(hContact, "CList", "ReadOnly", 1); + else + db_unset(hContact, "CList", "ReadOnly"); +} + +/////////////////////////////////////////////////////////////////////////////// + +MIR_APP_DLL(bool) Contact::OnList(MCONTACT hContact) +{ + return db_get_b(hContact, "CList", "NotOnList", 0) == 0; +} + +MIR_APP_DLL(void) Contact::PutOnList(MCONTACT hContact) +{ + db_unset(hContact, "CList", "NotOnList"); +} + +MIR_APP_DLL(void) Contact::RemoveFromList(MCONTACT hContact) +{ + db_set_b(hContact, "CList", "NotOnList", 1); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Options dialog + +class CContactOptsDlg : public CDlgBase +{ + CCtrlTreeView m_nameOrder; + +public: + CContactOptsDlg() : + CDlgBase(g_plugin, IDD_OPT_CONTACT), + m_nameOrder(this, IDC_NAMEORDER) + { + m_nameOrder.SetFlags(MTREE_DND); + m_nameOrder.OnBeginDrag = BCallback(this, &CContactOptsDlg::OnBeginDrag); + m_nameOrder.OnEndDrag = BCallback(this, &CContactOptsDlg::OnEndDrag); + } + + bool OnInitDialog() override + { + TVINSERTSTRUCT tvis; + tvis.hParent = nullptr; + tvis.hInsertAfter = TVI_LAST; + tvis.item.mask = TVIF_TEXT | TVIF_PARAM; + for (int i = 0; i < _countof(nameOrderDescr); i++) { + tvis.item.lParam = nameOrder[i]; + tvis.item.pszText = TranslateW(nameOrderDescr[nameOrder[i]]); + m_nameOrder.InsertItem(&tvis); + } + return true; + } + + bool OnApply() override + { + TVITEMEX tvi; + tvi.hItem = m_nameOrder.GetRoot(); + int i = 0; + while (tvi.hItem != nullptr) { + tvi.mask = TVIF_PARAM | TVIF_HANDLE; + m_nameOrder.GetItem(&tvi); + nameOrder[i++] = (uint8_t)tvi.lParam; + tvi.hItem = m_nameOrder.GetNextSibling(tvi.hItem); + } + db_set_blob(0, "Contact", "NameOrder", nameOrder, _countof(nameOrderDescr)); + g_clistApi.pfnInvalidateDisplayNameCacheEntry(INVALID_CONTACT_ID); + return true; + } + + bool OnBeginDrag(CCtrlTreeView::TEventInfo *evt) + { + LPNMTREEVIEW pNotify = evt->nmtv; + return (pNotify->itemNew.lParam != 0 && pNotify->itemNew.lParam != _countof(nameOrderDescr)-1); + } + + bool OnEndDrag(CCtrlTreeView::TEventInfo *evt) + { + auto &hti = *evt->ntvhi; + + // do not allow to move selection over the first item + if (hti.flags & TVHT_ABOVE) + return false; + + // do not allow to move selection below the last item either + TVITEMEX tvi; + tvi.mask = TVIF_HANDLE | TVIF_PARAM; + tvi.hItem = hti.hItem; + m_nameOrder.GetItem(&tvi); + if (tvi.lParam == _countof(nameOrderDescr) - 1) + return false; + + return true; + } +}; + +static int ContactOptInit(WPARAM wParam, LPARAM) +{ + OPTIONSDIALOGPAGE odp = {}; + odp.position = -1000000000; + odp.szGroup.a = LPGEN("Contact list"); + odp.szTitle.a = LPGEN("Contact names"); + odp.pDialog = new CContactOptsDlg(); + odp.flags = ODPF_BOLDGROUPS; + g_plugin.addOptions(wParam, &odp); + + return PopupOptionsInit(wParam); +} + +int LoadContactsModule(void) +{ + for (uint8_t i = 0; i < _countof(nameOrder); i++) + nameOrder[i] = i; + + DBVARIANT dbv; + if (!db_get(0, "Contact", "NameOrder", &dbv)) { + memcpy(nameOrder, dbv.pbVal, dbv.cpbVal); + db_free(&dbv); + } + + HookEvent(ME_OPT_INITIALISE, ContactOptInit); + return 0; +} |