From b61ba851da0157ace3bdfc1ebbf87156b0b76413 Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Wed, 6 Jun 2012 08:58:27 +0000 Subject: protocols plugins moved to protocols git-svn-id: http://svn.miranda-ng.org/main/trunk@327 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Quotes/Base64.cpp | 43 + protocols/Quotes/Base64.h | 12 + protocols/Quotes/Chart.h | 280 ++++ protocols/Quotes/ComHelper.cpp | 39 + protocols/Quotes/ComHelper.h | 9 + protocols/Quotes/CommonOptionDlg.cpp | 272 ++++ protocols/Quotes/CommonOptionDlg.h | 17 + protocols/Quotes/CreateFilePath.cpp | 45 + protocols/Quotes/CreateFilePath.h | 8 + protocols/Quotes/CurrencyConverter.cpp | 309 ++++ protocols/Quotes/CurrencyConverter.h | 6 + protocols/Quotes/DBUtils.cpp | 70 + protocols/Quotes/DBUtils.h | 16 + protocols/Quotes/EconomicRateInfo.h | 59 + protocols/Quotes/ExtraImages.cpp | 143 ++ protocols/Quotes/ExtraImages.h | 39 + protocols/Quotes/Forex.cpp | 517 +++++++ protocols/Quotes/Forex.rc | 573 +++++++ protocols/Quotes/Forex.sln | 26 + protocols/Quotes/Forex.vcxproj | 289 ++++ protocols/Quotes/Forex.vcxproj.filters | 307 ++++ protocols/Quotes/HTMLParserMS.cpp | 313 ++++ protocols/Quotes/HTMLParserMS.h | 36 + protocols/Quotes/HTTPSession.cpp | 262 ++++ protocols/Quotes/HTTPSession.h | 27 + protocols/Quotes/IHTMLEngine.h | 18 + protocols/Quotes/IHTMLParser.h | 41 + protocols/Quotes/IQuotesProvider.h | 41 + protocols/Quotes/IXMLEngine.h | 43 + protocols/Quotes/IconLib.cpp | 106 ++ protocols/Quotes/IconLib.h | 21 + protocols/Quotes/ImportExport.cpp | 850 ++++++++++ protocols/Quotes/ImportExport.h | 11 + protocols/Quotes/IsWithinAccuracy.h | 15 + protocols/Quotes/LightMutex.cpp | 22 + protocols/Quotes/LightMutex.h | 34 + protocols/Quotes/Locale.cpp | 75 + protocols/Quotes/Locale.h | 9 + protocols/Quotes/Log.cpp | 56 + protocols/Quotes/Log.h | 13 + protocols/Quotes/ModuleInfo.cpp | 150 ++ protocols/Quotes/ModuleInfo.h | 46 + protocols/Quotes/OptionDukasCopy.cpp | 414 +++++ protocols/Quotes/OptionDukasCopy.h | 8 + protocols/Quotes/QuoteChart.cpp | 408 +++++ protocols/Quotes/QuoteChart.h | 12 + protocols/Quotes/QuoteInfoDlg.cpp | 353 +++++ protocols/Quotes/QuoteInfoDlg.h | 11 + protocols/Quotes/QuotesProviderBase.cpp | Bin 0 -> 59044 bytes protocols/Quotes/QuotesProviderBase.h | 112 ++ protocols/Quotes/QuotesProviderDukasCopy.cpp | Bin 0 -> 15324 bytes protocols/Quotes/QuotesProviderDukasCopy.h | 38 + protocols/Quotes/QuotesProviderFinance.cpp | 318 ++++ protocols/Quotes/QuotesProviderFinance.h | 21 + protocols/Quotes/QuotesProviderGoogle.cpp | 543 +++++++ protocols/Quotes/QuotesProviderGoogle.h | 42 + protocols/Quotes/QuotesProviderGoogleFinance.cpp | 366 +++++ protocols/Quotes/QuotesProviderGoogleFinance.h | 25 + protocols/Quotes/QuotesProviderVisitor.h | 25 + .../Quotes/QuotesProviderVisitorDbSettings.cpp | 157 ++ protocols/Quotes/QuotesProviderVisitorDbSettings.h | 49 + .../QuotesProviderVisitorFormatSpecificator.cpp | 63 + .../QuotesProviderVisitorFormatSpecificator.h | 36 + protocols/Quotes/QuotesProviderVisitorFormater.cpp | 216 +++ protocols/Quotes/QuotesProviderVisitorFormater.h | 32 + protocols/Quotes/QuotesProviderVisitorTendency.cpp | 70 + protocols/Quotes/QuotesProviderVisitorTendency.h | 29 + protocols/Quotes/QuotesProviderYahoo.cpp | 193 +++ protocols/Quotes/QuotesProviderYahoo.h | 20 + protocols/Quotes/QuotesProviders.cpp | 120 ++ protocols/Quotes/QuotesProviders.h | 32 + protocols/Quotes/SettingsDlg.cpp | 1148 ++++++++++++++ protocols/Quotes/SettingsDlg.h | 118 ++ protocols/Quotes/Utility/DukasCopy.py | 48 + protocols/Quotes/Utility/Dukascopy.xml | 1635 ++++++++++++++++++++ protocols/Quotes/Utility/Google.py | 52 + protocols/Quotes/Utility/GoogleFinance.xml | 7 + protocols/Quotes/Utility/Quotes_Readme.txt | 112 ++ protocols/Quotes/Utility/Yahoo.xml | 7 + protocols/Quotes/Utility/google.xml | 91 ++ protocols/Quotes/Version.rc | 41 + protocols/Quotes/WinCtrlHelper.cpp | 49 + protocols/Quotes/WinCtrlHelper.h | 37 + protocols/Quotes/WorkingThread.cpp | 15 + protocols/Quotes/WorkingThread.h | 6 + protocols/Quotes/XMLEngineMI.cpp | 230 +++ protocols/Quotes/XMLEngineMI.h | 17 + protocols/Quotes/dllmain.cpp | 23 + protocols/Quotes/proto_Quotes/proto_Quotes.rc | 122 ++ .../Quotes/proto_Quotes/proto_Quotes_10.vcxproj | 129 ++ .../proto_Quotes/proto_Quotes_10.vcxproj.filters | 28 + protocols/Quotes/res/CurrencyConverter.ico | Bin 0 -> 5430 bytes protocols/Quotes/res/Export quotes.ico | Bin 0 -> 1150 bytes protocols/Quotes/res/Import quotes.ico | Bin 0 -> 1150 bytes protocols/Quotes/res/Refresh.ico | Bin 0 -> 1406 bytes protocols/Quotes/res/Section.ico | Bin 0 -> 1406 bytes protocols/Quotes/res/down.ico | Bin 0 -> 1406 bytes protocols/Quotes/res/main.ico | Bin 0 -> 1150 bytes protocols/Quotes/res/notchanged.ico | Bin 0 -> 1406 bytes protocols/Quotes/res/proto_na.ico | Bin 0 -> 1406 bytes protocols/Quotes/res/proto_occupied.ico | Bin 0 -> 1406 bytes protocols/Quotes/res/proto_offline.ico | Bin 0 -> 1406 bytes protocols/Quotes/res/proto_online.ico | Bin 0 -> 1406 bytes protocols/Quotes/res/quote.ico | Bin 0 -> 1406 bytes protocols/Quotes/res/swap.ico | Bin 0 -> 318 bytes protocols/Quotes/res/up.ico | Bin 0 -> 1406 bytes protocols/Quotes/resource.h | 109 ++ protocols/Quotes/stdafx.cpp | 8 + protocols/Quotes/stdafx.h | 165 ++ protocols/Quotes/targetver.h | 24 + protocols/Quotes/version.h | 25 + 111 files changed, 13227 insertions(+) create mode 100644 protocols/Quotes/Base64.cpp create mode 100644 protocols/Quotes/Base64.h create mode 100644 protocols/Quotes/Chart.h create mode 100644 protocols/Quotes/ComHelper.cpp create mode 100644 protocols/Quotes/ComHelper.h create mode 100644 protocols/Quotes/CommonOptionDlg.cpp create mode 100644 protocols/Quotes/CommonOptionDlg.h create mode 100644 protocols/Quotes/CreateFilePath.cpp create mode 100644 protocols/Quotes/CreateFilePath.h create mode 100644 protocols/Quotes/CurrencyConverter.cpp create mode 100644 protocols/Quotes/CurrencyConverter.h create mode 100644 protocols/Quotes/DBUtils.cpp create mode 100644 protocols/Quotes/DBUtils.h create mode 100644 protocols/Quotes/EconomicRateInfo.h create mode 100644 protocols/Quotes/ExtraImages.cpp create mode 100644 protocols/Quotes/ExtraImages.h create mode 100644 protocols/Quotes/Forex.cpp create mode 100644 protocols/Quotes/Forex.rc create mode 100644 protocols/Quotes/Forex.sln create mode 100644 protocols/Quotes/Forex.vcxproj create mode 100644 protocols/Quotes/Forex.vcxproj.filters create mode 100644 protocols/Quotes/HTMLParserMS.cpp create mode 100644 protocols/Quotes/HTMLParserMS.h create mode 100644 protocols/Quotes/HTTPSession.cpp create mode 100644 protocols/Quotes/HTTPSession.h create mode 100644 protocols/Quotes/IHTMLEngine.h create mode 100644 protocols/Quotes/IHTMLParser.h create mode 100644 protocols/Quotes/IQuotesProvider.h create mode 100644 protocols/Quotes/IXMLEngine.h create mode 100644 protocols/Quotes/IconLib.cpp create mode 100644 protocols/Quotes/IconLib.h create mode 100644 protocols/Quotes/ImportExport.cpp create mode 100644 protocols/Quotes/ImportExport.h create mode 100644 protocols/Quotes/IsWithinAccuracy.h create mode 100644 protocols/Quotes/LightMutex.cpp create mode 100644 protocols/Quotes/LightMutex.h create mode 100644 protocols/Quotes/Locale.cpp create mode 100644 protocols/Quotes/Locale.h create mode 100644 protocols/Quotes/Log.cpp create mode 100644 protocols/Quotes/Log.h create mode 100644 protocols/Quotes/ModuleInfo.cpp create mode 100644 protocols/Quotes/ModuleInfo.h create mode 100644 protocols/Quotes/OptionDukasCopy.cpp create mode 100644 protocols/Quotes/OptionDukasCopy.h create mode 100644 protocols/Quotes/QuoteChart.cpp create mode 100644 protocols/Quotes/QuoteChart.h create mode 100644 protocols/Quotes/QuoteInfoDlg.cpp create mode 100644 protocols/Quotes/QuoteInfoDlg.h create mode 100644 protocols/Quotes/QuotesProviderBase.cpp create mode 100644 protocols/Quotes/QuotesProviderBase.h create mode 100644 protocols/Quotes/QuotesProviderDukasCopy.cpp create mode 100644 protocols/Quotes/QuotesProviderDukasCopy.h create mode 100644 protocols/Quotes/QuotesProviderFinance.cpp create mode 100644 protocols/Quotes/QuotesProviderFinance.h create mode 100644 protocols/Quotes/QuotesProviderGoogle.cpp create mode 100644 protocols/Quotes/QuotesProviderGoogle.h create mode 100644 protocols/Quotes/QuotesProviderGoogleFinance.cpp create mode 100644 protocols/Quotes/QuotesProviderGoogleFinance.h create mode 100644 protocols/Quotes/QuotesProviderVisitor.h create mode 100644 protocols/Quotes/QuotesProviderVisitorDbSettings.cpp create mode 100644 protocols/Quotes/QuotesProviderVisitorDbSettings.h create mode 100644 protocols/Quotes/QuotesProviderVisitorFormatSpecificator.cpp create mode 100644 protocols/Quotes/QuotesProviderVisitorFormatSpecificator.h create mode 100644 protocols/Quotes/QuotesProviderVisitorFormater.cpp create mode 100644 protocols/Quotes/QuotesProviderVisitorFormater.h create mode 100644 protocols/Quotes/QuotesProviderVisitorTendency.cpp create mode 100644 protocols/Quotes/QuotesProviderVisitorTendency.h create mode 100644 protocols/Quotes/QuotesProviderYahoo.cpp create mode 100644 protocols/Quotes/QuotesProviderYahoo.h create mode 100644 protocols/Quotes/QuotesProviders.cpp create mode 100644 protocols/Quotes/QuotesProviders.h create mode 100644 protocols/Quotes/SettingsDlg.cpp create mode 100644 protocols/Quotes/SettingsDlg.h create mode 100644 protocols/Quotes/Utility/DukasCopy.py create mode 100644 protocols/Quotes/Utility/Dukascopy.xml create mode 100644 protocols/Quotes/Utility/Google.py create mode 100644 protocols/Quotes/Utility/GoogleFinance.xml create mode 100644 protocols/Quotes/Utility/Quotes_Readme.txt create mode 100644 protocols/Quotes/Utility/Yahoo.xml create mode 100644 protocols/Quotes/Utility/google.xml create mode 100644 protocols/Quotes/Version.rc create mode 100644 protocols/Quotes/WinCtrlHelper.cpp create mode 100644 protocols/Quotes/WinCtrlHelper.h create mode 100644 protocols/Quotes/WorkingThread.cpp create mode 100644 protocols/Quotes/WorkingThread.h create mode 100644 protocols/Quotes/XMLEngineMI.cpp create mode 100644 protocols/Quotes/XMLEngineMI.h create mode 100644 protocols/Quotes/dllmain.cpp create mode 100644 protocols/Quotes/proto_Quotes/proto_Quotes.rc create mode 100644 protocols/Quotes/proto_Quotes/proto_Quotes_10.vcxproj create mode 100644 protocols/Quotes/proto_Quotes/proto_Quotes_10.vcxproj.filters create mode 100644 protocols/Quotes/res/CurrencyConverter.ico create mode 100644 protocols/Quotes/res/Export quotes.ico create mode 100644 protocols/Quotes/res/Import quotes.ico create mode 100644 protocols/Quotes/res/Refresh.ico create mode 100644 protocols/Quotes/res/Section.ico create mode 100644 protocols/Quotes/res/down.ico create mode 100644 protocols/Quotes/res/main.ico create mode 100644 protocols/Quotes/res/notchanged.ico create mode 100644 protocols/Quotes/res/proto_na.ico create mode 100644 protocols/Quotes/res/proto_occupied.ico create mode 100644 protocols/Quotes/res/proto_offline.ico create mode 100644 protocols/Quotes/res/proto_online.ico create mode 100644 protocols/Quotes/res/quote.ico create mode 100644 protocols/Quotes/res/swap.ico create mode 100644 protocols/Quotes/res/up.ico create mode 100644 protocols/Quotes/resource.h create mode 100644 protocols/Quotes/stdafx.cpp create mode 100644 protocols/Quotes/stdafx.h create mode 100644 protocols/Quotes/targetver.h create mode 100644 protocols/Quotes/version.h (limited to 'protocols/Quotes') diff --git a/protocols/Quotes/Base64.cpp b/protocols/Quotes/Base64.cpp new file mode 100644 index 0000000000..1854fb42fd --- /dev/null +++ b/protocols/Quotes/Base64.cpp @@ -0,0 +1,43 @@ +#include "StdAfx.h" +#include "Base64.h" + +bool base64::encode(const BYTE* in, size_t inlen,std::vector& out) +{ + int nOutLength = Base64EncodeGetRequiredLength((int)inlen); + out.resize(nOutLength); + char* p = &*out.begin(); + bool bResult = (TRUE == Base64Encode(in,(int)inlen,p,&nOutLength)); + if(false == bResult) + { + out.resize(nOutLength); + p = &*out.begin(); + bResult = (TRUE == Base64Encode(in,(int)inlen,p,&nOutLength)); + } + if(bResult) + { + out.resize(nOutLength); + } + + return bResult; +} + + +bool base64::decode(const char* in, size_t inlen,std::vector& out) +{ + int nOutLength = (int)inlen; + out.resize(nOutLength); + BYTE* p = &*out.begin(); + bool bResult = TRUE == Base64Decode(in,(int)inlen,p,&nOutLength); + if(false == bResult) + { + out.resize(nOutLength); + p = &*out.begin(); + bResult = TRUE == Base64Decode(in,(int)inlen,p,&nOutLength); + } + if(bResult) + { + out.resize(nOutLength); + } + + return true; +} diff --git a/protocols/Quotes/Base64.h b/protocols/Quotes/Base64.h new file mode 100644 index 0000000000..3f911bfeb8 --- /dev/null +++ b/protocols/Quotes/Base64.h @@ -0,0 +1,12 @@ +#ifndef __FBB8ABCA_315E_4ace_B2EB_51E03AD6F8D1_Base64_h__ +#define __FBB8ABCA_315E_4ace_B2EB_51E03AD6F8D1_Base64_h__ + +#pragma once + +namespace base64 +{ + bool encode(const BYTE* in, size_t inlen,std::vector& out); + bool decode(const char* in, size_t inlen,std::vector& out); +} + +#endif //__FBB8ABCA_315E_4ace_B2EB_51E03AD6F8D1_Base64_h__ diff --git a/protocols/Quotes/Chart.h b/protocols/Quotes/Chart.h new file mode 100644 index 0000000000..62a658d818 --- /dev/null +++ b/protocols/Quotes/Chart.h @@ -0,0 +1,280 @@ +#ifndef __FAE7F26E_61ED_4951_BE87_5E022CDF21DF_Chart_h__ +#define __FAE7F26E_61ED_4951_BE87_5E022CDF21DF_Chart_h__ + +#pragma once + +namespace detail +{ + template struct CConverter + { + static double Convert(const T& v) + { + return boost::numeric_cast(v); + } + + static tstring ToString(const T& v) + { + return boost::lexical_cast(v); + } + }; + + template<> struct CConverter + { + static double Convert(double v) + { + return v; + } + + static tstring ToString(double v) + { + tostringstream s; + s.imbue(std::locale("")); + s << std::fixed << v; + return s.str(); + } + }; +} + +template,class TYConverter = detail::CConverter > +class CChart +{ +private: + typedef std::pair TValue; + typedef std::vector TValues; + +public: + CChart() : m_MaxY(),m_MinY() + { + ZeroMemory(&m_rect,sizeof(m_rect)); + } + + ~CChart() + { + } + + void AddValue(const TXValue& x,const TYValue& y) + { + if(m_aValues.empty()) + { + m_MaxY = m_MinY = y; + } + else + { + m_MaxY = __max(y,m_MaxY); + m_MinY = __min(y,m_MinY); + } + m_aValues.push_back(std::make_pair(x,y)); + } + + void SetRect(int x,int y,int cx,int cy) + { + m_rect.left = x; + m_rect.right = x + cx; + m_rect.top = y; + m_rect.bottom = y + cy; + } + + void Draw(HDC hdc)const + { + RECT rc = m_rect; + DrawBackground(hdc,rc); + if(false == m_aValues.empty()) + { + ::InflateRect(&rc,-10,-10); + DrawGrid(hdc,rc); + DrawAxis(hdc,rc); + DrawPoints(hdc,rc); + } + else + { + HFONT hFont = static_cast(::GetStockObject(DEFAULT_GUI_FONT)); + HFONT hOldFont = static_cast(::SelectObject(hdc,hFont)); + + LPCTSTR pszText = TranslateT("There is no to show"); + int nDrawTextResult = ::DrawText(hdc,pszText,::lstrlen(pszText),&rc,DT_SINGLELINE|DT_VCENTER|DT_CENTER); + assert(0 != nDrawTextResult); + + ::SelectObject(hdc,hOldFont); + BOOL bResult = ::DeleteObject(hFont); + assert(TRUE == bResult); + } + } + +private: + void DrawBackground(HDC hdc,RECT& rc)const + { +// HBRUSH hBrush = ::CreateSolidBrush(RGB(255,0,0));//user preferable background color here! +// ::FillRect(hdc,&m_rect,hBrush); +// ::DeleteBrush(hBrush); + } + + void DrawGrid(HDC hdc,RECT& rc)const + { + enum{number_of_lines = 5}; + HPEN hPen = ::CreatePen(PS_SOLID,1,RGB(125,125,125)); + HPEN hPenOld = static_cast(::SelectObject(hdc,hPen)); + HFONT hFont = static_cast(::GetStockObject(DEFAULT_GUI_FONT)); + HFONT hOldFont = static_cast(::SelectObject(hdc,hFont)); + + //vertical grid + int step = (rc.bottom-rc.top)/number_of_lines; + TYValue y_val = m_MinY + ((m_MaxY-m_MinY)/number_of_lines); + int nXIndent = 0; + for(int y = rc.bottom-step;y > rc.top;y-=step,y_val+=((m_MaxY-m_MinY)/number_of_lines)) + { + tstring sY = TYConverter::ToString(y_val); + SIZE sizeText = {0,0}; + BOOL bResult = ::GetTextExtentPoint32(hdc,sY.c_str(), (int)sY.size(), &sizeText); + assert(TRUE == bResult); + nXIndent = __max(nXIndent,sizeText.cx); + } + + y_val = m_MinY + ((m_MaxY-m_MinY)/number_of_lines); + nXIndent += 2; + rc.left += nXIndent; + for(int y = rc.bottom-step;y > rc.top;y-=step,y_val+=((m_MaxY-m_MinY)/number_of_lines)) + { + tstring sY = TYConverter::ToString(y_val); + SIZE sizeText = {0,0}; + BOOL bResult = ::GetTextExtentPoint32(hdc, sY.c_str(), (int)sY.size(), &sizeText); + assert(TRUE == bResult); + + RECT rcText = {rc.left-nXIndent,y-(sizeText.cy/2),rc.left-1,y+(sizeText.cy/2)}; + int nDrawTextResult = ::DrawText(hdc, sY.c_str(), (int)sY.size(), &rcText, DT_SINGLELINE|DT_VCENTER|DT_RIGHT); + assert(0 != nDrawTextResult); + + bResult = ::MoveToEx(hdc,rc.left,y,NULL); + assert(TRUE == bResult); + + bResult = ::LineTo(hdc,rc.right,y); + assert(TRUE == bResult); + } + + // horizontal grid + HRGN rgnAllLables = ::CreateRectRgn(0,0,0,0); + HRGN rgnTemporary = ::CreateRectRgn(0,0,0,0); + bool bFixedRect = false; + step = (rc.right-rc.left)/number_of_lines; + TXValue x_val = m_aValues[0].first + ((m_aValues[m_aValues.size()-1].first-m_aValues[0].first)/number_of_lines); + for(int x = rc.left+step;x < rc.right;x+=step,x_val+=((m_aValues[m_aValues.size()-1].first-m_aValues[0].first)/number_of_lines)) + { + tstring sX = TXConverter::ToString(x_val); + SIZE sizeText = {0,0}; + BOOL bResult = ::GetTextExtentPoint32(hdc, sX.c_str(), (int)sX.size(), &sizeText); + assert(TRUE == bResult); + + if(false == bFixedRect) + { + rc.bottom -= sizeText.cy+2; + bFixedRect = true; + } + + RECT rcText = {x-(sizeText.cx/2),rc.bottom,x+(sizeText.cx/2),rc.bottom+sizeText.cy-1}; + // Draw a label if it doesn't overlap with previous ones + HRGN rgnCurrentLable = ::CreateRectRgnIndirect(&rcText); + if(NULLREGION == ::CombineRgn(rgnTemporary,rgnCurrentLable,rgnAllLables,RGN_AND)) + { + int nDrawTextResult = ::DrawText(hdc, sX.c_str(), (int)sX.size(), &rcText, DT_SINGLELINE|DT_VCENTER|DT_CENTER); + assert(0 != nDrawTextResult); + int nCombineRgnResult = ::CombineRgn(rgnTemporary,rgnCurrentLable,rgnAllLables,RGN_OR); + assert(ERROR != nCombineRgnResult); + nCombineRgnResult = ::CombineRgn(rgnAllLables,rgnTemporary,NULL,RGN_COPY); + assert(ERROR != nCombineRgnResult); + } + bResult = ::DeleteObject(rgnCurrentLable); + assert(TRUE == bResult); + + bResult = ::MoveToEx(hdc,x,rc.bottom,NULL); + assert(TRUE == bResult); + + bResult = ::LineTo(hdc,x,rc.top); + assert(TRUE == bResult); + } + + BOOL bResult = ::DeleteObject(rgnAllLables); + assert(TRUE == bResult); + bResult = ::DeleteObject(rgnTemporary); + assert(TRUE == bResult); + + ::SelectObject(hdc,hOldFont); + ::SelectObject(hdc,hPenOld); + bResult = ::DeleteObject(hFont); + assert(TRUE == bResult); + bResult = ::DeleteObject(hPen); + assert(TRUE == bResult); + } + + void DrawAxis(HDC hdc,RECT& rc)const + { + HPEN hPen = ::CreatePen(PS_SOLID,2,RGB(0,0,0)); + HPEN hPenOld = static_cast(::SelectObject(hdc,hPen)); + + // draw Y-axes + BOOL bResult = ::MoveToEx(hdc,rc.left+1,rc.bottom-1,NULL); + assert(TRUE == bResult); + bResult = ::LineTo(hdc,rc.left+1,rc.top+1); + assert(TRUE == bResult); + + // draw X-axes + bResult = ::MoveToEx(hdc,rc.left+1,rc.bottom-1,NULL); + assert(TRUE == bResult); + bResult = ::LineTo(hdc,rc.right-1,rc.bottom-1); + assert(TRUE == bResult); + + ::SelectObject(hdc,hPenOld); + bResult = ::DeleteObject(hPen); + assert(TRUE == bResult); + } + + void DrawPoints(HDC hdc,RECT& rc)const + { + TXValue xMin(m_aValues[0].first); + double dx = TXConverter::Convert(m_aValues[m_aValues.size()-1].first-xMin); + double dY = TYConverter::Convert(m_MaxY-m_MinY); + + HPEN hPen = ::CreatePen(PS_SOLID,1,RGB(255,0,0)); + HGDIOBJ hPenOld = ::SelectObject(hdc,hPen); + + HBRUSH hBrush = ::CreateSolidBrush(RGB(255,0,0)); + HGDIOBJ hBrushOld = ::SelectObject(hdc,hBrush); + + bool bPrevValid = false; + int xPrex,yPrev; + + BOOST_FOREACH(const TValue& v,m_aValues) + { + double k = TXConverter::Convert(v.first-xMin); + + int x = rc.left+boost::numeric_cast((rc.right-rc.left)*(k/dx)); + k = TYConverter::Convert(v.second-m_MinY); + int y = rc.bottom-boost::numeric_cast((rc.bottom-rc.top)*(k/dY)); + ::Ellipse(hdc,x-5,y-5,x+5,y+5); + if(bPrevValid) + { + BOOL bResult = ::MoveToEx(hdc,xPrex,yPrev,NULL); + assert(TRUE == bResult); + bResult = ::LineTo(hdc,x,y); + assert(TRUE == bResult); + } + + xPrex = x,yPrev = y; + bPrevValid = true; + } + + ::SelectObject(hdc,hPenOld); + BOOL bResult = ::DeleteObject(hPen); + assert(TRUE == bResult); + + ::SelectObject(hdc,hBrushOld); + bResult = ::DeleteObject(hBrush); + assert(TRUE == bResult); + } + +private: + TValues m_aValues; + RECT m_rect; + TYValue m_MaxY; + TYValue m_MinY; +}; + +#endif // __FAE7F26E_61ED_4951_BE87_5E022CDF21DF_Chart_h__ diff --git a/protocols/Quotes/ComHelper.cpp b/protocols/Quotes/ComHelper.cpp new file mode 100644 index 0000000000..e15d05d739 --- /dev/null +++ b/protocols/Quotes/ComHelper.cpp @@ -0,0 +1,39 @@ +#include "StdAfx.h" +#include "ComHelper.h" +#include "Log.h" +#include "WinCtrlHelper.h" + +tstring ComException2Msg(_com_error& e,const tstring& rsAdditionalInfo) +{ + HRESULT hError = e.Error(); + tostringstream o; + if(false == rsAdditionalInfo.empty()) + { + o << rsAdditionalInfo << "\n"; + } + + o << e.ErrorMessage() << _T(" (") << std::hex << hError << _T(")"); + + IErrorInfo* p = e.ErrorInfo(); + CComPtr pErrorInfo(p); + if(NULL != p) + { + p->Release(); + } + + if(pErrorInfo) + { + o << _T("\n") << e.Description(); + } + + return o.str(); +} + +void ShowComError(_com_error& e,const tstring& rsAdditionalInfo) +{ + tstring sErrorMsg = ComException2Msg(e,rsAdditionalInfo); + LogIt(Error,sErrorMsg); + Quotes_MessageBox(NULL,sErrorMsg.c_str(),MB_OK|MB_ICONERROR); +} + + diff --git a/protocols/Quotes/ComHelper.h b/protocols/Quotes/ComHelper.h new file mode 100644 index 0000000000..0b4140d80d --- /dev/null +++ b/protocols/Quotes/ComHelper.h @@ -0,0 +1,9 @@ +#ifndef __37ae28ab_c414_4aba_bbef_d23dd68643a5_ComHelper_h__ +#define __37ae28ab_c414_4aba_bbef_d23dd68643a5_ComHelper_h__ + +#include + +void ShowComError(_com_error& e,const tstring& rsAdditionalInfo); +tstring ComException2Msg(_com_error& e,const tstring& rsAdditionalInfo); + +#endif//__37ae28ab_c414_4aba_bbef_d23dd68643a5_ComHelper_h__ diff --git a/protocols/Quotes/CommonOptionDlg.cpp b/protocols/Quotes/CommonOptionDlg.cpp new file mode 100644 index 0000000000..0b460665c5 --- /dev/null +++ b/protocols/Quotes/CommonOptionDlg.cpp @@ -0,0 +1,272 @@ +#include "StdAfx.h" +#include "CommonOptionDlg.h" +#include "QuotesProviderBase.h" +#include "resource.h" +#include "EconomicRateInfo.h" +#include "DBUtils.h" +#include "QuotesProviderVisitorDbSettings.h" +#include "WinCtrlHelper.h" +#include "SettingsDlg.h" + +namespace +{ + typedef boost::shared_ptr TAdvSettingsPtr; + typedef std::map TAdvSettings; + + TAdvSettings g_aAdvSettings; + + CAdvProviderSettings* get_adv_settings(const IQuotesProvider* pProvider,bool bCreateIfNonExist) + { + TAdvSettings::iterator i = g_aAdvSettings.find(pProvider); + if(i != g_aAdvSettings.end()) + { + return i->second.get(); + } + else if(true == bCreateIfNonExist) + { + TAdvSettingsPtr pAdvSet(new CAdvProviderSettings(pProvider)); + g_aAdvSettings.insert(std::make_pair(pProvider,pAdvSet)); + return pAdvSet.get(); + } + else + { + return NULL; + } + } + + void remove_adv_settings(const IQuotesProvider* pProvider) + { + TAdvSettings::iterator i = g_aAdvSettings.find(pProvider); + if(i != g_aAdvSettings.end()) + { + g_aAdvSettings.erase(i); + } + } +} + +void CommonOptionDlgProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp,CCommonDlgProcData& rData) +{ + switch(msg) + { + case WM_INITDIALOG: + { + assert(rData.m_pQuotesProvider); + + CQuotesProviderVisitorDbSettings visitor; + rData.m_pQuotesProvider->Accept(visitor); + assert(visitor.m_pszDbRefreshRateType); + assert(visitor.m_pszDbRefreshRateValue); + assert(visitor.m_pszDbDisplayNameFormat); + assert(visitor.m_pszDbStatusMsgFormat); + assert(visitor.m_pszDbTendencyFormat); + + // set contact list display format + tstring sDspNameFrmt = Quotes_DBGetStringT(NULL,QUOTES_MODULE_NAME,visitor.m_pszDbDisplayNameFormat,visitor.m_pszDefDisplayFormat); + ::SetDlgItemText(hWnd,IDC_EDIT_CONTACT_LIST_FORMAT,sDspNameFrmt.c_str()); + + // set status message display format + tstring sStatusMsgFrmt = Quotes_DBGetStringT(NULL,QUOTES_MODULE_NAME,visitor.m_pszDbStatusMsgFormat,visitor.m_pszDefStatusMsgFormat); + ::SetDlgItemText(hWnd,IDC_EDIT_STATUS_MESSAGE_FORMAT,sStatusMsgFrmt.c_str()); + + // set tendency format + tstring sTendencyFrmt = Quotes_DBGetStringT(NULL,QUOTES_MODULE_NAME,visitor.m_pszDbTendencyFormat,visitor.m_pszDefTendencyFormat); + ::SetDlgItemText(hWnd,IDC_EDIT_TENDENCY_FORMAT,sTendencyFrmt.c_str()); + + // refresh rate + HWND hwndCombo = ::GetDlgItem(hWnd,IDC_COMBO_REFRESH_RATE); + LPCTSTR pszRefreshRateTypes[] = {TranslateT("Seconds"),TranslateT("Minutes"),TranslateT("Hours")}; + for(int i = 0;i < SIZEOF(pszRefreshRateTypes);++i) + { + ::SendMessage(hwndCombo,CB_ADDSTRING,0,reinterpret_cast(pszRefreshRateTypes[i])); + } + + int nRefreshRateType = DBGetContactSettingWord(NULL,QUOTES_MODULE_NAME,visitor.m_pszDbRefreshRateType,RRT_MINUTES); + if(nRefreshRateType < RRT_SECONDS || nRefreshRateType > RRT_HOURS) + { + nRefreshRateType = RRT_MINUTES; + } + + UINT nRate = DBGetContactSettingWord(NULL,QUOTES_MODULE_NAME,visitor.m_pszDbRefreshRateValue,1); + switch(nRefreshRateType) + { + default: + case RRT_SECONDS: + case RRT_MINUTES: + if(nRate < 1 || nRate > 60) + { + nRate = 1; + } + spin_set_range(::GetDlgItem(hWnd,IDC_SPIN_REFRESH_RATE),1,60); + break; + case RRT_HOURS: + if(nRate < 1 || nRate > 24) + { + nRate = 1; + } + spin_set_range(::GetDlgItem(hWnd,IDC_SPIN_REFRESH_RATE),1,24); + break; + } + + ::SendMessage(hwndCombo,CB_SETCURSEL,nRefreshRateType,0); + ::SetDlgItemInt(hWnd,IDC_EDIT_REFRESH_RATE,nRate,FALSE); + + PropSheet_UnChanged(::GetParent(hWnd),hWnd); + } + break; + case WM_COMMAND: + switch(HIWORD(wp)) + { + case CBN_SELCHANGE: + if(IDC_COMBO_REFRESH_RATE == LOWORD(wp)) + { + ERefreshRateType nType = static_cast(::SendMessage(reinterpret_cast(lp),CB_GETCURSEL,0,0)); + switch(nType) + { + default: + case RRT_SECONDS: + case RRT_MINUTES: + spin_set_range(::GetDlgItem(hWnd,IDC_SPIN_REFRESH_RATE),1,60); + break; + case RRT_HOURS: + { + spin_set_range(::GetDlgItem(hWnd,IDC_SPIN_REFRESH_RATE),1,24); + BOOL bOk = FALSE; + UINT nRefreshRate = ::GetDlgItemInt(hWnd,IDC_EDIT_REFRESH_RATE,&bOk,FALSE); + if(TRUE == bOk && nRefreshRate > 24) + { + ::SetDlgItemInt(hWnd,IDC_EDIT_REFRESH_RATE,24,FALSE); + } + } + break; + } + + PropSheet_Changed(::GetParent(hWnd),hWnd); + } + break; + case EN_CHANGE: + switch(LOWORD(wp)) + { + case IDC_EDIT_REFRESH_RATE: + case IDC_EDIT_CONTACT_LIST_FORMAT: + case IDC_EDIT_STATUS_MESSAGE_FORMAT: + case IDC_EDIT_TENDENCY_FORMAT: + if(reinterpret_cast(lp) == ::GetFocus()) + { + PropSheet_Changed(::GetParent(hWnd),hWnd); + } + break; + } + break; + case BN_CLICKED: + switch( LOWORD(wp)) + { + case IDC_BUTTON_DESCRIPTION: + show_variable_list(hWnd,rData.m_pQuotesProvider); + break; + case IDC_BUTTON_ADVANCED_SETTINGS: + { + CAdvProviderSettings* pAdvSet = get_adv_settings(rData.m_pQuotesProvider,true); + assert(pAdvSet); + if(true == ShowSettingsDlg(hWnd,pAdvSet)) + { + PropSheet_Changed(::GetParent(hWnd),hWnd); + } + } + break; + } + break; + } + break; + case WM_NOTIFY: + { + LPNMHDR pNMHDR = reinterpret_cast(lp); + switch(pNMHDR->code) + { + case PSN_KILLACTIVE: + { + BOOL bOk = FALSE; + UINT nRefreshRate = ::GetDlgItemInt(hWnd,IDC_EDIT_REFRESH_RATE,&bOk,FALSE); + ERefreshRateType nType = static_cast(::SendMessage(::GetDlgItem(hWnd,IDC_COMBO_REFRESH_RATE),CB_GETCURSEL,0,0)); + switch(nType) + { + default: + case RRT_MINUTES: + case RRT_SECONDS: + if(FALSE == bOk || nRefreshRate < 1 || nRefreshRate > 60) + { + prepare_edit_ctrl_for_error(::GetDlgItem(hWnd,IDC_EDIT_REFRESH_RATE)); + Quotes_MessageBox(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(hWnd,IDC_EDIT_REFRESH_RATE)); + Quotes_MessageBox(hWnd,TranslateT("Enter integer value between 1 and 24."),MB_OK|MB_ICONERROR); + bOk = FALSE; + } + break; + } + + if(TRUE == bOk) + { + HWND hEdit = ::GetDlgItem(hWnd,IDC_EDIT_CONTACT_LIST_FORMAT); + assert(IsWindow(hEdit)); + + tstring s = get_window_text(hEdit); + if(true == s.empty()) + { + prepare_edit_ctrl_for_error(hEdit); + Quotes_MessageBox(hWnd,TranslateT("Enter text to display in contact list."),MB_OK|MB_ICONERROR); + bOk = FALSE; + } + } + + ::SetWindowLongPtr(hWnd,DWLP_MSGRESULT,(TRUE == bOk) ? FALSE : TRUE); + } + break; + case PSN_APPLY: + { + BOOL bOk = FALSE; + UINT nRefreshRate = ::GetDlgItemInt(hWnd,IDC_EDIT_REFRESH_RATE,&bOk,FALSE); + assert(TRUE == bOk); + ERefreshRateType nType = static_cast(::SendMessage(::GetDlgItem(hWnd,IDC_COMBO_REFRESH_RATE),CB_GETCURSEL,0,0)); + + assert(rData.m_pQuotesProvider); + + CQuotesProviderVisitorDbSettings visitor; + rData.m_pQuotesProvider->Accept(visitor); + assert(visitor.m_pszDbRefreshRateType); + assert(visitor.m_pszDbRefreshRateValue); + assert(visitor.m_pszDbDisplayNameFormat); + assert(visitor.m_pszDbStatusMsgFormat); + + rData.m_bFireSetingsChangedEvent = true; + DBWriteContactSettingWord(NULL,QUOTES_MODULE_NAME,visitor.m_pszDbRefreshRateType,nType); + DBWriteContactSettingWord(NULL,QUOTES_MODULE_NAME,visitor.m_pszDbRefreshRateValue,nRefreshRate); + + tstring s = get_window_text(::GetDlgItem(hWnd,IDC_EDIT_CONTACT_LIST_FORMAT)); + DBWriteContactSettingTString(NULL,QUOTES_MODULE_NAME,visitor.m_pszDbDisplayNameFormat,s.c_str()); + + s = get_window_text(::GetDlgItem(hWnd,IDC_EDIT_STATUS_MESSAGE_FORMAT)); + DBWriteContactSettingTString(NULL,QUOTES_MODULE_NAME,visitor.m_pszDbStatusMsgFormat,s.c_str()); + + s = get_window_text(::GetDlgItem(hWnd,IDC_EDIT_TENDENCY_FORMAT)); + DBWriteContactSettingTString(NULL,QUOTES_MODULE_NAME,visitor.m_pszDbTendencyFormat,s.c_str()); + + CAdvProviderSettings* pAdvSet = get_adv_settings(rData.m_pQuotesProvider,false); + if(pAdvSet) + { + pAdvSet->SaveToDb(); + } + } + break; + } + } + break; + case WM_DESTROY: + remove_adv_settings(rData.m_pQuotesProvider); + break; + } +} \ No newline at end of file diff --git a/protocols/Quotes/CommonOptionDlg.h b/protocols/Quotes/CommonOptionDlg.h new file mode 100644 index 0000000000..b9f696362a --- /dev/null +++ b/protocols/Quotes/CommonOptionDlg.h @@ -0,0 +1,17 @@ +#ifndef __c85fe710_f71b_4a58_9d44_3e39f6209c5f_CommonOptionDlg_h__ +#define __c85fe710_f71b_4a58_9d44_3e39f6209c5f_CommonOptionDlg_h__ + +class CQuotesProviderBase; + +struct CCommonDlgProcData +{ + CCommonDlgProcData(const CQuotesProviderBase* pQuotesProvider) + : m_pQuotesProvider(pQuotesProvider),m_bFireSetingsChangedEvent(false){} + + const CQuotesProviderBase* m_pQuotesProvider; + bool m_bFireSetingsChangedEvent; +}; + +void CommonOptionDlgProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp,CCommonDlgProcData& rData); + +#endif//__c85fe710_f71b_4a58_9d44_3e39f6209c5f_CommonOptionDlg_h__ diff --git a/protocols/Quotes/CreateFilePath.cpp b/protocols/Quotes/CreateFilePath.cpp new file mode 100644 index 0000000000..f1a3e4f331 --- /dev/null +++ b/protocols/Quotes/CreateFilePath.cpp @@ -0,0 +1,45 @@ +#include "StdAfx.h" +#include "CreateFilePath.h" + +#include +#include "ModuleInfo.h" + +namespace +{ + TCHAR replace_invalid_symbol(TCHAR chr) + { + TCHAR InvaliSymbols[] = {_T('\\'),_T('/'),_T(':'),_T('*'),_T('?'),_T('"'),_T('<'),_T('>'),_T('|')}; + for(int i = 0; i < sizeof(InvaliSymbols)/sizeof(InvaliSymbols[0]);++i) + { + if(chr == InvaliSymbols[i]) + { + return _T('_'); + } + } + + return chr; + } + + void prepare_name(tstring& rsName) + { + std::transform(rsName.begin(),rsName.end(),rsName.begin(),boost::bind(replace_invalid_symbol,_1)); + } +} + +tstring CreateFilePath(const tstring& rsName) +{ + TCHAR szPath[_MAX_PATH]; + ::GetModuleFileName(CModuleInfo::GetModuleHandle(),szPath,_MAX_PATH); + + TCHAR* p = _tcsrchr(szPath,_T('\\')); + if(p) + { + *p = 0; + } + + tstring s(rsName); + prepare_name(s); + tostringstream o; + o << szPath << _T("\\Quotes\\") << s; + return o.str(); +} \ No newline at end of file diff --git a/protocols/Quotes/CreateFilePath.h b/protocols/Quotes/CreateFilePath.h new file mode 100644 index 0000000000..f097e59a52 --- /dev/null +++ b/protocols/Quotes/CreateFilePath.h @@ -0,0 +1,8 @@ +#ifndef _aaf3bee6_cee7_4023_8848_5911ad7a9660_CreateFilePath_h__ +#define _aaf3bee6_cee7_4023_8848_5911ad7a9660_CreateFilePath_h__ + +#include + +tstring CreateFilePath(const tstring& rsName); + +#endif //_aaf3bee6_cee7_4023_8848_5911ad7a9660_CreateFilePath_h__ diff --git a/protocols/Quotes/CurrencyConverter.cpp b/protocols/Quotes/CurrencyConverter.cpp new file mode 100644 index 0000000000..0e04d2562e --- /dev/null +++ b/protocols/Quotes/CurrencyConverter.cpp @@ -0,0 +1,309 @@ +#include "StdAfx.h" +#include "CurrencyConverter.h" +#include "ModuleInfo.h" +#include "resource.h" + +#include "QuotesProviderGoogle.h" +#include "QuotesProviders.h" +#include "WinCtrlHelper.h" +#include "EconomicRateInfo.h" +#include "Locale.h" +#include "DBUtils.h" +#include "IconLib.h" + +#define WINDOW_PREFIX "CurrenyConverter_" + +#define DB_STR_CC_QUOTE_FROM_ID "CurrencyConverter_FromID" +#define DB_STR_CC_QUOTE_TO_ID "CurrencyConverter_ToID" +#define DB_STR_CC_AMOUNT "CurrencyConverter_Amount" + +namespace +{ + CQuotesProviderGoogle* get_google_provider() + { + CModuleInfo::TQuotesProvidersPtr& pProviders = CModuleInfo::GetQuoteProvidersPtr(); + const CQuotesProviders::TQuotesProviders& rapQuotesProviders = pProviders->GetProviders(); + for(CQuotesProviders::TQuotesProviders::const_iterator i = rapQuotesProviders.begin();i != rapQuotesProviders.end();++i) + { + const CQuotesProviders::TQuotesProviderPtr& pProvider = *i; + CQuotesProviderGoogle* pGoogle = dynamic_cast(pProvider.get()); + if(pGoogle) + { + return pGoogle; + } + } + + assert(!"We should never get here!"); + return NULL; + } + + + CQuotesProviderGoogle::CQuoteSection get_quotes(const CQuotesProviderGoogle* pProvider = NULL) + { + if(NULL == pProvider) + { + pProvider = get_google_provider(); + } + + if(pProvider) + { + const CQuotesProviderGoogle::CQuoteSection& rQuotes = pProvider->GetQuotes(); + if(rQuotes.GetSectionCount() > 0) + { + return rQuotes.GetSection(0); + } + } + + return CQuotesProviderGoogle::CQuoteSection(); + } + + inline tstring make_quote_name(const CQuotesProviderGoogle::CQuote& rQuote) + { + const tstring& rsDesc = rQuote.GetName(); + return((false == rsDesc.empty()) ? rsDesc : rQuote.GetSymbol()); + } + + inline void update_convert_button(HWND hDlg) + { + int nFrom = static_cast(::SendMessage(::GetDlgItem(hDlg,IDC_COMBO_CONVERT_FROM),CB_GETCURSEL,0,0)); + int nTo = static_cast(::SendMessage(::GetDlgItem(hDlg,IDC_COMBO_CONVERT_INTO),CB_GETCURSEL,0,0)); + bool bEnableButton = ((CB_ERR != nFrom) + && (CB_ERR != nTo) + && (nFrom != nTo) + && (GetWindowTextLength(GetDlgItem(hDlg,IDC_EDIT_VALUE)) > 0)); + EnableWindow(GetDlgItem(hDlg,IDC_BUTTON_CONVERT),bEnableButton); + } + + inline void update_swap_button(HWND hDlg) + { + int nFrom = static_cast(::SendMessage(::GetDlgItem(hDlg,IDC_COMBO_CONVERT_FROM),CB_GETCURSEL,0,0)); + int nTo = static_cast(::SendMessage(::GetDlgItem(hDlg,IDC_COMBO_CONVERT_INTO),CB_GETCURSEL,0,0)); + bool bEnableButton = ((CB_ERR != nFrom) + && (CB_ERR != nTo) + && (nFrom != nTo)); + EnableWindow(GetDlgItem(hDlg,IDC_BUTTON_SWAP),bEnableButton); + } + + inline tstring double2str(double dValue) + { + tostringstream output; + output.imbue(GetSystemLocale()); + output << std::fixed << std::setprecision(2) << dValue; + return output.str(); + } + + inline bool str2double(const tstring& s,double& d) + { + tistringstream input(s); + input.imbue(GetSystemLocale()); + input >> d; + return ((false == input.bad()) && (false == input.fail())); + } + + + INT_PTR CALLBACK CurrencyConverterDlgProc(HWND hDlg,UINT msg,WPARAM wp,LPARAM lp) + { + switch(msg) + { + case WM_INITDIALOG: + { + HANDLE hWL = CModuleInfo::GetInstance().GetWindowList(WINDOW_PREFIX,false); + assert(hWL); + WindowList_Add(hWL,hDlg,NULL); + + TranslateDialogDefault(hDlg); + + ::SendMessage(hDlg,WM_SETICON,FALSE,reinterpret_cast(Quotes_LoadIconEx(ICON_STR_CURRENCY_CONVERTER))); + ::SendMessage(hDlg,WM_SETICON,TRUE,reinterpret_cast(Quotes_LoadIconEx(ICON_STR_CURRENCY_CONVERTER,true))); + + HWND hcbxFrom = ::GetDlgItem(hDlg,IDC_COMBO_CONVERT_FROM); + HWND hcbxTo = ::GetDlgItem(hDlg,IDC_COMBO_CONVERT_INTO); + + tstring sFromQuoteID = Quotes_DBGetStringT(NULL,QUOTES_MODULE_NAME,DB_STR_CC_QUOTE_FROM_ID); + tstring sToQuoteID = Quotes_DBGetStringT(NULL,QUOTES_MODULE_NAME,DB_STR_CC_QUOTE_TO_ID); + + const CQuotesProviderGoogle* pProvider = get_google_provider(); + const CQuotesProviderGoogle::CQuoteSection& rSection = get_quotes(pProvider); + size_t cQuotes = rSection.GetQuoteCount(); + for(size_t i = 0;i < cQuotes;++i) + { + const CQuotesProviderGoogle::CQuote& rQuote = rSection.GetQuote(i); + tstring sName = make_quote_name(rQuote); + LPCTSTR pszName = sName.c_str(); + LRESULT nFrom = ::SendMessage(hcbxFrom,CB_ADDSTRING,0,reinterpret_cast(pszName)); + LRESULT nTo = ::SendMessage(hcbxTo,CB_ADDSTRING,0,reinterpret_cast(pszName)); + + if(0 == quotes_stricmp(rQuote.GetID().c_str(),sFromQuoteID.c_str())) + { + ::SendMessage(hcbxFrom,CB_SETCURSEL,nFrom,0); + } + + if(0 == quotes_stricmp(rQuote.GetID().c_str(),sToQuoteID.c_str())) + { + ::SendMessage(hcbxTo,CB_SETCURSEL,nTo,0); + } + } + + double dAmount = 1.0; + Quotes_DBReadDouble(NULL,QUOTES_MODULE_NAME,DB_STR_CC_AMOUNT,dAmount); + ::SetDlgItemText(hDlg,IDC_EDIT_VALUE,double2str(dAmount).c_str()); + + const IQuotesProvider::CProviderInfo& pi = pProvider->GetInfo(); + tostringstream o; + o << TranslateT("Info provided by") << _T(" ") << pi.m_sName << _T(""); + + ::SetDlgItemText(hDlg,IDC_SYSLINK_PROVIDER,o.str().c_str()); + + ::SendMessage(::GetDlgItem(hDlg,IDC_BUTTON_SWAP),BM_SETIMAGE,IMAGE_ICON, + reinterpret_cast(Quotes_LoadIconEx(ICON_STR_SWAP))); + + update_convert_button(hDlg); + update_swap_button(hDlg); + + Utils_RestoreWindowPositionNoSize(hDlg,NULL,QUOTES_PROTOCOL_NAME,WINDOW_PREFIX); + ::ShowWindow(hDlg,SW_SHOW); + } + return (TRUE); + case WM_CLOSE: + { + HANDLE hWL = CModuleInfo::GetInstance().GetWindowList(WINDOW_PREFIX,false); + assert(hWL); + WindowList_Remove(hWL,hDlg); + Utils_SaveWindowPosition(hDlg,NULL,QUOTES_PROTOCOL_NAME,WINDOW_PREFIX); + EndDialog(hDlg,0); + } + return (TRUE); + case WM_COMMAND: + switch(LOWORD(wp)) + { + case IDC_COMBO_CONVERT_FROM: + case IDC_COMBO_CONVERT_INTO: + if(CBN_SELCHANGE == HIWORD(wp)) + { + update_convert_button(hDlg); + update_swap_button(hDlg); + } + return TRUE; + case IDC_EDIT_VALUE: + if(EN_CHANGE == HIWORD(wp)) + { + update_convert_button(hDlg); + } + return TRUE; + case IDCANCEL: + { + SendMessage(hDlg, WM_CLOSE, 0, 0); + } + return (TRUE); + case IDC_BUTTON_SWAP: + { + HWND wndFrom = ::GetDlgItem(hDlg,IDC_COMBO_CONVERT_FROM); + HWND wndTo = ::GetDlgItem(hDlg,IDC_COMBO_CONVERT_INTO); + WPARAM nFrom = ::SendMessage(wndFrom,CB_GETCURSEL,0,0); + WPARAM nTo = ::SendMessage(wndTo,CB_GETCURSEL,0,0); + + ::SendMessage(wndFrom,CB_SETCURSEL,nTo,0); + ::SendMessage(wndTo,CB_SETCURSEL,nFrom,0); + } + return (TRUE); + case IDC_BUTTON_CONVERT: + { + HWND hwndAmount = GetDlgItem(hDlg,IDC_EDIT_VALUE); + tstring sText = get_window_text(hwndAmount); + + double dAmount = 1.0; + if ((true == str2double(sText,dAmount)) && (dAmount > 0.0)) + { + Quotes_DBWriteDouble(NULL,QUOTES_MODULE_NAME,DB_STR_CC_AMOUNT,dAmount); + + size_t nFrom = static_cast(::SendMessage(::GetDlgItem(hDlg,IDC_COMBO_CONVERT_FROM),CB_GETCURSEL,0,0)); + size_t nTo = static_cast(::SendMessage(::GetDlgItem(hDlg,IDC_COMBO_CONVERT_INTO),CB_GETCURSEL,0,0)); + if ((CB_ERR != nFrom) && (CB_ERR != nTo) && (nFrom != nTo)) + { + const CQuotesProviderGoogle::CQuoteSection& rSection = get_quotes(); + size_t cQuotes = rSection.GetQuoteCount(); + if ((nFrom < cQuotes) && (nTo < cQuotes)) + { + CQuotesProviderGoogle::CRateInfo ri; + CQuotesProviderGoogle::CQuote from = rSection.GetQuote(nFrom); + CQuotesProviderGoogle::CQuote to = rSection.GetQuote(nTo); + + DBWriteContactSettingTString(NULL,QUOTES_MODULE_NAME,DB_STR_CC_QUOTE_FROM_ID,from.GetID().c_str()); + DBWriteContactSettingTString(NULL,QUOTES_MODULE_NAME,DB_STR_CC_QUOTE_TO_ID,to.GetID().c_str()); + + const CQuotesProviderGoogle* pProvider = get_google_provider(); + assert(pProvider); + if(pProvider) + { + tstring sResult; + std::string sError; + try + { + double dResult = pProvider->Convert(dAmount,from,to); + tostringstream ss; + ss.imbue(GetSystemLocale()); + ss << std::fixed << std::setprecision(2) << dAmount << " " << from.GetName() << " = " << dResult << " " << to.GetName(); + sResult = ss.str(); + } + catch(std::exception& e) + { + sError = e.what(); + //Quotes_MessageBox(hDlg,sResult.c_str()); + } + + if(false == sError.empty()) + { + //USES_CONVERSION; + sResult = quotes_a2t(sError.c_str());//A2T(sError.c_str()); + } + + SetDlgItemText(hDlg,IDC_EDIT_RESULT,sResult.c_str()); + } + } + } + } + else + { + Quotes_MessageBox(hDlg,TranslateT("Enter positive number."),MB_OK|MB_ICONERROR); + prepare_edit_ctrl_for_error(GetDlgItem(hDlg,IDC_EDIT_VALUE)); + } + } + return (TRUE); + } + return (FALSE); + case WM_NOTIFY: + { + LPNMHDR pNMHDR = reinterpret_cast(lp); + switch(pNMHDR->code) + { + case NM_CLICK: + if(IDC_SYSLINK_PROVIDER == wp) + { + PNMLINK pNMLink = reinterpret_cast(pNMHDR); + ::ShellExecute(hDlg,_T("open"),pNMLink->item.szUrl,NULL,NULL,SW_SHOWNORMAL); + } + break; + } + } + break; + } + return (FALSE); + } +} + +INT_PTR QuotesMenu_CurrencyConverter(WPARAM wp,LPARAM lp) +{ + HANDLE hWL = CModuleInfo::GetInstance().GetWindowList(WINDOW_PREFIX,true); + HWND hWnd = WindowList_Find(hWL,NULL); + if(NULL != hWnd) + { + SetForegroundWindow(hWnd); + SetFocus(hWnd); + } + else + { + CreateDialogParam(CModuleInfo::GetModuleHandle(), MAKEINTRESOURCE(IDD_CURRENCY_CONVERTER), NULL, CurrencyConverterDlgProc, 0); + } + + return 0; +} diff --git a/protocols/Quotes/CurrencyConverter.h b/protocols/Quotes/CurrencyConverter.h new file mode 100644 index 0000000000..9af7c6bca1 --- /dev/null +++ b/protocols/Quotes/CurrencyConverter.h @@ -0,0 +1,6 @@ +#ifndef __4FB6320B_2D02_408b_BAF5_426C185AAA11_CurrencyConverter_h__ +#define __4FB6320B_2D02_408b_BAF5_426C185AAA11_CurrencyConverter_h__ + +INT_PTR QuotesMenu_CurrencyConverter(WPARAM wp,LPARAM lp); + +#endif //__4FB6320B_2D02_408b_BAF5_426C185AAA11_CurrencyConverter_h__ diff --git a/protocols/Quotes/DBUtils.cpp b/protocols/Quotes/DBUtils.cpp new file mode 100644 index 0000000000..11c0fb3d0d --- /dev/null +++ b/protocols/Quotes/DBUtils.cpp @@ -0,0 +1,70 @@ +#include "StdAfx.h" +#include "DBUtils.h" + +std::string Quotes_DBGetStringA(HANDLE hContact,const char* szModule,const char* szSetting,const char* pszDefValue /*= NULL*/) +{ + std::string sResult; + char* pszSymbol = DBGetString(hContact,szModule,szSetting); + if(NULL != pszSymbol) + { + sResult = pszSymbol; + mir_free(pszSymbol); + } + else if(NULL != pszDefValue) + { + sResult = pszDefValue; + } + + return sResult; +} + +std::wstring Quotes_DBGetStringW(HANDLE hContact,const char* szModule,const char* szSetting,const wchar_t* pszDefValue/* = NULL*/) +{ + std::wstring sResult; + wchar_t* pszSymbol = DBGetStringW(hContact,szModule,szSetting); + if(NULL != pszSymbol) + { + sResult = pszSymbol; + mir_free(pszSymbol); + } + else if(NULL != pszDefValue) + { + sResult = pszDefValue; + } + + return sResult; +} + +bool Quotes_DBWriteDouble(HANDLE hContact,const char* szModule,const char* szSetting,double dValue) +{ + DBCONTACTWRITESETTING cws = {0}; + + cws.szModule = szModule; + cws.szSetting = szSetting; + cws.value.type = DBVT_BLOB; + cws.value.cpbVal = sizeof(dValue); + cws.value.pbVal = reinterpret_cast(&dValue); + return 0 == CallService(MS_DB_CONTACT_WRITESETTING,reinterpret_cast(hContact),reinterpret_cast(&cws)); +} + +bool Quotes_DBReadDouble(HANDLE hContact,const char* szModule,const char* szSetting,double& rdValue) +{ + DBVARIANT dbv = {0}; + DBCONTACTGETSETTING cgs; + cgs.szModule=szModule; + cgs.szSetting=szSetting; + cgs.pValue = &dbv; + dbv.type = DBVT_BLOB; + + bool bResult = ((0 == CallService(MS_DB_CONTACT_GETSETTING,(WPARAM)hContact,(LPARAM)&cgs)) + && (DBVT_BLOB == dbv.type)); + + if(bResult) + { + rdValue = *reinterpret_cast(dbv.pbVal); + } + + DBFreeVariant(&dbv); + return bResult; +} + diff --git a/protocols/Quotes/DBUtils.h b/protocols/Quotes/DBUtils.h new file mode 100644 index 0000000000..d154e99075 --- /dev/null +++ b/protocols/Quotes/DBUtils.h @@ -0,0 +1,16 @@ +#ifndef __54294385_3fdd_4f0c_98c3_c583a96e7fb4_DBUtils_h__ +#define __54294385_3fdd_4f0c_98c3_c583a96e7fb4_DBUtils_h__ + +std::string Quotes_DBGetStringA(HANDLE hContact,const char* szModule,const char* szSetting,const char* pszDefValue = NULL); +std::wstring Quotes_DBGetStringW(HANDLE hContact,const char* szModule,const char* szSetting,const wchar_t* pszDefValue = NULL); + +#ifdef _UNICODE +#define Quotes_DBGetStringT Quotes_DBGetStringW +#else +#define Quotes_DBGetStringT Quotes_DBGetStringA +#endif + +bool Quotes_DBWriteDouble(HANDLE hContact,const char* szModule,const char* szSetting,double dValue); +bool Quotes_DBReadDouble(HANDLE hContact,const char* szModule,const char* szSetting,double& rdValue); + +#endif //__54294385_3fdd_4f0c_98c3_c583a96e7fb4_DBUtils_h__ diff --git a/protocols/Quotes/EconomicRateInfo.h b/protocols/Quotes/EconomicRateInfo.h new file mode 100644 index 0000000000..73e269619c --- /dev/null +++ b/protocols/Quotes/EconomicRateInfo.h @@ -0,0 +1,59 @@ +#ifndef __87d726e0_26c6_485d_8016_1fba819b037d_EconomicRateInfo__ +#define __87d726e0_26c6_485d_8016_1fba819b037d_EconomicRateInfo__ + +#define QUOTES_PROTOCOL_NAME "Quotes"// protocol name + +#define QUOTES_MODULE_NAME QUOTES_PROTOCOL_NAME // db settings module path + +enum ERefreshRateType +{ + RRT_SECONDS = 0, + RRT_MINUTES = 1, + RRT_HOURS = 2 +}; + +#define DB_STR_ENABLE_LOG "EnableLog" +#define DB_STR_QUOTE_PROVIDER "QuoteProvider" +#define DB_STR_QUOTE_ID "QuoteID" +#define DB_STR_QUOTE_SYMBOL "QuoteSymbol" +#define DB_STR_QUOTE_DESCRIPTION "QuoteDescription" +#define DB_STR_QUOTE_PREV_VALUE "PreviousQuoteValue" +#define DB_STR_QUOTE_CURR_VALUE "CurrentQuoteValue" +#define DB_STR_QUOTE_FETCH_TIME "FetchTime" + + +enum ELogMode +{ + lmDisabled = 0x0000, + lmInternalHistory = 0x0001, + lmExternalFile = 0x0002, + lmPopup = 0x0004, +}; + +#define DB_STR_CONTACT_SPEC_SETTINGS "ContactSpecSettings" +#define DB_STR_QUOTE_LOG "Log" +#define DB_STR_QUOTE_LOG_FILE "LogFile" +#define DB_STR_QUOTE_FORMAT_LOG_FILE "LogFileFormat" +#define DB_STR_QUOTE_FORMAT_HISTORY "HistoryFormat" +#define DB_STR_QUOTE_LOG_FILE_CONDITION "AddToLogOnlyIfValueIsChanged" +#define DB_STR_QUOTE_HISTORY_CONDITION "AddToHistoryOnlyIfValueIsChanged" +#define DB_STR_QUOTE_EXTRA_IMAGE_SLOT "ExtraImageSlot" +#define DB_STR_QUOTE_FORMAT_POPUP "PopupFormat" +#define DB_STR_QUOTE_POPUP_CONDITION "ShowPopupOnlyIfValueIsChanged" + +#define DB_STR_QUOTE_POPUP_COLOUR_MODE "PopupColourMode" +#define DB_STR_QUOTE_POPUP_COLOUR_BK "PopupColourBk" +#define DB_STR_QUOTE_POPUP_COLOUR_TEXT "PopupColourText" +#define DB_STR_QUOTE_POPUP_DELAY_MODE "PopupDelayMode" +#define DB_STR_QUOTE_POPUP_DELAY_TIMEOUT "PopupDelayTimeout" +#define DB_STR_QUOTE_POPUP_HISTORY_FLAG "PopupHistoryFlag" + + +// #define DB_STR_NICK "Nick" +#define DB_STR_STATUS "Status" + +#define LIST_MODULE_NAME "CList" +#define CONTACT_LIST_NAME "MyHandle" +#define STATUS_MSG_NAME "StatusMsg" + +#endif //__87d726e0_26c6_485d_8016_1fba819b037d_EconomicRateInfo__ diff --git a/protocols/Quotes/ExtraImages.cpp b/protocols/Quotes/ExtraImages.cpp new file mode 100644 index 0000000000..35a59a8c1d --- /dev/null +++ b/protocols/Quotes/ExtraImages.cpp @@ -0,0 +1,143 @@ +#include "StdAfx.h" +#include "ExtraImages.h" +#include "IconLib.h" +#include "EconomicRateInfo.h" +#include "ModuleInfo.h" +#include "QuotesProviders.h" +#include "IQuotesProvider.h" +#include "Log.h" +#include "DBUtils.h" + +namespace +{ + inline HANDLE extra_add_icon(const char* psz) + { + return reinterpret_cast( + CallService(MS_CLIST_EXTRA_ADD_ICON,reinterpret_cast(Quotes_LoadIconEx(psz)),0)); + } + + const HANDLE INVALID_IMAGE_HANDLE = reinterpret_cast(-1); +} + +CExtraImages::CExtraImages() + : m_hExtraIcons(ExtraIcon_Register(ICON_STR_QUOTE,QUOTES_PROTOCOL_NAME,Quotes_MakeIconName(ICON_STR_MAIN).c_str())), + m_bExtraImagesInit(false), + m_nSlot(DBGetContactSettingWord(NULL,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_EXTRA_IMAGE_SLOT,EXTRA_ICON_ADV1)) +{ + m_ahExtraImages[eiUp] = INVALID_IMAGE_HANDLE; + m_ahExtraImages[eiDown] = INVALID_IMAGE_HANDLE; + m_ahExtraImages[eiNotChanged] = INVALID_IMAGE_HANDLE; +} + +CExtraImages::~CExtraImages() +{ +} + +CExtraImages& CExtraImages::GetInstance() +{ + static CExtraImages s_ei; + return s_ei; +} + +void CExtraImages::RebuildExtraImages() +{ + if(NULL == m_hExtraIcons) + { + m_bExtraImagesInit = false; + CGuard cs(m_lmExtraImages); + m_ahExtraImages[eiUp] = extra_add_icon(ICON_STR_QUOTE_UP); + m_ahExtraImages[eiDown] = extra_add_icon(ICON_STR_QUOTE_DOWN); + m_ahExtraImages[eiNotChanged] = extra_add_icon(ICON_STR_QUOTE_NOT_CHANGED); + m_bExtraImagesInit = true; + } +} + + +bool CExtraImages::SetContactExtraImage(HANDLE hContact,EImageIndex nIndex)const +{ +// tstring s = Quotes_DBGetStringT(hContact,LIST_MODULE_NAME,CONTACT_LIST_NAME); +// tostringstream o; +// o << _T("SetContactExtraImage for ") << s << _T("\nExtra image list init: ") << m_bExtraImagesInit << _T("\n"); + + bool bResult = false; + if(m_hExtraIcons) + { +// o << "Using extra icon interface\n"; + std::string sIconName; + switch(nIndex) + { + case eiUp: + sIconName = Quotes_MakeIconName(ICON_STR_QUOTE_UP); + break; + case eiDown: + sIconName = Quotes_MakeIconName(ICON_STR_QUOTE_DOWN); + break; + case eiNotChanged: + sIconName = Quotes_MakeIconName(ICON_STR_QUOTE_NOT_CHANGED); + break; + } + bResult = (0 == ExtraIcon_SetIcon(m_hExtraIcons,hContact,sIconName.c_str())); + } + else if(m_bExtraImagesInit && ServiceExists(MS_CLIST_EXTRA_ADD_ICON)) + { +// o << "Using contact list interface index is "; + IconExtraColumn iec = {0}; + iec.cbSize = sizeof(iec); + iec.ColumnType = m_nSlot; + + { + CGuard cs(m_lmExtraImages); + switch(nIndex) + { + case eiUp: +// o << "up\n"; + iec.hImage = m_ahExtraImages[eiUp]; + break; + case eiDown: +// o << "down\n"; + iec.hImage = m_ahExtraImages[eiDown]; + break; + case eiNotChanged: +// o << "not changed\n"; + iec.hImage = m_ahExtraImages[eiNotChanged]; + break; + default: +// o << "invalid\n"; + iec.hImage = INVALID_IMAGE_HANDLE; + break; + } + } + + bResult = (0 == CallService(MS_CLIST_EXTRA_SET_ICON,reinterpret_cast(hContact),reinterpret_cast(&iec))); + } + +// o << "Result is " << bResult; +// LogIt(Info,o.str()); + return bResult; +} + +int QuotesEventFunc_onExtraImageListRebuild(WPARAM /*wp*/,LPARAM /*lp*/) +{ + if (ServiceExists(MS_CLIST_EXTRA_ADD_ICON)) + { + CExtraImages::GetInstance().RebuildExtraImages(); + } + + return 0; +} + +int QuotesEventFunc_onExtraImageApply(WPARAM wp,LPARAM lp) +{ + HANDLE hContact = reinterpret_cast(wp); + + const CModuleInfo::TQuotesProvidersPtr& pProviders = CModuleInfo::GetQuoteProvidersPtr(); + CQuotesProviders::TQuotesProviderPtr pProvider = pProviders->GetContactProviderPtr(hContact); + if(pProvider) + { + pProvider->SetContactExtraIcon(hContact); + } + + return 0; +} + + diff --git a/protocols/Quotes/ExtraImages.h b/protocols/Quotes/ExtraImages.h new file mode 100644 index 0000000000..ec8ae01e39 --- /dev/null +++ b/protocols/Quotes/ExtraImages.h @@ -0,0 +1,39 @@ +#ifndef __9d0dac0c_12e4_46ce_809a_db6dc7d6f269_ExtraImages_h__ +#define __9d0dac0c_12e4_46ce_809a_db6dc7d6f269_ExtraImages_h__ + +#include "LightMutex.h" + +class CExtraImages : private boost::noncopyable +{ +public: + enum EImageIndex + { + eiUp = 0, + eiDown = 1, + eiNotChanged = 2, + eiEmpty = 3, + ImageCount = 3 + }; + +private: + CExtraImages(); + ~CExtraImages(); + +public: + static CExtraImages& GetInstance(); + + void RebuildExtraImages(); + bool SetContactExtraImage(HANDLE hContact,EImageIndex nIndex)const; + +private: + mutable CLightMutex m_lmExtraImages; + HANDLE m_ahExtraImages[ImageCount]; + HANDLE m_hExtraIcons; + bool m_bExtraImagesInit; + int m_nSlot; +}; + +int QuotesEventFunc_onExtraImageListRebuild(WPARAM wp,LPARAM lp); +int QuotesEventFunc_onExtraImageApply(WPARAM wp,LPARAM lp); + +#endif //__9d0dac0c_12e4_46ce_809a_db6dc7d6f269_ExtraImages_h__ diff --git a/protocols/Quotes/Forex.cpp b/protocols/Quotes/Forex.cpp new file mode 100644 index 0000000000..3bb25a9f99 --- /dev/null +++ b/protocols/Quotes/Forex.cpp @@ -0,0 +1,517 @@ +// Forex.cpp : Defines the exported functions for the DLL application. +// + +#include "stdafx.h" + +#pragma warning(disable:4996) +#include +#include +#pragma warning(default:4996) +#include "WorkingThread.h" +#include +#include "resource.h" +#include "IconLib.h" +#include +#include +#include +#include "QuoteInfoDlg.h" +#include "ModuleInfo.h" +#include "QuotesProviders.h" +#include "IQuotesProvider.h" +#include "EconomicRateInfo.h" +#include "DBUtils.h" +#include "ExtraImages.h" +#include "HTTPSession.h" +#include "CurrencyConverter.h" +#ifdef CHART_IMPLEMENT +#include "QuoteChart.h" +#endif +#include "WinCtrlHelper.h" +#include "ImportExport.h" +#include "m_Quotes.h" +#include "version.h" + +PLUGINLINK* pluginLink = NULL; +struct MM_INTERFACE mmi; +struct UTF8_INTERFACE utfi; +int hLangpack; + +HANDLE g_hEventWorkThreadStop; +int g_nStatus = ID_STATUS_OFFLINE; +HGENMENU g_hMenuEditSettings = NULL; +HGENMENU g_hMenuOpenLogFile = NULL; +#ifdef CHART_IMPLEMENT +HGENMENU g_hMenuChart = NULL; +#endif +HGENMENU g_hMenuRefresh = NULL; + +namespace +{ + typedef std::vector THandles; + THandles g_ahEvents; + THandles g_ahServices; + THandles g_ahThreads; + std::vector g_ahMenus; + + PLUGININFOEX Global_pluginInfo = + { + sizeof(PLUGININFOEX), + __PLUGIN_NAME, + PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), + __DESCRIPTION, + __AUTHOR, + __AUTHOREMAIL, + __COPYRIGHT, + __AUTHORWEB, + UNICODE_AWARE, + 0 +#ifdef _UNICODE + // {E882056D-0D1D-4131-9A98-404CBAEA6A9C} + ,{0xe882056d, 0xd1d, 0x4131, { 0x9a, 0x98, 0x40, 0x4c, 0xba, 0xea, 0x6a, 0x9c } } +#else + // {8CE16273-89EA-4e12-8CF1-2D38AB6BF431} + ,{0x8ce16273, 0x89ea, 0x4e12, { 0x8c, 0xf1, 0x2d, 0x38, 0xab, 0x6b, 0xf4, 0x31 } } +#endif + }; + + INT_PTR QuotesMenu_RefreshAll(WPARAM wp,LPARAM lp) + { + const CQuotesProviders::TQuotesProviders& apProviders = CModuleInfo::GetQuoteProvidersPtr()->GetProviders(); + std::for_each(apProviders.begin(),apProviders.end(),boost::bind(&IQuotesProvider::RefreshAll,_1)); + return 0; + } + + void InitMenu() + { +// USES_CONVERSION; + + CLISTMENUITEM mi = {0}; + mi.cbSize = sizeof(CLISTMENUITEM); + //mi.ptszPopupName = _T("Quotes"); + mi.ptszName = _T("Quotes"); + mi.flags = CMIF_TCHAR|CMIF_ICONFROMICOLIB|CMIF_ROOTPOPUP; + mi.icolibItem = Quotes_GetIconHandle(IDI_ICON_MAIN); + HGENMENU hMenuRoot = reinterpret_cast(CallService(MS_CLIST_ADDMAINMENUITEM,0,reinterpret_cast(&mi))); + g_ahMenus.push_back(hMenuRoot); + + mi.ptszName = _T("Refresh All Quotes\\Rates"); + mi.flags = CMIF_TCHAR|CMIF_ICONFROMICOLIB|CMIF_ROOTHANDLE; + //mi.position = 0x0FFFFFFF; + mi.icolibItem = Quotes_GetIconHandle(IDI_ICON_MAIN); + mi.pszService = "Quotes/RefreshAll"; + mi.hParentMenu = hMenuRoot; + HGENMENU hMenu = reinterpret_cast(CallService(MS_CLIST_ADDMAINMENUITEM,0,reinterpret_cast(&mi))); + g_ahMenus.push_back(hMenu); + HANDLE h = CreateServiceFunction(mi.pszService, QuotesMenu_RefreshAll); + g_ahServices.push_back(h); + + mi.ptszName = _T("Currency Converter..."); + //mi.flags = CMIF_TCHAR|CMIF_ICONFROMICOLIB|CMIF_ROOTHANDLE; + //mi.position = 0x0FFFFFFF; + mi.icolibItem = Quotes_GetIconHandle(IDI_ICON_CURRENCY_CONVERTER); + mi.pszService = "Quotes/CurrencyConverter"; + hMenu = reinterpret_cast(CallService(MS_CLIST_ADDMAINMENUITEM,0,reinterpret_cast(&mi))); + g_ahMenus.push_back(hMenu); + h = CreateServiceFunction(mi.pszService, QuotesMenu_CurrencyConverter); + g_ahServices.push_back(h); + +#ifdef TEST_IMPORT_EXPORT + mi.ptszName = _T("Export All Quotes"); + //mi.flags = CMIF_TCHAR|CMIF_ICONFROMICOLIB|CMIF_ROOTHANDLE; + mi.icolibItem = Quotes_GetIconHandle(IDI_ICON_EXPORT); + mi.pszService = "Quotes/ExportAll"; + hMenu = reinterpret_cast(CallService(MS_CLIST_ADDMAINMENUITEM,0,reinterpret_cast(&mi))); + g_ahMenus.push_back(hMenu); + h = CreateServiceFunction(mi.pszService, QuotesMenu_ExportAll); + g_ahServices.push_back(h); + + mi.ptszName =_T("Import All Quotes"); + //mi.flags = CMIF_TCHAR|CMIF_ICONFROMICOLIB|CMIF_ROOTHANDLE; + mi.icolibItem = Quotes_GetIconHandle(IDI_ICON_IMPORT); + mi.pszService = "Quotes/ImportAll"; + hMenu = reinterpret_cast(CallService(MS_CLIST_ADDMAINMENUITEM,0,reinterpret_cast(&mi))); + g_ahMenus.push_back(hMenu); + h = CreateServiceFunction(mi.pszService, QuotesMenu_ImportAll); + g_ahServices.push_back(h); +#endif + + bool bSubGroups = 1 == ServiceExists(MS_CLIST_ADDSUBGROUPMENUITEM); + + h = HookEvent(ME_CLIST_PREBUILDCONTACTMENU,Quotes_PrebuildContactMenu); + g_ahEvents.push_back(h); + + ZeroMemory(&mi,sizeof(mi)); + mi.cbSize = sizeof(mi); + mi.pszContactOwner = QUOTES_PROTOCOL_NAME; + hMenuRoot = NULL; + if(bSubGroups) + { + mi.pszPopupName=(char *)-1; + mi.icolibItem = Quotes_GetIconHandle(IDI_ICON_MAIN); + mi.flags = CMIF_ICONFROMICOLIB|CMIF_TCHAR|CMIF_ROOTPOPUP; + tstring sProtocolName = quotes_a2t(QUOTES_PROTOCOL_NAME); + mi.ptszName = const_cast(sProtocolName.c_str());//A2T(QUOTES_PROTOCOL_NAME); + mi.position = 0; + + hMenuRoot = reinterpret_cast(CallService(MS_CLIST_ADDCONTACTMENUITEM,0,reinterpret_cast(&mi))); + } + + mi.flags = CMIF_TCHAR; + if(bSubGroups) + { + mi.flags |= CMIF_CHILDPOPUP; + mi.pszPopupName = (char*)hMenuRoot; + } + + mi.ptszName = _T("Refresh"); + mi.popupPosition = 0; + mi.flags |= CMIF_ICONFROMICOLIB; + mi.icolibItem = Quotes_GetIconHandle(IDI_ICON_REFRESH); + mi.pszService = "Quotes/RefreshContact"; + hMenu = reinterpret_cast(CallService(MS_CLIST_ADDCONTACTMENUITEM,0,reinterpret_cast(&mi))); + g_hMenuRefresh = hMenu; + g_ahMenus.push_back(hMenu); + h = CreateServiceFunction(mi.pszService, QuotesMenu_RefreshContact); + g_ahServices.push_back(h); + + mi.ptszName = _T("Open Log File..."); + mi.popupPosition = 1; + mi.icolibItem = NULL; + mi.pszService = "Quotes/OpenLogFile"; + hMenu = reinterpret_cast(CallService(MS_CLIST_ADDCONTACTMENUITEM,0,reinterpret_cast(&mi))); + g_hMenuOpenLogFile = hMenu; + g_ahMenus.push_back(hMenu); + h = CreateServiceFunction(mi.pszService, QuotesMenu_OpenLogFile); + g_ahServices.push_back(h); + +#ifdef CHART_IMPLEMENT + mi.ptszName = _T("Chart..."); + mi.popupPosition = 2; + mi.icolibItem = NULL; + mi.pszService = "Quotes/Chart"; + hMenu = reinterpret_cast(CallService(MS_CLIST_ADDCONTACTMENUITEM,0,reinterpret_cast(&mi))); + g_hMenuChart = hMenu; + g_ahMenus.push_back(hMenu); + h = CreateServiceFunction(mi.pszService, QuotesMenu_Chart); + g_ahServices.push_back(h); +#endif + + mi.ptszName = _T("Edit Settings..."); +#ifdef CHART_IMPLEMENT + mi.popupPosition = 3; +#else + mi.popupPosition = 2; +#endif + mi.icolibItem = NULL; + mi.pszService = "Quotes/EditSettings"; + hMenu = reinterpret_cast(CallService(MS_CLIST_ADDCONTACTMENUITEM,0,reinterpret_cast(&mi))); + g_hMenuEditSettings = hMenu; + g_ahMenus.push_back(hMenu); + h = CreateServiceFunction(mi.pszService, QuotesMenu_EditSettings); + g_ahServices.push_back(h); + } + + + int QuotesEventFunc_OnModulesLoaded(WPARAM, LPARAM) + { + CHTTPSession::Init(); + + if(ServiceExists(MS_UPDATE_REGISTER)) + { + Update update = {0}; + char szVersion[16]; + + update.szComponentName = Global_pluginInfo.shortName; + update.szVersionURL = "http://addons.miranda-im.org/details.php?action=viewfile&id=4021"; + update.pbVersionPrefix = (BYTE *)"Quotes "; + update.cpbVersionPrefix = (int)strlen((char *)update.pbVersionPrefix); + update.szUpdateURL = "http://addons.miranda-im.org/feed.php?dlfile=4021"; + + update.szBetaVersionURL = NULL; + update.pbBetaVersionPrefix = NULL; + update.cpbBetaVersionPrefix = 0; + update.szBetaUpdateURL = NULL; + + update.pbVersion = (BYTE*)CreateVersionString(Global_pluginInfo.version,szVersion); + update.cpbVersion = (int)strlen((char *)update.pbVersion); + + update.szBetaChangelogURL = NULL; + + CallService(MS_UPDATE_REGISTER,0,(WPARAM)&update); + } + + HANDLE h = HookEvent(ME_CLIST_EXTRA_LIST_REBUILD,QuotesEventFunc_onExtraImageListRebuild); + g_ahEvents.push_back(h); +// QuotesEventFunc_onExtraImageListRebuild(0,0); + + h = HookEvent(ME_CLIST_EXTRA_IMAGE_APPLY,QuotesEventFunc_onExtraImageApply); + g_ahEvents.push_back(h); + + g_hEventWorkThreadStop = ::CreateEvent(NULL,TRUE,FALSE,NULL); + h = (ME_USERINFO_INITIALISE,QuotesEventFunc_OnUserInfoInit); + g_ahEvents.push_back(h); + + + h = HookEvent(ME_CLIST_DOUBLECLICKED,Quotes_OnContactDoubleClick); + g_ahEvents.push_back(h); + + InitMenu(); + + return 0; + } + + int QuotesEventFunc_OnContactDeleted(WPARAM wParam, LPARAM) + { + HANDLE hContact = reinterpret_cast(wParam); + + const CModuleInfo::TQuotesProvidersPtr& pProviders = CModuleInfo::GetQuoteProvidersPtr(); + CQuotesProviders::TQuotesProviderPtr pProvider = pProviders->GetContactProviderPtr(hContact); + if(pProvider) + { + pProvider->DeleteContact(hContact); + } + + return 0; + } + + INT_PTR QuoteProtoFunc_GetStatus(WPARAM/* wp*/,LPARAM/* lp*/) + { + return g_nStatus; + } + + void WaitForWorkingThreads() + { + size_t cThreads = g_ahThreads.size(); + if(cThreads > 0) + { + HANDLE* paHandles = &*(g_ahThreads.begin()); + ::WaitForMultipleObjects((DWORD)cThreads,paHandles,TRUE,INFINITE); + } + } + + INT_PTR QuoteProtoFunc_SetStatus(WPARAM wp,LPARAM /*lp*/) + { + int nStatus = wp; + if ((ID_STATUS_ONLINE == nStatus) || (ID_STATUS_OFFLINE == nStatus)) + { + int nOldStatus = g_nStatus; + if(nStatus != g_nStatus) + { + g_nStatus = nStatus; + if ((ID_STATUS_ONLINE == nOldStatus) && (ID_STATUS_OFFLINE == g_nStatus)) + { + BOOL b = ::SetEvent(g_hEventWorkThreadStop); + assert(b); + } + else if ((ID_STATUS_ONLINE == g_nStatus) && (ID_STATUS_OFFLINE == nOldStatus)) + { + BOOL b = ::ResetEvent(g_hEventWorkThreadStop); + assert(b && "Failed to reset event"); + + const CModuleInfo::TQuotesProvidersPtr& pProviders = CModuleInfo::GetQuoteProvidersPtr(); + const CQuotesProviders::TQuotesProviders& rapProviders = pProviders->GetProviders(); + for(CQuotesProviders::TQuotesProviders::const_iterator i = rapProviders.begin();i != rapProviders.end();++i) + { + const CQuotesProviders::TQuotesProviderPtr& pProvider = *i; + HANDLE hThread = reinterpret_cast(mir_forkthread(WorkingThread,pProvider.get())); + g_ahThreads.push_back(hThread); + } + } + + ProtoBroadcastAck(QUOTES_PROTOCOL_NAME,NULL,ACKTYPE_STATUS,ACKRESULT_SUCCESS,reinterpret_cast(nOldStatus),g_nStatus); + } + + } + + return 0; + } + + int QuotesEventFunc_PreShutdown(WPARAM wParam, LPARAM lParam) + { + QuoteProtoFunc_SetStatus(ID_STATUS_OFFLINE,0); + //WindowList_Broadcast(g_hWindowListEditSettings,WM_CLOSE,0,0); + CModuleInfo::GetInstance().OnMirandaShutdown(); + return 0; + } + + INT_PTR QuoteProtoFunc_GetName(WPARAM wParam, LPARAM lParam) + { + if(lParam) + { + lstrcpynA(reinterpret_cast(lParam),QUOTES_PROTOCOL_NAME,wParam); + return 0; + } + else + { + return 1; + } + } + + INT_PTR QuoteProtoFunc_GetCaps(WPARAM wp,LPARAM lp) + { + int ret = 0; + switch(wp) + { + case PFLAGNUM_1: + ret = PF1_PEER2PEER; + break; + case PFLAGNUM_3: + case PFLAGNUM_2: + ret = PF2_ONLINE|PF2_LONGAWAY; + if(CModuleInfo::GetInstance().GetExtendedStatusFlag()) + { + ret |= PF2_LIGHTDND; + } + break; + } + + return ret; + } + + INT_PTR QuoteProtoFunc_LoadIcon(WPARAM wp,LPARAM /*lp*/) + { + if ((wp & 0xffff) == PLI_PROTOCOL) + { + return reinterpret_cast(::CopyIcon(Quotes_LoadIconEx(ICON_STR_MAIN))); + } + + return 0; + } + + int QuotesEventFunc_OptInitialise(WPARAM wp,LPARAM/* lp*/) + { +// USES_CONVERSION; + + const CModuleInfo::TQuotesProvidersPtr& pProviders = CModuleInfo::GetQuoteProvidersPtr(); + const CQuotesProviders::TQuotesProviders& rapProviders = pProviders->GetProviders(); + + OPTIONSDIALOGPAGE odp; + ZeroMemory(&odp,sizeof(odp)); + + odp.cbSize = sizeof(odp); + odp.position = 910000000; + odp.hInstance = CModuleInfo::GetModuleHandle(); + tstring sProtocolName = quotes_a2t(QUOTES_PROTOCOL_NAME); + odp.ptszTitle = const_cast(sProtocolName.c_str());//A2T(QUOTES_PROTOCOL_NAME); + odp.ptszGroup = _T("Network"); + odp.hIcon = Quotes_LoadIconEx(ICON_STR_MAIN); + odp.flags = ODPF_TCHAR|ODPF_USERINFOTAB; + + std::for_each(rapProviders.begin(),rapProviders.end(),boost::bind(&IQuotesProvider::ShowPropertyPage,_1,wp,boost::ref(odp))); + return 0; + } + + inline int Quotes_DestroyServiceFunction(HANDLE h) + { + return DestroyServiceFunction(h); + } + + inline int Quotes_UnhookEvent(HANDLE h) + { + return UnhookEvent(h); + } + + inline int Quotes_RemoveMenuItem(HGENMENU h) + { + return CallService(MS_CLIST_REMOVECONTACTMENUITEM,reinterpret_cast(h),0); + } + +// PROTO_INTERFACE* protoInit(const char* pszProtoName, const TCHAR* tszUserName) +// { +// CAimProto *ppro = new CAimProto(pszProtoName, tszUserName); +// g_Instances.insert(ppro); +// return ppro; +// } +// +// int protoUninit(PROTO_INTERFACE* ppro) +// { +// g_Instances.remove((CAimProto*)ppro); +// return 0; +// } + +} + +extern "C" +{ + __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) + { + return &Global_pluginInfo; + } + + +#define MIID_QUOTES {0x723243c2, 0x8d4b, 0x4c29, { 0x8a, 0x37, 0xc0, 0x11, 0x48, 0x65, 0xb0, 0x80}} + + __declspec(dllexport) const MUUID* MirandaPluginInterfaces() + { + static const MUUID interfaces[] = {MIID_PROTOCOL,MIID_QUOTES,MIID_LAST}; + return interfaces; + } + + int __declspec(dllexport) Load(PLUGINLINK *link) + { + pluginLink = link; + mir_getMMI(&mmi); + mir_getUTFI(&utfi); + mir_getLP(&Global_pluginInfo); +// if ((mirandaVersion >= 0x0800) && (1 == mir_getXI(&xi))) +// { +// CModuleInfo::SetXMLEnginePtr(CModuleInfo::TXMLEnginePtr(new CXMLEngineMI)); +// } + + if(false == CModuleInfo::Verify()) + { + return 1; + } + + Quotes_IconsInit(); + + PROTOCOLDESCRIPTOR pd = {0}; + pd.cbSize = /*sizeof(pd)*/PROTOCOLDESCRIPTOR_V3_SIZE; + pd.szName = QUOTES_PROTOCOL_NAME; + pd.type = PROTOTYPE_PROTOCOL; +// pd.fnInit = protoInit; +// pd.fnUninit = protoUninit; + + CallService( MS_PROTO_REGISTERMODULE, 0, ( LPARAM )&pd ); + + HANDLE h = CreateProtoServiceFunction(QUOTES_PROTOCOL_NAME, PS_GETNAME, QuoteProtoFunc_GetName); + g_ahServices.push_back(h); + h = CreateProtoServiceFunction(QUOTES_PROTOCOL_NAME, PS_GETCAPS, QuoteProtoFunc_GetCaps); + g_ahServices.push_back(h); + h = CreateProtoServiceFunction(QUOTES_PROTOCOL_NAME, PS_SETSTATUS, QuoteProtoFunc_SetStatus); + g_ahServices.push_back(h); + h = CreateProtoServiceFunction(QUOTES_PROTOCOL_NAME, PS_GETSTATUS, QuoteProtoFunc_GetStatus); + g_ahServices.push_back(h); + h = CreateProtoServiceFunction(QUOTES_PROTOCOL_NAME, PS_LOADICON, QuoteProtoFunc_LoadIcon); + g_ahServices.push_back(h); + + h = HookEvent(ME_SYSTEM_MODULESLOADED,QuotesEventFunc_OnModulesLoaded); + g_ahEvents.push_back(h); + h = HookEvent(ME_DB_CONTACT_DELETED,QuotesEventFunc_OnContactDeleted); + g_ahEvents.push_back(h); + h = HookEvent(ME_SYSTEM_PRESHUTDOWN,QuotesEventFunc_PreShutdown); + g_ahEvents.push_back(h); + h = HookEvent(ME_OPT_INITIALISE,QuotesEventFunc_OptInitialise); + g_ahEvents.push_back(h); + + h = CreateServiceFunction(MS_QUOTES_EXPORT, Quotes_Export); + g_ahServices.push_back(h); + h = CreateServiceFunction(MS_QUOTES_IMPORT, Quotes_Import); + g_ahServices.push_back(h); + + return 0; + } + + __declspec(dllexport) int Unload(void) + { + std::for_each(g_ahServices.begin(),g_ahServices.end(),boost::bind(Quotes_DestroyServiceFunction,_1)); + std::for_each(g_ahEvents.begin(),g_ahEvents.end(),boost::bind(Quotes_UnhookEvent,_1)); + std::for_each(g_ahMenus.begin(),g_ahMenus.end(),boost::bind(Quotes_RemoveMenuItem,_1)); + + WaitForWorkingThreads(); + + ::CloseHandle(g_hEventWorkThreadStop); + + return 0; + } +} diff --git a/protocols/Quotes/Forex.rc b/protocols/Quotes/Forex.rc new file mode 100644 index 0000000000..2bfbe8eb69 --- /dev/null +++ b/protocols/Quotes/Forex.rc @@ -0,0 +1,573 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1251) + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON_MAIN ICON "res\\main.ico" +IDI_ICON_SECTION ICON "res\\Section.ico" +IDI_ICON_QUOTE ICON "res\\quote.ico" +IDI_ICON_UP ICON "res\\up.ico" +IDI_ICON_DOWN ICON "res\\down.ico" +IDI_ICON_CURRENCY_CONVERTER ICON "res\\CurrencyConverter.ico" +IDI_ICON_REFRESH ICON "res\\Refresh.ico" +IDI_ICON_EXPORT ICON "res\\Export quotes.ico" +IDI_ICON_SWAP ICON "res\\swap.ico" +IDI_ICON_IMPORT ICON "res\\Import quotes.ico" +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Russian (Russia) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +#pragma code_page(1251) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG_VARIABLE_LIST DIALOGEX 0, 0, 216, 182 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Variable List" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,83,161,50,14 + EDITTEXT IDC_EDIT_VARIABLE,7,7,202,147,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_DIALOG_VARIABLE_LIST, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 209 + TOPMARGIN, 7 + BOTTOMMARGIN, 175 + END +END +#endif // APSTUDIO_INVOKED + +#endif // Russian (Russia) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON_NOTCHANGED ICON "res\\notchanged.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_CONTACT_SETTINGS DIALOGEX 0, 0, 323, 269 +STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Edit Settings" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "Use contact specific settings",IDC_CHECK_CONTACT_SPECIFIC, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,22,151,10 + GROUPBOX "Log",IDC_STATIC,26,35,290,137 + CONTROL "Use &Internal History",IDC_CHECK_INTERNAL_HISTORY, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,37,49,140,10 + LTEXT "&Format:",IDC_STATIC_HISTORY_FORMAT,50,63,47,8 + EDITTEXT IDC_EDIT_HISTORY_FORMAT,101,61,137,12,ES_AUTOHSCROLL + PUSHBUTTON "&Variables...",IDC_BUTTON_HISTORY_DESCRIPTION,241,61,65,12 + CONTROL "&Add to History only if Value Changed",IDC_CHECK_HISTORY_CONDITION, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,50,77,252,10 + CONTROL "Use &External File",IDC_CHECK_EXTERNAL_FILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,37,97,127,10 + LTEXT "&Select File:",IDC_STATIC_SELECT_FILE,50,113,49,8 + EDITTEXT IDC_EDIT_FILE_NAME,101,111,137,12,ES_AUTOHSCROLL + PUSHBUTTON "&Browse...",IDC_BUTTON_BROWSE,241,111,65,12 + LTEXT "Variables Allowed: %miranda_userdata%,%quotename%",IDC_STATIC,50,126,257,8,WS_DISABLED + LTEXT "F&ormat:",IDC_STATIC_LOG_FILE_FORMAT,50,142,47,8 + EDITTEXT IDC_EDIT_LOG_FILE_FORMAT,101,140,137,12,ES_AUTOHSCROLL + PUSHBUTTON "V&ariables...",IDC_BUTTON_LOG_FILE_DESCRIPTION,241,140,65,12 + CONTROL "Add to &Log only if Value Changed",IDC_CHECK_LOG_FILE_CONDITION, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,50,156,224,10 + CONTROL "Show &Popup Window",IDC_CHECK_SHOW_POPUP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,180,120,10 + LTEXT "F&ormat:",IDC_STATIC_POPUP_FORMAT,30,197,47,8 + EDITTEXT IDC_EDIT_POPUP_FORMAT,81,195,137,12,ES_AUTOHSCROLL + PUSHBUTTON "V&ariables...",IDC_BUTTON_POPUP_FORMAT_DESCRIPTION,221,195,65,12 + CONTROL "Show Popup Window Only if Value &Changed",IDC_CHECK_SHOW_POPUP_ONLY_VALUE_CHANGED, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,30,210,245,10 + DEFPUSHBUTTON "OK",IDOK,107,248,50,14 + PUSHBUTTON "Cancel",IDCANCEL,163,248,50,14 + EDITTEXT IDC_EDIT_NAME,7,7,309,12,ES_CENTER | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER + PUSHBUTTON "Popup settings...",IDC_BUTTON_POPUP_SETTINGS,98,222,111,14 +END + +IDD_CURRENCY_CONVERTER DIALOGEX 0, 0, 347, 101 +STYLE DS_SETFONT | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Currency Converter" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_EDIT_VALUE,6,7,56,13,ES_AUTOHSCROLL + COMBOBOX IDC_COMBO_CONVERT_FROM,68,7,105,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "&to:",IDC_STATIC,214,9,14,8 + COMBOBOX IDC_COMBO_CONVERT_INTO,230,7,105,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "&Swap",IDC_BUTTON_SWAP,180,7,24,12,BS_ICON + PUSHBUTTON "Convert",IDC_BUTTON_CONVERT,134,24,79,14 + EDITTEXT IDC_EDIT_RESULT,7,44,328,12,ES_CENTER | ES_AUTOHSCROLL | ES_READONLY + CONTROL "Info provided by Google",IDC_SYSLINK_PROVIDER, + "SysLink",WS_TABSTOP,7,61,159,11 + PUSHBUTTON "Close",IDCANCEL,148,80,50,14 +END + +IDD_CHART DIALOGEX 0, 0, 394, 279 +STYLE DS_SETFONT | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT +CAPTION "Chart" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "Info provided by Dukascopy Swiss Forex Group",IDC_SYSLINK_PROVIDER, + "SysLink",WS_TABSTOP,7,261,176,11 + PUSHBUTTON "Close",IDCANCEL,337,258,50,14 + CONTROL "",IDC_STATIC_IMAGE,"Static",SS_ETCHEDFRAME | NOT WS_VISIBLE,7,24,380,230,WS_EX_TRANSPARENT + LTEXT "Get data from:",IDC_STATIC,7,9,69,8 + COMBOBOX IDC_COMBO_DATA_SOURCE,79,7,85,54,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Filter:",IDC_STATIC,170,9,29,8 + COMBOBOX IDC_COMBO_FILTER,204,7,69,47,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + EDITTEXT IDC_EDIT_FROM,277,7,53,12,ES_AUTOHSCROLL | NOT WS_VISIBLE + EDITTEXT IDC_EDIT_TO,334,7,53,12,ES_AUTOHSCROLL | NOT WS_VISIBLE +END + +IDD_PROVIDER_ADV_SETTINGS DIALOGEX 0, 0, 303, 260 +STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Edit Settings" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Log",IDC_STATIC,7,23,289,139 + CONTROL "Use &Internal History",IDC_CHECK_INTERNAL_HISTORY, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,37,140,10 + LTEXT "&Format:",IDC_STATIC_HISTORY_FORMAT,30,51,47,8 + EDITTEXT IDC_EDIT_HISTORY_FORMAT,81,49,137,12,ES_AUTOHSCROLL + PUSHBUTTON "&Variables...",IDC_BUTTON_HISTORY_DESCRIPTION,221,49,65,12 + CONTROL "&Add to History only if Value Changed",IDC_CHECK_HISTORY_CONDITION, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,30,65,252,10 + CONTROL "Use &External File",IDC_CHECK_EXTERNAL_FILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,85,127,10 + LTEXT "&Select File:",IDC_STATIC_SELECT_FILE,30,101,49,8 + EDITTEXT IDC_EDIT_FILE_NAME,81,99,137,12,ES_AUTOHSCROLL + PUSHBUTTON "&Browse...",IDC_BUTTON_BROWSE,221,99,65,12 + LTEXT "Variables Allowed: %miranda_userdata%,%quotename%",IDC_STATIC,30,115,257,8,WS_DISABLED + LTEXT "F&ormat:",IDC_STATIC_LOG_FILE_FORMAT,30,131,47,8 + EDITTEXT IDC_EDIT_LOG_FILE_FORMAT,81,129,137,12,ES_AUTOHSCROLL + PUSHBUTTON "V&ariables...",IDC_BUTTON_LOG_FILE_DESCRIPTION,221,129,65,12 + CONTROL "Add to &Log only if Value Changed",IDC_CHECK_LOG_FILE_CONDITION, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,30,145,224,10 + CONTROL "Show &Popup Window",IDC_CHECK_SHOW_POPUP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,167,120,10 + LTEXT "F&ormat:",IDC_STATIC_POPUP_FORMAT,30,184,47,8 + EDITTEXT IDC_EDIT_POPUP_FORMAT,81,182,137,12,ES_AUTOHSCROLL + PUSHBUTTON "V&ariables...",IDC_BUTTON_POPUP_FORMAT_DESCRIPTION,221,182,65,12 + CONTROL "Show Popup Window Only if Value &Changed",IDC_CHECK_SHOW_POPUP_ONLY_VALUE_CHANGED, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,30,197,245,10 + DEFPUSHBUTTON "OK",IDOK,98,239,50,14 + PUSHBUTTON "Cancel",IDCANCEL,154,239,50,14 + EDITTEXT IDC_EDIT_NAME,7,7,289,12,ES_CENTER | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER + PUSHBUTTON "Popup settings...",IDC_BUTTON_POPUP_SETTINGS,86,210,111,14 +END + +IDD_DIALOG_POPUP DIALOGEX 0, 0, 319, 160 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Popup Window Settings" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Colours",IDC_STATIC,7,7,149,82,WS_GROUP + CONTROL "Use default colours",IDC_RADIO_DEFAULT_COLOURS,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,15,20,82,10 + CONTROL "Use user-defined colours",IDC_RADIO_USER_DEFINED_COLOURS, + "Button",BS_AUTORADIOBUTTON,15,34,97,10 + LTEXT "Background colour",IDC_STATIC,70,53,66,8 + CONTROL "",IDC_BGCOLOR,"ColourPicker",WS_TABSTOP,26,49,35,14 + LTEXT "Text colour",IDC_STATIC,70,71,66,8 + CONTROL "",IDC_TEXTCOLOR,"ColourPicker",WS_TABSTOP,26,67,35,14 + GROUPBOX "Delay",IDC_STATIC,162,6,149,82,WS_GROUP + CONTROL "From PopUp plugin",IDC_DELAYFROMPU,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,174,20,76,10 + CONTROL "Custom",IDC_DELAYCUSTOM,"Button",BS_AUTORADIOBUTTON,174,35,47,10 + CONTROL "Permanent",IDC_DELAYPERMANENT,"Button",BS_AUTORADIOBUTTON,174,50,50,10 + EDITTEXT IDC_DELAY,252,33,35,14,ES_AUTOHSCROLL | ES_NUMBER | WS_GROUP + CONTROL "Do not add to popup's history",IDC_CHECK_DONT_USE_POPUPHISTORY, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,96,200,10 + PUSHBUTTON "Preview",IDC_PREV,134,114,50,14 + DEFPUSHBUTTON "OK",IDOK,101,139,50,14 + PUSHBUTTON "Cancel",IDCANCEL,167,139,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_CONTACT_SETTINGS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 316 + TOPMARGIN, 7 + BOTTOMMARGIN, 262 + END + + IDD_CURRENCY_CONVERTER, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 335 + TOPMARGIN, 7 + BOTTOMMARGIN, 94 + END + + IDD_CHART, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 387 + TOPMARGIN, 7 + BOTTOMMARGIN, 272 + END + + IDD_PROVIDER_ADV_SETTINGS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 296 + TOPMARGIN, 7 + BOTTOMMARGIN, 253 + END + + IDD_DIALOG_POPUP, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 312 + TOPMARGIN, 7 + BOTTOMMARGIN, 153 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog Info +// + +IDD_CHART DLGINIT +BEGIN + IDC_COMBO_DATA_SOURCE, 0x403, 9, 0 +0x6f4c, 0x2067, 0x6946, 0x656c, "\000" + IDC_COMBO_DATA_SOURCE, 0x403, 18, 0 +0x694d, 0x6172, 0x646e, 0x2761, 0x2073, 0x6948, 0x7473, 0x726f, 0x0079, + + IDC_COMBO_FILTER, 0x403, 4, 0 +0x6c41, 0x006c, + IDC_COMBO_FILTER, 0x403, 9, 0 +0x614c, 0x7473, 0x4420, 0x7961, "\000" + IDC_COMBO_FILTER, 0x403, 10, 0 +0x614c, 0x7473, 0x5720, 0x6565, 0x006b, + IDC_COMBO_FILTER, 0x403, 11, 0 +0x614c, 0x7473, 0x4d20, 0x6e6f, 0x6874, "\000" + IDC_COMBO_FILTER, 0x403, 10, 0 +0x614c, 0x7473, 0x5920, 0x6165, 0x0072, + IDC_COMBO_FILTER, 0x403, 13, 0 +0x7355, 0x7265, 0x442d, 0x6665, 0x6e69, 0x6465, "\000" + 0 +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (United Kingdom) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG_ECONOMIC_RATES DIALOGEX 0, 0, 310, 230 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "&Choose Quotes to watch in contact list:",IDC_STATIC,7,7,298,8 + CONTROL "",IDC_TREE_ECONOMIC_RATES,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | TVS_CHECKBOXES | TVS_NOHSCROLL | WS_BORDER | WS_TABSTOP,21,18,284,126 + LTEXT "&Refresh Quotes Every:",IDC_STATIC,7,150,108,8 + EDITTEXT IDC_EDIT_REFRESH_RATE,118,148,40,12,ES_AUTOHSCROLL + CONTROL "",IDC_SPIN_REFRESH_RATE,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_HOTTRACK,230,147,11,14 + COMBOBOX IDC_COMBO_REFRESH_RATE,161,148,69,59,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "&Display in Contact List as:",IDC_STATIC,7,165,109,8 + EDITTEXT IDC_EDIT_CONTACT_LIST_FORMAT,118,162,120,12,ES_AUTOHSCROLL + PUSHBUTTON "&Variables...",IDC_BUTTON_DESCRIPTION,240,162,65,12 + LTEXT "&Status Message:",IDC_STATIC,7,178,107,8 + EDITTEXT IDC_EDIT_STATUS_MESSAGE_FORMAT,118,176,120,12,ES_AUTOHSCROLL + LTEXT "&Tendency:",IDC_STATIC,7,192,102,8 + EDITTEXT IDC_EDIT_TENDENCY_FORMAT,118,190,120,12,ES_AUTOHSCROLL + PUSHBUTTON "&Advanced Settings...",IDC_BUTTON_ADVANCED_SETTINGS,103,208,110,14 +END + +IDD_DIALOG_QUOTE_INFO DIALOGEX 0, 0, 222, 132 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CTEXT "Static",IDC_STATIC_QUOTE_NAME,7,7,208,8 + CONTROL "SysLink1",IDC_SYSLINK_PROVIDER,"SysLink",WS_TABSTOP,7,110,208,14 + LTEXT "Current Rate:",IDC_STATIC,21,62,72,8 + EDITTEXT IDC_EDIT_RATE,97,60,61,12,ES_AUTOHSCROLL | ES_READONLY + LTEXT "Rate Fetch Time:",IDC_STATIC,21,47,73,8 + EDITTEXT IDC_EDIT_RATE_FETCH_TIME,97,45,98,12,ES_AUTOHSCROLL | ES_READONLY + LTEXT "Previous Rate:",IDC_STATIC,21,77,71,8 + EDITTEXT IDC_EDIT_PREVIOUS_RATE,97,75,61,12,ES_AUTOHSCROLL | ES_READONLY +END + +IDD_DIALOG_OPT_GOOGLE DIALOGEX 0, 0, 310, 233 +STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "&Convert:",IDC_STATIC,7,9,56,8 + COMBOBOX IDC_COMBO_CONVERT_FROM,64,7,105,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "&to:",IDC_STATIC,175,9,21,8 + COMBOBOX IDC_COMBO_CONVERT_INTO,200,7,105,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "&Add",IDC_BUTTON_ADD,255,35,50,14 + LTEXT "&Watched currency rates:",IDC_STATIC,7,23,110,8 + LISTBOX IDC_LIST_RATES,19,35,231,111,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "&Remove",IDC_BUTTON_REMOVE,255,52,50,14 + LTEXT "&Refresh Rates Every:",IDC_STATIC,7,153,107,8 + EDITTEXT IDC_EDIT_REFRESH_RATE,117,151,40,12,ES_AUTOHSCROLL + CONTROL "",IDC_SPIN_REFRESH_RATE,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_HOTTRACK,234,150,11,14 + COMBOBOX IDC_COMBO_REFRESH_RATE,160,151,69,59,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "&Display in Contact List as:",IDC_STATIC,7,168,107,8 + EDITTEXT IDC_EDIT_CONTACT_LIST_FORMAT,117,165,120,12,ES_AUTOHSCROLL + PUSHBUTTON "&Variables...",IDC_BUTTON_DESCRIPTION,240,165,65,12 + LTEXT "&Status Message:",IDC_STATIC,7,181,108,8 + EDITTEXT IDC_EDIT_STATUS_MESSAGE_FORMAT,117,179,120,12,ES_AUTOHSCROLL + LTEXT "&Tendency:",IDC_STATIC,7,195,102,8 + EDITTEXT IDC_EDIT_TENDENCY_FORMAT,117,193,120,12,ES_AUTOHSCROLL + PUSHBUTTON "&Advanced Settings...",IDC_BUTTON_ADVANCED_SETTINGS,102,211,110,14 +END + +IDD_DIALOG_QUOTE_INFO_1 DIALOGEX 0, 0, 222, 143 +STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Quote\\Rate Info" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CTEXT "Static",IDC_STATIC_QUOTE_NAME,7,7,208,8 + CONTROL "SysLink1",IDC_SYSLINK_PROVIDER,"SysLink",WS_TABSTOP,7,98,208,14 + LTEXT "Current Rate:",IDC_STATIC,15,57,81,8 + EDITTEXT IDC_EDIT_RATE,108,55,61,12,ES_AUTOHSCROLL | ES_READONLY + LTEXT "Rate Fetch Time:",IDC_STATIC,15,42,81,8 + EDITTEXT IDC_EDIT_RATE_FETCH_TIME,108,40,98,12,ES_AUTOHSCROLL | ES_READONLY + LTEXT "Previous Rate:",IDC_STATIC,15,72,92,8 + EDITTEXT IDC_EDIT_PREVIOUS_RATE,108,70,61,12,ES_AUTOHSCROLL | ES_READONLY + PUSHBUTTON "Close",IDOK,85,122,50,14 +END + +IDD_DIALOG_OPT_FINANCE DIALOGEX 0, 0, 310, 232 +STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "Type &Stock Name or Symbol:",IDC_STATIC,7,10,96,8 + EDITTEXT IDC_EDIT_QUOTE,106,7,143,14,ES_AUTOHSCROLL + PUSHBUTTON "&Add",IDC_BUTTON_ADD,255,7,50,14 + LTEXT "&Watched Quotes:",IDC_STATIC,7,23,110,8 + LISTBOX IDC_LIST_RATES,19,35,231,112,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "&Remove",IDC_BUTTON_REMOVE,255,35,50,14 + LTEXT "&Refresh Rates Every:",IDC_STATIC,7,153,107,8 + EDITTEXT IDC_EDIT_REFRESH_RATE,117,151,40,12,ES_AUTOHSCROLL + CONTROL "",IDC_SPIN_REFRESH_RATE,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_HOTTRACK,234,150,11,14 + COMBOBOX IDC_COMBO_REFRESH_RATE,160,151,69,59,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "&Display in Contact List as:",IDC_STATIC,7,168,107,8 + EDITTEXT IDC_EDIT_CONTACT_LIST_FORMAT,117,165,120,12,ES_AUTOHSCROLL + PUSHBUTTON "&Variables...",IDC_BUTTON_DESCRIPTION,240,165,65,12 + LTEXT "Status &Message:",IDC_STATIC,7,181,108,8 + EDITTEXT IDC_EDIT_STATUS_MESSAGE_FORMAT,117,179,120,12,ES_AUTOHSCROLL + LTEXT "&Tendency:",IDC_STATIC,7,195,102,8 + EDITTEXT IDC_EDIT_TENDENCY_FORMAT,117,193,120,12,ES_AUTOHSCROLL + PUSHBUTTON "&Advanced Settings...",IDC_BUTTON_ADVANCED_SETTINGS,99,210,110,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_DIALOG_ECONOMIC_RATES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 305 + TOPMARGIN, 7 + BOTTOMMARGIN, 222 + END + + IDD_DIALOG_QUOTE_INFO, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 215 + TOPMARGIN, 7 + BOTTOMMARGIN, 124 + END + + IDD_DIALOG_OPT_GOOGLE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 305 + VERTGUIDE, 249 + TOPMARGIN, 7 + BOTTOMMARGIN, 225 + END + + IDD_DIALOG_QUOTE_INFO_1, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 215 + TOPMARGIN, 7 + BOTTOMMARGIN, 135 + END + + IDD_DIALOG_OPT_FINANCE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 305 + VERTGUIDE, 249 + TOPMARGIN, 7 + BOTTOMMARGIN, 224 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog Info +// + +IDD_DIALOG_ECONOMIC_RATES DLGINIT +BEGIN + IDC_COMBO_REFRESH_RATE, 0x403, 8, 0 +0x6553, 0x6f63, 0x646e, 0x0073, + IDC_COMBO_REFRESH_RATE, 0x403, 8, 0 +0x694d, 0x756e, 0x6574, 0x0073, + IDC_COMBO_REFRESH_RATE, 0x403, 6, 0 +0x6f48, 0x7275, 0x0073, + 0 +END + +IDD_DIALOG_OPT_GOOGLE DLGINIT +BEGIN + IDC_COMBO_REFRESH_RATE, 0x403, 8, 0 +0x6553, 0x6f63, 0x646e, 0x0073, + IDC_COMBO_REFRESH_RATE, 0x403, 8, 0 +0x694d, 0x756e, 0x6574, 0x0073, + IDC_COMBO_REFRESH_RATE, 0x403, 6, 0 +0x6f48, 0x7275, 0x0073, + 0 +END + +IDD_DIALOG_OPT_FINANCE DLGINIT +BEGIN + IDC_COMBO_REFRESH_RATE, 0x403, 8, 0 +0x6553, 0x6f63, 0x646e, 0x0073, + IDC_COMBO_REFRESH_RATE, 0x403, 8, 0 +0x694d, 0x756e, 0x6574, 0x0073, + IDC_COMBO_REFRESH_RATE, 0x403, 6, 0 +0x6f48, 0x7275, 0x0073, + 0 +END + +#endif // English (United Kingdom) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/protocols/Quotes/Forex.sln b/protocols/Quotes/Forex.sln new file mode 100644 index 0000000000..5f0d619104 --- /dev/null +++ b/protocols/Quotes/Forex.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Quotes", "Forex.vcxproj", "{C619A811-8023-4441-B3D7-785388A09DF0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C619A811-8023-4441-B3D7-785388A09DF0}.Debug|Win32.ActiveCfg = Debug|Win32 + {C619A811-8023-4441-B3D7-785388A09DF0}.Debug|Win32.Build.0 = Debug|Win32 + {C619A811-8023-4441-B3D7-785388A09DF0}.Debug|x64.ActiveCfg = Debug|x64 + {C619A811-8023-4441-B3D7-785388A09DF0}.Debug|x64.Build.0 = Debug|x64 + {C619A811-8023-4441-B3D7-785388A09DF0}.Release|Win32.ActiveCfg = Release|Win32 + {C619A811-8023-4441-B3D7-785388A09DF0}.Release|Win32.Build.0 = Release|Win32 + {C619A811-8023-4441-B3D7-785388A09DF0}.Release|x64.ActiveCfg = Release|x64 + {C619A811-8023-4441-B3D7-785388A09DF0}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/protocols/Quotes/Forex.vcxproj b/protocols/Quotes/Forex.vcxproj new file mode 100644 index 0000000000..4dd737de9c --- /dev/null +++ b/protocols/Quotes/Forex.vcxproj @@ -0,0 +1,289 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {C619A811-8023-4441-B3D7-785388A09DF0} + Quotes + + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + + + DynamicLibrary + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)64\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)64\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + true + true + true + true + + + + Disabled + ..\..\include;..\plugins\ExternalAPI;..\..\..\boost_1_49_0;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;FOREX_EXPORTS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Use + Level3 + EditAndContinue + + + comsuppw.lib;comctl32.lib;%(AdditionalDependencies) + true + Windows + $(IntDir)$(TargetName).lib + false + ..\..\..\boost_1_49_0\lib + + + ..\..\include\msapi + _DEBUG;%(PreprocessorDefinitions) + + + + + Disabled + ..\..\include;..\plugins\ExternalAPI;..\..\..\boost_1_49_0;%(AdditionalIncludeDirectories) + WIN64;_DEBUG;_WINDOWS;_USRDLL;FOREX_EXPORTS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Use + Level3 + + + comsuppw.lib;comctl32.lib;%(AdditionalDependencies) + true + Windows + $(IntDir)$(TargetName).lib + false + ..\..\..\boost_1_49_0\lib64 + + + ..\..\include\msapi + _DEBUG;%(PreprocessorDefinitions) + + + + + Full + true + Size + ..\..\include;..\plugins\ExternalAPI;..\..\..\boost_1_49_0;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FOREX_EXPORTS;%(PreprocessorDefinitions) + true + Use + Level3 + + + comsuppw.lib;comctl32.lib;%(AdditionalDependencies) + true + Windows + true + true + $(IntDir)$(TargetName).lib + false + ..\..\..\boost_1_49_0\lib + + + ..\..\include\msapi + NDEBUG;%(PreprocessorDefinitions) + + + + + Full + true + Size + ..\..\include;..\plugins\ExternalAPI;..\..\..\boost_1_49_0;%(AdditionalIncludeDirectories) + WIN64;NDEBUG;_WINDOWS;_USRDLL;FOREX_EXPORTS;%(PreprocessorDefinitions) + true + Use + Level3 + + + comsuppw.lib;comctl32.lib;%(AdditionalDependencies) + true + Windows + true + true + $(IntDir)$(TargetName).lib + false + ..\..\..\boost_1_49_0\lib64 + + + ..\..\include\msapi + NDEBUG;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/protocols/Quotes/Forex.vcxproj.filters b/protocols/Quotes/Forex.vcxproj.filters new file mode 100644 index 0000000000..127582eda6 --- /dev/null +++ b/protocols/Quotes/Forex.vcxproj.filters @@ -0,0 +1,307 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Resource Files + + + Resource Files + + + \ No newline at end of file diff --git a/protocols/Quotes/HTMLParserMS.cpp b/protocols/Quotes/HTMLParserMS.cpp new file mode 100644 index 0000000000..bfe58b43b1 --- /dev/null +++ b/protocols/Quotes/HTMLParserMS.cpp @@ -0,0 +1,313 @@ +#include "StdAfx.h" +#include "HTMLParserMS.h" + +using _com_util::CheckError; + +namespace +{ + class CHTMLNode : public IHTMLNode + { + public: + typedef CComPtr TComPtr; + typedef CComPtr TDocumentPtr; + + protected: + typedef CComPtr TElementCollectionPtr; + + public: + CHTMLNode(const TComPtr& pElement,const TDocumentPtr& pDocument) + : m_pElement(pElement),m_pDocument(pDocument){} + + virtual THTMLNodePtr GetElementByID(const tstring& rsID)const + { + if(m_pDocument) + { + CComPtr pElement; + if(SUCCEEDED(m_pDocument->getElementById(bstr_t(rsID.c_str()),&pElement)) + && pElement) + { + TComPtr p(pElement); + return THTMLNodePtr(new CHTMLNode(p,m_pDocument)); + } + } + + return THTMLNodePtr(); + } + + virtual size_t GetChildCount()const + { + TElementCollectionPtr pColl = GetElementCollectionPtr(); + if(pColl) + { + LONG celem = 0; + HRESULT hr = pColl->get_length(&celem); + if(S_OK == hr) + { + return celem; + } + } + + return 0; + } + + virtual THTMLNodePtr GetChildPtr(size_t nIndex) + { + TElementCollectionPtr pColl = GetElementCollectionPtr(); + if(pColl) + { + VARIANT varIndex; + varIndex.vt = VT_UINT; + varIndex.lVal = (LONG)nIndex; + VARIANT var2; + VariantInit(&var2); + TComPtr pDisp; + HRESULT hr = pColl->item(varIndex,var2,&pDisp); + if(S_OK == hr && pDisp) + { + return THTMLNodePtr(new CHTMLNode(pDisp,m_pDocument)); + } + } + + return THTMLNodePtr(); + } + + virtual bool Is(EType nType)const + { + switch(nType) + { + case Table: + { + CComPtr pTable; + return (SUCCEEDED(m_pElement->QueryInterface(IID_IHTMLTable,reinterpret_cast(&pTable))) && (pTable)); + } + case TableRow: + { + CComPtr pRow; + return (SUCCEEDED(m_pElement->QueryInterface(IID_IHTMLTableRow,reinterpret_cast(&pRow))) && (pRow)); + } + case TableColumn: + { + CComPtr pCol; + return (SUCCEEDED(m_pElement->QueryInterface(IID_IHTMLTableCol,reinterpret_cast(&pCol))) && (pCol)); + } + } + + return false; + } + + virtual tstring GetAttribute(const tstring& rsAttrName)const + { + USES_CONVERSION; + + tstring sAttr; + CComPtr pElement; + if(SUCCEEDED(m_pElement->QueryInterface(IID_IHTMLElement,reinterpret_cast(&pElement))) && pElement) + { + _variant_t vAttribute; + BSTR pbstrAttrName = T2BSTR(rsAttrName.c_str()); + if(SUCCEEDED(pElement->getAttribute(pbstrAttrName,1,&vAttribute)) + && VT_NULL != vAttribute.vt && VT_EMPTY != vAttribute.vt) + { + try + { + _bstr_t b(vAttribute); + LPCTSTR psz = b; + if(psz) + { + sAttr = psz; + } + } + catch(_com_error&) + { + } + } + } + + return sAttr; + } + + virtual tstring GetText()const + { +// USES_CONVERSION; + + tstring sText; + CComPtr pElement; + if(SUCCEEDED(m_pElement->QueryInterface(IID_IHTMLElement,reinterpret_cast(&pElement))) && pElement) + { + BSTR bstrText; + if(SUCCEEDED(pElement->get_innerText(&bstrText)) && bstrText) + { + try + { + sText = _bstr_t(bstrText); + } + catch(_com_error&) + { + } + + ::SysFreeString(bstrText); + } + } + + return sText; + } + + protected: + virtual TElementCollectionPtr GetElementCollectionPtr()const + { + TElementCollectionPtr pColl; + HRESULT hr = m_pElement->QueryInterface(IID_IHTMLElementCollection,reinterpret_cast(&pColl)); + if(FAILED(hr)) + { + CComPtr pElement; + if(SUCCEEDED(m_pElement->QueryInterface(IID_IHTMLElement,reinterpret_cast(&pElement))) && pElement) + { + CComPtr pDisp; + if(SUCCEEDED(pElement->get_children(&pDisp)) && pDisp) + { + hr = pDisp->QueryInterface(IID_IHTMLElementCollection,reinterpret_cast(&pColl)); + } + } + } + + return pColl; + } + + private: + TComPtr m_pElement; + TDocumentPtr m_pDocument; + }; +} + +CHTMLParserMS::CHTMLParserMS() : m_bCallUninit(false) +{ + try + { + CheckError(::CoInitialize(NULL)); + + m_bCallUninit = true; + + _com_util::CheckError( + ::CoCreateInstance(CLSID_HTMLDocument, + NULL, + CLSCTX_INPROC_SERVER, + IID_IHTMLDocument2, + (LPVOID*)&m_pDoc) + ); + + CComPtr pPersist; + _com_util::CheckError(m_pDoc->QueryInterface(IID_IPersistStreamInit, + (LPVOID*)&pPersist)); + + _com_util::CheckError(pPersist->InitNew()); + + _com_util::CheckError(m_pDoc->QueryInterface(IID_IMarkupServices, + (LPVOID*)&m_pMS)); + + if(m_pMS) + { + _com_util::CheckError(m_pMS->CreateMarkupPointer(&m_pMkStart)); + _com_util::CheckError(m_pMS->CreateMarkupPointer(&m_pMkFinish)); + } + } + catch(_com_error&/* e*/) + { +// show_com_error_msg(e); + } + +} + +CHTMLParserMS::~CHTMLParserMS() +{ + if(true == m_bCallUninit) + { + ::CoUninitialize(); + } +} + +CHTMLParserMS::THTMLNodePtr CHTMLParserMS::ParseString(const tstring& rsHTML) +{ + USES_CONVERSION; + + try + { + CGuard cs(m_cs); + + OLECHAR* p = T2OLE(const_cast(rsHTML.c_str())); + CComPtr pMC; + _com_util::CheckError(m_pMS->ParseString(p,0,&pMC,m_pMkStart,m_pMkFinish)); + + if(pMC) + { + CComPtr pNewDoc; + + _com_util::CheckError(pMC->QueryInterface(IID_IHTMLDocument, + (LPVOID*)&pNewDoc)); + + if(pNewDoc) + { + CComPtr pColl; + _com_util::CheckError(pNewDoc->get_all(&pColl)); + + CHTMLNode::TDocumentPtr pDoc; + pMC->QueryInterface(IID_IHTMLDocument3,(LPVOID*)&pDoc); + + + return THTMLNodePtr(new CHTMLNode(CHTMLNode::TComPtr(pColl),pDoc)); + } + } + } + catch(_com_error&/* e*/) + { +// show_com_error_msg(e); + } + + return THTMLNodePtr(); +} + +bool CHTMLParserMS::IsInstalled() +{ + bool bResult = true; + bool bCallUninit = false; + try + { + CheckError(::CoInitialize(NULL)); + + bCallUninit = true; + + CComPtr pDoc; + _com_util::CheckError( + ::CoCreateInstance(CLSID_HTMLDocument, + NULL, + CLSCTX_INPROC_SERVER, + IID_IHTMLDocument2, + reinterpret_cast(&pDoc)) + ); + } + catch(_com_error&/* e*/) + { + bResult = false; + } + + if(bCallUninit) + { + ::CoUninitialize(); + } + + return bResult; +} + +CHTMLEngineMS::CHTMLEngineMS() +{ + +} + +CHTMLEngineMS::~CHTMLEngineMS() +{ + +} + +CHTMLEngineMS::THTMLParserPtr CHTMLEngineMS::GetParserPtr()const +{ + return THTMLParserPtr(new CHTMLParserMS); +} diff --git a/protocols/Quotes/HTMLParserMS.h b/protocols/Quotes/HTMLParserMS.h new file mode 100644 index 0000000000..0773efa42a --- /dev/null +++ b/protocols/Quotes/HTMLParserMS.h @@ -0,0 +1,36 @@ +#ifndef __3c99e3f7_ecd9_4d9b_8f86_fe293c5fc8e6_HTMLParserMS_h__ +#define __3c99e3f7_ecd9_4d9b_8f86_fe293c5fc8e6_HTMLParserMS_h__ + +#include "ihtmlparser.h" +#include "LightMutex.h" +#include "IHTMLEngine.h" + +class CHTMLParserMS : public IHTMLParser +{ +public: + CHTMLParserMS(); + ~CHTMLParserMS(); + + virtual THTMLNodePtr ParseString(const tstring& rsHTML); + + static bool IsInstalled(); + +private: + bool m_bCallUninit; + CComPtr m_pDoc; + CComPtr m_pMS; + CComPtr m_pMkStart; + CComPtr m_pMkFinish; + mutable CLightMutex m_cs; +}; + +class CHTMLEngineMS : public IHTMLEngine +{ +public: + CHTMLEngineMS(); + ~CHTMLEngineMS(); + + virtual THTMLParserPtr GetParserPtr()const; +}; + +#endif //__3c99e3f7_ecd9_4d9b_8f86_fe293c5fc8e6_HTMLParserMS_h__ diff --git a/protocols/Quotes/HTTPSession.cpp b/protocols/Quotes/HTTPSession.cpp new file mode 100644 index 0000000000..aa66948ae9 --- /dev/null +++ b/protocols/Quotes/HTTPSession.cpp @@ -0,0 +1,262 @@ +#include "StdAfx.h" +#include "HTTPSession.h" +#include "EconomicRateInfo.h" +#include "LightMutex.h" + +class CHTTPSession::CImpl +{ +public: + CImpl() {} + virtual ~CImpl() {} + + virtual bool OpenURL(const tstring& rsURL) = 0; + virtual bool ReadResponce(tstring& rsResponce)const = 0; +}; + +namespace +{ +// class CImplMS : public CHTTPSession::CImpl +// { +// public: +// CImplMS() +// : m_hSession(::InternetOpen(_T("Dioksin"),PRE_CONFIG_INTERNET_ACCESS,NULL,INTERNET_INVALID_PORT_NUMBER,0)), +// m_hRequest(NULL) +// { +// +// } +// +// ~CImplMS() +// { +// if(m_hRequest) +// { +// ::InternetCloseHandle(m_hRequest); +// } +// +// if(m_hSession) +// { +// ::InternetCloseHandle(m_hSession); +// } +// } +// +// virtual bool OpenURL(const tstring& rsURL) +// { +// if(NULL == m_hSession) +// { +// return false; +// } +// +// if(NULL != m_hRequest) +// { +// ::InternetCloseHandle(m_hRequest); +// m_hRequest = NULL; +// } +// +// m_hRequest = ::InternetOpenUrl(m_hSession,rsURL.c_str(),NULL,0,INTERNET_FLAG_RELOAD,0); +// return NULL != m_hRequest; +// } +// +// virtual bool ReadResponce(tstring& rsResponce)const +// { +// if(NULL == m_hRequest) +// { +// return false; +// } +// +// std::string sBuffer; +// bool bResult = true; +// DWORD cbRead = 0; +// char szBuffer[1024]; +// do{ +// if(FALSE == ::InternetReadFile(m_hRequest,szBuffer,1024,&cbRead)) +// { +// bResult = false; +// break; +// } +// if (0 == cbRead) +// { +// break; // Stop. +// } +// else +// { +// sBuffer.insert(sBuffer.size(),szBuffer,cbRead); +// } +// }while(true); +// +// if(true == bResult) +// { +// USES_CONVERSION; +// rsResponce = A2CT(sBuffer.c_str()); +// } +// +// return bResult; +// } +// private: +// HINTERNET m_hSession; +// HINTERNET m_hRequest; +// }; +// + int find_header(const NETLIBHTTPREQUEST* pRequest,const char* hdr) + { + for(int i = 0;i < pRequest->headersCount; ++i) + { + if (0 == _stricmp(pRequest->headers[i].szName,hdr)) + { + return i; + } + } + + return -1; + } + + + class CImplMI : public CHTTPSession::CImpl + { + public: + CImplMI() {} + + static bool Init() + { + assert(NULL == g_hNetLib); + + NETLIBUSER nlu = {0}; + nlu.cbSize = sizeof(nlu); + nlu.flags = NUF_OUTGOING|NUF_HTTPCONNS|NUF_NOHTTPSOPTION|NUF_TCHAR; + nlu.szSettingsModule = QUOTES_PROTOCOL_NAME; + nlu.ptszDescriptiveName = TranslateT("Quotes HTTP connections"); + g_hNetLib = reinterpret_cast(CallService(MS_NETLIB_REGISTERUSER,0,(LPARAM)&nlu)); + return (NULL != g_hNetLib); + } + + static bool IsValid(){return NULL != g_hNetLib;} + + virtual bool OpenURL(const tstring& rsURL) + { +// USES_CONVERSION; + + m_aURL.swap(TBuffer()); + + std::string s = quotes_t2a(rsURL.c_str()); + const char* psz = s.c_str();//T2CA(rsURL.c_str()); + m_aURL.insert(m_aURL.begin(),psz,psz+strlen(psz)+1); + return true; + + } + virtual bool ReadResponce(tstring& rsResponce)const + { + if(true == m_aURL.empty()) + { + return false; + } + + + NETLIBHTTPREQUEST nlhr = {0}; + nlhr.cbSize = sizeof(nlhr); + nlhr.requestType = REQUEST_GET; + nlhr.flags = NLHRF_DUMPASTEXT|NLHRF_HTTP11|NLHRF_REDIRECT; + char* pURL = &*(m_aURL.begin()); + nlhr.szUrl = pURL; + + nlhr.headersCount = 4; + nlhr.headers=(NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER)*nlhr.headersCount); + nlhr.headers[0].szName = "User-Agent"; + nlhr.headers[0].szValue = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"; + nlhr.headers[1].szName = "Connection"; + nlhr.headers[1].szValue = "close"; + nlhr.headers[2].szName = "Cache-Control"; + nlhr.headers[2].szValue = "no-cache"; + nlhr.headers[3].szName = "Pragma"; + nlhr.headers[3].szValue = "no-cache"; + // nlhr.headers[4].szName = "Accept-Encoding"; + // nlhr.headers[4].szValue = "deflate, gzip"; + // nlhr.headers[5].szName = "Cookie"; + // nlhr.headers[5].szValue = cookie; + + bool bResult = false; + NETLIBHTTPREQUEST* pReply = NULL; + + { + CGuard guard(m_mx); + pReply = reinterpret_cast(CallService(MS_NETLIB_HTTPTRANSACTION, + reinterpret_cast(g_hNetLib),reinterpret_cast(&nlhr))); + } + + if(pReply) + { + if ((200 == pReply->resultCode) && (pReply->dataLength > 0)) + { + TBuffer apBuffer; + apBuffer.insert(apBuffer.begin(),pReply->pData,pReply->pData+pReply->dataLength); + apBuffer.push_back('\0'); + + char* pResult = &*(apBuffer.begin()); + int nIndex = find_header(pReply,"Content-Type"); + if ((-1 != nIndex) && (NULL != strstr(_strlwr(pReply->headers[nIndex].szValue),"utf-8"))) + { + TCHAR* p = mir_utf8decodeT(pResult); + rsResponce = p; + mir_free(p); + } + else + { +// USES_CONVERSION; +// LPCTSTR p = A2CT(pResult); + rsResponce = quotes_a2t(pResult);//p; + } + + bResult = true; + } + + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,reinterpret_cast(pReply)); + } + + mir_free(nlhr.headers); + + return bResult; + } + + private: + static HANDLE g_hNetLib; + typedef std::vector TBuffer; + mutable TBuffer m_aURL; + mutable CLightMutex m_mx; + }; + + HANDLE CImplMI::g_hNetLib = NULL; + +// CHTTPSession::CImpl* create_impl() +// { +// if(true == CImplMI::IsValid()) +// { +// return new CImplMI; +// } +// else +// { +// return new CImplMS; +// } +// } +} + + +CHTTPSession::CHTTPSession() + : m_pImpl(new CImplMI) +{ +} + +CHTTPSession::~CHTTPSession() +{ +} + +bool CHTTPSession::OpenURL(const tstring& rsURL) +{ + return m_pImpl->OpenURL(rsURL); +} + +bool CHTTPSession::ReadResponce(tstring& rsResponce)const +{ + return m_pImpl->ReadResponce(rsResponce); +} + +bool CHTTPSession::Init() +{ + return CImplMI::Init(); +} \ No newline at end of file diff --git a/protocols/Quotes/HTTPSession.h b/protocols/Quotes/HTTPSession.h new file mode 100644 index 0000000000..fe93a2dce5 --- /dev/null +++ b/protocols/Quotes/HTTPSession.h @@ -0,0 +1,27 @@ +#ifndef __8C9706FF_6B05_4d0d_85B8_5724E5DC0BA4_HTTPSession_h__ +#define __8C9706FF_6B05_4d0d_85B8_5724E5DC0BA4_HTTPSession_h__ + +#include + +class CHTTPSession +{ +public: + CHTTPSession(); + ~CHTTPSession(); + + static bool Init(); + + bool OpenURL(const tstring& rsURL); + bool ReadResponce(tstring& rsResponce)const; + + +public: + class CImpl; +private: + typedef boost::scoped_ptr TImpl; + +private: + TImpl m_pImpl; +}; + +#endif //__8C9706FF_6B05_4d0d_85B8_5724E5DC0BA4_HTTPSession_h__ diff --git a/protocols/Quotes/IHTMLEngine.h b/protocols/Quotes/IHTMLEngine.h new file mode 100644 index 0000000000..7df3074d3e --- /dev/null +++ b/protocols/Quotes/IHTMLEngine.h @@ -0,0 +1,18 @@ +#ifndef __85dbfa97_919b_4776_919c_7410a1c3d787_HTMLEngine_h__ +#define __85dbfa97_919b_4776_919c_7410a1c3d787_HTMLEngine_h__ + +class IHTMLParser; + +class IHTMLEngine +{ +public: + typedef boost::shared_ptr THTMLParserPtr; + +public: + IHTMLEngine(void){} + virtual ~IHTMLEngine() {} + + virtual THTMLParserPtr GetParserPtr()const = 0; +}; + +#endif //__85dbfa97_919b_4776_919c_7410a1c3d787_HTMLEngine_h__ diff --git a/protocols/Quotes/IHTMLParser.h b/protocols/Quotes/IHTMLParser.h new file mode 100644 index 0000000000..defc6f61cb --- /dev/null +++ b/protocols/Quotes/IHTMLParser.h @@ -0,0 +1,41 @@ +#ifndef __98ad6d6d_2a27_43fd_bf3e_c18416a45e54_IHTMLParser_h__ +#define __98ad6d6d_2a27_43fd_bf3e_c18416a45e54_IHTMLParser_h__ + +class IHTMLNode +{ +public: + typedef boost::shared_ptr THTMLNodePtr; + + enum EType + { + Table = 1, + TableRow, + TableColumn + }; + +public: + IHTMLNode() {} + virtual ~IHTMLNode() {} + + virtual size_t GetChildCount()const = 0; + virtual THTMLNodePtr GetChildPtr(size_t nIndex) = 0; + virtual bool Is(EType nType)const = 0; + + virtual THTMLNodePtr GetElementByID(const tstring& rsID)const = 0; + + virtual tstring GetAttribute(const tstring& rsAttrName)const = 0; + virtual tstring GetText()const = 0; +}; + +class IHTMLParser +{ +public: + typedef IHTMLNode::THTMLNodePtr THTMLNodePtr; +public: + IHTMLParser() {} + virtual ~IHTMLParser() {} + + virtual THTMLNodePtr ParseString(const tstring& rsHTML) = 0; +}; + +#endif //__98ad6d6d_2a27_43fd_bf3e_c18416a45e54_IHTMLParser_h__ diff --git a/protocols/Quotes/IQuotesProvider.h b/protocols/Quotes/IQuotesProvider.h new file mode 100644 index 0000000000..a03a2a9bcd --- /dev/null +++ b/protocols/Quotes/IQuotesProvider.h @@ -0,0 +1,41 @@ +#pragma once + +#ifndef __ac71e133_786c_41a7_ab07_625b76ff2a8c_QuotesProvider_h__ +#define __ac71e133_786c_41a7_ab07_625b76ff2a8c_QuotesProvider_h__ + +#include +#include + +class CQuotesProviderVisitor; + +class IQuotesProvider : private boost::noncopyable +{ +public: + struct CProviderInfo + { + tstring m_sName; + tstring m_sURL; + + }; + +public: + IQuotesProvider() {} + virtual ~IQuotesProvider() {} + + virtual bool Init() = 0; + virtual const CProviderInfo& GetInfo()const = 0; + + virtual void AddContact(HANDLE hContact) = 0; + virtual void DeleteContact(HANDLE hContact) = 0; + + virtual void ShowPropertyPage(WPARAM wp,OPTIONSDIALOGPAGE& odp) = 0; + virtual void RefreshAll() = 0; + virtual void RefreshContact(HANDLE hContact) = 0; + virtual void SetContactExtraIcon(HANDLE hContact)const = 0; + + virtual void Run() = 0; + + virtual void Accept(CQuotesProviderVisitor& visitor)const = 0; +}; + +#endif //__ac71e133_786c_41a7_ab07_625b76ff2a8c_QuotesProvider_h__ diff --git a/protocols/Quotes/IXMLEngine.h b/protocols/Quotes/IXMLEngine.h new file mode 100644 index 0000000000..910c3efea0 --- /dev/null +++ b/protocols/Quotes/IXMLEngine.h @@ -0,0 +1,43 @@ +#ifndef __f88e20d7_5e65_40fb_a7b5_7c7af1ee1c78_IXMLEngine_h__ +#define __f88e20d7_5e65_40fb_a7b5_7c7af1ee1c78_IXMLEngine_h__ + +class IXMLNode +{ +public: + typedef boost::shared_ptr TXMLNodePtr; + +public: + IXMLNode() {} + virtual ~IXMLNode() {} + + virtual size_t GetChildCount()const = 0; + virtual TXMLNodePtr GetChildNode(size_t nIndex)const = 0; + + virtual tstring GetText()const = 0; + virtual tstring GetName()const = 0; + + virtual bool AddChild(const TXMLNodePtr& pNode) = 0; + virtual bool AddAttribute(const tstring& rsName,const tstring& rsValue) = 0; + virtual tstring GetAttributeValue(const tstring& rsAttrName) = 0; + virtual void Write(tostream& o)const = 0; +}; + +inline tostream& operator<<(tostream& o,const IXMLNode& node) +{ + node.Write(o); + return o; +} + +class IXMLEngine +{ +public: + IXMLEngine() {} + + virtual ~IXMLEngine() {} + + virtual IXMLNode::TXMLNodePtr LoadFile(const tstring& rsFileName)const = 0; + virtual bool SaveFile(const tstring& rsFileName,const IXMLNode::TXMLNodePtr& pNode)const = 0; + virtual IXMLNode::TXMLNodePtr CreateNode(const tstring& rsName,const tstring& rsText)const = 0; +}; + +#endif //__f88e20d7_5e65_40fb_a7b5_7c7af1ee1c78_IXMLEngine_h__ diff --git a/protocols/Quotes/IconLib.cpp b/protocols/Quotes/IconLib.cpp new file mode 100644 index 0000000000..9702bfe3d8 --- /dev/null +++ b/protocols/Quotes/IconLib.cpp @@ -0,0 +1,106 @@ +#include "StdAfx.h" +#include "IconLib.h" +#include +#include "resource.h" +#include "EconomicRateInfo.h" +// #include +#include +#include +#pragma warning (disable:4996) +#include +#pragma warning (default:4996) +#include "ModuleInfo.h" + +// extern HMODULE g_hInstance; + +namespace +{ + struct CIconList + { + TCHAR* szDescr; + char* szName; + int defIconID; +// TCHAR* szSection; + HANDLE hIconLibItem; + }; + + CIconList iconList[] = + { + {_T("Protocol icon"),ICON_STR_MAIN,IDI_ICON_MAIN}, + {_T("Quote/Rate up"),ICON_STR_QUOTE_UP,IDI_ICON_UP}, + {_T("Quote/Rate down"),ICON_STR_QUOTE_DOWN,IDI_ICON_DOWN}, + {_T("Quote/Rate not changed"),ICON_STR_QUOTE_NOT_CHANGED,IDI_ICON_NOTCHANGED}, + {_T("Quote Section"),ICON_STR_SECTION,IDI_ICON_SECTION}, + {_T("Quote"),ICON_STR_QUOTE,IDI_ICON_QUOTE}, + {_T("Currency Converter"),ICON_STR_CURRENCY_CONVERTER,IDI_ICON_CURRENCY_CONVERTER}, + {_T("Refresh"),ICON_STR_REFRESH,IDI_ICON_REFRESH}, + {_T("Export"),ICON_STR_EXPORT,IDI_ICON_EXPORT}, + {_T("Swap button"),ICON_STR_SWAP,IDI_ICON_SWAP}, + {_T("Import"),ICON_STR_IMPORT,IDI_ICON_IMPORT}, + }; +} + +void Quotes_IconsInit() +{ + USES_CONVERSION; + + SKINICONDESC sid = {0}; + TCHAR szFile[MAX_PATH]; + ::GetModuleFileName(CModuleInfo::GetModuleHandle(), szFile, MAX_PATH); + + sid.cbSize = sizeof(SKINICONDESC); + sid.ptszDefaultFile = szFile; + sid.cx = sid.cy = 16; + sid.flags = SIDF_ALL_TCHAR; + sid.ptszSection = A2T(QUOTES_PROTOCOL_NAME); + +// TCHAR* szRootSection = TranslateTS(A2T(QUOTES_PROTOCOL_NAME)); + + for ( int i = 0; i < SIZEOF(iconList); i++ ) + { +// char szSettingName[100]; +// TCHAR szSectionName[100]; +// mir_snprintf( szSettingName, sizeof( szSettingName ),"%s_%s",QUOTES_PROTOCOL_NAME, iconList[i].szName ); +// { +// mir_sntprintf( szSectionName, SIZEOF( szSectionName ),_T("%s/%s"), TranslateT("Protocols"), szRootSection); +// sid.ptszSection = szSectionName; +// } + + std::string sName = Quotes_MakeIconName( iconList[i].szName); + sid.pszName = const_cast(sName.c_str()); + sid.ptszDescription = iconList[i].szDescr; + sid.iDefaultIndex = -iconList[i].defIconID; + iconList[i].hIconLibItem = reinterpret_cast(CallService(MS_SKIN2_ADDICON,0,reinterpret_cast(&sid))); + } +} + +std::string Quotes_MakeIconName(const char* name) +{ + assert(name); + //char szSettingName[100]; + //mir_snprintf(szSettingName,SIZEOF(szSettingName),"%s_%s",QUOTES_PROTOCOL_NAME,name); + std::string sName(QUOTES_PROTOCOL_NAME); + sName += "_"; + sName += name; + return sName; +} + +HICON Quotes_LoadIconEx(const char* name,bool bBig /*= false*/) +{ + std::string sIconName = Quotes_MakeIconName(name); + return reinterpret_cast(CallService( MS_SKIN2_GETICON,((bBig) ? 1 : 0),reinterpret_cast(sIconName.c_str()))); +} + +HANDLE Quotes_GetIconHandle(int iconId) +{ + for(int i=0;i < SIZEOF(iconList);i++) + { + if(iconList[i].defIconID == iconId) + { + return iconList[i].hIconLibItem; + } + } + + return NULL; +} + diff --git a/protocols/Quotes/IconLib.h b/protocols/Quotes/IconLib.h new file mode 100644 index 0000000000..29b0326622 --- /dev/null +++ b/protocols/Quotes/IconLib.h @@ -0,0 +1,21 @@ +#ifndef __8821d334_afac_439e_9a81_76318e1ac4ef_IconLib_h__ +#define __8821d334_afac_439e_9a81_76318e1ac4ef_IconLib_h__ + +#define ICON_STR_MAIN "main" +#define ICON_STR_QUOTE_UP "quote_up" +#define ICON_STR_QUOTE_DOWN "quote_down" +#define ICON_STR_QUOTE_NOT_CHANGED "quote_not_changed" +#define ICON_STR_SECTION "quote_section" +#define ICON_STR_QUOTE "quote" +#define ICON_STR_CURRENCY_CONVERTER "currency_converter" +#define ICON_STR_REFRESH "refresh" +#define ICON_STR_IMPORT "import" +#define ICON_STR_EXPORT "export" +#define ICON_STR_SWAP "swap" + +void Quotes_IconsInit(); +HICON Quotes_LoadIconEx(const char* name,bool bBig = false); +HANDLE Quotes_GetIconHandle(int iconId); +std::string Quotes_MakeIconName(const char* name); + +#endif //__8821d334_afac_439e_9a81_76318e1ac4ef_IconLib_h__ diff --git a/protocols/Quotes/ImportExport.cpp b/protocols/Quotes/ImportExport.cpp new file mode 100644 index 0000000000..2e38be0c0f --- /dev/null +++ b/protocols/Quotes/ImportExport.cpp @@ -0,0 +1,850 @@ +#include "StdAfx.h" +#include "ImportExport.h" +#include "ModuleInfo.h" +#include "QuotesProviders.h" +#ifdef TEST_IMPORT_EXPORT +#include "m_Quotes.h" +#endif +#include "IXMLEngine.h" +#include "Base64.h" +#include "EconomicRateInfo.h" +#include "IQuotesProvider.h" +#include "QuotesProviderVisitor.h" +#include "QuotesProviderDukasCopy.h" +#include "QuotesProviderGoogle.h" +#include "QuotesProviderGoogleFinance.h" +#include "Locale.h" + +namespace +{ + LPCTSTR g_pszXmlValue = _T("Value"); + LPCTSTR g_pszXmlName = _T("Name"); + LPCTSTR g_pszXmlSetting = _T("Setting"); + LPCTSTR g_pszXmlModule = _T("Module"); + LPCTSTR g_pszXmlContact = _T("Contact"); + LPCTSTR g_pszXmlContacts = _T("Contacts"); + LPCTSTR g_pszXmlType = _T("type"); + LPCTSTR g_pszXmlTypeByte = _T("byte"); + LPCTSTR g_pszXmlTypeWord = _T("word"); + LPCTSTR g_pszXmlTypeDword = _T("dword"); + LPCTSTR g_pszXmlTypeAsciiz = _T("asciiz"); + LPCTSTR g_pszXmlTypeWchar = _T("wchar"); + LPCTSTR g_pszXmlTypeUtf8 = _T("utf8"); + LPCTSTR g_pszXmlTypeBlob = _T("blob"); + + struct CEnumContext + { + CModuleInfo::TXMLEnginePtr m_pXmlEngine; + IXMLNode::TXMLNodePtr m_pNode; + HANDLE m_hContact; + LPCSTR m_pszModule; + }; + + struct mir_safety_dbvar + { + mir_safety_dbvar(DBVARIANT* p) : m_p(p){} + ~mir_safety_dbvar(){DBFreeVariant(m_p);} + DBVARIANT* m_p; + }; + + static int enum_contact_settings(const char* szSetting,LPARAM lp) + { +// USES_CONVERSION; + CEnumContext* ctx = reinterpret_cast(lp); + + DBVARIANT dbv; + DBCONTACTGETSETTING cgs; + + cgs.szModule = ctx->m_pszModule; + cgs.szSetting = szSetting; + cgs.pValue = &dbv; + if(0 == CallService(MS_DB_CONTACT_GETSETTING, + reinterpret_cast(ctx->m_hContact), + reinterpret_cast(&cgs))) + { + mir_safety_dbvar sdbvar(&dbv); + + tstring sType; + tostringstream sValue; + sValue.imbue(GetSystemLocale()); + + switch(dbv.type) + { + case DBVT_BYTE: + sValue << dbv.bVal; + sType = g_pszXmlTypeByte; + break; + case DBVT_WORD: + sValue << dbv.wVal; + sType = g_pszXmlTypeWord; + break; + case DBVT_DWORD: + sValue << dbv.dVal; + sType = g_pszXmlTypeDword; + break; + case DBVT_ASCIIZ: + sType = g_pszXmlTypeAsciiz; + if(dbv.pszVal) + { + sValue << dbv.pszVal; +// mir_safe_string mss(mir_utf8encode(dbv.pszVal)); +// if(mss.m_p) +// { +// sValue << mss.m_p; +// } + } + break; + case DBVT_WCHAR: + sType = g_pszXmlTypeWchar; + if(dbv.pwszVal) + { + sValue << dbv.pwszVal; +// mir_safe_string mss(mir_utf8encodeW(dbv.pwszVal)); +// if(mss.m_p) +// { +// sValue << mss.m_p; +// } + } + break; + case DBVT_UTF8: + sType = g_pszXmlTypeUtf8; + if(dbv.pszVal) + { + sValue << dbv.pszVal; + } + break; + case DBVT_BLOB: + sType = g_pszXmlTypeBlob; + if(dbv.pbVal) + { + std::vector buf; + if(true == base64::encode(dbv.pbVal,dbv.cpbVal,buf)) + { + buf.push_back('\0'); + sValue << &*buf.begin(); + } + } + break; + } + +// mir_safe_string mssSetting(mir_utf8encode(szSetting)); +// if(mssSetting.m_p) + { + IXMLNode::TXMLNodePtr pXmlSet = ctx->m_pXmlEngine->CreateNode(g_pszXmlSetting,tstring()); + if(pXmlSet) + { + IXMLNode::TXMLNodePtr pXmlName = ctx->m_pXmlEngine->CreateNode(g_pszXmlName,quotes_a2t(szSetting)); + + IXMLNode::TXMLNodePtr pXmlValue = ctx->m_pXmlEngine->CreateNode(g_pszXmlValue,sValue.str()); + if(pXmlName && pXmlValue) + { + pXmlValue->AddAttribute(g_pszXmlType,sType); + + pXmlSet->AddChild(pXmlName); + pXmlSet->AddChild(pXmlValue); + ctx->m_pNode->AddChild(pXmlSet); + } + } + } + } + + return 0; + } + + int EnumDbModules(const char* szModuleName, DWORD ofsModuleName, LPARAM lp) + { +// USES_CONVERSION; + CEnumContext* ctx = reinterpret_cast(lp); + IXMLNode::TXMLNodePtr pXml = ctx->m_pNode; + IXMLNode::TXMLNodePtr pModule = ctx->m_pXmlEngine->CreateNode(g_pszXmlModule,quotes_a2t(szModuleName)/*A2CT(szModuleName)*/); + if(pModule) + { + ctx->m_pszModule = szModuleName; + ctx->m_pNode = pModule; + + DBCONTACTENUMSETTINGS dbces; + dbces.pfnEnumProc = &enum_contact_settings; + dbces.szModule = szModuleName; + dbces.lParam = reinterpret_cast(ctx); + + CallService(MS_DB_CONTACT_ENUMSETTINGS,reinterpret_cast(ctx->m_hContact),reinterpret_cast(&dbces)); + if(pModule->GetChildCount() > 0) + { + pXml->AddChild(pModule); + } + ctx->m_pNode = pXml; + } + + return 0; + } + + IXMLNode::TXMLNodePtr export_contact(HANDLE hContact,const CModuleInfo::TXMLEnginePtr& pXmlEngine) + { + IXMLNode::TXMLNodePtr pNode = pXmlEngine->CreateNode(g_pszXmlContact,tstring()); + if(pNode) + { + CEnumContext ctx; + ctx.m_pXmlEngine = pXmlEngine; + ctx.m_pNode = pNode; + ctx.m_hContact = hContact; + + CallService(MS_DB_MODULES_ENUM,reinterpret_cast(&ctx),reinterpret_cast(EnumDbModules)); + } + return pNode; + } + + LPCTSTR prepare_filter(LPTSTR pszBuffer,size_t cBuffer) + { + LPTSTR p = pszBuffer; + LPCTSTR pszXml = TranslateT("Xml File (*.xml)"); + lstrcpyn(p,pszXml, (int)cBuffer); + size_t nLen = (int)lstrlen(pszXml)+1; + p+= nLen; + if(nLen < cBuffer) + { + lstrcpyn(p,_T("*.xml"),(int)(cBuffer-nLen)); + p+= 6; + nLen += 6; + } + + if(nLen < cBuffer) + { + LPCTSTR pszAll = TranslateT("All files (*.*)"); + lstrcpyn(p,pszAll,(int)(cBuffer-nLen)); + size_t n = lstrlen(pszAll)+1; + nLen += n; + p+= n; + } + + if(nLen < cBuffer) + { + lstrcpyn(p,_T("*.*"),(int)(cBuffer-nLen)); + p+= 4; + nLen += 4; + } + + if(nLen < cBuffer) + { + *p = _T('\0'); + } + + return pszBuffer; + } + + bool show_open_file_dialog(bool bOpen,tstring& rsFile) + { + TCHAR szBuffer[MAX_PATH]; + TCHAR szFilter[MAX_PATH]; + OPENFILENAME ofn; + memset(&ofn,0,sizeof(ofn)); + + ofn.lStructSize = sizeof(OPENFILENAME); + + ofn.hwndOwner = NULL; + ofn.lpstrFilter = prepare_filter(szFilter,MAX_PATH); + ofn.Flags = OFN_PATHMUSTEXIST|OFN_HIDEREADONLY|OFN_EXPLORER; + ofn.lpstrDefExt = _T("xml"); + if(true == bOpen) + { + ofn.Flags |= OFN_FILEMUSTEXIST; + } + else + { + ofn.Flags |= OFN_OVERWRITEPROMPT; + } + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFile = szBuffer; + ofn.lpstrFile[0] = _T('\0'); + + if(bOpen) + { + if(FALSE == GetOpenFileName(&ofn)) + { + return false; + } + } + else + { + if(FALSE == GetSaveFileName(&ofn)) + { + return false; + } + } + + rsFile = szBuffer; + + return true; + } +} + +INT_PTR Quotes_Export(WPARAM wp,LPARAM lp) +{ +// USES_CONVERSION; + + tstring sFileName; + const char* pszFile = reinterpret_cast(lp); + if(NULL == pszFile) + { + if(false == show_open_file_dialog(false,sFileName)) + { + return -1; + } + } + else + { + sFileName = quotes_a2t(pszFile);//A2CT(pszFile); + } + + CModuleInfo::TXMLEnginePtr pXmlEngine = CModuleInfo::GetInstance().GetXMLEnginePtr(); + CModuleInfo::TQuotesProvidersPtr pProviders = CModuleInfo::GetInstance().GetQuoteProvidersPtr(); + IXMLNode::TXMLNodePtr pRoot = pXmlEngine->CreateNode(g_pszXmlContacts,tstring()); + HANDLE hContact = reinterpret_cast(wp); + if(hContact) + { + CQuotesProviders::TQuotesProviderPtr pProvider = pProviders->GetContactProviderPtr(hContact); + if(pProvider) + { + IXMLNode::TXMLNodePtr pNode = export_contact(hContact,pXmlEngine); + if(pNode) + { + pRoot->AddChild(pNode); + } + } + } + else + { + for(hContact = reinterpret_cast(CallService(MS_DB_CONTACT_FINDFIRST,0,0));hContact;hContact = reinterpret_cast(CallService(MS_DB_CONTACT_FINDNEXT,reinterpret_cast(hContact),0))) + { + CQuotesProviders::TQuotesProviderPtr pProvider = pProviders->GetContactProviderPtr(hContact); + if(pProvider) + { + IXMLNode::TXMLNodePtr pNode = export_contact(hContact,pXmlEngine); + if(pNode) + { + pRoot->AddChild(pNode); + } + } + } + } + + return ((true == pXmlEngine->SaveFile(sFileName,pRoot)) ? 0 : 1); +} + +namespace +{ + bool set_contact_settings(HANDLE hContact,DBCONTACTWRITESETTING& dbs) + { + assert(DBVT_DELETED != dbs.value.type); + return (0 == CallService(MS_DB_CONTACT_WRITESETTING,reinterpret_cast(hContact), + reinterpret_cast(&dbs))); + } + + bool handle_module(HANDLE hContact,const IXMLNode::TXMLNodePtr& pXmlModule,UINT nFlags) + { +// USES_CONVERSION; + + size_t cCreatedRecords = 0; + tstring sModuleName = pXmlModule->GetText(); + if(false == sModuleName.empty()) + { + DBCONTACTWRITESETTING dbs; + std::string s = quotes_t2a(sModuleName.c_str()); + dbs.szModule = s.c_str();//T2CA(sModuleName.c_str()); + + bool bCListModule = 0 == quotes_stricmp(sModuleName.c_str(),_T("CList")); + + size_t cChild = pXmlModule->GetChildCount(); + for(size_t i = 0;i < cChild;++i) + { + IXMLNode::TXMLNodePtr pSetting = pXmlModule->GetChildNode(i); + tstring sSetting = pSetting->GetName(); + if(0 == quotes_stricmp(g_pszXmlSetting,sSetting.c_str())) + { + size_t cSetChild = pSetting->GetChildCount(); + if(cSetChild >= 2) + { + tstring sName; + tstring sValue; + tstring sType; + for(size_t i = 0;i < cSetChild;++i) + { + IXMLNode::TXMLNodePtr pNode = pSetting->GetChildNode(i); + tstring sNode = pNode->GetName(); + if(0 == quotes_stricmp(g_pszXmlName,sNode.c_str())) + { + sName = pNode->GetText(); + } + else if(0 == quotes_stricmp(g_pszXmlValue,sNode.c_str())) + { + sValue = pNode->GetText(); + sType = pNode->GetAttributeValue(g_pszXmlType); + } + } + + if ((false == sName.empty()) && (false == sType.empty())) + { + std::string s = quotes_t2a(sName.c_str()); + dbs.szSetting = s.c_str();//T2CA(sName.c_str()); + if(0 == quotes_stricmp(g_pszXmlTypeByte,sType.c_str())) + { + tistringstream in(sValue.c_str()); + in.imbue(GetSystemLocale()); + dbs.value.cVal = in.get(); + if(in.good() && in.eof()) + { + dbs.value.type = DBVT_BYTE; + if(set_contact_settings(hContact,dbs)) + { + ++cCreatedRecords; + } + } + } + else if(0 == quotes_stricmp(g_pszXmlTypeWord,sType.c_str())) + { + tistringstream in(sValue.c_str()); + in.imbue(GetSystemLocale()); + in >> dbs.value.wVal; + if(in.good() || in.eof()) + { + dbs.value.type = DBVT_WORD; + if(set_contact_settings(hContact,dbs)) + { + ++cCreatedRecords; + } + } + } + else if(0 == quotes_stricmp(g_pszXmlTypeDword,sType.c_str())) + { + tistringstream in(sValue.c_str()); + in.imbue(GetSystemLocale()); + in >> dbs.value.dVal; + if(in.good() || in.eof()) + { + dbs.value.type = DBVT_DWORD; + if(set_contact_settings(hContact,dbs)) + { + ++cCreatedRecords; + } + } + } + else if(0 == quotes_stricmp(g_pszXmlTypeAsciiz,sType.c_str())) + { + CT2A v(sValue.c_str()); + dbs.value.pszVal = v; + dbs.value.type = DBVT_ASCIIZ; + if(set_contact_settings(hContact,dbs)) + { + ++cCreatedRecords; + } + } + else if(0 == quotes_stricmp(g_pszXmlTypeUtf8,sType.c_str())) + { + dbs.value.pszVal = mir_utf8encodeT(sValue.c_str()); + dbs.value.type = DBVT_UTF8; + if(set_contact_settings(hContact,dbs)) + { + ++cCreatedRecords; + } + mir_free(dbs.value.pszVal); + } + else if(0 == quotes_stricmp(g_pszXmlTypeWchar,sType.c_str())) + { + CT2W val(sValue.c_str()); + dbs.value.pwszVal = val; + dbs.value.type = DBVT_WCHAR; + if(set_contact_settings(hContact,dbs)) + { + ++cCreatedRecords; + } + mir_free(dbs.value.pwszVal); + } + else if(0 == quotes_stricmp(g_pszXmlTypeBlob,sType.c_str())) + { + std::vector blob_buf; + std::string p = quotes_t2a(sValue.c_str());//T2A(sValue.c_str()); + if(true == base64::decode(p.c_str(),lstrlenA(p.c_str()),blob_buf)) + { + dbs.value.pbVal = &*blob_buf.begin(); + dbs.value.cpbVal = (WORD)blob_buf.size(); + dbs.value.type = DBVT_BLOB; + + if(set_contact_settings(hContact,dbs)) + { + ++cCreatedRecords; + } + } + } + + if ((true == bCListModule) && (0 == quotes_stricmp(sName.c_str(),_T("Group")))) + { + CallService(MS_CLIST_GROUPCREATE,NULL,reinterpret_cast(sValue.c_str())); + } + } + } + } + } + } + + return true; + } + + size_t count_contacts(const IXMLNode::TXMLNodePtr& pXmlRoot,bool bInContactsGroup) + { + size_t cContacts = 0; + size_t cChild = pXmlRoot->GetChildCount(); + for(size_t i = 0;i < cChild;++i) + { + IXMLNode::TXMLNodePtr pNode = pXmlRoot->GetChildNode(i); + tstring sName = pNode->GetName(); + if(false == bInContactsGroup) + { + if(0 == quotes_stricmp(g_pszXmlContacts,sName.c_str())) + { + cContacts += count_contacts(pNode,true); + } + else + { + cContacts += count_contacts(pNode,false); + } + } + else + { + if(0 == quotes_stricmp(g_pszXmlContact,sName.c_str())) + { + ++ cContacts; + } + } + } + + return cContacts; + } + + struct CImportContext + { + CImportContext(size_t cTotalContacts) : m_cTotalContacts(cTotalContacts),m_cHandledContacts(0),m_nFlags(0){} + + size_t m_cTotalContacts; + size_t m_cHandledContacts; + UINT m_nFlags; + }; + + struct CContactState + { + CContactState() : m_hContact(NULL),m_bNewContact(false){} + HANDLE m_hContact; + CQuotesProviders::TQuotesProviderPtr m_pProvider; + bool m_bNewContact; + }; + + IXMLNode::TXMLNodePtr find_quotes_module(const IXMLNode::TXMLNodePtr& pXmlContact) + { +// USES_CONVERSION; +// LPCTSTR pszQuotes = A2T(QUOTES_MODULE_NAME); + static const tstring g_sQuotes = quotes_a2t(QUOTES_MODULE_NAME); + size_t cChild = pXmlContact->GetChildCount(); + for(size_t i = 0;i < cChild;++i) + { + IXMLNode::TXMLNodePtr pNode = pXmlContact->GetChildNode(i); + tstring sName = pNode->GetName(); + if ((0 == quotes_stricmp(g_pszXmlModule,sName.c_str())) + && (0 == quotes_stricmp(g_sQuotes.c_str(),pNode->GetText().c_str()))) + { + return pNode; + } + } + + return IXMLNode::TXMLNodePtr(); + } + + typedef std::pair TNameValue;//first is name,second is value + TNameValue parse_setting_node(const IXMLNode::TXMLNodePtr& pXmlSetting) + { + assert(pXmlSetting); + + tstring sName,sValue; + size_t cSettingChildItems = pXmlSetting->GetChildCount(); + for(size_t j = 0;j < cSettingChildItems;++j) + { + IXMLNode::TXMLNodePtr pXMLSetChild = pXmlSetting->GetChildNode(j); + if(pXMLSetChild) + { + if(0 == quotes_stricmp(g_pszXmlName,pXMLSetChild->GetName().c_str())) + { + sName = pXMLSetChild->GetText(); + } + else if(0 == quotes_stricmp(g_pszXmlValue,pXMLSetChild->GetName().c_str())) + { + sValue = pXMLSetChild->GetText(); + } + } + } + + return std::make_pair(sName,sValue); + } + + CQuotesProviders::TQuotesProviderPtr find_provider(const IXMLNode::TXMLNodePtr& pXmlQuotesModule) + { +// USES_CONVERSION; + static const tstring g_sQuotesProvider = quotes_a2t(DB_STR_QUOTE_PROVIDER);//A2CT(DB_STR_QUOTE_PROVIDER); + size_t cChild = pXmlQuotesModule->GetChildCount(); + for(size_t i = 0;i < cChild;++i) + { + IXMLNode::TXMLNodePtr pXMLSetting = pXmlQuotesModule->GetChildNode(i); + if(pXMLSetting && (0 == quotes_stricmp(g_pszXmlSetting,pXMLSetting->GetName().c_str()))) + { + TNameValue Item = parse_setting_node(pXMLSetting); + if ((0 == quotes_stricmp(g_sQuotesProvider.c_str(),Item.first.c_str())) && (false == Item.second.empty())) + { + return CModuleInfo::GetInstance().GetQuoteProvidersPtr()->FindProvider(Item.second); + } + } + } + + return CQuotesProviders::TQuotesProviderPtr(); + } + + bool get_contact_state(const IXMLNode::TXMLNodePtr& pXmlContact,CContactState& cst) + { + class visitor : public CQuotesProviderVisitor + { + public: + visitor(const IXMLNode::TXMLNodePtr& pXmlQuotes) + : m_hContact(NULL),m_pXmlQuotes(pXmlQuotes){} + + HANDLE GetContact()const{return m_hContact;} + + private: + virtual void Visit(const CQuotesProviderDukasCopy& rProvider) + { + tstring sQuoteID = GetXMLNodeValue(DB_STR_QUOTE_ID); + if(false == sQuoteID.empty()) + { + m_hContact = rProvider.GetContactByQuoteID(sQuoteID); + } + } + + virtual void Visit(const CQuotesProviderGoogle& rProvider) + { +// USES_CONVERSION; + static const tstring g_sFromID = quotes_a2t(DB_STR_FROM_ID);//A2CT(DB_STR_FROM_ID); + static const tstring g_sToID = quotes_a2t(DB_STR_TO_ID);//A2CT(DB_STR_TO_ID); + + tstring sFromID; + tstring sToID; + size_t cChild = m_pXmlQuotes->GetChildCount(); + for(size_t i = 0;i < cChild;++i) + { + IXMLNode::TXMLNodePtr pNode = m_pXmlQuotes->GetChildNode(i); + if(pNode && (0 == quotes_stricmp(g_pszXmlSetting, pNode->GetName().c_str()))) + { + TNameValue Item = parse_setting_node(pNode); + if(0 == quotes_stricmp(g_sFromID.c_str(),Item.first.c_str())) + { + sFromID = Item.second; + } + else if(0 == quotes_stricmp(g_sToID.c_str(),Item.first.c_str())) + { + sToID = Item.second; + } + } + } + + if ((false == sFromID.empty()) && (false == sToID.empty())) + { + m_hContact = rProvider.GetContactByID(sFromID,sToID); + } + } + + virtual void Visit(const CQuotesProviderFinance& rProvider) + { + tstring sQuoteID = GetXMLNodeValue(DB_STR_QUOTE_ID); + if(false == sQuoteID.empty()) + { + m_hContact = rProvider.GetContactByQuoteID(sQuoteID); + } + } + + tstring GetXMLNodeValue(const char* pszXMLNodeName)const + { +// USES_CONVERSION; + tstring sXMLNodeName = quotes_a2t(pszXMLNodeName);//A2CT(pszXMLNodeName); + + tstring sValue; + size_t cChild = m_pXmlQuotes->GetChildCount(); + for(size_t i = 0;i < cChild;++i) + { + IXMLNode::TXMLNodePtr pNode = m_pXmlQuotes->GetChildNode(i); + if(pNode && (0 == quotes_stricmp(g_pszXmlSetting, pNode->GetName().c_str()))) + { + TNameValue Item = parse_setting_node(pNode); + if(0 == quotes_stricmp(Item.first.c_str(),sXMLNodeName.c_str())) + { + sValue = Item.second; + break; + } + } + } + + return sValue; + } + + private: + HANDLE m_hContact; + IXMLNode::TXMLNodePtr m_pXmlQuotes; + }; + + IXMLNode::TXMLNodePtr pXmlQuotes = find_quotes_module(pXmlContact); + if(pXmlQuotes) + { + cst.m_pProvider = find_provider(pXmlQuotes); + if(cst.m_pProvider) + { + visitor vs(pXmlQuotes); + cst.m_pProvider->Accept(vs); + cst.m_hContact = vs.GetContact(); + return true; + } + } + + return false; + } + + bool import_contact(const IXMLNode::TXMLNodePtr& pXmlContact,CImportContext& impctx) + { + ++ impctx.m_cHandledContacts; + + CContactState cst; + bool bResult = get_contact_state(pXmlContact,cst); + if(bResult) + { + if(NULL == cst.m_hContact) + { + cst.m_hContact = reinterpret_cast(CallService(MS_DB_CONTACT_ADD,0,0)); + cst.m_bNewContact = true; + } + else if(impctx.m_nFlags"ES_IMPORT_SKIP_EXISTING_CONTACTS) + { + return true; + } + + if(cst.m_hContact) + { + size_t cChild = pXmlContact->GetChildCount(); + for(size_t i = 0;i < cChild && bResult;++i) + { + IXMLNode::TXMLNodePtr pNode = pXmlContact->GetChildNode(i); + tstring sName = pNode->GetName(); + if(0 == quotes_stricmp(g_pszXmlModule,sName.c_str())) + { + bResult &= handle_module(cst.m_hContact,pNode,impctx.m_nFlags); + } + } + + if(cst.m_bNewContact && bResult) + { + cst.m_pProvider->AddContact(cst.m_hContact); + cst.m_pProvider->RefreshContact(cst.m_hContact); + } + } + else + { + bResult = false; + } + } + + return bResult; + + } + + size_t import_contacts(const IXMLNode::TXMLNodePtr& pXmlContacts,CImportContext& impctx) + { + size_t cContacts = 0; + size_t cChild = pXmlContacts->GetChildCount(); + for(size_t i = 0;i < cChild;++i) + { + IXMLNode::TXMLNodePtr pNode = pXmlContacts->GetChildNode(i); + tstring sName = pNode->GetName(); + if(0 == quotes_stricmp(g_pszXmlContact,sName.c_str())) + { + if(true == import_contact(pNode,impctx)) + { + ++ cContacts; + } + } + } + + return cContacts; + + } + + size_t handle_contacts_node(const IXMLNode::TXMLNodePtr& pXmlRoot,CImportContext& impctx) + { + size_t cContacts = 0; + size_t cChild = pXmlRoot->GetChildCount(); + for(size_t i = 0;i < cChild;++i) + { + IXMLNode::TXMLNodePtr pNode = pXmlRoot->GetChildNode(i); + tstring sName = pNode->GetName(); + if(0 == quotes_stricmp(g_pszXmlContacts,sName.c_str())) + { + cContacts += import_contacts(pNode,impctx); + } + else + { + cContacts += handle_contacts_node(pNode,impctx); + } + } + + return cContacts; + + } + + bool do_import(const IXMLNode::TXMLNodePtr& pXmlRoot,UINT nFlags) + { + CImportContext imctx(count_contacts(pXmlRoot,false)); + imctx.m_cHandledContacts = 0; + imctx.m_nFlags = nFlags; + + return (handle_contacts_node(pXmlRoot,imctx) > 0); + } +} + +INT_PTR Quotes_Import(WPARAM wp,LPARAM lp) +{ +// USES_CONVERSION; + + tstring sFileName; + const char* pszFile = reinterpret_cast(lp); + if(NULL == pszFile) + { + if(false == show_open_file_dialog(true,sFileName)) + { + return -1; + } + } + else + { + sFileName = quotes_a2t(pszFile);//A2CT(pszFile); + } + CModuleInfo::TXMLEnginePtr pXmlEngine = CModuleInfo::GetInstance().GetXMLEnginePtr(); + IXMLNode::TXMLNodePtr pXmlRoot = pXmlEngine->LoadFile(sFileName); + if(pXmlRoot) + { + return ((true == do_import(pXmlRoot,wp)) ? 0 : 1); + } + + return 1; +} + +#ifdef TEST_IMPORT_EXPORT +INT_PTR QuotesMenu_ImportAll(WPARAM wp,LPARAM lp) +{ + return CallService(MS_QUOTES_IMPORT,0,0); +} + +INT_PTR QuotesMenu_ExportAll(WPARAM wp,LPARAM lp) +{ + return CallService(MS_QUOTES_EXPORT,0,0); +} +#endif + diff --git a/protocols/Quotes/ImportExport.h b/protocols/Quotes/ImportExport.h new file mode 100644 index 0000000000..da2053e9a3 --- /dev/null +++ b/protocols/Quotes/ImportExport.h @@ -0,0 +1,11 @@ +#ifndef __F86374E6_713C_4600_85FB_903A5CDF7251_IMPORT_EXPORT_H__ +#define __F86374E6_713C_4600_85FB_903A5CDF7251_IMPORT_EXPORT_H__ + +INT_PTR Quotes_Export(WPARAM wp,LPARAM lp); +INT_PTR Quotes_Import(WPARAM wp,LPARAM lp); + +#ifdef TEST_IMPORT_EXPORT +INT_PTR QuotesMenu_ImportAll(WPARAM wp,LPARAM lp); +INT_PTR QuotesMenu_ExportAll(WPARAM wp,LPARAM lp); +#endif +#endif //__F86374E6_713C_4600_85FB_903A5CDF7251_IMPORT_EXPORT_H__ diff --git a/protocols/Quotes/IsWithinAccuracy.h b/protocols/Quotes/IsWithinAccuracy.h new file mode 100644 index 0000000000..5e39281719 --- /dev/null +++ b/protocols/Quotes/IsWithinAccuracy.h @@ -0,0 +1,15 @@ +#ifndef __C8C6FB80_D66B_4382_8FAB_E92C83F77BB8_IsWithinAcuracy_h__ +#define __C8C6FB80_D66B_4382_8FAB_E92C83F77BB8_IsWithinAcuracy_h__ + +inline bool IsWithinAccuracy(double dValue1, double dValue2, double dAccuracy = 1e-4) +{ + double dDifference = dValue1 - dValue2 ; + + if ((-dAccuracy <= dDifference) && (dDifference <= dAccuracy)) + return true ; + else + return false ; +} + + +#endif //__C8C6FB80_D66B_4382_8FAB_E92C83F77BB8_IsWithinAcuracy_h__ diff --git a/protocols/Quotes/LightMutex.cpp b/protocols/Quotes/LightMutex.cpp new file mode 100644 index 0000000000..8d14e8e7bb --- /dev/null +++ b/protocols/Quotes/LightMutex.cpp @@ -0,0 +1,22 @@ +#include "StdAfx.h" +#include "LightMutex.h" + +CLightMutex::CLightMutex() +{ + InitializeCriticalSection(&m_cs); +} + +CLightMutex::~CLightMutex() +{ + ::DeleteCriticalSection(&m_cs); +} + +void CLightMutex::Lock() +{ + ::EnterCriticalSection(&m_cs); +} + +void CLightMutex::Unlock() +{ + ::LeaveCriticalSection(&m_cs); +} diff --git a/protocols/Quotes/LightMutex.h b/protocols/Quotes/LightMutex.h new file mode 100644 index 0000000000..e8c7363ba1 --- /dev/null +++ b/protocols/Quotes/LightMutex.h @@ -0,0 +1,34 @@ +#ifndef __a33da2bb_d4fe4aa7_aaf5_f9f8c3156ce6_LightMutex_h__ +#define __a33da2bb_d4fe4aa7_aaf5_f9f8c3156ce6_LightMutex_h__ + +class CLightMutex +{ +public: + CLightMutex(); + ~CLightMutex(); + + void Lock(); + void Unlock(); + +private: + CRITICAL_SECTION m_cs; +}; + +template class CGuard +{ +public: + CGuard(TObject& obj) : m_obj(obj) + { + m_obj.Lock(); + } + + ~CGuard() + { + m_obj.Unlock(); + } + +private: + TObject& m_obj; +}; + +#endif //__a33da2bb_d4fe4aa7_aaf5_f9f8c3156ce6_LightMutex_h__ diff --git a/protocols/Quotes/Locale.cpp b/protocols/Quotes/Locale.cpp new file mode 100644 index 0000000000..c01f67148a --- /dev/null +++ b/protocols/Quotes/Locale.cpp @@ -0,0 +1,75 @@ +#include "StdAfx.h" +#include "Locale.h" + +const std::locale GetSystemLocale() +{ + return std::locale(""); +} + +namespace +{ + tstring get_int_registry_value(LPCTSTR pszValueName) + { + tstring sResult; + HKEY hKey = NULL; + LONG lResult = ::RegOpenKeyEx(HKEY_CURRENT_USER, + _T("Control Panel\\International"),0,KEY_QUERY_VALUE,&hKey); + if ((ERROR_SUCCESS == lResult) && (NULL != hKey)) + { + DWORD dwType = 0; + DWORD dwSize = 0; + lResult = ::RegQueryValueEx(hKey,pszValueName,nullptr,&dwType,nullptr,&dwSize); + if ((ERROR_SUCCESS == lResult) && ((REG_SZ == dwType) || (REG_EXPAND_SZ == dwType))) + { + std::vector aBuffer(dwSize); + lResult = ::RegQueryValueEx(hKey,pszValueName,nullptr,nullptr,reinterpret_cast(&*aBuffer.begin()),&dwSize); + if(ERROR_SUCCESS == lResult) + { + std::copy(aBuffer.begin(),aBuffer.end(),std::back_inserter(sResult)); + } + } + } + + if(NULL != hKey) + { + lResult = ::RegCloseKey(hKey); + assert(ERROR_SUCCESS == lResult); + } + + return sResult; + } + + tstring date_win_2_boost(const tstring& sFrmt) + { + tstring sResult(_T("%d.%m.%y")); + if(sFrmt == _T("dd/MM/yy")) + { + sResult = _T("%d/%m/%y"); + } + else if(sFrmt == _T("yyyy-MM-dd")) + { + sResult = _T("%y-%m-%d"); + } + return sResult; + } + + tstring time_win_2_boost(const tstring& sFrmt) + { + tstring sResult = _T("%H:%M:%S"); + if(sFrmt == _T("H:mm") || sFrmt == _T("HH:mm")) + { + sResult = _T("%H:%M"); + } + return sResult; + } +} + +tstring Quotes_GetDateFormat(bool bShort) +{ + return date_win_2_boost(get_int_registry_value(bShort ? _T("sShortDate") : _T("sLongDate"))); +} + +tstring Quotes_GetTimeFormat(bool bShort) +{ + return time_win_2_boost(get_int_registry_value(bShort ? _T("sShortTime") : _T("sTimeFormat"))); +} \ No newline at end of file diff --git a/protocols/Quotes/Locale.h b/protocols/Quotes/Locale.h new file mode 100644 index 0000000000..92d3a56ed4 --- /dev/null +++ b/protocols/Quotes/Locale.h @@ -0,0 +1,9 @@ +#ifndef __11f7afd0_5a66_4029_8bf3_e3c66346b349_Locale_h_ +#define __11f7afd0_5a66_4029_8bf3_e3c66346b349_Locale_h_ + +// std::string GetLocaleInfoString(LCTYPE LCType,LCID Locale = LOCALE_USER_DEFAULT); +const std::locale GetSystemLocale(); +tstring Quotes_GetDateFormat(bool bShort); +tstring Quotes_GetTimeFormat(bool bShort); + +#endif //__11f7afd0_5a66_4029_8bf3_e3c66346b349_Locale_h_ diff --git a/protocols/Quotes/Log.cpp b/protocols/Quotes/Log.cpp new file mode 100644 index 0000000000..d692763bad --- /dev/null +++ b/protocols/Quotes/Log.cpp @@ -0,0 +1,56 @@ +#include "StdAfx.h" +#include "Log.h" +#include "LightMutex.h" +#include "EconomicRateInfo.h" +#include "CreateFilePath.h" + +namespace +{ + CLightMutex g_Mutex; + + tstring get_log_file_name() + { + return CreateFilePath(_T("Quotes.log")); + } + + bool is_log_enabled() + { +#ifdef _DEBUG + return true; +#else + return (1 == DBGetContactSettingByte(NULL,QUOTES_PROTOCOL_NAME,DB_STR_ENABLE_LOG,false)); +#endif + } + + void do_log(const tstring& rsFileName,ESeverity nSeverity,const tstring& rsMsg) + { + CGuard guard(g_Mutex); + tofstream file(rsFileName.c_str(),std::ios::ate|std::ios::app); + if(file.good()) + { + TCHAR szTime[20]; +// TCHAR sz[10000+1]; + _tstrtime_s(szTime); + file << szTime << _T(" ================================>\n") << rsMsg << _T("\n\n"); + +// size_t cBytes = rsMsg.size(); +// const TCHAR* p = rsMsg.c_str(); +// for(size_t c = 0;c < cBytes;c += 10000,p+=10000) +// { +// _tcsncpy_s(sz,p,10000); +// file << sz; +// } +// +// file << "\n\n"; + } + } +} + +void LogIt(ESeverity nSeverity,const tstring& rsMsg) +{ + if(is_log_enabled()) + { + tstring sFileName = get_log_file_name(); + do_log(sFileName,nSeverity,rsMsg); + } +} diff --git a/protocols/Quotes/Log.h b/protocols/Quotes/Log.h new file mode 100644 index 0000000000..274fcfec06 --- /dev/null +++ b/protocols/Quotes/Log.h @@ -0,0 +1,13 @@ +#ifndef __653719be_16d6_4058_8555_8aa7d5404214_OutputDlg_h__ +#define __653719be_16d6_4058_8555_8aa7d5404214_OutputDlg_h__ + +enum ESeverity +{ + Info, + Warning, + Error +}; + +void LogIt(ESeverity nSeverity,const tstring& rsMsg); + +#endif //__653719be_16d6_4058_8555_8aa7d5404214_OutputDlg_h__ diff --git a/protocols/Quotes/ModuleInfo.cpp b/protocols/Quotes/ModuleInfo.cpp new file mode 100644 index 0000000000..69a835409e --- /dev/null +++ b/protocols/Quotes/ModuleInfo.cpp @@ -0,0 +1,150 @@ +#include "StdAfx.h" +#include "ModuleInfo.h" +#include "QuotesProviders.h" +#include "HTMLParserMS.h" +#include "LightMutex.h" +#include "WinCtrlHelper.h" +#include "EconomicRateInfo.h" +#include "XMLEngineMI.h" + +namespace +{ + HINSTANCE g_hInstance = NULL; + CModuleInfo::TXMLEnginePtr g_pXMLEngine; + CModuleInfo::THTMLEnginePtr g_pHTMLEngine; + CLightMutex g_lmParsers; +} + +CModuleInfo::CModuleInfo() + : m_bExtendedStatusInfo(1 == DBGetContactSettingByte(NULL,QUOTES_MODULE_NAME,"ExtendedStatus",false)) +{ +} + +CModuleInfo::~CModuleInfo() +{ +} + +CModuleInfo& CModuleInfo::GetInstance() +{ + static CModuleInfo mi; + return mi; +} + +HANDLE CModuleInfo::GetWindowList(const std::string& rsKey,bool bAllocateIfNonExist /*= true*/) +{ + HANDLE hResult = NULL; + THandles::const_iterator i = m_ahWindowLists.find(rsKey); + if(i != m_ahWindowLists.end()) + { + hResult = i->second; + } + else if(bAllocateIfNonExist) + { + hResult = reinterpret_cast(CallService(MS_UTILS_ALLOCWINDOWLIST,0,0)); + if(hResult) + { + m_ahWindowLists.insert(std::make_pair(rsKey,hResult)); + } + } + + return hResult; +} + +void CModuleInfo::OnMirandaShutdown() +{ + BOOST_FOREACH(THandles::value_type p,m_ahWindowLists) + { + WindowList_Broadcast(p.second,WM_CLOSE,0,0); + } +} + +void CModuleInfo::SetModuleHandle(HINSTANCE hInstance) +{ + assert(NULL == g_hInstance); + assert(NULL != hInstance); + + g_hInstance = hInstance; +} + +HINSTANCE CModuleInfo::GetModuleHandle() +{ + assert(NULL != g_hInstance); + return g_hInstance; +} + +CModuleInfo::TQuotesProvidersPtr CModuleInfo::GetQuoteProvidersPtr() +{ + static TQuotesProvidersPtr pProviders(new CQuotesProviders); + return pProviders; +} + +CModuleInfo::TXMLEnginePtr CModuleInfo::GetXMLEnginePtr() +{ + if (!g_pXMLEngine) + { + CGuard cs(g_lmParsers); + if (!g_pXMLEngine) + { + mir_getXI(&xi); + g_pXMLEngine = TXMLEnginePtr(new CXMLEngineMI); + } + } + + return g_pXMLEngine; +} + +// void CModuleInfo::SetXMLEnginePtr(TXMLEnginePtr pEngine) +// { +// g_pXMLEngine = pEngine; +// } + +CModuleInfo::THTMLEnginePtr CModuleInfo::GetHTMLEngine() +{ + if (!g_pHTMLEngine) + { + CGuard cs(g_lmParsers); + if (!g_pHTMLEngine) + { + g_pHTMLEngine = THTMLEnginePtr(new CHTMLEngineMS); + } + } + + return g_pHTMLEngine; +} + +void CModuleInfo::SetHTMLEngine(THTMLEnginePtr pEngine) +{ + g_pHTMLEngine = pEngine; +} + +bool CModuleInfo::Verify() +{ + INITCOMMONCONTROLSEX icc = {0}; + icc.dwSize = sizeof(icc); + icc.dwICC = ICC_WIN95_CLASSES|ICC_LINK_CLASS; + if(FALSE == ::InitCommonControlsEx(&icc)) + { + return false; + } + + if (!GetXMLEnginePtr()) + { + Quotes_MessageBox(NULL,TranslateT("Miranda could not load Quotes plugin. XML parser is missing."),MB_OK|MB_ICONERROR); + return false; + } + + if (!g_pHTMLEngine && (false == CHTMLParserMS::IsInstalled())) + { + Quotes_MessageBox(NULL, + TranslateT("Miranda could not load Quotes plugin. Microsoft HTML parser is missing."), + MB_YESNO|MB_ICONQUESTION); + return false; + } + + return true; +} + +bool CModuleInfo::GetExtendedStatusFlag()const +{ + return m_bExtendedStatusInfo; +} diff --git a/protocols/Quotes/ModuleInfo.h b/protocols/Quotes/ModuleInfo.h new file mode 100644 index 0000000000..5dcf7e5de6 --- /dev/null +++ b/protocols/Quotes/ModuleInfo.h @@ -0,0 +1,46 @@ +#ifndef __d0f22b66_3135_4bbe_bee5_a31ea631ce58_ModuleInfo__ +#define __d0f22b66_3135_4bbe_bee5_a31ea631ce58_ModuleInfo__ + +class CQuotesProviders; +class IXMLEngine; +class IHTMLEngine; +// class IHTMLParser; + +class CModuleInfo +{ +public: + typedef boost::shared_ptr TQuotesProvidersPtr; + typedef boost::shared_ptr TXMLEnginePtr; + typedef boost::shared_ptr THTMLEnginePtr; + +private: + CModuleInfo(); + ~CModuleInfo(void); + +public: + static CModuleInfo& GetInstance(); + + void OnMirandaShutdown(); + HANDLE GetWindowList(const std::string& rsKey,bool bAllocateIfNonExist = true); + bool GetExtendedStatusFlag()const; + + static void SetModuleHandle(HINSTANCE hInstance); + static HINSTANCE GetModuleHandle(); + + static bool Verify(); + + static TQuotesProvidersPtr GetQuoteProvidersPtr(); + + static TXMLEnginePtr GetXMLEnginePtr(); +// static void SetXMLEnginePtr(TXMLEnginePtr pEngine); + + static THTMLEnginePtr GetHTMLEngine(); + static void SetHTMLEngine(THTMLEnginePtr pEngine); + +private: + typedef std::map THandles; + THandles m_ahWindowLists; + bool m_bExtendedStatusInfo; +}; + +#endif //__d0f22b66_3135_4bbe_bee5_a31ea631ce58_ModuleInfo__ diff --git a/protocols/Quotes/OptionDukasCopy.cpp b/protocols/Quotes/OptionDukasCopy.cpp new file mode 100644 index 0000000000..1aef56b824 --- /dev/null +++ b/protocols/Quotes/OptionDukasCopy.cpp @@ -0,0 +1,414 @@ +#include "StdAfx.h" +#include "OptionDukasCopy.h" +#include "IconLib.h" +#include "ModuleInfo.h" +#include "QuotesProviders.h" +#include "QuotesProviderDukasCopy.h" +#include "resource.h" +#include "EconomicRateInfo.h" +#include "CommonOptionDlg.h" + +// extern HANDLE g_hEventSettingsCnanged; + +namespace +{ + enum ETreeCheckBoxState + { + // tree check box state + TCBS_NOSTATEBOX = 0, + TCBS_UNCHECKED = 1, + TCBS_CHECKED = 2, + }; + + enum + { + TREE_VIEW_CHECK_STATE_CHANGE = WM_USER + 100, + IMAGE_INDEX_SECTION = 0, + IMAGE_INDEX_QUOTE = 1 + }; + + // typedef CQuotesProviders::TQuotesProviders TQuotesProviders; + // typedef CQuotesProviders::TQuotesProviderPtr TQuotesProviderPtr; + + HTREEITEM tree_insert_item(HWND hwndTree, + const tstring& rsName, + HTREEITEM htiParent, + int nImage, + LPARAM lp = 0) + { +// USES_CONVERSION; + TVINSERTSTRUCT tvi; + ZeroMemory(&tvi,sizeof(tvi)); + + tvi.hParent = htiParent; + tvi.hInsertAfter = TVI_LAST; + tvi.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE; + +// CA2T name(rsName.c_str()); + + tvi.item.pszText = const_cast(rsName.c_str());//name; + tvi.item.lParam = lp; + tvi.item.iImage = nImage; + tvi.item.iSelectedImage = nImage; + return TreeView_InsertItem(hwndTree,&tvi); + } + + bool add_quote_to_tree(const CQuotesProviderDukasCopy::CQuote& q,HWND hwndTree,HTREEITEM htiParent,const CQuotesProviderDukasCopy* pQuotesProvier) + { + bool bChecked = pQuotesProvier->IsQuoteWatched(q); + HTREEITEM hti = tree_insert_item(hwndTree,((false == q.GetName().empty()) ? q.GetName() : q.GetSymbol()),htiParent,IMAGE_INDEX_QUOTE); + if(hti && bChecked) + { + HWND hDlg = ::GetParent(hwndTree); + assert(::IsWindow(hDlg)); + ::PostMessage(hDlg,TREE_VIEW_CHECK_STATE_CHANGE,MAKEWPARAM(0,TCBS_CHECKED),reinterpret_cast(hti)); + } + + return (NULL != hti && bChecked); + } + + void add_section_to_tree(const CQuotesProviderDukasCopy::CQuoteSection& qs, + HWND hwndTree, + HTREEITEM htiParent, + const CQuotesProviderDukasCopy* pQuotesProvier, + bool& rbIsChecked, + bool& rbIsExpended, + bool bExpand = false) + { + rbIsChecked = false; + rbIsExpended = false; + HTREEITEM hti = tree_insert_item(hwndTree,qs.GetName(),htiParent,IMAGE_INDEX_SECTION); + + size_t cCheckedItems = 0; + size_t cSection = qs.GetSectionCount(); + for(size_t i = 0;i < cSection;++i) + { + bool bIsChecked = false; + bool bIsExpanded = false; + CQuotesProviderDukasCopy::CQuoteSection other = qs.GetSection(i); + add_section_to_tree(other,hwndTree,hti,pQuotesProvier,bIsChecked,bIsExpanded); + + if(bIsChecked) + { + ++cCheckedItems; + } + + if(bIsExpanded) + { + bExpand = true; + } + } + + size_t cQuotes = qs.GetQuoteCount(); + for(size_t i = 0;i < cQuotes;++i) + { + CQuotesProviderDukasCopy::CQuote q = qs.GetQuote(i); + if(true == add_quote_to_tree(q,hwndTree,hti,pQuotesProvier)) + { + ++ cCheckedItems; + } + } + + if(bExpand || cCheckedItems > 0) + { + rbIsExpended = true; + TreeView_Expand(hwndTree,hti,TVE_EXPAND); + } + + if(cCheckedItems == (cSection+cQuotes)) + { + rbIsChecked = true; + HWND hDlg = ::GetParent(hwndTree); + assert(::IsWindow(hDlg)); + ::PostMessage(hDlg,TREE_VIEW_CHECK_STATE_CHANGE,MAKEWPARAM(0,TCBS_CHECKED),reinterpret_cast(hti)); + } + } + + void add_provider_to_tree(const CQuotesProviderDukasCopy* pQuotesProvier,HWND hwndTree) + { + CQuotesProviderDukasCopy::CQuoteSection qs = pQuotesProvier->GetQuotes(); + bool bIsChecked = false; + bool bIsExpanded = false; + add_section_to_tree(qs,hwndTree,TVI_ROOT,pQuotesProvier,bIsChecked,bIsExpanded,true); + } + + inline HTREEITEM tree_get_child_item(HWND hwndTree,HTREEITEM hti) + { + return reinterpret_cast(::SendMessage(hwndTree, TVM_GETNEXTITEM, TVGN_CHILD,reinterpret_cast(hti))); + } + + inline HTREEITEM tree_get_next_sibling_item(HWND hwndTree,HTREEITEM hti) + { + return reinterpret_cast(::SendMessage(hwndTree, TVM_GETNEXTITEM, TVGN_NEXT,reinterpret_cast(hti))); + } + + inline ETreeCheckBoxState tree_get_state_image(HWND hwndTree,HTREEITEM hti) + { + TVITEM tvi; + tvi.hItem = hti; + tvi.mask = TVIF_STATE|TVIF_HANDLE; + tvi.stateMask = TVIS_STATEIMAGEMASK; + if(TRUE == ::SendMessage(hwndTree,TVM_GETITEM,0,reinterpret_cast(&tvi))) + { + UINT nState = (tvi.state >> 12); + return static_cast(nState); + } + else + { + return TCBS_UNCHECKED; + } + } + + void tree_do_set_item_state(HWND hwndTree,HTREEITEM hti,ETreeCheckBoxState nState) + { + TVITEM tvi; + ZeroMemory(&tvi,sizeof(tvi)); + + tvi.mask = TVIF_STATE|TVIF_HANDLE; + tvi.hItem = hti; + + tvi.stateMask = TVIS_STATEIMAGEMASK; + tvi.state = INDEXTOSTATEIMAGEMASK(nState); + + ::SendMessage(hwndTree,TVM_SETITEM,0,reinterpret_cast(&tvi)); + } + + void tree_set_item_state(HWND hwndTree,HTREEITEM hti,ETreeCheckBoxState nState,bool bRecursively) + { + if(true == bRecursively) + { + for(hti = tree_get_child_item(hwndTree,hti);hti;hti = tree_get_next_sibling_item(hwndTree,hti)) + { + tree_do_set_item_state(hwndTree,hti,nState); + tree_set_item_state(hwndTree,hti,nState,bRecursively); + } + } + else + { + tree_do_set_item_state(hwndTree,hti,nState); + } + } + + void save_quote_selection(HWND hwndTree,HTREEITEM h,const CQuotesProviderDukasCopy::CQuote& q,CQuotesProviderDukasCopy* pQuotesProvier) + { + ETreeCheckBoxState nState = tree_get_state_image(hwndTree,h); + pQuotesProvier->WatchForQuote(q,(TCBS_CHECKED == nState)); + } + + void recursive_save_quote_section_selection(HWND hwndTree,HTREEITEM h,const CQuotesProviderDukasCopy::CQuoteSection& qs,CQuotesProviderDukasCopy* pQuotesProvier) + { + size_t cSection = qs.GetSectionCount(); + h = tree_get_child_item(hwndTree,h); + for(size_t i = 0;h && (i < cSection);++i,h = tree_get_next_sibling_item(hwndTree,h)) + { + CQuotesProviderDukasCopy::CQuoteSection other = qs.GetSection(i); + recursive_save_quote_section_selection(hwndTree,h,other,pQuotesProvier); + } + + size_t cQuotes = qs.GetQuoteCount(); + for(size_t i = 0;h && (i < cQuotes);++i,h = tree_get_next_sibling_item(hwndTree,h)) + { + CQuotesProviderDukasCopy::CQuote q = qs.GetQuote(i); + save_quote_selection(hwndTree,h,q,pQuotesProvier); + } + } + + void recursive_save_selection(HWND hwndTree,CQuotesProviderDukasCopy* pQuotesProvider) + { + // CModuleInfo::TQuotesProvidersPtr& pProviders = CModuleInfo::GetQuoteProvidersPtr(); + // const TQuotesProviders& rapQuotesProviders = pProviders->GetProviders(); + // + // TQuotesProviders::const_iterator i = rapQuotesProviders.begin(); + // TQuotesProviders::const_iterator iE = rapQuotesProviders.end(); + // for(HTREEITEM h = tree_get_child_item(hwndTree,TVI_ROOT);h && (i!=iE);++i,h = tree_get_next_sibling_item(hwndTree,h)) + // { + // const TQuotesProviderPtr& pQuotesProvier = *i; + CQuotesProviderDukasCopy::CQuoteSection qs = pQuotesProvider->GetQuotes(); + recursive_save_quote_section_selection(hwndTree,tree_get_child_item(hwndTree,TVI_ROOT),qs,pQuotesProvider); + // } + } + + class CImageListWrapper + { + public: + CImageListWrapper() + : m_hImageList(ImageList_Create(::GetSystemMetrics(SM_CXSMICON), + ::GetSystemMetrics(SM_CYSMICON), + ILC_COLOR24|ILC_MASK,2,0)) + { + if(m_hImageList) + { + ImageList_AddIcon(m_hImageList,Quotes_LoadIconEx(ICON_STR_SECTION)); + ImageList_AddIcon(m_hImageList,Quotes_LoadIconEx(ICON_STR_QUOTE)); + } + } + + ~CImageListWrapper() + { + if(m_hImageList) + { + ImageList_Destroy(m_hImageList); + } + } + + operator HIMAGELIST()const + { + return m_hImageList; + } + + private: + HIMAGELIST m_hImageList; + }; + + HIMAGELIST get_image_list() + { + static CImageListWrapper wrapper; + return wrapper; + } + + CQuotesProviderDukasCopy* get_dukas_copy_provider() + { + CModuleInfo::TQuotesProvidersPtr& pProviders = CModuleInfo::GetQuoteProvidersPtr(); + const CQuotesProviders::TQuotesProviders& rapQuotesProviders = pProviders->GetProviders(); + for(CQuotesProviders::TQuotesProviders::const_iterator i = rapQuotesProviders.begin();i != rapQuotesProviders.end();++i) + { + const CQuotesProviders::TQuotesProviderPtr& pProvider = *i; + CQuotesProviderDukasCopy* pDukas = dynamic_cast(pProvider.get()); + if(pDukas) + { + return pDukas; + } + } + + assert(!"We should never get here!"); + return NULL; + } + + INT_PTR CALLBACK EconomicRatesDlgProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) + { + CCommonDlgProcData d(get_dukas_copy_provider()); + CommonOptionDlgProc(hdlg,message,wParam,lParam,d); + + switch(message) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hdlg); + + HWND hwndTree = ::GetDlgItem(hdlg,IDC_TREE_ECONOMIC_RATES); + HIMAGELIST hImage = get_image_list(); + if(hImage) + { + TreeView_SetImageList(hwndTree,hImage,TVSIL_NORMAL); + } + + const CQuotesProviderDukasCopy* pDukasProvider = get_dukas_copy_provider(); + if(pDukasProvider) + { + add_provider_to_tree(pDukasProvider,hwndTree); + } + // Window_SetIcon_IcoLib(hdlg, SKINICON_OTHER_MIRANDA); + } + return TRUE; + + case WM_NOTIFY: + { + LPNMHDR pNMHDR = reinterpret_cast(lParam); + switch(pNMHDR->code) + { + case TVN_KEYDOWN: + if(IDC_TREE_ECONOMIC_RATES == wParam) + { + LPNMTVKEYDOWN pKeyDown = reinterpret_cast(lParam); + if(VK_SPACE == pKeyDown->wVKey) + { + HTREEITEM hti = TreeView_GetSelection(::GetDlgItem(hdlg,IDC_TREE_ECONOMIC_RATES)); + ::PostMessage(hdlg,TREE_VIEW_CHECK_STATE_CHANGE,MAKEWPARAM(1,0),reinterpret_cast(hti)); + PropSheet_Changed(::GetParent(hdlg),hdlg); + } + } + break; + case NM_CLICK: + if(IDC_TREE_ECONOMIC_RATES == wParam) + { + DWORD pos = ::GetMessagePos(); + + HWND hwndTree = ::GetDlgItem(hdlg,IDC_TREE_ECONOMIC_RATES); + + TVHITTESTINFO tvhti; + tvhti.pt.x = LOWORD(pos); + tvhti.pt.y = HIWORD(pos); + ::ScreenToClient(hwndTree,&(tvhti.pt)); + + HTREEITEM hti = reinterpret_cast(::SendMessage(hwndTree,TVM_HITTEST,0,reinterpret_cast(&tvhti))); + if(hti && (tvhti.flags&TVHT_ONITEMSTATEICON)) + { + ::PostMessage(hdlg,TREE_VIEW_CHECK_STATE_CHANGE,MAKEWPARAM(1,0),reinterpret_cast(hti)); + PropSheet_Changed(::GetParent(hdlg),hdlg); + } + } + break; + case PSN_APPLY: + { + CQuotesProviderDukasCopy* pDukasProvider = get_dukas_copy_provider(); + if(pDukasProvider) + { + recursive_save_selection(::GetDlgItem(hdlg,IDC_TREE_ECONOMIC_RATES),pDukasProvider); + pDukasProvider->RefreshAll(); + } + } + break; + } + } + return TRUE; + + case TREE_VIEW_CHECK_STATE_CHANGE: + { + HWND hwndTree = ::GetDlgItem(hdlg,IDC_TREE_ECONOMIC_RATES); + HTREEITEM hti = reinterpret_cast(lParam); + + ETreeCheckBoxState nState; + + bool bRecursively = 1 == LOWORD(wParam); + if(bRecursively) + { + nState = tree_get_state_image(hwndTree,hti); + } + else + { + nState = static_cast(HIWORD(wParam)); + } + + tree_set_item_state(hwndTree,hti,nState,bRecursively); + } + break; + // case WM_CLOSE: + // DestroyWindow(hdlg); + // break; + // case WM_DESTROY: + // g_hwndEconomicRates = NULL; + // break; + } + + return FALSE; + } +} + +void ShowDukasCopyPropPage(CQuotesProviderDukasCopy* pProvider,WPARAM wp,OPTIONSDIALOGPAGE& odp) +{ + const IQuotesProvider::CProviderInfo& pi = pProvider->GetInfo(); + + odp.pszTemplate = MAKEINTRESOURCEA(IDD_DIALOG_ECONOMIC_RATES); + odp.pfnDlgProc = EconomicRatesDlgProc; +// #if MIRANDA_VER >= 0x0600 + //odp.ptszTab = TranslateTS(const_cast(pi.m_sName.c_str())); + odp.ptszTab = const_cast(pi.m_sName.c_str()); +// #else +// tostringstream o; +// o << TranslateTS(QUOTES_PROTOCOL_NAME) << _T(" - ") << TranslateTS(pi.m_sName.c_str()); +// tstring sTitle = o.str(); +// odp.ptszTitle = TranslateTS(const_cast(sTitle.c_str())); +// #endif + + CallService(MS_OPT_ADDPAGE,wp,reinterpret_cast(&odp)); +} diff --git a/protocols/Quotes/OptionDukasCopy.h b/protocols/Quotes/OptionDukasCopy.h new file mode 100644 index 0000000000..0674119e83 --- /dev/null +++ b/protocols/Quotes/OptionDukasCopy.h @@ -0,0 +1,8 @@ +#ifndef __60a5d152_872c_4bc4_b9ae_cd561d110b2dOptionDukasCopy_h__ +#define __60a5d152_872c_4bc4_b9ae_cd561d110b2dOptionDukasCopy_h__ + +class CQuotesProviderDukasCopy; + +void ShowDukasCopyPropPage(CQuotesProviderDukasCopy* pProvider,WPARAM wp,OPTIONSDIALOGPAGE& odp); + +#endif //__60a5d152_872c_4bc4_b9ae_cd561d110b2dOptionDukasCopy_h__ diff --git a/protocols/Quotes/QuoteChart.cpp b/protocols/Quotes/QuoteChart.cpp new file mode 100644 index 0000000000..3746540d23 --- /dev/null +++ b/protocols/Quotes/QuoteChart.cpp @@ -0,0 +1,408 @@ +#include "StdAfx.h" +#include "QuoteChart.h" + +#ifdef CHART_IMPLEMENT + +// #include "QuotesProviderDukasCopy.h" +// #include "QuotesProviders.h" +#include "ModuleInfo.h" +#include "EconomicRateInfo.h" +// #include "WinCtrlHelper.h" +#include "resource.h" +#include "DBUtils.h" +#include "Locale.h" +#include "SettingsDlg.h" +#include "Chart.h" +#include "WinCtrlHelper.h" + +#define WINDOW_PREFIX "Quotes Chart_" +#define CHART_CTRL_CLASS _T("DioksinChart") + +namespace +{ + struct CTimeConvert + { + static double Convert(const boost::posix_time::time_duration& v) + { + return boost::numeric_cast(v.ticks()); + } + + static tstring ToString(const boost::posix_time::ptime& v) + { + tostringstream k; + k.imbue(std::locale(GetSystemLocale(),new ttime_facet(_T("%d/%m/%y %H:%M:%S")))); + k << v; + return k.str(); + } + }; + + typedef CChart TChart; + + inline TChart* get_chart_ptr(HWND hWnd) + { + TChart* pChart = reinterpret_cast(GetWindowLongPtr(hWnd,GWLP_USERDATA)); + return pChart; + } + + bool read_log_file(HANDLE hContact,TChart& rChart) + { + tstring sLogFileName = GetContactLogFileName(hContact); + if(false == sLogFileName.empty()) + { + std::locale loc(GetSystemLocale(),new ttime_input_facet(_T("%d.%m.%y %H:%M:%S"))); + boost::posix_time::ptime oDateTime; + double dRate; + + tifstream file(sLogFileName.c_str()); + file.imbue(loc); + while((false == file.fail()) && (false == file.eof())) + { + tstring sLine; + std::getline(file,sLine); + + tistringstream line(sLine); + line.imbue(loc); + + tstring sName; + std::getline(line,sName,_T('\t')); + line >> oDateTime >> dRate; + if ((false == line.fail()) && (true == line.eof())) + { + rChart.AddValue(oDateTime,dRate); + } + } + + return true; + } + return false; + } + + + enum + { + ID_CHART = 0x1969, + + srcLogFile = 0, + srcHistory = 1, + + filterAll = 0, + filterLastDay = 1, + filterLastWeek = 2, + filterLastMonth = 3, + filterLastYear = 4, + filterUserDefined = 5, + + CHART_SET_SOURCE = WM_USER + 1, + CHART_SET_FILTER = WM_USER + 2, + }; + + LRESULT CALLBACK ChartWndProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) + { + switch(msg) + { + case WM_CREATE: + { + CREATESTRUCT* pCS = reinterpret_cast(lp); + HANDLE hContact = reinterpret_cast(pCS->lpCreateParams); + + TChart* pChart = new TChart; + read_log_file(hContact,*pChart); + + ::SetWindowLongPtr(hWnd,GWLP_USERDATA,reinterpret_cast(pChart)); + } + return 0; + + case CHART_SET_SOURCE: + break; + + case CHART_SET_FILTER: + break; + + case WM_SIZE: + { + TChart* pChart = get_chart_ptr(hWnd); + pChart->SetRect(0,0,LOWORD(lp),HIWORD(lp)); + } + return 0; + + case WM_PAINT: + if(TRUE == ::GetUpdateRect(hWnd,NULL,FALSE)) + { + PAINTSTRUCT ps; + HDC hdc = ::BeginPaint(hWnd,&ps); + if(NULL != hdc) + { + TChart* pChart = get_chart_ptr(hWnd); + pChart->Draw(hdc); + ::EndPaint(hWnd,&ps); + } + } + + return 0; + case WM_DESTROY: + { + TChart* pChart = get_chart_ptr(hWnd); + ::SetWindowLongPtr(hWnd,GWLP_USERDATA,NULL); + delete pChart; + } + break; + } + + return ::DefWindowProc(hWnd,msg,wp,lp); + } + + void register_chart_control() + { + static bool g_bRegister = false; + if(g_bRegister) + { + return; + } + + WNDCLASS wc; + + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = ChartWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = CModuleInfo::GetInstance().GetModuleHandle(); + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL,IDC_ARROW); + wc.hbrBackground = static_cast(::GetStockObject(WHITE_BRUSH)); + wc.lpszMenuName = NULL; + wc.lpszClassName = CHART_CTRL_CLASS; + + if(RegisterClass(&wc)) + { + g_bRegister = true; + } + } + + + bool screen_2_client(HWND hWnd,LPRECT pRect) + { + POINT pt; + pt.x = pRect->left; + pt.y = pRect->top; + bool bResult = TRUE == ::ScreenToClient(hWnd,&pt); + pRect->left = pt.x; + pRect->top = pt.y; + pt.x = pRect->right; + pt.y = pRect->bottom; + bResult |= TRUE == ::ScreenToClient(hWnd,&pt); + pRect->right = pt.x; + pRect->bottom = pt.y; + return bResult; + } + + inline HANDLE get_contact(HWND hWnd) + { + HANDLE hContact = reinterpret_cast(GetWindowLongPtr(hWnd,GWLP_USERDATA)); + return hContact; + } + + void update_filter_controls(HWND hDlg) + { + int nSel = ::SendDlgItemMessage(hDlg,IDC_COMBO_FILTER,CB_GETCURSEL,0,0); + + ::ShowWindow(::GetDlgItem(hDlg,IDC_EDIT_FROM),(filterUserDefined == nSel) ? SW_SHOW : SW_HIDE); + ::ShowWindow(::GetDlgItem(hDlg,IDC_EDIT_TO),(filterUserDefined == nSel) ? SW_SHOW : SW_HIDE); + } + + INT_PTR CALLBACK ChartDlgProc(HWND hDlg,UINT msg,WPARAM wp,LPARAM lp) + { + switch(msg) + { + case WM_INITDIALOG: + { + HANDLE hContact = reinterpret_cast(lp); + + TranslateDialogDefault(hDlg); + + tstring sName = get_window_text(hDlg); + sName += _T(" - "); + sName += GetContactName(hContact); + ::SetWindowText(hDlg,sName.c_str()); + + HANDLE hWL = CModuleInfo::GetInstance().GetWindowList(WINDOW_PREFIX,false); + assert(hWL); + WindowList_Add(hWL,hDlg,hContact); + + ::SetWindowLongPtr(hDlg,GWLP_USERDATA,reinterpret_cast(hContact)); + + static LPCTSTR szSources[] = {_T("Log File"),_T("Miranda's History")}; + static LPCTSTR szFilters[] = {_T("All"),_T("Last Day"),_T("Last Week"),_T("Last Month"),_T("Last Year"),_T("User-Defined")}; + + for(int i = 0;i < sizeof(szSources)/sizeof(szSources[0]);++i) + { + LPCTSTR p = TranslateTS(szSources[i]); + ::SendDlgItemMessage(hDlg,IDC_COMBO_DATA_SOURCE,CB_INSERTSTRING,-1,reinterpret_cast(p)); + } + + int nSel = DBGetContactSettingByte(hContact,QUOTES_PROTOCOL_NAME,"Chart_Source",srcLogFile); + ::SendDlgItemMessage(hDlg,IDC_COMBO_DATA_SOURCE,CB_SETCURSEL,nSel,0); + + for(int i = 0;i < sizeof(szFilters)/sizeof(szFilters[0]);++i) + { + LPCTSTR p = TranslateTS(szSources[i]); + ::SendDlgItemMessage(hDlg,IDC_COMBO_FILTER,CB_INSERTSTRING,-1,reinterpret_cast(szFilters[i])); + } + + nSel = DBGetContactSettingByte(hContact,QUOTES_PROTOCOL_NAME,"Chart_Filter",filterAll); + ::SendDlgItemMessage(hDlg,IDC_COMBO_FILTER,CB_SETCURSEL,nSel,0); + + update_filter_controls(hDlg); + + register_chart_control(); + HWND hwndImage = ::GetDlgItem(hDlg,IDC_STATIC_IMAGE); + RECT rcImage; + ::GetWindowRect(hwndImage,&rcImage); + screen_2_client(hDlg,&rcImage); + //BOOL bResult = ShowWindow(hwndImage,SW_HIDE); + //assert(bResult); + + HWND hChart = ::CreateWindowEx(0L,CHART_CTRL_CLASS,NULL,WS_CHILDWINDOW|WS_VISIBLE, + rcImage.left,rcImage.top,rcImage.right-rcImage.left,rcImage.bottom-rcImage.top, + hDlg,reinterpret_cast(ID_CHART),CModuleInfo::GetInstance().GetModuleHandle(),hContact); + assert(NULL != hChart); + + Utils_RestoreWindowPosition(hDlg,hContact,QUOTES_MODULE_NAME,WINDOW_PREFIX); + BOOL bResult = ::ShowWindow(hDlg,SW_SHOW); + assert(bResult); + } + return (TRUE); + case WM_CLOSE: + { + HANDLE hContact = get_contact(hDlg); + SetWindowLongPtr(hDlg,GWLP_USERDATA,0); + +// save_options(hDlg,hContact); + + HANDLE hWL = CModuleInfo::GetInstance().GetWindowList(WINDOW_PREFIX,false); + assert(hWL); + WindowList_Remove(hWL,hDlg); + Utils_SaveWindowPosition(hDlg,hContact,QUOTES_MODULE_NAME,WINDOW_PREFIX); + + HWND hwndChart = ::GetDlgItem(hDlg,ID_CHART); + BOOL bResult = ::DestroyWindow(hwndChart); + assert(bResult); + + ::EndDialog(hDlg,0); + } + return (TRUE); + case WM_COMMAND: + switch(LOWORD(wp)) + { + case IDCANCEL: + { + SendMessage(hDlg, WM_CLOSE, 0, 0); + } + return (TRUE); + case IDC_COMBO_FILTER: + if(CBN_SELCHANGE == HIWORD(wp)) + { + ::SendDlgItemMessage(hDlg,ID_CHART,CHART_SET_FILTER,::SendDlgItemMessage(hDlg,IDC_COMBO_FILTER,CB_GETCURSEL,0,0),0); + update_filter_controls(hDlg); + } + break; + case IDC_COMBO_DATA_SOURCE: + if(CBN_SELCHANGE == HIWORD(wp)) + { + ::SendDlgItemMessage(hDlg,ID_CHART,CHART_SET_SOURCE,::SendDlgItemMessage(hDlg,IDC_COMBO_DATA_SOURCE,CB_GETCURSEL,0,0),0); + } + break; + } + return (FALSE); + case WM_NOTIFY: + { + LPNMHDR pNMHDR = reinterpret_cast(lp); + switch(pNMHDR->code) + { + case NM_CLICK: + if(IDC_SYSLINK_PROVIDER == wp) + { + PNMLINK pNMLink = reinterpret_cast(pNMHDR); + ::ShellExecute(hDlg,_T("open"),pNMLink->item.szUrl,NULL,NULL,SW_SHOWNORMAL); + } + break; + } + } + break; +// case WM_ERASEBKGND: +// { +// HDC hdc = reinterpret_cast(wp); +// TChart* pChart = get_chart_ptr(hDlg); +// pChart->DrawBackground(hdc); +// return TRUE; +// } +// break; + case WM_SIZE: + { + enum{ INDENT = 7}; + + int nWidth = LOWORD(lp); + int nHeight = HIWORD(lp); + + HWND hwndChart = GetDlgItem(hDlg,ID_CHART); + HWND hwndLink = GetDlgItem(hDlg,IDC_SYSLINK_PROVIDER); + HWND hwndClose = GetDlgItem(hDlg,IDCANCEL); + + RECT rcDlg; + GetClientRect(hDlg,&rcDlg); + + RECT rcChart; + GetWindowRect(hwndChart,&rcChart); + screen_2_client(hDlg,&rcChart); + + RECT rcLink; + GetWindowRect(hwndLink,&rcLink); + screen_2_client(hDlg,&rcLink); + SetWindowPos(hwndLink,NULL,rcDlg.left + INDENT, + rcDlg.bottom-INDENT-(rcLink.bottom-rcLink.top), + 0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); + + RECT rcClose; + GetWindowRect(hwndClose,&rcClose); + screen_2_client(hDlg,&rcClose); + SetWindowPos(hwndClose,NULL,rcDlg.right - INDENT - (rcClose.right-rcClose.left), + rcDlg.bottom-INDENT-(rcClose.bottom-rcClose.top), + 0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); + + SetWindowPos(hwndChart,NULL,rcDlg.left + INDENT, + rcChart.top, + (nWidth-INDENT*2), + nHeight-(rcClose.bottom-rcClose.top)-INDENT*2-rcChart.top, + SWP_NOZORDER|SWP_NOACTIVATE); + + } + break; + } + return (FALSE); + } +} + +INT_PTR QuotesMenu_Chart(WPARAM wp,LPARAM lp) +{ + HANDLE hContact = reinterpret_cast(wp); + if(NULL == hContact) + { + return 0; + } + + HANDLE hWL = CModuleInfo::GetInstance().GetWindowList(WINDOW_PREFIX,true); + assert(hWL); + HWND hWnd = WindowList_Find(hWL,hContact); + if(NULL != hWnd) + { + SetForegroundWindow(hWnd); + SetFocus(hWnd); + } + else + { + CreateDialogParam(CModuleInfo::GetModuleHandle(), MAKEINTRESOURCE(IDD_DUKASCOPY_CHART), NULL, ChartDlgProc, reinterpret_cast(hContact)); + } + + return 0; +} + +#endif //CHART_IMPLEMENT diff --git a/protocols/Quotes/QuoteChart.h b/protocols/Quotes/QuoteChart.h new file mode 100644 index 0000000000..1b40f428b5 --- /dev/null +++ b/protocols/Quotes/QuoteChart.h @@ -0,0 +1,12 @@ +#ifndef __39BE8775_A837_494f_925C_0ABF7910F238_QuoteChart_h__ +#define __39BE8775_A837_494f_925C_0ABF7910F238_QuoteChart_h__ + +#ifdef CHART_IMPLEMENT + +#pragma once + +INT_PTR QuotesMenu_Chart(WPARAM wp,LPARAM lp); + +#endif + +#endif //__39BE8775_A837_494f_925C_0ABF7910F238_QuoteChart_h__ diff --git a/protocols/Quotes/QuoteInfoDlg.cpp b/protocols/Quotes/QuoteInfoDlg.cpp new file mode 100644 index 0000000000..88253ec45d --- /dev/null +++ b/protocols/Quotes/QuoteInfoDlg.cpp @@ -0,0 +1,353 @@ +#include "StdAfx.h" +#include "QuoteInfoDlg.h" +#include "EconomicRateInfo.h" +#include "resource.h" +#include "ModuleInfo.h" +#include "QuotesProviders.h" +#include "IconLib.h" +#include "DBUtils.h" +#include "IQuotesProvider.h" +#include "Locale.h" +#include "SettingsDlg.h" + +// extern HANDLE g_hWindowListEditSettings; +extern HGENMENU g_hMenuEditSettings; +extern HGENMENU g_hMenuOpenLogFile; +#ifdef CHART_IMPLEMENT +extern HGENMENU g_hMenuChart; +#endif +extern HGENMENU g_hMenuRefresh; + + +#define WINDOW_PREFIX_INFO "Quote Info" + + +namespace +{ + HANDLE g_hContact; + + inline bool IsMyContact(HANDLE hContact) + { + CQuotesProviders::TQuotesProviderPtr pProvider = CModuleInfo::GetQuoteProvidersPtr()->GetContactProviderPtr(hContact); + return (NULL != pProvider); + } + + inline HANDLE get_contact(HWND hWnd) + { + return reinterpret_cast(GetWindowLongPtr(hWnd,GWLP_USERDATA)); + } + + + bool get_fetch_time(time_t& rTime,HANDLE hContact) + { + DBVARIANT dbv; + DBCONTACTGETSETTING cgs; + + cgs.szModule=QUOTES_PROTOCOL_NAME; + cgs.szSetting=DB_STR_QUOTE_FETCH_TIME; + cgs.pValue=&dbv; + if(CallService(MS_DB_CONTACT_GETSETTING,reinterpret_cast(hContact),reinterpret_cast(&cgs)) + || (DBVT_DWORD != dbv.type)) + { + return false; + } + + rTime = dbv.dVal; + return true; + } + + INT_PTR CALLBACK QuoteInfoDlgProcImpl(HANDLE hContact,HWND hdlg,UINT msg,WPARAM wParam,LPARAM lParam) + { + switch(msg) + { + case WM_INITDIALOG: + { + assert(hContact); + + TranslateDialogDefault(hdlg); + + tstring sDescription = GetContactName(hContact); + ::SetDlgItemText(hdlg,IDC_STATIC_QUOTE_NAME,sDescription.c_str()); + + double dRate = 0.0; + if(true == Quotes_DBReadDouble(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_PREV_VALUE,dRate)) + { + tostringstream o; + o.imbue(GetSystemLocale()); + o << dRate; + + ::SetDlgItemText(hdlg,IDC_EDIT_PREVIOUS_RATE,o.str().c_str()); + } + + dRate = 0.0; + if(true == Quotes_DBReadDouble(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_CURR_VALUE,dRate)) + { + tostringstream o; + o.imbue(GetSystemLocale()); + o << dRate; + + ::SetDlgItemText(hdlg,IDC_EDIT_RATE,o.str().c_str()); + } + + time_t nFetchTime; + if(true == get_fetch_time(nFetchTime,hContact)) + { + TCHAR szTime[50]; + if(0 == _tctime_s(szTime,50,&nFetchTime)) + { + szTime[::_tcslen(szTime)-1] = _T('\0'); + ::SetDlgItemText(hdlg,IDC_EDIT_RATE_FETCH_TIME,szTime); + } + } + + CQuotesProviders::TQuotesProviderPtr pProvider = CModuleInfo::GetQuoteProvidersPtr()->GetContactProviderPtr(hContact); + + const IQuotesProvider::CProviderInfo& pi = pProvider->GetInfo(); + tostringstream o; + o << TranslateT("Info provided by") << _T(" ") << pi.m_sName << _T(""); + + ::SetDlgItemText(hdlg,IDC_SYSLINK_PROVIDER,o.str().c_str()); + } + return TRUE; + case WM_NOTIFY: + { + LPNMHDR pNMHDR = reinterpret_cast(lParam); + switch(pNMHDR->code) + { + case NM_CLICK: + if(IDC_SYSLINK_PROVIDER == wParam) + { + PNMLINK pNMLink = reinterpret_cast(pNMHDR); + ::ShellExecute(hdlg,_T("open"),pNMLink->item.szUrl,NULL,NULL,SW_SHOWNORMAL); + } + break; + } + } + break; + } + return FALSE; + } + + INT_PTR CALLBACK QuoteInfoDlgProc(HWND hdlg,UINT msg,WPARAM wParam,LPARAM lParam) + { + return QuoteInfoDlgProcImpl(g_hContact,hdlg,msg,wParam,lParam); + } +} + +int QuotesEventFunc_OnUserInfoInit(WPARAM wp,LPARAM lp) +{ + HANDLE hContact = reinterpret_cast(lp); + if(NULL == hContact) + { + return 0; + } + + + if(false == IsMyContact(hContact)) + { + return 0; + } + + g_hContact = hContact; + + OPTIONSDIALOGPAGE odp = {0}; + odp.cbSize = sizeof( odp ); + odp.hInstance = CModuleInfo::GetModuleHandle(); + //odp.dwInitParam = ( LPARAM )this; + + odp.hIcon = Quotes_LoadIconEx(ICON_STR_MAIN); + odp.flags = ODPF_TCHAR; + odp.pfnDlgProc = QuoteInfoDlgProc; + odp.position = -2000000000; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_DIALOG_QUOTE_INFO); + odp.ptszTitle = TranslateT("Quote"); + CallService(MS_USERINFO_ADDPAGE,wp,reinterpret_cast(&odp)); + + return 0; +} + + +INT_PTR QuotesMenu_EditSettings(WPARAM wp,LPARAM lp) +{ + HANDLE hContact = reinterpret_cast(wp); + if(NULL == hContact) + { + return 0; + } + + ShowSettingsDlg(hContact); + + return 0; +} + +namespace +{ + bool get_log_file(HANDLE hContact,tstring& rsLogfile) + { + rsLogfile = GetContactLogFileName(hContact); + return ((rsLogfile.empty()) ? false : true); + } +} + +INT_PTR QuotesMenu_OpenLogFile(WPARAM wp,LPARAM lp) +{ + HANDLE hContact = reinterpret_cast(wp); + if(NULL == hContact) + { + return 0; + } + + tstring sLogFileName; + if ((true == get_log_file(hContact,sLogFileName)) && (false == sLogFileName.empty())) + { + ::ShellExecute(NULL,_T("open"),sLogFileName.c_str(),NULL,NULL,SW_SHOWNORMAL); + } + + return 0; +} + +INT_PTR QuotesMenu_RefreshContact(WPARAM wp,LPARAM lp) +{ + HANDLE hContact = reinterpret_cast(wp); + if(NULL == hContact) + { + return 0; + } + + CQuotesProviders::TQuotesProviderPtr pProvider = CModuleInfo::GetQuoteProvidersPtr()->GetContactProviderPtr(hContact); + if (!pProvider) + { + return 0; + } + + pProvider->RefreshContact(hContact); + + return 0; +} + +namespace +{ + INT_PTR CALLBACK QuoteInfoDlgProc1(HWND hdlg,UINT msg,WPARAM wParam,LPARAM lParam) + { + HANDLE hContact = NULL; + switch(msg) + { + case WM_INITDIALOG: + { + hContact = reinterpret_cast(lParam); + HANDLE hWL = CModuleInfo::GetInstance().GetWindowList(WINDOW_PREFIX_INFO,false); + assert(hWL); + WindowList_Add(hWL,hdlg,hContact); + + ::SetWindowLongPtr(hdlg,GWLP_USERDATA,reinterpret_cast(hContact)); + Utils_RestoreWindowPositionNoSize(hdlg,hContact,QUOTES_MODULE_NAME,WINDOW_PREFIX_INFO); + ::ShowWindow(hdlg,SW_SHOW); + } + break; + case WM_CLOSE: + DestroyWindow(hdlg); + return FALSE; + case WM_DESTROY: + { + HANDLE hContact = get_contact(hdlg); + if(hContact) + { + SetWindowLongPtr(hdlg,GWLP_USERDATA,0); + + HANDLE hWL = CModuleInfo::GetInstance().GetWindowList(WINDOW_PREFIX_INFO,false); + assert(hWL); + WindowList_Remove(hWL,hdlg); + Utils_SaveWindowPosition(hdlg,hContact,QUOTES_MODULE_NAME,WINDOW_PREFIX_INFO); + } + } + return FALSE; + case WM_COMMAND: + if(LOWORD(wParam) == IDOK) + { + ::DestroyWindow(hdlg); + return FALSE; + } + + default: + hContact = get_contact(hdlg); + break; + } + + return QuoteInfoDlgProcImpl(hContact,hdlg,msg,wParam,lParam); + } +} + +int Quotes_OnContactDoubleClick(WPARAM wp,LPARAM/* lp*/) +{ + HANDLE hContact = reinterpret_cast(wp); + if(CModuleInfo::GetQuoteProvidersPtr()->GetContactProviderPtr(hContact)) + { + HANDLE hWL = CModuleInfo::GetInstance().GetWindowList(WINDOW_PREFIX_INFO,true); + assert(hWL); + HWND hWnd = WindowList_Find(hWL,hContact); + if(NULL != hWnd) + { + SetForegroundWindow(hWnd); + SetFocus(hWnd); + } + else if(true == IsMyContact(hContact)) + { + CreateDialogParam(CModuleInfo::GetModuleHandle(),MAKEINTRESOURCE(IDD_DIALOG_QUOTE_INFO_1),NULL,QuoteInfoDlgProc1,reinterpret_cast(hContact)); + } + + return 1; + } + else + { + return 0; + } +} + +namespace +{ + void enable_menu(HANDLE hMenu,bool bEnable) + { + CLISTMENUITEM clmi = {0}; + clmi.cbSize = sizeof( CLISTMENUITEM ); + clmi.flags = CMIM_FLAGS; + if(false == bEnable) + { + clmi.flags |= /*CMIF_HIDDEN*/CMIF_GRAYED; + } + + CallService(MS_CLIST_MODIFYMENUITEM,reinterpret_cast(hMenu),reinterpret_cast(&clmi)); + } +} + +int Quotes_PrebuildContactMenu(WPARAM wp,LPARAM lp) +{ + enable_menu(g_hMenuEditSettings,false); + enable_menu(g_hMenuOpenLogFile,false); +#ifdef CHART_IMPLEMENT + enable_menu(g_hMenuChart,false); +#endif + enable_menu(g_hMenuRefresh,false); + + HANDLE hContact = reinterpret_cast(wp); + if(NULL == hContact) + { + return 0; + } + + enable_menu(g_hMenuEditSettings,true); + + enable_menu(g_hMenuRefresh,true); + + tstring sLogFileName; + bool bThereIsLogFile = (true == get_log_file(hContact,sLogFileName)) + && (false == sLogFileName.empty()) && (0 == _taccess(sLogFileName.c_str(),04)); + if(true == bThereIsLogFile) + { +#ifdef CHART_IMPLEMENT + enable_menu(g_hMenuChart,true); +#endif + enable_menu(g_hMenuOpenLogFile,true); + } + + return 0; +} diff --git a/protocols/Quotes/QuoteInfoDlg.h b/protocols/Quotes/QuoteInfoDlg.h new file mode 100644 index 0000000000..c4a1999a4c --- /dev/null +++ b/protocols/Quotes/QuoteInfoDlg.h @@ -0,0 +1,11 @@ +#ifndef __aa849fa0_ff3f_49e9_b47a_e7dd34783dc2_QuoteInfoDlg_h__ +#define __aa849fa0_ff3f_49e9_b47a_e7dd34783dc2_QuoteInfoDlg_h__ + +int QuotesEventFunc_OnUserInfoInit(WPARAM wp,LPARAM lp); +INT_PTR QuotesMenu_EditSettings(WPARAM wp,LPARAM lp); +INT_PTR QuotesMenu_OpenLogFile(WPARAM wp,LPARAM lp); +INT_PTR QuotesMenu_RefreshContact(WPARAM wp,LPARAM lp); +int Quotes_PrebuildContactMenu(WPARAM wp,LPARAM lp); +int Quotes_OnContactDoubleClick(WPARAM wp,LPARAM lp); + +#endif //__aa849fa0_ff3f_49e9_b47a_e7dd34783dc2_QuoteInfoDlg_h__ diff --git a/protocols/Quotes/QuotesProviderBase.cpp b/protocols/Quotes/QuotesProviderBase.cpp new file mode 100644 index 0000000000..c92c748a02 Binary files /dev/null and b/protocols/Quotes/QuotesProviderBase.cpp differ diff --git a/protocols/Quotes/QuotesProviderBase.h b/protocols/Quotes/QuotesProviderBase.h new file mode 100644 index 0000000000..76db155f4c --- /dev/null +++ b/protocols/Quotes/QuotesProviderBase.h @@ -0,0 +1,112 @@ +#ifndef __3e6cb4ec_fc47_468f_a2c8_a77941176bc9_QuotesProviderBase_h__ +#define __3e6cb4ec_fc47_468f_a2c8_a77941176bc9_QuotesProviderBase_h__ + +#include "iquotesprovider.h" +#include +#include "LightMutex.h" + +class CQuotesProviderBase : public IQuotesProvider +{ +public: + class CQuote + { + public: + CQuote(const tstring& rsID = _T(""),const tstring& rsSymbol = _T(""),const tstring& rsName = _T("")) + : m_sSymbol(rsSymbol),m_sName(rsName),m_sID(rsID){} + + const tstring& GetSymbol()const{return m_sSymbol;} + const tstring& GetName()const{return m_sName;} + const tstring& GetID()const{return m_sID;} + + private: + tstring m_sSymbol; + tstring m_sName; + tstring m_sID; + }; + + class CQuoteSection + { + public: + typedef std::vector TSections; + typedef std::vector TQuotes; + + public: + CQuoteSection(const tstring& rsName = _T(""),const TSections& raSections = TSections(),const TQuotes& raQuotes = TQuotes()) + : m_sName(rsName),m_aSections(raSections),m_aQuotes(raQuotes){} + + const tstring& GetName()const + {return m_sName;} + + size_t GetSectionCount()const + {return m_aSections.size();} + CQuoteSection GetSection(size_t nIndex)const + {return ((nIndex < m_aSections.size()) ? m_aSections[nIndex] : CQuoteSection());} + + size_t GetQuoteCount()const + {return m_aQuotes.size();} + CQuote GetQuote(size_t nIndex)const + {return ((nIndex < m_aQuotes.size()) ? m_aQuotes[nIndex] : CQuote());} + + private: + tstring m_sName; + TSections m_aSections; + TQuotes m_aQuotes; + }; + +protected: + typedef std::vector TContracts; + +public: + struct CXMLFileInfo; + +public: + CQuotesProviderBase(); + ~CQuotesProviderBase(); + + + const CQuoteSection& GetQuotes()const; +// void SetSettingsEvent(); + + virtual bool Init(); + virtual const CProviderInfo& GetInfo()const; + virtual void AddContact(HANDLE hContact); + virtual void DeleteContact(HANDLE hContact); + virtual void Run(); + virtual void Accept(CQuotesProviderVisitor& visitor)const; + virtual void RefreshAll(); + virtual void RefreshContact(HANDLE hContact); + virtual void SetContactExtraIcon(HANDLE hContact)const; + +protected: + const tstring& GetURL()const; + HANDLE CreateNewContact(const tstring& rsName); + static bool IsOnline(); + static void SetContactStatus(HANDLE hContact,int nNewStatus); + void WriteContactRate(HANDLE hContact,double dRate,const tstring& rsSymbol = _T("")); + +private: + virtual void RefreshQuotes(TContracts& anContacts) = 0; + +private: + virtual void OnEndRun(); + +private: + CXMLFileInfo* GetXMLFileInfo()const; + +protected: + TContracts m_aContacts; + mutable CLightMutex m_cs; + +private: + typedef boost::scoped_ptr TXMLFileInfoPtr; + mutable TXMLFileInfoPtr m_pXMLInfo; + HANDLE m_hEventSettingsChanged; + HANDLE m_hEventRefreshContact; + tstring m_sContactListFormat; + tstring m_sStatusMsgFormat; + tstring m_sTendencyFormat; + TContracts m_aRefreshingContacts; + bool m_bRefreshInProgress; +}; + +#endif //__3e6cb4ec_fc47_468f_a2c8_a77941176bc9_QuotesProviderBase_h__ diff --git a/protocols/Quotes/QuotesProviderDukasCopy.cpp b/protocols/Quotes/QuotesProviderDukasCopy.cpp new file mode 100644 index 0000000000..a7ffc5331a Binary files /dev/null and b/protocols/Quotes/QuotesProviderDukasCopy.cpp differ diff --git a/protocols/Quotes/QuotesProviderDukasCopy.h b/protocols/Quotes/QuotesProviderDukasCopy.h new file mode 100644 index 0000000000..d6ec498bcf --- /dev/null +++ b/protocols/Quotes/QuotesProviderDukasCopy.h @@ -0,0 +1,38 @@ +#ifndef __93121758_68c7_4836_b571_da84dfe82b84_QuotesProviderDukasCopy_h__ +#define __93121758_68c7_4836_b571_da84dfe82b84_QuotesProviderDukasCopy_h__ + +#include "quotesproviderbase.h" +#include + +#define DB_STR_REFRESH_RATE_TYPE "RefreshRateType" +#define DB_STR_REFRESH_RATE_VALUE "RefreshRateValue" +#define DB_STR_DC_DISPLAY_NAME_FORMAT "DC_DisplayNameFormat" +// #define DB_STR_DC_LOG_FILE_FORMAT "DC_LogFileFormat" +// #define DB_STR_DC_HISTORY_FORMAT "DC_HistoryFormat" + +class CQuotesProviderDukasCopy : public CQuotesProviderBase +{ +public: + CQuotesProviderDukasCopy(); + ~CQuotesProviderDukasCopy(); + + bool WatchForQuote(const CQuote& rQuote,bool bWatch); + bool IsQuoteWatched(const CQuote& rQuote)const; + + HANDLE GetContactByQuoteID(const tstring& rsQuoteID)const; +// #ifdef CHART_IMPLEMENT +// bool Chart(HANDLE hContact,const tstring& url)const; +// #endif + +private: + //IQuotesProvider implementation + virtual void RefreshQuotes(TContracts& anContacts); + virtual void ShowPropertyPage(WPARAM wp,OPTIONSDIALOGPAGE& odp); + virtual void Accept(CQuotesProviderVisitor& visitor)const; + +private: + tstring BuildHTTPURL()const; + +}; + +#endif //__93121758_68c7_4836_b571_da84dfe82b84_QuotesProviderDukasCopy_h__ diff --git a/protocols/Quotes/QuotesProviderFinance.cpp b/protocols/Quotes/QuotesProviderFinance.cpp new file mode 100644 index 0000000000..99d6127b32 --- /dev/null +++ b/protocols/Quotes/QuotesProviderFinance.cpp @@ -0,0 +1,318 @@ +#include "stdafx.h" +#include "QuotesProviderFinance.h" +#include "EconomicRateInfo.h" +#include "DBUtils.h" +#include "QuotesProviderVisitor.h" +#include "ModuleInfo.h" +#include "QuotesProviders.h" +#include "CommonOptionDlg.h" +#include "resource.h" +#include "WinCtrlHelper.h" + +void CQuotesProviderFinance::GetWatchedQuotes(TQuotes& raQuotes)const +{ + raQuotes.clear(); + BOOST_FOREACH(HANDLE hContact,m_aContacts) + { + tstring sID = Quotes_DBGetStringT(hContact,QUOTES_MODULE_NAME,DB_STR_QUOTE_ID); + tstring sSymbol = Quotes_DBGetStringT(hContact,QUOTES_MODULE_NAME,DB_STR_QUOTE_SYMBOL,sID.c_str()); + tstring sDescr = Quotes_DBGetStringT(hContact,QUOTES_MODULE_NAME,DB_STR_QUOTE_DESCRIPTION); + CQuotesProviderBase::CQuote quote(sID,sSymbol,sDescr); + + raQuotes.push_back(quote); + } +} + +namespace +{ + inline tstring get_quote_id(HANDLE hContact) + { + return Quotes_DBGetStringT(hContact,QUOTES_MODULE_NAME,DB_STR_QUOTE_ID); + } + + inline bool is_quote_id_equal(HANDLE hContact,const tstring& sID) + { + return sID == get_quote_id(hContact); + } +} + +bool CQuotesProviderFinance::WatchForQuote(const CQuote& rQuote,bool bWatch) +{ + const tstring& sQuoteID = rQuote.GetID(); + TContracts::iterator i = std::find_if(m_aContacts.begin(),m_aContacts.end(), + boost::bind(is_quote_id_equal,_1,sQuoteID)); + + if ((false == bWatch) && (i != m_aContacts.end())) + { + HANDLE hContact = *i; + {// for CCritSection + CGuard cs(m_cs); + m_aContacts.erase(i); + } + + CallService(MS_DB_CONTACT_DELETE,reinterpret_cast(hContact),0); + return true; + } + else if ((true == bWatch) && (i == m_aContacts.end())) + { + HANDLE hContact = CreateNewContact(rQuote.GetSymbol()); + if(hContact) + { + DBWriteContactSettingTString(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_ID,sQuoteID.c_str()); + if(false == rQuote.GetName().empty()) + { + DBWriteContactSettingTString(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_DESCRIPTION,rQuote.GetName().c_str()); + } + + return true; + } + } + + return false; +} + +HANDLE CQuotesProviderFinance::GetContactByQuoteID(const tstring& rsQuoteID)const +{ + CGuard cs(m_cs); + + TContracts::const_iterator i = std::find_if(m_aContacts.begin(),m_aContacts.end(), + boost::bind(std::equal_to(),rsQuoteID,boost::bind(get_quote_id,_1))); + if(i != m_aContacts.end()) + { + return *i; + } + else + { + return NULL; + } +} + +void CQuotesProviderFinance::Accept(CQuotesProviderVisitor& visitor)const +{ + CQuotesProviderBase::Accept(visitor); + visitor.Visit(*this); +} + +namespace +{ + inline tstring make_quote_name(const CQuotesProviderBase::CQuote& rQuote) + { + const tstring& rsDesc = rQuote.GetName(); + return((false == rsDesc.empty()) ? rsDesc : rQuote.GetSymbol()); + } + + int add_quote_to_wnd(const CQuotesProviderBase::CQuote& rQuote,HWND hwnd) + { + tstring sName = make_quote_name(rQuote); + int nIndex = ::SendMessage(hwnd,LB_ADDSTRING,0,reinterpret_cast(sName.c_str())); + if(nIndex >= 0) + { + CQuotesProviderBase::CQuote* pQuote = new CQuotesProviderBase::CQuote(rQuote); + if(LB_ERR == ::SendMessage(hwnd,LB_SETITEMDATA,nIndex,reinterpret_cast(pQuote))) + { + delete pQuote; + } + } + return nIndex; + } + +// typedef CQuotesProviderFinance::TQuotes TQuotes; +// TQuotes g_aWatchedQuotes; + +// inline bool cmp_quotes(const tstring& rsQuoteId,const CQuotesProviderBase::CQuote& quote) +// { +// return (0 == quotes_stricmp(rsQuoteId.c_str(),quote.GetID().c_str())); +// } + + CQuotesProviderBase::CQuote* get_quote_ptr_from_lb_index(HWND hwndListBox,int nIndex) + { + LRESULT lResult = ::SendMessage(hwndListBox,LB_GETITEMDATA,nIndex,0); + return (((LB_ERR != lResult) && (0 != lResult)) ? (reinterpret_cast(lResult)) : nullptr); + } + + int is_quote_added(HWND hwndList,const tstring& rsQuoteID) + { + int cItems = ::SendMessage(hwndList,LB_GETCOUNT,0,0); + for(int i = 0;i < cItems;++i) + { + const CQuotesProviderBase::CQuote* pQuote = get_quote_ptr_from_lb_index(hwndList,i); + if ((nullptr != pQuote) + && ((0 == quotes_stricmp(rsQuoteID.c_str(),pQuote->GetID().c_str())) + || (0 == quotes_stricmp(rsQuoteID.c_str(),pQuote->GetName().c_str())) + || (0 == quotes_stricmp(rsQuoteID.c_str(),pQuote->GetSymbol().c_str())))) + { + return i; + } + } + return LB_ERR; + } + + INT_PTR CALLBACK GoogleFinanceOptDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam) + { + CQuotesProviderFinance* pProvider = nullptr; + if(WM_INITDIALOG == message) + { + pProvider = reinterpret_cast(lParam); + SetWindowLongPtr(hDlg,GWLP_USERDATA,lParam); + } + else + { + pProvider = reinterpret_cast(GetWindowLongPtr(hDlg,GWLP_USERDATA)); + } + + CCommonDlgProcData d(pProvider); + CommonOptionDlgProc(hDlg,message,wParam,lParam,d); + + switch(message) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hDlg); + + CQuotesProviderFinance::TQuotes aQuotes; + pProvider->GetWatchedQuotes(aQuotes); + + HWND hwndList = GetDlgItem(hDlg,IDC_LIST_RATES); + std::for_each(aQuotes.begin(),aQuotes.end(), + boost::bind(add_quote_to_wnd,_1,hwndList)); + + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_ADD),FALSE); + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_REMOVE),FALSE); + } + return (TRUE); + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_EDIT_QUOTE: + if(EN_CHANGE == HIWORD(wParam)) + { + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_ADD),GetWindowTextLength(GetDlgItem(hDlg,IDC_EDIT_QUOTE)) > 0); + } + return (TRUE); + case IDC_BUTTON_ADD: + if(BN_CLICKED == HIWORD(wParam)) + { + HWND hEdit = GetDlgItem(hDlg,IDC_EDIT_QUOTE); + tstring sQuoteSymbol = get_window_text(hEdit); + assert(false == sQuoteSymbol.empty()); + HWND hwndList = GetDlgItem(hDlg,IDC_LIST_RATES); + if(LB_ERR == is_quote_added(hwndList,sQuoteSymbol)) + { + CQuotesProviderBase::CQuote quote(sQuoteSymbol,sQuoteSymbol); + if(add_quote_to_wnd(quote,hwndList) >= 0) + { + SetDlgItemText(hDlg,IDC_EDIT_QUOTE,_T("")); + SetFocus(hEdit); + PropSheet_Changed(::GetParent(hDlg),hDlg); + } + else + { + ::MessageBeep(MB_ICONERROR); + } + } + } + return (TRUE); + case IDC_BUTTON_REMOVE: + if(BN_CLICKED == HIWORD(wParam)) + { + HWND hWnd = ::GetDlgItem(hDlg,IDC_LIST_RATES); + int nSel = ::SendMessage(hWnd,LB_GETCURSEL,0,0); + if(LB_ERR != nSel) + { + CQuotesProviderBase::CQuote* pQuote = get_quote_ptr_from_lb_index(hWnd,nSel); + delete pQuote; + if(LB_ERR != ::SendMessage(hWnd,LB_DELETESTRING,nSel,0)) + { + PropSheet_Changed(::GetParent(hDlg),hDlg); + } + } + + nSel = ::SendMessage(hWnd,LB_GETCURSEL,0,0); + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_REMOVE),(LB_ERR != nSel)); + } + return (TRUE); + case IDC_LIST_RATES: + if(CBN_SELCHANGE == HIWORD(wParam)) + { + int nSel = ::SendMessage(::GetDlgItem(hDlg,IDC_LIST_RATES),LB_GETCURSEL,0,0); + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_REMOVE),(LB_ERR != nSel)); + } + return (TRUE); + } + return (FALSE); + + case WM_NOTIFY: + { + LPNMHDR pNMHDR = reinterpret_cast(lParam); + switch(pNMHDR->code) + { + case PSN_APPLY: + if(pProvider) + { + CQuotesProviderFinance::TQuotes aTemp; + pProvider->GetWatchedQuotes(aTemp); + + typedef std::vector TQuotesPtr; + TQuotesPtr apCurrent; + HWND hwndListBox = GetDlgItem(hDlg,IDC_LIST_RATES); + int cItems = ::SendMessage(hwndListBox,LB_GETCOUNT,0,0); + for(int i = 0;i < cItems;++i) + { + const CQuotesProviderBase::CQuote* pQuote = get_quote_ptr_from_lb_index(hwndListBox,i); + if(pQuote) + { + apCurrent.push_back(pQuote); + } + } + + std::for_each(aTemp.begin(),aTemp.end(), + [&apCurrent,pProvider](const CQuotesProviderBase::CQuote& quote) + { + if(apCurrent.end() == std::find_if(apCurrent.begin(),apCurrent.end(), + ["e](const CQuotesProviderBase::CQuote* pQuote){return 0 == quotes_stricmp(pQuote->GetID().c_str(),quote.GetID().c_str());})) + { + pProvider->WatchForQuote(quote,false); + } + }); + + std::for_each(apCurrent.begin(),apCurrent.end(), + [&aTemp,pProvider](const CQuotesProviderBase::CQuote* pQuote) + { + if(aTemp.end() == + std::find_if(aTemp.begin(),aTemp.end(), + [pQuote](const CQuotesProviderBase::CQuote& quote){return 0 == quotes_stricmp(pQuote->GetID().c_str(),quote.GetID().c_str());})) + { + pProvider->WatchForQuote(*pQuote,true); + } + + }); + + pProvider->RefreshAll(); + } + + return (TRUE); + } + } + return (FALSE); + case WM_DESTROY: + HWND hwndListBox = GetDlgItem(hDlg,IDC_LIST_RATES); + int cItems = ::SendMessage(hwndListBox,LB_GETCOUNT,0,0); + for(int i = 0;i < cItems;++i) + { + const CQuotesProviderBase::CQuote* pQuote = get_quote_ptr_from_lb_index(hwndListBox,i); + delete pQuote; + } + return (FALSE); + } + return (FALSE); + } +} + +void CQuotesProviderFinance::ShowPropertyPage(WPARAM wp,OPTIONSDIALOGPAGE& odp) +{ + odp.pszTemplate = MAKEINTRESOURCEA(IDD_DIALOG_OPT_FINANCE); + odp.pfnDlgProc = GoogleFinanceOptDlgProc; + odp.dwInitParam = reinterpret_cast(static_cast(this)); + odp.ptszTab = const_cast(GetInfo().m_sName.c_str()); + CallService(MS_OPT_ADDPAGE,wp,reinterpret_cast(&odp)); +} diff --git a/protocols/Quotes/QuotesProviderFinance.h b/protocols/Quotes/QuotesProviderFinance.h new file mode 100644 index 0000000000..f63077071d --- /dev/null +++ b/protocols/Quotes/QuotesProviderFinance.h @@ -0,0 +1,21 @@ +#ifndef __95A13A68_0DF0_43FA_B6C1_81D83AED59AA_QuotesProviderFinance_h__ +#define __95A13A68_0DF0_43FA_B6C1_81D83AED59AA_QuotesProviderFinance_h__ + +#include "QuotesProviderBase.h" + +class CQuotesProviderFinance : public CQuotesProviderBase +{ +public: + typedef std::vector TQuotes; + +public: + void GetWatchedQuotes(TQuotes& raQuotes)const; + bool WatchForQuote(const CQuote& rQuote,bool bWatch); + HANDLE GetContactByQuoteID(const tstring& rsQuoteID)const; + +protected: + virtual void ShowPropertyPage(WPARAM wp,OPTIONSDIALOGPAGE& odp); + virtual void Accept(CQuotesProviderVisitor& visitor)const; +}; + +#endif //__95A13A68_0DF0_43FA_B6C1_81D83AED59AA_QuotesProviderFinance_h__ \ No newline at end of file diff --git a/protocols/Quotes/QuotesProviderGoogle.cpp b/protocols/Quotes/QuotesProviderGoogle.cpp new file mode 100644 index 0000000000..6458180324 --- /dev/null +++ b/protocols/Quotes/QuotesProviderGoogle.cpp @@ -0,0 +1,543 @@ +#include "StdAfx.h" +#include "QuotesProviderGoogle.h" +#include "resource.h" +#include "HTTPSession.h" +#include "Log.h" +#include "DBUtils.h" +#include "EconomicRateInfo.h" +#include "ModuleInfo.h" +#include "QuotesProviders.h" +#include "IHTMLParser.h" +#include "IHTMLEngine.h" +#include "CommonOptionDlg.h" +#include "QuotesProviderVisitor.h" + +CQuotesProviderGoogle::CQuotesProviderGoogle() +{ +} + +CQuotesProviderGoogle::~CQuotesProviderGoogle() +{ +} + +namespace +{ + inline tstring make_contact_name(const tstring& rsSymbolFrom,const tstring& rsSymbolTo) + { + tostringstream o; + o << rsSymbolFrom << _T("/") << rsSymbolTo; + return o.str(); + } + + inline bool is_rate_watched(HANDLE hContact, + const CQuotesProviderBase::CQuote& from, + const CQuotesProviderBase::CQuote& to) + { + tstring sFrom = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_FROM_ID); + tstring sTo = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_TO_ID); + return ((0 == quotes_stricmp(from.GetID().c_str(),sFrom.c_str())) + && (0 == quotes_stricmp(to.GetID().c_str(),sTo.c_str()))); + } +} + +bool CQuotesProviderGoogle::WatchForRate(const CRateInfo& ri, + bool bWatch) +{ + TContracts::const_iterator i = std::find_if(m_aContacts.begin(),m_aContacts.end(), + boost::bind(is_rate_watched,_1,ri.m_from,ri.m_to)); + if ((true == bWatch) && (i == m_aContacts.end())) + { + tstring sName = make_contact_name(ri.m_from.GetSymbol(),ri.m_to.GetSymbol()); + HANDLE hContact = CreateNewContact(sName); + if(hContact) + { + DBWriteContactSettingTString(hContact,QUOTES_PROTOCOL_NAME,DB_STR_FROM_ID,ri.m_from.GetID().c_str()); + DBWriteContactSettingTString(hContact,QUOTES_PROTOCOL_NAME,DB_STR_TO_ID,ri.m_to.GetID().c_str()); + if(false == ri.m_from.GetName().empty()) + { + DBWriteContactSettingTString(hContact,QUOTES_PROTOCOL_NAME,DB_STR_FROM_DESCRIPTION,ri.m_from.GetName().c_str()); + } + if(false == ri.m_to.GetName().empty()) + { + DBWriteContactSettingTString(hContact,QUOTES_PROTOCOL_NAME,DB_STR_TO_DESCRIPTION,ri.m_to.GetName().c_str()); + } + + return true; + } + } + else if ((false == bWatch) && (i != m_aContacts.end())) + { + HANDLE hContact = *i; + {// for CCritSection + CGuard cs(m_cs); + m_aContacts.erase(i); + } + + CallService(MS_DB_CONTACT_DELETE,reinterpret_cast(hContact),0); + return true; + } + + return false; +} + +size_t CQuotesProviderGoogle::GetWatchedRateCount()const +{ + return m_aContacts.size(); +} + +bool CQuotesProviderGoogle::GetWatchedRateInfo(size_t nIndex,CRateInfo& rRateInfo) +{ + if(nIndex < m_aContacts.size()) + { + HANDLE hContact = m_aContacts[nIndex]; + tstring sSymbolFrom = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_FROM_ID); + tstring sSymbolTo = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_TO_ID); + tstring sDescFrom = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_FROM_DESCRIPTION); + tstring sDescTo = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_TO_DESCRIPTION); + + rRateInfo.m_from = CQuote(sSymbolFrom,sSymbolFrom,sDescFrom); + rRateInfo.m_to = CQuote(sSymbolTo,sSymbolTo,sDescTo); + return true; + } + else + { + return false; + } +} + +namespace +{ + tstring build_url(const tstring& rsURL,const tstring& from,const tstring& to,double dAmount) + { + tostringstream o; + o << rsURL << _T("?a=") << std::fixed << dAmount << _T("&from=") << from << _T("&to=") << to; + return o.str(); + } + tstring build_url(HANDLE hContact,const tstring& rsURL,double dAmount = 1.0) + { + tstring sFrom = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_FROM_ID); + tstring sTo = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_TO_ID); + return build_url(rsURL,sFrom,sTo,dAmount); + } + + typedef IHTMLNode::THTMLNodePtr THTMLNodePtr; + + bool parse_html_node(const THTMLNodePtr& pNode,double& rdRate) + { + tstring sID = pNode->GetAttribute(_T("id")); + if ((false == sID.empty()) && (0 == quotes_stricmp(sID.c_str(),_T("currency_converter_result")))) + { + size_t cChild = pNode->GetChildCount(); +// assert(1 == cChild); + if(cChild > 0) + { + THTMLNodePtr pChild = pNode->GetChildPtr(0); + tstring sRate = pChild->GetText(); + + tistringstream input(sRate); + input >> rdRate; + + return ((false == input.bad()) && (false == input.fail())); + } + } + else + { + size_t cChild = pNode->GetChildCount(); + for(size_t i = 0;i < cChild;++i) + { + THTMLNodePtr pChild = pNode->GetChildPtr(i); + if(pChild && (true == parse_html_node(pChild,rdRate))) + { + return true; + } + } + } + + return false; + } + + bool parse_responce(const tstring& rsHTML,double& rdRate) + { + IHTMLEngine::THTMLParserPtr pHTMLParser = CModuleInfo::GetHTMLEngine()->GetParserPtr(); + THTMLNodePtr pRoot = pHTMLParser->ParseString(rsHTML); + if(pRoot) + { + return parse_html_node(pRoot,rdRate); + } + else + { + return false; + } + } +} + +void CQuotesProviderGoogle::RefreshQuotes(TContracts& anContacts) +{ + CHTTPSession http; + tstring sURL = GetURL(); + + bool bUseExtendedStatus = CModuleInfo::GetInstance().GetExtendedStatusFlag(); + + for(TContracts::const_iterator i = anContacts.begin();i != anContacts.end() && IsOnline();++i) + { + HANDLE hContact = *i; + + if(bUseExtendedStatus) + { + SetContactStatus(hContact,ID_STATUS_OCCUPIED); + } + + tstring sFullURL = build_url(hContact,sURL); +// LogIt(Info,sFullURL); + if ((true == http.OpenURL(sFullURL)) && (true == IsOnline())) + { + tstring sHTML; + if ((true == http.ReadResponce(sHTML)) && (true == IsOnline())) + { +// LogIt(Info,sHTML); + + double dRate = 0.0; + if ((true == parse_responce(sHTML,dRate)) && (true == IsOnline())) + { + WriteContactRate(hContact,dRate); + continue; + } + } + } + + SetContactStatus(hContact,ID_STATUS_NA); + } +} + +namespace +{ + inline tstring make_quote_name(const CQuotesProviderGoogle::CQuote& rQuote) + { + const tstring& rsDesc = rQuote.GetName(); + return((false == rsDesc.empty()) ? rsDesc : rQuote.GetSymbol()); + } + + CQuotesProviderGoogle* get_google_provider() + { + CModuleInfo::TQuotesProvidersPtr& pProviders = CModuleInfo::GetQuoteProvidersPtr(); + const CQuotesProviders::TQuotesProviders& rapQuotesProviders = pProviders->GetProviders(); + for(CQuotesProviders::TQuotesProviders::const_iterator i = rapQuotesProviders.begin();i != rapQuotesProviders.end();++i) + { + const CQuotesProviders::TQuotesProviderPtr& pProvider = *i; + CQuotesProviderGoogle* pGoogle = dynamic_cast(pProvider.get()); + if(pGoogle) + { + return pGoogle; + } + } + + assert(!"We should never get here!"); + return NULL; + } + + CQuotesProviderGoogle::CQuoteSection get_quotes() + { + const CQuotesProviderGoogle* pProvider = get_google_provider(); + if(pProvider) + { + const CQuotesProviderGoogle::CQuoteSection& rQuotes = pProvider->GetQuotes(); + if(rQuotes.GetSectionCount() > 0) + { + return rQuotes.GetSection(0); + } + } + + return CQuotesProviderGoogle::CQuoteSection(); + } + + tstring make_rate_name(const CQuotesProviderGoogle::CQuote& rFrom, + const CQuotesProviderGoogle::CQuote& rTo) + { + if ((false == rFrom.GetName().empty()) && (false == rTo.GetName().empty())) + { + return make_contact_name(rFrom.GetName(),rTo.GetName()); + } + else + { + return make_contact_name(rFrom.GetSymbol(),rTo.GetSymbol()); + } + } + + typedef std::vector TWatchedRates; + TWatchedRates g_aWatchedRates; + + bool is_equal_rate(const CQuotesProviderGoogle::CRateInfo& riL,const CQuotesProviderGoogle::CRateInfo& riR) + { + return ((0 == quotes_stricmp(riL.m_from.GetID().c_str(),riR.m_from.GetID().c_str())) + && ((0 == quotes_stricmp(riL.m_to.GetID().c_str(),riR.m_to.GetID().c_str())))); + } + + INT_PTR CALLBACK GoogleOptDlgProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) + { + CQuotesProviderGoogle* pProvider = get_google_provider(); + + CCommonDlgProcData d(pProvider); + CommonOptionDlgProc(hdlg,message,wParam,lParam,d); + + switch(message) + { + case WM_NOTIFY: + { + LPNMHDR pNMHDR = reinterpret_cast(lParam); + switch(pNMHDR->code) + { + case PSN_APPLY: + { + if(pProvider) + { + TWatchedRates aTemp(g_aWatchedRates); + TWatchedRates aRemove; + size_t cWatchedRates = pProvider->GetWatchedRateCount(); + for(size_t i = 0;i < cWatchedRates;++i) + { + CQuotesProviderGoogle::CRateInfo ri; + if(true == pProvider->GetWatchedRateInfo(i,ri)) + { + TWatchedRates::iterator it = + std::find_if(aTemp.begin(),aTemp.end(), + boost::bind(is_equal_rate,_1,boost::cref(ri))); + if(it == aTemp.end()) + { + aRemove.push_back(ri); + } + else + { + aTemp.erase(it); + } + } + } + + std::for_each(aRemove.begin(),aRemove.end(),boost::bind(&CQuotesProviderGoogle::WatchForRate,pProvider,_1,false)); + std::for_each(aTemp.begin(),aTemp.end(),boost::bind(&CQuotesProviderGoogle::WatchForRate,pProvider,_1,true)); + + pProvider->RefreshAll(); + } + } + break; + } + } + break; + case WM_INITDIALOG: + { + TranslateDialogDefault(hdlg); + + g_aWatchedRates.clear(); + + HWND hcbxFrom = ::GetDlgItem(hdlg,IDC_COMBO_CONVERT_FROM); + HWND hcbxTo = ::GetDlgItem(hdlg,IDC_COMBO_CONVERT_INTO); + + const CQuotesProviderGoogle::CQuoteSection& rSection = get_quotes(); + size_t cQuotes = rSection.GetQuoteCount(); + for(size_t i = 0;i < cQuotes;++i) + { + const CQuotesProviderGoogle::CQuote& rQuote = rSection.GetQuote(i); + tstring sName = make_quote_name(rQuote); + LPCTSTR pszName = sName.c_str(); + ::SendMessage(hcbxFrom,CB_ADDSTRING,0,reinterpret_cast(pszName)); + ::SendMessage(hcbxTo,CB_ADDSTRING,0,reinterpret_cast(pszName)); + } + + CQuotesProviderGoogle* pProvider = get_google_provider(); + if(pProvider) + { + size_t cWatchedRates = pProvider->GetWatchedRateCount(); + for(size_t i = 0;i < cWatchedRates;++i) + { + CQuotesProviderGoogle::CRateInfo ri; + if(true == pProvider->GetWatchedRateInfo(i,ri)) + { + g_aWatchedRates.push_back(ri); + tstring sRate = make_rate_name(ri.m_from,ri.m_to); + LPCTSTR pszRateName = sRate.c_str(); + ::SendMessage(::GetDlgItem(hdlg,IDC_LIST_RATES),LB_ADDSTRING,0,reinterpret_cast(pszRateName)); + } + } + } + + ::EnableWindow(::GetDlgItem(hdlg,IDC_BUTTON_ADD),FALSE); + ::EnableWindow(::GetDlgItem(hdlg,IDC_BUTTON_REMOVE),FALSE); + } + return TRUE; + case WM_COMMAND: + switch(HIWORD(wParam)) + { + case CBN_SELCHANGE: + switch(LOWORD(wParam)) + { + case IDC_COMBO_REFRESH_RATE: + break; + case IDC_COMBO_CONVERT_FROM: + case IDC_COMBO_CONVERT_INTO: + { + int nFrom = static_cast(::SendMessage(::GetDlgItem(hdlg,IDC_COMBO_CONVERT_FROM),CB_GETCURSEL,0,0)); + int nTo = static_cast(::SendMessage(::GetDlgItem(hdlg,IDC_COMBO_CONVERT_INTO),CB_GETCURSEL,0,0)); + bool bEnableAddButton = ((CB_ERR != nFrom) && (CB_ERR != nTo) && (nFrom != nTo)); + EnableWindow(GetDlgItem(hdlg,IDC_BUTTON_ADD),bEnableAddButton); + } + break; + case IDC_LIST_RATES: + { + int nSel = ::SendMessage(::GetDlgItem(hdlg,IDC_LIST_RATES),LB_GETCURSEL,0,0); + ::EnableWindow(::GetDlgItem(hdlg,IDC_BUTTON_REMOVE),(LB_ERR != nSel)); + } + break; + } + break; + case BN_CLICKED: + switch(LOWORD(wParam)) + { + case IDC_BUTTON_ADD: + { + size_t nFrom = static_cast(::SendMessage(::GetDlgItem(hdlg,IDC_COMBO_CONVERT_FROM),CB_GETCURSEL,0,0)); + size_t nTo = static_cast(::SendMessage(::GetDlgItem(hdlg,IDC_COMBO_CONVERT_INTO),CB_GETCURSEL,0,0)); + if ((CB_ERR != nFrom) && (CB_ERR != nTo) && (nFrom != nTo)) + { + const CQuotesProviderGoogle::CQuoteSection& rSection = get_quotes(); + size_t cQuotes = rSection.GetQuoteCount(); + if ((nFrom < cQuotes) && (nTo < cQuotes)) + { + CQuotesProviderGoogle::CRateInfo ri; + ri.m_from = rSection.GetQuote(nFrom); + ri.m_to = rSection.GetQuote(nTo); + + g_aWatchedRates.push_back(ri); + + tstring sRate = make_rate_name(ri.m_from,ri.m_to); + LPCTSTR pszRateName = sRate.c_str(); + ::SendMessage(::GetDlgItem(hdlg,IDC_LIST_RATES),LB_ADDSTRING,0,reinterpret_cast(pszRateName)); + PropSheet_Changed(::GetParent(hdlg),hdlg); + } + } + } + break; + case IDC_BUTTON_REMOVE: + { + HWND hWnd = ::GetDlgItem(hdlg,IDC_LIST_RATES); + int nSel = ::SendMessage(hWnd,LB_GETCURSEL,0,0); + if(LB_ERR != nSel) + { + if ((LB_ERR != ::SendMessage(hWnd, LB_DELETESTRING,nSel,0)) + && (nSel < static_cast(g_aWatchedRates.size()))) + { + + TWatchedRates::iterator i = g_aWatchedRates.begin(); + std::advance(i,nSel); + g_aWatchedRates.erase(i); + PropSheet_Changed(::GetParent(hdlg),hdlg); + } + } + + nSel = ::SendMessage(hWnd,LB_GETCURSEL,0,0); + ::EnableWindow(::GetDlgItem(hdlg,IDC_BUTTON_REMOVE),(LB_ERR != nSel)); + } + break; + } + break; +// case LBN_SELCHANGE: +// switch(LOWORD(lParam)) +// { +// case IDC_LIST_RATES: +// { +// int nSel = ::SendMessage(::GetDlgItem(hdlg,IDC_LIST_RATES),LB_GETCURSEL,0,0); +// ::EnableWindow(::GetDlgItem(hdlg,IDC_BUTTON_REMOVE),(-1 != nSel)); +// } +// } +// break; + } + break; + + } + + return FALSE; + } +} + +void CQuotesProviderGoogle::ShowPropertyPage(WPARAM wp,OPTIONSDIALOGPAGE& odp) +{ + odp.pszTemplate = MAKEINTRESOURCEA(IDD_DIALOG_OPT_GOOGLE); + odp.pfnDlgProc = GoogleOptDlgProc; +// #if MIRANDA_VER >= 0x0600 + //odp.ptszTab = TranslateTS(const_cast(GetInfo().m_sName.c_str())); + odp.ptszTab = const_cast(GetInfo().m_sName.c_str()); +// #else +// tostringstream o; +// o << TranslateTS(QUOTES_PROTOCOL_NAME) << _T(" - ") << TranslateTS(GetInfo().m_sName.c_str()); +// tstring sTitle = o.str(); +// odp.ptszTitle = TranslateTS(const_cast(sTitle.c_str())); +// #endif + CallService(MS_OPT_ADDPAGE,wp,reinterpret_cast(&odp)); +} + +void CQuotesProviderGoogle::Accept(CQuotesProviderVisitor& visitor)const +{ + CQuotesProviderBase::Accept(visitor); + visitor.Visit(*this); +} + +double CQuotesProviderGoogle::Convert(double dAmount,const CQuote& from,const CQuote& to)const +{ + tstring sFullURL = build_url(GetURL(),from.GetID(),to.GetID(),dAmount); +// LogIt(Info,sFullURL); + + CHTTPSession http; + if ((true == http.OpenURL(sFullURL))) + { + tstring sHTML; + if ((true == http.ReadResponce(sHTML))) + { +// LogIt(Info,sHTML); + + double dResult = 0.0; + if ((true == parse_responce(sHTML,dResult))) + { + return dResult; + } + else + { + throw std::runtime_error(Translate("Error occurred during html parsing.")); + } + } + else + { + throw std::runtime_error(Translate("Error occurred during site access.")); + } + } + else + { + throw std::runtime_error(Translate("Error occurred during site access.")); + } + + return 0.0; +} + +namespace +{ + bool is_equal_ids(HANDLE hContact,const tstring& rsFromID,const tstring& rsToID) + { + tstring sFrom = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_FROM_ID); + tstring sTo = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_TO_ID); + return ((0 == quotes_stricmp(rsFromID.c_str(),sFrom.c_str())) + && (0 == quotes_stricmp(rsToID.c_str(),sTo.c_str()))); + } +} + +HANDLE CQuotesProviderGoogle::GetContactByID(const tstring& rsFromID,const tstring& rsToID)const +{ + CGuard cs(m_cs); + + TContracts::const_iterator i = std::find_if(m_aContacts.begin(),m_aContacts.end(), + boost::bind(is_equal_ids,_1,boost::cref(rsFromID),boost::cref(rsToID))); + if(i != m_aContacts.end()) + { + return *i; + } + else + { + return NULL; + } +} diff --git a/protocols/Quotes/QuotesProviderGoogle.h b/protocols/Quotes/QuotesProviderGoogle.h new file mode 100644 index 0000000000..4289861178 --- /dev/null +++ b/protocols/Quotes/QuotesProviderGoogle.h @@ -0,0 +1,42 @@ +#ifndef __c0e48a95_b3f0_4227_8adc_455e265f3c14_QuotesProviderGoogle_h__ +#define __c0e48a95_b3f0_4227_8adc_455e265f3c14_QuotesProviderGoogle_h__ + +#include "quotesproviderBase.h" + +#define DB_STR_FROM_ID "FromID" +#define DB_STR_TO_ID "ToID" +#define DB_STR_FROM_DESCRIPTION "FromDesc" +#define DB_STR_TO_DESCRIPTION "ToDesc" +#define DB_STR_GOOGLE_REFRESH_RATE_TYPE "Google_RefreshRateType" +#define DB_STR_GOOGLE_REFRESH_RATE_VALUE "Google_RefreshRateValue" +#define DB_STR_GOOGLE_DISPLAY_NAME_FORMAT "Google_DspNameFrmt" +// #define DB_STR_GOOGLE_LOG_FILE_FORMAT "Google_LogFileFormat" +// #define DB_STR_GOOGLE_HISTORY_FORMAT "Google_HistoryFormat" + +class CQuotesProviderGoogle : public CQuotesProviderBase +{ +public: + struct CRateInfo + { + CQuotesProviderBase::CQuote m_from; + CQuotesProviderBase::CQuote m_to; + }; +public: + CQuotesProviderGoogle(); + ~CQuotesProviderGoogle(); + + bool WatchForRate(const CRateInfo& ri,bool bWatch); + size_t GetWatchedRateCount()const; + bool GetWatchedRateInfo(size_t nIndex,CRateInfo& rRateInfo); + + HANDLE GetContactByID(const tstring& rsFromID,const tstring& rsToID)const; + + double Convert(double dAmount,const CQuote& from,const CQuote& to)const; + +private: + virtual void RefreshQuotes(TContracts& anContacts); + virtual void ShowPropertyPage(WPARAM wp,OPTIONSDIALOGPAGE& odp); + virtual void Accept(CQuotesProviderVisitor& visitor)const; +}; + +#endif //__c0e48a95_b3f0_4227_8adc_455e265f3c14_QuotesProviderGoogle_h__ diff --git a/protocols/Quotes/QuotesProviderGoogleFinance.cpp b/protocols/Quotes/QuotesProviderGoogleFinance.cpp new file mode 100644 index 0000000000..8a129b6b8b --- /dev/null +++ b/protocols/Quotes/QuotesProviderGoogleFinance.cpp @@ -0,0 +1,366 @@ +#include "StdAfx.h" +#include "QuotesProviderGoogleFinance.h" +#include "QuotesProviderVisitor.h" +#include "EconomicRateInfo.h" +#include "DBUtils.h" +#include "resource.h" +#include "ModuleInfo.h" +// #include "QuotesProviders.h" +// #include "CommonOptionDlg.h" +// #include "WinCtrlHelper.h" +#include "IHTMLParser.h" +#include "IHTMLEngine.h" +#include "HTTPSession.h" +#include "Log.h" +#include "Locale.h" + +CQuotesProviderGoogleFinance::CQuotesProviderGoogleFinance() +{ +} + +CQuotesProviderGoogleFinance::~CQuotesProviderGoogleFinance() +{ +} + +namespace +{ + tstring build_url(HANDLE hContact,const tstring& rsURL) + { + tostringstream o; + o << rsURL << _T("?q=") << Quotes_DBGetStringT(hContact,QUOTES_MODULE_NAME,DB_STR_QUOTE_ID); + return o.str(); + } + + struct CGoogleInfo + { + enum + { + giRate = 0x0001, + giOpen = 0x0002, + giPercentChangeAfterHours = 0x0004, + giPercentChangeToYesterdayClose = 0x0008 + }; + CGoogleInfo() + : m_dRate(0.0),m_dOpenValue(0.0),m_dPercentChangeAfterHours(0.0),m_dPercentChangeToYersterdayClose(0.0),m_nFlags(0){} +// tstring m_sCmpID; + tstring m_sCmpName; + double m_dRate; + double m_dOpenValue; + double m_dPercentChangeAfterHours; + double m_dPercentChangeToYersterdayClose; + +// tstring m_sRateID; +// tstring m_sDiffID; + byte m_nFlags; + }; + + tstring make_rate_id_value(const tstring& rsCmpID,int nFlags) + { + tostringstream o; + o << _T("ref_") << rsCmpID; + switch(nFlags) + { + default: + assert(!"Unknown type of value"); + case CGoogleInfo::giRate: + o << _T("_l"); + break; + case CGoogleInfo::giPercentChangeAfterHours: + o << _T("_ecp"); + break; + case CGoogleInfo::giPercentChangeToYesterdayClose: + o << _T("_cp"); + break; + } + + return o.str(); + } + + tstring get_var_value(const tstring& rsHTML,LPCTSTR pszVarName,size_t cVarNameLength) + { + tstring sResult; + tstring::size_type n = rsHTML.find(pszVarName); + if(tstring::npos != n) + { + size_t cLengthHTML = rsHTML.size(); + for(size_t i = n + cVarNameLength;i < cLengthHTML;++i) + { + TCHAR c = rsHTML[i]; + if(_T(';') == c) + { + break; + } + else + { + sResult.push_back(c); + } + } + } + + return sResult; + } + + tstring get_company_id(const tstring& rsHTML) + { + static LPCTSTR pszVarName = _T("setCompanyId("); + static size_t cVarNameLength = _tcslen(pszVarName); + + tstring sResult; + tstring::size_type n = rsHTML.find(pszVarName); + if(tstring::npos != n) + { + size_t cLengthHTML = rsHTML.size(); + for(size_t i = n + cVarNameLength;i < cLengthHTML;++i) + { + TCHAR c = rsHTML[i]; + if(_T(')') == c) + { + break; + } + else + { + sResult.push_back(c); + } + } + } + return sResult; +// return get_var_value(rsHTML,pszVarName,cVarNameLength); + } + + tstring get_company_name(const tstring& rsHTML) + { + static LPCTSTR pszVarName = _T("var _companyName = "); + static size_t cVarNameLength = _tcslen(pszVarName); + + tstring s = get_var_value(rsHTML,pszVarName,cVarNameLength); + if(s.size() > 0 && _T('\'') == s[0]) + { + s.erase(s.begin()); + } + + if(s.size() > 0 && _T('\'') == s[s.size()-1]) + { + s.erase(s.rbegin().base()-1); + } + + return s; + } + + bool get_double_value(const tstring& rsText,double& rdValue) + { + tistringstream input(rsText); + input.imbue(std::locale("English_United States.1252")); + input >> rdValue; + + if ((true == input.bad()) || (true == input.fail())) + { + tistringstream inputSys(rsText); + input.imbue(GetSystemLocale()); + input >> rdValue; + return (false == inputSys.bad()) && (false == inputSys.fail()); + } + else + { + return true; + } + } + + bool get_rate(const IHTMLNode::THTMLNodePtr& pRate,CGoogleInfo& rInfo) + { + tstring sRate = pRate->GetText(); + + if(true == get_double_value(sRate,rInfo.m_dRate)) + { + rInfo.m_nFlags |= CGoogleInfo::giRate; + return true; + } + else + { + return false; + } + } + + bool get_inline_data(const IHTMLNode::THTMLNodePtr& pNode,CGoogleInfo& rInfo) + { + size_t cChild = pNode->GetChildCount(); + for(size_t i = 0;i < cChild;++i) + { + IHTMLNode::THTMLNodePtr pChild = pNode->GetChildPtr(i); + size_t c = pChild->GetChildCount(); + assert(2 == c); + if(c >= 2) + { + IHTMLNode::THTMLNodePtr pName = pChild->GetChildPtr(0); + + tstring sName = pName->GetText(); + if(0 == quotes_stricmp(sName.c_str(),_T("Open"))) + { + IHTMLNode::THTMLNodePtr pValue = pChild->GetChildPtr(1); + tstring sValue = pValue->GetText(); + if(true == get_double_value(sValue,rInfo.m_dOpenValue)) + { + rInfo.m_nFlags |= CGoogleInfo::giOpen; + } + return true; + } + } + } + + return false; + } + + bool get_dif_value(const IHTMLNode::THTMLNodePtr& pNode,CGoogleInfo& rInfo,int nItem) + { + tstring sDiff = pNode->GetText(); + // this value is in brackets and it has percentage sign. + // Remove these symbols. + for(tstring::iterator i = sDiff.begin();i != sDiff.end();) + { + TCHAR s = *i; + if(_T('(') == s || _T(')') == s || _T('%') == s) + { + i = sDiff.erase(i); + } + else + { + ++i; + } + } + + double* pValue = NULL; + switch(nItem) + { + case CGoogleInfo::giPercentChangeAfterHours: + pValue = &rInfo.m_dPercentChangeAfterHours; + break; + case CGoogleInfo::giPercentChangeToYesterdayClose: + pValue = &rInfo.m_dPercentChangeToYersterdayClose; + break; + } + + assert(pValue); + + if ((pValue) && (true == get_double_value(sDiff,*pValue))) + { + rInfo.m_nFlags |= nItem; + return true; + } + else + { + return false; + } + + } + + bool parse_responce(const tstring& rsHTML,CGoogleInfo& rInfo) + { + IHTMLEngine::THTMLParserPtr pHTMLParser = CModuleInfo::GetHTMLEngine()->GetParserPtr(); + IHTMLNode::THTMLNodePtr pRoot = pHTMLParser->ParseString(rsHTML); + if(pRoot) + { + tstring sCmpID = get_company_id(rsHTML); + if(false == sCmpID.empty()) + { + tstring sRateID = make_rate_id_value(sCmpID,CGoogleInfo::giRate); + IHTMLNode::THTMLNodePtr pRate = pRoot->GetElementByID(sRateID); + if(pRate && get_rate(pRate,rInfo)) + { + rInfo.m_sCmpName = get_company_name(rsHTML); + + IHTMLNode::THTMLNodePtr pInline = pRoot->GetElementByID(_T("snap-data")); + if(pInline) + { + get_inline_data(pInline,rInfo); + } + + tstring sDiffID = make_rate_id_value(sCmpID,CGoogleInfo::giPercentChangeAfterHours); + IHTMLNode::THTMLNodePtr pDiff = pRoot->GetElementByID(sDiffID); + if(pDiff) + { + get_dif_value(pDiff,rInfo,CGoogleInfo::giPercentChangeAfterHours); + } + + sDiffID = make_rate_id_value(sCmpID,CGoogleInfo::giPercentChangeToYesterdayClose); + pDiff = pRoot->GetElementByID(sDiffID); + if(pDiff) + { + get_dif_value(pDiff,rInfo,CGoogleInfo::giPercentChangeToYesterdayClose); + } + + return true; + } + + //return (true == parse_html_node(pRoot,rInfo)); + } + } + + return false; + } +} + +void CQuotesProviderGoogleFinance::RefreshQuotes(TContracts& anContacts) +{ + CHTTPSession http; + tstring sURL = GetURL(); + bool bUseExtendedStatus = CModuleInfo::GetInstance().GetExtendedStatusFlag(); + + for(TContracts::const_iterator i = anContacts.begin();i != anContacts.end() && IsOnline();++i) + { + HANDLE hContact = *i; + + if(bUseExtendedStatus) + { + SetContactStatus(hContact,ID_STATUS_OCCUPIED); + } + + tstring sFullURL = build_url(hContact,sURL); +// LogIt(Info,sFullURL); + if ((true == http.OpenURL(sFullURL)) && (true == IsOnline())) + { + tstring sHTML; + if ((true == http.ReadResponce(sHTML)) && (true == IsOnline())) + { +// LogIt(Info,sHTML); + + CGoogleInfo Info; + parse_responce(sHTML,Info); + if(true == IsOnline()) + { + if(Info.m_nFlags&CGoogleInfo::giRate) + { + if(Info.m_nFlags&CGoogleInfo::giOpen) + { + Quotes_DBWriteDouble(hContact,QUOTES_MODULE_NAME,DB_STR_GOOGLE_FINANCE_OPEN_VALUE,Info.m_dOpenValue); + } + if(Info.m_nFlags&CGoogleInfo::giPercentChangeAfterHours) + { + Quotes_DBWriteDouble(hContact,QUOTES_MODULE_NAME,DB_STR_GOOGLE_FINANCE_DIFF,Info.m_dPercentChangeAfterHours); + } + if(Info.m_nFlags&CGoogleInfo::giPercentChangeToYesterdayClose) + { + Quotes_DBWriteDouble(hContact,QUOTES_MODULE_NAME,DB_STR_GOOGLE_FINANCE_PERCENT_CHANGE_TO_YERSTERDAY_CLOSE,Info.m_dPercentChangeToYersterdayClose); + } + if(false == Info.m_sCmpName.empty()) + { + DBWriteContactSettingTString(hContact,QUOTES_MODULE_NAME,DB_STR_QUOTE_DESCRIPTION,Info.m_sCmpName.c_str()); + } + + WriteContactRate(hContact,Info.m_dRate); + continue; + } + } + } + } + + SetContactStatus(hContact,ID_STATUS_NA); + } + +} + + +void CQuotesProviderGoogleFinance::Accept(CQuotesProviderVisitor& visitor)const +{ + CQuotesProviderFinance::Accept(visitor); + visitor.Visit(*this); +} + diff --git a/protocols/Quotes/QuotesProviderGoogleFinance.h b/protocols/Quotes/QuotesProviderGoogleFinance.h new file mode 100644 index 0000000000..075498a4dd --- /dev/null +++ b/protocols/Quotes/QuotesProviderGoogleFinance.h @@ -0,0 +1,25 @@ +#ifndef __89D3CC58_7DED_484f_AA25_62BDBB57E18B_QuotesProvider_Google_Finance_h__ +#define __89D3CC58_7DED_484f_AA25_62BDBB57E18B_QuotesProvider_Google_Finance_h__ + +#include "QuotesProviderFinance.h" + +#define DB_STR_GOOGLE_FINANCE_OPEN_VALUE "OpenQuotePrice" +#define DB_STR_GOOGLE_FINANCE_DIFF "DifferentFromStartOfDay" +#define DB_STR_GOOGLE_FINANCE_PERCENT_CHANGE_TO_YERSTERDAY_CLOSE "PercentChangeToYersterdayClose" + +// #define DB_STR_GOOGLE_FINANCE_COMP_NAME "CompanyName" + + +class CQuotesProviderGoogleFinance : public CQuotesProviderFinance +{ + +public: + CQuotesProviderGoogleFinance(); + ~CQuotesProviderGoogleFinance(); + +private: + virtual void RefreshQuotes(TContracts& anContacts); + virtual void Accept(CQuotesProviderVisitor& visitor)const; +}; + +#endif //__89D3CC58_7DED_484f_AA25_62BDBB57E18B_QuotesProvider_Google_Finance_h__ diff --git a/protocols/Quotes/QuotesProviderVisitor.h b/protocols/Quotes/QuotesProviderVisitor.h new file mode 100644 index 0000000000..9ae601f2a1 --- /dev/null +++ b/protocols/Quotes/QuotesProviderVisitor.h @@ -0,0 +1,25 @@ +#ifndef __7fca59e7_17b2_4849_bd7a_02c7675f2d76_QuotesProviderVisitor_h__ +#define __7fca59e7_17b2_4849_bd7a_02c7675f2d76_QuotesProviderVisitor_h__ + +class CQuotesProviderBase; +class CQuotesProviderFinance; +class CQuotesProviderDukasCopy; +class CQuotesProviderGoogle; +class CQuotesProviderGoogleFinance; +class CQuotesProviderYahoo; + +class CQuotesProviderVisitor +{ +public: + CQuotesProviderVisitor() {} + virtual ~CQuotesProviderVisitor() {} + + virtual void Visit(const CQuotesProviderBase& rProvider){} + virtual void Visit(const CQuotesProviderFinance& rProvider){} + virtual void Visit(const CQuotesProviderDukasCopy& rProvider){} + virtual void Visit(const CQuotesProviderGoogle& rProvider){} + virtual void Visit(const CQuotesProviderGoogleFinance& rProvider){} + virtual void Visit(const CQuotesProviderYahoo& rProvider){} +}; + +#endif //__7fca59e7_17b2_4849_bd7a_02c7675f2d76_QuotesProviderVisitor_h__ diff --git a/protocols/Quotes/QuotesProviderVisitorDbSettings.cpp b/protocols/Quotes/QuotesProviderVisitorDbSettings.cpp new file mode 100644 index 0000000000..5caea48685 --- /dev/null +++ b/protocols/Quotes/QuotesProviderVisitorDbSettings.cpp @@ -0,0 +1,157 @@ +#include "StdAfx.h" +#include "QuotesProviderVisitorDbSettings.h" + +#include "QuotesProviderGoogle.h" +#include "QuotesProviderDukasCopy.h" + +CQuotesProviderVisitorDbSettings::CQuotesProviderVisitorDbSettings() + : m_pszDbRefreshRateType(NULL), + m_pszDbRefreshRateValue(NULL), + m_pszDbDisplayNameFormat(NULL), + m_pszDefDisplayFormat(NULL), + m_pszDefLogFileFormat(NULL), + m_pszDefHistoryFormat(NULL), + m_pszXMLIniFileName(NULL), + m_pszDbStatusMsgFormat(NULL), + m_pszDefStatusMsgFormat(NULL), + m_pszDbLogMode(NULL), + m_pszDbHistoryFormat(NULL), + m_pszDbHistoryCondition(NULL), + m_pszDbLogFile(NULL), + m_pszDbLogFormat(NULL), + m_pszDbLogCondition(NULL), + m_pszDbPopupFormat(NULL), + m_pszDefPopupFormat(NULL), + m_pszDbPopupCondition(NULL), + m_pszDbPopupColourMode(NULL), + m_pszDbPopupBkColour(NULL), + m_pszDbPopupTextColour(NULL), + m_pszDbPopupDelayMode(NULL), + m_pszDbPopupDelayTimeout(NULL), + m_pszDbPopupHistoryFlag(NULL), + m_pszDbTendencyFormat(nullptr), + m_pszDefTendencyFormat(_T("%r>%p")) +{ +} + +CQuotesProviderVisitorDbSettings::~CQuotesProviderVisitorDbSettings() +{ +} + +void CQuotesProviderVisitorDbSettings::Visit(const CQuotesProviderBase&/* rProvider*/) +{ + m_pszDefLogFileFormat = _T("%s\\t%t\\t%r\\n"); + m_pszDefHistoryFormat = _T("%s %r"); + m_pszDefPopupFormat = _T("\\nCurrent = %r\\nPrevious = %p"); +} + +void CQuotesProviderVisitorDbSettings::Visit(const CQuotesProviderDukasCopy&/* rProvider*/) +{ + m_pszDbRefreshRateType = DB_STR_REFRESH_RATE_TYPE; + m_pszDbRefreshRateValue = DB_STR_REFRESH_RATE_VALUE; + m_pszDbDisplayNameFormat = DB_STR_DC_DISPLAY_NAME_FORMAT; + m_pszDefDisplayFormat = _T("%s %r"); + m_pszXMLIniFileName = _T("Dukascopy.xml"); + m_pszDbStatusMsgFormat = "DC_StatusMessageFormat"; + + m_pszDbLogMode = "DC_LogMode"; + m_pszDbHistoryFormat = "DC_HistoryFormat"; + m_pszDbHistoryCondition = "DC_AddToHistoryOnlyIfValueIsChanged"; + m_pszDbLogFile = "DC_LogFile"; + m_pszDbLogFormat = "DC_LogFileFormat"; + m_pszDbLogCondition = "DC_AddToLogOnlyIfValueIsChanged"; + m_pszDbPopupFormat ="DC_PopupFormat"; + m_pszDbPopupCondition = "DC_ShowPopupOnlyIfValueChanged"; + + m_pszDbPopupColourMode = "DC_PopupColourMode"; + m_pszDbPopupBkColour = "DC_PopupColourBk"; + m_pszDbPopupTextColour = "DC_PopupColourText"; + m_pszDbPopupDelayMode = "DC_PopupDelayMode"; + m_pszDbPopupDelayTimeout = "DC_PopupDelayTimeout"; + m_pszDbPopupHistoryFlag = "DC_PopupHistoryFlag"; + m_pszDbTendencyFormat = "DC_TendencyFormat"; +} + +void CQuotesProviderVisitorDbSettings::Visit(const CQuotesProviderGoogle&/* rProvider*/) +{ + m_pszDbRefreshRateType = DB_STR_GOOGLE_REFRESH_RATE_TYPE; + m_pszDbRefreshRateValue = DB_STR_GOOGLE_REFRESH_RATE_VALUE; + m_pszDbDisplayNameFormat = DB_STR_GOOGLE_DISPLAY_NAME_FORMAT; + m_pszDefDisplayFormat = _T("1 %f = %r %i"); + m_pszXMLIniFileName = _T("Google.xml"); + m_pszDbStatusMsgFormat = "Google_StatusMessageFormat"; + + m_pszDbLogMode = "Google_LogMode"; + m_pszDbHistoryFormat = "Google_HistoryFormat"; + m_pszDbHistoryCondition = "Google_AddToHistoryOnlyIfValueIsChanged"; + m_pszDbLogFile = "Google_LogFile"; + m_pszDbLogFormat = "Google_LogFileFormat"; + m_pszDbLogCondition = "Google_AddToLogOnlyIfValueIsChanged"; + m_pszDbPopupFormat ="Google_PopupFormat"; + m_pszDbPopupCondition = "Google_ShowPopupOnlyIfValueChanged"; + + m_pszDbPopupColourMode = "Google_PopupColourMode"; + m_pszDbPopupBkColour = "Google_PopupColourBk"; + m_pszDbPopupTextColour = "Google_PopupColourText"; + m_pszDbPopupDelayMode = "Google_PopupDelayMode"; + m_pszDbPopupDelayTimeout = "Google_PopupDelayTimeout"; + m_pszDbPopupHistoryFlag = "Google_PopupHistoryFlag"; + + m_pszDbTendencyFormat = "Google_TendencyFormat"; +} + +void CQuotesProviderVisitorDbSettings::Visit(const CQuotesProviderGoogleFinance&/* rProvider*/) +{ + m_pszDbRefreshRateType = "GoogleFinance_RefreshRateType"; + m_pszDbRefreshRateValue = "GoogleFinance_RefreshRateValue"; + m_pszDbDisplayNameFormat = "GoogleFinance_DspNameFrmt"; + m_pszDefDisplayFormat = _T("%s %r"); + m_pszXMLIniFileName = _T("GoogleFinance.xml"); + m_pszDbStatusMsgFormat = "GoogleFinance_StatusMessageFormat"; + + m_pszDbLogMode = "GoogleFinance_LogMode"; + m_pszDbHistoryFormat = "GoogleFinance_HistoryFormat"; + m_pszDbHistoryCondition = "GoogleFinance_AddToHistoryOnlyIfValueIsChanged"; + m_pszDbLogFile = "GoogleFinance_LogFile"; + m_pszDbLogFormat = "GoogleFinance_LogFileFormat"; + m_pszDbLogCondition = "GoogleFinance_AddToLogOnlyIfValueIsChanged"; + m_pszDbPopupFormat ="GoogleFinance_PopupFormat"; + m_pszDbPopupCondition = "GoogleFinance_ShowPopupOnlyIfValueChanged"; + + m_pszDbPopupColourMode = "GoogleFinance_PopupColourMode"; + m_pszDbPopupBkColour = "GoogleFinance_PopupColourBk"; + m_pszDbPopupTextColour = "GoogleFinance_PopupColourText"; + m_pszDbPopupDelayMode = "GoogleFinance_PopupDelayMode"; + m_pszDbPopupDelayTimeout = "GoogleFinance_PopupDelayTimeout"; + m_pszDbPopupHistoryFlag = "GoogleFinance_PopupHistoryFlag"; + + m_pszDbTendencyFormat = "GoogleFinance_TendencyFormat"; +} + +void CQuotesProviderVisitorDbSettings::Visit(const CQuotesProviderYahoo& rProvider) +{ + m_pszDbRefreshRateType = "Yahoo_RefreshRateType"; + m_pszDbRefreshRateValue = "Yahoo_RefreshRateValue"; + m_pszDbDisplayNameFormat = "Yahoo_DspNameFrmt"; + m_pszDefDisplayFormat = _T("%s %r"); + m_pszXMLIniFileName = _T("Yahoo.xml"); + m_pszDbStatusMsgFormat = "Yahoo_StatusMessageFormat"; + + m_pszDbLogMode = "Yahoo_LogMode"; + m_pszDbHistoryFormat = "Yahoo_HistoryFormat"; + m_pszDbHistoryCondition = "Yahoo_AddToHistoryOnlyIfValueIsChanged"; + m_pszDbLogFile = "Yahoo_LogFile"; + m_pszDbLogFormat = "Yahoo_LogFileFormat"; + m_pszDbLogCondition = "Yahoo_AddToLogOnlyIfValueIsChanged"; + m_pszDbPopupFormat ="Yahoo_PopupFormat"; + m_pszDbPopupCondition = "Yahoo_ShowPopupOnlyIfValueChanged"; + + m_pszDbPopupColourMode = "Yahoo_PopupColourMode"; + m_pszDbPopupBkColour = "Yahoo_PopupColourBk"; + m_pszDbPopupTextColour = "Yahoo_PopupColourText"; + m_pszDbPopupDelayMode = "Yahoo_PopupDelayMode"; + m_pszDbPopupDelayTimeout = "Yahoo_PopupDelayTimeout"; + m_pszDbPopupHistoryFlag = "Yahoo_PopupHistoryFlag"; + + m_pszDbTendencyFormat = "Yahoo_TendencyFormat"; +} diff --git a/protocols/Quotes/QuotesProviderVisitorDbSettings.h b/protocols/Quotes/QuotesProviderVisitorDbSettings.h new file mode 100644 index 0000000000..728a436dfa --- /dev/null +++ b/protocols/Quotes/QuotesProviderVisitorDbSettings.h @@ -0,0 +1,49 @@ +#ifndef __97cd432a_1119_4803_a96f_0abc1cc2653f_QuotesProviderVisitorDbSettings_h__ +#define __97cd432a_1119_4803_a96f_0abc1cc2653f_QuotesProviderVisitorDbSettings_h__ + +#include "quotesprovidervisitor.h" + +class CQuotesProviderVisitorDbSettings : public CQuotesProviderVisitor +{ +public: + CQuotesProviderVisitorDbSettings(); + ~CQuotesProviderVisitorDbSettings(); + +private: + virtual void Visit(const CQuotesProviderBase& rProvider); + virtual void Visit(const CQuotesProviderDukasCopy& rProvider); + virtual void Visit(const CQuotesProviderGoogle& rProvider); + virtual void Visit(const CQuotesProviderGoogleFinance& rProvider); + virtual void Visit(const CQuotesProviderYahoo& rProvider); +public: + LPCSTR m_pszDbRefreshRateType; + LPCSTR m_pszDbRefreshRateValue; + LPCSTR m_pszDbDisplayNameFormat; + LPCTSTR m_pszDefDisplayFormat; + LPCTSTR m_pszDefLogFileFormat; + LPCTSTR m_pszDefHistoryFormat; + LPCTSTR m_pszXMLIniFileName; + LPCSTR m_pszDbStatusMsgFormat; + LPCTSTR m_pszDefStatusMsgFormat; + LPCTSTR m_pszDefPopupFormat; + LPCSTR m_pszDbTendencyFormat; + LPCTSTR m_pszDefTendencyFormat; + + //global settings + LPCSTR m_pszDbLogMode; + LPCSTR m_pszDbHistoryFormat; + LPCSTR m_pszDbHistoryCondition; + LPCSTR m_pszDbLogFile; + LPCSTR m_pszDbLogFormat; + LPCSTR m_pszDbLogCondition; + LPCSTR m_pszDbPopupFormat; + LPCSTR m_pszDbPopupCondition; + LPCSTR m_pszDbPopupColourMode; + LPCSTR m_pszDbPopupBkColour; + LPCSTR m_pszDbPopupTextColour; + LPCSTR m_pszDbPopupDelayMode; + LPCSTR m_pszDbPopupDelayTimeout; + LPCSTR m_pszDbPopupHistoryFlag; +}; + +#endif //__97cd432a_1119_4803_a96f_0abc1cc2653f_QuotesProviderVisitorDbSettings_h__ diff --git a/protocols/Quotes/QuotesProviderVisitorFormatSpecificator.cpp b/protocols/Quotes/QuotesProviderVisitorFormatSpecificator.cpp new file mode 100644 index 0000000000..9e643fe1b6 --- /dev/null +++ b/protocols/Quotes/QuotesProviderVisitorFormatSpecificator.cpp @@ -0,0 +1,63 @@ +#include "StdAfx.h" +#include "QuotesProviderVisitorFormatSpecificator.h" + +CQuotesProviderVisitorFormatSpecificator::CQuotesProviderVisitorFormatSpecificator() +{ +} + +CQuotesProviderVisitorFormatSpecificator::~CQuotesProviderVisitorFormatSpecificator() +{ +} + +void CQuotesProviderVisitorFormatSpecificator::Visit(const CQuotesProviderDukasCopy&/* rProvider*/) +{ + m_aSpecificators.push_back(CFormatSpecificator(_T("%s"),TranslateT("Quote Symbol"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%d"),TranslateT("Quote Name"))); +} + +void CQuotesProviderVisitorFormatSpecificator::Visit(const CQuotesProviderGoogle&/* rProvider*/) +{ + m_aSpecificators.push_back(CFormatSpecificator(_T("%F"),TranslateT("From Currency Full Name"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%f"),TranslateT("From Currency Short Name"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%I"),TranslateT("Into Currency Full Name"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%i"),TranslateT("Into Currency Short Name"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%s"),TranslateT("Short notation for \"%f/%i\""))); +} + +void CQuotesProviderVisitorFormatSpecificator::Visit(const CQuotesProviderBase&/* rProvider*/) +{ + m_aSpecificators.push_back(CFormatSpecificator(_T("%S"),TranslateT("Source of Information"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%r"),TranslateT("Rate Value"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%p"),TranslateT("Previous Rate Value"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%X"),TranslateT("Fetch Time"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%x"),TranslateT("Fetch Date"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%t"),TranslateT("Fetch Time and Date"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("\\%"),TranslateT("Percentage Character (%)"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("\\t"),TranslateT("Tabulation"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("\\\\"),TranslateT("Left slash (\\)"))); +} + +void CQuotesProviderVisitorFormatSpecificator::Visit(const CQuotesProviderGoogleFinance&/* rProvider*/) +{ + m_aSpecificators.push_back(CFormatSpecificator(_T("%s"),TranslateT("Quote Symbol"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%n"),TranslateT("Quote Name"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%o"),TranslateT("Open Price"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%d"),TranslateT("Percent Change to After Hours"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%y"),TranslateT("Percent Change to Yesterday Close"))); +} + +const CQuotesProviderVisitorFormatSpecificator::TFormatSpecificators& CQuotesProviderVisitorFormatSpecificator::GetSpecificators()const +{ + return m_aSpecificators; +} + +void CQuotesProviderVisitorFormatSpecificator::Visit(const CQuotesProviderYahoo& rProvider) +{ + m_aSpecificators.push_back(CFormatSpecificator(_T("%s"),TranslateT("Quote Symbol"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%n"),TranslateT("Quote Name"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%o"),TranslateT("Open Price"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%h"),TranslateT("Day's High"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%g"),TranslateT("Day's Low"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%P"),TranslateT("Previous Close"))); + m_aSpecificators.push_back(CFormatSpecificator(_T("%c"),TranslateT("Change"))); +} diff --git a/protocols/Quotes/QuotesProviderVisitorFormatSpecificator.h b/protocols/Quotes/QuotesProviderVisitorFormatSpecificator.h new file mode 100644 index 0000000000..870ab00634 --- /dev/null +++ b/protocols/Quotes/QuotesProviderVisitorFormatSpecificator.h @@ -0,0 +1,36 @@ +#ifndef __00c159f3_525a_41e9_8fc5_00464b6fafa3_QuotesProviderVisitorFormatSpecificator_h__ +#define __00c159f3_525a_41e9_8fc5_00464b6fafa3_QuotesProviderVisitorFormatSpecificator_h__ + +#include "quotesprovidervisitor.h" + +class CQuotesProviderVisitorFormatSpecificator : public CQuotesProviderVisitor +{ +public: + struct CFormatSpecificator + { + CFormatSpecificator(const tstring& rsSymbol = _T(""),const tstring& rsDec = _T("")) + : m_sSymbol(rsSymbol),m_sDesc(rsDec){} + + tstring m_sSymbol; + tstring m_sDesc; + }; + typedef std::vector TFormatSpecificators; + +public: + CQuotesProviderVisitorFormatSpecificator(); + ~CQuotesProviderVisitorFormatSpecificator(); + + const TFormatSpecificators& GetSpecificators()const; + +private: + virtual void Visit(const CQuotesProviderDukasCopy& rProvider); + virtual void Visit(const CQuotesProviderGoogle& rProvider); + virtual void Visit(const CQuotesProviderBase& rProvider); + virtual void Visit(const CQuotesProviderGoogleFinance& rProvider); + virtual void Visit(const CQuotesProviderYahoo& rProvider); + +private: + TFormatSpecificators m_aSpecificators; +}; + +#endif//__00c159f3_525a_41e9_8fc5_00464b6fafa3_QuotesProviderVisitorFormatSpecificator_h__ diff --git a/protocols/Quotes/QuotesProviderVisitorFormater.cpp b/protocols/Quotes/QuotesProviderVisitorFormater.cpp new file mode 100644 index 0000000000..4b1d73bb05 --- /dev/null +++ b/protocols/Quotes/QuotesProviderVisitorFormater.cpp @@ -0,0 +1,216 @@ +#include "StdAfx.h" +#include "QuotesProviderVisitorFormater.h" +#include "DBUtils.h" +#include "EconomicRateInfo.h" +#include "QuotesProviderGoogle.h" +#include "Locale.h" +#include "IsWithinAccuracy.h" +#include "QuotesProviderGoogleFinance.h" +#include "QuotesProviderYahoo.h" + +CQuotesProviderVisitorFormater::CQuotesProviderVisitorFormater(HANDLE hContact,TCHAR chr,int nWidth) + : m_hContact(hContact), + m_chr(chr), + m_nWidth(nWidth) +{ +} + +CQuotesProviderVisitorFormater::~CQuotesProviderVisitorFormater() +{ +} + +const tstring& CQuotesProviderVisitorFormater::GetResult()const +{ + return m_sResult; +} + +void CQuotesProviderVisitorFormater::Visit(const CQuotesProviderDukasCopy& rProvider) +{ + if(_T('d') == m_chr || _T('D') == m_chr) + { + m_sResult = Quotes_DBGetStringT(m_hContact,QUOTES_MODULE_NAME,DB_STR_QUOTE_DESCRIPTION); + } +} + +void CQuotesProviderVisitorFormater::Visit(const CQuotesProviderGoogle& rProvider) +{ + switch(m_chr) + { + case _T('F'): + m_sResult = Quotes_DBGetStringT(m_hContact,QUOTES_MODULE_NAME,DB_STR_FROM_DESCRIPTION); + break; + case _T('f'): + m_sResult = Quotes_DBGetStringT(m_hContact,QUOTES_MODULE_NAME,DB_STR_FROM_ID); + break; + case _T('I'): + m_sResult = Quotes_DBGetStringT(m_hContact,QUOTES_MODULE_NAME,DB_STR_TO_DESCRIPTION); + break; + case _T('i'): + m_sResult = Quotes_DBGetStringT(m_hContact,QUOTES_MODULE_NAME,DB_STR_TO_ID); + break; + } +} + +namespace +{ + bool get_fetch_time(HANDLE hContact,time_t& rTime) + { + DBVARIANT dbv; + DBCONTACTGETSETTING cgs; + + cgs.szModule=QUOTES_MODULE_NAME; + cgs.szSetting=DB_STR_QUOTE_FETCH_TIME; + cgs.pValue=&dbv; + if(CallService(MS_DB_CONTACT_GETSETTING,reinterpret_cast(hContact),reinterpret_cast(&cgs)) + || (DBVT_DWORD != dbv.type)) + { + return false; + } + + rTime = dbv.dVal; + return true; + } + + tstring format_fetch_time(const CQuotesProviderBase& rProvider,HANDLE 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(); + } +} + +void CQuotesProviderVisitorFormater::Visit(const CQuotesProviderBase& rProvider) +{ + switch(m_chr) + { +// default: +// m_sResult = m_chr; +// break; + case _T('%'): + case _T('\t'): + case _T('\\'): + m_sResult = m_chr; + break; + case _T('S'): + m_sResult = Quotes_DBGetStringT(m_hContact,QUOTES_MODULE_NAME,DB_STR_QUOTE_PROVIDER); + break; + case _T('s'): + m_sResult = Quotes_DBGetStringT(m_hContact,QUOTES_MODULE_NAME,DB_STR_QUOTE_SYMBOL); + break; + case _T('X'): + //m_sResult = format_fetch_time(rProvider,m_hContact,_T("%H:%M:%S")); + m_sResult = format_fetch_time(rProvider,m_hContact,Quotes_GetTimeFormat(true)); + break; + case _T('x'): + //m_sResult = format_fetch_time(rProvider,m_hContact,_T("%d.%m.%y")); + m_sResult = format_fetch_time(rProvider,m_hContact,Quotes_GetDateFormat(true)); + break; + case _T('t'): + { + tstring sFrmt = Quotes_GetDateFormat(true); + sFrmt += _T(" "); + sFrmt += Quotes_GetTimeFormat(true); + m_sResult = format_fetch_time(rProvider,m_hContact,sFrmt); + + //m_sResult = format_fetch_time(rProvider,m_hContact,_T("%d.%m.%y %H:%M:%S")); + } + break; + case _T('r'): + case _T('R'): + FormatDoubleHelper(DB_STR_QUOTE_CURR_VALUE); + break; + case _T('p'): + FormatDoubleHelper(DB_STR_QUOTE_PREV_VALUE); + break; +// case _T('c'): +// FormatChangeValueHelper(false); +// break; +// case _T('C'): +// FormatChangeValueHelper(true); +// break; + } +} + +void CQuotesProviderVisitorFormater::Visit(const CQuotesProviderGoogleFinance&/* rProvider*/) +{ + switch(m_chr) + { + case _T('o'): + FormatDoubleHelper(DB_STR_GOOGLE_FINANCE_OPEN_VALUE); + break; + case _T('d'): + FormatDoubleHelper(DB_STR_GOOGLE_FINANCE_DIFF,_T("0")); + break; + case _T('y'): + FormatDoubleHelper(DB_STR_GOOGLE_FINANCE_PERCENT_CHANGE_TO_YERSTERDAY_CLOSE,_T("0")); + break; + case _T('n'): + m_sResult = Quotes_DBGetStringT(m_hContact,QUOTES_MODULE_NAME,DB_STR_QUOTE_DESCRIPTION); + break; + } +} + +namespace +{ + 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(); + } +} + +void CQuotesProviderVisitorFormater::FormatDoubleHelper(LPCSTR pszDbSet, + const tstring sInvalid/* = _T("-")*/) +{ + double d = 0.0; + if(true == Quotes_DBReadDouble(m_hContact,QUOTES_MODULE_NAME,pszDbSet,d)) + { + m_sResult = format_double(d,m_nWidth); + } + else + { + m_sResult = sInvalid; + } +} + +void CQuotesProviderVisitorFormater::Visit(const CQuotesProviderYahoo& rProvider) +{ + switch(m_chr) + { + case _T('o'): + FormatDoubleHelper(DB_STR_YAHOO_OPEN_VALUE); + break; + case _T('h'): + FormatDoubleHelper(DB_STR_YAHOO_DAY_HIGH); + break; + case _T('P'): + FormatDoubleHelper(DB_STR_YAHOO_PREVIOUS_CLOSE); + break; + case _T('c'): + FormatDoubleHelper(DB_STR_YAHOO_CHANGE); + break; + case _T('g'): + FormatDoubleHelper(DB_STR_YAHOO_DAY_LOW); + break; + case _T('n'): + m_sResult = Quotes_DBGetStringT(m_hContact,QUOTES_MODULE_NAME,DB_STR_QUOTE_DESCRIPTION); + break; + } + +} diff --git a/protocols/Quotes/QuotesProviderVisitorFormater.h b/protocols/Quotes/QuotesProviderVisitorFormater.h new file mode 100644 index 0000000000..7c9c222269 --- /dev/null +++ b/protocols/Quotes/QuotesProviderVisitorFormater.h @@ -0,0 +1,32 @@ +#ifndef __2b5ddd05_9255_4be0_9408_e59768b70568_QuotesProviderVisitorFormater_h__ +#define __2b5ddd05_9255_4be0_9408_e59768b70568_QuotesProviderVisitorFormater_h__ + +#include "quotesprovidervisitor.h" + +class CQuotesProviderVisitorFormater : public CQuotesProviderVisitor +{ +public: + CQuotesProviderVisitorFormater(HANDLE hContact,TCHAR chr,int nWidth); + ~CQuotesProviderVisitorFormater(); + + const tstring& GetResult()const; + +private: + virtual void Visit(const CQuotesProviderDukasCopy& rProvider); + virtual void Visit(const CQuotesProviderGoogle& rProvider); + virtual void Visit(const CQuotesProviderBase& rProvider); + virtual void Visit(const CQuotesProviderGoogleFinance& rProvider); + virtual void Visit(const CQuotesProviderYahoo& rProvider); + +private: + void FormatDoubleHelper(LPCSTR pszDbSet,const tstring sInvalid = _T("-")); +// void FormatChangeValueHelper(bool bPercentage); + +private: + HANDLE m_hContact; + TCHAR m_chr; + tstring m_sResult; + int m_nWidth; +}; + +#endif //__2b5ddd05_9255_4be0_9408_e59768b70568_QuotesProviderVisitorFormater_h__ diff --git a/protocols/Quotes/QuotesProviderVisitorTendency.cpp b/protocols/Quotes/QuotesProviderVisitorTendency.cpp new file mode 100644 index 0000000000..00703521b3 --- /dev/null +++ b/protocols/Quotes/QuotesProviderVisitorTendency.cpp @@ -0,0 +1,70 @@ +#include "stdafx.h" +#include "QuotesProviderVisitorTendency.h" +#include "DBUtils.h" +#include "QuotesProviderGoogleFinance.h" +#include "EconomicRateInfo.h" +#include "QuotesProviderYahoo.h" + +CQuotesProviderVisitorTendency::CQuotesProviderVisitorTendency(HANDLE hContact,TCHAR chr) + : m_hContact(hContact),m_chr(chr),m_bValid(false),m_dResult(0.0) +{ +} + +void CQuotesProviderVisitorTendency::Visit(const CQuotesProviderBase& rProvider) +{ + switch(m_chr) + { + case _T('r'): + case _T('R'): + GetValue(DB_STR_QUOTE_CURR_VALUE); + break; + case _T('p'): + GetValue(DB_STR_QUOTE_PREV_VALUE); + break; + } +} + +void CQuotesProviderVisitorTendency::Visit(const CQuotesProviderGoogleFinance& rProvider) +{ + switch(m_chr) + { + case _T('o'): + GetValue(DB_STR_GOOGLE_FINANCE_OPEN_VALUE); + break; + case _T('d'): + GetValue(DB_STR_GOOGLE_FINANCE_DIFF); + break; + case _T('y'): + GetValue(DB_STR_GOOGLE_FINANCE_PERCENT_CHANGE_TO_YERSTERDAY_CLOSE); + break; + } +} + +void CQuotesProviderVisitorTendency::Visit(const CQuotesProviderYahoo& rProvider) +{ + switch(m_chr) + { + case _T('o'): + GetValue(DB_STR_YAHOO_OPEN_VALUE); + break; + case _T('h'): + GetValue(DB_STR_YAHOO_DAY_HIGH); + break; + case _T('P'): + GetValue(DB_STR_YAHOO_PREVIOUS_CLOSE); + break; + case _T('c'): + GetValue(DB_STR_YAHOO_CHANGE); + break; + case _T('g'): + GetValue(DB_STR_YAHOO_DAY_LOW); + break; + } + +} + + +void CQuotesProviderVisitorTendency::GetValue(LPCSTR pszDbKeyName) +{ + m_bValid = Quotes_DBReadDouble(m_hContact,QUOTES_MODULE_NAME,pszDbKeyName,m_dResult); +} diff --git a/protocols/Quotes/QuotesProviderVisitorTendency.h b/protocols/Quotes/QuotesProviderVisitorTendency.h new file mode 100644 index 0000000000..fa0f04c5f0 --- /dev/null +++ b/protocols/Quotes/QuotesProviderVisitorTendency.h @@ -0,0 +1,29 @@ +#ifndef __AD721194_E9944366_9CF1_0307460EF32F_QuotesProviderVisitorTendency_h__ +#define __AD721194_E9944366_9CF1_0307460EF32F_QuotesProviderVisitorTendency_h__ + +#include "quotesprovidervisitor.h" + +class CQuotesProviderVisitorTendency : public CQuotesProviderVisitor +{ +public: + CQuotesProviderVisitorTendency(HANDLE hContact,TCHAR chr); + + bool IsValid()const{return m_bValid;} + double GetResult()const{return m_dResult;} + +private: + virtual void Visit(const CQuotesProviderBase& rProvider); + virtual void Visit(const CQuotesProviderGoogleFinance& rProvider); + virtual void Visit(const CQuotesProviderYahoo& rProvider); + +private: + void GetValue(LPCSTR pszDbKeyName); + +private: + HANDLE m_hContact; + TCHAR m_chr; + bool m_bValid; + double m_dResult; +}; + +#endif //__AD721194_E9944366_9CF1_0307460EF32F_QuotesProviderVisitorTendency_h__ diff --git a/protocols/Quotes/QuotesProviderYahoo.cpp b/protocols/Quotes/QuotesProviderYahoo.cpp new file mode 100644 index 0000000000..35edb3207c --- /dev/null +++ b/protocols/Quotes/QuotesProviderYahoo.cpp @@ -0,0 +1,193 @@ +#include "stdafx.h" +#include "QuotesProviderYahoo.h" +#include "QuotesProviderVisitor.h" +#include "ModuleInfo.h" +#include "DBUtils.h" +#include "EconomicRateInfo.h" +#include "HTTPSession.h" + +namespace +{ + void remove_quotes(tstring& s) + { + if (*s.begin() == _T('"')) + { + s.erase(s.begin()); + } + if (*s.rbegin() == _T('"')) + { + tstring::iterator i(s.begin()); + std::advance(i,s.size()-1); + s.erase(i); + } + } + + void remove_end_of_line(tstring& s) + { + if (*s.rbegin() == _T('\n')) + { + tstring::iterator i(s.begin()); + std::advance(i,s.size()-1); + s.erase(i); + } + if (*s.rbegin() == _T('\r')) + { + tstring::iterator i(s.begin()); + std::advance(i,s.size()-1); + s.erase(i); + } + } + + bool t2d(const tstring& s,double& d) + { + tistringstream stream(s); + stream >> d; + return ((false == stream.fail()) && (false == stream.bad())); +// try +// { +// d = boost::lexical_cast(s); +// return true; +// } +// catch(boost::bad_lexical_cast& e) +// { +// } +// return false; + } + + typedef std::vector TStrings; + + bool get_double_from_parsed_line(HANDLE hContact,const TStrings& rasParsedLine,size_t nIndex,const char* pszDbName) + { + if(rasParsedLine.size() > nIndex) + { + double d = 0.0; + if(true == t2d(rasParsedLine[nIndex],d)) + { + return Quotes_DBWriteDouble(hContact,QUOTES_MODULE_NAME,pszDbName,d); + } + } + + DBWriteContactSettingTString(hContact,QUOTES_MODULE_NAME,pszDbName,_T("")); + return false; + } +} + +void CQuotesProviderYahoo::RefreshQuotes(TContracts& anContacts) +{ + tstring sURL = GetURL(); + bool bUseExtendedStatus = CModuleInfo::GetInstance().GetExtendedStatusFlag(); + + typedef std::map TQuoteID2ContractHandles; + TQuoteID2ContractHandles aQuoteID2Handles; + tostringstream oURL; + oURL << sURL << _T("dioksin.txt?s="); + for(TContracts::const_iterator i = anContacts.begin();i != anContacts.end() && IsOnline();++i) + { + HANDLE hContact = *i; + if(bUseExtendedStatus) + { + SetContactStatus(hContact,ID_STATUS_OCCUPIED); + } + + tstring sQuoteID = Quotes_DBGetStringT(hContact,QUOTES_MODULE_NAME,DB_STR_QUOTE_ID); + aQuoteID2Handles[sQuoteID] = hContact; + if(i != anContacts.begin()) + { + oURL << _T("+"); + } + oURL << sQuoteID; + } + + if(true == IsOnline()) + { + oURL << _T("&f=snl1ohgpc1"); + CHTTPSession http; + if ((true == http.OpenURL(oURL.str())) && (true == IsOnline())) + { + tstring sFile; + if ((true == http.ReadResponce(sFile)) && (true == IsOnline())) + { + tistringstream out_str(sFile.c_str()); + while(false == out_str.eof()) + { + tstring sLine; + std::getline(out_str,sLine); + if(false == sLine.empty()) + { + remove_end_of_line(sLine); + + TStrings asStrings; + for(tstring::size_type nPos = sLine.find(_T(','));nPos != tstring::npos; nPos = sLine.find(_T(','))) + { + tstring::iterator i(sLine.begin()); + std::advance(i,nPos); + tstring s(sLine.begin(),i); + remove_quotes(s); + asStrings.push_back(s); + + if(i != sLine.end()) + { + std::advance(i,1); + } + sLine.erase(sLine.begin(),i); + } + + if(false == sLine.empty()) + { + remove_quotes(sLine); + + if(false == sLine.empty()) + asStrings.push_back(sLine); + } + + size_t cItems = asStrings.size(); + if(cItems >= 3) + { + enum + { + indexSymbol = 0, + indexName, + indexLastTrade, + indexOpen, + indexDayHigh, + indexDayLow, + indexPreviousClose, + indexChange + }; + auto it3 = aQuoteID2Handles.find(asStrings[indexSymbol]); + if(it3 != aQuoteID2Handles.end()) + { + HANDLE hContact = it3->second; + double dRate = 0.0; + if(true == t2d(asStrings[indexLastTrade],dRate)) + { + DBWriteContactSettingTString(hContact,QUOTES_MODULE_NAME,DB_STR_QUOTE_DESCRIPTION,asStrings[indexName].c_str()); + + get_double_from_parsed_line(hContact,asStrings,indexOpen,DB_STR_YAHOO_OPEN_VALUE); + get_double_from_parsed_line(hContact,asStrings,indexDayHigh,DB_STR_YAHOO_DAY_HIGH); + get_double_from_parsed_line(hContact,asStrings,indexDayLow,DB_STR_YAHOO_DAY_LOW); + get_double_from_parsed_line(hContact,asStrings,indexPreviousClose,DB_STR_YAHOO_PREVIOUS_CLOSE); + get_double_from_parsed_line(hContact,asStrings,indexChange,DB_STR_YAHOO_CHANGE); + WriteContactRate(hContact,dRate); + aQuoteID2Handles.erase(it3); + } + } + } + } + } + } + } + + if(true == IsOnline()) + { + std::for_each(aQuoteID2Handles.begin(),aQuoteID2Handles.end(), + [](const TQuoteID2ContractHandles::value_type& pair){SetContactStatus(pair.second,ID_STATUS_NA);}); + } + } +} + +void CQuotesProviderYahoo::Accept(CQuotesProviderVisitor& visitor)const +{ + CQuotesProviderFinance::Accept(visitor); + visitor.Visit(*this); +} diff --git a/protocols/Quotes/QuotesProviderYahoo.h b/protocols/Quotes/QuotesProviderYahoo.h new file mode 100644 index 0000000000..feadefbca4 --- /dev/null +++ b/protocols/Quotes/QuotesProviderYahoo.h @@ -0,0 +1,20 @@ +#ifndef __E927F394_5452_458E_AF48_71E44F9EE793_QuotesProviderYahoo_h__ +#define __E927F394_5452_458E_AF48_71E44F9EE793_QuotesProviderYahoo_h__ + +#include "QuotesProviderFinance.h" + + +#define DB_STR_YAHOO_OPEN_VALUE "OpenQuotePrice" +#define DB_STR_YAHOO_DAY_HIGH "DayHigh" +#define DB_STR_YAHOO_DAY_LOW "DayLow" +#define DB_STR_YAHOO_PREVIOUS_CLOSE "PreviousClose" +#define DB_STR_YAHOO_CHANGE "Change" + +class CQuotesProviderYahoo : public CQuotesProviderFinance +{ +private: + virtual void RefreshQuotes(TContracts& anContacts); + virtual void Accept(CQuotesProviderVisitor& visitor)const; +}; + +#endif //__E927F394_5452_458E_AF48_71E44F9EE793_QuotesProviderYahoo_h__ diff --git a/protocols/Quotes/QuotesProviders.cpp b/protocols/Quotes/QuotesProviders.cpp new file mode 100644 index 0000000000..5fac2af14f --- /dev/null +++ b/protocols/Quotes/QuotesProviders.cpp @@ -0,0 +1,120 @@ +#include "StdAfx.h" +#include "QuotesProviders.h" + +#include "QuotesProviderDukasCopy.h" +#include "EconomicRateInfo.h" +#include "QuotesProviderGoogle.h" +#include "DBUtils.h" +#include "QuotesProviderGoogleFinance.h" +#include "QuotesProviderYahoo.h" + +#define LAST_RUN_VERSION "LastRunVersion" + +CQuotesProviders::CQuotesProviders() +{ + InitProviders(); +} + +CQuotesProviders::~CQuotesProviders() +{ + ClearProviders(); +} + +const CQuotesProviders::TQuotesProviders& CQuotesProviders::GetProviders()const +{ + return m_apProviders; +} + +namespace +{ + templatevoid create_provider(CQuotesProviders::TQuotesProviders& apProviders) + { + CQuotesProviders::TQuotesProviderPtr pProvider(new T); + if(pProvider->Init()) + { + apProviders.push_back(pProvider); + } + } +} + +void CQuotesProviders::CreateProviders() +{ + create_provider(m_apProviders); + create_provider(m_apProviders); + create_provider(m_apProviders); + create_provider(m_apProviders); +} + +void CQuotesProviders::ClearProviders() +{ + m_apProviders.clear(); +} + +namespace +{ + void convert_contact_settings(HANDLE hContact) + { + WORD dwLogMode = DBGetContactSettingWord(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_LOG,static_cast(lmDisabled)); + if ((dwLogMode&lmInternalHistory) || (dwLogMode&lmExternalFile)) + { + DBWriteContactSettingByte(hContact,QUOTES_PROTOCOL_NAME,DB_STR_CONTACT_SPEC_SETTINGS,1); + } + } +} +void CQuotesProviders::InitProviders() +{ + CreateProviders(); + + const WORD nCurrentVersion = 17; + WORD nVersion = DBGetContactSettingWord(NULL,QUOTES_MODULE_NAME,LAST_RUN_VERSION,1); + + for(HANDLE hContact = reinterpret_cast(CallService(MS_DB_CONTACT_FINDFIRST,0,0));hContact;hContact = reinterpret_cast(CallService(MS_DB_CONTACT_FINDNEXT,reinterpret_cast(hContact),0))) + { + TQuotesProviderPtr pProvider = GetContactProviderPtr(hContact); + if(pProvider) + { + pProvider->AddContact(hContact); + if(nVersion < nCurrentVersion) + { + convert_contact_settings(hContact); + } + } + } + + DBWriteContactSettingWord(NULL,QUOTES_MODULE_NAME,LAST_RUN_VERSION,nCurrentVersion); +} + +CQuotesProviders::TQuotesProviderPtr CQuotesProviders::GetContactProviderPtr(HANDLE hContact)const +{ + char* szProto = reinterpret_cast(CallService(MS_PROTO_GETCONTACTBASEPROTO, + reinterpret_cast(hContact),0)); + if(NULL == szProto || 0 != ::_stricmp(szProto,QUOTES_PROTOCOL_NAME)) + { + return TQuotesProviderPtr(); + } + + tstring sProvider = Quotes_DBGetStringT(hContact,QUOTES_MODULE_NAME,DB_STR_QUOTE_PROVIDER); + if(true == sProvider.empty()) + { + return TQuotesProviderPtr(); + } + + return FindProvider(sProvider); +} + +CQuotesProviders::TQuotesProviderPtr CQuotesProviders::FindProvider(const tstring& rsName)const +{ + TQuotesProviderPtr pResult; + for(TQuotesProviders::const_iterator i = m_apProviders.begin();i != m_apProviders.end();++i) + { + const TQuotesProviderPtr& pProvider = *i; + const IQuotesProvider::CProviderInfo& rInfo = pProvider->GetInfo(); + if(0 == ::quotes_stricmp(rsName.c_str(),rInfo.m_sName.c_str())) + { + pResult = pProvider; + break; + } + } + + return pResult; +} diff --git a/protocols/Quotes/QuotesProviders.h b/protocols/Quotes/QuotesProviders.h new file mode 100644 index 0000000000..02aa5184c9 --- /dev/null +++ b/protocols/Quotes/QuotesProviders.h @@ -0,0 +1,32 @@ +#ifndef __148306d1_da2a_43df_b1ad_0cdc8ef8a79e_QuotesProviders_h__ +#define __148306d1_da2a_43df_b1ad_0cdc8ef8a79e_QuotesProviders_h__ + +#include +#include + +class IQuotesProvider; + +class CQuotesProviders +{ +public: + typedef boost::shared_ptr TQuotesProviderPtr; + typedef std::vector TQuotesProviders; + +public: + CQuotesProviders(); + ~CQuotesProviders(); + + TQuotesProviderPtr FindProvider(const tstring& rsName)const; + TQuotesProviderPtr GetContactProviderPtr(HANDLE hContact)const; + const TQuotesProviders& GetProviders()const; + +private: + void InitProviders(); + void CreateProviders(); + void ClearProviders(); + +private: + TQuotesProviders m_apProviders; +}; + +#endif //__148306d1_da2a_43df_b1ad_0cdc8ef8a79e_QuotesProviders_h__ diff --git a/protocols/Quotes/SettingsDlg.cpp b/protocols/Quotes/SettingsDlg.cpp new file mode 100644 index 0000000000..e5795b51d1 --- /dev/null +++ b/protocols/Quotes/SettingsDlg.cpp @@ -0,0 +1,1148 @@ +#include "StdAfx.h" +#include "SettingsDlg.h" +#include "EconomicRateInfo.h" +#include "ModuleInfo.h" +#include "WinCtrlHelper.h" +#include "CreateFilePath.h" +#include "QuotesProviderVisitorDbSettings.h" +#include "DBUtils.h" +#include "resource.h" +#include "QuotesProviders.h" +#include "IQuotesProvider.h" + +#define WINDOW_PREFIX_SETTINGS "Edit Settings_" + +namespace +{ + LPCTSTR g_pszVariableQuoteName = _T("%quotename%"); + LPCTSTR g_pszVariableUserProfile = _T("%miranda_userdata%"); + + void update_file_controls(HWND hDlg) + { + bool bEnable = (1 == ::IsDlgButtonChecked(hDlg,IDC_CHECK_EXTERNAL_FILE)); + + ::EnableWindow(::GetDlgItem(hDlg,IDC_EDIT_FILE_NAME),bEnable); + ::EnableWindow(::GetDlgItem(hDlg,IDC_STATIC_SELECT_FILE),bEnable); + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_BROWSE),bEnable); + ::EnableWindow(::GetDlgItem(hDlg,IDC_STATIC_LOG_FILE_FORMAT),bEnable); + ::EnableWindow(::GetDlgItem(hDlg,IDC_EDIT_LOG_FILE_FORMAT),bEnable); + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_LOG_FILE_DESCRIPTION),bEnable); + ::EnableWindow(::GetDlgItem(hDlg,IDC_CHECK_LOG_FILE_CONDITION),bEnable); + } + + void update_history_controls(HWND hDlg) + { + bool bEnable = (1 == ::IsDlgButtonChecked(hDlg,IDC_CHECK_INTERNAL_HISTORY)); + + ::EnableWindow(::GetDlgItem(hDlg,IDC_STATIC_HISTORY_FORMAT),bEnable); + ::EnableWindow(::GetDlgItem(hDlg,IDC_EDIT_HISTORY_FORMAT),bEnable); + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_HISTORY_DESCRIPTION),bEnable); + ::EnableWindow(::GetDlgItem(hDlg,IDC_CHECK_HISTORY_CONDITION),bEnable); + } + + void update_popup_controls(HWND hDlg) + { + bool bEnable = (1 == ::IsDlgButtonChecked(hDlg,IDC_CHECK_SHOW_POPUP)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_EDIT_POPUP_FORMAT),bEnable); + ::EnableWindow(::GetDlgItem(hDlg,IDC_CHECK_SHOW_POPUP_ONLY_VALUE_CHANGED),bEnable); + ::EnableWindow(::GetDlgItem(hDlg,IDC_STATIC_POPUP_FORMAT),bEnable); + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_POPUP_FORMAT_DESCRIPTION),bEnable); + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_POPUP_SETTINGS),bEnable); + } + + bool enable_popup_controls(HWND hDlg) + { + bool bIsPopupServiceEnabled = 1 == ServiceExists(MS_POPUP_ADDPOPUPT); + ::EnableWindow(::GetDlgItem(hDlg,IDC_CHECK_SHOW_POPUP),bIsPopupServiceEnabled); + ::EnableWindow(::GetDlgItem(hDlg,IDC_EDIT_POPUP_FORMAT),bIsPopupServiceEnabled); + ::EnableWindow(::GetDlgItem(hDlg,IDC_CHECK_SHOW_POPUP_ONLY_VALUE_CHANGED),bIsPopupServiceEnabled); + ::EnableWindow(::GetDlgItem(hDlg,IDC_STATIC_POPUP_FORMAT),bIsPopupServiceEnabled); + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_POPUP_FORMAT_DESCRIPTION),bIsPopupServiceEnabled); + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_POPUP_SETTINGS),bIsPopupServiceEnabled); + + return bIsPopupServiceEnabled; + } + + void update_all_controls(HWND hDlg) + { + bool bIsCheckedContactSpec = (1 == ::IsDlgButtonChecked(hDlg,IDC_CHECK_CONTACT_SPECIFIC)); + bool bIsCheckedExternal = (1 == ::IsDlgButtonChecked(hDlg,IDC_CHECK_EXTERNAL_FILE)); + + ::EnableWindow(::GetDlgItem(hDlg,IDC_CHECK_EXTERNAL_FILE),bIsCheckedContactSpec); + ::EnableWindow(::GetDlgItem(hDlg,IDC_EDIT_FILE_NAME),(bIsCheckedContactSpec&&bIsCheckedExternal)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_STATIC_SELECT_FILE),(bIsCheckedContactSpec&&bIsCheckedExternal)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_BROWSE),(bIsCheckedContactSpec&&bIsCheckedExternal)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_STATIC_LOG_FILE_FORMAT),(bIsCheckedContactSpec&&bIsCheckedExternal)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_EDIT_LOG_FILE_FORMAT),(bIsCheckedContactSpec&&bIsCheckedExternal)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_LOG_FILE_DESCRIPTION),(bIsCheckedContactSpec&&bIsCheckedExternal)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_CHECK_LOG_FILE_CONDITION),(bIsCheckedContactSpec&&bIsCheckedExternal)); + + bool bIsCheckedHistory = (1 == ::IsDlgButtonChecked(hDlg,IDC_CHECK_INTERNAL_HISTORY)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_CHECK_INTERNAL_HISTORY),bIsCheckedContactSpec); + ::EnableWindow(::GetDlgItem(hDlg,IDC_STATIC_HISTORY_FORMAT),(bIsCheckedContactSpec&&bIsCheckedHistory)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_EDIT_HISTORY_FORMAT),(bIsCheckedContactSpec&&bIsCheckedHistory)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_HISTORY_DESCRIPTION),(bIsCheckedContactSpec&&bIsCheckedHistory)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_CHECK_HISTORY_CONDITION),(bIsCheckedContactSpec&&bIsCheckedHistory)); + + bool bIsPopupServiceEnabled = 1 == ServiceExists(MS_POPUP_ADDPOPUPT); + bool bIsCheckedShowPopup = (1 == ::IsDlgButtonChecked(hDlg,IDC_CHECK_SHOW_POPUP)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_CHECK_SHOW_POPUP),(bIsCheckedContactSpec&&bIsPopupServiceEnabled)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_EDIT_POPUP_FORMAT),(bIsCheckedContactSpec&&bIsPopupServiceEnabled&&bIsCheckedShowPopup)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_CHECK_SHOW_POPUP_ONLY_VALUE_CHANGED),(bIsCheckedContactSpec&&bIsPopupServiceEnabled&&bIsCheckedShowPopup)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_STATIC_POPUP_FORMAT),(bIsCheckedContactSpec&&bIsPopupServiceEnabled&&bIsCheckedShowPopup)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_POPUP_FORMAT_DESCRIPTION),(bIsCheckedContactSpec&&bIsPopupServiceEnabled&&bIsCheckedShowPopup)); + ::EnableWindow(::GetDlgItem(hDlg,IDC_BUTTON_POPUP_SETTINGS),(bIsCheckedContactSpec&&bIsPopupServiceEnabled)); + } + + std::vector get_filter() + { + std::vector aFilter; + LPCTSTR pszFilterParts[] = {_T("Log Files (*.txt,*.log)"),_T("*.txt;*.log"),_T("All files (*.*)"),_T("*.*")}; + for(int i = 0;i < sizeof(pszFilterParts)/sizeof(pszFilterParts[0]);++i) + { + tstring sPart = TranslateTS(pszFilterParts[i]); + std::copy(sPart.begin(),sPart.end(),std::back_inserter(aFilter)); + aFilter.push_back(_T('\0')); + + } + aFilter.push_back(_T('\0')); + return aFilter; + } + void select_log_file(HWND hDlg) + { +// tstring sFileName = GenerateLogFileName( +// get_window_text(::GetDlgItem(hDlg,IDC_EDIT_FILE_NAME)),tstring(),glfnResolveUserProfile); + std::vector aFileBuffer(_MAX_PATH*2,_T('\0')); +// std::copy(sFileName.begin(),sFileName.end(),aFileBuffer.begin()); + LPTSTR pszFile = &*aFileBuffer.begin(); + + std::vector aFilterBuffer = get_filter(); + LPCTSTR pszFilter = &*aFilterBuffer.begin(); + + OPENFILENAME ofn = {0}; + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hDlg; + ofn.lpstrFile = pszFile; + ofn.nMaxFile = (DWORD)aFileBuffer.size(); + ofn.lpstrFilter = pszFilter; + ofn.nFilterIndex = 1; + ofn.hInstance = CModuleInfo::GetModuleHandle(); + ofn.lpstrDefExt = _T("log"); +// ofn.lpstrFileTitle = NULL; +// ofn.nMaxFileTitle = 0; +// ofn.lpstrInitialDir = NULL; + ofn.Flags = OFN_PATHMUSTEXIST|OFN_HIDEREADONLY|OFN_EXPLORER; + + BOOL b = GetOpenFileName(&ofn); + if(TRUE == b) + { + SetDlgItemText(hDlg,IDC_EDIT_FILE_NAME,ofn.lpstrFile); + } + } + + struct CSettingWindowParam + { + CSettingWindowParam(HANDLE hContact) : m_hContact(hContact),m_pPopupSettings(NULL){} + ~CSettingWindowParam(){delete m_pPopupSettings;} + + HANDLE m_hContact; + CPopupSettings* m_pPopupSettings; + }; + + inline CSettingWindowParam* get_param(HWND hWnd) + { + return reinterpret_cast(GetWindowLongPtr(hWnd,GWLP_USERDATA)); + } + + +// inline HANDLE get_contact(HWND hWnd) +// { +// return reinterpret_cast(GetWindowLong(hWnd,GWLP_USERDATA)); +// } + + void update_popup_controls_settings(HWND hDlg) + { + bool bIsColoursEnabled = 1 == IsDlgButtonChecked(hDlg,IDC_RADIO_USER_DEFINED_COLOURS); + ::EnableWindow(::GetDlgItem(hDlg,IDC_BGCOLOR),bIsColoursEnabled); + ::EnableWindow(::GetDlgItem(hDlg,IDC_TEXTCOLOR),bIsColoursEnabled); + + bool bIsDelayEnabled = 1 == IsDlgButtonChecked(hDlg,IDC_DELAYCUSTOM); + ::EnableWindow(::GetDlgItem(hDlg,IDC_DELAY),bIsDelayEnabled); + + } + + INT_PTR CALLBACK EditPopupSettingsDlgProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) + { + switch(msg) + { + case WM_INITDIALOG: + { + CPopupSettings* pSettings = reinterpret_cast(lp); + TranslateDialogDefault( hWnd ); +// ::SendDlgItemMessage(hWnd,IDC_BGCOLOR,CPM_SETDEFAULTCOLOUR,0,::GetSysColor(COLOR_BTNFACE)); +// ::SendDlgItemMessage(hWnd,IDC_TEXTCOLOR,CPM_SETDEFAULTCOLOUR,0,::GetSysColor(COLOR_BTNTEXT)); + ::SendDlgItemMessage(hWnd,IDC_BGCOLOR,CPM_SETCOLOUR,0,pSettings->GetColourBk()); + ::SendDlgItemMessage(hWnd,IDC_TEXTCOLOR,CPM_SETCOLOUR,0,pSettings->GetColourText()); + + ::CheckDlgButton(hWnd,IDC_CHECK_DONT_USE_POPUPHISTORY,pSettings->GetHistoryFlag()); + + ::CheckRadioButton(hWnd,IDC_RADIO_DEFAULT_COLOURS,IDC_RADIO_USER_DEFINED_COLOURS,(CPopupSettings::colourDefault == pSettings->GetColourMode()) ? IDC_RADIO_DEFAULT_COLOURS : IDC_RADIO_USER_DEFINED_COLOURS); + UINT n; + switch(pSettings->GetDelayMode()) + { + default: + assert(!"Unknown delay mode. Please, fix it"); + case CPopupSettings::delayFromPopup: + n = IDC_DELAYFROMPU; + break; + case CPopupSettings::delayCustom: + n = IDC_DELAYCUSTOM; + break; + case CPopupSettings::delayPermanent: + n = IDC_DELAYPERMANENT; + break; + } + ::CheckRadioButton(hWnd,IDC_DELAYFROMPU,IDC_DELAYPERMANENT,n); + + ::SetDlgItemInt(hWnd,IDC_DELAY,pSettings->GetDelayTimeout(),FALSE); + + update_popup_controls_settings(hWnd); + + ::SetWindowLongPtr(hWnd,GWLP_USERDATA,reinterpret_cast(pSettings)); + } + return TRUE; + case WM_COMMAND: + switch(LOWORD(wp)) + { + case IDC_RADIO_DEFAULT_COLOURS: + case IDC_RADIO_USER_DEFINED_COLOURS: + case IDC_DELAYFROMPU: + case IDC_DELAYCUSTOM: + case IDC_DELAYPERMANENT: + update_popup_controls_settings(hWnd); + break; + + case IDCANCEL: + ::EndDialog(hWnd,IDCANCEL); + break; + case IDOK: + { + CPopupSettings* pSettings = reinterpret_cast(GetWindowLongPtr(hWnd,GWLP_USERDATA)); + + bool bError = false; + BOOL bOk = FALSE; + UINT nDelay = ::GetDlgItemInt(hWnd,IDC_DELAY,&bOk,FALSE); + CPopupSettings::EDelayMode nModeDelay = pSettings->GetDelayMode(); + if(1 == ::IsDlgButtonChecked(hWnd,IDC_DELAYFROMPU)) + { + nModeDelay = CPopupSettings::delayFromPopup; + } + else if(1 == ::IsDlgButtonChecked(hWnd,IDC_DELAYCUSTOM)) + { + if(TRUE == bOk) + { + nModeDelay = CPopupSettings::delayCustom; + } + else + { + prepare_edit_ctrl_for_error(::GetDlgItem(hWnd,IDC_DELAY)); + Quotes_MessageBox(hWnd,TranslateT("Enter integer value"),MB_OK|MB_ICONERROR); + bError = true; + } + } + else if(1 == ::IsDlgButtonChecked(hWnd,IDC_DELAYPERMANENT)) + { + nModeDelay = CPopupSettings::delayPermanent; + } + if(false == bError) + { + pSettings->SetDelayMode(nModeDelay); + if(TRUE == bOk) + { + pSettings->SetDelayTimeout(nDelay); + } + pSettings->SetHistoryFlag((1 == IsDlgButtonChecked(hWnd,IDC_CHECK_DONT_USE_POPUPHISTORY))); + + if(1 == ::IsDlgButtonChecked(hWnd,IDC_RADIO_DEFAULT_COLOURS)) + { + pSettings->SetColourMode(CPopupSettings::colourDefault); + } + else if(1 == ::IsDlgButtonChecked(hWnd,IDC_RADIO_USER_DEFINED_COLOURS)) + { + pSettings->SetColourMode(CPopupSettings::colourUserDefined); + } + + pSettings->SetColourBk(static_cast(::SendDlgItemMessage(hWnd,IDC_BGCOLOR,CPM_GETCOLOUR,0,0))); + pSettings->SetColourText(static_cast(::SendDlgItemMessage(hWnd,IDC_TEXTCOLOR,CPM_GETCOLOUR,0,0))); + + ::EndDialog(hWnd,IDOK); + } + } + break; + } + break; + } + + return FALSE; + } + + INT_PTR CALLBACK EditSettingsPerContactDlgProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) + { + switch(msg) + { + case WM_INITDIALOG: + { + HANDLE hContact = reinterpret_cast(lp); + TranslateDialogDefault(hWnd); + + HANDLE hWL = CModuleInfo::GetInstance().GetWindowList(WINDOW_PREFIX_SETTINGS,false); + assert(hWL); + WindowList_Add(hWL,hWnd,hContact); + + tstring sName = GetContactName(hContact); + ::SetDlgItemText(hWnd,IDC_EDIT_NAME,sName.c_str()); + + CQuotesProviders::TQuotesProviderPtr pProvider = CModuleInfo::GetQuoteProvidersPtr()->GetContactProviderPtr(hContact); + + BYTE bUseContactSpecific = DBGetContactSettingByte(hContact,QUOTES_PROTOCOL_NAME,DB_STR_CONTACT_SPEC_SETTINGS,0); + ::CheckDlgButton(hWnd,IDC_CHECK_CONTACT_SPECIFIC,bUseContactSpecific); + + CAdvProviderSettings setGlobal(pProvider.get()); + // log to history + WORD dwLogMode = DBGetContactSettingWord(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_LOG,setGlobal.GetLogMode()); + UINT nCheck = (dwLogMode&lmInternalHistory) ? 1 : 0; + ::CheckDlgButton(hWnd,IDC_CHECK_INTERNAL_HISTORY,nCheck); + + tstring sHistoryFrmt = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_FORMAT_HISTORY,setGlobal.GetHistoryFormat().c_str()); + ::SetDlgItemText(hWnd,IDC_EDIT_HISTORY_FORMAT,sHistoryFrmt.c_str()); + + WORD wOnlyIfChanged = DBGetContactSettingWord(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_HISTORY_CONDITION,setGlobal.GetHistoryOnlyChangedFlag()); + ::CheckDlgButton(hWnd,IDC_CHECK_HISTORY_CONDITION,(1 == wOnlyIfChanged) ? 1 : 0); + + // log to file + nCheck = (dwLogMode&lmExternalFile) ? 1 : 0; + ::CheckDlgButton(hWnd,IDC_CHECK_EXTERNAL_FILE,nCheck); + + tstring sLogFileName = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_LOG_FILE); + if(true == sLogFileName.empty()) + { + sLogFileName = GenerateLogFileName(setGlobal.GetLogFileName(),Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_SYMBOL),glfnResolveQuoteName); + } + ::SetDlgItemText(hWnd,IDC_EDIT_FILE_NAME,sLogFileName.c_str()); + + tstring sLogFileFrmt = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_FORMAT_LOG_FILE,setGlobal.GetLogFormat().c_str()); + ::SetDlgItemText(hWnd,IDC_EDIT_LOG_FILE_FORMAT,sLogFileFrmt.c_str()); + + wOnlyIfChanged = DBGetContactSettingWord(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_LOG_FILE_CONDITION,setGlobal.GetLogOnlyChangedFlag()); + ::CheckDlgButton(hWnd,IDC_CHECK_LOG_FILE_CONDITION,(1 == wOnlyIfChanged) ? 1 : 0); + + // popup + nCheck = (dwLogMode&lmPopup) ? 1 : 0; + ::CheckDlgButton(hWnd,IDC_CHECK_SHOW_POPUP,nCheck); + tstring sPopupFrmt = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_FORMAT_POPUP,setGlobal.GetPopupFormat().c_str()); + ::SetDlgItemText(hWnd,IDC_EDIT_POPUP_FORMAT,sPopupFrmt.c_str()); + bool bOnlyIfChanged = 1 == DBGetContactSettingByte(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_POPUP_CONDITION,setGlobal.GetShowPopupIfValueChangedFlag()); + ::CheckDlgButton(hWnd,IDC_CHECK_SHOW_POPUP_ONLY_VALUE_CHANGED,(true == bOnlyIfChanged) ? 1 : 0); + + update_all_controls(hWnd); + + CSettingWindowParam* pParam = new CSettingWindowParam(hContact); + ::SetWindowLongPtr(hWnd,GWLP_USERDATA,reinterpret_cast(pParam)); + Utils_RestoreWindowPositionNoSize(hWnd,hContact,QUOTES_MODULE_NAME,WINDOW_PREFIX_SETTINGS); + ::ShowWindow(hWnd,SW_SHOW); + } + break; + case WM_COMMAND: + switch(LOWORD(wp)) + { + case IDC_BUTTON_HISTORY_DESCRIPTION: + case IDC_BUTTON_LOG_FILE_DESCRIPTION: + case IDC_BUTTON_POPUP_FORMAT_DESCRIPTION: + if(BN_CLICKED == HIWORD(wp)) + { + CQuotesProviders::TQuotesProviderPtr pProvider = CModuleInfo::GetQuoteProvidersPtr()->GetContactProviderPtr(get_param(hWnd)->m_hContact); + show_variable_list(hWnd,pProvider.get()); + } + break; + + case IDC_CHECK_CONTACT_SPECIFIC: + if(BN_CLICKED == HIWORD(wp)) + { + update_all_controls(hWnd); + } + break; + case IDC_CHECK_EXTERNAL_FILE: + if(BN_CLICKED == HIWORD(wp)) + { + update_file_controls(hWnd); + } + break; + case IDC_CHECK_INTERNAL_HISTORY: + if(BN_CLICKED == HIWORD(wp)) + { + update_history_controls(hWnd); + } + break; + case IDC_CHECK_SHOW_POPUP: + if(BN_CLICKED == HIWORD(wp)) + { + update_popup_controls(hWnd); + } + break; + case IDC_BUTTON_BROWSE: + if(BN_CLICKED == HIWORD(wp)) + { + select_log_file(hWnd); + } + break; + case IDC_BUTTON_POPUP_SETTINGS: + if(BN_CLICKED == HIWORD(wp)) + { + CSettingWindowParam* pParam = get_param(hWnd); + if (!pParam->m_pPopupSettings) + { + CQuotesProviders::TQuotesProviderPtr pProvider = CModuleInfo::GetQuoteProvidersPtr()->GetContactProviderPtr(pParam->m_hContact); + + pParam->m_pPopupSettings = new CPopupSettings(pProvider.get()); + pParam->m_pPopupSettings->InitForContact(pParam->m_hContact); + } + + DialogBoxParam(CModuleInfo::GetModuleHandle(), + MAKEINTRESOURCE(IDD_DIALOG_POPUP), + hWnd, + EditPopupSettingsDlgProc,reinterpret_cast(pParam->m_pPopupSettings)); + } + break; + + case IDOK: + { + CSettingWindowParam* pParam = get_param(hWnd); + HANDLE hContact = pParam->m_hContact; + + bool bUseContactSpec = 1 == ::IsDlgButtonChecked(hWnd,IDC_CHECK_CONTACT_SPECIFIC); + + WORD nLogMode = lmDisabled; + UINT nCheck = ::IsDlgButtonChecked(hWnd,IDC_CHECK_EXTERNAL_FILE); + if(1 == nCheck) + { + nLogMode |= lmExternalFile; + } + + nCheck = ::IsDlgButtonChecked(hWnd,IDC_CHECK_INTERNAL_HISTORY); + if(1 == nCheck) + { + nLogMode |= lmInternalHistory; + } + + nCheck = ::IsDlgButtonChecked(hWnd,IDC_CHECK_SHOW_POPUP); + if(1 == nCheck) + { + nLogMode |= lmPopup; + } + + bool bOk = true; + HWND hwndLogFile = ::GetDlgItem(hWnd,IDC_EDIT_FILE_NAME); + HWND hwndLogFileFrmt = ::GetDlgItem(hWnd,IDC_EDIT_LOG_FILE_FORMAT); + HWND hwndHistoryFrmt = ::GetDlgItem(hWnd,IDC_EDIT_HISTORY_FORMAT); + tstring sLogFile = get_window_text(hwndLogFile); + tstring sLogFileFormat = get_window_text(hwndLogFileFrmt); + tstring sHistoryFormat = get_window_text(hwndHistoryFrmt); + if ((nLogMode&lmExternalFile)) + { + if(true == sLogFile.empty()) + { + prepare_edit_ctrl_for_error(hwndLogFile); + Quotes_MessageBox(hWnd,TranslateT("Enter log file name."),MB_OK|MB_ICONERROR); + bOk = false; + } + else if(true == sLogFileFormat.empty()) + { + prepare_edit_ctrl_for_error(hwndLogFileFrmt); + Quotes_MessageBox(hWnd,TranslateT("Enter log file format."),MB_OK|MB_ICONERROR); + bOk = false; + } + } + + if ((true == bOk) && (nLogMode&lmInternalHistory) && (true == sHistoryFormat.empty())) + { + prepare_edit_ctrl_for_error(hwndHistoryFrmt); + Quotes_MessageBox(hWnd,TranslateT("Enter history format."),MB_OK|MB_ICONERROR); + bOk = false; + } + + HWND hwndPopupFrmt = ::GetDlgItem(hWnd,IDC_EDIT_POPUP_FORMAT); + tstring sPopupFormat = get_window_text(hwndPopupFrmt); + if ((true == bOk) && (nLogMode&lmPopup) && (true == sPopupFormat.empty())) + { + prepare_edit_ctrl_for_error(hwndPopupFrmt); + Quotes_MessageBox(hWnd,TranslateT("Enter popup window format."),MB_OK|MB_ICONERROR); + bOk = false; + } + + if(true == bOk) + { + UINT nIfChangedHistory = IsDlgButtonChecked(hWnd,IDC_CHECK_HISTORY_CONDITION); + UINT nIfChangedFile = IsDlgButtonChecked(hWnd,IDC_CHECK_LOG_FILE_CONDITION); + bool bIfChangedPopup = (1 == IsDlgButtonChecked(hWnd,IDC_CHECK_SHOW_POPUP_ONLY_VALUE_CHANGED)); + + DBWriteContactSettingByte(hContact,QUOTES_PROTOCOL_NAME,DB_STR_CONTACT_SPEC_SETTINGS,bUseContactSpec); + DBWriteContactSettingWord(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_LOG,nLogMode); + DBWriteContactSettingWord(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_LOG_FILE_CONDITION,nIfChangedFile); + DBWriteContactSettingWord(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_HISTORY_CONDITION,nIfChangedHistory); + DBWriteContactSettingByte(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_POPUP_CONDITION,bIfChangedPopup); + DBWriteContactSettingTString(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_LOG_FILE,sLogFile.c_str()); + DBWriteContactSettingTString(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_FORMAT_LOG_FILE,sLogFileFormat.c_str()); + DBWriteContactSettingTString(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_FORMAT_HISTORY,sHistoryFormat.c_str()); + DBWriteContactSettingTString(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_FORMAT_POPUP,sPopupFormat.c_str()); + + if(pParam->m_pPopupSettings) + { + pParam->m_pPopupSettings->SaveForContact(hContact); + } + + ::DestroyWindow(hWnd); + } + } + break; + case IDCANCEL: + DestroyWindow(hWnd); + break; + } + break; + case WM_CLOSE: + DestroyWindow(hWnd); + break; + case WM_DESTROY: + { + CSettingWindowParam* pParam = get_param(hWnd); + SetWindowLongPtr(hWnd,GWLP_USERDATA,0); + + HANDLE hWL = CModuleInfo::GetInstance().GetWindowList(WINDOW_PREFIX_SETTINGS,false); + assert(hWL); + WindowList_Remove(hWL,hWnd); + Utils_SaveWindowPosition(hWnd,pParam->m_hContact,QUOTES_MODULE_NAME,WINDOW_PREFIX_SETTINGS); + delete pParam; + } + break; + } + + return FALSE; + } +} + + +void ShowSettingsDlg(HANDLE hContact) +{ + HANDLE hWL = CModuleInfo::GetInstance().GetWindowList(WINDOW_PREFIX_SETTINGS,true); + assert(hWL); + HWND hWnd = WindowList_Find(hWL,hContact); + if(NULL != hWnd) + { + SetForegroundWindow(hWnd); + SetFocus(hWnd); + } + else + { + CreateDialogParam(CModuleInfo::GetModuleHandle(),MAKEINTRESOURCE(IDD_CONTACT_SETTINGS),NULL,EditSettingsPerContactDlgProc,reinterpret_cast(hContact)); + } +} + +////////////////////////////////////////////////////////////////////////// + +namespace +{ + INT_PTR CALLBACK EditSettingsPerProviderDlgProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) + { + switch(msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hWnd); + CAdvProviderSettings* pAdvSettings = reinterpret_cast(lp); + + ::SetDlgItemText(hWnd,IDC_EDIT_NAME,pAdvSettings->GetProviderPtr()->GetInfo().m_sName.c_str()); + + // log to history + WORD dwLogMode = pAdvSettings->GetLogMode(); + UINT nCheck = (dwLogMode&lmInternalHistory) ? 1 : 0; + ::CheckDlgButton(hWnd,IDC_CHECK_INTERNAL_HISTORY,nCheck); + ::SetDlgItemText(hWnd,IDC_EDIT_HISTORY_FORMAT,pAdvSettings->GetHistoryFormat().c_str()); + ::CheckDlgButton(hWnd,IDC_CHECK_HISTORY_CONDITION,(true == pAdvSettings->GetHistoryOnlyChangedFlag()) ? 1 : 0); + + // log to file + nCheck = (dwLogMode&lmExternalFile) ? 1 : 0; + ::CheckDlgButton(hWnd,IDC_CHECK_EXTERNAL_FILE,nCheck); + ::SetDlgItemText(hWnd,IDC_EDIT_FILE_NAME,pAdvSettings->GetLogFileName().c_str()); + ::SetDlgItemText(hWnd,IDC_EDIT_LOG_FILE_FORMAT,pAdvSettings->GetLogFormat().c_str()); + ::CheckDlgButton(hWnd,IDC_CHECK_LOG_FILE_CONDITION,(true == pAdvSettings->GetLogOnlyChangedFlag()) ? 1 : 0); + + update_file_controls(hWnd); + update_history_controls(hWnd); + + // popup + nCheck = (dwLogMode&lmPopup) ? 1 : 0; + ::CheckDlgButton(hWnd,IDC_CHECK_SHOW_POPUP,nCheck); + ::SetDlgItemText(hWnd,IDC_EDIT_POPUP_FORMAT,pAdvSettings->GetPopupFormat().c_str()); + ::CheckDlgButton(hWnd,IDC_CHECK_SHOW_POPUP_ONLY_VALUE_CHANGED,(true == pAdvSettings->GetShowPopupIfValueChangedFlag()) ? 1 : 0); + + if(true == enable_popup_controls(hWnd)) + { + update_popup_controls(hWnd); + } + + ::SetWindowLongPtr(hWnd,GWLP_USERDATA,reinterpret_cast(pAdvSettings)); + } + return TRUE; + case WM_COMMAND: + switch(LOWORD(wp)) + { + case IDOK: + { + WORD nLogMode = lmDisabled; + UINT nCheck = ::IsDlgButtonChecked(hWnd,IDC_CHECK_EXTERNAL_FILE); + if(1 == nCheck) + { + nLogMode |= lmExternalFile; + } + + nCheck = ::IsDlgButtonChecked(hWnd,IDC_CHECK_INTERNAL_HISTORY); + if(1 == nCheck) + { + nLogMode |= lmInternalHistory; + } + + nCheck = ::IsDlgButtonChecked(hWnd,IDC_CHECK_SHOW_POPUP); + if(1 == nCheck) + { + nLogMode |= lmPopup; + } + + bool bOk = true; + HWND hwndLogFile = ::GetDlgItem(hWnd,IDC_EDIT_FILE_NAME); + HWND hwndLogFileFrmt = ::GetDlgItem(hWnd,IDC_EDIT_LOG_FILE_FORMAT); + + tstring sLogFile = get_window_text(hwndLogFile); + tstring sLogFileFormat = get_window_text(hwndLogFileFrmt); + + if ((nLogMode&lmExternalFile)) + { + if(true == sLogFile.empty()) + { + prepare_edit_ctrl_for_error(hwndLogFile); + Quotes_MessageBox(hWnd,TranslateT("Enter log file name."),MB_OK|MB_ICONERROR); + bOk = false; + } + else if(true == sLogFileFormat.empty()) + { + prepare_edit_ctrl_for_error(hwndLogFileFrmt); + Quotes_MessageBox(hWnd,TranslateT("Enter log file format."),MB_OK|MB_ICONERROR); + bOk = false; + } + } + + HWND hwndHistoryFrmt = ::GetDlgItem(hWnd,IDC_EDIT_HISTORY_FORMAT); + tstring sHistoryFormat = get_window_text(hwndHistoryFrmt); + if ((true == bOk) && (nLogMode&lmInternalHistory) && (true == sHistoryFormat.empty())) + { + prepare_edit_ctrl_for_error(hwndHistoryFrmt); + Quotes_MessageBox(hWnd,TranslateT("Enter history format."),MB_OK|MB_ICONERROR); + bOk = false; + } + + HWND hwndPopupFrmt = ::GetDlgItem(hWnd,IDC_EDIT_POPUP_FORMAT); + tstring sPopupFormat = get_window_text(hwndPopupFrmt); + if ((true == bOk) && (nLogMode&lmPopup) && (true == sPopupFormat.empty())) + { + prepare_edit_ctrl_for_error(hwndPopupFrmt); + Quotes_MessageBox(hWnd,TranslateT("Enter popup window format."),MB_OK|MB_ICONERROR); + bOk = false; + } + + if(true == bOk) + { + CAdvProviderSettings* pAdvSettings = reinterpret_cast(GetWindowLongPtr(hWnd,GWLP_USERDATA)); + + pAdvSettings->SetLogMode(nLogMode); + pAdvSettings->SetHistoryOnlyChangedFlag(1 == IsDlgButtonChecked(hWnd,IDC_CHECK_HISTORY_CONDITION)); + pAdvSettings->SetLogOnlyChangedFlag(1 == IsDlgButtonChecked(hWnd,IDC_CHECK_LOG_FILE_CONDITION)); + pAdvSettings->SetShowPopupIfValueChangedFlag(1 == IsDlgButtonChecked(hWnd,IDC_CHECK_SHOW_POPUP_ONLY_VALUE_CHANGED)); + pAdvSettings->SetLogFileName(sLogFile); + pAdvSettings->SetLogFormat(sLogFileFormat); + pAdvSettings->SetHistoryFormat(sHistoryFormat); + pAdvSettings->SetPopupFormat(sPopupFormat); + + ::EndDialog(hWnd,IDOK); + } + } + break; + case IDCANCEL: + ::EndDialog(hWnd,IDCANCEL); + break; + case IDC_BUTTON_HISTORY_DESCRIPTION: + case IDC_BUTTON_LOG_FILE_DESCRIPTION: + case IDC_BUTTON_POPUP_FORMAT_DESCRIPTION: + if(BN_CLICKED == HIWORD(wp)) + { + const CAdvProviderSettings* pAdvSettings = reinterpret_cast(GetWindowLongPtr(hWnd,GWLP_USERDATA)); + show_variable_list(hWnd,pAdvSettings->GetProviderPtr()); + } + break; + case IDC_CHECK_EXTERNAL_FILE: + if(BN_CLICKED == HIWORD(wp)) + { + update_file_controls(hWnd); + } + break; + case IDC_CHECK_INTERNAL_HISTORY: + if(BN_CLICKED == HIWORD(wp)) + { + update_history_controls(hWnd); + } + break; + case IDC_CHECK_SHOW_POPUP: + if(BN_CLICKED == HIWORD(wp)) + { + update_popup_controls(hWnd); + } + break; + case IDC_BUTTON_BROWSE: + if(BN_CLICKED == HIWORD(wp)) + { + select_log_file(hWnd); + } + break; + case IDC_BUTTON_POPUP_SETTINGS: + { + const CAdvProviderSettings* pAdvSettings = reinterpret_cast(GetWindowLongPtr(hWnd,GWLP_USERDATA)); + DialogBoxParam(CModuleInfo::GetModuleHandle(), + MAKEINTRESOURCE(IDD_DIALOG_POPUP), + hWnd, + EditPopupSettingsDlgProc,reinterpret_cast(pAdvSettings->GetPopupSettingsPtr())); + + } + break; + } + break; + } + return FALSE; + } +} + +CAdvProviderSettings::CAdvProviderSettings(const IQuotesProvider* pQuotesProvider) + : m_pQuotesProvider(pQuotesProvider), + m_wLogMode(lmDisabled), + m_bIsOnlyChangedHistory(false), + m_bIsOnlyChangedLogFile(false), + m_bShowPopupIfValueChanged(false), + m_pPopupSettings(nullptr) +{ + assert(m_pQuotesProvider); + + CQuotesProviderVisitorDbSettings visitor; + m_pQuotesProvider->Accept(visitor); + + assert(visitor.m_pszDefLogFileFormat); + assert(visitor.m_pszDefHistoryFormat); + assert(visitor.m_pszDbLogMode); + assert(visitor.m_pszDbHistoryFormat); + assert(visitor.m_pszDbHistoryCondition); + assert(visitor.m_pszDbLogFile); + assert(visitor.m_pszDbLogFormat); + assert(visitor.m_pszDbLogCondition); + + m_wLogMode = DBGetContactSettingWord(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbLogMode,static_cast(lmDisabled)); + m_sFormatHistory = Quotes_DBGetStringT(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbHistoryFormat,visitor.m_pszDefHistoryFormat); + m_bIsOnlyChangedHistory = 1 == DBGetContactSettingByte(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbHistoryCondition,0); + + m_sLogFileName = Quotes_DBGetStringT(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbLogFile); + if(true == m_sLogFileName.empty()) + { + m_sLogFileName = g_pszVariableUserProfile; + m_sLogFileName += _T("\\Quotes\\"); + m_sLogFileName += g_pszVariableQuoteName; + m_sLogFileName += _T(".log"); + } + + m_sFormatLogFile = Quotes_DBGetStringT(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbLogFormat,visitor.m_pszDefLogFileFormat); + m_bIsOnlyChangedLogFile = (1 == DBGetContactSettingByte(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbLogCondition,0)); + + m_sPopupFormat = Quotes_DBGetStringT(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbPopupFormat,visitor.m_pszDefPopupFormat); + m_bShowPopupIfValueChanged = (1 == DBGetContactSettingByte(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbPopupCondition,0)); +} + +CAdvProviderSettings::~CAdvProviderSettings() +{ + delete m_pPopupSettings; +} + +const IQuotesProvider* CAdvProviderSettings::GetProviderPtr()const +{ + return m_pQuotesProvider; +} + +void CAdvProviderSettings::SaveToDb()const +{ + CQuotesProviderVisitorDbSettings visitor; + m_pQuotesProvider->Accept(visitor); + + assert(visitor.m_pszDbLogMode); + assert(visitor.m_pszDbHistoryFormat); + assert(visitor.m_pszDbHistoryCondition); + assert(visitor.m_pszDbLogFile); + assert(visitor.m_pszDbLogFormat); + assert(visitor.m_pszDbLogCondition); + assert(visitor.m_pszDbPopupColourMode); + assert(visitor.m_pszDbPopupBkColour); + assert(visitor.m_pszDbPopupTextColour); + assert(visitor.m_pszDbPopupDelayMode); + assert(visitor.m_pszDbPopupDelayTimeout); + assert(visitor.m_pszDbPopupHistoryFlag); + + DBWriteContactSettingWord(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbLogMode,m_wLogMode); + DBWriteContactSettingTString(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbHistoryFormat,m_sFormatHistory.c_str()); + DBWriteContactSettingByte(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbHistoryCondition,m_bIsOnlyChangedHistory); + DBWriteContactSettingTString(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbLogFile,m_sLogFileName.c_str()); + DBWriteContactSettingTString(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbLogFormat,m_sFormatLogFile.c_str()); + DBWriteContactSettingByte(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbLogCondition,m_bIsOnlyChangedLogFile); + DBWriteContactSettingTString(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbPopupFormat,m_sPopupFormat.c_str()); + DBWriteContactSettingByte(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbPopupCondition,m_bShowPopupIfValueChanged); + + if(nullptr != m_pPopupSettings) + { + DBWriteContactSettingByte(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbPopupColourMode,static_cast(m_pPopupSettings->GetColourMode())); + DBWriteContactSettingDword(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbPopupBkColour,m_pPopupSettings->GetColourBk()); + DBWriteContactSettingDword(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbPopupTextColour,m_pPopupSettings->GetColourText()); + DBWriteContactSettingByte(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbPopupDelayMode,static_cast(m_pPopupSettings->GetDelayMode())); + DBWriteContactSettingWord(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbPopupDelayTimeout,m_pPopupSettings->GetDelayTimeout()); + DBWriteContactSettingByte(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbPopupHistoryFlag,m_pPopupSettings->GetHistoryFlag()); + } +} + +WORD CAdvProviderSettings::GetLogMode()const +{ + return m_wLogMode; +} + +void CAdvProviderSettings::SetLogMode(WORD wMode) +{ + m_wLogMode = wMode; +} + +tstring CAdvProviderSettings::GetHistoryFormat()const +{ + return m_sFormatHistory; +} + +void CAdvProviderSettings::SetHistoryFormat(const tstring& rsFormat) +{ + m_sFormatHistory = rsFormat; +} + +bool CAdvProviderSettings::GetHistoryOnlyChangedFlag()const +{ + return m_bIsOnlyChangedHistory; +} + +void CAdvProviderSettings::SetHistoryOnlyChangedFlag(bool bMode) +{ + m_bIsOnlyChangedHistory = bMode; +} + +tstring CAdvProviderSettings::GetLogFileName()const +{ + return m_sLogFileName; +} + +void CAdvProviderSettings::SetLogFileName(const tstring& rsFile) +{ + m_sLogFileName = rsFile; +} + +tstring CAdvProviderSettings::GetLogFormat()const +{ + return m_sFormatLogFile; +} + +void CAdvProviderSettings::SetLogFormat(const tstring& rsFormat) +{ + m_sFormatLogFile = rsFormat; +} + +bool CAdvProviderSettings::GetLogOnlyChangedFlag()const +{ + return m_bIsOnlyChangedLogFile; +} + +void CAdvProviderSettings::SetLogOnlyChangedFlag(bool bMode) +{ + m_bIsOnlyChangedLogFile = bMode; +} + +const tstring& CAdvProviderSettings::GetPopupFormat() const +{ + return m_sPopupFormat; +} + +void CAdvProviderSettings::SetPopupFormat(const tstring& val) +{ + m_sPopupFormat = val; +} + +bool CAdvProviderSettings::GetShowPopupIfValueChangedFlag() const +{ + return m_bShowPopupIfValueChanged; +} + +void CAdvProviderSettings::SetShowPopupIfValueChangedFlag(bool val) +{ + m_bShowPopupIfValueChanged = val; +} + +CPopupSettings* CAdvProviderSettings::GetPopupSettingsPtr()const +{ + if(nullptr == m_pPopupSettings) + { + m_pPopupSettings = new CPopupSettings(m_pQuotesProvider); + } + + return m_pPopupSettings; +} + +CPopupSettings::CPopupSettings(const IQuotesProvider* pQuotesProvider) + : m_modeColour(colourDefault), + m_modeDelay(delayFromPopup), + m_rgbBkg(GetDefColourBk()), + m_rgbText(GetDefColourText()), + m_wDelay(3), + m_bUseHistory(false) + +{ + CQuotesProviderVisitorDbSettings visitor; + pQuotesProvider->Accept(visitor); + + assert(visitor.m_pszDbPopupColourMode); + assert(visitor.m_pszDbPopupBkColour); + assert(visitor.m_pszDbPopupTextColour); + assert(visitor.m_pszDbPopupDelayMode); + assert(visitor.m_pszDbPopupDelayTimeout); + assert(visitor.m_pszDbPopupHistoryFlag); + + BYTE m = DBGetContactSettingByte(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbPopupColourMode,static_cast(m_modeColour)); + if(m >= colourDefault && m <= colourUserDefined) + { + m_modeColour = static_cast(m); + } + + m_rgbBkg = DBGetContactSettingDword(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbPopupBkColour,m_rgbBkg); + m_rgbText = DBGetContactSettingDword(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbPopupTextColour,m_rgbText); + + m = DBGetContactSettingByte(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbPopupDelayMode,static_cast(m_modeDelay)); + if(m >= delayFromPopup && m <= delayPermanent) + { + m_modeDelay = static_cast(m); + } + m_wDelay = DBGetContactSettingWord(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbPopupDelayTimeout,m_wDelay); + m_bUseHistory = (1 == DBGetContactSettingByte(NULL,QUOTES_PROTOCOL_NAME,visitor.m_pszDbPopupHistoryFlag,m_bUseHistory)); +} + +/*static */ +COLORREF CPopupSettings::GetDefColourBk() +{ + return ::GetSysColor(COLOR_BTNFACE); +} + +/*static */ +COLORREF CPopupSettings::GetDefColourText() +{ + return ::GetSysColor(COLOR_BTNTEXT); +} + +void CPopupSettings::InitForContact(HANDLE hContact) +{ + BYTE m = DBGetContactSettingByte(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_POPUP_COLOUR_MODE,static_cast(m_modeColour)); + if(m >= CPopupSettings::colourDefault && m <= CPopupSettings::colourUserDefined) + { + m_modeColour = static_cast(m); + } + + m_rgbBkg = DBGetContactSettingDword(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_POPUP_COLOUR_BK,m_rgbBkg); + m_rgbText = DBGetContactSettingDword(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_POPUP_COLOUR_TEXT,m_rgbText); + + m = DBGetContactSettingByte(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_POPUP_DELAY_MODE,static_cast(m_modeDelay)); + if(m >= CPopupSettings::delayFromPopup && m <= CPopupSettings::delayPermanent) + { + m_modeDelay = static_cast(m); + } + m_wDelay = DBGetContactSettingWord(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_POPUP_DELAY_TIMEOUT,m_wDelay); + m_bUseHistory = 1 == DBGetContactSettingByte(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_POPUP_HISTORY_FLAG,m_bUseHistory); +} + +void CPopupSettings::SaveForContact(HANDLE hContact)const +{ + DBWriteContactSettingByte(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_POPUP_COLOUR_MODE,static_cast(m_modeColour)); + DBWriteContactSettingDword(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_POPUP_COLOUR_BK,m_rgbBkg); + DBWriteContactSettingDword(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_POPUP_COLOUR_TEXT,m_rgbText); + DBWriteContactSettingByte(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_POPUP_DELAY_MODE,static_cast(m_modeDelay)); + DBWriteContactSettingWord(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_POPUP_DELAY_TIMEOUT,m_wDelay); + DBWriteContactSettingByte(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_POPUP_HISTORY_FLAG,m_bUseHistory); +} + +CPopupSettings::EColourMode CPopupSettings::GetColourMode()const +{ + return m_modeColour; +} + +void CPopupSettings::SetColourMode(EColourMode nMode) +{ + m_modeColour = nMode; +} + +COLORREF CPopupSettings::GetColourBk()const +{ + return m_rgbBkg; +} + +void CPopupSettings::SetColourBk(COLORREF rgb) +{ + m_rgbBkg = rgb; +} + +COLORREF CPopupSettings::GetColourText()const +{ + return m_rgbText; +} + +void CPopupSettings::SetColourText(COLORREF rgb) +{ + m_rgbText = rgb; +} + +CPopupSettings::EDelayMode CPopupSettings::GetDelayMode()const +{ + return m_modeDelay; +} + +void CPopupSettings::SetDelayMode(EDelayMode nMode) +{ + m_modeDelay = nMode; +} + +WORD CPopupSettings::GetDelayTimeout()const +{ + return m_wDelay; +} + +void CPopupSettings::SetDelayTimeout(WORD delay) +{ + m_wDelay = delay; +} + +bool CPopupSettings::GetHistoryFlag()const +{ + return m_bUseHistory; +} + +void CPopupSettings::SetHistoryFlag(bool flag) +{ + m_bUseHistory = flag; +} + +bool ShowSettingsDlg(HWND hWndParent,CAdvProviderSettings* pAdvSettings) +{ + assert(pAdvSettings); + + return (IDOK == DialogBoxParam(CModuleInfo::GetModuleHandle(), + MAKEINTRESOURCE(IDD_PROVIDER_ADV_SETTINGS), + hWndParent, + EditSettingsPerProviderDlgProc, + reinterpret_cast(pAdvSettings))); +} + +namespace +{ + void replace_invalid_char(tstring::value_type& rChar,tstring::value_type repl) + { + static const TCHAR charInvalidSigns[] = {_T('\\'), _T('/'), _T(':'), _T('*'), _T('?'), _T('\"'), _T('<'), _T('>'), _T('|')}; + + for(int i = 0; i < sizeof(charInvalidSigns)/sizeof(charInvalidSigns[0]);++i) + { + if(rChar == charInvalidSigns[i]) + { + rChar = repl; + break; + } + } + } + +} + +tstring GenerateLogFileName(const tstring& rsLogFilePattern, + const tstring& rsQuoteSymbol, + int nFlags/* = glfnResolveAll*/) +{ + tstring sPath = rsLogFilePattern; + if(nFlags&glfnResolveQuoteName) + { + assert(false == rsQuoteSymbol.empty()); + + tstring::size_type n = sPath.find(g_pszVariableQuoteName); + if(tstring::npos != n) + { + tstring s = rsQuoteSymbol; + std::for_each(s.begin(),s.end(),boost::bind(replace_invalid_char,_1,_T('_'))); + sPath.replace(n,lstrlen(g_pszVariableQuoteName),s.c_str()); + } + } + + if(nFlags&glfnResolveUserProfile) + { + REPLACEVARSDATA dat = {0}; + dat.cbSize = sizeof(dat); + dat.dwFlags = RVF_TCHAR; + + TCHAR* ptszParsedName = reinterpret_cast(CallService(MS_UTILS_REPLACEVARS, + reinterpret_cast(sPath.c_str()),reinterpret_cast(&dat))); + if(ptszParsedName) + { + sPath = ptszParsedName; + mir_free(ptszParsedName); + } + } + + return sPath; +} + +tstring GetContactLogFileName(HANDLE hContact) +{ + tstring result; + + const CQuotesProviders::TQuotesProviderPtr& pProvider = CModuleInfo::GetQuoteProvidersPtr()->GetContactProviderPtr(hContact); + if(pProvider) + { + tstring sPattern; + bool bUseContactSpecific = (DBGetContactSettingByte(hContact,QUOTES_PROTOCOL_NAME,DB_STR_CONTACT_SPEC_SETTINGS,0) > 0); + if(bUseContactSpecific) + { + sPattern = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_LOG_FILE); + } + else + { + CAdvProviderSettings global_settings(pProvider.get()); + sPattern = global_settings.GetLogFileName(); + } + + result = GenerateLogFileName(sPattern,Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_SYMBOL)); + } + + return result; +} + +tstring GetContactName(HANDLE hContact) +{ + tstring sDescription = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_DESCRIPTION); + if(sDescription.empty()) + { + sDescription = Quotes_DBGetStringT(hContact,QUOTES_PROTOCOL_NAME,DB_STR_QUOTE_SYMBOL); + } + return sDescription; +} diff --git a/protocols/Quotes/SettingsDlg.h b/protocols/Quotes/SettingsDlg.h new file mode 100644 index 0000000000..569d0b7d2c --- /dev/null +++ b/protocols/Quotes/SettingsDlg.h @@ -0,0 +1,118 @@ +#ifndef __E211E4D9_383C_43BE_A787_7EF1D585B90D_SettingsDlg_h__ +#define __E211E4D9_383C_43BE_A787_7EF1D585B90D_SettingsDlg_h__ + +class IQuotesProvider; + +class CPopupSettings +{ +public: + enum EColourMode + { + colourDefault, + colourUserDefined, + }; + + enum EDelayMode + { + delayFromPopup, + delayCustom, + delayPermanent + }; + +public: + CPopupSettings(const IQuotesProvider* pQuotesProvider); + + static COLORREF GetDefColourBk(); + static COLORREF GetDefColourText(); + + void InitForContact(HANDLE hContact); + void SaveForContact(HANDLE hContact)const; + + EColourMode GetColourMode()const; + void SetColourMode(EColourMode nMode); + + COLORREF GetColourBk()const; + void SetColourBk(COLORREF rgb); + + COLORREF GetColourText()const; + void SetColourText(COLORREF rgb); + + EDelayMode GetDelayMode()const; + void SetDelayMode(EDelayMode nMode); + + WORD GetDelayTimeout()const; + void SetDelayTimeout(WORD delay); + + bool GetHistoryFlag()const; + void SetHistoryFlag(bool flag); + +private: + EColourMode m_modeColour; + EDelayMode m_modeDelay; + COLORREF m_rgbBkg; + COLORREF m_rgbText; + WORD m_wDelay; + bool m_bUseHistory; +}; + + +class CAdvProviderSettings +{ +public: + CAdvProviderSettings(const IQuotesProvider* pQuotesProvider); + ~CAdvProviderSettings(); + + void SaveToDb()const; + + const IQuotesProvider* GetProviderPtr()const; + + WORD GetLogMode()const; + void SetLogMode(WORD wMode); + tstring GetHistoryFormat()const; + void SetHistoryFormat(const tstring& rsFormat); + bool GetHistoryOnlyChangedFlag()const; + void SetHistoryOnlyChangedFlag(bool bMode); + + tstring GetLogFileName()const; + void SetLogFileName(const tstring& rsFile); + tstring GetLogFormat()const; + void SetLogFormat(const tstring& rsFormat); + bool GetLogOnlyChangedFlag()const; + void SetLogOnlyChangedFlag(bool bMode); + + const tstring& GetPopupFormat() const; + void SetPopupFormat(const tstring& val); + + bool GetShowPopupIfValueChangedFlag() const; + void SetShowPopupIfValueChangedFlag(bool val); + + CPopupSettings* GetPopupSettingsPtr()const; + +private: + const IQuotesProvider* m_pQuotesProvider; + WORD m_wLogMode; + tstring m_sFormatHistory; + bool m_bIsOnlyChangedHistory; + tstring m_sLogFileName; + tstring m_sFormatLogFile; + bool m_bIsOnlyChangedLogFile; + tstring m_sPopupFormat; + bool m_bShowPopupIfValueChanged; + mutable CPopupSettings* m_pPopupSettings; +}; + +void ShowSettingsDlg(HANDLE hContact); +bool ShowSettingsDlg(HWND hWndParent,CAdvProviderSettings* pAdvSettings); + +enum +{ + glfnResolveQuoteName = 0x0001, + glfnResolveUserProfile = 0x0002, + glfnResolveAll = glfnResolveQuoteName|glfnResolveUserProfile, +}; +tstring GenerateLogFileName(const tstring& rsLogFilePattern,const tstring& rsQuoteSymbol,int nFlags = glfnResolveAll); +tstring GetContactLogFileName(HANDLE hContact); +tstring GetContactName(HANDLE hContact); + +#endif //__E211E4D9_383C_43BE_A787_7EF1D585B90D_SettingsDlg_h__ + diff --git a/protocols/Quotes/Utility/DukasCopy.py b/protocols/Quotes/Utility/DukasCopy.py new file mode 100644 index 0000000000..2d12d1c4ec --- /dev/null +++ b/protocols/Quotes/Utility/DukasCopy.py @@ -0,0 +1,48 @@ +from html.parser import HTMLParser +import sys + +class MyHTMLParser(HTMLParser): + def __init__(self, in_fn,out_fn): + HTMLParser.__init__(self) + f_in = open(in_fn,'r') + self.quote = 0 + self.descr = '' + self.f_out = open(out_fn,'w') + self.feed(f_in.read()) + f_in.close() + self.f_out.close() + + def handle_starttag(self, tag, attrs): + #print ("start of a %s" % tag) + #print (attrs) + self.start = 1 + if tag == 'input': + self.f_out.write('\n') + for k in attrs: + if k[0] == 'stname': + self.f_out.write('\n\t%s'%k[1]) + if k[0] == 'stid': + self.f_out.write('\n\t%s'%k[1]) + self.quote = 1 + + + def handle_endtag(self, tag): + self.start = 0 + if tag == 'tr' and self.quote == 1: + if self.descr: + self.f_out.write('\n\t%s'%self.descr) + self.f_out.write('\n') + self.quote = 0 + self.descr = 1 + #print ("end of a %s" % tag) + + def handle_data(self, data): + if self.start == 1: + self.descr = data + #print ("Data %s" % self.descr) + + + +parser = MyHTMLParser(sys.argv[1],sys.argv[2]) +parser.close() + \ No newline at end of file diff --git a/protocols/Quotes/Utility/Dukascopy.xml b/protocols/Quotes/Utility/Dukascopy.xml new file mode 100644 index 0000000000..92890888b9 --- /dev/null +++ b/protocols/Quotes/Utility/Dukascopy.xml @@ -0,0 +1,1635 @@ + + + + Dukascopy Swiss Forex Group + http://www.dukascopy.com + http://freeserv.dukascopy.com/qt/?&STOCKS= + + + +
+ European Stocks + + + 127 + BA + BAE Systems + + + 130 + BKIR + Bank of Ireland + + + 131 + BP + British Petroleum + + + 138 + SBRY + Sainsbury + + + 142 + AZN + Astrazeneca + + + 145 + CNA + Centrica + + + 153 + MKS + Spencer + + + 155 + RTR + Reuters Group + + + 156 + RR + Rolls Royce + + + 158 + TSCO + Tesco + + + 165 + ALV + Alliaz AG + + + 167 + BAY + Bayer AG + + + 169 + CBK + Commerzbank AG + + + 171 + DBK + Deutsche Bank AG + + + 177 + SIE + Siemens AG + + + 178 + TKA + Thyssenkrupp AG + + + 179 + VOW + Volkswagen AG + + + 183 + FTE + France Telecom + + + 191 + OR + LOreal + + + 192 + ML + Michelin + + + 193 + RNO + Renault + + + 195 + UG + Peugeot SA + + + 198 + LG + Lafarge + + + 206 + PIN + Pinguin + + + 213 + RBACW + Rabo Agaath Bank + + + 221 + ABBN + ABB Finance + + + 222 + ADEN + Adecco SA + + + 224 + RUKN + Swiss Reinsurance + + + 232 + GFC + Gecina + + + 234 + VK + Vallourec + + + 235 + FLE + Fleury Michon + + + 242 + NEX + National Express Group + + + 245 + IMT + Imperial Tobacco + + + 338 + Pseudo + Pseudo + + + 340 + Pseudo1 + Pseudo1 + + + 321 + ROS + OAO Rostelecom + + + 325 + FIA + Fiat S.p.A. + + + 326 + E + Eni S.p.A. + + + 327 + EN + Enel S.p.A. + + + 152 + LLOY + Lloyds TSB Bank + + + 226 + AKZA + Akzo Nobel NV + + + 135 + BSY + British Sky Broadcast + + + 144 + CW + Wireless + + + 146 + GSK + Glaxosmithkline + + + 149 + HSBA + HSBC Bank + + + 151 + KGF + Kingfisher + + + 166 + BAS + BASF AG + + + 172 + DPW + Deutsche Post AG + + + 173 + DTE + Deutsche Telecom + + + 249 + CA + Carrefour + + + 218 + NESN + Nestle SA + + + 219 + UBSN + UBS AG + + + 229 + DIE + DIeteren Trading + + + 237 + GAM + Gaumont + + + 238 + AGE + AGFA Gevaert NV + + + 243 + CBRY + Cadbury Schweppes + + + 246 + MLW + Merrill Lynch World + + + 248 + MASN + Micronas Semiconductors + + + 255 + ARE + Groupe Ares + + + 200 + DELB + Delhaize Group + + + 215 + PHIA + Philips Electronics + + + 216 + CSGN + Credit Suisse Groupe CAP + + + 772 + VOD + VODAFONE + + + 773 + BA + British Airways + + +
+ + + +
+ US Stocks + + + + 99 + INTC + Intel Corp. + + + 98 + QCOM + QUALCOMM Incorporated + + + 97 + CSCO + Cisco Systems, Inc. + + + 96 + AMGN + Amgen Inc. + + + 94 + ORCL + Oracle Corp. + + + 92 + MXIM + Maxim Integrated Products, Inc. + + + 85 + SBUX + Starbucks Corp. + + + 82 + CTAS + Cintas Corp. + + + 81 + BMET + Biomet, Inc. + + + 80 + PAYX + Paychex, Inc + + + 79 + XLNX + Xilinx, Inc. + + + 75 + FISV + Fiserv, Inc. + + + 69 + COST + Costco Wholesale Corp. + + + 64 + PCAR + PACCAR Inc. + + + 62 + ADBE + Adobe Systems Incorporated + + + 61 + SPLS + Staples, Inc. + + + 33 + T + T Corp. + + + 31 + AA + Alcoa + + + 32 + AXP + American Express Co. + + + 34 + BA + The Boeing Co. + + + 35 + CAT + Caterpillar Inc. + + + 36 + C + Citigroup, Inc. + + + 37 + KO + The Coca-Cola Co. + + + 40 + EK + Eastman Kodak Co. + + + 43 + GM + General Motors Corp. + + + 49 + JNJ + Johnson + + + 50 + MCD + McDonald's Corp. + + + 51 + MRK + Merck Company, Inc. + + + 52 + MMM + Manufacturing Co. + + + 53 + JPM + J.P. Morgan Company Inc. + + + 57 + UTX + United Technologies Corp. + + + 58 + WMT + Wal-Mart Stores, Inc. + + + 104 + CDWC + CDW Computer Centers, Inc. + + + 116 + SGA + Saga Communications, Inc. + + + 118 + MPP + Medical Technology System + + + 119 + ACU + Acme United Corp. + + + 128 + BAL + Barclays + + + 141 + RBS + Royal Bank of Scotland + + + 250 + BMO + Bank of Montreal + + + 254 + TRP + TransCanada PipeLines Ltd + + + 329 + QQQQ + TransCanada PipeLines Ltd + + + 330 + DIA + TransCanada PipeLines Ltd + + + 332 + SMH + TransCanada PipeLines Ltd + + + 122 + DW + Drew Industries, Inc. + + + 123 + FPU + Florida Public Utilities + + + 280 + NOK + Nokia + + + 281 + UPM + UPM-Kymmene OYJ + + + 282 + SEO + Stora Enso OYJ + + + 287 + BEAS + BEA System INC. + + + 288 + BRCD + Brocade Communication System Inc. + + + 291 + CEPH + Cephalon Inc. + + + 292 + CIEN + Ciena Corp. + + + 293 + CHKP + Checkpoint Software + + + 295 + DISH + Echostar Communications + + + 100 + MSFT + Microsoft Corp. + + + 95 + DELL + Dell Computer Corp. + + + 91 + EBAY + eBay Inc. + + + 88 + BBBY + Beyond Inc. + + + 87 + LLTC + Linear Technology Corp. + + + 84 + IACI + USA Interactive + + + 76 + KLAC + KLA-Tencor Corp. + + + 70 + APOL + Apollo Group, Inc. + + + 68 + TEVA + Teva Pharmaceutical Industries Limited + + + 65 + ALTR + Altera Corp. + + + 63 + SYMC + Symantec Corp. + + + 42 + GE + General Electric Co. + + + 44 + HPQ + Hewlett-Packard Co. + + + 46 + HON + Honeywell International Inc. + + + 47 + IBM + International Business Machines Corp. + + + 54 + MO + Morris Companies, Inc. + + + 55 + PG + Gamble Co. + + + 103 + FLEX + Flextronics International Ltd. + + + 115 + OHB + Orleans Homebuilders + + + 251 + BNS + Bank of Nova Scotia + + + 252 + BCE + BCE, Inc. + + + 331 + SPY + BCE, Inc. + + + 286 + AMCC + Applied Micro Circuit Corp. + + + 294 + CTXS + Citrix Systems + + + 738 + MCHP + Microchip Technology + + + 747 + NTE + NAM TAI Electronics + + + 759 + TTWO + Take-Two Interactive Software + + + 700 + ADI + Analog Devices + + + 701 + ADTN + Adtran + + + 702 + AIG + American International Group + + + 703 + APA + Apache Corp + + + 704 + BAC + Bank of America Corp + + + 705 + BBY + Best Buy Co + + + 706 + BIIB + Biogen Idec + + + 707 + BOBJ + Business Objects SA + + + 708 + BRCM + Broadcom Corp + + + 709 + CALM + Cal-Maine Foods + + + 710 + CCU + Clear Channel Communications + + + 711 + COF + Capital One Financial Corp + + + 714 + DLTR + Dollar Tree Stores + + + 716 + FITB + Fifth Third Bancorp + + + 717 + FNM + Fannie Mae + + + 718 + FRE + Freddie Mac + + + 719 + FRX + Forest Laboratories + + + 720 + GCI + Gannett Co + + + 721 + GD + General Dynamics Corp + + + 724 + GS + Goldman Sachs Group + + + 726 + HOV + Hovnanian Enterprises + + + 727 + ICOS + ICOS Corp + + + 728 + IMCL + ImClone Systems + + + 731 + KSS + Kohl's Corp + + + 732 + LEH + Lehman Brothers Holdings Inc + + + 734 + LLY + Co + + + 737 + LXK + Lexmark International + + + 743 + NEM + Newmont Mining Corp + + + 744 + NFLX + NetFlix + + + 745 + NOC + Northrop Grumman Corp + + + 748 + NTES + Netease.com + + + 749 + NVLS + Novellus Systems + + + 750 + OVTI + Omnivision Technologies + + + 753 + RMBS + Rambus + + + 755 + SINA + Sina Corp + + + 756 + SNDK + Sandisk Corp + + + 757 + SNPS + Synopsys + + + 758 + SOHU + Sohu.com + + + 760 + UTSI + Utstarcom + + + 762 + WLP + WellPoint Health Networks + + + 763 + WY + Weyerhaeuser Co + + + 764 + XMSR + XM Satellite Radio Holdings + + + 765 + YHOO + Yahoo! + + + 38 + DIS + The Walt Disney Co. + + + 39 + DD + E.I. duPont de Nemours Co. + + + 78 + ERTS + Electronic Arts Inc. + + + 77 + GENZ + Genzyme General + + + 766 + GOOGL + Google! + + + 45 + HD + Home Depot Inc. + + + 48 + IP + International Paper Co. + + + 121 + DLA + Delta Apparel Inc. + + + 86 + AMAT + Applied Materials, Inc. + + + 41 + XOM + Exxon Mobil Corp. + + + 102 + AMZN + Amazon.com, Inc. + + + 729 + IVGN + Invitrogen Corp + + + 736 + LRCX + Lam Research Corp + + + 712 + CTSH + Cognizant Technology Solutions Corp + + + 713 + DHI + DR Horton + + + 740 + MNST + Monster Worldwide + + +
+ + + + +
+ Indices + +
+ on the basis of US Indices + + + 22 + SandP-500 + P 500 + + + 23 + NQ-100 + CFD statistics for Nasdaq 100 + + + 28 + Nyssee-comp + CFD statistics for NYSE Composite + + + 21 + D&J-Ind + CFD statistics for Dow Jones Industrial Average + + + 26 + NQ-comp + CFD statistics for Nasdaq Composite + + + 27 + AMMEKS + CFD statistics for AMEX + + + 768 + VIXX + Volatility Index + + + 769 + 10Y note + 10Y note yield + + + 770 + 5Y note + 5Y note yield + + + 771 + ST note + Short term note yield + + +
+ +
+ on the basis of European Indices + + + 24 + CAAC-40 + CFD statistics for CAC 40 + + + 25 + DAAX + CFD statistics for XETRA DAX + + + 225 + SWMI + CFD statistics for SMI + + + 345 + Futsee-100 + CFD statistics for FTSE + + + 503 + DJE50XX + CFD statistics for DJ Euro Stoxx50 + + +
+ +
+ on the basis of Asian Indices + + + 500 + N225Jap + CFD statistics for Nikkei 225 + + + 501 + SC-Korea + CFD statistics for KOSPI + + + 502 + H-Kong + CFD statistics for Hang Seng + + +
+
+ + +
+ FOREX + +
+ Major + + + 3 + USD/CHF + USD/CHF + + + 9 + USD/CAD + USD/CAD + + + 10 + AUD/USD + AUD/USD + + + 11 + NZD/USD + NZD/USD + + + 1 + EUR/USD + EUR/USD + + + 2 + GBP/USD + GBP/USD + + +
+ +
+ Other Currencies + + + + 12 + USD/NOK + USD/NOK + + + 13 + USD/DKK + USD/DKK + + + 14 + USD/SEK + USD/SEK + + + 15 + USD/SAR + USD/SAR + + + 507 + USD/EUR + USD/EUR + + + 508 + USD/GBP + USD/GBP + + + 512 + JPY/USD + JPY/USD + + + 513 + JPY/EUR + JPY/EUR + + + 516 + GBP/EUR + GBP/EUR + + + 519 + CHF/USD + CHF/USD + + + 521 + CHF/JPY + CHF/JPY + + + 514 + JPY/GBP + JPY/GBP + + + 515 + JPY/CHF + JPY/CHF + + + 520 + CHF/EUR + CHF/EUR + + + 522 + CHF/GBP + CHF/GBP + + + 74 + USD/ZAR + USD/ZAR + + + 30 + USD/SGD + USD/SGD + + + 29 + EUR/SEK + EUR/SEK + +
+ +
+ Crosses + + + + 509 + EUR/JPY + EUR/JPY + + + 510 + EUR/GBP + EUR/GBP + + + 511 + EUR/CHF + EUR/CHF + + + 517 + GBP/JPY + GBP/JPY + + + 518 + GBP/CHF + GBP/CHF + + + 60 + AUD/JPY + AUD/JPY + + + 767 + CAD/JPY + CAD/JPY + +
+ +
+ Other Arab Currencies + + + + 4 + USD/JPY + USD/JPY + + + 5 + USD/EGP + USD/EGP + + + 6 + USD/JOD + USD/JOD + + + 7 + USD/QAR + USD/QAR + + + 16 + USD/TND + USD/TND + + + 17 + EUR/EGP + EUR/EGP + + + 18 + EUR/JOD + EUR/JOD + + + 19 + EUR/QAR + EUR/QAR + + + 59 + EUR/TND + EUR/TND + + + 523 + EGP/USD + EGP/USD + + + 524 + EGP/EUR + EGP/EUR + + + 527 + EGP/CHF + EGP/CHF + + + 528 + JOD/USD + JOD/USD + + + 529 + JOD/EUR + JOD/EUR + + + 530 + JOD/JPY + JOD/JPY + + + 531 + JOD/GBP + JOD/GBP + + + 533 + JOD/CHF + JOD/CHF + + + 534 + QAR/EUR + QAR/EUR + + + 535 + QAR/USD + QAR/USD + + + 536 + QAR/JPY + QAR/JPY + + + 537 + QAR/GBP + QAR/GBP + + + 538 + QAR/CHF + QAR/CHF + + + 539 + SAR/USD + SAR/USD + + + 540 + SAR/EUR + SAR/EUR + + + 541 + SAR/JPY + SAR/JPY + + + 542 + SAR/GBP + SAR/GBP + + + 543 + GBP/SAR + GBP/SAR + + + 544 + SAR/CHF + SAR/CHF + + + 545 + TND/USD + TND/USD + + + 546 + TND/EUR + TND/EUR + + + 547 + TND/JPY + TND/JPY + + + 548 + TND/GBP + TND/GBP + + + 549 + TND/CHF + TND/CHF + + + 20 + EUR/SAR + EUR/SAR + + + 525 + EGP/JPY + EGP/JPY + + + 526 + EGP/GBP + EGP/GBP + + + 532 + GBP/JOD + GBP/JOD + + +
+
+ + +
+ Asian Stocks + + + + 307 + TSM + Taiwan Semiconductor Mfg + + + 308 + SNE + Sony Corp. + + + 310 + MITSY + Mitsui Co., Ltd. + + + 314 + NSANY + Nissan Motor Co., Ltd. + + + 317 + CAJ + Canon, Inc. + + + 323 + CHL + China Mobile Limited + + + 324 + SNP + Chemical Corp. + + + 313 + HMC + Honda Motor Co., Ltd. + + + 315 + MC + Matsushita Electric Ind. + + + 311 + NTT + Telephone + + + 312 + HIT + Hitachi, Ltd. + + +
+ + +
+ Commodities + + + + 333 + XAU/USD + XAU/USD + + + 334 + XAG/USD + XAG/USD + + + 335 + Platinum + Platinum + + + 336 + Palladium + Palladium + + + 504 + Light + Light + + + 505 + Brent + Brent + + + 506 + Copper + Copper + + +
+
diff --git a/protocols/Quotes/Utility/Google.py b/protocols/Quotes/Utility/Google.py new file mode 100644 index 0000000000..35653a77f6 --- /dev/null +++ b/protocols/Quotes/Utility/Google.py @@ -0,0 +1,52 @@ +from html.parser import HTMLParser +import sys +from xml.etree.ElementTree import Element, ElementTree, SubElement + +class MyHTMLParser(HTMLParser): + def __init__(self,in_fn,out_fn): + HTMLParser.__init__(self) + f_in = open(in_fn,'r') + self.quote = 0 + self.start = 0 + self.parse_option = 0 + self.elQuote = Element("fake") + elProvider = Element("Provider") + SubElement(elProvider,'name').text = 'Google' + SubElement(elProvider,'ref').text = 'http://www.google.com' + SubElement(elProvider,'url').text = 'http://www.google.com/finance/converter?a=1&' + self.root = SubElement(elProvider,'section') + SubElement(self.root,'name').text = 'Currencies' + self.feed(f_in.read()) + f_in.close() + ElementTree(elProvider).write(out_fn) + + def handle_starttag(self, tag, attrs): + self.start = 1 + if tag == 'select': + if self.parse_option == 0: + for k in attrs: + if k[0] == 'name' and k[1] == 'from': + self.parse_option = 1 + break + else: + self.parse_option == 0 + elif self.parse_option == 1 and tag == 'option': + for k in attrs: + if k[0] == 'value': + self.elQuote = SubElement(self.root,'quote') + SubElement(self.elQuote,'id').text = k[1] + SubElement(self.elQuote,'symbol').text = k[1] + break + + def handle_endtag(self, tag): + self.start = 0 + if tag == 'select': + self.parse_option == 0 + + def handle_data(self, data): + if self.start == 1 and self.parse_option == 1: + SubElement(self.elQuote,'description').text = data + +parser = MyHTMLParser(sys.argv[1],sys.argv[2]) +parser.close() + diff --git a/protocols/Quotes/Utility/GoogleFinance.xml b/protocols/Quotes/Utility/GoogleFinance.xml new file mode 100644 index 0000000000..031afbcdd5 --- /dev/null +++ b/protocols/Quotes/Utility/GoogleFinance.xml @@ -0,0 +1,7 @@ + + + + Google Finance + http://www.google.com + http://www.google.com/finance + \ No newline at end of file diff --git a/protocols/Quotes/Utility/Quotes_Readme.txt b/protocols/Quotes/Utility/Quotes_Readme.txt new file mode 100644 index 0000000000..7c0bf2ca10 --- /dev/null +++ b/protocols/Quotes/Utility/Quotes_Readme.txt @@ -0,0 +1,112 @@ +Quotes version 0.0.24.0 plugin for Miranda + +This plugin displays periodically updated economic quotes, currency exchanges and different economic and financial indexes in Miranda contact list. + +Author: Dioksin. +You can always contact me via email dioksin@ua.fm + +How to install: +unpack zip archive; +copy quotes.dll and Quotes subdirectory from Plugins folder to miranda plugins floder. +copy proto_Quotes.dll from Icons folder to miranda icons folder + +[2011-10-24] Changelog Release 0.0.24.0 +1. Tendency calculation for Yahoo was fixed + +[2011-10-18] Changelog Release 0.0.23.0 +1. Previous Close and Change values were added to YAHOO +2. If there is no xml file corresponding options page is not show in properties window + +[2011-10-14] Changelog Release 0.0.22.0 +1. Supports YAHOO +2. Options location was moved from "Plugins\Quotes" to "Network\Quotes" + +[2011-08-19] Changelog Release 0.0.21.0 +1. Tendency format specification +2. Main icon was changed +3. Currency converter icon was changed +4. Popup plugin support +5. Per-contact options +6. Menu redesign +7. Import/export from/to xml file + +[2011-08-14] Changelog Release 0.0.20.0 +1. Updation of code to use new format of Google finance HTML page + +[2010-09-26] Changelog Release 0.0.19.0 +1. Currency converter shown values in the sientific format +2. Currency converter didn't convert big values +3. Currency converter output is formatted with user-defined locale preferences +4. Swap button in the currency converter has an icon +5. Big icon is set for the currency converter to correct show in ALT+TAB dialog + +[2010-09-19] Changelog Release 0.0.18.0 +1. Thousand separator error for non USA locale in Google Finance + +Changelog Release 0.0.17.0 +1. The percent change with respecto to yesterday close variable was added to the Google Finance +2. The Vietnamese Dong was added to the Currency Converter + +Changelog Release 0.0.16.0 +1. It was impossible to get quotes from google finance on non-USA locale + +Changelog Release 0.0.15.0 +1. Crash if invalid display name format was used + +Changelog Release 0.0.14.0 +1. References to Microsoft's XML parser were removed. + +Changelog Release 0.0.12.0 +1. The Swap button had been added to the Currency Converter + +Changelog Release 0.0.11.0 +1. Google finance is supported +2. Occupied status was made optionally (To use it's necessary to set the 'ExtendedStatus' option in the Miranda's database). + +Changelog Release 0.0.9.981 +1. Currency converter +2. Refresh all Quotes\Rates +3. Refresh particular Quote\Rate +2. Minor fixings to better support national language pack + +Changelog Release 0.0.0.8 +1. Minor changing in logic of status +2. Minor resource modification to better support national language pack + +Changelog Release 0.0.0.7 +1. Status message may be set on per contact basis (second line in contact list) +2. Two new modes were added. Occupied - it's set if error occurred during rate/quote updation. DND - it's set if updation is in progress. +3. Open Log File menu item was added and Quotes related menu items are grouped in Quotes popup menu. +4. Several new variables were added: previous rate, fetch date, fetch time. +5. New empty icon was added. This icon is used when rate/quote was not changed. +6. Quotes\rate info page was changed to show both current and previous rates. +7. Database ForceToAddArrowToNick setting was added. This value governs an up\down arrow appearance in contact name. If it's equal 0 (default value) - arrows will be added only if extraicons were set . It it' equal 1 - arrows will be shown always and if it's equal 2 - arrows will be never shown. + +Changelog Release 0.0.0.6 +1. Change to log and to history only if rate (quote) value changed option has been added +2. Several minor bugs were fixed + +Changelog Release 0.0.0.5 +1. Extraicons supporting +2. Ability to change name in contact list with variables +3. Log to file +4. Log to Miranda's history +5. Proxy server supporting +6. Protocol icons were changes and removed to separate dll + +Changelog Release 0.0.0.4 +1. It is possible to get currency exchange rates from Google site +2. Unicode supporting was improved +3. User info page was modified +4. Option pages were moved under Plugin section + +Changelog Release 0.0.0.3 +1. Fix bug when decimal separator was not dot +2. User info page was added + +Changelog Release 0.0.0.2 +1. The size of plugin was reduced +2. The plugin was statically link with CRT library to resolve some dependencies to system modules +3. The updater plugin is supported now. + + diff --git a/protocols/Quotes/Utility/Yahoo.xml b/protocols/Quotes/Utility/Yahoo.xml new file mode 100644 index 0000000000..1c2a156d89 --- /dev/null +++ b/protocols/Quotes/Utility/Yahoo.xml @@ -0,0 +1,7 @@ + + + + Yahoo + http://finance.yahoo.com/ + http://finance.yahoo.com/d/ + \ No newline at end of file diff --git a/protocols/Quotes/Utility/google.xml b/protocols/Quotes/Utility/google.xml new file mode 100644 index 0000000000..9363addced --- /dev/null +++ b/protocols/Quotes/Utility/google.xml @@ -0,0 +1,91 @@ + + + + Google + http://www.google.com + http://www.google.com/finance/converter + +
+ Currencies + + AED + AED + United Arab Emirates Dirham (AED) + + + ANGANGNetherlands Antillean Gulden (ANG) + + + ARSARSArgentine Peso (ARS) + + + AUDAUDAustralian Dollar (AUD) + + + BGNBGNBulgarian Lev (BGN) + + + BHDBHDBahraini Dinar (BHD) + + + BNDBNDBrunei Dollar (BND) + + + BOBBOBBolivian Boliviano (BOB) + + + BRLBRLBrazilian Real (BRL) + + + BWPBWPBotswana Pula (BWP) + + + CADCADCanadian Dollar (CAD) + + + CHFCHFSwiss Franc (CHF) + + + CLPCLPChilean Peso (CLP) + + + CNYCNYChinese Yuan (renminbi) (CNY) + + + COPCOPColombian Peso (COP) + + + CSDCSDSerbian Dinar (CSD) + + + CZKCZKCzech Koruna (CZK) + + + DKKDKKDanish Krone (DKK) + + + EEKEEKEstonian Kroon (EEK) + + + EGPEGPEgyptian Pound (EGP) + + + EUREUREuro (EUR) + + + FJDFJDFijian Dollar (FJD) + + GBPGBPBritish Pound (GBP)HKDHKDHong Kong Dollar (HKD)HNLHNLHonduran Lempira (HNL)HRKHRKCroatian Kuna (HRK)HUFHUFHungarian Forint (HUF)IDRIDRIndonesian Rupiah (IDR)ILSILSNew Israeli Sheqel (ILS)INRINRIndian Rupee (INR)ISKISKIcelandic Króna (ISK)JPYJPYJapanese Yen (JPY)KRWKRWSouth Korean Won (KRW)KWDKWDKuwaiti Dinar (KWD)KZTKZTKazakhstani Tenge (KZT)LKRLKRSri Lankan Rupee (LKR)LTLLTLLithuanian Litas (LTL)MADMADMoroccan Dirham (MAD)MURMURMauritian Rupee (MUR)MXNMXNMexican Peso (MXN)MYRMYRMalaysian Ringgit (MYR)NOKNOKNorwegian Krone (NOK)NPRNPRNepalese Rupee (NPR)NZDNZDNew Zealand Dollar (NZD)OMROMROmani Rial (OMR)PENPENPeruvian Nuevo Sol (PEN)PHPPHPPhilippine Peso (PHP)PKRPKRPakistani Rupee (PKR)PLNPLNPolish Złoty (PLN)QARQARQatari Riyal (QAR)RONRONNew Romanian Leu (RON) + + + RUBRUBRussian Ruble (RUB) + + + SARSARSaudi Riyal (SAR) + + SEKSEKSwedish Krona (SEK)SGDSGDSingapore Dollar (SGD)SITSITSlovenian Tolar (SIT)SKKSKKSlovak Koruna (SKK)THBTHBThai Baht (THB)TRYTRYNew Turkish Lira (TRY)TTDTTDTrinidad and Tobago Dollar (TTD)TWDTWDNew Taiwan Dollar (TWD)UAHUAHUkrainian Hryvnia (UAH)USDUSDUnited States Dollar (USD)VEBVEBVenezuelan Bolívar (VEB)ZARZARSouth African Rand (ZAR) + + VNDVNDVietnamese Dong (VND) + +
+
\ No newline at end of file diff --git a/protocols/Quotes/Version.rc b/protocols/Quotes/Version.rc new file mode 100644 index 0000000000..a5fcb30231 --- /dev/null +++ b/protocols/Quotes/Version.rc @@ -0,0 +1,41 @@ +// Microsoft Visual C++ generated resource script. +// +#include "afxres.h" +#include "version.h" + +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#endif //_WIN32 + +VS_VERSION_INFO VERSIONINFO + FILEVERSION __FILEVERSION_STRING + PRODUCTVERSION __FILEVERSION_STRING + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "FileDescription", __DESCRIPTION + VALUE "FileVersion", __FILEVERSION_DOTS + VALUE "InternalName", __PLUGIN_NAME + VALUE "LegalCopyright", __COPYRIGHT + VALUE "OriginalFilename", __FILENAME + VALUE "ProductName", __PLUGIN_NAME + VALUE "ProductVersion", __FILEVERSION_DOTS + VALUE "SpecialBuild", SPECIAL_BUILD_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/protocols/Quotes/WinCtrlHelper.cpp b/protocols/Quotes/WinCtrlHelper.cpp new file mode 100644 index 0000000000..dba445958e --- /dev/null +++ b/protocols/Quotes/WinCtrlHelper.cpp @@ -0,0 +1,49 @@ +#include "stdafx.h" +#include "QuotesProviderVisitorFormatSpecificator.h" +#include "IQuotesProvider.h" +#include "resource.h" +#include "ModuleInfo.h" + +namespace +{ + INT_PTR CALLBACK VariableListDlgProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) + { + switch(msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hWnd); + const IQuotesProvider* pProvider = reinterpret_cast(lp); + CQuotesProviderVisitorFormatSpecificator visitor; + pProvider->Accept(visitor); + + tostringstream o; + const CQuotesProviderVisitorFormatSpecificator::TFormatSpecificators& raSpec = visitor.GetSpecificators(); + std::for_each(raSpec.begin(),raSpec.end(), + [&o](const CQuotesProviderVisitorFormatSpecificator::CFormatSpecificator& spec) + { + o << spec.m_sSymbol << _T('\t') << spec.m_sDesc << _T("\r\n"); + }); + ::SetDlgItemText(hWnd,IDC_EDIT_VARIABLE,o.str().c_str()); + } + break; + case WM_COMMAND: + if(BN_CLICKED == HIWORD(wp) && (IDOK == LOWORD(wp) || IDCANCEL == LOWORD(wp))) + { + ::EndDialog(hWnd,IDOK); + } + break; + } + + return FALSE; + } +} + +void show_variable_list(HWND hwndParent,const IQuotesProvider* pProvider) +{ + ::DialogBoxParam(CModuleInfo::GetModuleHandle(), + MAKEINTRESOURCE(IDD_DIALOG_VARIABLE_LIST), + hwndParent, + VariableListDlgProc, + reinterpret_cast(pProvider)); +} diff --git a/protocols/Quotes/WinCtrlHelper.h b/protocols/Quotes/WinCtrlHelper.h new file mode 100644 index 0000000000..d7f8957a86 --- /dev/null +++ b/protocols/Quotes/WinCtrlHelper.h @@ -0,0 +1,37 @@ +#ifndef __a05d6852_4497_4f28_85e1_48a15a170738_WinCtrlHelper_h__ +#define __a05d6852_4497_4f28_85e1_48a15a170738_WinCtrlHelper_h__ + +class IQuotesProvider; + +inline tstring get_window_text(HWND hWnd) +{ + int cBytes = ::GetWindowTextLength(hWnd); + + std::vector aBuf(cBytes+1); + LPTSTR pBuffer = &*(aBuf.begin()); + ::GetWindowText(hWnd,pBuffer,cBytes+1); + + return tstring(pBuffer); +} + +inline void prepare_edit_ctrl_for_error(HWND hwndEdit) +{ + ::SetFocus(hwndEdit); + ::SendMessage(hwndEdit, EM_SETSEL, 0, -1); + ::SendMessage(hwndEdit, EM_SCROLLCARET, 0, 0); +} + +void show_variable_list(HWND hwndParent,const IQuotesProvider* pProvider); + +inline int Quotes_MessageBox(HWND hWnd,LPCTSTR pszText,UINT nType = MB_OK) +{ + return ::MessageBox(hWnd,pszText,quotes_a2t(MIRANDANAME).c_str(),nType); +} + +inline void spin_set_range(HWND hwndSpin,short nLower,short nUpper) +{ + ::SendMessage(hwndSpin,UDM_SETRANGE,0,MAKELPARAM(nUpper,nLower)); +} + + +#endif //__a05d6852_4497_4f28_85e1_48a15a170738_WinCtrlHelper_h__ diff --git a/protocols/Quotes/WorkingThread.cpp b/protocols/Quotes/WorkingThread.cpp new file mode 100644 index 0000000000..bc4d80b734 --- /dev/null +++ b/protocols/Quotes/WorkingThread.cpp @@ -0,0 +1,15 @@ +#include "StdAfx.h" +#include "WorkingThread.h" + +#include "IQuotesProvider.h" + +void WorkingThread(void* pParam) +{ + IQuotesProvider* pProvider = reinterpret_cast(pParam); + assert(pProvider); + + if(pProvider) + { + pProvider->Run(); + } +} diff --git a/protocols/Quotes/WorkingThread.h b/protocols/Quotes/WorkingThread.h new file mode 100644 index 0000000000..a77734bb85 --- /dev/null +++ b/protocols/Quotes/WorkingThread.h @@ -0,0 +1,6 @@ +#ifndef __cd52f1a3_63b2_44f0_a0a9_48c203958fa4_WorkingThread_h__ +#define __cd52f1a3_63b2_44f0_a0a9_48c203958fa4_WorkingThread_h__ + +void WorkingThread(void* pParam); + +#endif //__cd52f1a3_63b2_44f0_a0a9_48c203958fa4_WorkingThread_h__ diff --git a/protocols/Quotes/XMLEngineMI.cpp b/protocols/Quotes/XMLEngineMI.cpp new file mode 100644 index 0000000000..7e2adfb7d9 --- /dev/null +++ b/protocols/Quotes/XMLEngineMI.cpp @@ -0,0 +1,230 @@ +#include "StdAfx.h" +#include "XMLEngineMI.h" + +XML_API xi; + +namespace +{ + class CXMLNodeMI : public IXMLNode, + private boost::noncopyable + { + public: + typedef boost::shared_ptr TXMLNodePtr; + + public: + explicit CXMLNodeMI(HXML hXMl,bool bDestroy = false) : m_hXML(hXMl),m_bDestroy(bDestroy) + { + assert(m_hXML); + } + + virtual ~CXMLNodeMI() + { + if(m_bDestroy) + { + xi.destroyNode(m_hXML); + } + } + + virtual size_t GetChildCount()const + { + return xi.getChildCount(m_hXML); + } + + virtual TXMLNodePtr GetChildNode(size_t nIndex)const + { + HXML h = xi.getChild(m_hXML, (int)nIndex); + if(h) + { + return TXMLNodePtr(new CXMLNodeMI(h)); + } + else + { + return TXMLNodePtr(); + } + } + + virtual tstring GetText()const + { + tstring sResult; + LPCTSTR psz = xi.getText(m_hXML); + if(psz) + { + sResult = psz; + } + + return sResult; + } + + virtual tstring GetName()const + { + tstring sResult; + LPCTSTR psz = xi.getName(m_hXML); + if(psz) + { + sResult = psz; + } + + return sResult; + } + + virtual bool AddChild(const TXMLNodePtr& pNode) + { + CXMLNodeMI* pXML = dynamic_cast(pNode.get()); + if(pXML) + { + xi.addChild2(pXML->m_hXML,m_hXML); + pXML->m_bDestroy = false; + return true; + } + else + { + return false; + } + } + + virtual bool AddAttribute(const tstring& rsName,const tstring& rsValue) + { + xi.addAttr(m_hXML,rsName.c_str(),rsValue.c_str()); + return true; + } + + virtual tstring GetAttributeValue(const tstring& rsAttrName) + { + LPCTSTR pszValue = xi.getAttrValue(m_hXML,rsAttrName.c_str()); + return ((NULL != pszValue) ? tstring(pszValue) : tstring()); + } + + virtual void Write(tostream& o)const + { +// struct safe_string +// { +// safe_string(LPTSTR p):m_p(p){} +// ~safe_string(){xi.freeMem(m_p);} +// +// LPTSTR m_p; +// }; +// +// struct mir_safe_string +// { +// mir_safe_string(LPSTR p) : m_p(p){} +// ~mir_safe_string(){mir_free(m_p);} +// +// LPSTR m_p; +// }; + + + safe_string ss(xi.toString(m_hXML,NULL)); + if(ss.m_p) + { + mir_safe_string mss(mir_utf8encodeT(ss.m_p)); + if(mss.m_p) + { + o << mss.m_p; + } + } + } + + private: + HXML m_hXML; + bool m_bDestroy; + }; +} + +CXMLEngineMI::CXMLEngineMI() +{ +} + +CXMLEngineMI::~CXMLEngineMI() +{ +} + +IXMLNode::TXMLNodePtr CXMLEngineMI::LoadFile(const tstring& rsFileName)const +{ +// struct mir_safe_string +// { +// mir_safe_string(LPTSTR p) : m_p(p){} +// ~mir_safe_string(){mir_free(m_p);} +// +// LPTSTR m_p; +// }; + + + IXMLNode::TXMLNodePtr pResult; + FILE* stream; + if(0 == ::_tfopen_s(&stream,rsFileName.c_str(),_T("r"))) + { + struct _stat st; + if (-1 != ::_fstat(::_fileno(stream),&st)) + { + std::vector aBuffer(st.st_size+1); + char* pBuffer = &*(aBuffer.begin()); + size_t cBytes = ::fread(pBuffer,sizeof(char),st.st_size,stream); + if(cBytes > 0 && cBytes <= static_cast(st.st_size)) + { + pBuffer[cBytes] = '\0'; + + int nLen = (int)cBytes; + mir_safe_string ss(mir_utf8decodeT(pBuffer)); + if(ss.m_p) + { + HXML h = xi.parseString(ss.m_p,&nLen,NULL); + if(h) + { + pResult = IXMLNode::TXMLNodePtr(new CXMLNodeMI(h,true)); + } + } + } + } + ::fclose(stream); + } + + return pResult; +} + +namespace +{ + IXMLNode::TXMLNodePtr create_node(const tstring& rsName,const tstring& rsText,bool bIsDecl) + { + IXMLNode::TXMLNodePtr pResult; + HXML h = xi.createNode(rsName.c_str(),rsText.c_str(),bIsDecl); + if(h) + { + pResult = IXMLNode::TXMLNodePtr(new CXMLNodeMI(h,true)); + } + + return pResult; + } +} + +bool CXMLEngineMI::SaveFile(const tstring& rsFileName,const IXMLNode::TXMLNodePtr& pNode)const +{ + CXMLNodeMI* pXML = dynamic_cast(pNode.get()); + if(pXML) + { + tofstream file(rsFileName.c_str()); + if(file.good()) + { + IXMLNode::TXMLNodePtr pRoot(create_node(_T("xml"),tstring(),true)); + if(pRoot) + { + pRoot->AddAttribute(_T("version"),_T("1.0")); + pRoot->AddAttribute(_T("encoding"),_T("UTF-8")); + file << *pRoot; + } + + if(file.good()) + { + file << *pNode; + } + } + + return file.good(); + } + + return false; +} + +IXMLNode::TXMLNodePtr CXMLEngineMI::CreateNode(const tstring& rsName,const tstring& rsText)const +{ + return create_node(rsName,rsText,false); +} \ No newline at end of file diff --git a/protocols/Quotes/XMLEngineMI.h b/protocols/Quotes/XMLEngineMI.h new file mode 100644 index 0000000000..5e5a51232f --- /dev/null +++ b/protocols/Quotes/XMLEngineMI.h @@ -0,0 +1,17 @@ +#ifndef __0c3d1da4_92b7_431c_83e5_f998cd513f0d_XMLEngineMI_h__ +#define __0c3d1da4_92b7_431c_83e5_f998cd513f0d_XMLEngineMI_h__ + +#include "ixmlengine.h" + +class CXMLEngineMI : public IXMLEngine +{ +public: + CXMLEngineMI(); + ~CXMLEngineMI(); + + virtual IXMLNode::TXMLNodePtr LoadFile(const tstring& rsFileName)const; + virtual bool SaveFile(const tstring& rsFileName,const IXMLNode::TXMLNodePtr& pNode)const; + virtual IXMLNode::TXMLNodePtr CreateNode(const tstring& rsName,const tstring& rsText)const; +}; + +#endif //__0c3d1da4_92b7_431c_83e5_f998cd513f0d_XMLEngineMI_h__ diff --git a/protocols/Quotes/dllmain.cpp b/protocols/Quotes/dllmain.cpp new file mode 100644 index 0000000000..9a1be15de5 --- /dev/null +++ b/protocols/Quotes/dllmain.cpp @@ -0,0 +1,23 @@ +// dllmain.cpp : Defines the entry point for the DLL application. +#include "stdafx.h" +#include "ModuleInfo.h" + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + CModuleInfo::SetModuleHandle(hModule); + break; + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} + diff --git a/protocols/Quotes/proto_Quotes/proto_Quotes.rc b/protocols/Quotes/proto_Quotes/proto_Quotes.rc new file mode 100644 index 0000000000..b9ce00b0cd --- /dev/null +++ b/protocols/Quotes/proto_Quotes/proto_Quotes.rc @@ -0,0 +1,122 @@ +//Microsoft Developer Studio generated resource script. +// + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +104 ICON DISCARDABLE "../res/proto_online.ico" +105 ICON DISCARDABLE "../res/proto_offline.ico" +131 ICON DISCARDABLE "../res/proto_na.ico" +159 ICON DISCARDABLE "../res/proto_occupied.ico" + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) +#ifdef _WIN32 +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +#pragma code_page(1251) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,0,0,1 + PRODUCTVERSION 0,0,0,15 + FILEFLAGSMASK 0x37L +#ifdef _DEBUG + FILEFLAGS 0x21L +#else + FILEFLAGS 0x20L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", "Dioksin" + VALUE "FileDescription", "Quotes protocol icons" + VALUE "FileVersion", "0, 0, 0, 1" + VALUE "InternalName", "proto_Quotes" + VALUE "LegalCopyright", "Do not worry!" + VALUE "OriginalFilename", "proto_Quotes.dll" + VALUE "ProductName", "Miranda IM" + VALUE "ProductVersion", "0, 0, 0, 15" + VALUE "SpecialBuild", "3" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + +#endif // Russian resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/protocols/Quotes/proto_Quotes/proto_Quotes_10.vcxproj b/protocols/Quotes/proto_Quotes/proto_Quotes_10.vcxproj new file mode 100644 index 0000000000..13a3acc0bc --- /dev/null +++ b/protocols/Quotes/proto_Quotes/proto_Quotes_10.vcxproj @@ -0,0 +1,129 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + Proto_Quotes + {5A0A9761-78E1-4E0F-AD8C-8931A667A5F2} + + + + DynamicLibrary + Unicode + + + DynamicLibrary + Unicode + + + DynamicLibrary + Unicode + + + DynamicLibrary + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\Icons\ + $(SolutionDir)$(Configuration)64\Icons\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)\Icons\ + $(SolutionDir)$(Configuration)64\Icons\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + true + true + true + true + + + + true + false + Windows + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + + + true + false + Windows + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + + + true + false + Windows + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + + + true + false + Windows + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/protocols/Quotes/proto_Quotes/proto_Quotes_10.vcxproj.filters b/protocols/Quotes/proto_Quotes/proto_Quotes_10.vcxproj.filters new file mode 100644 index 0000000000..6da0285fe9 --- /dev/null +++ b/protocols/Quotes/proto_Quotes/proto_Quotes_10.vcxproj.filters @@ -0,0 +1,28 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/protocols/Quotes/res/CurrencyConverter.ico b/protocols/Quotes/res/CurrencyConverter.ico new file mode 100644 index 0000000000..67ac2095f5 Binary files /dev/null and b/protocols/Quotes/res/CurrencyConverter.ico differ diff --git a/protocols/Quotes/res/Export quotes.ico b/protocols/Quotes/res/Export quotes.ico new file mode 100644 index 0000000000..31c7aa2ba1 Binary files /dev/null and b/protocols/Quotes/res/Export quotes.ico differ diff --git a/protocols/Quotes/res/Import quotes.ico b/protocols/Quotes/res/Import quotes.ico new file mode 100644 index 0000000000..506aa62af3 Binary files /dev/null and b/protocols/Quotes/res/Import quotes.ico differ diff --git a/protocols/Quotes/res/Refresh.ico b/protocols/Quotes/res/Refresh.ico new file mode 100644 index 0000000000..2dbcfd3878 Binary files /dev/null and b/protocols/Quotes/res/Refresh.ico differ diff --git a/protocols/Quotes/res/Section.ico b/protocols/Quotes/res/Section.ico new file mode 100644 index 0000000000..f59105b665 Binary files /dev/null and b/protocols/Quotes/res/Section.ico differ diff --git a/protocols/Quotes/res/down.ico b/protocols/Quotes/res/down.ico new file mode 100644 index 0000000000..9dfe185cbe Binary files /dev/null and b/protocols/Quotes/res/down.ico differ diff --git a/protocols/Quotes/res/main.ico b/protocols/Quotes/res/main.ico new file mode 100644 index 0000000000..4d32e57495 Binary files /dev/null and b/protocols/Quotes/res/main.ico differ diff --git a/protocols/Quotes/res/notchanged.ico b/protocols/Quotes/res/notchanged.ico new file mode 100644 index 0000000000..e1d9ee3a09 Binary files /dev/null and b/protocols/Quotes/res/notchanged.ico differ diff --git a/protocols/Quotes/res/proto_na.ico b/protocols/Quotes/res/proto_na.ico new file mode 100644 index 0000000000..c8888adb80 Binary files /dev/null and b/protocols/Quotes/res/proto_na.ico differ diff --git a/protocols/Quotes/res/proto_occupied.ico b/protocols/Quotes/res/proto_occupied.ico new file mode 100644 index 0000000000..3f54c740d1 Binary files /dev/null and b/protocols/Quotes/res/proto_occupied.ico differ diff --git a/protocols/Quotes/res/proto_offline.ico b/protocols/Quotes/res/proto_offline.ico new file mode 100644 index 0000000000..cd99c072bf Binary files /dev/null and b/protocols/Quotes/res/proto_offline.ico differ diff --git a/protocols/Quotes/res/proto_online.ico b/protocols/Quotes/res/proto_online.ico new file mode 100644 index 0000000000..29e500e2bb Binary files /dev/null and b/protocols/Quotes/res/proto_online.ico differ diff --git a/protocols/Quotes/res/quote.ico b/protocols/Quotes/res/quote.ico new file mode 100644 index 0000000000..832ed12f52 Binary files /dev/null and b/protocols/Quotes/res/quote.ico differ diff --git a/protocols/Quotes/res/swap.ico b/protocols/Quotes/res/swap.ico new file mode 100644 index 0000000000..1bff71b764 Binary files /dev/null and b/protocols/Quotes/res/swap.ico differ diff --git a/protocols/Quotes/res/up.ico b/protocols/Quotes/res/up.ico new file mode 100644 index 0000000000..a75899cd3d Binary files /dev/null and b/protocols/Quotes/res/up.ico differ diff --git a/protocols/Quotes/resource.h b/protocols/Quotes/resource.h new file mode 100644 index 0000000000..50ee0a637b --- /dev/null +++ b/protocols/Quotes/resource.h @@ -0,0 +1,109 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Forex.rc +// +#define IDD_DIALOG_ECONOMIC_RATES 101 +#define IDI_ICON_MAIN 102 +#define IDD_DIALOG_QUOTE_INFO 102 +#define IDD_DIALOG_OPT_GOOGLE 103 +#define IDI_ICON_SECTION 110 +#define IDI_ICON_QUOTE 111 +#define IDI_ICON_UP 113 +#define IDI_ICON_DOWN 114 +#define IDD_CONTACT_SETTINGS 115 +#define IDI_ICON_NOTCHANGED 116 +#define IDD_CURRENCY_CONVERTER 116 +#define IDI_ICON_CURRENCY_CONVERTER 117 +#define IDD_DUKASCOPY_CHART 117 +#define IDD_CHART 117 +#define IDD_DIALOG_QUOTE_INFO_1 118 +#define IDI_ICON_REFRESH 118 +#define IDD_DIALOG_OPT_FINANCE 119 +#define IDI_ICON_IMPORT 119 +#define IDI_ICON_EXPORT 120 +#define IDD_PROVIDER_ADV_SETTINGS 120 +#define IDI_ICON_SWAP 121 +#define IDD_DIALOG_POPUP 121 +#define IDD_DIALOG_VARIABLE_LIST 123 +#define IDC_TREE_ECONOMIC_RATES 1001 +#define IDC_EDIT_REFRESH_RATE 1002 +#define IDC_SPIN_REFRESH_RATE 1003 +#define IDC_COMBO_REFRESH_RATE 1004 +#define IDC_STATIC_QUOTE_NAME 1008 +#define IDC_SYSLINK_PROVIDER 1009 +#define IDC_STATIC_CHART 1010 +#define IDC_STATIC_QUOTE_CHART 1010 +#define IDC_COMBO_CONVERT_FROM 1011 +#define IDC_COMBO_CONVERT_INTO 1012 +#define IDC_BUTTON_ADD 1013 +#define IDC_LIST_RATES 1014 +#define IDC_BUTTON_REMOVE 1015 +#define IDC_EDIT_RATE 1016 +#define IDC_EDIT_RATE_FETCH_TIME 1017 +#define IDC_EDIT_CONTACT_LIST_FORMAT 1018 +#define IDC_EDIT_PREVIOUS_RATE 1018 +#define IDC_BUTTON_DESCRIPTION 1019 +#define IDC_CHECK_INTERNAL_HISTORY 1020 +#define IDC_EDIT_STATUS_MESSAGE_FORMAT 1020 +#define IDC_CHECK_EXTERNAL_FILE 1021 +#define IDC_EDIT_FILE_NAME 1022 +#define IDC_EDIT_TENDENCY_FORMAT 1022 +#define IDC_BUTTON_BROWSE 1023 +#define IDC_STATIC_SELECT_FILE 1024 +#define IDC_EDIT_NAME 1025 +#define IDC_EDIT_HISTORY_FORMAT 1026 +#define IDC_EDIT_LOG_FILE_FORMAT 1027 +#define IDC_BUTTON_DESCRIPTION2 1028 +#define IDC_BUTTON_LOG_FILE_DESCRIPTION 1028 +#define IDC_STATIC_HISTORY_FORMAT 1029 +#define IDC_BUTTON_HISTORY_DESCRIPTION 1030 +#define IDC_STATIC_LOG_FILE_FORMAT 1031 +#define IDC_CHECK_HISTORY_CONDITION 1032 +#define IDC_CHECK_LOG_CONDITION2 1033 +#define IDC_CHECK_LOG_FILE_CONDITION 1033 +#define IDC_EDIT_VALUE 1033 +#define IDC_BUTTON_CONVERT 1034 +#define IDC_CHECK_SHOW_POPUP_ONLY_VALUE_CHANGED 1034 +#define IDC_STATIC_POPUP_FORMAT 1035 +#define IDC_EDIT_POPUP_FORMAT 1036 +#define IDC_BUTTON_LOG_FILE_DESCRIPTION2 1037 +#define IDC_BUTTON_POPUP_FORMAT_DESCRIPTION 1037 +#define IDC_EDIT_RESULT 1039 +#define IDC_STATIC_IMAGE 1056 +#define IDC_EDIT_QUOTE 1059 +#define IDC_BUTTON_SWAP 1060 +#define IDC_BUTTON_ADVANCED_SETTINGS 1061 +#define IDC_BUTTON_POPUP_SETTINGS 1061 +#define IDC_CHECK_CONTACT_SPECIFIC 1062 +#define IDC_RADIO_DEFAULT_COLOURS 1063 +#define IDC_CHECK_SHOW_POPUP 1064 +#define IDC_RADIO_USER_DEFINED_COLOURS 1064 +#define IDC_MFCCOLORBUTTON1 1066 +#define IDC_CHECK1 1067 +#define IDC_CHECK_DONT_USE_POPUPHISTORY 1067 +#define IDC_COMBO_DATA_SOURCE 1068 +#define IDC_COMBO_FILTER 1069 +#define IDC_EDIT_FROM 1070 +#define IDC_EDIT_FROM2 1071 +#define IDC_EDIT_TO 1071 +#define IDC_STATIC_PROVIDER_NAME 1071 +#define IDC_DELAY 1072 +#define IDC_EDIT1 1072 +#define IDC_EDIT_VARIABLE 1072 +#define IDC_BGCOLOR 1074 +#define IDC_TEXTCOLOR 1075 +#define IDC_PREV 1076 +#define IDC_DELAYFROMPU 1093 +#define IDC_DELAYCUSTOM 1094 +#define IDC_DELAYPERMANENT 1095 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 124 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1073 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/protocols/Quotes/stdafx.cpp b/protocols/Quotes/stdafx.cpp new file mode 100644 index 0000000000..e4738d8f60 --- /dev/null +++ b/protocols/Quotes/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// Forex.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/protocols/Quotes/stdafx.h b/protocols/Quotes/stdafx.h new file mode 100644 index 0000000000..19c85a3303 --- /dev/null +++ b/protocols/Quotes/stdafx.h @@ -0,0 +1,165 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" +#define MIRANDA_VER 0x0800 +#define MIRANDA_CUSTOM_LP +// #define CHART_IMPLEMENT +#define TEST_IMPORT_EXPORT + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// Miranda headers +#pragma warning(disable: 4996) +#include +#include +#include +#include +#pragma warning(default: 4996) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// boost headers +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "boost/date_time/c_local_time_adjustor.hpp" + +// stl headers +#include +#include +#include +#include +#include +#include + +#ifdef _UNICODE +typedef std::wstring tstring; +typedef std::wostringstream tostringstream; +typedef std::wistringstream tistringstream; +typedef std::wofstream tofstream; +typedef std::wifstream tifstream; +typedef std::wostream tostream; +typedef std::wistream tistream; +typedef boost::posix_time::wtime_input_facet ttime_input_facet; +typedef boost::posix_time::wtime_facet ttime_facet; +#else +typedef std::string tstring; +typedef std::ostringstream tostringstream; +typedef std::istringstream tistringstream; +typedef std::ofstream tofstream; +typedef std::ifstream tifstream; +typedef std::ostream tostream; +typedef std::istream tistream; +typedef boost::posix_time::time_input_facet ttime_input_facet; +typedef boost::posix_time::time_facet ttime_facet; +#endif + +inline int quotes_stricmp(LPCTSTR p1,LPCTSTR p2) +{ + return _tcsicmp(p1,p2); +} + +inline std::string quotes_t2a(const TCHAR* t) +{ + std::string s; + char* p = mir_t2a(t); + if(p) + { + s = p; + mir_free(p); + } + return s; +} + +inline tstring quotes_a2t(const char* s) +{ + tstring t; + TCHAR* p = mir_a2t(s); + if(p) + { + t = p; + mir_free(p); + } + return t; +} +namespace detail +{ + template struct safe_string_impl + { + typedef T* PTR; + + safe_string_impl(PTR p) : m_p(p){} + ~safe_string_impl(){TD::dealloc(m_p);} + + PTR m_p; + }; + + template struct MirandaFree + { + static void dealloc(T* p){mir_free(p);} + }; + + template struct OwnerFree + { + static void dealloc(T* p){::free(p);} + }; +} + +template struct mir_safe_string : public detail::safe_string_impl> +{ + mir_safe_string(PTR p) : detail::safe_string_impl>(p){} +}; + +template struct safe_string : public detail::safe_string_impl> +{ + safe_string(PTR p) : detail::safe_string_impl>(p){} +}; + + +// #ifdef MIRANDA_VER +// #undef MIRANDA_VER +// #endif + +// TODO: reference additional headers your program requires here diff --git a/protocols/Quotes/targetver.h b/protocols/Quotes/targetver.h new file mode 100644 index 0000000000..f583181dfd --- /dev/null +++ b/protocols/Quotes/targetver.h @@ -0,0 +1,24 @@ +#pragma once + +// The following macros define the minimum required platform. The minimum required platform +// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run +// your application. The macros work by enabling all features available on platform versions up to and +// including the version specified. + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Specifies that the minimum required platform is Windows Vista. +#define WINVER 0x0600 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. +#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98. +#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0. +#define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE. +#endif diff --git a/protocols/Quotes/version.h b/protocols/Quotes/version.h new file mode 100644 index 0000000000..956486d4d5 --- /dev/null +++ b/protocols/Quotes/version.h @@ -0,0 +1,25 @@ +#define __MAJOR_VERSION 0 +#define __MINOR_VERSION 0 +#define __RELEASE_NUM 24 +#define __BUILD_NUM 0 + +#define __FILEVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM +#define __FILEVERSION_DOTS __MAJOR_VERSION.__MINOR_VERSION.__RELEASE_NUM.__BUILD_NUM + +#define __STRINGIFY_IMPL(x) #x +#define __STRINGIFY(x) __STRINGIFY_IMPL(x) +#define __VERSION_STRING __STRINGIFY(__FILEVERSION_DOTS) + +#if defined (_UNICODE) +#define __PLUGIN_NAME "Quotes (Unicode)" +#else +#define __PLUGIN_NAME "Quotes" +#endif +#define __INTERNAL_NAME "Quotes" +#define __FILENAME "Quotes.dll" +#define __DESCRIPTION "Show currency rates and economic quotes." +#define __AUTHOR "Dioksin" +#define __AUTHOREMAIL "dioksin@ua.fm" +#define __AUTHORWEB "http://www.miranda-im.org" +#define __COPYRIGHT "Don't worry!" +#define SPECIAL_BUILD_STRING "5388" -- cgit v1.2.3