summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2018-05-11 21:22:17 +0200
committerGeorge Hazan <ghazan@miranda.im>2018-05-11 21:22:17 +0200
commit3f1628f127d35aa14da97e50c2a94cfd61ad52dd (patch)
treee9f1d8a1282e3c5ee0139003f4aac0e932a99213
parent6a6f2b9e3b2749f16b513dfc98d5d5038b5628fb (diff)
merge from master to
fixes #1349 (Miranda crashes on coming back from auto away)
-rw-r--r--plugins/MyDetails/src/data.cpp2
-rw-r--r--plugins/Scriver/res/resource.rc4
-rw-r--r--plugins/Scriver/src/chat_window.cpp14
-rw-r--r--plugins/Scriver/src/globals.cpp2
-rw-r--r--plugins/Scriver/src/globals.h1
-rw-r--r--plugins/Scriver/src/msgdialog.cpp12
-rw-r--r--plugins/Scriver/src/msgoptions.cpp4
-rw-r--r--plugins/Scriver/src/msgs.h2
-rw-r--r--plugins/Scriver/src/resource.h1
-rw-r--r--plugins/Scriver/src/version.h2
-rw-r--r--plugins/SimpleStatusMsg/src/main.cpp3
-rw-r--r--plugins/SmileyAdd/src/options.cpp4
-rw-r--r--plugins/SmileyAdd/src/smileys.cpp1928
-rw-r--r--plugins/SmileyAdd/src/smileys.h3
-rw-r--r--plugins/SmileyAdd/src/stdafx.h1
-rw-r--r--plugins/SmileyAdd/src/version.h2
-rw-r--r--plugins/StatusManager/src/AdvancedAutoAway/advancedautoaway.cpp2
-rw-r--r--plugins/StatusManager/src/KeepStatus/keepstatus.cpp6
-rw-r--r--plugins/StatusManager/src/StartupStatus/ss_profiles.cpp2
-rw-r--r--plugins/StatusManager/src/StartupStatus/startupstatus.cpp2
-rw-r--r--plugins/StatusManager/src/commonstatus.cpp59
-rw-r--r--plugins/StatusManager/src/commonstatus.h2
-rw-r--r--plugins/StatusManager/src/confirmdialog.cpp28
-rw-r--r--plugins/StatusManager/src/version.h4
-rw-r--r--plugins/TabSRMM/src/resource.h1
-rw-r--r--src/core/stdmsg/res/resource.rc35
-rw-r--r--src/core/stdmsg/src/chat_manager.cpp28
-rw-r--r--src/core/stdmsg/src/chat_options.cpp2
-rw-r--r--src/core/stdmsg/src/chat_window.cpp30
-rw-r--r--src/core/stdmsg/src/globals.cpp3
-rw-r--r--src/core/stdmsg/src/globals.h2
-rw-r--r--src/core/stdmsg/src/msgdialog.cpp84
-rw-r--r--src/core/stdmsg/src/msgoptions.cpp8
-rw-r--r--src/core/stdmsg/src/msgs.cpp38
-rw-r--r--src/core/stdmsg/src/msgs.h66
-rw-r--r--src/core/stdmsg/src/resource.h14
-rw-r--r--src/core/stdmsg/src/stdafx.h9
-rw-r--r--src/core/stdmsg/src/tabs.cpp51
-rw-r--r--src/mir_app/src/clisttray.cpp2
39 files changed, 1245 insertions, 1218 deletions
diff --git a/plugins/MyDetails/src/data.cpp b/plugins/MyDetails/src/data.cpp
index 8dda970f0a..813041948d 100644
--- a/plugins/MyDetails/src/data.cpp
+++ b/plugins/MyDetails/src/data.cpp
@@ -154,7 +154,7 @@ void Protocol::SetStatus(int aStatus)
GetStatusMsg(aStatus, status_msg, _countof(status_msg));
pse[0]->m_szMsg = status_msg;
- CallService(MS_CS_SETSTATUSEX, (WPARAM)&pse, 0);
+ CallService(MS_CS_SETSTATUSEX, (WPARAM)&pse, pCount);
for (int i = 0; i < pCount; i++)
mir_free(pse[i]);
diff --git a/plugins/Scriver/res/resource.rc b/plugins/Scriver/res/resource.rc
index 69aadc0e0d..b5254672e9 100644
--- a/plugins/Scriver/res/resource.rc
+++ b/plugins/Scriver/res/resource.rc
@@ -91,9 +91,7 @@ BEGIN
CONTROL "Show toolbar",IDC_SHOWTOOLBAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,34,180,10
CONTROL "Show info bar",IDC_SHOWINFOBAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,45,180,10
CONTROL "Show avatars",IDC_AVATARSUPPORT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,56,180,10
- CONTROL "Use the contact's status icon as the window icon",IDC_STATUSWIN,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,67,292,10
- CONTROL "Show progress indicator",IDC_SHOWPROGRESS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,78,180,10
+ CONTROL "Show progress indicator",IDC_SHOWPROGRESS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,67,180,10
CONTROL "Enable transparency",IDC_TRANSPARENCY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,95,140,10
LTEXT "active",IDC_TRANSPARENCYTEXT1,152,91,36,8
CONTROL "Slider1",IDC_ATRANSPARENCYVALUE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,194,91,70,12
diff --git a/plugins/Scriver/src/chat_window.cpp b/plugins/Scriver/src/chat_window.cpp
index 7331033f84..ad31b1805e 100644
--- a/plugins/Scriver/src/chat_window.cpp
+++ b/plugins/Scriver/src/chat_window.cpp
@@ -533,16 +533,11 @@ void CChatRoomDlg::UpdateStatusBar()
void CChatRoomDlg::UpdateTitle()
{
+ MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule);
+
TitleBarData tbd = {};
- if (g_dat.flags & SMF_STATUSICON) {
- MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule);
- tbd.hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIcon : mi->hOfflineIcon;
- tbd.hIconBig = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIconBig : mi->hOfflineIconBig;
- }
- else {
- tbd.hIcon = GetCachedIcon("chat_window");
- tbd.hIconBig = g_dat.hIconChatBig;
- }
+ tbd.hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIcon : mi->hOfflineIcon;
+ tbd.hIconBig = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIconBig : mi->hOfflineIconBig;
tbd.hIconNot = (m_si->wState & (GC_EVENT_HIGHLIGHT | STATE_TALK)) ? GetCachedIcon("chat_overlay") : nullptr;
wchar_t szTemp[512];
@@ -564,6 +559,7 @@ void CChatRoomDlg::UpdateTitle()
tbd.iFlags = TBDF_TEXT | TBDF_ICON;
tbd.pszText = szTemp;
SendMessage(m_hwndParent, CM_UPDATETITLEBAR, (WPARAM)&tbd, (LPARAM)m_hwnd);
+
SendMessage(m_hwnd, DM_UPDATETABCONTROL, 0, 0);
}
diff --git a/plugins/Scriver/src/globals.cpp b/plugins/Scriver/src/globals.cpp
index 058f0d5286..0886f048cc 100644
--- a/plugins/Scriver/src/globals.cpp
+++ b/plugins/Scriver/src/globals.cpp
@@ -366,8 +366,6 @@ void ReloadGlobals()
g_dat.flags |= SMF_SENDONENTER;
if (db_get_b(0, SRMM_MODULE, SRMSGSET_SENDONDBLENTER, SRMSGDEFSET_SENDONDBLENTER))
g_dat.flags |= SMF_SENDONDBLENTER;
- if (db_get_b(0, SRMM_MODULE, SRMSGSET_STATUSICON, SRMSGDEFSET_STATUSICON))
- g_dat.flags |= SMF_STATUSICON;
if (db_get_b(0, SRMM_MODULE, SRMSGSET_INDENTTEXT, SRMSGDEFSET_INDENTTEXT))
g_dat.flags |= SMF_INDENTTEXT;
diff --git a/plugins/Scriver/src/globals.h b/plugins/Scriver/src/globals.h
index a396493a4a..652a077f86 100644
--- a/plugins/Scriver/src/globals.h
+++ b/plugins/Scriver/src/globals.h
@@ -33,7 +33,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define SMF_SENDONDBLENTER 0x00000200
#define SMF_SHOWPROGRESS 0x00000400
#define SMF_AVATAR 0x00000800
-#define SMF_STATUSICON 0x00002000
#define SMF_RTL 0x00004000
#define SMF_USEIEVIEW 0x00010000
#define SMF_SHOWICONS 0x00020000
diff --git a/plugins/Scriver/src/msgdialog.cpp b/plugins/Scriver/src/msgdialog.cpp
index faddf76067..a9110a2e03 100644
--- a/plugins/Scriver/src/msgdialog.cpp
+++ b/plugins/Scriver/src/msgdialog.cpp
@@ -598,14 +598,14 @@ void CSrmmWindow::GetTitlebarIcon(TitleBarData *tbd)
if (m_bShowTyping && (g_dat.flags2 & SMF2_SHOWTYPINGWIN))
tbd->hIconNot = tbd->hIcon = GetCachedIcon("scriver_TYPING");
else if (m_iShowUnread && (GetActiveWindow() != m_hwndParent || GetForegroundWindow() != m_hwndParent)) {
- tbd->hIcon = (g_dat.flags & SMF_STATUSICON) ? m_hStatusIcon : g_dat.hMsgIcon;
- tbd->hIconNot = (g_dat.flags & SMF_STATUSICON) ? g_dat.hMsgIcon : GetCachedIcon("scriver_OVERLAY");
+ tbd->hIcon = m_hStatusIcon;
+ tbd->hIconNot = g_dat.hMsgIcon;
}
else {
- tbd->hIcon = (g_dat.flags & SMF_STATUSICON) ? m_hStatusIcon : g_dat.hMsgIcon;
+ tbd->hIcon = m_hStatusIcon;
tbd->hIconNot = nullptr;
}
- tbd->hIconBig = (g_dat.flags & SMF_STATUSICON) ? m_hStatusIconBig : g_dat.hMsgIconBig;
+ tbd->hIconBig = m_hStatusIconBig;
}
bool CSrmmWindow::IsTypingNotificationSupported()
@@ -784,10 +784,8 @@ void CSrmmWindow::UpdateTitle()
ptrW tmplt(db_get_wsa(0, SRMM_MODULE, SRMSGSET_WINDOWTITLE));
if (tmplt != nullptr)
wszTitle = tmplt;
- else if (g_dat.flags & SMF_STATUSICON)
- wszTitle = L"%name% - ";
else
- wszTitle = L"%name% (%status%) : ";
+ wszTitle = L"%name% - ";
if (m_hContact && m_szProto) {
wszTitle.Replace(L"%name%", Clist_GetContactDisplayName(m_hContact));
diff --git a/plugins/Scriver/src/msgoptions.cpp b/plugins/Scriver/src/msgoptions.cpp
index ecaac38ec9..0ddefba75d 100644
--- a/plugins/Scriver/src/msgoptions.cpp
+++ b/plugins/Scriver/src/msgoptions.cpp
@@ -398,7 +398,6 @@ static INT_PTR CALLBACK DlgProcLayoutOptions(HWND hwndDlg, UINT msg, WPARAM wPar
EnableWindow(GetDlgItem(hwndDlg, IDC_TRANSPARENCYTEXT1), bChecked);
EnableWindow(GetDlgItem(hwndDlg, IDC_TRANSPARENCYTEXT2), bChecked);
- CheckDlgButton(hwndDlg, IDC_STATUSWIN, db_get_b(0, SRMM_MODULE, SRMSGSET_STATUSICON, SRMSGDEFSET_STATUSICON) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_SHOWPROGRESS, db_get_b(0, SRMM_MODULE, SRMSGSET_SHOWPROGRESS, SRMSGDEFSET_SHOWPROGRESS) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_AVATARSUPPORT, g_dat.flags & SMF_AVATAR);
return TRUE;
@@ -449,7 +448,6 @@ static INT_PTR CALLBACK DlgProcLayoutOptions(HWND hwndDlg, UINT msg, WPARAM wPar
db_set_dw(0, SRMM_MODULE, SRMSGSET_ACTIVEALPHA, SendDlgItemMessage(hwndDlg, IDC_ATRANSPARENCYVALUE, TBM_GETPOS, 0, 0));
db_set_dw(0, SRMM_MODULE, SRMSGSET_INACTIVEALPHA, SendDlgItemMessage(hwndDlg, IDC_ITRANSPARENCYVALUE, TBM_GETPOS, 0, 0));
- db_set_b(0, SRMM_MODULE, SRMSGSET_STATUSICON, (BYTE)IsDlgButtonChecked(hwndDlg, IDC_STATUSWIN));
db_set_b(0, SRMM_MODULE, SRMSGSET_SHOWPROGRESS, (BYTE)IsDlgButtonChecked(hwndDlg, IDC_SHOWPROGRESS));
db_set_b(0, SRMM_MODULE, SRMSGSET_AVATARENABLE, (BYTE)IsDlgButtonChecked(hwndDlg, IDC_AVATARSUPPORT));
@@ -487,8 +485,6 @@ static INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LP
CheckDlgButton(hwndDlg, IDC_CASCADE, db_get_b(0, SRMM_MODULE, SRMSGSET_CASCADE, SRMSGDEFSET_CASCADE) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_SENDONENTER, db_get_b(0, SRMM_MODULE, SRMSGSET_SENDONENTER, SRMSGDEFSET_SENDONENTER) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_SENDONDBLENTER, db_get_b(0, SRMM_MODULE, SRMSGSET_SENDONDBLENTER, SRMSGDEFSET_SENDONDBLENTER) ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_STATUSWIN, db_get_b(0, SRMM_MODULE, SRMSGSET_STATUSICON, SRMSGDEFSET_STATUSICON) ? BST_CHECKED : BST_UNCHECKED);
-
CheckDlgButton(hwndDlg, IDC_HIDECONTAINERS, db_get_b(0, SRMM_MODULE, SRMSGSET_HIDECONTAINERS, SRMSGDEFSET_HIDECONTAINERS) ? BST_CHECKED : BST_UNCHECKED);
EnableWindow(GetDlgItem(hwndDlg, IDC_STAYMINIMIZED), IsDlgButtonChecked(hwndDlg, IDC_AUTOPOPUP));
diff --git a/plugins/Scriver/src/msgs.h b/plugins/Scriver/src/msgs.h
index bb209cb686..16c6b6e5d6 100644
--- a/plugins/Scriver/src/msgs.h
+++ b/plugins/Scriver/src/msgs.h
@@ -374,8 +374,6 @@ extern int fontOptionsListSize;
#define SRMSGDEFSET_SENDONENTER 1
#define SRMSGSET_SENDONDBLENTER "SendOnDblEnter"
#define SRMSGDEFSET_SENDONDBLENTER 0
-#define SRMSGSET_STATUSICON "UseStatusWinIcon"
-#define SRMSGDEFSET_STATUSICON 0
#define SRMSGSET_SENDBUTTON "UseSendButton"
#define SRMSGDEFSET_SENDBUTTON 0
#define SRMSGSET_CHARCOUNT "ShowCharCount"
diff --git a/plugins/Scriver/src/resource.h b/plugins/Scriver/src/resource.h
index 7966a71277..7b429acd80 100644
--- a/plugins/Scriver/src/resource.h
+++ b/plugins/Scriver/src/resource.h
@@ -125,7 +125,6 @@
#define IDC_ERRORTEXT 1596
#define IDC_MSGTEXT 1597
#define IDC_SHOWNOTIFY 1600
-#define IDC_STATUSWIN 1601
#define IDC_TYPEWIN 1602
#define IDC_TYPETRAY 1603
#define IDC_TABSATBOTTOM 1603
diff --git a/plugins/Scriver/src/version.h b/plugins/Scriver/src/version.h
index d6cf92b2b3..fc56d643d5 100644
--- a/plugins/Scriver/src/version.h
+++ b/plugins/Scriver/src/version.h
@@ -1,7 +1,7 @@
#define __MAJOR_VERSION 3
#define __MINOR_VERSION 0
#define __RELEASE_NUM 1
-#define __BUILD_NUM 7
+#define __BUILD_NUM 8
#include <stdver.h>
diff --git a/plugins/SimpleStatusMsg/src/main.cpp b/plugins/SimpleStatusMsg/src/main.cpp
index 1e01eb7936..92575882db 100644
--- a/plugins/SimpleStatusMsg/src/main.cpp
+++ b/plugins/SimpleStatusMsg/src/main.cpp
@@ -1727,8 +1727,7 @@ static int OnModulesLoaded(WPARAM, LPARAM)
if (db_get_b(NULL, "SimpleStatusMsg", "UpdateMsgOn", 1))
g_uUpdateMsgTimer = SetTimer(nullptr, 0, db_get_w(NULL, "SimpleStatusMsg", "UpdateMsgInt", 10) * 1000, UpdateMsgTimerProc);
- if (ServiceExists(MS_CS_SETSTATUSEX))
- HookEvent(ME_CS_STATUSCHANGEEX, CSStatusChange);
+ HookEvent(ME_CS_STATUSCHANGEEX, CSStatusChange);
if (accounts->statusCount == 0)
return 0;
diff --git a/plugins/SmileyAdd/src/options.cpp b/plugins/SmileyAdd/src/options.cpp
index 897982ade5..de31cf1b8a 100644
--- a/plugins/SmileyAdd/src/options.cpp
+++ b/plugins/SmileyAdd/src/options.cpp
@@ -482,9 +482,9 @@ bool OptionsDialogType::BrowseForSmileyPacks(int item)
wchar_t filter[512], *pfilter;
mir_wstrcpy(filter, TranslateT("Smiley packs"));
- mir_wstrcat(filter, L" (*.msl;*.asl)");
+ mir_wstrcat(filter, L" (*.msl;*.asl;*.xep)");
pfilter = filter + mir_wstrlen(filter) + 1;
- mir_wstrcpy(pfilter, L"*.msl;*.asl");
+ mir_wstrcpy(pfilter, L"*.msl;*.asl;*.xep");
pfilter = pfilter + mir_wstrlen(pfilter) + 1;
mir_wstrcpy(pfilter, TranslateT("All files"));
mir_wstrcat(pfilter, L" (*.*)");
diff --git a/plugins/SmileyAdd/src/smileys.cpp b/plugins/SmileyAdd/src/smileys.cpp
index 73a303a393..6c19d195f0 100644
--- a/plugins/SmileyAdd/src/smileys.cpp
+++ b/plugins/SmileyAdd/src/smileys.cpp
@@ -1,911 +1,1017 @@
-/*
-Miranda NG SmileyAdd Plugin
-Copyright (C) 2012-18 Miranda NG team (https://miranda-ng.org)
-Copyright (C) 2005-11 Boris Krasnovskiy All Rights Reserved
-Copyright (C) 2003-04 Rein-Peter de Boer
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation version 2
-of the License.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "stdafx.h"
-
-SmileyPackListType g_SmileyPacks;
-SmileyCategoryListType g_SmileyCategories;
-
-static HWND hwndHidden = nullptr;
-
-static void CALLBACK timerProc(HWND, UINT, UINT_PTR param, DWORD)
-{
- SmileyType *pType = (SmileyType*)param;
- pType->MoveToNextFrame();
-}
-
-// these two functions must be called from the main thread
-static void CALLBACK sttStartTimer(PVOID obj)
-{
- if (hwndHidden == nullptr)
- hwndHidden = CreateWindowEx(0, L"STATIC", nullptr, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr, nullptr);
-
- SmileyType *pType = (SmileyType*)obj;
- pType->SetFrameDelay();
-}
-
-static void CALLBACK sttStopTimer(PVOID obj)
-{
- KillTimer(hwndHidden, (DWORD_PTR)obj);
-}
-
-//
-// SmileyType
-//
-
-SmileyType::SmileyType(void) :
- m_arSmileys(10, PtrKeySortT)
-{
- m_SmileyIcon = nullptr;
- m_xepimg = nullptr;
- m_flags = 0;
- m_index = 0;
- m_size.cx = 0;
- m_size.cy = 0;
-}
-
-SmileyType::~SmileyType()
-{
- if (m_xepimg) {
- m_xepimg->Release();
- m_xepimg = nullptr;
- }
-
- if (m_SmileyIcon != nullptr) {
- DestroyIcon(m_SmileyIcon);
- m_SmileyIcon = nullptr;
- }
-}
-
-void SmileyType::AddObject(ISmileyBase *pObject)
-{
- if (m_arSmileys.getCount() == 0) {
- if (m_xepimg == nullptr)
- m_xepimg = AddCacheImage(m_filepath, m_index);
- CallFunctionAsync(sttStartTimer, this);
- }
-
- m_arSmileys.insert(pObject);
-}
-
-void SmileyType::RemoveObject(ISmileyBase *pObject)
-{
- int idx = m_arSmileys.getIndex(pObject);
- if (idx == -1)
- return;
-
- m_arSmileys.remove(idx);
- if (m_arSmileys.getCount() == 0)
- CallFunctionAsync(sttStopTimer, this);
-}
-
-void SmileyType::SetFrameDelay()
-{
- int iFrameDelay = (m_xepimg == nullptr) ? 0 : m_xepimg->GetFrameDelay();
- if (iFrameDelay <= 0)
- KillTimer(hwndHidden, (DWORD_PTR)this);
- else
- SetTimer(hwndHidden, (DWORD_PTR)this, iFrameDelay*10, timerProc);
-}
-
-void SmileyType::MoveToNextFrame()
-{
- m_index = m_xepimg->SelectNextFrame(m_index);
-
- for (auto &it : m_arSmileys)
- it->Draw();
-
- SetFrameDelay(); // reset timer
-}
-
-HICON SmileyType::GetIcon(void)
-{
- if (m_SmileyIcon == nullptr) {
- ImageBase *img = CreateCachedImage();
- if (!img)
- return nullptr;
-
- img->SelectFrame(m_index);
- m_SmileyIcon = img->GetIcon();
- img->Release();
- }
- return m_SmileyIcon;
-}
-
-HICON SmileyType::GetIconDup(void)
-{
- ImageBase *img = CreateCachedImage();
- img->SelectFrame(m_index);
- HICON hIcon = img->GetIcon();
- img->Release();
- return hIcon;
-}
-
-bool SmileyType::LoadFromImage(IStream *pStream)
-{
- if (m_xepimg)
- m_xepimg->Release();
-
- CMStringW name;
- m_xepimg = new ImageType(0, name, pStream);
- return true;
-}
-
-bool SmileyType::LoadFromResource(const CMStringW &file, const int index)
-{
- m_index = index;
- m_filepath = file;
- return true;
-}
-
-void SmileyType::GetSize(SIZE &size)
-{
- if (m_size.cy == 0) {
- ImageBase *img = CreateCachedImage();
- if (img) {
- img->GetSize(m_size);
- img->Release();
- }
- }
- size = m_size;
-}
-
-ImageBase* SmileyType::CreateCachedImage(void)
-{
- if (m_xepimg) {
- m_xepimg->AddRef();
- return m_xepimg;
- }
- return AddCacheImage(m_filepath, m_index);
-}
-
-void SmileyType::SetImList(HIMAGELIST hImLst, long i)
-{
- if (m_xepimg) m_xepimg->Release();
- m_xepimg = new ImageListItemType(0, hImLst, i);
-}
-
-HBITMAP SmileyType::GetBitmap(COLORREF bkgClr, int sizeX, int sizeY)
-{
- ImageBase *img = CreateCachedImage();
- if (!img) return nullptr;
- img->SelectFrame(m_index);
- HBITMAP hBmp = img->GetBitmap(bkgClr, sizeX, sizeY);
- img->Release();
-
- return hBmp;
-}
-
-//
-// SmileyPackType
-//
-
-SmileyPackType::SmileyPackType()
-{
- m_hSmList = nullptr;
- errorFound = false;
-}
-
-SmileyType* SmileyPackType::GetSmiley(unsigned index)
-{
- return (index < (unsigned)m_SmileyList.getCount()) ? &m_SmileyList[index] : nullptr;
-}
-
-static DWORD_PTR ConvertServiceParam(MCONTACT hContact, const wchar_t *param)
-{
- if (param == nullptr)
- return 0;
- if (mir_wstrcmpi(L"hContact", param) == 0)
- return hContact;
- if (iswdigit(*param))
- return _wtoi(param);
-
- return (DWORD_PTR)param;
-}
-
-void SmileyType::CallSmileyService(MCONTACT hContact)
-{
- MRegexp16 srvsplit(L"(.*)\\|(.*)\\|(.*)");
- srvsplit.match(m_TriggerText);
-
- CMStringW name = srvsplit.getGroup(1);
- CMStringW par1 = srvsplit.getGroup(2);
- CMStringW par2 = srvsplit.getGroup(3);
-
- const char *proto = "";
- if (name[0] == '/') {
- proto = (const char*)GetContactProto(hContact);
- if (proto == nullptr)
- return;
- }
-
- char str[MAXMODULELABELLENGTH];
- mir_snprintf(str, "%s%s", proto, _T2A(name.c_str()));
- CallService(str,
- ConvertServiceParam(hContact, par1.c_str()),
- ConvertServiceParam(hContact, par2.c_str()));
-}
-
-SmileyPackType::~SmileyPackType()
-{
- if (m_hSmList != nullptr) ImageList_Destroy(m_hSmList);
-}
-
-static const wchar_t urlRegEx[] = L"(?:ftp|https|http|file|aim|webcal|irc|msnim|xmpp|gopher|mailto|news|nntp|telnet|wais|prospero)://?[\\w.?%:/$+;]*";
-static const wchar_t pathRegEx[] = L"[\\s\"][a-zA-Z]:[\\\\/][\\w.\\-\\\\/]*";
-static const wchar_t timeRegEx[] = L"\\d{1,2}:\\d{2}:\\d{2}|\\d{1,2}:\\d{2}";
-
-void SmileyPackType::AddTriggersToSmileyLookup(void)
-{
- CMStringW emptystr;
- m_SmileyLookup.insert(new SmileyLookup(urlRegEx, true, -1, emptystr));
- m_SmileyLookup.insert(new SmileyLookup(pathRegEx, true, -1, emptystr));
- m_SmileyLookup.insert(new SmileyLookup(timeRegEx, true, -1, emptystr));
-
- for (int dist = 0; dist < m_SmileyList.getCount(); dist++) {
- auto &p = m_SmileyList[dist];
- if (p.IsRegEx()) {
- SmileyLookup *dats = new SmileyLookup(p.GetTriggerText(), true, dist, GetFilename());
- if (dats->IsValid())
- m_SmileyLookup.insert(dats);
- else
- errorFound = true;
- if (p.m_InsertText.IsEmpty())
- p.m_InsertText = p.m_ToolText;
- }
- else if (!p.IsService()) {
- bool first = true;
- const CMStringW &text = p.GetTriggerText();
- int iStart = 0;
- while (true) {
- CMStringW wszWord = text.Tokenize(L" \t", iStart);
- if (iStart == -1)
- break;
-
- ReplaceAllSpecials(wszWord, wszWord);
- SmileyLookup *dats = new SmileyLookup(wszWord, false, dist, GetFilename());
- if (dats->IsValid()) {
- m_SmileyLookup.insert(dats);
- if (first) {
- p.m_InsertText = wszWord;
- first = false;
- }
- }
- else delete dats;
- }
- }
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static MRegexp16 isCode(L"\\&\\#(\\d*)\\;");
-
-static void replaceCodes(CMStringW &str)
-{
- if (isCode.match(str) < 0)
- return;
-
- str.Delete(isCode.getPos(), isCode.getLength());
-
- uint32_t iCode = _wtoi(isCode.getGroup(1));
- wchar_t tmp[3] = { 0, 0, 0 };
- if (iCode < 0x10000)
- tmp[0] = LOWORD(iCode), tmp[1] = HIWORD(iCode);
- else {
- iCode -= 0x10000;
- tmp[0] = 0xD800 + (iCode >> 10);
- tmp[1] = 0xDC00 + (iCode & 0x3FF);
- }
- str.Insert(isCode.getPos(), tmp);
-}
-
-void SmileyPackType::ReplaceAllSpecials(const CMStringW &Input, CMStringW &Output)
-{
- Output = Input;
- Output.Replace(L"%%_%%", L" ");
- Output.Replace(L"%%__%%", L" ");
- Output.Replace(L"%%''%%", L"\"");
- replaceCodes(Output);
-}
-
-void SmileyPackType::Clear(void)
-{
- m_SmileyList.destroy();
- m_SmileyLookup.destroy();
- if (m_hSmList != nullptr) { ImageList_Destroy(m_hSmList); m_hSmList = nullptr; }
- m_Filename.Empty();
- m_Name.Empty();
- m_Date.Empty();
- m_Version.Empty();
- m_Author.Empty();
- m_VisibleCount = 0;
- m_ButtonSmiley.Empty();
- errorFound = false;
-}
-
-bool SmileyPackType::LoadSmileyFile(const CMStringW &filename, const CMStringW &packname, bool onlyInfo, bool noerr)
-{
- Clear();
-
- if (filename.IsEmpty()) {
- m_Name = L"Nothing loaded";
- return false;
- }
-
- CMStringW modpath;
- pathToAbsolute(filename, modpath);
-
- // Load file
- int fh = _wopen(modpath.c_str(), _O_BINARY | _O_RDONLY);
- if (fh == -1) {
- if (!noerr) {
- static const wchar_t errmsg[] = LPGENW("Smiley pack %s for category \"%s\" not found.\nSelect correct smiley pack in the Options -> Customize -> Smileys.");
- wchar_t msgtxt[1024];
- mir_snwprintf(msgtxt, TranslateW(errmsg), modpath.c_str(), packname.c_str());
- ReportError(msgtxt);
- }
-
- m_Name = L"Nothing loaded";
- return false;
- }
-
- m_Filename = filename;
-
- // Find file size
- const long flen = _filelength(fh);
-
- // Allocate file buffer
- char *buf = new char[flen + sizeof(wchar_t)];
-
- // Read file in
- int len = _read(fh, buf, flen);
- *(wchar_t*)(buf + len) = 0;
-
- // Close file
- _close(fh);
-
- CMStringW tbuf;
-
- if (len > 2 && *(wchar_t*)buf == 0xfeff)
- tbuf = ((wchar_t*)buf + 1);
- else if (len > 3 && buf[0] == '\xef' && buf[1] == '\xbb' && buf[2] == '\xbf')
- tbuf = _A2T(buf + 3, CP_UTF8);
- else
- tbuf = _A2T(buf);
-
- delete[] buf;
-
- CMStringW pathstr, packstr;
- {
- MRegexp16 pathsplit(L"(.*\\\\)(.*)\\.|$");
- pathsplit.match(modpath);
-
- pathstr = pathsplit.getGroup(1);
- packstr = pathsplit.getGroup(2);
- }
-
- if (!onlyInfo)
- selec.x = selec.y = win.x = win.y = 0;
-
- int iStart = 0;
- MRegexp16 otherf(L"^\\s*(Name|Author|Date|Version|ButtonSmiley)\\s*=\\s*\"(.*)\"");
- MRegexp16 size(L"^\\s*(Selection|Window)Size\\s*=\\s*(\\d+)\\s*,\\s*(\\d+)");
- MRegexp16 smiley(
- L"^\\s*Smiley(\\*)?\\s*=" // Is Hidden
- L"(?:\\s*\"(.*)\")" // Smiley file name
- L"(?:[\\s,]+(\\-?\\d+))" // Icon resource id
- L"(?:[\\s,]+(R|S)?\"(.*?)\")" // Trigger text
- L"(?:[\\s,]+\"(.*?)\")?" // Tooltip or insert text
- L"(?:[\\s,]+\"(.*?)\")?"); // Tooltip text
-
- SmileyVectorType hiddenSmileys;
- unsigned smnum = 0;
-
- while (true) {
- CMStringW line = tbuf.Tokenize(L"\r\n", iStart);
- if (iStart == -1)
- break;
-
- if (line.IsEmpty() || line[0] == ';')
- continue;
-
- if (otherf.match(line) >= 0) {
- CMStringW key(otherf.getGroup(1)), value(otherf.getGroup(2));
- if (key == L"Name")
- m_Name = value;
- else if (key == L"Author")
- m_Author = value;
- else if (key == L"Date")
- m_Date = value;
- else if (key == L"Version")
- m_Version = value;
- else if (key == L"ButtonSmiley")
- m_ButtonSmiley = value;
- continue;
- }
-
- if (onlyInfo)
- continue;
-
- if (size.match(line) >= 0) {
- POINT tpt;
- tpt.x = _wtol(size.getGroup(2));
- tpt.y = _wtol(size.getGroup(3));
-
- if (size.getGroup(1) == L"Selection")
- selec = tpt;
- else if (size.getGroup(1) == L"Window")
- win = tpt;
- continue;
- }
-
- if (smiley.match(line)) {
- CMStringW resname = smiley.getGroup(2);
- if (resname.Find(L"http://") != -1) {
- if (GetSmileyFile(resname, packstr))
- continue;
- }
- else if (!resname.IsEmpty())
- resname.Insert(0, pathstr);
-
- SmileyType *dat = new SmileyType;
-
- const int iconIndex = _wtol(smiley.getGroup(3));
-
- dat->SetHidden(!smiley.getGroup(1).IsEmpty());
-
- CMStringW wszGrp4(smiley.getGroup(4));
- if (!wszGrp4.IsEmpty()) {
- dat->SetRegEx(wszGrp4 == L"R");
- dat->SetService(wszGrp4 == L"S");
- }
-
- dat->m_TriggerText = smiley.getGroup(5);
-
- CMStringW wszGrp6(smiley.getGroup(6)), wszGrp7(smiley.getGroup(7));
- if (dat->IsRegEx()) {
- if (!wszGrp6.IsEmpty())
- ReplaceAllSpecials(wszGrp6, dat->m_InsertText);
-
- if (!wszGrp7.IsEmpty())
- ReplaceAllSpecials(wszGrp7, dat->m_ToolText);
- else
- dat->m_ToolText = dat->m_InsertText;
- }
- else {
- if (!wszGrp6.IsEmpty())
- ReplaceAllSpecials(wszGrp6, dat->m_ToolText);
- else
- ReplaceAllSpecials(dat->m_TriggerText, dat->m_ToolText);
- }
-
- if (resname.IsEmpty()) {
- dat->SetHidden(true);
- dat->SetText(true);
- noerr = true;
- }
- else noerr = dat->LoadFromResource(resname, iconIndex);
-
- if (dat->IsHidden())
- hiddenSmileys.insert(dat);
- else
- m_SmileyList.insert(dat);
-
- if (!noerr) {
- static const wchar_t errmsg[] = LPGENW("Smiley #%u in file %s for smiley pack %s not found.");
- wchar_t msgtxt[1024];
- mir_snwprintf(msgtxt, TranslateW(errmsg), smnum, resname.c_str(), modpath.c_str());
- Netlib_LogW(hNetlibUser, msgtxt);
- errorFound = true;
- }
- smnum++;
- }
- }
-
- m_VisibleCount = m_SmileyList.getCount();
- m_SmileyList.splice(hiddenSmileys);
- AddTriggersToSmileyLookup();
-
- if (errorFound)
- ReportError(TranslateT("There were problems loading smiley pack (it should be corrected).\nSee network log for details."));
-
- return true;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// SmileyPackListType
-
-bool SmileyPackListType::AddSmileyPack(CMStringW &filename, CMStringW &packname)
-{
- bool res = true;
- if (GetSmileyPack(filename) == nullptr) { //not exist yet, so add
- SmileyPackType *smileyPack = new SmileyPackType;
-
- res = smileyPack->LoadSmileyFile(filename, packname, FALSE);
- if (res)
- m_SmileyPacks.insert(smileyPack);
- else
- delete smileyPack;
- }
- return res;
-}
-
-SmileyPackType* SmileyPackListType::GetSmileyPack(CMStringW &filename)
-{
- CMStringW modpath;
- pathToAbsolute(filename, modpath);
-
- for (auto &it : m_SmileyPacks) {
- CMStringW modpath1;
- pathToAbsolute(it->GetFilename(), modpath1);
- if (mir_wstrcmpi(modpath.c_str(), modpath1.c_str()) == 0)
- return it;
- }
- return nullptr;
-}
-
-void SmileyPackListType::ClearAndFreeAll()
-{
- m_SmileyPacks.destroy();
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// SmileyCategoryType
-
-SmileyCategoryType::SmileyCategoryType(SmileyPackListType *pSPS, const CMStringW &name,
- const CMStringW &displayName, const CMStringW &defaultFilename, SmcType typ)
-{
- m_pSmileyPackStore = pSPS;
- type = typ;
- m_Name = name;
- m_DisplayName = displayName;
- visible = true;
-
- opt.ReadPackFileName(m_Filename, m_Name, defaultFilename);
-}
-
-
-void SmileyCategoryType::Load(void)
-{
- bool bVisibleCat = opt.UsePhysProto ? !IsAcc() : !IsPhysProto();
- bool bVisible = opt.UseOneForAll ? !IsProto() : bVisibleCat;
- if (bVisible && !m_Filename.IsEmpty()) {
- bool loaded = m_pSmileyPackStore->AddSmileyPack(m_Filename, m_DisplayName);
- if (!loaded) {
- ClearFilename();
- SaveSettings();
- }
- }
-}
-
-SmileyPackType* SmileyCategoryType::GetSmileyPack(void)
-{
- return m_pSmileyPackStore->GetSmileyPack(m_Filename);
-}
-
-void SmileyCategoryType::SaveSettings(void)
-{
- opt.WritePackFileName(m_Filename, m_Name);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// SmileyCategoryListType
-
-void SmileyCategoryListType::ClearAndLoadAll(void)
-{
- m_pSmileyPackStore->ClearAndFreeAll();
-
- for (auto &it : m_SmileyCategories)
- it->Load();
-}
-
-SmileyCategoryType* SmileyCategoryListType::GetSmileyCategory(const CMStringW &name)
-{
- for (auto &it : m_SmileyCategories)
- if (name.CompareNoCase(it->GetName()) == 0)
- return it;
-
- return nullptr;
-}
-
-SmileyCategoryType* SmileyCategoryListType::GetSmileyCategory(unsigned index)
-{
- return index < (unsigned)m_SmileyCategories.getCount() ? &m_SmileyCategories[index] : nullptr;
-}
-
-SmileyPackType* SmileyCategoryListType::GetSmileyPack(CMStringW &categoryname)
-{
- SmileyCategoryType *smc = GetSmileyCategory(categoryname);
- return smc != nullptr ? smc->GetSmileyPack() : nullptr;
-}
-
-void SmileyCategoryListType::SaveSettings(void)
-{
- CMStringW catstr;
- for (auto &it : m_SmileyCategories) {
- it->SaveSettings();
- if (it->IsCustom()) {
- if (!catstr.IsEmpty())
- catstr += '#';
- catstr += it->GetName();
- }
- }
- opt.WriteCustomCategories(catstr);
-}
-
-void SmileyCategoryListType::AddAndLoad(const CMStringW &name, const CMStringW &displayName)
-{
- if (GetSmileyCategory(name) != nullptr)
- return;
-
- AddCategory(name, displayName, smcExt);
- // Load only if other smileys have been loaded already
- if (m_SmileyCategories.getCount() > 1)
- m_SmileyCategories[m_SmileyCategories.getCount() - 1].Load();
-}
-
-void SmileyCategoryListType::AddCategory(const CMStringW &name, const CMStringW &displayName, SmcType typ, const CMStringW &defaultFilename)
-{
- if (GetSmileyCategory(name) == nullptr)
- m_SmileyCategories.insert(new SmileyCategoryType(m_pSmileyPackStore, name, displayName, defaultFilename, typ));
-}
-
-bool SmileyCategoryListType::DeleteCustomCategory(int index)
-{
- if (index < m_SmileyCategories.getCount()) {
- if (m_SmileyCategories[index].IsCustom()) {
- m_SmileyCategories.remove(index);
- return true;
- }
- }
- return false;
-}
-
-void SmileyCategoryListType::AddAccountAsCategory(PROTOACCOUNT *acc, const CMStringW &defaultFile)
-{
- if (acc->IsEnabled() && acc->szProtoName && IsSmileyProto(acc->szModuleName)) {
- CMStringW displayName(acc->tszAccountName ? acc->tszAccountName : _A2T(acc->szModuleName));
- CMStringW PhysProtoName, paths;
- DBVARIANT dbv;
-
- if (db_get_ws(NULL, acc->szModuleName, "AM_BaseProto", &dbv) == 0) {
- PhysProtoName = L"AllProto";
- PhysProtoName += dbv.ptszVal;
- db_free(&dbv);
- }
-
- if (!PhysProtoName.IsEmpty())
- paths = g_SmileyCategories.GetSmileyCategory(PhysProtoName) ? g_SmileyCategories.GetSmileyCategory(PhysProtoName)->GetFilename() : L"";
-
- if (paths.IsEmpty()) {
- const char *packnam = acc->szProtoName;
- if (mir_strcmp(packnam, "JABBER") == 0)
- packnam = "JGMail";
- else if (strstr(packnam, "SIP") != nullptr)
- packnam = "MSN";
-
- char path[MAX_PATH];
- mir_snprintf(path, "Smileys\\nova\\%s.msl", packnam);
-
- paths = _A2T(path);
- CMStringW patha;
- pathToAbsolute(paths, patha);
-
- if (_waccess(patha.c_str(), 0) != 0)
- paths = defaultFile;
- }
-
- CMStringW tname(_A2T(acc->szModuleName));
- AddCategory(tname, displayName, acc->bIsVirtual ? smcVirtualProto : smcProto, paths);
- }
-}
-
-void SmileyCategoryListType::AddProtoAsCategory(char *acc, const CMStringW &defaultFile)
-{
- if (acc == nullptr)
- return;
-
- const char *packnam = acc;
- if (mir_strcmp(packnam, "JABBER") == 0)
- packnam = "JGMail";
- else if (strstr(packnam, "SIP") != nullptr)
- packnam = "MSN";
-
- char path[MAX_PATH];
- mir_snprintf(path, "Smileys\\nova\\%s.msl", packnam);
-
- CMStringW paths = _A2T(path), patha;
- pathToAbsolute(paths, patha);
-
- if (_waccess(patha.c_str(), 0) != 0)
- paths = defaultFile;
- CMStringW dName(acc), displayName;
- displayName.AppendFormat(TranslateT("%s global smiley pack"), dName.GetBuffer());
- CMStringW tname("AllProto");
- tname += _A2T(acc);
- AddCategory(tname, displayName, smcPhysProto, paths);
-}
-
-void SmileyCategoryListType::DeleteAccountAsCategory(PROTOACCOUNT *acc)
-{
- CMStringW tname(_A2T(acc->szModuleName));
-
- for (auto &hContact : Contacts()) {
- char *proto = GetContactProto(hContact);
- if (proto == nullptr)
- continue;
-
- DBVARIANT dbv;
- if (!db_get_ws(hContact, proto, "Transport", &dbv)) {
- bool found = (tname.CompareNoCase(dbv.ptszVal) == 0);
- db_free(&dbv);
- if (found)
- return;
- }
- }
-
- for (auto &it : m_SmileyCategories) {
- if (tname.CompareNoCase(it->GetName()) == 0) {
- m_SmileyCategories.removeItem(&it);
- break;
- }
- }
-}
-
-void SmileyCategoryListType::AddContactTransportAsCategory(MCONTACT hContact, const CMStringW &defaultFile)
-{
- char *proto = GetContactProto(hContact);
- if (proto == nullptr)
- return;
-
- DBVARIANT dbv;
- if (!db_get_ws(hContact, proto, "Transport", &dbv)) {
- if (dbv.ptszVal[0] == '\0') {
- db_free(&dbv);
- return;
- }
- char *trsp = mir_strdup(_T2A(dbv.ptszVal));
- _strlwr(trsp);
-
- const char *packname = nullptr;
- if (strstr(trsp, "msn") != nullptr)
- packname = "msn";
- else if (strstr(trsp, "icq") != nullptr)
- packname = "icq";
- else if (strstr(trsp, "yahoo") != nullptr)
- packname = "yahoo";
- else if (strstr(trsp, "aim") != nullptr)
- packname = "aim";
- else if (strstr(trsp, "lcs") != nullptr)
- packname = "msn";
-
- mir_free(trsp);
-
- CMStringW displayName = dbv.ptszVal;
- if (packname != nullptr) {
- char path[MAX_PATH];
- mir_snprintf(path, "Smileys\\nova\\%s.msl", packname);
-
- CMStringW paths = _A2T(path), patha;
- pathToAbsolute(paths, patha);
-
- if (_waccess(patha.c_str(), 0) != 0)
- paths = defaultFile;
-
- AddCategory(displayName, displayName, smcTransportProto, paths);
- }
- else AddCategory(displayName, displayName, smcTransportProto, defaultFile);
-
- db_free(&dbv);
- }
-}
-
-void SmileyCategoryListType::AddAllProtocolsAsCategory(void)
-{
- CMStringW displayName = TranslateT("Standard");
- CMStringW tname = L"Standard";
- AddCategory(tname, displayName, smcStd);
-
- const CMStringW &defaultFile = GetSmileyCategory(tname)->GetFilename();
-
- PROTOCOLDESCRIPTOR **proto;
- int protoCount = 0;
- Proto_EnumProtocols(&protoCount, &proto);
-
- for (int i = 0; i < protoCount; i++) {
- PROTOCOLDESCRIPTOR *pd = proto[i];
- if (pd->type == PROTOTYPE_PROTOWITHACCS)
- AddProtoAsCategory(pd->szName, defaultFile);
- }
-
- for (auto &pa : Accounts())
- AddAccountAsCategory(pa, defaultFile);
-
- for (auto &hContact : Contacts())
- AddContactTransportAsCategory(hContact, defaultFile);
-
- CMStringW cats;
- opt.ReadCustomCategories(cats);
-
- int cppv = 0;
- for (;;) {
- int cp = cats.Find('#', cppv);
- if (cp == -1)
- break;
-
- displayName = cats.Mid(cppv, cp - cppv);
- AddCategory(displayName, displayName, smcCustom, defaultFile);
- cppv = cp + 1;
- }
-
- if (cppv != cats.GetLength()) {
- displayName = cats.Mid(cppv);
- AddCategory(displayName, displayName, smcCustom, defaultFile);
- }
-}
-
-static const CMStringW testString(L"Test String");
-
-SmileyLookup::SmileyLookup(const CMStringW &str, const bool regexs, const int ind, const CMStringW &smpt)
-{
- m_ind = ind;
- if (regexs) {
- m_pattern.compile(str);
- m_valid = m_pattern.isValid();
- if (!m_valid) {
- wchar_t msgtxt[1024];
- mir_snwprintf(msgtxt, TranslateT("Regular expression \"%s\" in smiley pack \"%s\" malformed."), str.c_str(), smpt.c_str());
- Netlib_LogW(hNetlibUser, msgtxt);
- }
- }
- else {
- m_text = str;
- replaceCodes(m_text);
- m_valid = !str.IsEmpty();
- }
-}
-
-SmileyLookup::~SmileyLookup()
-{
-}
-
-void SmileyLookup::Find(const CMStringW &str, SmileyLocVecType &smlcur, bool firstOnly)
-{
- if (!m_valid) return;
-
- if (m_text.IsEmpty()) {
- while (m_pattern.nextMatch(str) >= 0) {
- CMStringW wszMatch(m_pattern.getMatch());
- smlcur.insert(new SmileyLocType(m_pattern.getPos(), wszMatch.GetLength()));
- if (firstOnly && m_ind != -1)
- return;
- }
- }
- else {
- const wchar_t *pos = str.c_str();
- while ((pos = wcsstr(pos, m_text.c_str())) != nullptr) {
- smlcur.insert(new SmileyLocType(pos - str.c_str(), m_text.GetLength()));
- pos += m_text.GetLength();
- if (firstOnly && m_ind != -1)
- return;
- }
- }
-}
+/*
+Miranda NG SmileyAdd Plugin
+Copyright (C) 2012-18 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2005-11 Boris Krasnovskiy All Rights Reserved
+Copyright (C) 2003-04 Rein-Peter de Boer
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stdafx.h"
+
+SmileyPackListType g_SmileyPacks;
+SmileyCategoryListType g_SmileyCategories;
+
+static HWND hwndHidden = nullptr;
+
+static void CALLBACK timerProc(HWND, UINT, UINT_PTR param, DWORD)
+{
+ SmileyType *pType = (SmileyType*)param;
+ pType->MoveToNextFrame();
+}
+
+// these two functions must be called from the main thread
+static void CALLBACK sttStartTimer(PVOID obj)
+{
+ if (hwndHidden == nullptr)
+ hwndHidden = CreateWindowEx(0, L"STATIC", nullptr, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr, nullptr);
+
+ SmileyType *pType = (SmileyType*)obj;
+ pType->SetFrameDelay();
+}
+
+static void CALLBACK sttStopTimer(PVOID obj)
+{
+ KillTimer(hwndHidden, (DWORD_PTR)obj);
+}
+
+//
+// SmileyType
+//
+
+SmileyType::SmileyType(void) :
+ m_arSmileys(10, PtrKeySortT)
+{
+ m_SmileyIcon = nullptr;
+ m_xepimg = nullptr;
+ m_flags = 0;
+ m_index = 0;
+ m_size.cx = 0;
+ m_size.cy = 0;
+}
+
+SmileyType::~SmileyType()
+{
+ if (m_xepimg) {
+ m_xepimg->Release();
+ m_xepimg = nullptr;
+ }
+
+ if (m_SmileyIcon != nullptr) {
+ DestroyIcon(m_SmileyIcon);
+ m_SmileyIcon = nullptr;
+ }
+}
+
+void SmileyType::AddObject(ISmileyBase *pObject)
+{
+ if (m_arSmileys.getCount() == 0) {
+ if (m_xepimg == nullptr)
+ m_xepimg = AddCacheImage(m_filepath, m_index);
+ CallFunctionAsync(sttStartTimer, this);
+ }
+
+ m_arSmileys.insert(pObject);
+}
+
+void SmileyType::RemoveObject(ISmileyBase *pObject)
+{
+ int idx = m_arSmileys.getIndex(pObject);
+ if (idx == -1)
+ return;
+
+ m_arSmileys.remove(idx);
+ if (m_arSmileys.getCount() == 0)
+ CallFunctionAsync(sttStopTimer, this);
+}
+
+void SmileyType::SetFrameDelay()
+{
+ int iFrameDelay = (m_xepimg == nullptr) ? 0 : m_xepimg->GetFrameDelay();
+ if (iFrameDelay <= 0)
+ KillTimer(hwndHidden, (DWORD_PTR)this);
+ else
+ SetTimer(hwndHidden, (DWORD_PTR)this, iFrameDelay*10, timerProc);
+}
+
+void SmileyType::MoveToNextFrame()
+{
+ m_index = m_xepimg->SelectNextFrame(m_index);
+
+ for (auto &it : m_arSmileys)
+ it->Draw();
+
+ SetFrameDelay(); // reset timer
+}
+
+HICON SmileyType::GetIcon(void)
+{
+ if (m_SmileyIcon == nullptr) {
+ ImageBase *img = CreateCachedImage();
+ if (!img)
+ return nullptr;
+
+ img->SelectFrame(m_index);
+ m_SmileyIcon = img->GetIcon();
+ img->Release();
+ }
+ return m_SmileyIcon;
+}
+
+HICON SmileyType::GetIconDup(void)
+{
+ ImageBase *img = CreateCachedImage();
+ img->SelectFrame(m_index);
+ HICON hIcon = img->GetIcon();
+ img->Release();
+ return hIcon;
+}
+
+bool SmileyType::LoadFromImage(IStream *pStream)
+{
+ if (m_xepimg)
+ m_xepimg->Release();
+
+ CMStringW name;
+ m_xepimg = new ImageType(0, name, pStream);
+ return true;
+}
+
+bool SmileyType::LoadFromResource(const CMStringW &file, const int index)
+{
+ m_index = index;
+ m_filepath = file;
+ return true;
+}
+
+void SmileyType::GetSize(SIZE &size)
+{
+ if (m_size.cy == 0) {
+ ImageBase *img = CreateCachedImage();
+ if (img) {
+ img->GetSize(m_size);
+ img->Release();
+ }
+ }
+ size = m_size;
+}
+
+ImageBase* SmileyType::CreateCachedImage(void)
+{
+ if (m_xepimg) {
+ m_xepimg->AddRef();
+ return m_xepimg;
+ }
+ return AddCacheImage(m_filepath, m_index);
+}
+
+void SmileyType::SetImList(HIMAGELIST hImLst, long i)
+{
+ if (m_xepimg) m_xepimg->Release();
+ m_xepimg = new ImageListItemType(0, hImLst, i);
+}
+
+HBITMAP SmileyType::GetBitmap(COLORREF bkgClr, int sizeX, int sizeY)
+{
+ ImageBase *img = CreateCachedImage();
+ if (!img) return nullptr;
+ img->SelectFrame(m_index);
+ HBITMAP hBmp = img->GetBitmap(bkgClr, sizeX, sizeY);
+ img->Release();
+
+ return hBmp;
+}
+
+//
+// SmileyPackType
+//
+
+SmileyPackType::SmileyPackType()
+{
+ m_hSmList = nullptr;
+ errorFound = false;
+}
+
+SmileyType* SmileyPackType::GetSmiley(unsigned index)
+{
+ return (index < (unsigned)m_SmileyList.getCount()) ? &m_SmileyList[index] : nullptr;
+}
+
+static DWORD_PTR ConvertServiceParam(MCONTACT hContact, const wchar_t *param)
+{
+ if (param == nullptr)
+ return 0;
+ if (mir_wstrcmpi(L"hContact", param) == 0)
+ return hContact;
+ if (iswdigit(*param))
+ return _wtoi(param);
+
+ return (DWORD_PTR)param;
+}
+
+void SmileyType::CallSmileyService(MCONTACT hContact)
+{
+ MRegexp16 srvsplit(L"(.*)\\|(.*)\\|(.*)");
+ srvsplit.match(m_TriggerText);
+
+ CMStringW name = srvsplit.getGroup(1);
+ CMStringW par1 = srvsplit.getGroup(2);
+ CMStringW par2 = srvsplit.getGroup(3);
+
+ const char *proto = "";
+ if (name[0] == '/') {
+ proto = (const char*)GetContactProto(hContact);
+ if (proto == nullptr)
+ return;
+ }
+
+ char str[MAXMODULELABELLENGTH];
+ mir_snprintf(str, "%s%s", proto, _T2A(name.c_str()));
+ CallService(str,
+ ConvertServiceParam(hContact, par1.c_str()),
+ ConvertServiceParam(hContact, par2.c_str()));
+}
+
+SmileyPackType::~SmileyPackType()
+{
+ if (m_hSmList != nullptr) ImageList_Destroy(m_hSmList);
+}
+
+static const wchar_t urlRegEx[] = L"(?:ftp|https|http|file|aim|webcal|irc|msnim|xmpp|gopher|mailto|news|nntp|telnet|wais|prospero)://?[\\w.?%:/$+;]*";
+static const wchar_t pathRegEx[] = L"[\\s\"][a-zA-Z]:[\\\\/][\\w.\\-\\\\/]*";
+static const wchar_t timeRegEx[] = L"\\d{1,2}:\\d{2}:\\d{2}|\\d{1,2}:\\d{2}";
+
+void SmileyPackType::AddTriggersToSmileyLookup(void)
+{
+ CMStringW emptystr;
+ m_SmileyLookup.insert(new SmileyLookup(urlRegEx, true, -1, emptystr));
+ m_SmileyLookup.insert(new SmileyLookup(pathRegEx, true, -1, emptystr));
+ m_SmileyLookup.insert(new SmileyLookup(timeRegEx, true, -1, emptystr));
+
+ for (int dist = 0; dist < m_SmileyList.getCount(); dist++) {
+ auto &p = m_SmileyList[dist];
+ if (p.IsRegEx()) {
+ SmileyLookup *dats = new SmileyLookup(p.GetTriggerText(), true, dist, GetFilename());
+ if (dats->IsValid())
+ m_SmileyLookup.insert(dats);
+ else
+ errorFound = true;
+ if (p.m_InsertText.IsEmpty())
+ p.m_InsertText = p.m_ToolText;
+ }
+ else if (!p.IsService()) {
+ bool first = true;
+ const CMStringW &text = p.GetTriggerText();
+ int iStart = 0;
+ while (true) {
+ CMStringW wszWord = text.Tokenize(L" \t", iStart);
+ if (iStart == -1)
+ break;
+
+ ReplaceAllSpecials(wszWord, wszWord);
+ SmileyLookup *dats = new SmileyLookup(wszWord, false, dist, GetFilename());
+ if (dats->IsValid()) {
+ m_SmileyLookup.insert(dats);
+ if (first) {
+ p.m_InsertText = wszWord;
+ first = false;
+ }
+ }
+ else delete dats;
+ }
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static MRegexp16 isCode(L"\\&\\#(\\d*)\\;");
+
+static void replaceCodes(CMStringW &str)
+{
+ if (isCode.match(str) < 0)
+ return;
+
+ str.Delete(isCode.getPos(), isCode.getLength());
+
+ uint32_t iCode = _wtoi(isCode.getGroup(1));
+ wchar_t tmp[3] = { 0, 0, 0 };
+ if (iCode < 0x10000)
+ tmp[0] = LOWORD(iCode), tmp[1] = HIWORD(iCode);
+ else {
+ iCode -= 0x10000;
+ tmp[0] = 0xD800 + (iCode >> 10);
+ tmp[1] = 0xDC00 + (iCode & 0x3FF);
+ }
+ str.Insert(isCode.getPos(), tmp);
+}
+
+void SmileyPackType::ReplaceAllSpecials(const CMStringW &Input, CMStringW &Output)
+{
+ Output = Input;
+ Output.Replace(L"%%_%%", L" ");
+ Output.Replace(L"%%__%%", L" ");
+ Output.Replace(L"%%''%%", L"\"");
+ replaceCodes(Output);
+}
+
+void SmileyPackType::Clear(void)
+{
+ m_SmileyList.destroy();
+ m_SmileyLookup.destroy();
+ if (m_hSmList != nullptr) { ImageList_Destroy(m_hSmList); m_hSmList = nullptr; }
+ m_Filename.Empty();
+ m_Name.Empty();
+ m_Date.Empty();
+ m_Version.Empty();
+ m_Author.Empty();
+ m_VisibleCount = 0;
+ m_ButtonSmiley.Empty();
+ errorFound = false;
+}
+
+bool SmileyPackType::LoadSmileyFile(const CMStringW &filename, const CMStringW &packname, bool onlyInfo, bool noerr)
+{
+ Clear();
+
+ if (filename.IsEmpty()) {
+ m_Name = L"Nothing loaded";
+ return false;
+ }
+
+ CMStringW modpath;
+ pathToAbsolute(filename, modpath);
+
+ // Load file
+ int fh = _wopen(modpath.c_str(), _O_BINARY | _O_RDONLY);
+ if (fh == -1) {
+ if (!noerr) {
+ static const wchar_t errmsg[] = LPGENW("Smiley pack %s for category \"%s\" not found.\nSelect correct smiley pack in the Options -> Customize -> Smileys.");
+ wchar_t msgtxt[1024];
+ mir_snwprintf(msgtxt, TranslateW(errmsg), modpath.c_str(), packname.c_str());
+ ReportError(msgtxt);
+ }
+
+ m_Name = L"Nothing loaded";
+ return false;
+ }
+
+ m_Filename = filename;
+
+ // Find file size
+ const long flen = _filelength(fh);
+
+ // Allocate file buffer
+ char *buf = new char[flen + sizeof(wchar_t)];
+
+ // Read file in
+ int len = _read(fh, buf, flen);
+ *(wchar_t*)(buf + len) = 0;
+
+ // Close file
+ _close(fh);
+
+ CMStringW tbuf;
+ if (len > 2 && *(wchar_t*)buf == 0xfeff)
+ tbuf = ((wchar_t*)buf + 1);
+ else if (len > 3 && buf[0] == '\xef' && buf[1] == '\xbb' && buf[2] == '\xbf')
+ tbuf = _A2T(buf + 3, CP_UTF8);
+ else
+ tbuf = _A2T(buf);
+
+ delete[] buf;
+
+ bool res;
+ if (filename.Find(L".xep") == -1)
+ res = LoadSmileyFileMSL(tbuf, onlyInfo, modpath);
+ else
+ res = LoadSmileyFileXEP(tbuf, onlyInfo);
+
+ if (errorFound)
+ ReportError(TranslateT("There were problems loading smiley pack (it should be corrected).\nSee network log for details."));
+
+ return res;
+}
+
+static IStream* DecodeBase64Data(const wchar_t *pString)
+{
+ size_t dataLen;
+ ptrA data((char*)mir_base64_decode(_T2A(pString), &dataLen));
+ if (data == nullptr)
+ return nullptr;
+
+ // Read image list
+ HGLOBAL hBuffer = GlobalAlloc(GMEM_MOVEABLE, dataLen);
+ if (!hBuffer)
+ return nullptr;
+
+ void *dst = GlobalLock(hBuffer);
+ memcpy(dst, data, dataLen);
+ GlobalUnlock(hBuffer);
+
+ IStream *pStream = nullptr;
+ CreateStreamOnHGlobal(hBuffer, TRUE, &pStream);
+ return pStream;
+}
+
+static CMStringW FilterQuotes(const wchar_t *pStr)
+{
+ CMStringW res(pStr);
+ int iStart = res.Find('\"', 0);
+ if (iStart != -1) {
+ int iEnd = res.Find('\"', ++iStart);
+ if (iEnd != -1)
+ res = res.Mid(iStart, iEnd - iStart);
+ }
+
+ return res;
+}
+
+bool SmileyPackType::LoadSmileyFileXEP(CMStringW &tbuf, bool onlyInfo)
+{
+ HXML node, xmlRoot = xmlParseString(tbuf, nullptr, nullptr);
+ if (!xmlRoot)
+ return false;
+
+ if (node = xmlGetChildByPath(xmlRoot, L"settings/DataBaseName", 0))
+ m_Name = xmlGetText(node);
+ if (node = xmlGetChildByPath(xmlRoot, L"settings/PackageAuthor", 0))
+ m_Author = xmlGetText(node);
+
+ if (!onlyInfo) {
+ const wchar_t *pStr = xmlGetClear(xmlGetChildByPath(xmlRoot, L"lists/images", 0), 0, 0, 0);
+ if (pStr) {
+ IStream *pStream = DecodeBase64Data(pStr);
+ if (pStream) {
+ if (m_hSmList != nullptr)
+ ImageList_Destroy(m_hSmList);
+ m_hSmList = ImageList_Read(pStream);
+ pStream->Release();
+ }
+ }
+
+ HXML nRec, dataRoot = xmlGetChildByPath(xmlRoot, L"dataroot", 0);
+ for (int i = 0; (nRec = xmlGetNthChild(dataRoot, L"record", i)) != 0; i++) {
+ pStr = xmlGetAttrValue(nRec, L"ImageIndex");
+ if (pStr == nullptr)
+ continue;
+
+ SmileyType *dat = new SmileyType;
+ dat->SetRegEx(true);
+ dat->SetImList(m_hSmList, _wtoi(pStr));
+ dat->m_ToolText = xmlGetText(nRec);
+
+ if (node = xmlGetChildByPath(nRec, L"Expression", 0))
+ dat->m_TriggerText = FilterQuotes(xmlGetText(node));
+ if (node = xmlGetChildByPath(nRec, L"PasteText", 0))
+ dat->m_InsertText = FilterQuotes(xmlGetText(node));
+
+ dat->SetHidden(dat->m_InsertText.IsEmpty());
+
+ if (node = xmlGetChildByPath(nRec, L"Image", 0)) {
+ IStream *pStream = DecodeBase64Data(xmlGetText(node));
+ if (pStream) {
+ dat->LoadFromImage(pStream);
+ pStream->Release();
+ }
+ }
+
+ m_SmileyList.insert(dat);
+ }
+ }
+
+ xmlDestroyNode(xmlRoot);
+
+ m_VisibleCount = m_SmileyList.getCount();
+ AddTriggersToSmileyLookup();
+
+ selec.x = selec.y = win.x = win.y = 0;
+ return true;
+}
+
+bool SmileyPackType::LoadSmileyFileMSL(CMStringW &tbuf, bool onlyInfo, CMStringW &modpath)
+{
+ CMStringW pathstr, packstr;
+ {
+ MRegexp16 pathsplit(L"(.*\\\\)(.*)\\.|$");
+ pathsplit.match(modpath);
+
+ pathstr = pathsplit.getGroup(1);
+ packstr = pathsplit.getGroup(2);
+ }
+
+ if (!onlyInfo)
+ selec.x = selec.y = win.x = win.y = 0;
+
+ int iStart = 0;
+ MRegexp16 otherf(L"^\\s*(Name|Author|Date|Version|ButtonSmiley)\\s*=\\s*\"(.*)\"");
+ MRegexp16 size(L"^\\s*(Selection|Window)Size\\s*=\\s*(\\d+)\\s*,\\s*(\\d+)");
+ MRegexp16 smiley(
+ L"^\\s*Smiley(\\*)?\\s*=" // Is Hidden
+ L"(?:\\s*\"(.*)\")" // Smiley file name
+ L"(?:[\\s,]+(\\-?\\d+))" // Icon resource id
+ L"(?:[\\s,]+(R|S)?\"(.*?)\")" // Trigger text
+ L"(?:[\\s,]+\"(.*?)\")?" // Tooltip or insert text
+ L"(?:[\\s,]+\"(.*?)\")?"); // Tooltip text
+
+ SmileyVectorType hiddenSmileys;
+ unsigned smnum = 0;
+
+ while (true) {
+ CMStringW line = tbuf.Tokenize(L"\r\n", iStart);
+ if (iStart == -1)
+ break;
+
+ if (line.IsEmpty() || line[0] == ';')
+ continue;
+
+ if (otherf.match(line) >= 0) {
+ CMStringW key(otherf.getGroup(1)), value(otherf.getGroup(2));
+ if (key == L"Name")
+ m_Name = value;
+ else if (key == L"Author")
+ m_Author = value;
+ else if (key == L"Date")
+ m_Date = value;
+ else if (key == L"Version")
+ m_Version = value;
+ else if (key == L"ButtonSmiley")
+ m_ButtonSmiley = value;
+ continue;
+ }
+
+ if (onlyInfo)
+ continue;
+
+ if (size.match(line) >= 0) {
+ POINT tpt;
+ tpt.x = _wtol(size.getGroup(2));
+ tpt.y = _wtol(size.getGroup(3));
+
+ if (size.getGroup(1) == L"Selection")
+ selec = tpt;
+ else if (size.getGroup(1) == L"Window")
+ win = tpt;
+ continue;
+ }
+
+ if (smiley.match(line)) {
+ CMStringW resname = smiley.getGroup(2);
+ if (resname.Find(L"http://") != -1) {
+ if (GetSmileyFile(resname, packstr))
+ continue;
+ }
+ else if (!resname.IsEmpty())
+ resname.Insert(0, pathstr);
+
+ SmileyType *dat = new SmileyType;
+
+ const int iconIndex = _wtol(smiley.getGroup(3));
+
+ dat->SetHidden(!smiley.getGroup(1).IsEmpty());
+
+ CMStringW wszGrp4(smiley.getGroup(4));
+ if (!wszGrp4.IsEmpty()) {
+ dat->SetRegEx(wszGrp4 == L"R");
+ dat->SetService(wszGrp4 == L"S");
+ }
+
+ dat->m_TriggerText = smiley.getGroup(5);
+
+ CMStringW wszGrp6(smiley.getGroup(6)), wszGrp7(smiley.getGroup(7));
+ if (dat->IsRegEx()) {
+ if (!wszGrp6.IsEmpty())
+ ReplaceAllSpecials(wszGrp6, dat->m_InsertText);
+
+ if (!wszGrp7.IsEmpty())
+ ReplaceAllSpecials(wszGrp7, dat->m_ToolText);
+ else
+ dat->m_ToolText = dat->m_InsertText;
+ }
+ else {
+ if (!wszGrp6.IsEmpty())
+ ReplaceAllSpecials(wszGrp6, dat->m_ToolText);
+ else
+ ReplaceAllSpecials(dat->m_TriggerText, dat->m_ToolText);
+ }
+
+ bool noerr;
+ if (resname.IsEmpty()) {
+ dat->SetHidden(true);
+ dat->SetText(true);
+ noerr = true;
+ }
+ else noerr = dat->LoadFromResource(resname, iconIndex);
+
+ if (dat->IsHidden())
+ hiddenSmileys.insert(dat);
+ else
+ m_SmileyList.insert(dat);
+
+ if (!noerr) {
+ static const wchar_t errmsg[] = LPGENW("Smiley #%u in file %s for smiley pack %s not found.");
+ wchar_t msgtxt[1024];
+ mir_snwprintf(msgtxt, TranslateW(errmsg), smnum, resname.c_str(), modpath.c_str());
+ Netlib_LogW(hNetlibUser, msgtxt);
+ errorFound = true;
+ }
+ smnum++;
+ }
+ }
+
+ m_VisibleCount = m_SmileyList.getCount();
+ m_SmileyList.splice(hiddenSmileys);
+ AddTriggersToSmileyLookup();
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// SmileyPackListType
+
+bool SmileyPackListType::AddSmileyPack(CMStringW &filename, CMStringW &packname)
+{
+ bool res = true;
+ if (GetSmileyPack(filename) == nullptr) { //not exist yet, so add
+ SmileyPackType *smileyPack = new SmileyPackType;
+
+ res = smileyPack->LoadSmileyFile(filename, packname, FALSE);
+ if (res)
+ m_SmileyPacks.insert(smileyPack);
+ else
+ delete smileyPack;
+ }
+ return res;
+}
+
+SmileyPackType* SmileyPackListType::GetSmileyPack(CMStringW &filename)
+{
+ CMStringW modpath;
+ pathToAbsolute(filename, modpath);
+
+ for (auto &it : m_SmileyPacks) {
+ CMStringW modpath1;
+ pathToAbsolute(it->GetFilename(), modpath1);
+ if (mir_wstrcmpi(modpath.c_str(), modpath1.c_str()) == 0)
+ return it;
+ }
+ return nullptr;
+}
+
+void SmileyPackListType::ClearAndFreeAll()
+{
+ m_SmileyPacks.destroy();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// SmileyCategoryType
+
+SmileyCategoryType::SmileyCategoryType(SmileyPackListType *pSPS, const CMStringW &name,
+ const CMStringW &displayName, const CMStringW &defaultFilename, SmcType typ)
+{
+ m_pSmileyPackStore = pSPS;
+ type = typ;
+ m_Name = name;
+ m_DisplayName = displayName;
+ visible = true;
+
+ opt.ReadPackFileName(m_Filename, m_Name, defaultFilename);
+}
+
+
+void SmileyCategoryType::Load(void)
+{
+ bool bVisibleCat = opt.UsePhysProto ? !IsAcc() : !IsPhysProto();
+ bool bVisible = opt.UseOneForAll ? !IsProto() : bVisibleCat;
+ if (bVisible && !m_Filename.IsEmpty()) {
+ bool loaded = m_pSmileyPackStore->AddSmileyPack(m_Filename, m_DisplayName);
+ if (!loaded) {
+ ClearFilename();
+ SaveSettings();
+ }
+ }
+}
+
+SmileyPackType* SmileyCategoryType::GetSmileyPack(void)
+{
+ return m_pSmileyPackStore->GetSmileyPack(m_Filename);
+}
+
+void SmileyCategoryType::SaveSettings(void)
+{
+ opt.WritePackFileName(m_Filename, m_Name);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// SmileyCategoryListType
+
+void SmileyCategoryListType::ClearAndLoadAll(void)
+{
+ m_pSmileyPackStore->ClearAndFreeAll();
+
+ for (auto &it : m_SmileyCategories)
+ it->Load();
+}
+
+SmileyCategoryType* SmileyCategoryListType::GetSmileyCategory(const CMStringW &name)
+{
+ for (auto &it : m_SmileyCategories)
+ if (name.CompareNoCase(it->GetName()) == 0)
+ return it;
+
+ return nullptr;
+}
+
+SmileyCategoryType* SmileyCategoryListType::GetSmileyCategory(unsigned index)
+{
+ return index < (unsigned)m_SmileyCategories.getCount() ? &m_SmileyCategories[index] : nullptr;
+}
+
+SmileyPackType* SmileyCategoryListType::GetSmileyPack(CMStringW &categoryname)
+{
+ SmileyCategoryType *smc = GetSmileyCategory(categoryname);
+ return smc != nullptr ? smc->GetSmileyPack() : nullptr;
+}
+
+void SmileyCategoryListType::SaveSettings(void)
+{
+ CMStringW catstr;
+ for (auto &it : m_SmileyCategories) {
+ it->SaveSettings();
+ if (it->IsCustom()) {
+ if (!catstr.IsEmpty())
+ catstr += '#';
+ catstr += it->GetName();
+ }
+ }
+ opt.WriteCustomCategories(catstr);
+}
+
+void SmileyCategoryListType::AddAndLoad(const CMStringW &name, const CMStringW &displayName)
+{
+ if (GetSmileyCategory(name) != nullptr)
+ return;
+
+ AddCategory(name, displayName, smcExt);
+ // Load only if other smileys have been loaded already
+ if (m_SmileyCategories.getCount() > 1)
+ m_SmileyCategories[m_SmileyCategories.getCount() - 1].Load();
+}
+
+void SmileyCategoryListType::AddCategory(const CMStringW &name, const CMStringW &displayName, SmcType typ, const CMStringW &defaultFilename)
+{
+ if (GetSmileyCategory(name) == nullptr)
+ m_SmileyCategories.insert(new SmileyCategoryType(m_pSmileyPackStore, name, displayName, defaultFilename, typ));
+}
+
+bool SmileyCategoryListType::DeleteCustomCategory(int index)
+{
+ if (index < m_SmileyCategories.getCount()) {
+ if (m_SmileyCategories[index].IsCustom()) {
+ m_SmileyCategories.remove(index);
+ return true;
+ }
+ }
+ return false;
+}
+
+void SmileyCategoryListType::AddAccountAsCategory(PROTOACCOUNT *acc, const CMStringW &defaultFile)
+{
+ if (acc->IsEnabled() && acc->szProtoName && IsSmileyProto(acc->szModuleName)) {
+ CMStringW displayName(acc->tszAccountName ? acc->tszAccountName : _A2T(acc->szModuleName));
+ CMStringW PhysProtoName, paths;
+ DBVARIANT dbv;
+
+ if (db_get_ws(NULL, acc->szModuleName, "AM_BaseProto", &dbv) == 0) {
+ PhysProtoName = L"AllProto";
+ PhysProtoName += dbv.ptszVal;
+ db_free(&dbv);
+ }
+
+ if (!PhysProtoName.IsEmpty())
+ paths = g_SmileyCategories.GetSmileyCategory(PhysProtoName) ? g_SmileyCategories.GetSmileyCategory(PhysProtoName)->GetFilename() : L"";
+
+ if (paths.IsEmpty()) {
+ const char *packnam = acc->szProtoName;
+ if (mir_strcmp(packnam, "JABBER") == 0)
+ packnam = "JGMail";
+ else if (strstr(packnam, "SIP") != nullptr)
+ packnam = "MSN";
+
+ char path[MAX_PATH];
+ mir_snprintf(path, "Smileys\\nova\\%s.msl", packnam);
+
+ paths = _A2T(path);
+ CMStringW patha;
+ pathToAbsolute(paths, patha);
+
+ if (_waccess(patha.c_str(), 0) != 0)
+ paths = defaultFile;
+ }
+
+ CMStringW tname(_A2T(acc->szModuleName));
+ AddCategory(tname, displayName, acc->bIsVirtual ? smcVirtualProto : smcProto, paths);
+ }
+}
+
+void SmileyCategoryListType::AddProtoAsCategory(char *acc, const CMStringW &defaultFile)
+{
+ if (acc == nullptr)
+ return;
+
+ const char *packnam = acc;
+ if (mir_strcmp(packnam, "JABBER") == 0)
+ packnam = "JGMail";
+ else if (strstr(packnam, "SIP") != nullptr)
+ packnam = "MSN";
+
+ char path[MAX_PATH];
+ mir_snprintf(path, "Smileys\\nova\\%s.msl", packnam);
+
+ CMStringW paths = _A2T(path), patha;
+ pathToAbsolute(paths, patha);
+
+ if (_waccess(patha.c_str(), 0) != 0)
+ paths = defaultFile;
+ CMStringW dName(acc), displayName;
+ displayName.AppendFormat(TranslateT("%s global smiley pack"), dName.GetBuffer());
+ CMStringW tname("AllProto");
+ tname += _A2T(acc);
+ AddCategory(tname, displayName, smcPhysProto, paths);
+}
+
+void SmileyCategoryListType::DeleteAccountAsCategory(PROTOACCOUNT *acc)
+{
+ CMStringW tname(_A2T(acc->szModuleName));
+
+ for (auto &hContact : Contacts()) {
+ char *proto = GetContactProto(hContact);
+ if (proto == nullptr)
+ continue;
+
+ DBVARIANT dbv;
+ if (!db_get_ws(hContact, proto, "Transport", &dbv)) {
+ bool found = (tname.CompareNoCase(dbv.ptszVal) == 0);
+ db_free(&dbv);
+ if (found)
+ return;
+ }
+ }
+
+ for (auto &it : m_SmileyCategories) {
+ if (tname.CompareNoCase(it->GetName()) == 0) {
+ m_SmileyCategories.removeItem(&it);
+ break;
+ }
+ }
+}
+
+void SmileyCategoryListType::AddContactTransportAsCategory(MCONTACT hContact, const CMStringW &defaultFile)
+{
+ char *proto = GetContactProto(hContact);
+ if (proto == nullptr)
+ return;
+
+ DBVARIANT dbv;
+ if (!db_get_ws(hContact, proto, "Transport", &dbv)) {
+ if (dbv.ptszVal[0] == '\0') {
+ db_free(&dbv);
+ return;
+ }
+ char *trsp = mir_strdup(_T2A(dbv.ptszVal));
+ _strlwr(trsp);
+
+ const char *packname = nullptr;
+ if (strstr(trsp, "msn") != nullptr)
+ packname = "msn";
+ else if (strstr(trsp, "icq") != nullptr)
+ packname = "icq";
+ else if (strstr(trsp, "yahoo") != nullptr)
+ packname = "yahoo";
+ else if (strstr(trsp, "aim") != nullptr)
+ packname = "aim";
+ else if (strstr(trsp, "lcs") != nullptr)
+ packname = "msn";
+
+ mir_free(trsp);
+
+ CMStringW displayName = dbv.ptszVal;
+ if (packname != nullptr) {
+ char path[MAX_PATH];
+ mir_snprintf(path, "Smileys\\nova\\%s.msl", packname);
+
+ CMStringW paths = _A2T(path), patha;
+ pathToAbsolute(paths, patha);
+
+ if (_waccess(patha.c_str(), 0) != 0)
+ paths = defaultFile;
+
+ AddCategory(displayName, displayName, smcTransportProto, paths);
+ }
+ else AddCategory(displayName, displayName, smcTransportProto, defaultFile);
+
+ db_free(&dbv);
+ }
+}
+
+void SmileyCategoryListType::AddAllProtocolsAsCategory(void)
+{
+ CMStringW displayName = TranslateT("Standard");
+ CMStringW tname = L"Standard";
+ AddCategory(tname, displayName, smcStd);
+
+ const CMStringW &defaultFile = GetSmileyCategory(tname)->GetFilename();
+
+ PROTOCOLDESCRIPTOR **proto;
+ int protoCount = 0;
+ Proto_EnumProtocols(&protoCount, &proto);
+
+ for (int i = 0; i < protoCount; i++) {
+ PROTOCOLDESCRIPTOR *pd = proto[i];
+ if (pd->type == PROTOTYPE_PROTOWITHACCS)
+ AddProtoAsCategory(pd->szName, defaultFile);
+ }
+
+ for (auto &pa : Accounts())
+ AddAccountAsCategory(pa, defaultFile);
+
+ for (auto &hContact : Contacts())
+ AddContactTransportAsCategory(hContact, defaultFile);
+
+ CMStringW cats;
+ opt.ReadCustomCategories(cats);
+
+ int cppv = 0;
+ for (;;) {
+ int cp = cats.Find('#', cppv);
+ if (cp == -1)
+ break;
+
+ displayName = cats.Mid(cppv, cp - cppv);
+ AddCategory(displayName, displayName, smcCustom, defaultFile);
+ cppv = cp + 1;
+ }
+
+ if (cppv != cats.GetLength()) {
+ displayName = cats.Mid(cppv);
+ AddCategory(displayName, displayName, smcCustom, defaultFile);
+ }
+}
+
+static const CMStringW testString(L"Test String");
+
+SmileyLookup::SmileyLookup(const CMStringW &str, const bool regexs, const int ind, const CMStringW &smpt)
+{
+ m_ind = ind;
+ if (regexs) {
+ m_pattern.compile(str);
+ m_valid = m_pattern.isValid();
+ if (!m_valid) {
+ wchar_t msgtxt[1024];
+ mir_snwprintf(msgtxt, TranslateT("Regular expression \"%s\" in smiley pack \"%s\" malformed."), str.c_str(), smpt.c_str());
+ Netlib_LogW(hNetlibUser, msgtxt);
+ }
+ }
+ else {
+ m_text = str;
+ replaceCodes(m_text);
+ m_valid = !str.IsEmpty();
+ }
+}
+
+SmileyLookup::~SmileyLookup()
+{
+}
+
+void SmileyLookup::Find(const CMStringW &str, SmileyLocVecType &smlcur, bool firstOnly)
+{
+ if (!m_valid) return;
+
+ if (m_text.IsEmpty()) {
+ while (m_pattern.nextMatch(str) >= 0) {
+ CMStringW wszMatch(m_pattern.getMatch());
+ smlcur.insert(new SmileyLocType(m_pattern.getPos(), wszMatch.GetLength()));
+ if (firstOnly && m_ind != -1)
+ return;
+ }
+ }
+ else {
+ const wchar_t *pos = str.c_str();
+ while ((pos = wcsstr(pos, m_text.c_str())) != nullptr) {
+ smlcur.insert(new SmileyLocType(pos - str.c_str(), m_text.GetLength()));
+ pos += m_text.GetLength();
+ if (firstOnly && m_ind != -1)
+ return;
+ }
+ }
+}
diff --git a/plugins/SmileyAdd/src/smileys.h b/plugins/SmileyAdd/src/smileys.h
index d75d40c418..d0d7a0ef3c 100644
--- a/plugins/SmileyAdd/src/smileys.h
+++ b/plugins/SmileyAdd/src/smileys.h
@@ -203,6 +203,9 @@ public:
bool LoadSmileyFile(const CMStringW &filename, const CMStringW &packname, bool onlyInfo, bool noerr = false);
+ bool LoadSmileyFileMSL(CMStringW &body, bool bOnlyInfo, CMStringW &modPath);
+ bool LoadSmileyFileXEP(CMStringW &body, bool bOnlyInfo);
+
void Clear(void);
};
diff --git a/plugins/SmileyAdd/src/stdafx.h b/plugins/SmileyAdd/src/stdafx.h
index 3993c29660..db2cc70b63 100644
--- a/plugins/SmileyAdd/src/stdafx.h
+++ b/plugins/SmileyAdd/src/stdafx.h
@@ -68,6 +68,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <m_regexp.h>
#include <m_string.h>
#include <m_fontservice.h>
+#include <m_xml.h>
#include <m_metacontacts.h>
#include <m_smileyadd.h>
diff --git a/plugins/SmileyAdd/src/version.h b/plugins/SmileyAdd/src/version.h
index 5c207eebfb..486043ea5f 100644
--- a/plugins/SmileyAdd/src/version.h
+++ b/plugins/SmileyAdd/src/version.h
@@ -1,7 +1,7 @@
#define __MAJOR_VERSION 0
#define __MINOR_VERSION 3
#define __RELEASE_NUM 0
-#define __BUILD_NUM 1
+#define __BUILD_NUM 2
#include <stdver.h>
diff --git a/plugins/StatusManager/src/AdvancedAutoAway/advancedautoaway.cpp b/plugins/StatusManager/src/AdvancedAutoAway/advancedautoaway.cpp
index 5ca571ec9d..ae7c2bd791 100644
--- a/plugins/StatusManager/src/AdvancedAutoAway/advancedautoaway.cpp
+++ b/plugins/StatusManager/src/AdvancedAutoAway/advancedautoaway.cpp
@@ -324,7 +324,7 @@ static VOID CALLBACK AutoAwayTimer(HWND, UINT, UINT_PTR, DWORD)
if (confirm)
confirmDialog = ShowConfirmDialogEx(&ps, db_get_w(0, AAAMODULENAME, SETTING_CONFIRMDELAY, 5));
else if (statusChanged)
- CallService(MS_CS_SETSTATUSEX, (WPARAM)&ps, 0);
+ SetStatusEx(ps);
}
}
diff --git a/plugins/StatusManager/src/KeepStatus/keepstatus.cpp b/plugins/StatusManager/src/KeepStatus/keepstatus.cpp
index cd24606687..403f8e8be2 100644
--- a/plugins/StatusManager/src/KeepStatus/keepstatus.cpp
+++ b/plugins/StatusManager/src/KeepStatus/keepstatus.cpp
@@ -198,7 +198,7 @@ static int SetCurrentStatus()
}
}
ProcessPopup(KS_CONN_STATE_RETRY, (LPARAM)ps.getArray());
- return CallService(MS_CS_SETSTATUSEX, (WPARAM)&ps, 0);
+ return SetStatusEx(ps);
}
static int StatusChange(WPARAM wParam, LPARAM lParam)
@@ -243,7 +243,7 @@ static int CSStatusChange(WPARAM wParam, LPARAM)
return 0;
}
-static int CSStatusChangeEx(WPARAM wParam, LPARAM)
+static int CSStatusChangeEx(WPARAM wParam, LPARAM pCount)
{
// the status was changed by commonstatus (new)
if (wParam != 0) {
@@ -251,7 +251,7 @@ static int CSStatusChangeEx(WPARAM wParam, LPARAM)
if (protoSettings == nullptr)
return -1;
- for (int i = 0; i < protoList.getCount(); i++) {
+ for (int i = 0; i < pCount; i++) {
auto psi = protoSettings[i];
if (psi->m_szName == nullptr)
continue;
diff --git a/plugins/StatusManager/src/StartupStatus/ss_profiles.cpp b/plugins/StatusManager/src/StartupStatus/ss_profiles.cpp
index 2aba9ad8d8..46db3d1299 100644
--- a/plugins/StatusManager/src/StartupStatus/ss_profiles.cpp
+++ b/plugins/StatusManager/src/StartupStatus/ss_profiles.cpp
@@ -204,7 +204,7 @@ INT_PTR LoadAndSetProfile(WPARAM iProfileNo, LPARAM)
char setting[64];
mir_snprintf(setting, "%d_%s", profile, SETTING_SHOWCONFIRMDIALOG);
if (!db_get_b(0, SSMODULENAME, setting, 0))
- CallService(MS_CS_SETSTATUSEX, (WPARAM)&ps, 0);
+ SetStatusEx(ps);
else
ShowConfirmDialogEx(&ps, db_get_dw(0, SSMODULENAME, SETTING_DLGTIMEOUT, 5));
}
diff --git a/plugins/StatusManager/src/StartupStatus/startupstatus.cpp b/plugins/StatusManager/src/StartupStatus/startupstatus.cpp
index 6eb6bb820a..a4e67e1b31 100644
--- a/plugins/StatusManager/src/StartupStatus/startupstatus.cpp
+++ b/plugins/StatusManager/src/StartupStatus/startupstatus.cpp
@@ -215,7 +215,7 @@ static void CALLBACK SetStatusTimed(HWND, UINT, UINT_PTR, DWORD)
if (it->ssDisabled)
it->m_status = ID_STATUS_DISABLED;
- CallService(MS_CS_SETSTATUSEX, (WPARAM)&ps, 0);
+ SetStatusEx(ps);
}
static int OnOkToExit(WPARAM, LPARAM)
diff --git a/plugins/StatusManager/src/commonstatus.cpp b/plugins/StatusManager/src/commonstatus.cpp
index 13e7108af6..7cf8928221 100644
--- a/plugins/StatusManager/src/commonstatus.cpp
+++ b/plugins/StatusManager/src/commonstatus.cpp
@@ -69,7 +69,6 @@ TProtoSettings::TProtoSettings(const TProtoSettings &p)
char* StatusModeToDbSetting(int status, const char *suffix);
DWORD StatusModeToProtoFlag(int status);
-INT_PTR SetStatusEx(WPARAM wParam, LPARAM lParam);
// some helpers from awaymsg.c ================================================================
@@ -144,9 +143,9 @@ wchar_t* GetDefaultStatusMessage(PROTOCOLSETTINGEX *ps, int newstatus)
return tMsg;
}
-static int equalsGlobalStatus(PROTOCOLSETTINGEX **ps)
+static int equalsGlobalStatus(TProtoSettings &ps)
{
- int j, pstatus = 0, gstatus = 0;
+ int pstatus = 0, gstatus = 0;
for (auto &it : protoList)
if (it->m_szMsg != nullptr && GetActualStatus(it) != ID_STATUS_OFFLINE)
@@ -157,9 +156,9 @@ static int equalsGlobalStatus(PROTOCOLSETTINGEX **ps)
continue;
pstatus = 0;
- for (j = 0; j < protoList.getCount(); j++)
- if (!mir_strcmp(pa->szModuleName, ps[j]->m_szName))
- pstatus = GetActualStatus(ps[j]);
+ for (auto &it : ps)
+ if (!mir_strcmp(pa->szModuleName, it->m_szName))
+ pstatus = GetActualStatus(it);
if (pstatus == 0)
pstatus = pa->iRealStatus;
@@ -215,22 +214,17 @@ static void SetStatusMsg(PROTOCOLSETTINGEX *ps, int newstatus)
mir_free(tszMsg);
}
-INT_PTR SetStatusEx(WPARAM wParam, LPARAM)
+int SetStatusEx(TProtoSettings &ps)
{
- PROTOCOLSETTINGEX** protoSettings = *(PROTOCOLSETTINGEX***)wParam;
- if (protoSettings == nullptr)
- return -1;
-
- int globStatus = equalsGlobalStatus(protoSettings);
+ int globStatus = equalsGlobalStatus(ps);
// issue with setting global status;
// things get messy because SRAway hooks ME_CLIST_STATUSMODECHANGE, so the status messages of SRAway and
// commonstatus will clash
- NotifyEventHooks(hCSStatusChangedExEvent, (WPARAM)&protoSettings, protoList.getCount());
+ NotifyEventHooks(hCSStatusChangedExEvent, (WPARAM)&ps, ps.getCount());
// set all status messages first
- for (int i = 0; i < protoList.getCount(); i++) {
- PROTOCOLSETTINGEX *p = protoSettings[i];
+ for (auto &p : ps) {
if (p->m_status == ID_STATUS_DISABLED)
continue;
@@ -239,7 +233,7 @@ INT_PTR SetStatusEx(WPARAM wParam, LPARAM)
continue;
}
// some checks
- int newstatus = GetActualStatus(protoSettings[i]);
+ int newstatus = GetActualStatus(p);
if (newstatus == 0) {
log_debugA("CommonStatus: incorrect status for %s (%d)", p->m_szName, p->m_status);
continue;
@@ -273,7 +267,7 @@ INT_PTR SetStatusEx(WPARAM wParam, LPARAM)
// set status message first
if (b_Caps1 && b_Caps3)
- SetStatusMsg(protoSettings[i], newstatus);
+ SetStatusMsg(p, newstatus);
// set the status
if (newstatus != oldstatus /*&& !(b_Caps1 && b_Caps3 && ServiceExists(MS_NAS_SETSTATE))*/) {
@@ -306,18 +300,6 @@ bool IsSuitableProto(PROTOACCOUNT *pa)
return (pa == nullptr) ? false : pa->IsVisible();
}
-static int CreateServices()
-{
- if (ServiceExists(MS_CS_SETSTATUSEX))
- return -1;
-
- hCSStatusChangedExEvent = CreateHookableEvent(ME_CS_STATUSCHANGEEX);
-
- CreateServiceFunction(MS_CS_SETSTATUSEX, SetStatusEx);
- CreateServiceFunction(MS_CS_GETPROTOCOUNT, GetProtocolCountService);
- return 0;
-}
-
static int onShutdown(WPARAM, LPARAM)
{
g_bMirandaLoaded = false;
@@ -325,10 +307,25 @@ static int onShutdown(WPARAM, LPARAM)
return 0;
}
+static INT_PTR SetStatusEx(WPARAM wParam, LPARAM pCount)
+{
+ PROTOCOLSETTINGEX **protoSettings = *(PROTOCOLSETTINGEX***)wParam;
+ if (protoSettings == nullptr)
+ return -1;
+
+ TProtoSettings ps;
+ for (int i = 0; i < pCount; i++)
+ ps.insert((SMProto*)protoSettings[i]);
+ return SetStatusEx(ps);
+}
+
int InitCommonStatus()
{
- if (!CreateServices())
- HookEvent(ME_SYSTEM_PRESHUTDOWN, onShutdown);
+ hCSStatusChangedExEvent = CreateHookableEvent(ME_CS_STATUSCHANGEEX);
+ CreateServiceFunction(MS_CS_SETSTATUSEX, SetStatusEx);
+ CreateServiceFunction(MS_CS_GETPROTOCOUNT, GetProtocolCountService);
+
+ HookEvent(ME_SYSTEM_PRESHUTDOWN, onShutdown);
return 0;
}
diff --git a/plugins/StatusManager/src/commonstatus.h b/plugins/StatusManager/src/commonstatus.h
index ee9fa8b128..1577f6a5a7 100644
--- a/plugins/StatusManager/src/commonstatus.h
+++ b/plugins/StatusManager/src/commonstatus.h
@@ -138,4 +138,6 @@ extern TProtoSettings protoList;
int CompareProtoSettings(const SMProto *p1, const SMProto *p2);
HWND ShowConfirmDialogEx(TProtoSettings *params, int _timeout);
+int SetStatusEx(TProtoSettings &ps);
+
#endif //COMMONSTATUSHEADER
diff --git a/plugins/StatusManager/src/confirmdialog.cpp b/plugins/StatusManager/src/confirmdialog.cpp
index a833408839..63c13658e0 100644
--- a/plugins/StatusManager/src/confirmdialog.cpp
+++ b/plugins/StatusManager/src/confirmdialog.cpp
@@ -27,27 +27,7 @@
static HWND win;
static int timeOut;
-struct TConfirmSetting : public PROTOCOLSETTINGEX
-{
- TConfirmSetting(const PROTOCOLSETTINGEX &x)
- {
- memcpy(this, &x, sizeof(PROTOCOLSETTINGEX));
- if (m_szMsg)
- m_szMsg = mir_wstrdup(m_szMsg);
- }
-
- ~TConfirmSetting()
- {
- mir_free(m_szMsg);
- }
-};
-
-static int CompareSettings(const TConfirmSetting* p1, const TConfirmSetting* p2)
-{
- return mir_strcmp(p1->m_szName, p2->m_szName);
-}
-
-static OBJLIST<TConfirmSetting> *confirmSettings;
+static TProtoSettings *confirmSettings;
static INT_PTR CALLBACK StatusMessageDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
@@ -385,7 +365,7 @@ static INT_PTR CALLBACK ConfirmDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LP
break;
case UM_CLOSECONFIRMDLG:
- CallService(MS_CS_SETSTATUSEX, (WPARAM)confirmSettings, 0);
+ SetStatusEx(*confirmSettings);
DestroyWindow(hwndDlg);
break;
@@ -400,11 +380,11 @@ static INT_PTR CALLBACK ConfirmDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LP
HWND ShowConfirmDialogEx(TProtoSettings *params, int _timeout)
{
delete confirmSettings;
- confirmSettings = new OBJLIST<TConfirmSetting>(10, CompareSettings);
+ confirmSettings = new TProtoSettings();
for (auto &it : *params)
if (it->m_status != ID_STATUS_DISABLED)
- confirmSettings->insert(new TConfirmSetting(*it));
+ confirmSettings->insert(new SMProto(*it));
timeOut = _timeout;
if (timeOut < 0)
diff --git a/plugins/StatusManager/src/version.h b/plugins/StatusManager/src/version.h
index 45db33e0dc..b16d6f952c 100644
--- a/plugins/StatusManager/src/version.h
+++ b/plugins/StatusManager/src/version.h
@@ -1,8 +1,8 @@
// plugin version part
#define __MAJOR_VERSION 1
-#define __MINOR_VERSION 1
+#define __MINOR_VERSION 2
#define __RELEASE_NUM 0
-#define __BUILD_NUM 4
+#define __BUILD_NUM 1
// other stuff for Version resource
#include <stdver.h>
diff --git a/plugins/TabSRMM/src/resource.h b/plugins/TabSRMM/src/resource.h
index c4472425c5..b0ecaae43e 100644
--- a/plugins/TabSRMM/src/resource.h
+++ b/plugins/TabSRMM/src/resource.h
@@ -193,7 +193,6 @@
#define IDC_TOGGLETOOLBAR 1144
#define IDC_ERRORTEXT 1145
#define IDC_SHOWNOTIFY 1146
-#define IDC_STATUSWIN 1147
#define IDC_TYPEFLASHWIN 1148
#define IDC_CHARCOUNT 1149
#define IDC_TYPENOWIN 1150
diff --git a/src/core/stdmsg/res/resource.rc b/src/core/stdmsg/res/resource.rc
index dbdc5bcf2b..9acdd24f88 100644
--- a/src/core/stdmsg/res/resource.rc
+++ b/src/core/stdmsg/res/resource.rc
@@ -33,36 +33,39 @@ EXSTYLE WS_EX_CONTROLPARENT
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
LTEXT "Automatically popup window when:",IDC_STATIC,7,7,141,13
- CONTROL "Tree1",IDC_POPLIST,"SysTreeView32",TVS_DISABLEDRAGDROP | TVS_NOTOOLTIPS | TVS_NOHSCROLL | TVS_NONEVENHEIGHT | WS_BORDER | WS_HSCROLL | WS_TABSTOP,199,6,98,42
+ CONTROL "Tree1",IDC_POPLIST,"SysTreeView32",TVS_DISABLEDRAGDROP | TVS_NOTOOLTIPS | TVS_NOHSCROLL | TVS_NONEVENHEIGHT | WS_BORDER | WS_TABSTOP,199,6,98,42
CONTROL "In background",IDC_DONOTSTEALFOCUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,21,130,10
+
+ LTEXT "Maximum number of flashes",IDC_STATIC,7,35,141,8
+ EDITTEXT IDC_NFLASHES,148,33,25,12,ES_AUTOHSCROLL | ES_NUMBER
+
CONTROL "Close the message window on send",IDC_AUTOCLOSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,50,289,10
CONTROL "Minimize the message window on send",IDC_AUTOMIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,62,289,10
- CONTROL "Use the contact's status icon as the window icon",IDC_STATUSWIN,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,74,289,10
CONTROL "Save the window size and location individually for each contact",IDC_SAVEPERCONTACT,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,86,289,10
CONTROL "Cascade new windows",IDC_CASCADE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,98,289,10
- CONTROL "Show 'Send' button",IDC_SHOWSENDBTN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,166,135,10
- CONTROL "Show toolbar buttons on top row",IDC_SHOWBUTTONLINE,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,192,137,10
- CONTROL "Send message on double 'Enter'",IDC_SENDONDBLENTER,
- "Button", BS_AUTORADIOBUTTON | WS_TABSTOP,148,166,149,10
- CONTROL "Send message on 'Enter'",IDC_SENDONENTER,"Button", BS_AUTORADIOBUTTON | WS_TABSTOP,148,179,152,10
- CONTROL "Show character count",IDC_CHARCOUNT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,148,192,149,10
- LTEXT "Show warning when message has not been received after",IDC_STATIC,8,208,211,8
- EDITTEXT IDC_SECONDS,223,206,25,12,ES_AUTOHSCROLL
- LTEXT "seconds",IDC_STATIC,253,208,44,8
CONTROL "Support CTRL+Up/Down in message area to show previously sent messages",IDC_CTRLSUPPORT,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,110,289,10
CONTROL "Delete temporary contacts when closing message window",IDC_DELTEMP,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,122,287,10
CONTROL "Enable avatar support in the message window",IDC_AVATARSUPPORT,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,135,289,10
+
CONTROL "Limit avatar height to",IDC_LIMITAVATARH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,149,126,10
EDITTEXT IDC_AVATARHEIGHT,148,148,28,13,ES_AUTOHSCROLL
LTEXT "pixels",IDC_STATIC,181,150,35,8
- LTEXT "Maximum number of flashes",IDC_STATIC,7,35,141,8
- EDITTEXT IDC_NFLASHES,148,33,25,12,ES_AUTOHSCROLL | ES_NUMBER
+
+ CONTROL "Show 'Send' button",IDC_SHOWSENDBTN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,166,135,10
+ CONTROL "Show character count",IDC_CHARCOUNT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,179,135,10
+ CONTROL "Show toolbar buttons on top row",IDC_SHOWBUTTONLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,192,137,10
+
+ CONTROL "Send message on double 'Enter'",IDC_SENDONDBLENTER,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,148,166,149,10
+ CONTROL "Send message on 'Enter'",IDC_SENDONENTER,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,148,179,152,10
+ CONTROL "Send message on 'Ctrl-Enter'",IDC_SENDONCTRLENTER, "Button",BS_AUTORADIOBUTTON | WS_TABSTOP,148,192,152,10
+
+ LTEXT "Show warning when message has not been received after",IDC_STATIC,8,208,211,8
+ EDITTEXT IDC_SECONDS,223,206,25,12,ES_AUTOHSCROLL
+ LTEXT "seconds",IDC_STATIC,253,208,44,8
END
IDD_MSGSENDERROR DIALOGEX 0, 0, 187, 110
@@ -242,7 +245,7 @@ BEGIN
CONTROL "Custom2",IDC_BKG,"ColourPicker",WS_TABSTOP,201,93,50,14,WS_EX_NOACTIVATE | 0x10000000L
EDITTEXT IDC_TIMEOUT,132,134,38,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER
CONTROL "Spin1",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,169,135,11,14
- GROUPBOX "Popups for the Chat plugin",IDC_STATIC,0,0,277,174
+ GROUPBOX "Popups for the StdMsg plugin",IDC_STATIC,0,0,277,174
LTEXT "Timeout (s)",IDC_STATIC,33,138,92,8
LTEXT "Text",IDC_STATIC,141,83,49,8
LTEXT "Background",IDC_STATIC,201,83,67,8
diff --git a/src/core/stdmsg/src/chat_manager.cpp b/src/core/stdmsg/src/chat_manager.cpp
index a4e4697f3e..d55671f558 100644
--- a/src/core/stdmsg/src/chat_manager.cpp
+++ b/src/core/stdmsg/src/chat_manager.cpp
@@ -60,33 +60,26 @@ CHAT_MANAGER *pci;
HMENU g_hMenu = nullptr;
BOOL SmileyAddInstalled = FALSE, PopupInstalled = FALSE;
-HIMAGELIST hIconsList;
GlobalLogSettings g_Settings;
static void OnDestroyModule(MODULEINFO *mi)
{
- if (mi->hOnlineIcon) DestroyIcon(mi->hOnlineIcon);
- if (mi->hOnlineTalkIcon) DestroyIcon(mi->hOnlineTalkIcon);
- if (mi->hOfflineIcon) DestroyIcon(mi->hOfflineIcon);
- if (mi->hOfflineTalkIcon) DestroyIcon(mi->hOfflineTalkIcon);
+ if (mi->hOnlineIcon)
+ DestroyIcon(mi->hOnlineIcon);
+ if (mi->hOfflineIcon)
+ DestroyIcon(mi->hOfflineIcon);
}
static void OnCreateModule(MODULEINFO *mi)
{
OnDestroyModule(mi);
- mi->OnlineIconIndex = ImageList_AddIcon(hIconsList, Skin_LoadProtoIcon(mi->pszModule, ID_STATUS_ONLINE));
- mi->hOnlineIcon = ImageList_GetIcon(hIconsList, mi->OnlineIconIndex, ILD_TRANSPARENT);
- mi->hOnlineTalkIcon = ImageList_GetIcon(hIconsList, mi->OnlineIconIndex, ILD_TRANSPARENT | INDEXTOOVERLAYMASK(1));
- ImageList_AddIcon(hIconsList, mi->hOnlineTalkIcon);
+ mi->OnlineIconIndex = pcli->pfnIconFromStatusMode(mi->pszModule, ID_STATUS_ONLINE, 0);
+ mi->hOnlineIcon = ImageList_GetIcon(Clist_GetImageList(), mi->OnlineIconIndex, ILD_TRANSPARENT);
- mi->OfflineIconIndex = ImageList_AddIcon(hIconsList, Skin_LoadProtoIcon(mi->pszModule, ID_STATUS_OFFLINE));
- mi->hOfflineIcon = ImageList_GetIcon(hIconsList, mi->OfflineIconIndex, ILD_TRANSPARENT);
- mi->hOfflineTalkIcon = ImageList_GetIcon(hIconsList, mi->OfflineIconIndex, ILD_TRANSPARENT | INDEXTOOVERLAYMASK(1));
- ImageList_AddIcon(hIconsList, mi->hOfflineTalkIcon);
-
- g_iMessageIconIndex = ImageList_AddIcon(hIconsList, Skin_LoadIcon(SKINICON_EVENT_MESSAGE));
+ mi->OfflineIconIndex = pcli->pfnIconFromStatusMode(mi->pszModule, ID_STATUS_OFFLINE, 0);
+ mi->hOfflineIcon = ImageList_GetIcon(Clist_GetImageList(), mi->OfflineIconIndex, ILD_TRANSPARENT);
}
static void OnReplaceSession(SESSION_INFO *si)
@@ -257,11 +250,6 @@ void Load_ChatModule()
g_hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_MENU));
- hIconsList = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, 0, 100);
- ImageList_AddIcon(hIconsList, Skin_LoadIcon(SKINICON_EVENT_MESSAGE));
- ImageList_AddIcon(hIconsList, LoadIconEx("overlay", FALSE));
- ImageList_SetOverlayImage(hIconsList, 1, 1);
-
HookEvent(ME_SYSTEM_MODULELOAD, OnCheckPlugins);
}
diff --git a/src/core/stdmsg/src/chat_options.cpp b/src/core/stdmsg/src/chat_options.cpp
index 96bdb59659..2764e3c528 100644
--- a/src/core/stdmsg/src/chat_options.cpp
+++ b/src/core/stdmsg/src/chat_options.cpp
@@ -31,8 +31,6 @@ struct branch_t
};
static branch_t branch1[] = {
- { LPGENW("Send message by pressing the 'Enter' key"), "SendOnEnter", 0, true },
- { LPGENW("Send message by pressing the 'Enter' key twice"), "SendOnDblEnter", 0, false },
{ LPGENW("Flash window when someone speaks"), "FlashWindow", 0, false },
{ LPGENW("Flash window when a word is highlighted"), "FlashWindowHighlight", 0, true },
{ LPGENW("Show list of users in the chat room"), "ShowNicklist", 0, true },
diff --git a/src/core/stdmsg/src/chat_window.cpp b/src/core/stdmsg/src/chat_window.cpp
index 4767d84312..a015311e85 100644
--- a/src/core/stdmsg/src/chat_window.cpp
+++ b/src/core/stdmsg/src/chat_window.cpp
@@ -58,7 +58,7 @@ void CChatRoomDlg::OnInitDialog()
if (g_Settings.bTabsEnable)
SetWindowLongPtr(m_hwnd, GWL_EXSTYLE, GetWindowLongPtr(m_hwnd, GWL_EXSTYLE) | WS_EX_APPWINDOW);
else
- onActivate();
+ OnActivate();
m_log.SendMsg(EM_AUTOURLDETECT, 1, 0);
@@ -86,7 +86,7 @@ void CChatRoomDlg::OnDestroy()
CSuper::OnDestroy();
}
-void CChatRoomDlg::onActivate()
+void CChatRoomDlg::OnActivate()
{
WINDOWPLACEMENT wp = {};
wp.length = sizeof(wp);
@@ -286,13 +286,8 @@ void CChatRoomDlg::UpdateOptions()
hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIcon : mi->hOfflineIcon;
}
- if (g_Settings.bTabsEnable)
- g_pTabDialog->FixTabIcons(nullptr);
-
SendMessage(m_pOwner->m_hwndStatus, SB_SETICON, 0, (LPARAM)hIcon);
- Window_SetIcon_IcoLib(m_pOwner->GetHwnd(), GetIconHandle("window"));
-
m_log.SendMsg(EM_SETBKGNDCOLOR, 0, g_Settings.crLogBackground);
CHARFORMAT2 cf;
@@ -341,10 +336,6 @@ void CChatRoomDlg::UpdateStatusBar()
}
SendMessage(m_pOwner->m_hwndStatus, SB_SETICON, 0, (LPARAM)hIcon);
-
- if (g_Settings.bTabsEnable)
- g_pTabDialog->FixTabIcons(nullptr);
-
SendMessage(m_pOwner->m_hwndStatus, SB_SETTEXT, 0, (LPARAM)ptszDispName);
SendMessage(m_pOwner->m_hwndStatus, SB_SETTEXT, 1, (LPARAM)(m_si->ptszStatusbarText ? m_si->ptszStatusbarText : L""));
SendMessage(m_pOwner->m_hwndStatus, SB_SETTIPTEXT, 1, (LPARAM)(m_si->ptszStatusbarText ? m_si->ptszStatusbarText : L""));
@@ -635,11 +626,11 @@ LRESULT CChatRoomDlg::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam)
return TRUE;
if (wParam == '\n' || wParam == '\r') {
- if ((isCtrl != 0) ^ (0 != db_get_b(0, CHAT_MODULE, "SendOnEnter", 1))) {
+ if ((isCtrl && g_dat.bSendOnCtrlEnter) || (!isCtrl && g_dat.bSendOnEnter)) {
m_btnOk.OnClick(&m_btnOk);
return 0;
}
- if (db_get_b(0, CHAT_MODULE, "SendOnDblEnter", 0)) {
+ if (g_dat.bSendOnDblEnter) {
if (m_iLastEnterTime + 2 < time(0))
m_iLastEnterTime = time(0);
else {
@@ -667,10 +658,10 @@ LRESULT CChatRoomDlg::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam)
bool isAlt = (GetKeyState(VK_MENU) & 0x8000) != 0;
if (wParam == VK_RETURN) {
szTabSave[0] = '\0';
- if ((isCtrl != 0) ^ (0 != db_get_b(0, CHAT_MODULE, "SendOnEnter", 1)))
+ if ((isCtrl && g_dat.bSendOnCtrlEnter) || (!isCtrl && g_dat.bSendOnEnter))
return 0;
- if (db_get_b(0, CHAT_MODULE, "SendOnDblEnter", 0))
+ if (g_dat.bSendOnDblEnter)
if (m_iLastEnterTime + 2 >= time(0))
return 0;
@@ -1110,17 +1101,8 @@ INT_PTR CChatRoomDlg::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
if (g_Settings.bTabsEnable) {
m_si->wState &= ~GC_EVENT_HIGHLIGHT;
m_si->wState &= ~STATE_TALK;
- g_pTabDialog->FixTabIcons(nullptr);
}
- break;
}
- if (LOWORD(wParam) == WA_ACTIVE)
- onActivate();
- break;
-
- case WM_MOUSEACTIVATE:
- onActivate();
- SetFocus(m_message.GetHwnd());
break;
case WM_NOTIFY:
diff --git a/src/core/stdmsg/src/globals.cpp b/src/core/stdmsg/src/globals.cpp
index 01aa85af7b..353bd8bf17 100644
--- a/src/core/stdmsg/src/globals.cpp
+++ b/src/core/stdmsg/src/globals.cpp
@@ -47,7 +47,6 @@ static int OnShutdown(WPARAM, LPARAM)
si->pDlg->Close();
UninitTabs();
- ImageList_Destroy(hIconsList);
return 0;
}
@@ -126,9 +125,9 @@ GlobalMessageData::GlobalMessageData() :
bCtrlSupport(SRMMMOD, "SupportCtrlUpDn", true),
bShowReadChar(SRMMMOD, "ShowCharCount", false),
bSendOnDblEnter(SRMMMOD, "SendOnDblEnter", false),
+ bSendOnCtrlEnter(SRMMMOD, "SendOnCtrlEnter", false),
bDeleteTempCont(SRMMMOD, "DeleteTempCont", false),
bSavePerContact(SRMMMOD, "SavePerContact", false),
- bUseStatusWinIcon(SRMMMOD, "UseStatusWinIcon", false),
bDoNotStealFocus(SRMMMOD, "DoNotStealFocus", false),
bLimitAvatarHeight(SRMMMOD, "AvatarLimitHeight", true),
diff --git a/src/core/stdmsg/src/globals.h b/src/core/stdmsg/src/globals.h
index fef2a2a44f..a0ad036b01 100644
--- a/src/core/stdmsg/src/globals.h
+++ b/src/core/stdmsg/src/globals.h
@@ -41,6 +41,7 @@ struct GlobalMessageData
CMOption<bool> bShowReadChar;
CMOption<bool> bSendOnEnter;
CMOption<bool> bSendOnDblEnter;
+ CMOption<bool> bSendOnCtrlEnter;
CMOption<bool> bAutoClose;
CMOption<bool> bAutoMin;
CMOption<bool> bTypingNew;
@@ -48,7 +49,6 @@ struct GlobalMessageData
CMOption<bool> bCtrlSupport;
CMOption<bool> bShowFormat;
CMOption<bool> bSavePerContact;
- CMOption<bool> bUseStatusWinIcon;
CMOption<bool> bDoNotStealFocus;
CMOption<bool> bCascade;
CMOption<bool> bDeleteTempCont;
diff --git a/src/core/stdmsg/src/msgdialog.cpp b/src/core/stdmsg/src/msgdialog.cpp
index 0a5ef46008..a65857539a 100644
--- a/src/core/stdmsg/src/msgdialog.cpp
+++ b/src/core/stdmsg/src/msgdialog.cpp
@@ -308,6 +308,17 @@ void CSrmmWindow::OnDestroy()
db_delete_contact(m_hContact);
}
+void CSrmmWindow::OnActivate()
+{
+ SetupStatusBar();
+ SetFocus(m_message.GetHwnd());
+ UpdateTitle();
+ UpdateLastMessage();
+ if (KillTimer(m_hwnd, TIMERID_FLASHWND))
+ FlashWindow(m_pOwner->GetHwnd(), FALSE);
+ SendMessage(m_hwnd, DM_UPDATEWINICON, 0, 0);
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
void CSrmmWindow::onClick_Ok(CCtrlButton *pButton)
@@ -353,12 +364,12 @@ void CSrmmWindow::OnOptionsApplied(bool bUpdateAvatar)
continue;
bool bShow = false;
- if (m_hContact) {
+ if (m_hContact && g_dat.bShowButtons) {
if (cbd->m_dwButtonCID == IDC_ADD) {
bShow = 0 != db_get_b(m_hContact, "CList", "NotOnList", 0);
cbd->m_bHidden = !bShow;
}
- else bShow = g_dat.bShowButtons;
+ else bShow = true;
}
ShowWindow(hwndButton, (bShow) ? SW_SHOW : SW_HIDE);
}
@@ -585,19 +596,22 @@ void CSrmmWindow::UpdateIcon(WPARAM wParam)
if (!m_hContact || !m_szProto)
return;
+ bool bIsStatus = false;
DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *)wParam;
- if (!cws || (!mir_strcmp(cws->szModule, m_szProto) && !mir_strcmp(cws->szSetting, "Status"))) {
- if (m_szProto) {
- HICON hIcon = Skin_LoadProtoIcon(m_szProto, m_wStatus);
- if (hIcon) {
- if (m_hStatusIcon)
- IcoLib_ReleaseIcon(m_hStatusIcon);
- m_hStatusIcon = hIcon;
- SendDlgItemMessage(m_hwnd, IDC_USERMENU, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
- }
+ if (cws && !mir_strcmp(cws->szModule, m_szProto) && !mir_strcmp(cws->szSetting, "Status")) {
+ bIsStatus = true;
+ m_wStatus = cws->value.wVal;
+ }
+
+ if (!cws || bIsStatus) {
+ HICON hIcon = Skin_LoadProtoIcon(m_szProto, m_wStatus);
+ if (hIcon) {
+ if (m_hStatusIcon)
+ IcoLib_ReleaseIcon(m_hStatusIcon);
+ m_hStatusIcon = hIcon;
}
- if (g_dat.bUseStatusWinIcon)
- SendMessage(m_hwnd, DM_UPDATEWINICON, 0, 0);
+
+ SendMessage(m_hwnd, DM_UPDATEWINICON, 0, 0);
}
}
@@ -634,23 +648,15 @@ void CSrmmWindow::UpdateTitle()
m_wStatus = db_get_w(m_hContact, m_szProto, "Status", ID_STATUS_OFFLINE);
wchar_t *contactName = Clist_GetContactDisplayName(m_hContact);
- if (g_dat.bUseStatusWinIcon)
- mir_snwprintf(newtitle, L"%s - %s", contactName, TranslateT("Message session"));
- else {
- wchar_t *szStatus = Clist_GetStatusModeDescription(m_szProto == nullptr ? ID_STATUS_OFFLINE : db_get_w(m_hContact, m_szProto, "Status", ID_STATUS_OFFLINE), 0);
- mir_snwprintf(newtitle, L"%s (%s): %s", contactName, szStatus, TranslateT("Message session"));
- }
-
+ mir_snwprintf(newtitle, L"%s - %s", contactName, TranslateT("Message session"));
m_wOldStatus = m_wStatus;
}
else mir_wstrncpy(newtitle, TranslateT("Message session"), _countof(newtitle));
wchar_t oldtitle[256];
GetWindowText(m_pOwner->GetHwnd(), oldtitle, _countof(oldtitle));
- if (mir_wstrcmp(newtitle, oldtitle)) { //swt() flickers even if the title hasn't actually changed
+ if (mir_wstrcmp(newtitle, oldtitle)) //swt() flickers even if the title hasn't actually changed
SetWindowText(m_pOwner->GetHwnd(), newtitle);
- Resize();
- }
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -737,7 +743,11 @@ LRESULT CSrmmWindow::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam)
isAlt = (GetKeyState(VK_MENU) & 0x8000) != 0;
if (wParam == VK_RETURN) {
- if (!isShift && isCtrl != g_dat.bSendOnEnter) {
+ if (!isShift && !isCtrl && g_dat.bSendOnEnter) {
+ onClick_Ok(&m_btnOk);
+ return 0;
+ }
+ if (!isShift && isCtrl && g_dat.bSendOnCtrlEnter) {
onClick_Ok(&m_btnOk);
return 0;
}
@@ -1032,15 +1042,7 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
break;
case DM_UPDATEWINICON:
- if (g_dat.bUseStatusWinIcon) {
- Window_FreeIcon_IcoLib(m_pOwner->GetHwnd());
-
- if (m_szProto) {
- Window_SetProtoIcon_IcoLib(m_pOwner->GetHwnd(), m_szProto, Contact_GetStatus(m_hContact));
- break;
- }
- }
- Window_SetSkinIcon_IcoLib(m_pOwner->GetHwnd(), SKINICON_EVENT_MESSAGE);
+ m_pOwner->FixTabIcons(this);
break;
case DM_USERNAMETOCLIP:
@@ -1080,22 +1082,6 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
}
break;
- case WM_ACTIVATE:
- if (LOWORD(wParam) != WA_ACTIVE)
- break;
-
- __fallthrough;
-
- case WM_MOUSEACTIVATE:
- SetFocus(m_message.GetHwnd());
- UpdateTitle();
- UpdateLastMessage();
- if (KillTimer(m_hwnd, TIMERID_FLASHWND))
- FlashWindow(m_pOwner->GetHwnd(), FALSE);
- if (g_dat.bUseStatusWinIcon)
- SendMessage(m_hwnd, DM_UPDATEWINICON, 0, 0);
- break;
-
case WM_CBD_LOADICONS:
Srmm_UpdateToolbarIcons(m_hwnd);
break;
diff --git a/src/core/stdmsg/src/msgoptions.cpp b/src/core/stdmsg/src/msgoptions.cpp
index 5168b2933c..6c62b74d07 100644
--- a/src/core/stdmsg/src/msgoptions.cpp
+++ b/src/core/stdmsg/src/msgoptions.cpp
@@ -154,9 +154,9 @@ class COptionMainDlg : public CPluginDlgBase
{
CCtrlEdit edtNFlash, edtAvatarH, edtSecs;
CCtrlCheck chkAutoMin, chkAutoClose, chkSavePerContact, chkDoNotStealFocus;
- CCtrlCheck chkDelTemp, chkCascade, chkCharCount, chkStatusWin, chkCtrlSupport;
+ CCtrlCheck chkDelTemp, chkCascade, chkCharCount, chkCtrlSupport;
CCtrlCheck chkAvatar, chkLimitAvatar;
- CCtrlCheck chkSendOnEnter, chkSendOnDblEnter, chkShowSend, chkShowButtons;
+ CCtrlCheck chkSendOnEnter, chkSendOnDblEnter, chkSendOnCtrlEnter, chkShowSend, chkShowButtons;
CCtrlTreeView tree;
@@ -204,13 +204,13 @@ public:
chkCascade(this, IDC_CASCADE),
chkShowSend(this, IDC_SHOWSENDBTN),
chkAutoClose(this, IDC_AUTOCLOSE),
- chkStatusWin(this, IDC_STATUSWIN),
chkCharCount(this, IDC_CHARCOUNT),
chkLimitAvatar(this, IDC_LIMITAVATARH),
chkShowButtons(this, IDC_SHOWBUTTONLINE),
chkCtrlSupport(this, IDC_CTRLSUPPORT),
chkSendOnEnter(this, IDC_SENDONENTER),
chkSendOnDblEnter(this, IDC_SENDONDBLENTER),
+ chkSendOnCtrlEnter(this, IDC_SENDONCTRLENTER),
chkSavePerContact(this, IDC_SAVEPERCONTACT),
chkDoNotStealFocus(this, IDC_DONOTSTEALFOCUS)
{
@@ -234,11 +234,11 @@ public:
CreateLink(chkAutoClose, g_dat.bAutoClose);
CreateLink(chkShowSend, g_dat.bSendButton);
CreateLink(chkCharCount, g_dat.bShowReadChar);
- CreateLink(chkStatusWin, g_dat.bUseStatusWinIcon);
CreateLink(chkShowButtons, g_dat.bShowButtons);
CreateLink(chkCtrlSupport, g_dat.bCtrlSupport);
CreateLink(chkSendOnEnter, g_dat.bSendOnEnter);
CreateLink(chkSendOnDblEnter, g_dat.bSendOnDblEnter);
+ CreateLink(chkSendOnCtrlEnter, g_dat.bSendOnCtrlEnter);
CreateLink(chkSavePerContact, g_dat.bSavePerContact);
CreateLink(chkDoNotStealFocus, g_dat.bDoNotStealFocus);
}
diff --git a/src/core/stdmsg/src/msgs.cpp b/src/core/stdmsg/src/msgs.cpp
index 1b8a5f9727..a95501bf69 100644
--- a/src/core/stdmsg/src/msgs.cpp
+++ b/src/core/stdmsg/src/msgs.cpp
@@ -41,6 +41,23 @@ void CMsgDialog::CloseTab()
else SendMessage(m_hwndParent, WM_CLOSE, 0, 0);
}
+INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg) {
+ case WM_ACTIVATE:
+ if (LOWORD(wParam) == WA_ACTIVE)
+ OnActivate();
+ break;
+
+ case WM_MOUSEACTIVATE:
+ OnActivate();
+ SetFocus(m_message.GetHwnd());
+ break;
+ }
+
+ return CSuper::DlgProc(uMsg, wParam, lParam);
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
int OnCheckPlugins(WPARAM, LPARAM);
@@ -409,27 +426,20 @@ void SetButtonsPos(HWND hwndDlg, bool bIsChat)
GetClientRect(hwndDlg, &rc);
int iLeftX = 2, iRightX = rc.right - 2;
- bool bShow = (bIsChat) ? true : g_dat.bShowButtons;
-
CustomButtonData *cbd;
for (int i = 0; cbd = Srmm_GetNthButton(i); i++) {
HWND hwndButton = GetDlgItem(hwndDlg, cbd->m_dwButtonCID);
if (hwndButton == nullptr || cbd->m_bHidden)
continue;
- if (bShow) {
- ShowWindow(hwndButton, SW_SHOW);
-
- if (cbd->m_bRSided) {
- iRightX -= g_dat.iGap + cbd->m_iButtonWidth;
- hdwp = DeferWindowPos(hdwp, hwndButton, nullptr, iRightX, yPos, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
- }
- else {
- hdwp = DeferWindowPos(hdwp, hwndButton, nullptr, iLeftX, yPos, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
- iLeftX += g_dat.iGap + cbd->m_iButtonWidth;
- }
+ if (cbd->m_bRSided) {
+ iRightX -= g_dat.iGap + cbd->m_iButtonWidth;
+ hdwp = DeferWindowPos(hdwp, hwndButton, nullptr, iRightX, yPos, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
+ }
+ else {
+ hdwp = DeferWindowPos(hdwp, hwndButton, nullptr, iLeftX, yPos, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
+ iLeftX += g_dat.iGap + cbd->m_iButtonWidth;
}
- else ShowWindow(hwndButton, SW_HIDE);
}
EndDeferWindowPos(hdwp);
diff --git a/src/core/stdmsg/src/msgs.h b/src/core/stdmsg/src/msgs.h
index 75c64c69cb..3d5e443517 100644
--- a/src/core/stdmsg/src/msgs.h
+++ b/src/core/stdmsg/src/msgs.h
@@ -53,8 +53,12 @@ protected:
CMsgDialog(int idDialog, SESSION_INFO *si = nullptr);
+ virtual void OnActivate() PURE;
+
+ INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override;
+
public:
- virtual void CloseTab() override;
+ void CloseTab() override;
__forceinline SESSION_INFO* getChat() const { return m_si; }
};
@@ -63,8 +67,8 @@ class CSrmmWindow : public CMsgDialog
{
typedef CMsgDialog CSuper;
- virtual LRESULT WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) override;
- virtual LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) override;
+ LRESULT WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) override;
+ LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) override;
CCtrlBase m_avatar;
CSplitter m_splitter;
@@ -114,16 +118,17 @@ public:
public:
CSrmmWindow(CTabbedWindow*, MCONTACT hContact);
- virtual void OnInitDialog() override;
- virtual void OnDestroy() override;
+ void OnInitDialog() override;
+ void OnDestroy() override;
+ void OnActivate() override;
- virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override;
- virtual int Resizer(UTILRESIZECONTROL *urc) override;
+ INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override;
+ int Resizer(UTILRESIZECONTROL *urc) override;
- virtual void LoadSettings() override {}
- virtual void ScrollToBottom() override;
- virtual void SetStatusText(const wchar_t*, HICON) override;
- virtual void UpdateTitle() override;
+ void LoadSettings() override {}
+ void ScrollToBottom() override;
+ void SetStatusText(const wchar_t*, HICON) override;
+ void UpdateTitle() override;
void OnSplitterMoved(CSplitter*);
@@ -152,9 +157,9 @@ class CChatRoomDlg : public CMsgDialog
static INT_PTR CALLBACK FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
- virtual LRESULT WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) override;
- virtual LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) override;
- virtual LRESULT WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) override;
+ LRESULT WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) override;
+ LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) override;
+ LRESULT WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) override;
wchar_t szTabSave[20];
@@ -164,26 +169,25 @@ class CChatRoomDlg : public CMsgDialog
int m_iSplitterX, m_iSplitterY;
- void onActivate(void);
-
public:
CChatRoomDlg(CTabbedWindow*, SESSION_INFO*);
- virtual void OnInitDialog() override;
- virtual void OnDestroy() override;
-
- virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override;
- virtual int Resizer(UTILRESIZECONTROL *urc) override;
-
- virtual void LoadSettings() override;
- virtual void RedrawLog() override;
- virtual void StreamInEvents(LOGINFO *lin, bool bRedraw) override;
- virtual void ScrollToBottom() override;
- virtual void ShowFilterMenu() override;
- virtual void UpdateNickList() override;
- virtual void UpdateOptions() override;
- virtual void UpdateStatusBar() override;
- virtual void UpdateTitle() override;
+ void OnInitDialog() override;
+ void OnDestroy() override;
+ void OnActivate() override;
+
+ INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override;
+ int Resizer(UTILRESIZECONTROL *urc) override;
+
+ void LoadSettings() override;
+ void RedrawLog() override;
+ void StreamInEvents(LOGINFO *lin, bool bRedraw) override;
+ void ScrollToBottom() override;
+ void ShowFilterMenu() override;
+ void UpdateNickList() override;
+ void UpdateOptions() override;
+ void UpdateStatusBar() override;
+ void UpdateTitle() override;
void onClick_Ok(CCtrlButton*);
diff --git a/src/core/stdmsg/src/resource.h b/src/core/stdmsg/src/resource.h
index fda43c6d1e..92b72236fb 100644
--- a/src/core/stdmsg/src/resource.h
+++ b/src/core/stdmsg/src/resource.h
@@ -1,4 +1,4 @@
-//{{NO_DEPENDENCIES}}
+//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by resource.rc
//
@@ -60,7 +60,6 @@
#define IDI_INCOMING 276
#define IDI_OUTGOING 277
#define IDI_EXCL 282
-
#define IDC_SPLITTERX 1003
#define IDC_AUTOCLOSE 1004
#define IDC_AUTOMIN 1005
@@ -88,6 +87,7 @@
#define IDC_SENDONDBLENTER 1044
#define IDC_LOADTIMEN 1045
#define IDC_LOADTIMESPIN 1046
+#define IDC_SENDONCTRLENTER 1046
#define IDC_LOADTIME 1047
#define IDC_STMINSOLD 1048
#define IDC_SPIN1 1049
@@ -130,14 +130,12 @@
#define IDC_HIGHLIGHT 1089
#define IDC_TEXTO 1090
#define IDC_LOGGING 1091
-
+#define IDC_STMSGLOGGROUP 1442
#define IDC_DETAILS 1469
#define IDC_USERMENU 1471
-#define IDC_STMSGLOGGROUP 1442
#define IDC_ERRORTEXT 1596
#define IDC_MSGTEXT 1597
#define IDC_SHOWNOTIFY 1600
-#define IDC_STATUSWIN 1601
#define IDC_TYPEWIN 1602
#define IDC_CHARCOUNT 1603
#define IDC_TYPETRAY 1603
@@ -158,7 +156,6 @@
#define IDC_CLOSETABS 1621
#define IDC_RESTORETABS 1622
#define IDC_TABSBOTTOM 1623
-
#define IDM_CUT 40000
#define IDM_COPY 40001
#define IDM_PASTE 40002
@@ -169,17 +166,16 @@
#define IDM_COPYALL 40011
#define IDM_SELECTALL 40012
#define IDM_CLEAR 40013
-
#define ID_MESS 40021
#define ID_COPYALL 40026
#define ID_CLEARLOG 40029
+#define ID_MESSAGE_PASTE 40030
#define ID_MESSAGE_UNDO 40033
#define ID_MESSAGE_COPY 40034
#define ID_MESSAGE_CUT 40035
#define ID_MESSAGE_CLEAR 40037
#define ID_MESSAGE_SELECTALL 40038
#define ID_MESSAGE_REDO 40039
-#define ID_MESSAGE_PASTE 40030
#define ID_CLOSE 40042
#define ID_CLOSEOTHER 40043
#define ID_LOCKPOSITION 40044
@@ -190,7 +186,7 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 290
+#define _APS_NEXT_RESOURCE_VALUE 291
#define _APS_NEXT_COMMAND_VALUE 40019
#define _APS_NEXT_CONTROL_VALUE 1620
#define _APS_NEXT_SYMED_VALUE 101
diff --git a/src/core/stdmsg/src/stdafx.h b/src/core/stdmsg/src/stdafx.h
index 28f6e257fd..c9f458a840 100644
--- a/src/core/stdmsg/src/stdafx.h
+++ b/src/core/stdmsg/src/stdafx.h
@@ -88,11 +88,8 @@ extern HINSTANCE g_hInst;
struct MODULEINFO : public GCModuleInfoBase
{
- HICON hOnlineIcon, hOnlineTalkIcon;
- HICON hOfflineIcon, hOfflineTalkIcon;
-
- int OnlineIconIndex;
- int OfflineIconIndex;
+ HICON hOnlineIcon, hOfflineIcon;
+ int OnlineIconIndex, OfflineIconIndex;
};
struct SESSION_INFO : public GCSessionInfoBase {};
@@ -112,11 +109,9 @@ struct GlobalLogSettings : public GlobalLogSettingsBase
extern GlobalLogSettings g_Settings;
extern HMENU g_hMenu;
-extern HIMAGELIST hIconsList;
extern HINSTANCE g_hInst;
extern BOOL SmileyAddInstalled, PopupInstalled;
-extern int g_iMessageIconIndex;
// main.cpp
void LoadIcons(void);
diff --git a/src/core/stdmsg/src/tabs.cpp b/src/core/stdmsg/src/tabs.cpp
index c244f0dd24..ba2e2670c5 100644
--- a/src/core/stdmsg/src/tabs.cpp
+++ b/src/core/stdmsg/src/tabs.cpp
@@ -42,7 +42,6 @@ void TB_SaveSession(SESSION_INFO *si)
}
CTabbedWindow *g_pTabDialog = nullptr;
-int g_iMessageIconIndex;
/////////////////////////////////////////////////////////////////////////////////////////
@@ -85,7 +84,7 @@ static LRESULT CALLBACK TabSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
MODULEINFO *mi = pci->MM_FindModule(si->pszModule);
bDragging = true;
iBeginIndex = idx;
- ImageList_BeginDrag(hIconsList, bOnline ? mi->OnlineIconIndex : mi->OfflineIconIndex, 8, 8);
+ ImageList_BeginDrag(Clist_GetImageList(), bOnline ? mi->OnlineIconIndex : mi->OfflineIconIndex, 8, 8);
ImageList_DragEnter(hwnd, tci.pt.x, tci.pt.y);
SetCapture(hwnd);
}
@@ -192,7 +191,7 @@ void CTabbedWindow::OnInitDialog()
SetWindowLongPtr(m_tab.GetHwnd(), GWL_STYLE, mask);
TabCtrl_SetMinTabWidth(m_tab.GetHwnd(), 80);
- TabCtrl_SetImageList(m_tab.GetHwnd(), hIconsList);
+ TabCtrl_SetImageList(m_tab.GetHwnd(), Clist_GetImageList());
// restore previous tabs
if (g_Settings.bTabRestore) {
@@ -273,9 +272,8 @@ void CTabbedWindow::AddPage(SESSION_INFO *si, int insertAt)
CChatRoomDlg *pDlg = new CChatRoomDlg(this, si);
pDlg->SetParent(m_hwnd);
m_tab.AddPage(szTemp, nullptr, pDlg);
- FixTabIcons(pDlg);
-
m_tab.ActivatePage(m_tab.GetCount() - 1);
+ FixTabIcons(pDlg);
}
else if (insertAt == -1)
m_tab.ActivatePage(indexfound);
@@ -283,31 +281,32 @@ void CTabbedWindow::AddPage(SESSION_INFO *si, int insertAt)
void CTabbedWindow::FixTabIcons(CSrmmBaseDialog *pDlg)
{
- if (pDlg != nullptr) {
- int idx = m_tab.GetDlgIndex(pDlg);
- if (idx == -1)
- return;
+ if (pDlg == nullptr)
+ return;
- int image = 0;
- if (SESSION_INFO *si = ((CChatRoomDlg*)pDlg)->m_si) {
- if (!(si->wState & GC_EVENT_HIGHLIGHT)) {
- MODULEINFO *mi = pci->MM_FindModule(si->pszModule);
- image = (si->wStatus == ID_STATUS_ONLINE) ? mi->OnlineIconIndex : mi->OfflineIconIndex;
- if (si->wState & STATE_TALK)
- image++;
- }
- }
- else image = g_iMessageIconIndex;
+ int idx = m_tab.GetDlgIndex(pDlg);
+ if (idx == -1)
+ return;
- TCITEM tci = {};
- tci.mask = TCIF_IMAGE;
- TabCtrl_GetItem(m_tab.GetHwnd(), idx, &tci);
- if (tci.iImage != image) {
- tci.iImage = image;
- TabCtrl_SetItem(m_tab.GetHwnd(), idx, &tci);
+ int image = 0;
+ if (SESSION_INFO *si = ((CChatRoomDlg*)pDlg)->m_si) {
+ if (!(si->wState & GC_EVENT_HIGHLIGHT)) {
+ MODULEINFO *mi = pci->MM_FindModule(si->pszModule);
+ image = (si->wStatus == ID_STATUS_ONLINE) ? mi->OnlineIconIndex : mi->OfflineIconIndex;
}
}
- else RedrawWindow(m_tab.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE);
+ else image = pcli->pfnIconFromStatusMode(GetContactProto(pDlg->m_hContact), Contact_GetStatus(pDlg->m_hContact), pDlg->m_hContact);
+
+ TCITEM tci = {};
+ tci.mask = TCIF_IMAGE;
+ TabCtrl_GetItem(m_tab.GetHwnd(), idx, &tci);
+ if (tci.iImage != image) {
+ tci.iImage = image;
+ TabCtrl_SetItem(m_tab.GetHwnd(), idx, &tci);
+ }
+
+ if (pDlg == m_tab.GetActivePage())
+ SendMessage(m_hwnd, WM_SETICON, 0, (LPARAM)ImageList_GetIcon(Clist_GetImageList(), image, 0));
}
void CTabbedWindow::SaveWindowPosition(bool bUpdateSession)
diff --git a/src/mir_app/src/clisttray.cpp b/src/mir_app/src/clisttray.cpp
index 658a11fd70..95a48da22d 100644
--- a/src/mir_app/src/clisttray.cpp
+++ b/src/mir_app/src/clisttray.cpp
@@ -27,8 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define TOOLTIP_TOLERANCE 5
-extern HIMAGELIST hCListImages;
-
static UINT WM_TASKBARCREATED;
static UINT WM_TASKBARBUTTONCREATED;
static UINT_PTR RefreshTimerId = 0; /////by FYR