From f04d64869f3b1de54fb343f28f955584780001b8 Mon Sep 17 00:00:00 2001 From: mataes2007 Date: Sat, 26 Nov 2011 15:41:10 +0000 Subject: Project folders rename part 3 git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@215 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- TooltipNotify/src/TooltipNotify.cpp | 1114 +++++++++++++++++++++++++++++++++++ 1 file changed, 1114 insertions(+) create mode 100644 TooltipNotify/src/TooltipNotify.cpp (limited to 'TooltipNotify/src/TooltipNotify.cpp') diff --git a/TooltipNotify/src/TooltipNotify.cpp b/TooltipNotify/src/TooltipNotify.cpp new file mode 100644 index 0000000..ac480dc --- /dev/null +++ b/TooltipNotify/src/TooltipNotify.cpp @@ -0,0 +1,1114 @@ +// TooltipNotify.cpp: implementation of the CTooltipNotify class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "resource.h" +#include "TooltipNotify.h" +#include "Tooltip.h" +#include "Settings.h" +#include "DbHelpers.h" +#include "Utils.h" + +#define ReadSettingByte(c, d) DBGetContactSettingByte(NULL, s_szModuleName, c, d) +#define ReadSettingWord(c, d) DBGetContactSettingWord(NULL, s_szModuleName, c, d) +#define ReadSettingDword(c, d) DBGetContactSettingDword(NULL, s_szModuleName, c, d) +#define ReadSettingString(c, d) DBGetContactSettingTString(NULL, s_szModuleName, c, d) + +#define WriteSettingByte(c, d) DBWriteContactSettingByte(NULL, s_szModuleName, c, d) +#define WriteSettingWord(c, d) DBWriteContactSettingWord(NULL, s_szModuleName, c, d) +#define WriteSettingDword(c, d) DBWriteContactSettingDword(NULL, s_szModuleName, c, d) +#define WriteSettingString(c, d) DBWriteContactSettingTString(NULL, s_szModuleName, c, d) + +enum +{ + ProtoIntBit = 0x01, + ProtoUserBit = 0x02 +}; + +static const char* SND_ONLINE = "ttntfOnline"; +static const char* SND_OFFLINE = "ttntfOffline"; +static const char* SND_OTHER = "ttntfOther"; +static const char* SND_TYPING = "ttntfTyping"; +static const char* CONTACT_IGNORE_TTNOTIFY = "Ignore"; + +static const int ID_TTNTF_STATUS_TYPING = ID_STATUS_INVISIBLE+10; +static const int ID_TTNTF_STATUS_IDLE = ID_STATUS_INVISIBLE+11; +static const int ID_TTNTF_STATUS_NOT_IDLE = ID_STATUS_INVISIBLE+12; + +#define FONTSERV_GROUP _T("Tooltip Notify") +#define FONTSERV_ONLINE _T("Online") +#define FONTSERV_OFFLINE _T("Offline") +#define FONTSERV_OTHER _T("Other Status") +#define FONTSERV_TYPING _T("Typing") +#define FONTSERV_IDLE _T("Idle") + +struct FontEntry +{ + int status; + TCHAR* name; + char* fontPrefix; + char* clrPrefix; +}; + +static FontEntry s_fontTable[] = +{ + ID_STATUS_ONLINE, FONTSERV_ONLINE, "OnlineFont", "OnlineBgColor", + ID_STATUS_OFFLINE, FONTSERV_OFFLINE, "OfflineFont", "OfflineBgColor", + ID_TTNTF_STATUS_TYPING, FONTSERV_TYPING, "TypingFont", "TypingBgColor", + ID_TTNTF_STATUS_IDLE, FONTSERV_IDLE, "IdleFont", "IdleBgColor", + ID_TTNTF_STATUS_NOT_IDLE, FONTSERV_IDLE, "IdleFont", "IdleBgColor", + 0, FONTSERV_OTHER, "OtherFont", "OtherBgColor", +}; + +/*static*/ CTooltipNotify *CTooltipNotify::s_pInstance = 0; +/*static*/ const char *CTooltipNotify::s_szModuleNameOld = "ttntfmod"; +/*static*/ const char *CTooltipNotify::s_szModuleName = "TooltipNotify"; + + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CTooltipNotify::CTooltipNotify(HINSTANCE hinstDLL) : + m_hDllInstance(hinstDLL), m_bNt50(IsNt50()) +{ + if (s_pInstance!=0) + throw EAlreadyExists(); + + s_pInstance = this; + + CTooltip::Initialize(m_hDllInstance); +} + +CTooltipNotify::~CTooltipNotify() +{ + EndNotifyAll(); + CTooltip::Deinitialize(m_hDllInstance); + s_pInstance=0; +} + +void CTooltipNotify::RegisterFonts() +{ + FontIDT fontId = {0}; + fontId.cbSize = sizeof(fontId); + _tcscpy(fontId.group, FONTSERV_GROUP); + strcpy(fontId.dbSettingsGroup, s_szModuleName); + fontId.flags = FIDF_DEFAULTVALID; + fontId.deffontsettings.colour = DEF_SETTING_TXTCOLOR; + fontId.deffontsettings.size = -MulDiv(DEF_SETTING_FONT_SIZE, DEF_LOGPIXELSY, 72); + fontId.deffontsettings.style = DEF_SETTING_FONT_STYLE; + fontId.deffontsettings.charset = DEF_SETTING_FONT_CHARSET; + _tcscpy(fontId.deffontsettings.szFace, DEF_SETTING_FONT_FACE); + fontId.order = 0; + _tcscpy(fontId.backgroundGroup, FONTSERV_GROUP); + + ColourIDT colorId = {0}; + colorId.cbSize = sizeof(colorId); + _tcscpy(colorId.group, FONTSERV_GROUP); + strcpy(colorId.dbSettingsGroup, s_szModuleName); + colorId.flags = 0; + colorId.defcolour = DEF_SETTING_BGCOLOR; + colorId.order = 0; + + for (int i=0; i0) + { + STooltipData *pTooltipData = new STooltipData; + pTooltipData->uiTimeout = lParam*1000; + pTooltipData->hContact = (HANDLE)wParam; + pTooltipData->iStatus = ID_TTNTF_STATUS_TYPING; + + EndNotifyAll(); + SkinPlaySound(SND_TYPING); + BeginNotify(pTooltipData); + } + else + { + EndNotifyAll(); + } + + return 0; +} + + +int CTooltipNotify::ProtoAck(WPARAM wParam, LPARAM lParam) +{ + ACKDATA *ack=(ACKDATA*)lParam; + if(ack->type != ACKTYPE_STATUS) return 0; + + WORD wNewStatus = (WORD)ack->lParam; + WORD wOldStatus = (WORD)ack->hProcess; + if (wOldStatus == wNewStatus) return 0; //Useless message. + + char *szProtocol = (char *)ack->szModule; + + if (wNewStatus == ID_STATUS_OFFLINE) + { + BYTE bProtoActive = ReadSettingByte(szProtocol, ProtoUserBit|ProtoIntBit); + bProtoActive &= ~ProtoIntBit; + WriteSettingByte(szProtocol, bProtoActive); + } + else + { + if (wOldStatus < ID_STATUS_ONLINE && wNewStatus > ID_STATUS_OFFLINE) + { + UINT_PTR idTimer = SetTimer(0, 0, m_sOptions.wStartupDelay*1000, ConnectionTimerProcWrapper); + ProtoData protoData = { _strdup(szProtocol), idTimer }; + m_mapTimerIdProto.push_back(protoData); + } + } + + return 0; +} + +int CTooltipNotify::ContactSettingChanged(WPARAM wParam, LPARAM lParam) +{ + DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam; + HANDLE hContact = (HANDLE)wParam; + if(hContact==NULL) return 0; + + bool idle = false; + if (lstrcmpA(cws->szSetting,"Status")==0) + idle = false; + else if (lstrcmpA(cws->szSetting,"IdleTS")==0) + idle = true; + else return 0; + + if(DBGetContactSettingByte(hContact, "CList", "Hidden", 0)) return 0; + + const char *pszProto = cws->szModule; + if (ReadSettingByte(pszProto, ProtoUserBit|ProtoIntBit) != (ProtoUserBit|ProtoIntBit)) + { + return 0; + } + + if (DBGetContactSettingByte(hContact, "CList", "NotOnList", 0) && m_sOptions.bIgnoreUnknown) + { + return 0; + } + + if (DBGetContactSettingByte(hContact, s_szModuleName, CONTACT_IGNORE_TTNOTIFY, m_sOptions.bIgnoreNew)) + { + return 0; + } + + if (idle && !m_sOptions.bIdle) return 0; + + WORD wNewStatus = cws->value.wVal; + switch(wNewStatus) + { + case ID_STATUS_OFFLINE: + if (!m_sOptions.bOffline) return 0; + SkinPlaySound(SND_OFFLINE); + break; + + case ID_STATUS_ONLINE: + if(CallService(MS_IGNORE_ISIGNORED,(WPARAM)hContact,IGNOREEVENT_USERONLINE) && m_sOptions.bConjSOLN) return 0; + if (!m_sOptions.bOnline) return 0; + SkinPlaySound(SND_ONLINE); + break; + + default: + if (!m_sOptions.bOther) return 0; + SkinPlaySound(SND_OTHER); + break; + } + + STooltipData *pTooltipData = new STooltipData; + pTooltipData->uiTimeout = m_sOptions.wDuration * (wNewStatus==ID_STATUS_ONLINE ? (m_sOptions.bX2+1):1); + pTooltipData->hContact = hContact; + + if (idle) wNewStatus = (wNewStatus!=0 ? ID_TTNTF_STATUS_IDLE : ID_TTNTF_STATUS_NOT_IDLE); + pTooltipData->iStatus = wNewStatus; + + EndNotifyAll(); + BeginNotify(pTooltipData); + + return 0; + +} + +int CTooltipNotify::InitializeOptions(WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp; + + ZeroMemory(&odp,sizeof(odp)); + odp.cbSize = sizeof(odp); + odp.position = 100000000; + odp.hInstance = m_hDllInstance; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); + odp.ptszTitle = TranslateT("Tooltip Notify"); + odp.ptszGroup = TranslateT("Appearance"); + odp.groupPosition = 910000000; + odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; + odp.pfnDlgProc = CTooltipNotify::OptionsDlgProcWrapper; + ::CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp); + + return 0; +} + +CTooltip *CTooltipNotify::BeginNotify(STooltipData *pTooltipData) +{ + TCHAR szTooltipText[64] = {0}; + MakeTooltipString(pTooltipData->hContact, pTooltipData->iStatus, szTooltipText, 64); + + LOGFONT lf = {0}; + COLORREF textColor = 0; + COLORREF bgColor = 0; + GetFont(pTooltipData->iStatus, &lf, &textColor, &bgColor); + + CTooltip *pTooltip = new CTooltip(this); + pTooltip->set_Text(szTooltipText); + pTooltip->set_Font(lf); + pTooltip->set_BgColor(bgColor); + pTooltip->set_TextColor(textColor); + if (m_bNt50 && m_sOptions.bTransp) + pTooltip->set_Translucency(m_sOptions.bAlpha); + pTooltip->set_TransparentInput(m_bNt50 && m_sOptions.bTransp && m_sOptions.bTranspInput); + pTooltip->Validate(); + + RECT TooltipRect, WorkAreaRect; + SystemParametersInfo(SPI_GETWORKAREA, 0, &WorkAreaRect, 0); + pTooltip->get_Rect(&TooltipRect); + + int tt_width = TooltipRect.right-TooltipRect.left; + int tt_height = TooltipRect.bottom-TooltipRect.top; + + if (m_sOptions.bAutoPos || + m_sOptions.wXPos > WorkAreaRect.right-tt_width || + m_sOptions.wYPos > WorkAreaRect.bottom-tt_height) + { + pTooltip->set_Position( + WorkAreaRect.right - 10 - tt_width, + WorkAreaRect.bottom - 2 - tt_height); + } + else + { + pTooltip->set_Position(m_sOptions.wXPos, m_sOptions.wYPos); + } + + + UINT_PTR idTimer = SetTimer(0, 0, pTooltipData->uiTimeout, TooltipTimerProcWrapper); + pTooltipData->idTimer = idTimer; + pTooltipData->pTooltip = pTooltip; + + m_TooltipsList.push_back(pTooltipData); + + pTooltip->Show(); + + return pTooltip; +} + +BOOL CTooltipNotify::EndNotify(STooltipData* pTooltipData) +{ + CTooltip* pTooltip = pTooltipData->pTooltip; + + // return if the tooltip timer suspended + if (pTooltipData->idTimer == 0) return FALSE; + SuspendTimer(pTooltip); + + pTooltip->Hide(); + delete pTooltip; + delete pTooltipData; + + m_TooltipsList.erase( + std::remove(m_TooltipsList.begin(), m_TooltipsList.end(), pTooltipData), + m_TooltipsList.end()); + + return TRUE; +} + +VOID CTooltipNotify::EndNotifyAll() +{ + // iterate through active tooltips and + // remove one which do not have its timer suspended + TooltipsList::reverse_iterator mapRevIter = m_TooltipsList.rbegin(); + while (mapRevIter != m_TooltipsList.rend()) + { + STooltipData* pTooltipData = *mapRevIter; + if (EndNotify(pTooltipData)) + { + mapRevIter = m_TooltipsList.rbegin(); + } + else + { + ++mapRevIter; + } + } +} + +CTooltipNotify::MapTimerIdProtoIter CTooltipNotify::FindProtoByTimer(UINT idTimer) +{ + for ( + MapTimerIdProtoIter iter = m_mapTimerIdProto.begin(); + iter != m_mapTimerIdProto.end(); + ++iter) + { + if (iter->timerId == idTimer) + { + return iter; + } + } + + return m_mapTimerIdProto.end(); +} + +VOID CTooltipNotify::OnConnectionTimer(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + BOOL bSuccess = KillTimer(0, idEvent); + assert(bSuccess); + + MapTimerIdProtoIter iter = FindProtoByTimer(idEvent); + assert(iter!=m_mapTimerIdProto.end()); + + BYTE bProtoActive = ReadSettingByte(iter->proto, ProtoUserBit|ProtoIntBit); + bProtoActive |= ProtoIntBit; + WriteSettingByte(iter->proto, bProtoActive); + + free((char*)iter->proto); + m_mapTimerIdProto.erase(iter); +} + + +VOID CTooltipNotify::OnTooltipTimer(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + TooltipsList::iterator iter = FindBy(&STooltipData::idTimer, idEvent); + assert(iter!=m_TooltipsList.end()); + + STooltipData* pTooltipData = *iter; + EndNotify(pTooltipData); +} + +VOID CTooltipNotify::MigrateSettings() +{ + if (ModuleSettingsExists(NULL, s_szModuleNameOld) && !ModuleSettingsExists(NULL, s_szModuleName)) + { + RenameModule(NULL, s_szModuleNameOld, s_szModuleName); + } +} + +VOID CTooltipNotify::LoadSettings() +{ + m_sOptions.bFirstRun = ReadSettingByte("firstrun", DEF_SETTING_FIRSTRUN); + m_sOptions.bOffline = ReadSettingByte("offline", DEF_SETTING_OFFLINE); + m_sOptions.bOnline = ReadSettingByte("online", DEF_SETTING_ONLINE); + m_sOptions.bOther = ReadSettingByte("other", DEF_SETTING_OTHER); + m_sOptions.bTyping = ReadSettingByte("typing", DEF_SETTING_TYPING); + m_sOptions.bIdle = ReadSettingByte("idle", DEF_SETTING_TYPING); + m_sOptions.bX2 = ReadSettingByte("x2", DEF_SETTING_X2); + m_sOptions.bConjSOLN = ReadSettingByte("conjsoln", DEF_SETTING_CONJSOLN); + m_sOptions.bAutoPos = ReadSettingByte("autopos", DEF_SETTING_DEF_POS); + m_sOptions.bBallonTip = ReadSettingByte("balloontip", DEF_SETTING_BALLONTIP); + m_sOptions.bTransp = ReadSettingByte("transp", DEF_SETTING_TRANSP); + m_sOptions.bAlpha = ReadSettingByte("alpha", DEF_SETTING_ALPHA); + m_sOptions.bTranspInput = ReadSettingByte("transpinput", DEF_SETTING_TRANSP_INPUT); + m_sOptions.bPrefixProto = ReadSettingByte("prfxproto", DEF_SETTING_PREFIX_PROTO); + m_sOptions.bLDblClick = ReadSettingByte("ldblclick", DEF_SETTING_LDBLCLICK); + m_sOptions.wDuration = ReadSettingWord("duration", DEF_SETTING_DURATION); + m_sOptions.wXPos = ReadSettingWord("xpos", DEF_SETTING_DEF_XPOS); + m_sOptions.wYPos = ReadSettingWord("ypos", DEF_SETTING_DEF_YPOS); + m_sOptions.wStartupDelay = ReadSettingWord("suprconndelay", DEF_SETTING_STARTUP_DELAY); + m_sOptions.bIgnoreUnknown = ReadSettingByte("ignoreunknown", DEF_SETTING_IGNORE_UNKNOWN); + m_sOptions.bIgnoreNew = ReadSettingByte("ignorenew", DEF_SETTING_IGNORE_NEW); +} + +VOID CTooltipNotify::SaveSettings() +{ + WriteSettingWord("duration", m_sOptions.wDuration); + WriteSettingWord("suprconndelay", m_sOptions.wStartupDelay); + WriteSettingByte("offline", m_sOptions.bOffline); + WriteSettingByte("online", m_sOptions.bOnline); + WriteSettingByte("other", m_sOptions.bOther); + WriteSettingByte("typing", m_sOptions.bTyping); + WriteSettingByte("idle", m_sOptions.bIdle); + WriteSettingByte("prfxproto", m_sOptions.bPrefixProto); + WriteSettingByte("x2", m_sOptions.bX2); + WriteSettingByte("conjsoln", m_sOptions.bConjSOLN); + WriteSettingByte("autopos", m_sOptions.bAutoPos); + WriteSettingByte("balloontip", m_sOptions.bBallonTip); + WriteSettingByte("transp", m_sOptions.bTransp); + WriteSettingByte("alpha", m_sOptions.bAlpha); + WriteSettingByte("transpinput", m_sOptions.bTranspInput); + WriteSettingByte("ldblclick", m_sOptions.bLDblClick); + WriteSettingByte("ignoreunknown", m_sOptions.bIgnoreUnknown); + WriteSettingByte("ignorenew", m_sOptions.bIgnoreNew); +} + + +VOID CTooltipNotify::ReadSettingsFromDlg(HWND hDlg) +{ + m_sOptions.bOffline = (BYTE)(IsDlgButtonChecked(hDlg, IDC_OFFLINE) == BST_CHECKED ? 1:0); + m_sOptions.bOnline = (BYTE)(IsDlgButtonChecked(hDlg, IDC_ONLINE) == BST_CHECKED ? 1:0); + m_sOptions.bOther = (BYTE)(IsDlgButtonChecked(hDlg, IDC_OTHER) == BST_CHECKED ? 1:0); + m_sOptions.bTyping = (BYTE)(IsDlgButtonChecked(hDlg, IDC_TYPING) == BST_CHECKED ? 1:0); + m_sOptions.bIdle = (BYTE)(IsDlgButtonChecked(hDlg, IDC_IDLE) == BST_CHECKED ? 1:0); + m_sOptions.bX2 = (BYTE)(IsDlgButtonChecked(hDlg, IDC_X2) == BST_CHECKED ? 1:0); + m_sOptions.bConjSOLN = (BYTE)(IsDlgButtonChecked(hDlg, IDC_CONJSOLN) == BST_CHECKED ? 1:0); + m_sOptions.bAutoPos = (BYTE)(IsDlgButtonChecked(hDlg, IDC_AUTOPOS) == BST_CHECKED ? 1:0); + m_sOptions.bBallonTip = (BYTE)(IsDlgButtonChecked(hDlg, IDC_BALLONTIP) == BST_CHECKED ? 1:0); + m_sOptions.bTransp = (BYTE)(IsDlgButtonChecked(hDlg, IDC_TRANSPARENCY) == BST_CHECKED ? 1:0); + m_sOptions.bAlpha = (BYTE)SendDlgItemMessage(hDlg,IDC_TRANSPARENCY_SLIDER,TBM_GETPOS,0,0); + m_sOptions.bTranspInput = (BYTE)(IsDlgButtonChecked(hDlg, IDC_TRANSP_INPUT) == BST_CHECKED ? 1:0); + m_sOptions.bPrefixProto = (BYTE)(IsDlgButtonChecked(hDlg, IDC_PREFIX_PROTO) == BST_CHECKED ? 1:0); + m_sOptions.bLDblClick = (BYTE)(IsDlgButtonChecked(hDlg, IDC_RB_CLIST) == BST_CHECKED) ? SHOW_HIDE_CLIST:OPEN_MSGDLG; + m_sOptions.wDuration = LOWORD(SendDlgItemMessage(hDlg, IDC_DURATIONSPIN, UDM_GETPOS, 0, 0)); + m_sOptions.wStartupDelay = LOWORD(SendDlgItemMessage(hDlg, IDC_DELAYONCONNSPIN, UDM_GETPOS, 0, 0)); +} + +VOID CTooltipNotify::WriteSettingsToDlg(HWND hDlg) +{ + SendDlgItemMessage(hDlg, IDC_DURATIONSPIN, UDM_SETRANGE, 0, MAKELONG(550*36, 550)); + SendDlgItemMessage(hDlg, IDC_DURATIONSPIN, UDM_SETPOS, 0, MAKELONG(m_sOptions.wDuration, 0)); + SendDlgItemMessage(hDlg, IDC_DELAYONCONNSPIN, UDM_SETRANGE, 0, MAKELONG(30, 0)); + SendDlgItemMessage(hDlg, IDC_DELAYONCONNSPIN, UDM_SETPOS, 0, MAKELONG(m_sOptions.wStartupDelay, 0)); + + CheckDlgButton(hDlg, IDC_OFFLINE, m_sOptions.bOffline ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_ONLINE, m_sOptions.bOnline ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_OTHER, m_sOptions.bOther ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_TYPING, m_sOptions.bTyping ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_IDLE, m_sOptions.bIdle ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_PREFIX_PROTO, m_sOptions.bPrefixProto ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_X2, m_sOptions.bX2 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_CONJSOLN, m_sOptions.bConjSOLN ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_AUTOPOS, m_sOptions.bAutoPos ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_BALLONTIP, m_sOptions.bBallonTip ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_TRANSPARENCY, m_sOptions.bTransp ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_TRANSP_INPUT, m_sOptions.bTranspInput ? BST_CHECKED:BST_UNCHECKED); + + switch(m_sOptions.bLDblClick) + { + case SHOW_HIDE_CLIST: CheckDlgButton(hDlg, IDC_RB_CLIST, TRUE); break; + case OPEN_MSGDLG: CheckDlgButton(hDlg, IDC_RB_MSGDLG, TRUE); break; + default: CheckDlgButton(hDlg, IDC_RB_CLIST, TRUE); break; + } + + EnableWindow(GetDlgItem(hDlg, IDC_GB_TRANSP), m_bNt50); + EnableWindow(GetDlgItem(hDlg, IDC_TRANSPARENCY), m_bNt50); + EnableWindow(GetDlgItem(hDlg, IDC_TRANSPARENCY_SLIDER), m_sOptions.bTransp && m_bNt50); + EnableWindow(GetDlgItem(hDlg, IDC_TRANSPERC), m_sOptions.bTransp && m_bNt50); + EnableWindow(GetDlgItem(hDlg, IDC_TRANSP_INPUT), m_sOptions.bTransp && m_bNt50); + //EnableWindow(GetDlgItem(hDlg, IDC_GB_DBLCLICK), m_sOptions.bTranspInput); + EnableWindow(GetDlgItem(hDlg, IDC_RB_CLIST), !m_sOptions.bTranspInput); + EnableWindow(GetDlgItem(hDlg, IDC_RB_MSGDLG), !m_sOptions.bTranspInput); + + SendDlgItemMessage(hDlg, IDC_TRANSPARENCY_SLIDER, TBM_SETRANGE, FALSE, MAKELONG(1,255)); + SendDlgItemMessage(hDlg, IDC_TRANSPARENCY_SLIDER, TBM_SETPOS, TRUE, m_sOptions.bAlpha); +} + + +VOID CTooltipNotify::ValidateSettings() +{ + if (m_sOptions.wStartupDelay>30) m_sOptions.wStartupDelay=30; + if (m_sOptions.wDuration>550*36) m_sOptions.wDuration=550*36; + if (m_sOptions.wDuration<550*1) m_sOptions.wDuration=550*1; + if (!m_sOptions.bTransp) m_sOptions.bTranspInput=0; +} + + +// main options dialog +BOOL CTooltipNotify::OptionsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hDlg); + WriteSettingsToDlg(hDlg); + SendMessage(hDlg, WM_HSCROLL, 0x12345678, 0); + + return TRUE; + } + + case WM_VSCROLL: + case WM_HSCROLL: + { + TCHAR str[10]; + wsprintf(str, _T("%d%%"), 100*SendDlgItemMessage(hDlg, IDC_TRANSPARENCY_SLIDER, TBM_GETPOS, 0, 0)/255); + SetDlgItemText(hDlg, IDC_TRANSPERC, str); + if(wParam!=0x12345678) SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0); + return TRUE; + } + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_TRANSPARENCY: + EnableWindow(GetDlgItem(hDlg, IDC_TRANSPERC), IsDlgButtonChecked(hDlg, IDC_TRANSPARENCY) == BST_CHECKED); + EnableWindow(GetDlgItem(hDlg, IDC_TRANSPARENCY_SLIDER), IsDlgButtonChecked(hDlg, IDC_TRANSPARENCY) == BST_CHECKED); + EnableWindow(GetDlgItem(hDlg, IDC_TRANSP_INPUT), IsDlgButtonChecked(hDlg, IDC_TRANSPARENCY) == BST_CHECKED); + CheckDlgButton(hDlg, IDC_TRANSP_INPUT, IsDlgButtonChecked(hDlg, IDC_TRANSPARENCY) == BST_CHECKED ? m_sOptions.bTranspInput : BST_UNCHECKED); + SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(IDC_TRANSP_INPUT, 0), 0); + SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0); + break; + + case IDC_TRANSP_INPUT: + //EnableWindow(GetDlgItem(hDlg,IDC_GB_DBLCLICK), IsDlgButtonChecked(hDlg, IDC_TRANSP_INPUT)); + EnableWindow(GetDlgItem(hDlg,IDC_RB_CLIST), !(IsDlgButtonChecked(hDlg, IDC_TRANSP_INPUT) == BST_CHECKED)); + EnableWindow(GetDlgItem(hDlg,IDC_RB_MSGDLG), !(IsDlgButtonChecked(hDlg, IDC_TRANSP_INPUT) == BST_CHECKED)); + SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0); + break; + + case IDC_BALLONTIP: + EnableWindow(GetDlgItem(hDlg,IDC_DURATION),!(IsDlgButtonChecked(hDlg,IDC_BALLONTIP)==BST_CHECKED)); + EnableWindow(GetDlgItem(hDlg,IDC_X2),!(IsDlgButtonChecked(hDlg,IDC_BALLONTIP)==BST_CHECKED)); + EnableWindow(GetDlgItem(hDlg,IDC_RB_CLIST),!(IsDlgButtonChecked(hDlg,IDC_BALLONTIP)==BST_CHECKED)); + EnableWindow(GetDlgItem(hDlg,IDC_RB_MSGDLG),!(IsDlgButtonChecked(hDlg,IDC_BALLONTIP)==BST_CHECKED)); + EnableWindow(GetDlgItem(hDlg,IDC_TRANSP_INPUT),!(IsDlgButtonChecked(hDlg,IDC_BALLONTIP)==BST_CHECKED)); + EnableWindow(GetDlgItem(hDlg,IDC_AUTOPOS),!(IsDlgButtonChecked(hDlg,IDC_BALLONTIP)==BST_CHECKED)); + SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0); + break; + + case IDC_DURATION: + if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus()) return FALSE; + SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0); + break; + + case IDC_DELAYONCONN: + if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus()) return FALSE; + SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0); + break; + + case IDC_PREVIEW: + { + STooltipData *pTooltipData = new STooltipData; + pTooltipData->uiTimeout = m_sOptions.wDuration * (m_sOptions.bX2 ? (m_sOptions.bX2+1):1); + pTooltipData->hContact = 0; + pTooltipData->iStatus = ID_STATUS_ONLINE; + + EndNotifyAll(); + BeginNotify(pTooltipData); + break; + } + + case IDC_SEL_PROTO: + DialogBox(m_hDllInstance, MAKEINTRESOURCE(IDD_PROTOS), hDlg, (DLGPROC)CTooltipNotify::ProtosDlgProcWrapper); + break; + + case IDC_IGNORE: + DialogBox(m_hDllInstance, MAKEINTRESOURCE(IDD_CONTACTS), hDlg, (DLGPROC)CTooltipNotify::ContactsDlgProcWrapper); + break; + + default: + // activate 'apply' button + SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0); + return TRUE; + } + + return TRUE; + } + + case WM_NOTIFY: + { + //Here we have pressed either the OK or the APPLY button. + switch(((LPNMHDR)lParam)->idFrom) + { + case 0: + switch (((LPNMHDR)lParam)->code) + { + case PSN_APPLY: + ReadSettingsFromDlg(hDlg); + SaveSettings(); + return TRUE; + + } // switch code + break; + + } //switch idFrom + + return TRUE; + } + + default: + break; + + } + + return FALSE; + +} + + +// dialog for protocols selecting +BOOL CTooltipNotify::ProtosDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + + case WM_INITDIALOG: + { + TranslateDialogDefault(hDlg); + + ListView_SetExtendedListViewStyle(GetDlgItem(hDlg, IDC_PROTOS), LVS_EX_CHECKBOXES); + + // enum protocols currently running + int iProtoCount = 0; + PROTOCOLDESCRIPTOR **ppProtos = 0; + ::CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&iProtoCount, (LPARAM)&ppProtos); + + // and fill in the list + int iNonProtoCount = 0; + for (int i=0; i < iProtoCount; i++) + { + if (ppProtos[i]->type == PROTOTYPE_PROTOCOL) + { + LV_ITEM lvi; + + lvi.mask = LVIF_TEXT; + lvi.iSubItem = 0; + lvi.iItem = i; + lvi.lParam = i; +#ifdef _UNICODE + WCHAR wszProto[128]; + long lLen = MultiByteToWideChar(CP_ACP, 0, ppProtos[i]->szName, + strlen(ppProtos[i]->szName), wszProto, ARRAY_SIZE(wszProto)); + wszProto[lLen] = L'\0'; + + lvi.pszText = wszProto; +#else + lvi.pszText = ppProtos[lvi.iItem]->szName; +#endif + int new_item = ListView_InsertItem(GetDlgItem(hDlg,IDC_PROTOS),&lvi); + + BYTE bProtoState = ReadSettingByte(ppProtos[i]->szName, ProtoUserBit|ProtoIntBit); + BOOL bProtoEnabled = (bProtoState & ProtoUserBit) != 0; + ListView_SetCheckState(GetDlgItem(hDlg,IDC_PROTOS), i-iNonProtoCount, bProtoEnabled); + } + else + { + iNonProtoCount++; + } + } + + return TRUE; + } + + + case WM_COMMAND: + { + if (LOWORD(wParam) == IDOK) + { + int proto_count = ListView_GetItemCount(GetDlgItem(hDlg,IDC_PROTOS)); + + for (int i=0; i < proto_count; i++) + { + TCHAR szProto[64]; + + ListView_GetItemText(GetDlgItem(hDlg,IDC_PROTOS), i, 0, szProto, ARRAY_SIZE(szProto)); +#ifdef _UNICODE + char szMultiByteProto[128]; + long lLen = WideCharToMultiByte(CP_ACP, 0, szProto, lstrlen(szProto), + szMultiByteProto, sizeof(szMultiByteProto), NULL, NULL); + szMultiByteProto[lLen] = '\0'; + + BYTE bProtoState = ReadSettingByte(szMultiByteProto, ProtoUserBit|ProtoIntBit); +#else + BYTE bProtoState = ReadSettingByte(szProto, ProtoUserBit|ProtoIntBit); +#endif + + BOOL bProtoEnabled = ListView_GetCheckState(GetDlgItem(hDlg,IDC_PROTOS), i); + bProtoState = bProtoEnabled ? bProtoState|ProtoUserBit : bProtoState&~ProtoUserBit; +#ifdef _UNICODE + WriteSettingByte(szMultiByteProto, bProtoState); +#else + WriteSettingByte(szProto, bProtoState); +#endif + } + + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + } + + if (LOWORD(wParam) == IDCANCEL) + { + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + } + + return TRUE; + } + + case WM_CLOSE: + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + + default: + break; + + } // switch (msg) + + return FALSE; + +} + +void CTooltipNotify::ResetCList(HWND hwndDlg) +{ + BOOL b = (CallService(MS_CLUI_GETCAPS, 0, 0) & CLUIF_DISABLEGROUPS && + DBGetContactSettingByte(NULL, "CList", "UseGroups", SETTING_USEGROUPS_DEFAULT)); + SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETUSEGROUPS, (WPARAM) b, 0); + + SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETHIDEEMPTYGROUPS, 1, 0); + SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETGREYOUTFLAGS, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETLEFTMARGIN, 2, 0); + SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETBKBITMAP, 0, (LPARAM) (HBITMAP) NULL); + SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETBKCOLOR, GetSysColor(COLOR_WINDOW), 0); + SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETINDENT, 10, 0); + + for (int i = 0; i <= FONTID_MAX; i++) + SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETTEXTCOLOR, i, GetSysColor(COLOR_WINDOWTEXT)); +} + +void CTooltipNotify::LoadList(HWND hwndDlg, HANDLE hItemNew, HANDLE hItemUnknown) +{ + if (hItemNew && !m_sOptions.bIgnoreNew) + { + SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETCHECKMARK, (WPARAM) hItemNew, 1); + } + if (hItemUnknown && !m_sOptions.bIgnoreUnknown) + { + SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETCHECKMARK, (WPARAM) hItemUnknown, 1); + } + + HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + do + { + HANDLE hItem = (HANDLE) SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_FINDCONTACT, (WPARAM) hContact, 0); + if (hItem && !DBGetContactSettingByte(hContact, s_szModuleName, CONTACT_IGNORE_TTNOTIFY, m_sOptions.bIgnoreNew)) + { + SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETCHECKMARK, (WPARAM) hItem, 1); + } + } + while (hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0)); +} + +void CTooltipNotify::SaveList(HWND hwndDlg, HANDLE hItemNew, HANDLE hItemUnknown) +{ + if (hItemNew) + { + m_sOptions.bIgnoreNew = (BYTE) (SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_GETCHECKMARK, (WPARAM) hItemNew, 0) ? 0 : 1); + } + if (hItemUnknown) + { + m_sOptions.bIgnoreUnknown = (BYTE) (SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_GETCHECKMARK, (WPARAM) hItemUnknown, 0) ? 0 : 1); + } + + HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + do + { + HANDLE hItem = (HANDLE) SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_FINDCONTACT, (WPARAM) hContact, 0); + if (hItem) + { + BYTE bChecked = (BYTE) (SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_GETCHECKMARK, (WPARAM) hItem, 0)); + DBWriteContactSettingByte(hContact, s_szModuleName, CONTACT_IGNORE_TTNOTIFY, bChecked ? 0 : 1); + } + } + while (hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0)); +} + + +// dialog for ignore tooltip notifications +BOOL CTooltipNotify::ContactsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static HANDLE hItemNew, hItemUnknown; + + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hDlg); + + CLCINFOITEM cii = { 0 }; + cii.cbSize = sizeof(cii); + cii.flags = CLCIIF_GROUPFONT | CLCIIF_CHECKBOX; + cii.pszText = TranslateT("** New contacts **"); + hItemNew = (HANDLE) SendDlgItemMessage(hDlg, IDC_CLIST, CLM_ADDINFOITEM, 0, (LPARAM) & cii); + cii.pszText = TranslateT("** Unknown contacts **"); + hItemUnknown = (HANDLE) SendDlgItemMessage(hDlg, IDC_CLIST, CLM_ADDINFOITEM, 0, (LPARAM) & cii); + + ResetCList(hDlg); + LoadList(hDlg, hItemNew, hItemUnknown); + return TRUE; + } + + + case WM_COMMAND: + { + if (LOWORD(wParam) == IDOK) + { + SaveList(hDlg, hItemNew, hItemUnknown); + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + } + + if (LOWORD(wParam) == IDCANCEL) + { + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + } + + return TRUE; + } + + case WM_CLOSE: + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + + default: + break; + + } // switch (msg) + + return FALSE; + +} + + + +TCHAR *CTooltipNotify::StatusToString(int iStatus, TCHAR *szStatus, int iBufSize) +{ + + //iBufSize--; + + switch(iStatus) + { + case ID_STATUS_OFFLINE: + lstrcpyn(szStatus, TranslateT("Offline"), iBufSize); + break; + + case ID_STATUS_ONLINE: + lstrcpyn(szStatus, TranslateT("Online"), iBufSize); + break; + + case ID_STATUS_AWAY: + lstrcpyn(szStatus, TranslateT("Away"), iBufSize); + break; + + case ID_STATUS_NA : + lstrcpyn(szStatus, TranslateT("N/A"), iBufSize); + break; + + case ID_STATUS_OCCUPIED: + lstrcpyn(szStatus, TranslateT("Occupied"), iBufSize); + break; + + case ID_STATUS_DND: + lstrcpyn(szStatus, TranslateT("DND"), iBufSize); + break; + + case ID_STATUS_FREECHAT: + lstrcpyn(szStatus, TranslateT("Free for chat"), iBufSize); + break; + + case ID_STATUS_INVISIBLE: + lstrcpyn(szStatus, TranslateT("Invisible"), iBufSize); + break; + + case ID_TTNTF_STATUS_TYPING: + lstrcpyn(szStatus, TranslateT("Typing"), iBufSize); + break; + + case ID_TTNTF_STATUS_IDLE: + lstrcpyn(szStatus, TranslateT("Idle"), iBufSize); + break; + + case ID_TTNTF_STATUS_NOT_IDLE: + lstrcpyn(szStatus, TranslateT("Not Idle"), iBufSize); + break; + + default: + lstrcpyn(szStatus, TranslateT("Unknown"), iBufSize); + break; + } + + return szStatus; + +} + +TCHAR *CTooltipNotify::MakeTooltipString(HANDLE hContact, int iStatus, TCHAR *szString, int iBufSize) +{ + TCHAR szStatus[32]; + StatusToString(iStatus, szStatus, ARRAY_SIZE(szStatus)); + + // "proro: user is online" + const TCHAR *szFormatString = m_sOptions.bPrefixProto ? _T("%s%s%s") : _T("%.0s%.0s%s"); + const TCHAR* szIs = TranslateT("is"); + + const char* szProto = + hContact==0 ? "Proto" : (char*)::CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + const TCHAR* szContactName = + (TCHAR *)::CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR); + + memset(szString, 0, iBufSize*sizeof(TCHAR)); + +#ifdef _UNICODE + WCHAR wszProto[32]; + long lLen = MultiByteToWideChar(CP_ACP, 0, szProto, strlen(szProto), wszProto, ARRAY_SIZE(wszProto)); + wszProto[lLen] = _T('\0'); + + _sntprintf(szString, iBufSize-1, szFormatString, wszProto, _T(": "), szContactName); +#else + _sntprintf(szString, iBufSize-1, szFormatString, szProto, _T(": "), szContactName); +#endif + + TruncateWithDots(szString, iBufSize-1-_tcslen(szStatus)-_tcslen(szIs)-2); // 2 spaces around szIs + _sntprintf(szString+_tcslen(szString), iBufSize-1-_tcslen(szString), _T(" %s %s"), szIs, szStatus); + + return szString; +} + + +VOID CTooltipNotify::OnTooltipDblClicked(CTooltip *pTooltip) +{ + switch(m_sOptions.bLDblClick) + { + case SHOW_HIDE_CLIST: + ::CallService(MS_CLIST_SHOWHIDE,0,0); + break; + + case OPEN_MSGDLG: + { + TooltipsList::iterator iter = FindBy(&STooltipData::pTooltip, pTooltip); + STooltipData* pTooltipData = *iter; + WPARAM wParam = (WPARAM)pTooltipData->hContact; + if (wParam) ::CallService(MS_CLIST_CONTACTDOUBLECLICKED, wParam, 0); + break; + } + + default: + ::CallService(MS_CLIST_SHOWHIDE,0,0); + break; + } +} + + +BOOL CTooltipNotify::OnTooltipBeginMove(CTooltip *pTooltip) +{ + if (m_sOptions.bAutoPos) return FALSE; + + SuspendTimer(pTooltip); + return TRUE; +} + + +VOID CTooltipNotify::OnTooltipEndMove(CTooltip *pTooltip) +{ + RECT TooltipRect; + + pTooltip->get_Rect(&TooltipRect); + m_sOptions.wXPos = (WORD)TooltipRect.left; + m_sOptions.wYPos = (WORD)TooltipRect.top; + WriteSettingWord("xpos", m_sOptions.wXPos); + WriteSettingWord("ypos", m_sOptions.wYPos); + + ResumeTimer(pTooltip); +} + + +VOID CTooltipNotify::SuspendTimer(CTooltip *pTooltip) +{ + TooltipsList::iterator iter = FindBy(&STooltipData::pTooltip, pTooltip); + assert(iter!=m_TooltipsList.end()); + + STooltipData* pTooltipData = *iter; + + BOOL bSuccess = KillTimer(0, pTooltipData->idTimer); + assert(bSuccess); + pTooltipData->idTimer = 0; // denote that the timer is inactive +} + + +VOID CTooltipNotify::ResumeTimer(CTooltip *pTooltip) +{ + TooltipsList::iterator iter = FindBy(&STooltipData::pTooltip, pTooltip); + assert(iter!=m_TooltipsList.end()); + + STooltipData* pTooltipData = *iter; + + UINT_PTR idTimer = SetTimer(0, 0, pTooltipData->uiTimeout, TooltipTimerProcWrapper); + pTooltipData->idTimer = idTimer; +} + +template +CTooltipNotify::TooltipsList::iterator CTooltipNotify::FindBy(T STooltipData::* field, const T& value) +{ + for ( + TooltipsList::iterator iter = m_TooltipsList.begin(); + iter != m_TooltipsList.end(); + ++iter) + { + STooltipData *pTooltipData = *iter; + if (pTooltipData->*field == value) + { + return iter; + } + } + + return m_TooltipsList.end(); +} -- cgit v1.2.3