From 931a7dc1ac0dbc7e6c1083583ced915e572f5b47 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sat, 2 Mar 2019 12:32:44 +0300 Subject: all protocols (even virtual ones) moved to the Protocols folder --- .../src/CurrencyRatesProviderBase.cpp | 935 --------------------- 1 file changed, 935 deletions(-) delete mode 100644 plugins/CurrencyRates/src/CurrencyRatesProviderBase.cpp (limited to 'plugins/CurrencyRates/src/CurrencyRatesProviderBase.cpp') diff --git a/plugins/CurrencyRates/src/CurrencyRatesProviderBase.cpp b/plugins/CurrencyRates/src/CurrencyRatesProviderBase.cpp deleted file mode 100644 index 592fd551ba..0000000000 --- a/plugins/CurrencyRates/src/CurrencyRatesProviderBase.cpp +++ /dev/null @@ -1,935 +0,0 @@ -#include "StdAfx.h" - -extern bool g_bAutoUpdate; -extern HANDLE g_hEventWorkThreadStop; - -struct CXMLFileInfo -{ - CXMLFileInfo() : m_qs(L"Unknown") {} - ICurrencyRatesProvider::CProviderInfo m_pi; - CCurrencyRateSection m_qs; - tstring m_sURL; -}; - -inline tstring get_ini_file_name(LPCTSTR pszFileName) -{ - return CreateFilePath(pszFileName); -} - -bool parse_currencyrate(const TiXmlNode *pTop, CCurrencyRate &q) -{ - tstring sSymbol, sDescription, sID; - - for (auto *pNode : TiXmlEnum(pTop)) { - const char *sName = pNode->Value(); - if (!mir_strcmpi(sName, "symbol")) { - sSymbol = GetNodeText(pNode); - if (sSymbol.empty()) - return false; - } - else if (!mir_strcmpi(sName, "description")) { - sDescription = GetNodeText(pNode); - } - else if (!mir_strcmpi(sName, "id")) { - sID = GetNodeText(pNode); - if (sID.empty()) - return false; - } - } - - q = CCurrencyRate(sID, TranslateW(sSymbol.c_str()), TranslateW(sDescription.c_str())); - return true; -} - -bool parse_section(const TiXmlNode *pTop, CCurrencyRateSection &qs) -{ - CCurrencyRateSection::TSections aSections; - CCurrencyRateSection::TCurrencyRates aCurrencyRates; - tstring sSectionName; - - for (auto *pNode : TiXmlEnum(pTop)) { - const char *sName = pNode->Value(); - if (!mir_strcmpi(sName, "section")) { - CCurrencyRateSection qs1; - if (true == parse_section(pNode, qs1)) - aSections.push_back(qs1); - } - else if (!mir_strcmpi(sName, "currencyrate")) { - CCurrencyRate q; - if (true == parse_currencyrate(pNode, q)) - aCurrencyRates.push_back(q); - } - else if (!mir_strcmpi(sName, "name")) { - sSectionName = GetNodeText(pNode); - if (sSectionName.empty()) - return false; - } - } - - qs = CCurrencyRateSection(TranslateW(sSectionName.c_str()), aSections, aCurrencyRates); - return true; -} - -const TiXmlNode* find_provider(const TiXmlNode *pRoot) -{ - for (auto *pNode : TiXmlEnum(pRoot)) { - const char *sName = pNode->Value(); - if (!mir_strcmpi(sName, "Provider")) - return pNode; - - if (auto *pProvider = find_provider(pNode)) - return pProvider; - } - - return nullptr; -} - -CXMLFileInfo parse_ini_file(const tstring &rsXMLFile, bool &rbSucceded) -{ - CXMLFileInfo res; - CCurrencyRateSection::TSections aSections; - - TiXmlDocument doc; - if (doc.LoadFile(_T2A(rsXMLFile.c_str())) == tinyxml2::XML_SUCCESS) { - const TiXmlNode *pProvider = find_provider(&doc); - if (pProvider) { - rbSucceded = true; - for (auto *pNode : TiXmlEnum(pProvider)) { - const char *sName = pNode->Value(); - if (!mir_strcmpi(sName, "section")) { - CCurrencyRateSection qs; - if (parse_section(pNode, qs)) - aSections.push_back(qs); - } - else if (!mir_strcmpi(sName, "Name")) - res.m_pi.m_sName = GetNodeText(pNode); - else if (!mir_strcmpi(sName, "ref")) - res.m_pi.m_sURL = GetNodeText(pNode); - else if (!mir_strcmpi(sName, "url")) - res.m_sURL = GetNodeText(pNode); - } - } - } - - res.m_qs = CCurrencyRateSection(res.m_pi.m_sName, aSections); - return res; -} - -CXMLFileInfo init_xml_info(LPCTSTR pszFileName, bool& rbSucceded) -{ - rbSucceded = false; - tstring sIniFile = get_ini_file_name(pszFileName); - return parse_ini_file(sIniFile, rbSucceded); -} - -CCurrencyRatesProviderBase::CCurrencyRatesProviderBase() : - m_hEventSettingsChanged(::CreateEvent(nullptr, FALSE, FALSE, nullptr)), - m_hEventRefreshContact(::CreateEvent(nullptr, FALSE, FALSE, nullptr)), - m_bRefreshInProgress(false) -{ -} - -CCurrencyRatesProviderBase::~CCurrencyRatesProviderBase() -{ - delete m_pXMLInfo; - - ::CloseHandle(m_hEventSettingsChanged); - ::CloseHandle(m_hEventRefreshContact); -} - -bool CCurrencyRatesProviderBase::Init() -{ - bool bSucceded = (m_pXMLInfo == nullptr); - if (!m_pXMLInfo) - m_pXMLInfo = new CXMLFileInfo(init_xml_info(DB_DEF_IniFileName, bSucceded)); - - return bSucceded; -} - -const CCurrencyRatesProviderBase::CProviderInfo& CCurrencyRatesProviderBase::GetInfo() const -{ - return m_pXMLInfo->m_pi; -} - -const CCurrencyRateSection& CCurrencyRatesProviderBase::GetCurrencyRates() const -{ - return m_pXMLInfo->m_qs; -} - -const tstring& CCurrencyRatesProviderBase::GetURL() const -{ - return m_pXMLInfo->m_sURL; -} - -bool CCurrencyRatesProviderBase::IsOnline() -{ - return /*g_bAutoUpdate*/true; -} - -void CCurrencyRatesProviderBase::AddContact(MCONTACT hContact) -{ - // CCritSection cs(m_cs); - assert(m_aContacts.end() == std::find(m_aContacts.begin(), m_aContacts.end(), hContact)); - - m_aContacts.push_back(hContact); -} - -void CCurrencyRatesProviderBase::DeleteContact(MCONTACT hContact) -{ - mir_cslock lck(m_cs); - - TContacts::iterator i = std::find(m_aContacts.begin(), m_aContacts.end(), hContact); - if (i != m_aContacts.end()) - m_aContacts.erase(i); -} - -void CCurrencyRatesProviderBase::SetContactStatus(MCONTACT hContact, int nNewStatus) -{ - int nStatus = db_get_w(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_STATUS, ID_STATUS_OFFLINE); - if (nNewStatus != nStatus) { - db_set_w(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_STATUS, nNewStatus); - - if (ID_STATUS_ONLINE != nNewStatus) { - db_unset(hContact, LIST_MODULE_NAME, STATUS_MSG_NAME); - tstring sSymbol = CurrencyRates_DBGetStringW(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_SYMBOL); - if (false == sSymbol.empty()) - db_set_ws(hContact, LIST_MODULE_NAME, CONTACT_LIST_NAME, sSymbol.c_str()); - - SetContactExtraImage(hContact, eiEmpty); - } - } -} - -class CTendency -{ - enum { NumValues = 2 }; - enum EComparison - { - NonValid, - Greater, - Less, - Equal, - GreaterOrEqual, - LessOrEqual - }; - -public: - enum EResult - { - NotChanged, - Up, - Down - }; - -public: - CTendency() : m_nComparison(NonValid) {} - - bool Parse(CCurrencyRatesProviderBase *pProvider, const tstring& rsFrmt, MCONTACT hContact) - { - m_abValueFlags[0] = false; - m_abValueFlags[1] = false; - m_nComparison = NonValid; - bool bValid = true; - int nCurValue = 0; - for (tstring::const_iterator i = rsFrmt.begin(); i != rsFrmt.end() && bValid && nCurValue < NumValues;) { - wchar_t chr = *i; - switch (chr) { - default: - if (false == std::isspace(chr)) - bValid = false; - else - ++i; - break; - - case '%': - ++i; - if (i != rsFrmt.end()) { - wchar_t t = *i; - ++i; - - double d; - bValid = pProvider->ParseSymbol(hContact, t, d); - if (bValid) { - m_adValues[nCurValue] = d; - m_abValueFlags[nCurValue] = true; - ++nCurValue; - } - } - else bValid = false; - break; - case '>': - m_nComparison = Greater; - ++i; - break; - case '<': - m_nComparison = Less; - ++i; - break; - case '=': - switch (m_nComparison) { - default: - bValid = false; - break; - case NonValid: - m_nComparison = Equal; - break; - case Greater: - m_nComparison = GreaterOrEqual; - break; - case Less: - m_nComparison = LessOrEqual; - break; - } - ++i; - break; - } - } - - return (bValid && IsValid()); - } - - bool IsValid() const { return (m_abValueFlags[0] && m_abValueFlags[1] && (m_nComparison != NonValid)); } - - EResult Compare() const - { - switch (m_nComparison) { - case Greater: - if (true == IsWithinAccuracy(m_adValues[0], m_adValues[1])) - return NotChanged; - - if (m_adValues[0] > m_adValues[1]) - return Up; - return Down; - - case GreaterOrEqual: - if ((true == IsWithinAccuracy(m_adValues[0], m_adValues[1])) || (m_adValues[0] > m_adValues[1])) - return Up; - return Down; - - case Less: - if (true == IsWithinAccuracy(m_adValues[0], m_adValues[1])) - return NotChanged; - - if (m_adValues[0] < m_adValues[1]) - return Up; - return Down; - - case LessOrEqual: - if ((true == IsWithinAccuracy(m_adValues[0], m_adValues[1])) || (m_adValues[0] < m_adValues[1])) - return Up; - return Down; - - case Equal: - if (true == IsWithinAccuracy(m_adValues[0], m_adValues[1])) - return Up; - return Down; - } - return NotChanged; - } - -private: - double m_adValues[NumValues]; - bool m_abValueFlags[NumValues]; - EComparison m_nComparison; -}; - -tstring format_rate(const ICurrencyRatesProvider *pProvider, MCONTACT hContact, const tstring &rsFrmt) -{ - tstring sResult; - - for (tstring::const_iterator i = rsFrmt.begin(); i != rsFrmt.end();) { - wchar_t chr = *i; - switch (chr) { - default: - sResult += chr; - ++i; - break; - - case '\\': - ++i; - if (i != rsFrmt.end()) { - wchar_t t = *i; - switch (t) { - case '%': sResult += L"%"; break; - case 't': sResult += L"\t"; break; - case 'n': sResult += L"\n"; break; - case '\\': sResult += L"\\"; break; - default: sResult += chr; sResult += t; break; - } - ++i; - } - else sResult += chr; - break; - - case '%': - ++i; - if (i != rsFrmt.end()) { - chr = *i; - - byte nWidth = 0; - if (::isdigit(chr)) { - nWidth = chr - 0x30; - ++i; - if (i == rsFrmt.end()) { - sResult += chr; - break; - } - else chr = *i; - } - - sResult += pProvider->FormatSymbol(hContact, chr, nWidth); - ++i; - } - else sResult += chr; - break; - } - } - - return sResult; -} - -void log_to_file(const ICurrencyRatesProvider *pProvider, - MCONTACT hContact, - const tstring& rsLogFileName, - const tstring& rsFormat) -{ - CreatePathToFileW(rsLogFileName.c_str()); - - tofstream file(rsLogFileName.c_str(), std::ios::app | std::ios::out); - file.imbue(GetSystemLocale()); - if (file.good()) { - tstring s = format_rate(pProvider, hContact, rsFormat); - file << s; - } -} - -void log_to_history(const ICurrencyRatesProvider *pProvider, - MCONTACT hContact, - time_t nTime, - const tstring& rsFormat) -{ - tstring s = format_rate(pProvider, hContact, rsFormat); - T2Utf psz(s.c_str()); - - DBEVENTINFO dbei = {}; - dbei.szModule = CURRENCYRATES_MODULE_NAME; - dbei.timestamp = static_cast(nTime); - dbei.flags = DBEF_READ | DBEF_UTF; - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.cbBlob = (int)::mir_strlen(psz) + 1; - dbei.pBlob = (PBYTE)(char*)psz; - db_event_add(hContact, &dbei); -} - -bool do_set_contact_extra_icon(MCONTACT hContact, const CTendency& tendency) -{ - CTendency::EResult nComparison = tendency.Compare(); - - if (CTendency::NotChanged == nComparison) - return SetContactExtraImage(hContact, eiNotChanged); - - if (CTendency::Up == nComparison) - return SetContactExtraImage(hContact, eiUp); - - if (CTendency::Down == nComparison) - return SetContactExtraImage(hContact, eiDown); - - return false; -} - -bool show_popup(const ICurrencyRatesProvider *pProvider, - MCONTACT hContact, - const CTendency& tendency, - const tstring& rsFormat, - const CPopupSettings& ps) -{ - if (!ServiceExists(MS_POPUP_ADDPOPUPW)) - return false; - - POPUPDATAW ppd; - memset(&ppd, 0, sizeof(ppd)); - ppd.lchContact = hContact; - - if (tendency.IsValid()) { - CTendency::EResult nComparison = tendency.Compare(); - if (CTendency::NotChanged == nComparison) - ppd.lchIcon = CurrencyRates_LoadIconEx(IDI_ICON_NOTCHANGED); - else if (CTendency::Up == nComparison) - ppd.lchIcon = CurrencyRates_LoadIconEx(IDI_ICON_UP); - else if (CTendency::Down == nComparison) - ppd.lchIcon = CurrencyRates_LoadIconEx(IDI_ICON_DOWN); - } - - mir_wstrncpy(ppd.lpwzContactName, pProvider->FormatSymbol(hContact, 's').c_str(), MAX_CONTACTNAME); - { - ptrW ss(variables_parsedup((wchar_t*)rsFormat.c_str(), nullptr, hContact)); - tstring sText = format_rate(pProvider, hContact, tstring(ss)); - mir_wstrncpy(ppd.lpwzText, sText.c_str(), MAX_SECONDLINE); - } - - if (CPopupSettings::colourDefault == ps.GetColourMode()) { - ppd.colorText = CPopupSettings::GetDefColourText(); - ppd.colorBack = CPopupSettings::GetDefColourBk(); - } - else { - ppd.colorText = ps.GetColourText(); - ppd.colorBack = ps.GetColourBk(); - } - - switch (ps.GetDelayMode()) { - default: - assert(!"Unknown popup delay mode"); - case CPopupSettings::delayFromPopup: - ppd.iSeconds = 0; - break; - case CPopupSettings::delayPermanent: - ppd.iSeconds = -1; - break; - case CPopupSettings::delayCustom: - ppd.iSeconds = ps.GetDelayTimeout(); - break; - } - - LPARAM lp = 0; - if (false == ps.GetHistoryFlag()) - lp |= 0x08; - - return (0 == CallService(MS_POPUP_ADDPOPUPW, reinterpret_cast(&ppd), lp)); -} - -void CCurrencyRatesProviderBase::WriteContactRate(MCONTACT hContact, double dRate, const tstring& rsSymbol/* = ""*/) -{ - time_t nTime = ::time(0); - - if (false == rsSymbol.empty()) - db_set_ws(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_SYMBOL, rsSymbol.c_str()); - - double dPrev = 0.0; - bool bValidPrev = CurrencyRates_DBReadDouble(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_CURR_VALUE, dPrev); - if (true == bValidPrev) - CurrencyRates_DBWriteDouble(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_PREV_VALUE, dPrev); - - CurrencyRates_DBWriteDouble(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_CURR_VALUE, dRate); - db_set_dw(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_FETCH_TIME, nTime); - - tstring sSymbol = rsSymbol; - - tostringstream oNick; - oNick.imbue(GetSystemLocale()); - if (false == m_sContactListFormat.empty()) { - tstring s = format_rate(this, hContact, m_sContactListFormat); - oNick << s; - } - else { - if (true == sSymbol.empty()) - sSymbol = CurrencyRates_DBGetStringW(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_SYMBOL); - - oNick << std::setfill(L' ') << std::setw(10) << std::left << sSymbol << std::setw(6) << std::right << dRate; - } - CTendency tendency; - - if (true == tendency.Parse(this, m_sTendencyFormat, hContact)) - do_set_contact_extra_icon(hContact, tendency); - - db_set_ws(hContact, LIST_MODULE_NAME, CONTACT_LIST_NAME, oNick.str().c_str()); - - tstring sStatusMsg = format_rate(this, hContact, m_sStatusMsgFormat); - if (false == sStatusMsg.empty()) - db_set_ws(hContact, LIST_MODULE_NAME, STATUS_MSG_NAME, sStatusMsg.c_str()); - else - db_unset(hContact, LIST_MODULE_NAME, STATUS_MSG_NAME); - - bool bUseContactSpecific = (db_get_b(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CONTACT_SPEC_SETTINGS, 0) > 0); - - CAdvProviderSettings global_settings(this); - - WORD dwMode = (bUseContactSpecific) - ? db_get_w(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_LOG, static_cast(lmDisabled)) - : global_settings.GetLogMode(); - if (dwMode&lmExternalFile) { - bool bAdd = true; - bool bOnlyIfChanged = (bUseContactSpecific) - ? (db_get_w(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_LOG_FILE_CONDITION, 1) > 0) - : global_settings.GetLogOnlyChangedFlag(); - if (true == bOnlyIfChanged) { - bAdd = ((false == bValidPrev) || (false == IsWithinAccuracy(dRate, dPrev))); - } - if (true == bAdd) { - tstring sLogFileName = (bUseContactSpecific) - ? CurrencyRates_DBGetStringW(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_LOG_FILE, global_settings.GetLogFileName().c_str()) - : global_settings.GetLogFileName(); - - if (true == sSymbol.empty()) { - sSymbol = CurrencyRates_DBGetStringW(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_SYMBOL); - } - - sLogFileName = GenerateLogFileName(sLogFileName, sSymbol); - - tstring sFormat = global_settings.GetLogFormat(); - if (bUseContactSpecific) - sFormat = CurrencyRates_DBGetStringW(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_FORMAT_LOG_FILE, DB_DEF_LogFormat); - - log_to_file(this, hContact, sLogFileName, sFormat); - } - } - if (dwMode&lmInternalHistory) { - bool bAdd = true; - bool bOnlyIfChanged = (bUseContactSpecific) - ? (db_get_w(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_HISTORY_CONDITION, 1) > 0) - : global_settings.GetHistoryOnlyChangedFlag(); - - if (true == bOnlyIfChanged) { - bAdd = ((false == bValidPrev) || (false == IsWithinAccuracy(dRate, dPrev))); - } - if (true == bAdd) { - tstring sFormat = (bUseContactSpecific) - ? CurrencyRates_DBGetStringW(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_FORMAT_HISTORY, global_settings.GetHistoryFormat().c_str()) - : global_settings.GetHistoryFormat(); - - log_to_history(this, hContact, nTime, sFormat); - } - } - - if (dwMode&lmPopup) { - bool bOnlyIfChanged = (bUseContactSpecific) - ? (1 == db_get_b(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_POPUP_CONDITION, 1) > 0) - : global_settings.GetShowPopupIfValueChangedFlag(); - if ((false == bOnlyIfChanged) - || ((true == bOnlyIfChanged) && (true == bValidPrev) && (false == IsWithinAccuracy(dRate, dPrev)))) { - tstring sFormat = (bUseContactSpecific) - ? CurrencyRates_DBGetStringW(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_FORMAT_POPUP, global_settings.GetPopupFormat().c_str()) - : global_settings.GetPopupFormat(); - - CPopupSettings ps = *(global_settings.GetPopupSettingsPtr()); - ps.InitForContact(hContact); - show_popup(this, hContact, tendency, sFormat, ps); - } - } - - SetContactStatus(hContact, ID_STATUS_ONLINE); -} - -MCONTACT CCurrencyRatesProviderBase::CreateNewContact(const tstring& rsName) -{ - MCONTACT hContact = db_add_contact(); - if (hContact) { - if (0 == Proto_AddToContact(hContact, CURRENCYRATES_PROTOCOL_NAME)) { - tstring sProvName = GetInfo().m_sName; - db_set_ws(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_PROVIDER, sProvName.c_str()); - db_set_ws(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_SYMBOL, rsName.c_str()); - db_set_ws(hContact, LIST_MODULE_NAME, CONTACT_LIST_NAME, rsName.c_str()); - - mir_cslock lck(m_cs); - m_aContacts.push_back(hContact); - } - else { - db_delete_contact(hContact); - hContact = NULL; - } - } - - return hContact; -} - -DWORD get_refresh_timeout_miliseconds() -{ - if (!g_bAutoUpdate) - return INFINITE; - - int nRefreshRateType = db_get_w(0, CURRENCYRATES_MODULE_NAME, DB_KEY_RefreshRateType, RRT_MINUTES); - if (nRefreshRateType < RRT_SECONDS || nRefreshRateType > RRT_HOURS) - nRefreshRateType = RRT_MINUTES; - - DWORD nTimeout = db_get_w(0, CURRENCYRATES_MODULE_NAME, DB_KEY_RefreshRateValue, 1); - switch (nRefreshRateType) { - default: - case RRT_SECONDS: - if (nTimeout < 1 || nTimeout > 60) - nTimeout = 1; - - nTimeout *= 1000; - break; - case RRT_MINUTES: - if (nTimeout < 1 || nTimeout > 60) - nTimeout = 1; - - nTimeout *= 1000 * 60; - break; - case RRT_HOURS: - if (nTimeout < 1 || nTimeout > 24) - nTimeout = 1; - - nTimeout *= 1000 * 60 * 60; - break; - } - - return nTimeout; -} - -class CBoolGuard -{ -public: - CBoolGuard(bool& rb) : m_b(rb) { m_b = true; } - ~CBoolGuard() { m_b = false; } - -private: - bool m_b; -}; - -void CCurrencyRatesProviderBase::Run() -{ - DWORD nTimeout = get_refresh_timeout_miliseconds(); - m_sContactListFormat = CurrencyRates_DBGetStringW(NULL, CURRENCYRATES_MODULE_NAME, DB_KEY_DisplayNameFormat, DB_DEF_DisplayNameFormat); - m_sStatusMsgFormat = CurrencyRates_DBGetStringW(NULL, CURRENCYRATES_MODULE_NAME, DB_KEY_StatusMsgFormat, DB_DEF_StatusMsgFormat); - m_sTendencyFormat = CurrencyRates_DBGetStringW(NULL, CURRENCYRATES_MODULE_NAME, DB_KEY_TendencyFormat, DB_DEF_TendencyFormat); - - enum - { - STOP_THREAD = 0, - SETTINGS_CHANGED = 1, - REFRESH_CONTACT = 2, - COUNT_SYNC_OBJECTS = 3 - }; - - HANDLE anEvents[COUNT_SYNC_OBJECTS]; - anEvents[STOP_THREAD] = g_hEventWorkThreadStop; - anEvents[SETTINGS_CHANGED] = m_hEventSettingsChanged; - anEvents[REFRESH_CONTACT] = m_hEventRefreshContact; - - TContacts anContacts; - { - mir_cslock lck(m_cs); - anContacts = m_aContacts; - } - - bool bGoToBed = false; - - if (g_bAutoUpdate) { - CBoolGuard bg(m_bRefreshInProgress); - RefreshCurrencyRates(anContacts); - } - - while (false == bGoToBed) { - anContacts.clear(); - - DWORD dwBegin = ::GetTickCount(); - DWORD dwResult = ::WaitForMultipleObjects(COUNT_SYNC_OBJECTS, anEvents, FALSE, nTimeout); - switch (dwResult) { - case WAIT_FAILED: - assert(!"WaitForMultipleObjects failed"); - bGoToBed = true; - break; - - case WAIT_ABANDONED_0 + STOP_THREAD: - case WAIT_ABANDONED_0 + SETTINGS_CHANGED: - case WAIT_ABANDONED_0 + REFRESH_CONTACT: - assert(!"WaitForMultipleObjects abandoned"); - - case WAIT_OBJECT_0 + STOP_THREAD: - bGoToBed = true; - break; - - case WAIT_OBJECT_0 + SETTINGS_CHANGED: - nTimeout = get_refresh_timeout_miliseconds(); - m_sContactListFormat = CurrencyRates_DBGetStringW(NULL, CURRENCYRATES_MODULE_NAME, DB_KEY_DisplayNameFormat, DB_DEF_DisplayNameFormat); - m_sStatusMsgFormat = CurrencyRates_DBGetStringW(NULL, CURRENCYRATES_MODULE_NAME, DB_KEY_StatusMsgFormat, DB_DEF_StatusMsgFormat); - m_sTendencyFormat = CurrencyRates_DBGetStringW(NULL, CURRENCYRATES_MODULE_NAME, DB_KEY_TendencyFormat, DB_DEF_TendencyFormat); - { - mir_cslock lck(m_cs); - anContacts = m_aContacts; - } - break; - - case WAIT_OBJECT_0 + REFRESH_CONTACT: - { - DWORD dwTimeRest = ::GetTickCount() - dwBegin; - if (INFINITE != nTimeout && dwTimeRest < nTimeout) - nTimeout -= dwTimeRest; - - { - mir_cslock lck(m_cs); - anContacts = m_aRefreshingContacts; - m_aRefreshingContacts.clear(); - } - - CBoolGuard bg(m_bRefreshInProgress); - RefreshCurrencyRates(anContacts); - } - break; - - case WAIT_TIMEOUT: - nTimeout = get_refresh_timeout_miliseconds(); - { - mir_cslock lck(m_cs); - anContacts = m_aContacts; - } - { - CBoolGuard bg(m_bRefreshInProgress); - RefreshCurrencyRates(anContacts); - } - break; - - default: - assert(!"What is the hell?"); - } - } - - OnEndRun(); -} - -void CCurrencyRatesProviderBase::OnEndRun() -{ - TContacts anContacts; - { - mir_cslock lck(m_cs); - anContacts = m_aContacts; - m_aRefreshingContacts.clear(); - } - - CBoolGuard bg(m_bRefreshInProgress); - for (auto &it : anContacts) - SetContactStatus(it, ID_STATUS_OFFLINE); -} - -void CCurrencyRatesProviderBase::RefreshSettings() -{ - ::SetEvent(m_hEventSettingsChanged); -} - -void CCurrencyRatesProviderBase::RefreshAllContacts() -{ - { mir_cslock lck(m_cs); - m_aRefreshingContacts.clear(); - for (auto &hContact : m_aContacts) - m_aRefreshingContacts.push_back(hContact); - } - - ::SetEvent(m_hEventRefreshContact); -} - -void CCurrencyRatesProviderBase::RefreshContact(MCONTACT hContact) -{ - { mir_cslock lck(m_cs); - m_aRefreshingContacts.push_back(hContact); - } - - ::SetEvent(m_hEventRefreshContact); -} - -void CCurrencyRatesProviderBase::FillFormat(TFormatSpecificators &array) const -{ - array.push_back(CFormatSpecificator(L"%S", TranslateT("Source of Information"))); - array.push_back(CFormatSpecificator(L"%r", TranslateT("Rate Value"))); - array.push_back(CFormatSpecificator(L"%p", TranslateT("Previous Rate Value"))); - array.push_back(CFormatSpecificator(L"%X", TranslateT("Fetch Time"))); - array.push_back(CFormatSpecificator(L"%x", TranslateT("Fetch Date"))); - array.push_back(CFormatSpecificator(L"%t", TranslateT("Fetch Time and Date"))); - array.push_back(CFormatSpecificator(L"\\%", TranslateT("Percentage Character (%)"))); - array.push_back(CFormatSpecificator(L"\\t", TranslateT("Tabulation"))); - array.push_back(CFormatSpecificator(L"\\\\", TranslateT("Left slash (\\)"))); -} - -bool CCurrencyRatesProviderBase::ParseSymbol(MCONTACT hContact, wchar_t c, double &d) -{ - switch (c) { - case 'r': - case 'R': - return CurrencyRates_DBReadDouble(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_CURR_VALUE, d); - - case 'p': - case 'P': - return CurrencyRates_DBReadDouble(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_PREV_VALUE, d); - } - - return false; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static bool get_fetch_time(MCONTACT hContact, time_t &rTime) -{ - DBVARIANT dbv; - if (db_get(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_FETCH_TIME, &dbv) || (DBVT_DWORD != dbv.type)) - return false; - - rTime = dbv.dVal; - return true; -} - -static tstring format_fetch_time(MCONTACT hContact, const tstring &rsFormat) -{ - time_t nTime; - if (true == get_fetch_time(hContact, nTime)) { - boost::posix_time::ptime time = boost::date_time::c_local_adjustor::utc_to_local(boost::posix_time::from_time_t(nTime)); - tostringstream k; - k.imbue(std::locale(GetSystemLocale(), new ttime_facet(rsFormat.c_str()))); - k << time; - return k.str(); - } - - return tstring(); -} - -static tstring format_double(double dValue, int nWidth) -{ - tostringstream o; - o.imbue(GetSystemLocale()); - - if (nWidth > 0 && nWidth <= 9) - o << std::setprecision(nWidth) << std::showpoint << std::fixed; - - o << dValue; - - return o.str(); -} - -tstring CCurrencyRatesProviderBase::FormatSymbol(MCONTACT hContact, wchar_t c, int nWidth) const -{ - tstring ret; - double d = 0.0; - - switch (c) { - case '%': - case '\t': - case '\\': - ret = c; - break; - case 'S': - ret = CurrencyRates_DBGetStringW(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_PROVIDER); - break; - case 's': - ret = CurrencyRates_DBGetStringW(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_SYMBOL); - break; - case 'X': - ret = format_fetch_time(hContact, CurrencyRates_GetTimeFormat(true)); - break; - case 'x': - ret = format_fetch_time(hContact, CurrencyRates_GetDateFormat(true)); - break; - case 't': - { - tstring sFrmt = CurrencyRates_GetDateFormat(true); - sFrmt += L" "; - sFrmt += CurrencyRates_GetTimeFormat(true); - ret = format_fetch_time(hContact, sFrmt); - } - break; - case 'r': - case 'R': - if (true == CurrencyRates_DBReadDouble(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_CURR_VALUE, d)) - ret = format_double(d, nWidth); - else - ret = L"-"; - break; - - case 'p': - case 'P': - if (true == CurrencyRates_DBReadDouble(hContact, CURRENCYRATES_MODULE_NAME, DB_STR_CURRENCYRATE_PREV_VALUE, d)) - ret = format_double(d, nWidth); - else - ret = L"-"; - break; - } - - return ret; -} -- cgit v1.2.3