summaryrefslogtreecommitdiff
path: root/protocols/CurrencyRates
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2023-11-17 13:10:33 +0300
committerGeorge Hazan <george.hazan@gmail.com>2023-11-17 13:10:33 +0300
commit8de798016edb9d7e87bda93431ba9548f5c6353a (patch)
treec7d30216e49860ab78114fbb593c0f840d0b3270 /protocols/CurrencyRates
parent65204f98efd6595b903d1dd6ee7a21ba88d63948 (diff)
CurrencyRates: options moved to the separate file
Diffstat (limited to 'protocols/CurrencyRates')
-rw-r--r--protocols/CurrencyRates/Forex.vcxproj1
-rw-r--r--protocols/CurrencyRates/Forex.vcxproj.filters3
-rw-r--r--protocols/CurrencyRates/src/CurrencyRatesProviderBase.cpp1
-rw-r--r--protocols/CurrencyRates/src/CurrencyRatesProviderCurrencyConverter.cpp349
-rw-r--r--protocols/CurrencyRates/src/CurrencyRatesProviderCurrencyConverter.h1
-rw-r--r--protocols/CurrencyRates/src/Forex.cpp15
-rw-r--r--protocols/CurrencyRates/src/ICurrencyRatesProvider.h2
-rw-r--r--protocols/CurrencyRates/src/Options.cpp375
8 files changed, 382 insertions, 365 deletions
diff --git a/protocols/CurrencyRates/Forex.vcxproj b/protocols/CurrencyRates/Forex.vcxproj
index 5dc8e5f06b..99c68f8138 100644
--- a/protocols/CurrencyRates/Forex.vcxproj
+++ b/protocols/CurrencyRates/Forex.vcxproj
@@ -40,6 +40,7 @@
<ClCompile Include="src\ImportExport.cpp" />
<ClCompile Include="src\Locale.cpp" />
<ClCompile Include="src\ModuleInfo.cpp" />
+ <ClCompile Include="src\Options.cpp" />
<ClCompile Include="src\SettingsDlg.cpp" />
<ClCompile Include="src\stdafx.cxx">
<PrecompiledHeader>Create</PrecompiledHeader>
diff --git a/protocols/CurrencyRates/Forex.vcxproj.filters b/protocols/CurrencyRates/Forex.vcxproj.filters
index 895b379c35..aeda748bf4 100644
--- a/protocols/CurrencyRates/Forex.vcxproj.filters
+++ b/protocols/CurrencyRates/Forex.vcxproj.filters
@@ -53,6 +53,9 @@
<ClCompile Include="src\WinCtrlHelper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\Options.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Chart.h">
diff --git a/protocols/CurrencyRates/src/CurrencyRatesProviderBase.cpp b/protocols/CurrencyRates/src/CurrencyRatesProviderBase.cpp
index 70ecc65a35..94dd3cf6b0 100644
--- a/protocols/CurrencyRates/src/CurrencyRatesProviderBase.cpp
+++ b/protocols/CurrencyRates/src/CurrencyRatesProviderBase.cpp
@@ -702,6 +702,7 @@ void CCurrencyRatesProviderBase::Run()
case WAIT_ABANDONED_0 + SETTINGS_CHANGED:
case WAIT_ABANDONED_0 + REFRESH_CONTACT:
assert(!"WaitForMultipleObjects abandoned");
+ __fallthrough;
case WAIT_OBJECT_0 + STOP_THREAD:
bGoToBed = true;
diff --git a/protocols/CurrencyRates/src/CurrencyRatesProviderCurrencyConverter.cpp b/protocols/CurrencyRates/src/CurrencyRatesProviderCurrencyConverter.cpp
index abeb77a885..cea1fff5b7 100644
--- a/protocols/CurrencyRates/src/CurrencyRatesProviderCurrencyConverter.cpp
+++ b/protocols/CurrencyRates/src/CurrencyRatesProviderCurrencyConverter.cpp
@@ -1,33 +1,6 @@
#include "stdafx.h"
#include "CurrencyRatesProviderCurrencyConverter.h"
-typedef boost::shared_ptr<CAdvProviderSettings> TAdvSettingsPtr;
-typedef std::map<const ICurrencyRatesProvider *, TAdvSettingsPtr> TAdvSettings;
-
-TAdvSettings g_aAdvSettings;
-
-CAdvProviderSettings *get_adv_settings(const ICurrencyRatesProvider *m_pProvider, bool bCreateIfNonExist)
-{
- TAdvSettings::iterator i = g_aAdvSettings.find(m_pProvider);
- if (i != g_aAdvSettings.end())
- return i->second.get();
-
- if (true == bCreateIfNonExist) {
- TAdvSettingsPtr pAdvSet(new CAdvProviderSettings(m_pProvider));
- g_aAdvSettings.insert(std::make_pair(m_pProvider, pAdvSet));
- return pAdvSet.get();
- }
-
- return nullptr;
-}
-
-void remove_adv_settings(const ICurrencyRatesProvider *m_pProvider)
-{
- TAdvSettings::iterator i = g_aAdvSettings.find(m_pProvider);
- if (i != g_aAdvSettings.end())
- g_aAdvSettings.erase(i);
-}
-
CMStringW build_url(const CMStringW &rsURL, const CMStringW &from, const CMStringW &to)
{
CMStringW res = rsURL + L"?q=" + from + L"_" + to + L"&compact=ultra";
@@ -54,321 +27,6 @@ bool parse_response(const CMStringW &rsJSON, double &dRate)
return true;
}
-using TWatchedRates = std::vector<CCurrencyRatesProviderCurrencyConverter::TRateInfo>;
-TWatchedRates g_aWatchedRates;
-
-class COptionsDlg : public CDlgBase
-{
- CCurrencyRatesProviderCurrencyConverter* get_provider()
- {
- for (auto &it : g_apProviders)
- if (auto p = dynamic_cast<CCurrencyRatesProviderCurrencyConverter*>(it))
- return p;
-
- assert(!"We should never get here!");
- return nullptr;
- };
-
- CMStringW make_currencyrate_name(const CCurrencyRate &rCurrencyRate)
- {
- auto &rsDesc = rCurrencyRate.GetName();
- return((false == rsDesc.IsEmpty()) ? rsDesc : rCurrencyRate.GetSymbol());
- };
-
- CMStringW make_contact_name(const CMStringW &rsSymbolFrom, const CMStringW &rsSymbolTo)
- {
- return rsSymbolFrom + L"/" + rsSymbolTo;
- };
-
- CMStringW make_rate_name(const CCurrencyRatesProviderCurrencyConverter::TRateInfo &ri)
- {
- if ((false == ri.first.GetName().IsEmpty()) && (false == ri.second.GetName().IsEmpty()))
- return make_contact_name(ri.first.GetName(), ri.second.GetName());
-
- return make_contact_name(ri.first.GetSymbol(), ri.second.GetSymbol());
- };
-
- CCurrencyRatesProviderCurrencyConverter *m_pProvider;
-
- CCtrlCombo cmbFrom, cmbTo;
- CCtrlButton btnAdd, btnRemove, btnDescr, btnAdvanced;
- CCtrlListBox m_list;
-
-public:
- COptionsDlg() :
- CDlgBase(g_plugin, IDD_DIALOG_OPT_GOOGLE),
- m_pProvider(get_provider()),
- m_list(this, IDC_LIST_RATES),
- btnAdd(this, IDC_BUTTON_ADD),
- btnDescr(this, IDC_BUTTON_DESCRIPTION),
- btnRemove(this, IDC_BUTTON_REMOVE),
- btnAdvanced(this, IDC_BUTTON_ADVANCED_SETTINGS),
- cmbTo(this, IDC_COMBO_CONVERT_INTO),
- cmbFrom(this, IDC_COMBO_CONVERT_FROM)
- {
- btnAdd.OnClick = Callback(this, &COptionsDlg::onClick_Add);
- btnDescr.OnClick = Callback(this, &COptionsDlg::onClick_Descr);
- btnRemove.OnClick = Callback(this, &COptionsDlg::onClick_Remove);
- btnAdvanced.OnClick = Callback(this, &COptionsDlg::onClick_Advanced);
-
- cmbTo.OnSelChanged = cmbFrom.OnSelChanged = Callback(this, &COptionsDlg::onSelChange_From);
- m_list.OnSelChange = Callback(this, &COptionsDlg::onSelChange_Rates);
- }
-
- bool OnInitDialog() override
- {
- // set contact list display format
- ::SetDlgItemTextW(m_hwnd, IDC_EDIT_CONTACT_LIST_FORMAT, g_plugin.getMStringW(DB_KEY_DisplayNameFormat, DB_DEF_DisplayNameFormat));
-
- // set status message display format
- ::SetDlgItemTextW(m_hwnd, IDC_EDIT_STATUS_MESSAGE_FORMAT, g_plugin.getMStringW(DB_KEY_StatusMsgFormat, DB_DEF_StatusMsgFormat));
-
- // set tendency format
- ::SetDlgItemTextW(m_hwnd, IDC_EDIT_TENDENCY_FORMAT, g_plugin.getMStringW(DB_KEY_TendencyFormat, DB_DEF_TendencyFormat));
-
- // set api key
- ::SetDlgItemTextW(m_hwnd, IDC_EDIT_PERSONAL_KEY, g_plugin.getMStringW(DB_KEY_ApiKey));
-
- // refresh rate
- HWND hwndCombo = ::GetDlgItem(m_hwnd, IDC_COMBO_REFRESH_RATE);
- LPCTSTR pszRefreshRateTypes[] = { TranslateT("Seconds"), TranslateT("Minutes"), TranslateT("Hours") };
- for (int i = 0; i < _countof(pszRefreshRateTypes); ++i)
- ::SendMessage(hwndCombo, CB_ADDSTRING, 0, LPARAM(pszRefreshRateTypes[i]));
-
- int nRefreshRateType = g_plugin.getWord(DB_KEY_RefreshRateType, RRT_MINUTES);
- if (nRefreshRateType < RRT_SECONDS || nRefreshRateType > RRT_HOURS)
- nRefreshRateType = RRT_MINUTES;
-
- UINT nRate = g_plugin.getWord(DB_KEY_RefreshRateValue, 1);
- switch (nRefreshRateType) {
- case RRT_SECONDS:
- case RRT_MINUTES:
- if (nRate < 1 || nRate > 60)
- nRate = 1;
-
- spin_set_range(::GetDlgItem(m_hwnd, IDC_SPIN_REFRESH_RATE), 1, 60);
- break;
- case RRT_HOURS:
- if (nRate < 1 || nRate > 24)
- nRate = 1;
-
- spin_set_range(::GetDlgItem(m_hwnd, IDC_SPIN_REFRESH_RATE), 1, 24);
- break;
- }
-
- ::SendMessage(hwndCombo, CB_SETCURSEL, nRefreshRateType, 0);
- ::SetDlgItemInt(m_hwnd, IDC_EDIT_REFRESH_RATE, nRate, FALSE);
-
- g_aWatchedRates.clear();
-
- CCurrencyRateSection rSection;
- const auto &rCurrencyRates = m_pProvider->GetCurrencyRates();
- if (rCurrencyRates.GetSectionCount() > 0) {
- rSection = rCurrencyRates.GetSection(0);
- }
-
- auto cCurrencyRates = rSection.GetCurrencyRateCount();
- for (auto i = 0u; i < cCurrencyRates; ++i) {
- const auto &rCurrencyRate = rSection.GetCurrencyRate(i);
- CMStringW sName = make_currencyrate_name(rCurrencyRate);
- cmbFrom.AddString(sName);
- cmbTo.AddString(sName);
- }
-
- auto cWatchedRates = m_pProvider->GetWatchedRateCount();
- for (auto i = 0u; i < cWatchedRates; ++i) {
- CCurrencyRatesProviderCurrencyConverter::TRateInfo ri;
- if (true == m_pProvider->GetWatchedRateInfo(i, ri)) {
- g_aWatchedRates.push_back(ri);
- CMStringW sRate = make_rate_name(ri);
- m_list.AddString(sRate);
- }
- }
-
- btnAdd.Disable();
- btnRemove.Disable();
- return true;
- }
-
- bool OnApply() override
- {
- BOOL bOk = FALSE;
- UINT nRefreshRate = ::GetDlgItemInt(m_hwnd, IDC_EDIT_REFRESH_RATE, &bOk, FALSE);
- ERefreshRateType nType = static_cast<ERefreshRateType>(::SendDlgItemMessage(m_hwnd, IDC_COMBO_REFRESH_RATE, CB_GETCURSEL, 0, 0));
-
- g_plugin.setWord(DB_KEY_RefreshRateType, nType);
- g_plugin.setWord(DB_KEY_RefreshRateValue, nRefreshRate);
-
- g_plugin.setWString(DB_KEY_DisplayNameFormat, get_window_text(::GetDlgItem(m_hwnd, IDC_EDIT_CONTACT_LIST_FORMAT)));
- g_plugin.setWString(DB_KEY_StatusMsgFormat, get_window_text(::GetDlgItem(m_hwnd, IDC_EDIT_STATUS_MESSAGE_FORMAT)));
- g_plugin.setWString(DB_KEY_TendencyFormat, get_window_text(::GetDlgItem(m_hwnd, IDC_EDIT_TENDENCY_FORMAT)));
- g_plugin.setWString(DB_KEY_ApiKey, get_window_text(::GetDlgItem(m_hwnd, IDC_EDIT_PERSONAL_KEY)));
-
- CAdvProviderSettings *pAdvSet = get_adv_settings(m_pProvider, false);
- if (pAdvSet)
- pAdvSet->SaveToDb();
-
- TWatchedRates aTemp(g_aWatchedRates);
- TWatchedRates aRemove;
- size_t cWatchedRates = m_pProvider->GetWatchedRateCount();
- for (size_t i = 0; i < cWatchedRates; ++i) {
- CCurrencyRatesProviderCurrencyConverter::TRateInfo ri;
- if (true == m_pProvider->GetWatchedRateInfo(i, ri)) {
- auto it = std::find_if(aTemp.begin(), aTemp.end(), [&ri](const auto& other)->bool
- {
- return ((0 == mir_wstrcmpi(ri.first.GetID().c_str(), other.first.GetID().c_str()))
- && ((0 == mir_wstrcmpi(ri.second.GetID().c_str(), other.second.GetID().c_str()))));
- });
- if (it == aTemp.end()) {
- aRemove.push_back(ri);
- }
- else {
- aTemp.erase(it);
- }
- }
- }
-
- for (auto &it : aRemove)
- m_pProvider->WatchForRate(it, false);
- for (auto &it : aTemp)
- m_pProvider->WatchForRate(it, true);
- m_pProvider->RefreshSettings();
- return true;
- }
-
- void OnDestroy() override
- {
- remove_adv_settings(m_pProvider);
- }
-
- LRESULT DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override
- {
- if (msg == WM_NOTIFY) {
- LPNMHDR pNMHDR = reinterpret_cast<LPNMHDR>(lParam);
- switch (pNMHDR->code) {
- case PSN_KILLACTIVE:
- BOOL bOk = FALSE;
- UINT nRefreshRate = ::GetDlgItemInt(m_hwnd, IDC_EDIT_REFRESH_RATE, &bOk, FALSE);
- ERefreshRateType nType = static_cast<ERefreshRateType>(::SendDlgItemMessage(m_hwnd, IDC_COMBO_REFRESH_RATE, CB_GETCURSEL, 0, 0));
- switch (nType) {
- case RRT_MINUTES:
- case RRT_SECONDS:
- if (FALSE == bOk || nRefreshRate < 1 || nRefreshRate > 60) {
- prepare_edit_ctrl_for_error(::GetDlgItem(m_hwnd, IDC_EDIT_REFRESH_RATE));
- CurrencyRates_MessageBox(m_hwnd, TranslateT("Enter integer value between 1 and 60."), MB_OK | MB_ICONERROR);
- bOk = FALSE;
- }
- break;
- case RRT_HOURS:
- if (FALSE == bOk || nRefreshRate < 1 || nRefreshRate > 24) {
- prepare_edit_ctrl_for_error(::GetDlgItem(m_hwnd, IDC_EDIT_REFRESH_RATE));
- CurrencyRates_MessageBox(m_hwnd, TranslateT("Enter integer value between 1 and 24."), MB_OK | MB_ICONERROR);
- bOk = FALSE;
- }
- break;
- }
-
- if (TRUE == bOk) {
- HWND hEdit = ::GetDlgItem(m_hwnd, IDC_EDIT_CONTACT_LIST_FORMAT);
- assert(IsWindow(hEdit));
-
- CMStringW s = get_window_text(hEdit);
- if (s.IsEmpty()) {
- prepare_edit_ctrl_for_error(hEdit);
- CurrencyRates_MessageBox(m_hwnd, TranslateT("Enter text to display in contact list."), MB_OK | MB_ICONERROR);
- bOk = FALSE;
- }
- }
-
- ::SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, (TRUE == bOk) ? FALSE : TRUE);
- break;
- }
- }
-
- return CDlgBase::DlgProc(msg, wParam, lParam);
- }
-
- void onSelChange_From(CCtrlCombo*)
- {
- int nFrom = cmbFrom.GetCurSel();
- int nTo = cmbTo.GetCurSel();
- btnAdd.Enable((CB_ERR != nFrom) && (CB_ERR != nTo) && (nFrom != nTo));
- }
-
- void onSelChange_Rates(CCtrlCombo *)
- {
- int nType = m_list.GetCurSel();
- btnRemove.Enable(LB_ERR != nType);
-
- switch (nType) {
- case RRT_SECONDS:
- case RRT_MINUTES:
- spin_set_range(::GetDlgItem(m_hwnd, IDC_SPIN_REFRESH_RATE), 1, 60);
- break;
- case RRT_HOURS:
- spin_set_range(::GetDlgItem(m_hwnd, IDC_SPIN_REFRESH_RATE), 1, 24);
- BOOL bOk = FALSE;
- UINT nRefreshRate = ::GetDlgItemInt(m_hwnd, IDC_EDIT_REFRESH_RATE, &bOk, FALSE);
- if (TRUE == bOk && nRefreshRate > 24)
- ::SetDlgItemInt(m_hwnd, IDC_EDIT_REFRESH_RATE, 24, FALSE);
- break;
- }
- }
-
- void onClick_Add(CCtrlButton*)
- {
- size_t nFrom = cmbFrom.GetCurSel();
- size_t nTo = cmbTo.GetCurSel();
- if ((CB_ERR != nFrom) && (CB_ERR != nTo) && (nFrom != nTo)) {
- CCurrencyRateSection rSection;
- const auto& rCurrencyRates = m_pProvider->GetCurrencyRates();
- if (rCurrencyRates.GetSectionCount() > 0)
- rSection = rCurrencyRates.GetSection(0);
-
- auto cCurrencyRates = rSection.GetCurrencyRateCount();
- if ((nFrom < cCurrencyRates) && (nTo < cCurrencyRates)) {
- CCurrencyRatesProviderCurrencyConverter::TRateInfo ri;
- ri.first = rSection.GetCurrencyRate(nFrom);
- ri.second = rSection.GetCurrencyRate(nTo);
-
- g_aWatchedRates.push_back(ri);
-
- CMStringW sRate = make_rate_name(ri);
- m_list.AddString(sRate);
- NotifyChange();
- }
- }
- }
-
- void onClick_Advanced(CCtrlButton *)
- {
- CAdvProviderSettings *pAdvSet = get_adv_settings(m_pProvider, true);
- assert(pAdvSet);
- if (true == ShowSettingsDlg(m_hwnd, pAdvSet))
- NotifyChange();
- }
-
- void onClick_Descr(CCtrlButton *)
- {
- show_variable_list(m_hwnd, m_pProvider);
- }
-
- void onClick_Remove(CCtrlButton *)
- {
- int nSel = m_list.GetCurSel();
- if (LB_ERR != nSel) {
- m_list.DeleteString(nSel);
- if (nSel < static_cast<int>(g_aWatchedRates.size())) {
- g_aWatchedRates.erase(g_aWatchedRates.begin() + nSel);
- NotifyChange();
- }
- }
-
- nSel = m_list.GetCurSel();
- btnRemove.Enable(LB_ERR != nSel);
- }
-};
-
CCurrencyRatesProviderCurrencyConverter::CCurrencyRatesProviderCurrencyConverter()
{
}
@@ -377,13 +35,6 @@ CCurrencyRatesProviderCurrencyConverter::~CCurrencyRatesProviderCurrencyConverte
{
}
-void CCurrencyRatesProviderCurrencyConverter::ShowPropertyPage(WPARAM wp, OPTIONSDIALOGPAGE &odp)
-{
- odp.pDialog = new COptionsDlg();
- odp.szTab.w = const_cast<LPTSTR>(GetInfo().m_sName.c_str());
- g_plugin.addOptions(wp, &odp);
-}
-
void CCurrencyRatesProviderCurrencyConverter::RefreshCurrencyRates(TContacts &anContacts)
{
CHTTPSession http;
diff --git a/protocols/CurrencyRates/src/CurrencyRatesProviderCurrencyConverter.h b/protocols/CurrencyRates/src/CurrencyRatesProviderCurrencyConverter.h
index 0bb2f6225f..2d87b02256 100644
--- a/protocols/CurrencyRates/src/CurrencyRatesProviderCurrencyConverter.h
+++ b/protocols/CurrencyRates/src/CurrencyRatesProviderCurrencyConverter.h
@@ -25,7 +25,6 @@ public:
private:
void FillFormat(TFormatSpecificators &) const override;
void RefreshCurrencyRates(TContacts &anContacts) override;
- void ShowPropertyPage(WPARAM wp, OPTIONSDIALOGPAGE &odp) override;
MCONTACT ImportContact(const TiXmlNode*) override;
CMStringW FormatSymbol(MCONTACT hContact, wchar_t c, int nWidth) const override;
diff --git a/protocols/CurrencyRates/src/Forex.cpp b/protocols/CurrencyRates/src/Forex.cpp
index cd4982e42d..8006a6e448 100644
--- a/protocols/CurrencyRates/src/Forex.cpp
+++ b/protocols/CurrencyRates/src/Forex.cpp
@@ -8,6 +8,8 @@
#define DB_STR_AUTO_UPDATE "AutoUpdate"
+int CurrencyRatesEventFunc_OptInitialise(WPARAM wp, LPARAM);
+
CMPlugin g_plugin;
HANDLE g_hEventWorkThreadStop;
@@ -242,19 +244,6 @@ int CurrencyRatesEventFunc_PreShutdown(WPARAM, LPARAM)
return 0;
}
-int CurrencyRatesEventFunc_OptInitialise(WPARAM wp, LPARAM/* lp*/)
-{
- OPTIONSDIALOGPAGE odp = {};
- odp.position = 910000000;
- odp.szTitle.w = LPGENW("Currency Rates");
- odp.szGroup.w = LPGENW("Network");
- odp.flags = ODPF_USERINFOTAB | ODPF_UNICODE;
-
- for (auto &it : g_apProviders)
- it->ShowPropertyPage(wp, odp);
- return 0;
-}
-
inline int CurrencyRates_UnhookEvent(HANDLE h)
{
return UnhookEvent(h);
diff --git a/protocols/CurrencyRates/src/ICurrencyRatesProvider.h b/protocols/CurrencyRates/src/ICurrencyRatesProvider.h
index 63783cdb7d..3d8d07ca92 100644
--- a/protocols/CurrencyRates/src/ICurrencyRatesProvider.h
+++ b/protocols/CurrencyRates/src/ICurrencyRatesProvider.h
@@ -34,8 +34,6 @@ public:
virtual void DeleteContact(MCONTACT hContact) = 0;
virtual MCONTACT ImportContact(const TiXmlNode*) = 0;
- virtual void ShowPropertyPage(WPARAM wp, OPTIONSDIALOGPAGE& odp) = 0;
-
virtual void RefreshAllContacts() = 0;
virtual void RefreshSettings() = 0;
virtual void RefreshContact(MCONTACT hContact) = 0;
diff --git a/protocols/CurrencyRates/src/Options.cpp b/protocols/CurrencyRates/src/Options.cpp
new file mode 100644
index 0000000000..50e770faed
--- /dev/null
+++ b/protocols/CurrencyRates/src/Options.cpp
@@ -0,0 +1,375 @@
+/*
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+
+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 version 2
+of the License.
+
+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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stdafx.h"
+#include "CurrencyRatesProviderCurrencyConverter.h"
+
+typedef boost::shared_ptr<CAdvProviderSettings> TAdvSettingsPtr;
+typedef std::map<const ICurrencyRatesProvider *, TAdvSettingsPtr> TAdvSettings;
+
+TAdvSettings g_aAdvSettings;
+
+CAdvProviderSettings *get_adv_settings(const ICurrencyRatesProvider *m_pProvider, bool bCreateIfNonExist)
+{
+ TAdvSettings::iterator i = g_aAdvSettings.find(m_pProvider);
+ if (i != g_aAdvSettings.end())
+ return i->second.get();
+
+ if (true == bCreateIfNonExist) {
+ TAdvSettingsPtr pAdvSet(new CAdvProviderSettings(m_pProvider));
+ g_aAdvSettings.insert(std::make_pair(m_pProvider, pAdvSet));
+ return pAdvSet.get();
+ }
+
+ return nullptr;
+}
+
+void remove_adv_settings(const ICurrencyRatesProvider *m_pProvider)
+{
+ TAdvSettings::iterator i = g_aAdvSettings.find(m_pProvider);
+ if (i != g_aAdvSettings.end())
+ g_aAdvSettings.erase(i);
+}
+
+class COptionsDlg : public CDlgBase
+{
+ CCurrencyRatesProviderCurrencyConverter *get_provider()
+ {
+ for (auto &it : g_apProviders)
+ if (auto p = dynamic_cast<CCurrencyRatesProviderCurrencyConverter *>(it))
+ return p;
+
+ assert(!"We should never get here!");
+ return nullptr;
+ };
+
+ CMStringW make_currencyrate_name(const CCurrencyRate &rCurrencyRate)
+ {
+ auto &rsDesc = rCurrencyRate.GetName();
+ return((false == rsDesc.IsEmpty()) ? rsDesc : rCurrencyRate.GetSymbol());
+ };
+
+ CMStringW make_contact_name(const CMStringW &rsSymbolFrom, const CMStringW &rsSymbolTo)
+ {
+ return rsSymbolFrom + L"/" + rsSymbolTo;
+ };
+
+ CMStringW make_rate_name(const CCurrencyRatesProviderCurrencyConverter::TRateInfo &ri)
+ {
+ if ((false == ri.first.GetName().IsEmpty()) && (false == ri.second.GetName().IsEmpty()))
+ return make_contact_name(ri.first.GetName(), ri.second.GetName());
+
+ return make_contact_name(ri.first.GetSymbol(), ri.second.GetSymbol());
+ };
+
+ using TWatchedRates = std::vector<CCurrencyRatesProviderCurrencyConverter::TRateInfo>;
+ TWatchedRates g_aWatchedRates;
+
+ CCurrencyRatesProviderCurrencyConverter *m_pProvider;
+
+ CCtrlCombo cmbFrom, cmbTo;
+ CCtrlButton btnAdd, btnRemove, btnDescr, btnAdvanced;
+ CCtrlListBox m_list;
+
+public:
+ COptionsDlg() :
+ CDlgBase(g_plugin, IDD_DIALOG_OPT_GOOGLE),
+ m_pProvider(get_provider()),
+ m_list(this, IDC_LIST_RATES),
+ btnAdd(this, IDC_BUTTON_ADD),
+ btnDescr(this, IDC_BUTTON_DESCRIPTION),
+ btnRemove(this, IDC_BUTTON_REMOVE),
+ btnAdvanced(this, IDC_BUTTON_ADVANCED_SETTINGS),
+ cmbTo(this, IDC_COMBO_CONVERT_INTO),
+ cmbFrom(this, IDC_COMBO_CONVERT_FROM)
+ {
+ btnAdd.OnClick = Callback(this, &COptionsDlg::onClick_Add);
+ btnDescr.OnClick = Callback(this, &COptionsDlg::onClick_Descr);
+ btnRemove.OnClick = Callback(this, &COptionsDlg::onClick_Remove);
+ btnAdvanced.OnClick = Callback(this, &COptionsDlg::onClick_Advanced);
+
+ cmbTo.OnSelChanged = cmbFrom.OnSelChanged = Callback(this, &COptionsDlg::onSelChange_From);
+ m_list.OnSelChange = Callback(this, &COptionsDlg::onSelChange_Rates);
+ }
+
+ bool OnInitDialog() override
+ {
+ // set contact list display format
+ ::SetDlgItemTextW(m_hwnd, IDC_EDIT_CONTACT_LIST_FORMAT, g_plugin.getMStringW(DB_KEY_DisplayNameFormat, DB_DEF_DisplayNameFormat));
+
+ // set status message display format
+ ::SetDlgItemTextW(m_hwnd, IDC_EDIT_STATUS_MESSAGE_FORMAT, g_plugin.getMStringW(DB_KEY_StatusMsgFormat, DB_DEF_StatusMsgFormat));
+
+ // set tendency format
+ ::SetDlgItemTextW(m_hwnd, IDC_EDIT_TENDENCY_FORMAT, g_plugin.getMStringW(DB_KEY_TendencyFormat, DB_DEF_TendencyFormat));
+
+ // set api key
+ ::SetDlgItemTextW(m_hwnd, IDC_EDIT_PERSONAL_KEY, g_plugin.getMStringW(DB_KEY_ApiKey));
+
+ // refresh rate
+ HWND hwndCombo = ::GetDlgItem(m_hwnd, IDC_COMBO_REFRESH_RATE);
+ LPCTSTR pszRefreshRateTypes[] = { TranslateT("Seconds"), TranslateT("Minutes"), TranslateT("Hours") };
+ for (int i = 0; i < _countof(pszRefreshRateTypes); ++i)
+ ::SendMessage(hwndCombo, CB_ADDSTRING, 0, LPARAM(pszRefreshRateTypes[i]));
+
+ int nRefreshRateType = g_plugin.getWord(DB_KEY_RefreshRateType, RRT_MINUTES);
+ if (nRefreshRateType < RRT_SECONDS || nRefreshRateType > RRT_HOURS)
+ nRefreshRateType = RRT_MINUTES;
+
+ UINT nRate = g_plugin.getWord(DB_KEY_RefreshRateValue, 1);
+ switch (nRefreshRateType) {
+ case RRT_SECONDS:
+ case RRT_MINUTES:
+ if (nRate < 1 || nRate > 60)
+ nRate = 1;
+
+ spin_set_range(::GetDlgItem(m_hwnd, IDC_SPIN_REFRESH_RATE), 1, 60);
+ break;
+ case RRT_HOURS:
+ if (nRate < 1 || nRate > 24)
+ nRate = 1;
+
+ spin_set_range(::GetDlgItem(m_hwnd, IDC_SPIN_REFRESH_RATE), 1, 24);
+ break;
+ }
+
+ ::SendMessage(hwndCombo, CB_SETCURSEL, nRefreshRateType, 0);
+ ::SetDlgItemInt(m_hwnd, IDC_EDIT_REFRESH_RATE, nRate, FALSE);
+
+ g_aWatchedRates.clear();
+
+ CCurrencyRateSection rSection;
+ const auto &rCurrencyRates = m_pProvider->GetCurrencyRates();
+ if (rCurrencyRates.GetSectionCount() > 0) {
+ rSection = rCurrencyRates.GetSection(0);
+ }
+
+ auto cCurrencyRates = rSection.GetCurrencyRateCount();
+ for (auto i = 0u; i < cCurrencyRates; ++i) {
+ const auto &rCurrencyRate = rSection.GetCurrencyRate(i);
+ CMStringW sName = make_currencyrate_name(rCurrencyRate);
+ cmbFrom.AddString(sName);
+ cmbTo.AddString(sName);
+ }
+
+ auto cWatchedRates = m_pProvider->GetWatchedRateCount();
+ for (auto i = 0u; i < cWatchedRates; ++i) {
+ CCurrencyRatesProviderCurrencyConverter::TRateInfo ri;
+ if (true == m_pProvider->GetWatchedRateInfo(i, ri)) {
+ g_aWatchedRates.push_back(ri);
+ CMStringW sRate = make_rate_name(ri);
+ m_list.AddString(sRate);
+ }
+ }
+
+ btnAdd.Disable();
+ btnRemove.Disable();
+ return true;
+ }
+
+ bool OnApply() override
+ {
+ BOOL bOk = FALSE;
+ UINT nRefreshRate = ::GetDlgItemInt(m_hwnd, IDC_EDIT_REFRESH_RATE, &bOk, FALSE);
+ ERefreshRateType nType = static_cast<ERefreshRateType>(::SendDlgItemMessage(m_hwnd, IDC_COMBO_REFRESH_RATE, CB_GETCURSEL, 0, 0));
+
+ g_plugin.setWord(DB_KEY_RefreshRateType, nType);
+ g_plugin.setWord(DB_KEY_RefreshRateValue, nRefreshRate);
+
+ g_plugin.setWString(DB_KEY_DisplayNameFormat, get_window_text(::GetDlgItem(m_hwnd, IDC_EDIT_CONTACT_LIST_FORMAT)));
+ g_plugin.setWString(DB_KEY_StatusMsgFormat, get_window_text(::GetDlgItem(m_hwnd, IDC_EDIT_STATUS_MESSAGE_FORMAT)));
+ g_plugin.setWString(DB_KEY_TendencyFormat, get_window_text(::GetDlgItem(m_hwnd, IDC_EDIT_TENDENCY_FORMAT)));
+ g_plugin.setWString(DB_KEY_ApiKey, get_window_text(::GetDlgItem(m_hwnd, IDC_EDIT_PERSONAL_KEY)));
+
+ CAdvProviderSettings *pAdvSet = get_adv_settings(m_pProvider, false);
+ if (pAdvSet)
+ pAdvSet->SaveToDb();
+
+ TWatchedRates aTemp(g_aWatchedRates);
+ TWatchedRates aRemove;
+ size_t cWatchedRates = m_pProvider->GetWatchedRateCount();
+ for (size_t i = 0; i < cWatchedRates; ++i) {
+ CCurrencyRatesProviderCurrencyConverter::TRateInfo ri;
+ if (true == m_pProvider->GetWatchedRateInfo(i, ri)) {
+ auto it = std::find_if(aTemp.begin(), aTemp.end(), [&ri](const auto &other)->bool
+ {
+ return ((0 == mir_wstrcmpi(ri.first.GetID().c_str(), other.first.GetID().c_str()))
+ && ((0 == mir_wstrcmpi(ri.second.GetID().c_str(), other.second.GetID().c_str()))));
+ });
+ if (it == aTemp.end()) {
+ aRemove.push_back(ri);
+ }
+ else {
+ aTemp.erase(it);
+ }
+ }
+ }
+
+ for (auto &it : aRemove)
+ m_pProvider->WatchForRate(it, false);
+ for (auto &it : aTemp)
+ m_pProvider->WatchForRate(it, true);
+ m_pProvider->RefreshSettings();
+ return true;
+ }
+
+ void OnDestroy() override
+ {
+ remove_adv_settings(m_pProvider);
+ }
+
+ LRESULT DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override
+ {
+ if (msg == WM_NOTIFY) {
+ LPNMHDR pNMHDR = reinterpret_cast<LPNMHDR>(lParam);
+ switch (pNMHDR->code) {
+ case PSN_KILLACTIVE:
+ BOOL bOk = FALSE;
+ UINT nRefreshRate = ::GetDlgItemInt(m_hwnd, IDC_EDIT_REFRESH_RATE, &bOk, FALSE);
+ ERefreshRateType nType = static_cast<ERefreshRateType>(::SendDlgItemMessage(m_hwnd, IDC_COMBO_REFRESH_RATE, CB_GETCURSEL, 0, 0));
+ switch (nType) {
+ case RRT_MINUTES:
+ case RRT_SECONDS:
+ if (FALSE == bOk || nRefreshRate < 1 || nRefreshRate > 60) {
+ prepare_edit_ctrl_for_error(::GetDlgItem(m_hwnd, IDC_EDIT_REFRESH_RATE));
+ CurrencyRates_MessageBox(m_hwnd, TranslateT("Enter integer value between 1 and 60."), MB_OK | MB_ICONERROR);
+ bOk = FALSE;
+ }
+ break;
+ case RRT_HOURS:
+ if (FALSE == bOk || nRefreshRate < 1 || nRefreshRate > 24) {
+ prepare_edit_ctrl_for_error(::GetDlgItem(m_hwnd, IDC_EDIT_REFRESH_RATE));
+ CurrencyRates_MessageBox(m_hwnd, TranslateT("Enter integer value between 1 and 24."), MB_OK | MB_ICONERROR);
+ bOk = FALSE;
+ }
+ break;
+ }
+
+ if (TRUE == bOk) {
+ HWND hEdit = ::GetDlgItem(m_hwnd, IDC_EDIT_CONTACT_LIST_FORMAT);
+ assert(IsWindow(hEdit));
+
+ CMStringW s = get_window_text(hEdit);
+ if (s.IsEmpty()) {
+ prepare_edit_ctrl_for_error(hEdit);
+ CurrencyRates_MessageBox(m_hwnd, TranslateT("Enter text to display in contact list."), MB_OK | MB_ICONERROR);
+ bOk = FALSE;
+ }
+ }
+
+ ::SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, (TRUE == bOk) ? FALSE : TRUE);
+ break;
+ }
+ }
+
+ return CDlgBase::DlgProc(msg, wParam, lParam);
+ }
+
+ void onSelChange_From(CCtrlCombo *)
+ {
+ int nFrom = cmbFrom.GetCurSel();
+ int nTo = cmbTo.GetCurSel();
+ btnAdd.Enable((CB_ERR != nFrom) && (CB_ERR != nTo) && (nFrom != nTo));
+ }
+
+ void onSelChange_Rates(CCtrlCombo *)
+ {
+ int nType = m_list.GetCurSel();
+ btnRemove.Enable(LB_ERR != nType);
+
+ switch (nType) {
+ case RRT_SECONDS:
+ case RRT_MINUTES:
+ spin_set_range(::GetDlgItem(m_hwnd, IDC_SPIN_REFRESH_RATE), 1, 60);
+ break;
+ case RRT_HOURS:
+ spin_set_range(::GetDlgItem(m_hwnd, IDC_SPIN_REFRESH_RATE), 1, 24);
+ BOOL bOk = FALSE;
+ UINT nRefreshRate = ::GetDlgItemInt(m_hwnd, IDC_EDIT_REFRESH_RATE, &bOk, FALSE);
+ if (TRUE == bOk && nRefreshRate > 24)
+ ::SetDlgItemInt(m_hwnd, IDC_EDIT_REFRESH_RATE, 24, FALSE);
+ break;
+ }
+ }
+
+ void onClick_Add(CCtrlButton *)
+ {
+ size_t nFrom = cmbFrom.GetCurSel();
+ size_t nTo = cmbTo.GetCurSel();
+ if ((CB_ERR != nFrom) && (CB_ERR != nTo) && (nFrom != nTo)) {
+ CCurrencyRateSection rSection;
+ const auto &rCurrencyRates = m_pProvider->GetCurrencyRates();
+ if (rCurrencyRates.GetSectionCount() > 0)
+ rSection = rCurrencyRates.GetSection(0);
+
+ auto cCurrencyRates = rSection.GetCurrencyRateCount();
+ if ((nFrom < cCurrencyRates) && (nTo < cCurrencyRates)) {
+ CCurrencyRatesProviderCurrencyConverter::TRateInfo ri;
+ ri.first = rSection.GetCurrencyRate(nFrom);
+ ri.second = rSection.GetCurrencyRate(nTo);
+
+ g_aWatchedRates.push_back(ri);
+
+ CMStringW sRate = make_rate_name(ri);
+ m_list.AddString(sRate);
+ NotifyChange();
+ }
+ }
+ }
+
+ void onClick_Advanced(CCtrlButton *)
+ {
+ CAdvProviderSettings *pAdvSet = get_adv_settings(m_pProvider, true);
+ assert(pAdvSet);
+ if (true == ShowSettingsDlg(m_hwnd, pAdvSet))
+ NotifyChange();
+ }
+
+ void onClick_Descr(CCtrlButton *)
+ {
+ show_variable_list(m_hwnd, m_pProvider);
+ }
+
+ void onClick_Remove(CCtrlButton *)
+ {
+ int nSel = m_list.GetCurSel();
+ if (LB_ERR != nSel) {
+ m_list.DeleteString(nSel);
+ if (nSel < static_cast<int>(g_aWatchedRates.size())) {
+ g_aWatchedRates.erase(g_aWatchedRates.begin() + nSel);
+ NotifyChange();
+ }
+ }
+
+ nSel = m_list.GetCurSel();
+ btnRemove.Enable(LB_ERR != nSel);
+ }
+};
+
+int CurrencyRatesEventFunc_OptInitialise(WPARAM wp, LPARAM)
+{
+ OPTIONSDIALOGPAGE odp = {};
+ odp.position = 910000000;
+ odp.szTitle.a = LPGEN("Currency Rates");
+ odp.szGroup.a = LPGEN("Network");
+ odp.flags = ODPF_USERINFOTAB;
+
+ odp.pDialog = new COptionsDlg();
+ odp.szTab.a = LPGEN("General");
+ g_plugin.addOptions(wp, &odp);
+ return 0;
+}