From 1979fd80424d16b2e489f9b57d01d9c7811d25a2 Mon Sep 17 00:00:00 2001 From: dartraiden Date: Mon, 2 Jan 2023 21:10:29 +0300 Subject: Update copyrights --- src/core/stdmsg/src/chat_manager.cpp | 486 ++++++------- src/core/stdmsg/src/chat_window.cpp | 550 +++++++------- src/core/stdmsg/src/cmdlist.cpp | 2 +- src/core/stdmsg/src/cmdlist.h | 2 +- src/core/stdmsg/src/globals.cpp | 2 +- src/core/stdmsg/src/msgdialog.cpp | 2 +- src/core/stdmsg/src/msglog.cpp | 2 +- src/core/stdmsg/src/msgoptions.cpp | 2 +- src/core/stdmsg/src/msgs.cpp | 2 +- src/core/stdmsg/src/msgs.h | 2 +- src/core/stdmsg/src/msgtimedout.cpp | 2 +- src/core/stdmsg/src/srmm.cpp | 2 +- src/core/stdmsg/src/statusicon.cpp | 2 +- src/core/stdmsg/src/stdafx.cxx | 2 +- src/core/stdmsg/src/stdafx.h | 2 +- src/core/stdmsg/src/tabs.cpp | 1336 +++++++++++++++++----------------- src/core/stdmsg/src/version.h | 2 +- 17 files changed, 1200 insertions(+), 1200 deletions(-) (limited to 'src/core/stdmsg') diff --git a/src/core/stdmsg/src/chat_manager.cpp b/src/core/stdmsg/src/chat_manager.cpp index b72f53acd7..b461b91703 100644 --- a/src/core/stdmsg/src/chat_manager.cpp +++ b/src/core/stdmsg/src/chat_manager.cpp @@ -1,243 +1,243 @@ -/* -Chat module plugin for Miranda IM - -Copyright 2000-12 Miranda IM, 2012-22 Miranda NG team, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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; either version 2 -of the License, or (at your option) any later version. - -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, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "stdafx.h" - -pfnDoTrayIcon oldDoTrayIcon; -pfnDoPopup oldDoPopup; - -SESSION_INFO* SM_GetPrevWindow(SESSION_INFO *si) -{ - int i = g_chatApi.arSessions.indexOf(si); - if (i == -1) - return nullptr; - - for (i--; i >= 0; i--) { - SESSION_INFO *p = g_chatApi.arSessions[i]; - if (p->pDlg) - return p; - } - - return nullptr; -} - -SESSION_INFO* SM_GetNextWindow(SESSION_INFO *si) -{ - int i = g_chatApi.arSessions.indexOf(si); - if (i == -1) - return nullptr; - - for (i++; i < g_chatApi.arSessions.getCount(); i++) { - SESSION_INFO *p = g_chatApi.arSessions[i]; - if (p->pDlg) - return p; - } - - return nullptr; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -HMENU g_hMenu = nullptr; - -GlobalLogSettings g_Settings; - -static MODULEINFO* MM_CreateModule() -{ - return new MODULEINFO(); -} - -static void OnReplaceSession(SESSION_INFO *si) -{ - if (si->pDlg) - RedrawWindow(GetDlgItem(si->pDlg->GetHwnd(), IDC_SRMM_NICKLIST), nullptr, nullptr, RDW_INVALIDATE); -} - -static void OnFlashHighlight(SESSION_INFO *si, int bInactive) -{ - if (!bInactive || si->pDlg == nullptr) - return; - - if (g_Settings.bTabsEnable) - g_pTabDialog->SetMessageHighlight(si->pDlg); - else if (Chat::bFlashWindowHighlight) - si->pDlg->StartFlash(); -} - -static void OnFlashWindow(SESSION_INFO *si, int bInactive) -{ - if (!bInactive || si->pDlg == nullptr) - return; - - if (g_Settings.bTabsEnable) - g_pTabDialog->SetTabHighlight(si->pDlg); - else if (Chat::bFlashWindow) - si->pDlg->StartFlash(); -} - -static BOOL DoTrayIcon(SESSION_INFO *si, GCEVENT *gce) -{ - if (gce->iType & g_Settings.dwTrayIconFlags) - return oldDoTrayIcon(si, gce); - return TRUE; -} - -static BOOL DoPopup(SESSION_INFO *si, GCEVENT *gce) -{ - if (gce->iType & g_Settings.dwPopupFlags) - return oldDoPopup(si, gce); - return TRUE; -} - -static void OnLoadSettings() -{ - g_Settings.iX = db_get_dw(0, CHAT_MODULE, "roomx", -1); - g_Settings.iY = db_get_dw(0, CHAT_MODULE, "roomy", -1); - - g_Settings.bTabsEnable = db_get_b(0, CHAT_MODULE, "Tabs", 1) != 0; - g_Settings.bTabsAtBottom = db_get_b(0, CHAT_MODULE, "TabBottom", 0) != 0; - g_Settings.bTabCloseOnDblClick = db_get_b(0, CHAT_MODULE, "TabCloseOnDblClick", 0) != 0; - g_Settings.bAddColonToAutoComplete = db_get_b(0, CHAT_MODULE, "AddColonToAutoComplete", 1) != 0; - - g_Settings.iSplitterX = db_get_w(0, CHAT_MODULE, "SplitterX", 105); - if (g_Settings.iSplitterX <= 50) - g_Settings.iSplitterX = 105; - g_Settings.iSplitterY = db_get_w(0, CHAT_MODULE, "SplitterY", 90); - if (g_Settings.iSplitterY <= 65) - g_Settings.iSplitterY = 90; -} - -static void RegisterFonts() -{ - ColourIDW colourid = {}; - strncpy(colourid.dbSettingsGroup, CHAT_MODULE, sizeof(colourid.dbSettingsGroup)); - wcsncpy(colourid.group, LPGENW("Message sessions") L"/" LPGENW("Chat module"), _countof(colourid.group)); - - strncpy(colourid.setting, "ColorLogBG", _countof(colourid.setting)); - wcsncpy(colourid.name, LPGENW("Group chat log background"), _countof(colourid.name)); - colourid.defcolour = GetSysColor(COLOR_WINDOW); - g_plugin.addColor(&colourid); - - strncpy(colourid.setting, "ColorMessageBG", _countof(colourid.setting)); - wcsncpy(colourid.name, LPGENW("Message background"), _countof(colourid.name)); - colourid.defcolour = GetSysColor(COLOR_WINDOW); - g_plugin.addColor(&colourid); - - strncpy(colourid.setting, "ColorNicklistBG", _countof(colourid.setting)); - wcsncpy(colourid.name, LPGENW("Nick list background"), _countof(colourid.name)); - colourid.defcolour = GetSysColor(COLOR_WINDOW); - g_plugin.addColor(&colourid); - - strncpy(colourid.setting, "ColorNicklistLines", _countof(colourid.setting)); - wcsncpy(colourid.name, LPGENW("Nick list lines"), _countof(colourid.name)); - colourid.defcolour = GetSysColor(COLOR_INACTIVEBORDER); - g_plugin.addColor(&colourid); - - strncpy(colourid.setting, "ColorNicklistSelectedBG", _countof(colourid.setting)); - wcsncpy(colourid.name, LPGENW("Nick list background (selected)"), _countof(colourid.name)); - colourid.defcolour = GetSysColor(COLOR_HIGHLIGHT); - g_plugin.addColor(&colourid); -} - -static void ShowRoom(SESSION_INFO *si) -{ - if (!si) - return; - - // Do we need to create a window? - if (si->pDlg == nullptr) { - CTabbedWindow *pContainer = GetContainer(); - if (g_Settings.bTabsEnable) { - pContainer->AddPage(si); - PostMessage(pContainer->GetHwnd(), WM_SIZE, 0, 0); - } - else { - CMsgDialog *pDlg = pContainer->m_pEmbed = new CMsgDialog(pContainer, si); - pContainer->Create(); - pDlg->SetParent(pContainer->GetHwnd()); - pDlg->Create(); - pContainer->Show(); - pContainer->FixTabIcons(pDlg); - PostMessage(pContainer->GetHwnd(), WM_SIZE, 0, 0); - } - - if (si->iType != GCW_SERVER) - si->pDlg->UpdateNickList(); - else - si->pDlg->UpdateTitle(); - si->pDlg->UpdateStatusBar(); - } - else if (g_Settings.bTabsEnable && g_pTabDialog) - g_pTabDialog->m_tab.ActivatePage(g_pTabDialog->m_tab.GetDlgIndex(si->pDlg)); - - SetWindowLongPtr(si->pDlg->GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(si->pDlg->GetHwnd(), GWL_EXSTYLE) | WS_EX_APPWINDOW); - - if (IsIconic(si->pDlg->GetHwnd())) - si->pDlg->Show(SW_NORMAL); - si->pDlg->Show(SW_SHOW); - SetForegroundWindow(si->pDlg->GetHwnd()); -} - -int OnCheckPlugins(WPARAM, LPARAM) -{ - g_plugin.bSmileyInstalled = ServiceExists(MS_SMILEYADD_REPLACESMILEYS); - return 0; -} - -void Load_ChatModule() -{ - AddIcons(); - RegisterFonts(); - - CHAT_MANAGER_INITDATA data = { &g_Settings, sizeof(MODULEINFO), sizeof(SESSION_INFO), LPGENW("Message sessions") L"/" LPGENW("Chat module"), FONTMODE_USE, &g_plugin }; - Chat_CustomizeApi(&data); - - g_chatApi.MM_CreateModule = MM_CreateModule; - g_chatApi.OnReplaceSession = OnReplaceSession; - - g_chatApi.OnLoadSettings = OnLoadSettings; - g_chatApi.OnFlashWindow = OnFlashWindow; - g_chatApi.OnFlashHighlight = OnFlashHighlight; - g_chatApi.ShowRoom = ShowRoom; - - Srmm_CreateHotkey(LPGEN("Messaging"), LPGEN("Send message")); - - oldDoPopup = g_chatApi.DoPopup; g_chatApi.DoPopup = DoPopup; - oldDoTrayIcon = g_chatApi.DoTrayIcon; g_chatApi.DoTrayIcon = DoTrayIcon; - g_chatApi.ReloadSettings(); - - g_hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_MENU)); - - HookEvent(ME_SYSTEM_MODULELOAD, OnCheckPlugins); -} - -void Unload_ChatModule() -{ - db_set_w(0, CHAT_MODULE, "SplitterX", (uint16_t)g_Settings.iSplitterX); - db_set_w(0, CHAT_MODULE, "SplitterY", (uint16_t)g_Settings.iSplitterY); - db_set_dw(0, CHAT_MODULE, "roomx", g_Settings.iX); - db_set_dw(0, CHAT_MODULE, "roomy", g_Settings.iY); - db_set_dw(0, CHAT_MODULE, "roomwidth", g_Settings.iWidth); - db_set_dw(0, CHAT_MODULE, "roomheight", g_Settings.iHeight); - - DestroyMenu(g_hMenu); -} +/* +Chat module plugin for Miranda IM + +Copyright 2000-12 Miranda IM, 2012-23 Miranda NG team, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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; either version 2 +of the License, or (at your option) any later version. + +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "stdafx.h" + +pfnDoTrayIcon oldDoTrayIcon; +pfnDoPopup oldDoPopup; + +SESSION_INFO* SM_GetPrevWindow(SESSION_INFO *si) +{ + int i = g_chatApi.arSessions.indexOf(si); + if (i == -1) + return nullptr; + + for (i--; i >= 0; i--) { + SESSION_INFO *p = g_chatApi.arSessions[i]; + if (p->pDlg) + return p; + } + + return nullptr; +} + +SESSION_INFO* SM_GetNextWindow(SESSION_INFO *si) +{ + int i = g_chatApi.arSessions.indexOf(si); + if (i == -1) + return nullptr; + + for (i++; i < g_chatApi.arSessions.getCount(); i++) { + SESSION_INFO *p = g_chatApi.arSessions[i]; + if (p->pDlg) + return p; + } + + return nullptr; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +HMENU g_hMenu = nullptr; + +GlobalLogSettings g_Settings; + +static MODULEINFO* MM_CreateModule() +{ + return new MODULEINFO(); +} + +static void OnReplaceSession(SESSION_INFO *si) +{ + if (si->pDlg) + RedrawWindow(GetDlgItem(si->pDlg->GetHwnd(), IDC_SRMM_NICKLIST), nullptr, nullptr, RDW_INVALIDATE); +} + +static void OnFlashHighlight(SESSION_INFO *si, int bInactive) +{ + if (!bInactive || si->pDlg == nullptr) + return; + + if (g_Settings.bTabsEnable) + g_pTabDialog->SetMessageHighlight(si->pDlg); + else if (Chat::bFlashWindowHighlight) + si->pDlg->StartFlash(); +} + +static void OnFlashWindow(SESSION_INFO *si, int bInactive) +{ + if (!bInactive || si->pDlg == nullptr) + return; + + if (g_Settings.bTabsEnable) + g_pTabDialog->SetTabHighlight(si->pDlg); + else if (Chat::bFlashWindow) + si->pDlg->StartFlash(); +} + +static BOOL DoTrayIcon(SESSION_INFO *si, GCEVENT *gce) +{ + if (gce->iType & g_Settings.dwTrayIconFlags) + return oldDoTrayIcon(si, gce); + return TRUE; +} + +static BOOL DoPopup(SESSION_INFO *si, GCEVENT *gce) +{ + if (gce->iType & g_Settings.dwPopupFlags) + return oldDoPopup(si, gce); + return TRUE; +} + +static void OnLoadSettings() +{ + g_Settings.iX = db_get_dw(0, CHAT_MODULE, "roomx", -1); + g_Settings.iY = db_get_dw(0, CHAT_MODULE, "roomy", -1); + + g_Settings.bTabsEnable = db_get_b(0, CHAT_MODULE, "Tabs", 1) != 0; + g_Settings.bTabsAtBottom = db_get_b(0, CHAT_MODULE, "TabBottom", 0) != 0; + g_Settings.bTabCloseOnDblClick = db_get_b(0, CHAT_MODULE, "TabCloseOnDblClick", 0) != 0; + g_Settings.bAddColonToAutoComplete = db_get_b(0, CHAT_MODULE, "AddColonToAutoComplete", 1) != 0; + + g_Settings.iSplitterX = db_get_w(0, CHAT_MODULE, "SplitterX", 105); + if (g_Settings.iSplitterX <= 50) + g_Settings.iSplitterX = 105; + g_Settings.iSplitterY = db_get_w(0, CHAT_MODULE, "SplitterY", 90); + if (g_Settings.iSplitterY <= 65) + g_Settings.iSplitterY = 90; +} + +static void RegisterFonts() +{ + ColourIDW colourid = {}; + strncpy(colourid.dbSettingsGroup, CHAT_MODULE, sizeof(colourid.dbSettingsGroup)); + wcsncpy(colourid.group, LPGENW("Message sessions") L"/" LPGENW("Chat module"), _countof(colourid.group)); + + strncpy(colourid.setting, "ColorLogBG", _countof(colourid.setting)); + wcsncpy(colourid.name, LPGENW("Group chat log background"), _countof(colourid.name)); + colourid.defcolour = GetSysColor(COLOR_WINDOW); + g_plugin.addColor(&colourid); + + strncpy(colourid.setting, "ColorMessageBG", _countof(colourid.setting)); + wcsncpy(colourid.name, LPGENW("Message background"), _countof(colourid.name)); + colourid.defcolour = GetSysColor(COLOR_WINDOW); + g_plugin.addColor(&colourid); + + strncpy(colourid.setting, "ColorNicklistBG", _countof(colourid.setting)); + wcsncpy(colourid.name, LPGENW("Nick list background"), _countof(colourid.name)); + colourid.defcolour = GetSysColor(COLOR_WINDOW); + g_plugin.addColor(&colourid); + + strncpy(colourid.setting, "ColorNicklistLines", _countof(colourid.setting)); + wcsncpy(colourid.name, LPGENW("Nick list lines"), _countof(colourid.name)); + colourid.defcolour = GetSysColor(COLOR_INACTIVEBORDER); + g_plugin.addColor(&colourid); + + strncpy(colourid.setting, "ColorNicklistSelectedBG", _countof(colourid.setting)); + wcsncpy(colourid.name, LPGENW("Nick list background (selected)"), _countof(colourid.name)); + colourid.defcolour = GetSysColor(COLOR_HIGHLIGHT); + g_plugin.addColor(&colourid); +} + +static void ShowRoom(SESSION_INFO *si) +{ + if (!si) + return; + + // Do we need to create a window? + if (si->pDlg == nullptr) { + CTabbedWindow *pContainer = GetContainer(); + if (g_Settings.bTabsEnable) { + pContainer->AddPage(si); + PostMessage(pContainer->GetHwnd(), WM_SIZE, 0, 0); + } + else { + CMsgDialog *pDlg = pContainer->m_pEmbed = new CMsgDialog(pContainer, si); + pContainer->Create(); + pDlg->SetParent(pContainer->GetHwnd()); + pDlg->Create(); + pContainer->Show(); + pContainer->FixTabIcons(pDlg); + PostMessage(pContainer->GetHwnd(), WM_SIZE, 0, 0); + } + + if (si->iType != GCW_SERVER) + si->pDlg->UpdateNickList(); + else + si->pDlg->UpdateTitle(); + si->pDlg->UpdateStatusBar(); + } + else if (g_Settings.bTabsEnable && g_pTabDialog) + g_pTabDialog->m_tab.ActivatePage(g_pTabDialog->m_tab.GetDlgIndex(si->pDlg)); + + SetWindowLongPtr(si->pDlg->GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(si->pDlg->GetHwnd(), GWL_EXSTYLE) | WS_EX_APPWINDOW); + + if (IsIconic(si->pDlg->GetHwnd())) + si->pDlg->Show(SW_NORMAL); + si->pDlg->Show(SW_SHOW); + SetForegroundWindow(si->pDlg->GetHwnd()); +} + +int OnCheckPlugins(WPARAM, LPARAM) +{ + g_plugin.bSmileyInstalled = ServiceExists(MS_SMILEYADD_REPLACESMILEYS); + return 0; +} + +void Load_ChatModule() +{ + AddIcons(); + RegisterFonts(); + + CHAT_MANAGER_INITDATA data = { &g_Settings, sizeof(MODULEINFO), sizeof(SESSION_INFO), LPGENW("Message sessions") L"/" LPGENW("Chat module"), FONTMODE_USE, &g_plugin }; + Chat_CustomizeApi(&data); + + g_chatApi.MM_CreateModule = MM_CreateModule; + g_chatApi.OnReplaceSession = OnReplaceSession; + + g_chatApi.OnLoadSettings = OnLoadSettings; + g_chatApi.OnFlashWindow = OnFlashWindow; + g_chatApi.OnFlashHighlight = OnFlashHighlight; + g_chatApi.ShowRoom = ShowRoom; + + Srmm_CreateHotkey(LPGEN("Messaging"), LPGEN("Send message")); + + oldDoPopup = g_chatApi.DoPopup; g_chatApi.DoPopup = DoPopup; + oldDoTrayIcon = g_chatApi.DoTrayIcon; g_chatApi.DoTrayIcon = DoTrayIcon; + g_chatApi.ReloadSettings(); + + g_hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_MENU)); + + HookEvent(ME_SYSTEM_MODULELOAD, OnCheckPlugins); +} + +void Unload_ChatModule() +{ + db_set_w(0, CHAT_MODULE, "SplitterX", (uint16_t)g_Settings.iSplitterX); + db_set_w(0, CHAT_MODULE, "SplitterY", (uint16_t)g_Settings.iSplitterY); + db_set_dw(0, CHAT_MODULE, "roomx", g_Settings.iX); + db_set_dw(0, CHAT_MODULE, "roomy", g_Settings.iY); + db_set_dw(0, CHAT_MODULE, "roomwidth", g_Settings.iWidth); + db_set_dw(0, CHAT_MODULE, "roomheight", g_Settings.iHeight); + + DestroyMenu(g_hMenu); +} diff --git a/src/core/stdmsg/src/chat_window.cpp b/src/core/stdmsg/src/chat_window.cpp index 52106ae755..8e1871dd4c 100644 --- a/src/core/stdmsg/src/chat_window.cpp +++ b/src/core/stdmsg/src/chat_window.cpp @@ -1,275 +1,275 @@ -/* -Chat module plugin for Miranda IM - -Copyright 2000-12 Miranda IM, 2012-22 Miranda NG team, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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; either version 2 -of the License, or (at your option) any later version. - -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, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "stdafx.h" - -///////////////////////////////////////////////////////////////////////////////////////// - -void CMsgDialog::LoadSettings() -{ - m_clrInputBG = db_get_dw(0, CHAT_MODULE, "ColorMessageBG", GetSysColor(COLOR_WINDOW)); - LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, nullptr, &m_clrInputFG); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void CMsgDialog::ShowFilterMenu() -{ - HWND hwnd = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_FILTER), m_hwnd, FilterWndProc, (LPARAM)this); - TranslateDialogDefault(hwnd); - - RECT rc; - GetWindowRect(m_btnFilter.GetHwnd(), &rc); - SetWindowPos(hwnd, HWND_TOP, rc.left - 85, (IsWindowVisible(m_btnFilter.GetHwnd()) || IsWindowVisible(m_btnBold.GetHwnd())) ? rc.top - 206 : rc.top - 186, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); -} - -void CMsgDialog::UpdateNickList() -{ - int i = m_nickList.SendMsg(LB_GETTOPINDEX, 0, 0); - m_nickList.SendMsg(LB_SETCOUNT, m_si->getUserList().getCount(), 0); - m_nickList.SendMsg(LB_SETTOPINDEX, i, 0); - - UpdateTitle(); -} - -void CMsgDialog::UpdateOptions() -{ - m_btnNickList.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(m_bNicklistEnabled ? IDI_NICKLIST2 : IDI_NICKLIST, FALSE)); - m_btnFilter.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(m_bFilterEnabled ? IDI_FILTER2 : IDI_FILTER, FALSE)); - - HICON hIcon = ImageList_GetIcon(Clist_GetImageList(), GetImageId(), ILD_TRANSPARENT); - SendMessage(m_pOwner->m_hwndStatus, SB_SETICON, 0, (LPARAM)hIcon); - DestroyIcon(hIcon); - - Window_SetIcon_IcoLib(m_pOwner->GetHwnd(), g_plugin.getIconHandle(IDI_CHANMGR)); - - m_pLog->UpdateOptions(); - - // nicklist - int ih = Chat_GetTextPixelSize(L"AQGglo", g_Settings.UserListFont, FALSE); - int ih2 = Chat_GetTextPixelSize(L"AQGglo", g_Settings.UserListHeadingsFont, FALSE); - int height = db_get_b(0, CHAT_MODULE, "NicklistRowDist", 12); - int font = ih > ih2 ? ih : ih2; - - // make sure we have space for icon! - if (g_Settings.bShowContactStatus) - font = font > 16 ? font : 16; - - m_nickList.SendMsg(LB_SETITEMHEIGHT, 0, height > font ? height : font); - InvalidateRect(m_nickList.GetHwnd(), nullptr, TRUE); - - CSuper::UpdateOptions(); -} - -void CMsgDialog::UpdateStatusBar() -{ - wchar_t *ptszDispName = m_si->pMI->ptszModDispName; - int x = 12; - x += Chat_GetTextPixelSize(ptszDispName, (HFONT)SendMessage(m_pOwner->m_hwndStatus, WM_GETFONT, 0, 0), TRUE); - x += GetSystemMetrics(SM_CXSMICON); - int iStatusbarParts[2] = { x, -1 }; - SendMessage(m_pOwner->m_hwndStatus, SB_SETPARTS, 2, (LPARAM)&iStatusbarParts); - - HICON hIcon = ImageList_GetIcon(Clist_GetImageList(), GetImageId(), ILD_TRANSPARENT); - SendMessage(m_pOwner->m_hwndStatus, SB_SETICON, 0, (LPARAM)hIcon); - DestroyIcon(hIcon); - - 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"")); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void CLogWindow::LogEvents(LOGINFO *lin, bool bRedraw) -{ - auto *si = m_pDlg.m_si; - if (lin == nullptr || si == nullptr) - return; - - if (!bRedraw && si->iType == GCW_CHATROOM && m_pDlg.m_bFilterEnabled && (m_pDlg.m_iLogFilterFlags & lin->iType) == 0) - return; - - LOGSTREAMDATA streamData; - memset(&streamData, 0, sizeof(streamData)); - streamData.hwnd = m_rtf.GetHwnd(); - streamData.si = si; - streamData.lin = lin; - streamData.bStripFormat = FALSE; - - bool bFlag = false; - - EDITSTREAM stream = {}; - stream.pfnCallback = Srmm_LogStreamCallback; - stream.dwCookie = (DWORD_PTR)& streamData; - - SCROLLINFO scroll; - scroll.cbSize = sizeof(SCROLLINFO); - scroll.fMask = SIF_RANGE | SIF_POS | SIF_PAGE; - GetScrollInfo(m_rtf.GetHwnd(), SB_VERT, &scroll); - - POINT point = {}; - m_rtf.SendMsg(EM_GETSCROLLPOS, 0, (LPARAM)&point); - - // do not scroll to bottom if there is a selection - CHARRANGE oldsel, sel; - m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldsel); - if (oldsel.cpMax != oldsel.cpMin) - m_rtf.SetDraw(false); - - //set the insertion point at the bottom - sel.cpMin = sel.cpMax = m_rtf.GetRichTextLength(); - m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - - // fix for the indent... must be a M$ bug - if (sel.cpMax == 0) - bRedraw = TRUE; - - // should the event(s) be appended to the current log - WPARAM wp = bRedraw ? SF_RTF : SFF_SELECTION | SF_RTF; - - //get the number of pixels per logical inch - if (bRedraw) { - HDC hdc = GetDC(nullptr); - g_chatApi.logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY); - g_chatApi.logPixelSX = GetDeviceCaps(hdc, LOGPIXELSX); - ReleaseDC(nullptr, hdc); - m_rtf.SetDraw(false); - bFlag = true; - } - - // stream in the event(s) - streamData.lin = lin; - streamData.bRedraw = bRedraw; - m_rtf.SendMsg(EM_STREAMIN, wp, (LPARAM)&stream); - - // do smileys - if (g_plugin.bSmileyInstalled && (bRedraw || (lin->ptszText && lin->iType != GC_EVENT_JOIN && lin->iType != GC_EVENT_NICK && lin->iType != GC_EVENT_ADDSTATUS && lin->iType != GC_EVENT_REMOVESTATUS))) { - CHARRANGE newsel; - newsel.cpMax = -1; - newsel.cpMin = sel.cpMin; - if (newsel.cpMin < 0) - newsel.cpMin = 0; - - SMADD_RICHEDIT3 sm = {}; - sm.cbSize = sizeof(sm); - sm.hwndRichEditControl = m_rtf.GetHwnd(); - sm.Protocolname = si->pszModule; - sm.rangeToReplace = bRedraw ? nullptr : &newsel; - sm.disableRedraw = TRUE; - sm.hContact = si->hContact; - CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM)&sm); - } - - // scroll log to bottom if the log was previously scrolled to bottom, else restore old position - if (bRedraw || (UINT)scroll.nPos >= (UINT)scroll.nMax - scroll.nPage - 5 || scroll.nMax - scroll.nMin - scroll.nPage < 50) - ScrollToBottom(); - else - m_rtf.SendMsg(EM_SETSCROLLPOS, 0, (LPARAM)&point); - - // do we need to restore the selection - if (oldsel.cpMax != oldsel.cpMin) { - m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&oldsel); - m_rtf.SetDraw(true); - InvalidateRect(m_rtf.GetHwnd(), nullptr, TRUE); - } - - // need to invalidate the window - if (bFlag) { - sel.cpMin = sel.cpMax = m_rtf.GetRichTextLength(); - m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - m_rtf.SetDraw(true); - InvalidateRect(m_rtf.GetHwnd(), nullptr, TRUE); - } -} - -///////////////////////////////////////////////////////////////////////////////////////// - -INT_PTR CALLBACK CMsgDialog::FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - static CMsgDialog *pDlg = nullptr; - switch (uMsg) { - case WM_INITDIALOG: - pDlg = (CMsgDialog*)lParam; - CheckDlgButton(hwndDlg, IDC_1, pDlg->m_iLogFilterFlags & GC_EVENT_ACTION ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_2, pDlg->m_iLogFilterFlags & GC_EVENT_MESSAGE ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_3, pDlg->m_iLogFilterFlags & GC_EVENT_NICK ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_4, pDlg->m_iLogFilterFlags & GC_EVENT_JOIN ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_5, pDlg->m_iLogFilterFlags & GC_EVENT_PART ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_6, pDlg->m_iLogFilterFlags & GC_EVENT_TOPIC ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_7, pDlg->m_iLogFilterFlags & GC_EVENT_ADDSTATUS ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_8, pDlg->m_iLogFilterFlags & GC_EVENT_INFORMATION ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_9, pDlg->m_iLogFilterFlags & GC_EVENT_QUIT ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_10, pDlg->m_iLogFilterFlags & GC_EVENT_KICK ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_11, pDlg->m_iLogFilterFlags & GC_EVENT_NOTICE ? BST_CHECKED : BST_UNCHECKED); - break; - - case WM_CTLCOLOREDIT: - case WM_CTLCOLORSTATIC: - SetTextColor((HDC)wParam, RGB(60, 60, 150)); - SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW)); - return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); - - case WM_ACTIVATE: - if (LOWORD(wParam) == WA_INACTIVE) { - int iFlags = 0; - - if (IsDlgButtonChecked(hwndDlg, IDC_1) == BST_CHECKED) - iFlags |= GC_EVENT_ACTION; - if (IsDlgButtonChecked(hwndDlg, IDC_2) == BST_CHECKED) - iFlags |= GC_EVENT_MESSAGE; - if (IsDlgButtonChecked(hwndDlg, IDC_3) == BST_CHECKED) - iFlags |= GC_EVENT_NICK; - if (IsDlgButtonChecked(hwndDlg, IDC_4) == BST_CHECKED) - iFlags |= GC_EVENT_JOIN; - if (IsDlgButtonChecked(hwndDlg, IDC_5) == BST_CHECKED) - iFlags |= GC_EVENT_PART; - if (IsDlgButtonChecked(hwndDlg, IDC_6) == BST_CHECKED) - iFlags |= GC_EVENT_TOPIC; - if (IsDlgButtonChecked(hwndDlg, IDC_7) == BST_CHECKED) - iFlags |= GC_EVENT_ADDSTATUS; - if (IsDlgButtonChecked(hwndDlg, IDC_8) == BST_CHECKED) - iFlags |= GC_EVENT_INFORMATION; - if (IsDlgButtonChecked(hwndDlg, IDC_9) == BST_CHECKED) - iFlags |= GC_EVENT_QUIT; - if (IsDlgButtonChecked(hwndDlg, IDC_10) == BST_CHECKED) - iFlags |= GC_EVENT_KICK; - if (IsDlgButtonChecked(hwndDlg, IDC_11) == BST_CHECKED) - iFlags |= GC_EVENT_NOTICE; - - if (iFlags & GC_EVENT_ADDSTATUS) - iFlags |= GC_EVENT_REMOVESTATUS; - - pDlg->m_iLogFilterFlags = iFlags; - if (pDlg->m_bFilterEnabled) - pDlg->RedrawLog(); - PostMessage(hwndDlg, WM_CLOSE, 0, 0); - } - break; - - case WM_CLOSE: - DestroyWindow(hwndDlg); - break; - } - - return FALSE; -} +/* +Chat module plugin for Miranda IM + +Copyright 2000-12 Miranda IM, 2012-23 Miranda NG team, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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; either version 2 +of the License, or (at your option) any later version. + +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "stdafx.h" + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::LoadSettings() +{ + m_clrInputBG = db_get_dw(0, CHAT_MODULE, "ColorMessageBG", GetSysColor(COLOR_WINDOW)); + LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, nullptr, &m_clrInputFG); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::ShowFilterMenu() +{ + HWND hwnd = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_FILTER), m_hwnd, FilterWndProc, (LPARAM)this); + TranslateDialogDefault(hwnd); + + RECT rc; + GetWindowRect(m_btnFilter.GetHwnd(), &rc); + SetWindowPos(hwnd, HWND_TOP, rc.left - 85, (IsWindowVisible(m_btnFilter.GetHwnd()) || IsWindowVisible(m_btnBold.GetHwnd())) ? rc.top - 206 : rc.top - 186, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); +} + +void CMsgDialog::UpdateNickList() +{ + int i = m_nickList.SendMsg(LB_GETTOPINDEX, 0, 0); + m_nickList.SendMsg(LB_SETCOUNT, m_si->getUserList().getCount(), 0); + m_nickList.SendMsg(LB_SETTOPINDEX, i, 0); + + UpdateTitle(); +} + +void CMsgDialog::UpdateOptions() +{ + m_btnNickList.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(m_bNicklistEnabled ? IDI_NICKLIST2 : IDI_NICKLIST, FALSE)); + m_btnFilter.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(m_bFilterEnabled ? IDI_FILTER2 : IDI_FILTER, FALSE)); + + HICON hIcon = ImageList_GetIcon(Clist_GetImageList(), GetImageId(), ILD_TRANSPARENT); + SendMessage(m_pOwner->m_hwndStatus, SB_SETICON, 0, (LPARAM)hIcon); + DestroyIcon(hIcon); + + Window_SetIcon_IcoLib(m_pOwner->GetHwnd(), g_plugin.getIconHandle(IDI_CHANMGR)); + + m_pLog->UpdateOptions(); + + // nicklist + int ih = Chat_GetTextPixelSize(L"AQGglo", g_Settings.UserListFont, FALSE); + int ih2 = Chat_GetTextPixelSize(L"AQGglo", g_Settings.UserListHeadingsFont, FALSE); + int height = db_get_b(0, CHAT_MODULE, "NicklistRowDist", 12); + int font = ih > ih2 ? ih : ih2; + + // make sure we have space for icon! + if (g_Settings.bShowContactStatus) + font = font > 16 ? font : 16; + + m_nickList.SendMsg(LB_SETITEMHEIGHT, 0, height > font ? height : font); + InvalidateRect(m_nickList.GetHwnd(), nullptr, TRUE); + + CSuper::UpdateOptions(); +} + +void CMsgDialog::UpdateStatusBar() +{ + wchar_t *ptszDispName = m_si->pMI->ptszModDispName; + int x = 12; + x += Chat_GetTextPixelSize(ptszDispName, (HFONT)SendMessage(m_pOwner->m_hwndStatus, WM_GETFONT, 0, 0), TRUE); + x += GetSystemMetrics(SM_CXSMICON); + int iStatusbarParts[2] = { x, -1 }; + SendMessage(m_pOwner->m_hwndStatus, SB_SETPARTS, 2, (LPARAM)&iStatusbarParts); + + HICON hIcon = ImageList_GetIcon(Clist_GetImageList(), GetImageId(), ILD_TRANSPARENT); + SendMessage(m_pOwner->m_hwndStatus, SB_SETICON, 0, (LPARAM)hIcon); + DestroyIcon(hIcon); + + 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"")); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CLogWindow::LogEvents(LOGINFO *lin, bool bRedraw) +{ + auto *si = m_pDlg.m_si; + if (lin == nullptr || si == nullptr) + return; + + if (!bRedraw && si->iType == GCW_CHATROOM && m_pDlg.m_bFilterEnabled && (m_pDlg.m_iLogFilterFlags & lin->iType) == 0) + return; + + LOGSTREAMDATA streamData; + memset(&streamData, 0, sizeof(streamData)); + streamData.hwnd = m_rtf.GetHwnd(); + streamData.si = si; + streamData.lin = lin; + streamData.bStripFormat = FALSE; + + bool bFlag = false; + + EDITSTREAM stream = {}; + stream.pfnCallback = Srmm_LogStreamCallback; + stream.dwCookie = (DWORD_PTR)& streamData; + + SCROLLINFO scroll; + scroll.cbSize = sizeof(SCROLLINFO); + scroll.fMask = SIF_RANGE | SIF_POS | SIF_PAGE; + GetScrollInfo(m_rtf.GetHwnd(), SB_VERT, &scroll); + + POINT point = {}; + m_rtf.SendMsg(EM_GETSCROLLPOS, 0, (LPARAM)&point); + + // do not scroll to bottom if there is a selection + CHARRANGE oldsel, sel; + m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldsel); + if (oldsel.cpMax != oldsel.cpMin) + m_rtf.SetDraw(false); + + //set the insertion point at the bottom + sel.cpMin = sel.cpMax = m_rtf.GetRichTextLength(); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + + // fix for the indent... must be a M$ bug + if (sel.cpMax == 0) + bRedraw = TRUE; + + // should the event(s) be appended to the current log + WPARAM wp = bRedraw ? SF_RTF : SFF_SELECTION | SF_RTF; + + //get the number of pixels per logical inch + if (bRedraw) { + HDC hdc = GetDC(nullptr); + g_chatApi.logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY); + g_chatApi.logPixelSX = GetDeviceCaps(hdc, LOGPIXELSX); + ReleaseDC(nullptr, hdc); + m_rtf.SetDraw(false); + bFlag = true; + } + + // stream in the event(s) + streamData.lin = lin; + streamData.bRedraw = bRedraw; + m_rtf.SendMsg(EM_STREAMIN, wp, (LPARAM)&stream); + + // do smileys + if (g_plugin.bSmileyInstalled && (bRedraw || (lin->ptszText && lin->iType != GC_EVENT_JOIN && lin->iType != GC_EVENT_NICK && lin->iType != GC_EVENT_ADDSTATUS && lin->iType != GC_EVENT_REMOVESTATUS))) { + CHARRANGE newsel; + newsel.cpMax = -1; + newsel.cpMin = sel.cpMin; + if (newsel.cpMin < 0) + newsel.cpMin = 0; + + SMADD_RICHEDIT3 sm = {}; + sm.cbSize = sizeof(sm); + sm.hwndRichEditControl = m_rtf.GetHwnd(); + sm.Protocolname = si->pszModule; + sm.rangeToReplace = bRedraw ? nullptr : &newsel; + sm.disableRedraw = TRUE; + sm.hContact = si->hContact; + CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM)&sm); + } + + // scroll log to bottom if the log was previously scrolled to bottom, else restore old position + if (bRedraw || (UINT)scroll.nPos >= (UINT)scroll.nMax - scroll.nPage - 5 || scroll.nMax - scroll.nMin - scroll.nPage < 50) + ScrollToBottom(); + else + m_rtf.SendMsg(EM_SETSCROLLPOS, 0, (LPARAM)&point); + + // do we need to restore the selection + if (oldsel.cpMax != oldsel.cpMin) { + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&oldsel); + m_rtf.SetDraw(true); + InvalidateRect(m_rtf.GetHwnd(), nullptr, TRUE); + } + + // need to invalidate the window + if (bFlag) { + sel.cpMin = sel.cpMax = m_rtf.GetRichTextLength(); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + m_rtf.SetDraw(true); + InvalidateRect(m_rtf.GetHwnd(), nullptr, TRUE); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +INT_PTR CALLBACK CMsgDialog::FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + static CMsgDialog *pDlg = nullptr; + switch (uMsg) { + case WM_INITDIALOG: + pDlg = (CMsgDialog*)lParam; + CheckDlgButton(hwndDlg, IDC_1, pDlg->m_iLogFilterFlags & GC_EVENT_ACTION ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_2, pDlg->m_iLogFilterFlags & GC_EVENT_MESSAGE ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_3, pDlg->m_iLogFilterFlags & GC_EVENT_NICK ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_4, pDlg->m_iLogFilterFlags & GC_EVENT_JOIN ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_5, pDlg->m_iLogFilterFlags & GC_EVENT_PART ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_6, pDlg->m_iLogFilterFlags & GC_EVENT_TOPIC ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_7, pDlg->m_iLogFilterFlags & GC_EVENT_ADDSTATUS ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_8, pDlg->m_iLogFilterFlags & GC_EVENT_INFORMATION ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_9, pDlg->m_iLogFilterFlags & GC_EVENT_QUIT ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_10, pDlg->m_iLogFilterFlags & GC_EVENT_KICK ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_11, pDlg->m_iLogFilterFlags & GC_EVENT_NOTICE ? BST_CHECKED : BST_UNCHECKED); + break; + + case WM_CTLCOLOREDIT: + case WM_CTLCOLORSTATIC: + SetTextColor((HDC)wParam, RGB(60, 60, 150)); + SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW)); + return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); + + case WM_ACTIVATE: + if (LOWORD(wParam) == WA_INACTIVE) { + int iFlags = 0; + + if (IsDlgButtonChecked(hwndDlg, IDC_1) == BST_CHECKED) + iFlags |= GC_EVENT_ACTION; + if (IsDlgButtonChecked(hwndDlg, IDC_2) == BST_CHECKED) + iFlags |= GC_EVENT_MESSAGE; + if (IsDlgButtonChecked(hwndDlg, IDC_3) == BST_CHECKED) + iFlags |= GC_EVENT_NICK; + if (IsDlgButtonChecked(hwndDlg, IDC_4) == BST_CHECKED) + iFlags |= GC_EVENT_JOIN; + if (IsDlgButtonChecked(hwndDlg, IDC_5) == BST_CHECKED) + iFlags |= GC_EVENT_PART; + if (IsDlgButtonChecked(hwndDlg, IDC_6) == BST_CHECKED) + iFlags |= GC_EVENT_TOPIC; + if (IsDlgButtonChecked(hwndDlg, IDC_7) == BST_CHECKED) + iFlags |= GC_EVENT_ADDSTATUS; + if (IsDlgButtonChecked(hwndDlg, IDC_8) == BST_CHECKED) + iFlags |= GC_EVENT_INFORMATION; + if (IsDlgButtonChecked(hwndDlg, IDC_9) == BST_CHECKED) + iFlags |= GC_EVENT_QUIT; + if (IsDlgButtonChecked(hwndDlg, IDC_10) == BST_CHECKED) + iFlags |= GC_EVENT_KICK; + if (IsDlgButtonChecked(hwndDlg, IDC_11) == BST_CHECKED) + iFlags |= GC_EVENT_NOTICE; + + if (iFlags & GC_EVENT_ADDSTATUS) + iFlags |= GC_EVENT_REMOVESTATUS; + + pDlg->m_iLogFilterFlags = iFlags; + if (pDlg->m_bFilterEnabled) + pDlg->RedrawLog(); + PostMessage(hwndDlg, WM_CLOSE, 0, 0); + } + break; + + case WM_CLOSE: + DestroyWindow(hwndDlg); + break; + } + + return FALSE; +} diff --git a/src/core/stdmsg/src/cmdlist.cpp b/src/core/stdmsg/src/cmdlist.cpp index beb669dcf5..1ace5b0545 100644 --- a/src/core/stdmsg/src/cmdlist.cpp +++ b/src/core/stdmsg/src/cmdlist.cpp @@ -1,6 +1,6 @@ /* -Copyright 2000-12 Miranda IM, 2012-22 Miranda NG team, +Copyright 2000-12 Miranda IM, 2012-23 Miranda NG team, all portions of this codebase are copyrighted to the people listed in contributors.txt. diff --git a/src/core/stdmsg/src/cmdlist.h b/src/core/stdmsg/src/cmdlist.h index bbe8c9b11b..fda5562689 100644 --- a/src/core/stdmsg/src/cmdlist.h +++ b/src/core/stdmsg/src/cmdlist.h @@ -1,6 +1,6 @@ /* -Copyright 2000-12 Miranda IM, 2012-22 Miranda NG team, +Copyright 2000-12 Miranda IM, 2012-23 Miranda NG team, all portions of this codebase are copyrighted to the people listed in contributors.txt. diff --git a/src/core/stdmsg/src/globals.cpp b/src/core/stdmsg/src/globals.cpp index de2ca11c6d..5d2b95cc46 100644 --- a/src/core/stdmsg/src/globals.cpp +++ b/src/core/stdmsg/src/globals.cpp @@ -1,6 +1,6 @@ /* -Copyright 2000-12 Miranda IM, 2012-22 Miranda NG team, +Copyright 2000-12 Miranda IM, 2012-23 Miranda NG team, all portions of this codebase are copyrighted to the people listed in contributors.txt. diff --git a/src/core/stdmsg/src/msgdialog.cpp b/src/core/stdmsg/src/msgdialog.cpp index 8e0c4ff3ed..359b308022 100644 --- a/src/core/stdmsg/src/msgdialog.cpp +++ b/src/core/stdmsg/src/msgdialog.cpp @@ -1,6 +1,6 @@ /* -Copyright 2000-12 Miranda IM, 2012-22 Miranda NG team, +Copyright 2000-12 Miranda IM, 2012-23 Miranda NG team, all portions of this codebase are copyrighted to the people listed in contributors.txt. diff --git a/src/core/stdmsg/src/msglog.cpp b/src/core/stdmsg/src/msglog.cpp index 8fb1f5edbd..791cd1b71e 100644 --- a/src/core/stdmsg/src/msglog.cpp +++ b/src/core/stdmsg/src/msglog.cpp @@ -1,6 +1,6 @@ /* -Copyright 2000-12 Miranda IM, 2012-22 Miranda NG team, +Copyright 2000-12 Miranda IM, 2012-23 Miranda NG team, all portions of this codebase are copyrighted to the people listed in contributors.txt. diff --git a/src/core/stdmsg/src/msgoptions.cpp b/src/core/stdmsg/src/msgoptions.cpp index 590afa2478..34dc8e044f 100644 --- a/src/core/stdmsg/src/msgoptions.cpp +++ b/src/core/stdmsg/src/msgoptions.cpp @@ -1,6 +1,6 @@ /* -Copyright 2000-12 Miranda IM, 2012-22 Miranda NG team, +Copyright 2000-12 Miranda IM, 2012-23 Miranda NG team, all portions of this codebase are copyrighted to the people listed in contributors.txt. diff --git a/src/core/stdmsg/src/msgs.cpp b/src/core/stdmsg/src/msgs.cpp index 95b209fd02..9f5be7be28 100644 --- a/src/core/stdmsg/src/msgs.cpp +++ b/src/core/stdmsg/src/msgs.cpp @@ -1,6 +1,6 @@ /* -Copyright 2000-12 Miranda IM, 2012-22 Miranda NG team, +Copyright 2000-12 Miranda IM, 2012-23 Miranda NG team, all portions of this codebase are copyrighted to the people listed in contributors.txt. diff --git a/src/core/stdmsg/src/msgs.h b/src/core/stdmsg/src/msgs.h index f21110e641..0e9f38dead 100644 --- a/src/core/stdmsg/src/msgs.h +++ b/src/core/stdmsg/src/msgs.h @@ -1,6 +1,6 @@ /* -Copyright 2000-12 Miranda IM, 2012-22 Miranda NG team, +Copyright 2000-12 Miranda IM, 2012-23 Miranda NG team, all portions of this codebase are copyrighted to the people listed in contributors.txt. diff --git a/src/core/stdmsg/src/msgtimedout.cpp b/src/core/stdmsg/src/msgtimedout.cpp index 19744fe695..828924580e 100644 --- a/src/core/stdmsg/src/msgtimedout.cpp +++ b/src/core/stdmsg/src/msgtimedout.cpp @@ -1,6 +1,6 @@ /* -Copyright 2000-12 Miranda IM, 2012-22 Miranda NG team, +Copyright 2000-12 Miranda IM, 2012-23 Miranda NG team, all portions of this codebase are copyrighted to the people listed in contributors.txt. diff --git a/src/core/stdmsg/src/srmm.cpp b/src/core/stdmsg/src/srmm.cpp index 69c350aad7..4485d40bb3 100644 --- a/src/core/stdmsg/src/srmm.cpp +++ b/src/core/stdmsg/src/srmm.cpp @@ -1,6 +1,6 @@ /* -Copyright 2000-12 Miranda IM, 2012-22 Miranda NG team, +Copyright 2000-12 Miranda IM, 2012-23 Miranda NG team, all portions of this codebase are copyrighted to the people listed in contributors.txt. diff --git a/src/core/stdmsg/src/statusicon.cpp b/src/core/stdmsg/src/statusicon.cpp index 4244f9037c..6255dc3e1e 100644 --- a/src/core/stdmsg/src/statusicon.cpp +++ b/src/core/stdmsg/src/statusicon.cpp @@ -1,6 +1,6 @@ /* -Copyright 2000-12 Miranda IM, 2012-22 Miranda NG team, +Copyright 2000-12 Miranda IM, 2012-23 Miranda NG team, all portions of this codebase are copyrighted to the people listed in contributors.txt. diff --git a/src/core/stdmsg/src/stdafx.cxx b/src/core/stdmsg/src/stdafx.cxx index 52ec2d6817..e23069a5b8 100644 --- a/src/core/stdmsg/src/stdafx.cxx +++ b/src/core/stdmsg/src/stdafx.cxx @@ -1,6 +1,6 @@ /* -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) +Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/src/core/stdmsg/src/stdafx.h b/src/core/stdmsg/src/stdafx.h index a42feafac9..33d557a6a9 100644 --- a/src/core/stdmsg/src/stdafx.h +++ b/src/core/stdmsg/src/stdafx.h @@ -1,6 +1,6 @@ /* -Copyright 2000-12 Miranda IM, 2012-22 Miranda NG team, +Copyright 2000-12 Miranda IM, 2012-23 Miranda NG team, all portions of this codebase are copyrighted to the people listed in contributors.txt. diff --git a/src/core/stdmsg/src/tabs.cpp b/src/core/stdmsg/src/tabs.cpp index d60bec7634..402d1f2f0f 100644 --- a/src/core/stdmsg/src/tabs.cpp +++ b/src/core/stdmsg/src/tabs.cpp @@ -1,668 +1,668 @@ -/* - -Copyright 2000-12 Miranda IM, 2012-22 Miranda NG team, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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; either version 2 -of the License, or (at your option) any later version. - -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, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "stdafx.h" -#include "statusicon.h" - -CTabbedWindow *g_pTabDialog = nullptr; - -///////////////////////////////////////////////////////////////////////////////////////// - -CTabbedWindow* GetContainer() -{ - if (g_Settings.bTabsEnable) { - if (g_pTabDialog == nullptr) { - g_pTabDialog = new CTabbedWindow(); - g_pTabDialog->Show(); - } - return g_pTabDialog; - } - - return new CTabbedWindow(); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static LRESULT CALLBACK TabSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - CTabbedWindow *pOwner = (CTabbedWindow*)GetWindowLongPtr(hwnd, GWLP_USERDATA); - TCHITTESTINFO tci = {}; - - static bool bDragging = false; - static int iBeginIndex = 0; - switch (msg) { - case WM_LBUTTONDOWN: - tci.pt.x = (short)LOWORD(GetMessagePos()); - tci.pt.y = (short)HIWORD(GetMessagePos()); - if (DragDetect(hwnd, tci.pt) && TabCtrl_GetItemCount(hwnd) > 1) { - tci.flags = TCHT_ONITEM; - ScreenToClient(hwnd, &tci.pt); - int idx = TabCtrl_HitTest(hwnd, &tci); - if (idx != -1) { - CMsgDialog *pDlg = (CMsgDialog*)pOwner->m_tab.GetNthPage(idx); - if (pDlg) { - bDragging = true; - iBeginIndex = idx; - ImageList_BeginDrag(Clist_GetImageList(), pDlg->GetImageId(), 8, 8); - ImageList_DragEnter(hwnd, tci.pt.x, tci.pt.y); - SetCapture(hwnd); - } - return TRUE; - } - } - else pOwner->TabClicked(); - break; - - case WM_CAPTURECHANGED: - bDragging = false; - ImageList_DragLeave(hwnd); - ImageList_EndDrag(); - break; - - case WM_MOUSEMOVE: - if (bDragging) { - tci.pt.x = (short)LOWORD(GetMessagePos()); - tci.pt.y = (short)HIWORD(GetMessagePos()); - ScreenToClient(hwnd, &tci.pt); - ImageList_DragMove(tci.pt.x, tci.pt.y); - } - break; - - case WM_LBUTTONUP: - if (bDragging && ReleaseCapture()) { - tci.pt.x = (short)LOWORD(GetMessagePos()); - tci.pt.y = (short)HIWORD(GetMessagePos()); - tci.flags = TCHT_ONITEM; - bDragging = false; - ImageList_DragLeave(hwnd); - ImageList_EndDrag(); - - ScreenToClient(hwnd, &tci.pt); - int idx = TabCtrl_HitTest(hwnd, &tci); - if (idx != -1 && idx != iBeginIndex) - pOwner->DropTab(idx, iBeginIndex); - } - break; - - case WM_LBUTTONDBLCLK: - if (g_Settings.bTabCloseOnDblClick) { - tci.pt.x = (short)LOWORD(GetMessagePos()); - tci.pt.y = (short)HIWORD(GetMessagePos()); - ScreenToClient(hwnd, &tci.pt); - - tci.flags = TCHT_ONITEM; - int idx = TabCtrl_HitTest(hwnd, &tci); - if (idx != -1) { - CMsgDialog *pDlg = (CMsgDialog*)pOwner->m_tab.GetNthPage(idx); - if (pDlg) - pDlg->CloseTab(); - } - } - break; - - case WM_MBUTTONUP: - tci.pt.x = (short)LOWORD(GetMessagePos()); - tci.pt.y = (short)HIWORD(GetMessagePos()); - tci.flags = TCHT_ONITEM; - - ScreenToClient(hwnd, &tci.pt); - int idx = TabCtrl_HitTest(hwnd, &tci); - if (idx != -1) { - CMsgDialog *pDlg = (CMsgDialog*)pOwner->m_tab.GetNthPage(idx); - if (pDlg) - pDlg->CloseTab(); - } - break; - } - - return mir_callNextSubclass(hwnd, TabSubclassProc, msg, wParam, lParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -CTabbedWindow::CTabbedWindow() : - CDlgBase(g_plugin, IDD_CONTAINER), - m_tab(this, IDC_TAB) -{ - SetMinSize(450, 350); -} - -bool CTabbedWindow::OnInitDialog() -{ - SetWindowLongPtr(m_tab.GetHwnd(), GWLP_USERDATA, LPARAM(this)); - mir_subclassWindow(m_tab.GetHwnd(), ::TabSubclassProc); - - m_hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, nullptr, WS_CHILD | WS_VISIBLE | SBT_TOOLTIPS | SBARS_SIZEGRIP, 0, 0, 0, 0, m_hwnd, nullptr, g_plugin.getInst(), nullptr); - SendMessage(m_hwndStatus, SB_SETMINHEIGHT, GetSystemMetrics(SM_CYSMICON), 0); - - RECT rc; - GetWindowRect(m_hwndStatus, &rc); - m_statusHeight = rc.bottom - rc.top; - - SetWindowPosition(); - - if (!g_Settings.bTabsEnable) { - m_tab.Hide(); - return false; - } - - LONG_PTR mask = GetWindowLongPtr(m_tab.GetHwnd(), GWL_STYLE); - if (g_Settings.bTabsAtBottom) - mask |= TCS_BOTTOM; - else - mask &= ~TCS_BOTTOM; - SetWindowLongPtr(m_tab.GetHwnd(), GWL_STYLE, mask); - - TabCtrl_SetMinTabWidth(m_tab.GetHwnd(), 80); - TabCtrl_SetImageList(m_tab.GetHwnd(), Clist_GetImageList()); - return true; -} - -void CTabbedWindow::OnDestroy() -{ - DestroyWindow(m_hwndStatus); m_hwndStatus = nullptr; - - SaveWindowPosition(true); - - Utils_SaveWindowPosition(m_hwnd, g_plugin.bSavePerContact ? ((m_pEmbed == nullptr) ? 0 : m_pEmbed->m_hContact) : 0, CHAT_MODULE, "room"); - - if (m_pEmbed == nullptr) - g_pTabDialog = nullptr; -} - -void CTabbedWindow::OnResize() -{ - CDlgBase::OnResize(); - - SendMessage(m_hwndStatus, WM_SIZE, 0, 0); - - if (m_pEmbed) { - RECT rc; - GetClientRect(m_tab.GetHwnd(), &rc); - MoveWindow(m_pEmbed->GetHwnd(), 0, 0, rc.right - rc.left, rc.bottom - rc.top, FALSE); - } - - SaveWindowPosition(false); -} - -int CTabbedWindow::Resizer(UTILRESIZECONTROL *urc) -{ - if (urc->wId == IDC_TAB) { - urc->rcItem.top = 1; - urc->rcItem.bottom = urc->dlgNewSize.cy - m_statusHeight - 1; - return RD_ANCHORX_WIDTH | RD_ANCHORY_CUSTOM; - } - - return RD_ANCHORX_WIDTH | RD_ANCHORY_BOTTOM; // status bar -} - -///////////////////////////////////////////////////////////////////////////////////////// - -CTabbedWindow* CTabbedWindow::AddPage(MCONTACT hContact, wchar_t *pwszText, int iNoActivate) -{ - CMsgDialog *pDlg = new CMsgDialog(this, hContact); - pDlg->m_wszInitialText = pwszText; - if (iNoActivate != -1) - pDlg->m_bNoActivate = iNoActivate != 0; - - if (g_Settings.bTabsEnable) { - m_tab.AddPage(Clist_GetContactDisplayName(hContact), nullptr, pDlg); - FixTabIcons(pDlg); - - m_tab.ActivatePage(m_tab.GetCount() - 1); - } - else { - m_pEmbed = pDlg; - Create(); - pDlg->SetParent(m_hwnd); - pDlg->Create(); - Show(); - } - - PostMessage(m_hwnd, WM_SIZE, 0, 0); - return this; -} - -void CTabbedWindow::AddPage(SESSION_INFO *si, int insertAt) -{ - // does the tab already exist? - int indexfound = (si->pDlg) ? m_tab.GetDlgIndex(si->pDlg) : -1; - if (indexfound == -1) { // create a new tab - wchar_t szTemp[30]; - mir_wstrncpy(szTemp, si->ptszName, 21); - if (mir_wstrlen(si->ptszName) > 20) - mir_wstrncpy(szTemp + 20, L"...", 4); - - if (!IsWindowVisible(m_hwnd)) - Show(SW_SHOW); - - CMsgDialog *pDlg = new CMsgDialog(this, si); - pDlg->SetParent(m_hwnd); - m_tab.AddPage(szTemp, nullptr, pDlg); - m_tab.ActivatePage(m_tab.GetCount() - 1); - FixTabIcons(pDlg); - } - else if (insertAt == -1) - m_tab.ActivatePage(indexfound); -} - -CMsgDialog* CTabbedWindow::CurrPage() const -{ - return (m_pEmbed != nullptr) ? m_pEmbed : (CMsgDialog*)m_tab.GetActivePage(); -} - -void CTabbedWindow::DropTab(int begin, int end) -{ - if (begin == end) - return; - - m_tab.SwapPages(begin, end); - - CMsgDialog *pDlg = (CMsgDialog *)m_tab.GetNthPage(end); - if (pDlg) { - FixTabIcons(pDlg); - m_tab.ActivatePage(end); - } - - // fix the "fixed" positions - int tabCount = m_tab.GetCount(); - for (int i = 0; i < tabCount; i++) { - pDlg = (CMsgDialog *)m_tab.GetNthPage(i); - if (pDlg == nullptr) - continue; - - SESSION_INFO *si = pDlg->m_si; - if (si && si->hContact && db_get_w(si->hContact, si->pszModule, "TabPosition", 0) != 0) - db_set_w(si->hContact, si->pszModule, "TabPosition", i + 1); - } -} - -void CTabbedWindow::FixTabIcons(CMsgDialog *pDlg) -{ - if (pDlg == nullptr) - return; - - int image = pDlg->GetImageId(); - - // if tabs are turned off, simply change the window's icon, otherwise set the tab's icon first - if (m_pEmbed == nullptr) { - 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); - } - } - - // set the container's icon only if we're processing the current page - if (pDlg == CurrPage()) { - Window_FreeIcon_IcoLib(m_hwnd); - if (g_plugin.bUseStatusWinIcon) - Window_SetProtoIcon_IcoLib(m_hwnd, pDlg->m_szProto, pDlg->m_wStatus); - else if (pDlg->isChat()) - Window_SetIcon_IcoLib(m_hwnd, g_plugin.getIconHandle(IDI_CHANMGR)); - else - Window_SetSkinIcon_IcoLib(m_hwnd, SKINICON_EVENT_MESSAGE); - } -} - -void CTabbedWindow::RemoveTab(CMsgDialog *pDlg) -{ - int idx = m_tab.GetDlgIndex(pDlg); - if (idx == -1) - return; - - m_tab.RemovePage(idx); - if (m_tab.GetCount() == 0) - PostMessage(m_hwnd, WM_CLOSE, 0, 0); - else { - if (m_tab.GetNthPage(idx) == nullptr) - idx--; - m_tab.ActivatePage(idx); - } -} - -void CTabbedWindow::SaveWindowPosition(bool bUpdateSession) -{ - WINDOWPLACEMENT wp = {}; - wp.length = sizeof(wp); - GetWindowPlacement(m_hwnd, &wp); - - g_Settings.iX = wp.rcNormalPosition.left; - g_Settings.iY = wp.rcNormalPosition.top; - g_Settings.iWidth = wp.rcNormalPosition.right - wp.rcNormalPosition.left; - g_Settings.iHeight = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; - - if (bUpdateSession) { - iX = g_Settings.iX; - iY = g_Settings.iY; - iWidth = g_Settings.iWidth; - iHeight = g_Settings.iHeight; - } -} - -void CTabbedWindow::SetMessageHighlight(CMsgDialog *pDlg) -{ - if (m_tab.GetDlgIndex(pDlg) == -1) - return; - - pDlg->m_si->wState |= GC_EVENT_HIGHLIGHT; - FixTabIcons(pDlg); - if (Chat::bFlashWindowHighlight && pDlg != m_tab.GetActivePage()) - pDlg->StartFlash(); -} - -void CTabbedWindow::SetTabHighlight(CMsgDialog *pDlg) -{ - if (m_tab.GetDlgIndex(pDlg) == -1) - return; - - FixTabIcons(pDlg); - if (Chat::bFlashWindow && pDlg != m_tab.GetActivePage()) - pDlg->StartFlash(); -} - -void CTabbedWindow::SetWindowPosition() -{ - if (m_pEmbed == nullptr) { - Utils_RestoreWindowPosition(m_hwnd, 0, CHAT_MODULE, "room"); - return; - } - - if (iX) { - WINDOWPLACEMENT wp; - wp.length = sizeof(wp); - GetWindowPlacement(m_hwnd, &wp); - - wp.rcNormalPosition.left = iX; - wp.rcNormalPosition.top = iY; - wp.rcNormalPosition.right = wp.rcNormalPosition.left + iWidth; - wp.rcNormalPosition.bottom = wp.rcNormalPosition.top + iHeight; - wp.showCmd = SW_HIDE; - SetWindowPlacement(m_hwnd, &wp); - return; - } - - int flag = m_pEmbed->m_bNoActivate ? RWPF_HIDDEN : 0; - if (Utils_RestoreWindowPosition(m_hwnd, g_plugin.bSavePerContact ? m_pEmbed->m_hContact : 0, CHAT_MODULE, "room", flag)) { - if (g_plugin.bSavePerContact) { - if (Utils_RestoreWindowPosition(m_hwnd, 0, CHAT_MODULE, "room", flag | RWPF_NOMOVE)) - SetWindowPos(m_hwnd, nullptr, 0, 0, 550, 400, SWP_NOZORDER | SWP_NOMOVE | SWP_SHOWWINDOW); - } - else SetWindowPos(m_hwnd, nullptr, 0, 0, 550, 400, SWP_NOZORDER | SWP_NOMOVE | SWP_SHOWWINDOW); - } - - if (!g_plugin.bSavePerContact && g_plugin.bCascade) { - RECT rc, rcMax = {}; - CTabbedWindow *pMaxTab = nullptr; - - for (auto &it : g_arDialogs) { - auto *pTab = it->m_pOwner; - if (pTab == this) - continue; - - GetWindowRect(pTab->GetHwnd(), &rc); - if (rc.left > rcMax.left && rc.top > rcMax.top) { - pMaxTab = pTab; - rcMax = rc; - } - } - - if (pMaxTab) { - m_windowWasCascaded = 1; - int offset = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME); - SetWindowPos(m_hwnd, nullptr, rcMax.left + offset, rcMax.top + offset, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE); - } - } -} - -void CTabbedWindow::SwitchNextTab() -{ - int total = m_tab.GetCount(); - int i = TabCtrl_GetCurSel(m_tab.GetHwnd()); - if (i != -1 && total > 1) { - if (i < total - 1) - i++; - else - i = 0; - m_tab.ActivatePage(i); - TabClicked(); - } -} - -void CTabbedWindow::SwitchPrevTab() -{ - int total = m_tab.GetCount(); - int i = TabCtrl_GetCurSel(m_tab.GetHwnd()); - if (i != -1 && total >= 1) { - if (i > 0) - i--; - else - i = total - 1; - m_tab.ActivatePage(i); - TabClicked(); - } -} - -void CTabbedWindow::SwitchTab(int iNewTab) -{ - int total = m_tab.GetCount(); - int i = TabCtrl_GetCurSel(m_tab.GetHwnd()); - if (i != -1 && total != -1 && total != 1 && i != iNewTab && total > iNewTab) { - m_tab.ActivatePage(iNewTab); - TabClicked(); - } -} - -void CTabbedWindow::TabClicked() -{ - CMsgDialog *pDlg = (CMsgDialog*)m_tab.GetActivePage(); - if (pDlg == nullptr) - return; - - SetFocus(pDlg->m_message.GetHwnd()); - - SESSION_INFO *si = pDlg->m_si; - if (si) { - if (si->wState & STATE_TALK) { - si->wState &= ~STATE_TALK; - db_set_w(si->hContact, si->pszModule, "ApparentMode", 0); - } - - if (si->wState & GC_EVENT_HIGHLIGHT) { - si->wState &= ~GC_EVENT_HIGHLIGHT; - - if (g_clistApi.pfnGetEvent(si->hContact, 0)) - g_clistApi.pfnRemoveEvent(si->hContact, GC_FAKE_EVENT); - } - - if (!si->pDlg) { - g_chatApi.ShowRoom(si); - SendMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); - } - } - - FixTabIcons(pDlg); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -INT_PTR CTabbedWindow::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) -{ - RECT rc; - int idx; - - switch (msg) { - case WM_MOVE: - SaveWindowPosition(false); - break; - - case WM_ENTERSIZEMOVE: - GetClientRect(m_hwnd, &rc); - oldSizeX = rc.right - rc.left; - oldSizeY = rc.bottom - rc.top; - break; - - case WM_EXITSIZEMOVE: - GetClientRect(m_hwnd, &rc); - if (!((rc.right - rc.left) == oldSizeX && (rc.bottom - rc.top) == oldSizeY)) { - CMsgDialog *pDlg = (g_Settings.bTabsEnable) ? (CMsgDialog*)m_tab.GetActivePage() : m_pEmbed; - if (pDlg != nullptr) { - pDlg->m_pLog->ScrollToBottom(); - pDlg->Resize(); - } - } - break; - - case WM_DRAWITEM: - { - LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lParam; - if (dis->hwndItem == m_hwndStatus) { - CMsgDialog *pDlg = (g_Settings.bTabsEnable) ? (CMsgDialog*)m_tab.GetActivePage() : m_pEmbed; - if (pDlg != nullptr) - DrawStatusIcons(pDlg->m_hContact, dis->hDC, dis->rcItem, 2); - return TRUE; - } - } - break; - - case WM_COMMAND: - if (LOWORD(wParam) == IDOK) { - CMsgDialog *pDlg = (g_Settings.bTabsEnable) ? (CMsgDialog*)m_tab.GetActivePage() : m_pEmbed; - if (pDlg != nullptr) { - pDlg->m_btnOk.Click(); - return TRUE; - } - } - break; - - case WM_ACTIVATE: - if (LOWORD(wParam) == WA_INACTIVE) - break; - - if (!m_pEmbed) { - idx = TabCtrl_GetCurSel(m_tab.GetHwnd()); - if (idx != -1) - m_tab.ActivatePage(idx); - } - else m_pEmbed->OnActivate(); - break; - - case WM_NOTIFY: - if (((LPNMHDR)lParam)->hwndFrom == m_hwndStatus) { - if (((LPNMHDR)lParam)->code == NM_CLICK || ((LPNMHDR)lParam)->code == NM_RCLICK) { - NMMOUSE *nm = (NMMOUSE *)lParam; - SendMessage(m_hwndStatus, SB_GETRECT, SendMessage(m_hwndStatus, SB_GETPARTS, 0, 0) - 1, (LPARAM)&rc); - if (nm->pt.x >= rc.left) { - CMsgDialog *pDlg = (g_Settings.bTabsEnable) ? (CMsgDialog*)m_tab.GetActivePage() : m_pEmbed; - if (pDlg != nullptr) - CheckStatusIconClick(pDlg->m_hContact, m_hwndStatus, nm->pt, rc, 2, ((LPNMHDR)lParam)->code == NM_RCLICK ? MBCF_RIGHTBUTTON : 0); - } - return TRUE; - } - } - - if (((LPNMHDR)lParam)->idFrom == IDC_TAB) { - switch (((LPNMHDR)lParam)->code) { - case TCN_SELCHANGE: - m_tab.ActivatePage(TabCtrl_GetCurSel(m_tab.GetHwnd())); - break; - - case NM_RCLICK: - int i = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom); - if (i == -1) - break; - - TCHITTESTINFO tci = {}; - tci.pt.x = (short)LOWORD(GetMessagePos()); - tci.pt.y = (short)HIWORD(GetMessagePos()); - tci.flags = TCHT_ONITEM; - ScreenToClient(GetDlgItem(m_hwnd, IDC_TAB), &tci.pt); - if ((i = TabCtrl_HitTest(((LPNMHDR)lParam)->hwndFrom, &tci)) == -1) - break; - - CMsgDialog *pDlg = (CMsgDialog*)m_tab.GetNthPage(i); - SESSION_INFO *si = pDlg->m_si; - - ClientToScreen(GetDlgItem(m_hwnd, IDC_TAB), &tci.pt); - HMENU hSubMenu = GetSubMenu(g_hMenu, 1); - TranslateMenu(hSubMenu); - - if (si != nullptr) { - uint16_t w = db_get_w(si->hContact, si->pszModule, "TabPosition", 0); - if (w == 0) - CheckMenuItem(hSubMenu, ID_LOCKPOSITION, MF_BYCOMMAND | MF_UNCHECKED); - else - CheckMenuItem(hSubMenu, ID_LOCKPOSITION, MF_BYCOMMAND | MF_CHECKED); - } - else CheckMenuItem(hSubMenu, ID_LOCKPOSITION, MF_BYCOMMAND | MF_UNCHECKED); - - switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, tci.pt.x, tci.pt.y, 0, m_hwnd, nullptr)) { - case ID_CLOSE: - pDlg->CloseTab(); - break; - - case ID_LOCKPOSITION: - if (si != nullptr) { - if (!(GetMenuState(hSubMenu, ID_LOCKPOSITION, MF_BYCOMMAND)&MF_CHECKED)) { - if (si->hContact) - db_set_w(si->hContact, si->pszModule, "TabPosition", (uint16_t)(i + 1)); - } - else db_unset(si->hContact, si->pszModule, "TabPosition"); - } - break; - - case ID_CLOSEOTHER: - int tabCount = m_tab.GetCount(); - if (tabCount > 1) { - while (tabCount--) { - if (tabCount == i) - continue; - - if (pDlg = (CMsgDialog*)m_tab.GetNthPage(tabCount)) - pDlg->CloseTab(); - } - m_tab.ActivatePage(0); - } - break; - } - } - } - break; - } - - return CDlgBase::DlgProc(msg, wParam, lParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void UninitTabs() -{ - if (g_pTabDialog != nullptr) { - g_pTabDialog->Close(); - g_pTabDialog = nullptr; - } -} +/* + +Copyright 2000-12 Miranda IM, 2012-23 Miranda NG team, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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; either version 2 +of the License, or (at your option) any later version. + +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "stdafx.h" +#include "statusicon.h" + +CTabbedWindow *g_pTabDialog = nullptr; + +///////////////////////////////////////////////////////////////////////////////////////// + +CTabbedWindow* GetContainer() +{ + if (g_Settings.bTabsEnable) { + if (g_pTabDialog == nullptr) { + g_pTabDialog = new CTabbedWindow(); + g_pTabDialog->Show(); + } + return g_pTabDialog; + } + + return new CTabbedWindow(); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static LRESULT CALLBACK TabSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + CTabbedWindow *pOwner = (CTabbedWindow*)GetWindowLongPtr(hwnd, GWLP_USERDATA); + TCHITTESTINFO tci = {}; + + static bool bDragging = false; + static int iBeginIndex = 0; + switch (msg) { + case WM_LBUTTONDOWN: + tci.pt.x = (short)LOWORD(GetMessagePos()); + tci.pt.y = (short)HIWORD(GetMessagePos()); + if (DragDetect(hwnd, tci.pt) && TabCtrl_GetItemCount(hwnd) > 1) { + tci.flags = TCHT_ONITEM; + ScreenToClient(hwnd, &tci.pt); + int idx = TabCtrl_HitTest(hwnd, &tci); + if (idx != -1) { + CMsgDialog *pDlg = (CMsgDialog*)pOwner->m_tab.GetNthPage(idx); + if (pDlg) { + bDragging = true; + iBeginIndex = idx; + ImageList_BeginDrag(Clist_GetImageList(), pDlg->GetImageId(), 8, 8); + ImageList_DragEnter(hwnd, tci.pt.x, tci.pt.y); + SetCapture(hwnd); + } + return TRUE; + } + } + else pOwner->TabClicked(); + break; + + case WM_CAPTURECHANGED: + bDragging = false; + ImageList_DragLeave(hwnd); + ImageList_EndDrag(); + break; + + case WM_MOUSEMOVE: + if (bDragging) { + tci.pt.x = (short)LOWORD(GetMessagePos()); + tci.pt.y = (short)HIWORD(GetMessagePos()); + ScreenToClient(hwnd, &tci.pt); + ImageList_DragMove(tci.pt.x, tci.pt.y); + } + break; + + case WM_LBUTTONUP: + if (bDragging && ReleaseCapture()) { + tci.pt.x = (short)LOWORD(GetMessagePos()); + tci.pt.y = (short)HIWORD(GetMessagePos()); + tci.flags = TCHT_ONITEM; + bDragging = false; + ImageList_DragLeave(hwnd); + ImageList_EndDrag(); + + ScreenToClient(hwnd, &tci.pt); + int idx = TabCtrl_HitTest(hwnd, &tci); + if (idx != -1 && idx != iBeginIndex) + pOwner->DropTab(idx, iBeginIndex); + } + break; + + case WM_LBUTTONDBLCLK: + if (g_Settings.bTabCloseOnDblClick) { + tci.pt.x = (short)LOWORD(GetMessagePos()); + tci.pt.y = (short)HIWORD(GetMessagePos()); + ScreenToClient(hwnd, &tci.pt); + + tci.flags = TCHT_ONITEM; + int idx = TabCtrl_HitTest(hwnd, &tci); + if (idx != -1) { + CMsgDialog *pDlg = (CMsgDialog*)pOwner->m_tab.GetNthPage(idx); + if (pDlg) + pDlg->CloseTab(); + } + } + break; + + case WM_MBUTTONUP: + tci.pt.x = (short)LOWORD(GetMessagePos()); + tci.pt.y = (short)HIWORD(GetMessagePos()); + tci.flags = TCHT_ONITEM; + + ScreenToClient(hwnd, &tci.pt); + int idx = TabCtrl_HitTest(hwnd, &tci); + if (idx != -1) { + CMsgDialog *pDlg = (CMsgDialog*)pOwner->m_tab.GetNthPage(idx); + if (pDlg) + pDlg->CloseTab(); + } + break; + } + + return mir_callNextSubclass(hwnd, TabSubclassProc, msg, wParam, lParam); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +CTabbedWindow::CTabbedWindow() : + CDlgBase(g_plugin, IDD_CONTAINER), + m_tab(this, IDC_TAB) +{ + SetMinSize(450, 350); +} + +bool CTabbedWindow::OnInitDialog() +{ + SetWindowLongPtr(m_tab.GetHwnd(), GWLP_USERDATA, LPARAM(this)); + mir_subclassWindow(m_tab.GetHwnd(), ::TabSubclassProc); + + m_hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, nullptr, WS_CHILD | WS_VISIBLE | SBT_TOOLTIPS | SBARS_SIZEGRIP, 0, 0, 0, 0, m_hwnd, nullptr, g_plugin.getInst(), nullptr); + SendMessage(m_hwndStatus, SB_SETMINHEIGHT, GetSystemMetrics(SM_CYSMICON), 0); + + RECT rc; + GetWindowRect(m_hwndStatus, &rc); + m_statusHeight = rc.bottom - rc.top; + + SetWindowPosition(); + + if (!g_Settings.bTabsEnable) { + m_tab.Hide(); + return false; + } + + LONG_PTR mask = GetWindowLongPtr(m_tab.GetHwnd(), GWL_STYLE); + if (g_Settings.bTabsAtBottom) + mask |= TCS_BOTTOM; + else + mask &= ~TCS_BOTTOM; + SetWindowLongPtr(m_tab.GetHwnd(), GWL_STYLE, mask); + + TabCtrl_SetMinTabWidth(m_tab.GetHwnd(), 80); + TabCtrl_SetImageList(m_tab.GetHwnd(), Clist_GetImageList()); + return true; +} + +void CTabbedWindow::OnDestroy() +{ + DestroyWindow(m_hwndStatus); m_hwndStatus = nullptr; + + SaveWindowPosition(true); + + Utils_SaveWindowPosition(m_hwnd, g_plugin.bSavePerContact ? ((m_pEmbed == nullptr) ? 0 : m_pEmbed->m_hContact) : 0, CHAT_MODULE, "room"); + + if (m_pEmbed == nullptr) + g_pTabDialog = nullptr; +} + +void CTabbedWindow::OnResize() +{ + CDlgBase::OnResize(); + + SendMessage(m_hwndStatus, WM_SIZE, 0, 0); + + if (m_pEmbed) { + RECT rc; + GetClientRect(m_tab.GetHwnd(), &rc); + MoveWindow(m_pEmbed->GetHwnd(), 0, 0, rc.right - rc.left, rc.bottom - rc.top, FALSE); + } + + SaveWindowPosition(false); +} + +int CTabbedWindow::Resizer(UTILRESIZECONTROL *urc) +{ + if (urc->wId == IDC_TAB) { + urc->rcItem.top = 1; + urc->rcItem.bottom = urc->dlgNewSize.cy - m_statusHeight - 1; + return RD_ANCHORX_WIDTH | RD_ANCHORY_CUSTOM; + } + + return RD_ANCHORX_WIDTH | RD_ANCHORY_BOTTOM; // status bar +} + +///////////////////////////////////////////////////////////////////////////////////////// + +CTabbedWindow* CTabbedWindow::AddPage(MCONTACT hContact, wchar_t *pwszText, int iNoActivate) +{ + CMsgDialog *pDlg = new CMsgDialog(this, hContact); + pDlg->m_wszInitialText = pwszText; + if (iNoActivate != -1) + pDlg->m_bNoActivate = iNoActivate != 0; + + if (g_Settings.bTabsEnable) { + m_tab.AddPage(Clist_GetContactDisplayName(hContact), nullptr, pDlg); + FixTabIcons(pDlg); + + m_tab.ActivatePage(m_tab.GetCount() - 1); + } + else { + m_pEmbed = pDlg; + Create(); + pDlg->SetParent(m_hwnd); + pDlg->Create(); + Show(); + } + + PostMessage(m_hwnd, WM_SIZE, 0, 0); + return this; +} + +void CTabbedWindow::AddPage(SESSION_INFO *si, int insertAt) +{ + // does the tab already exist? + int indexfound = (si->pDlg) ? m_tab.GetDlgIndex(si->pDlg) : -1; + if (indexfound == -1) { // create a new tab + wchar_t szTemp[30]; + mir_wstrncpy(szTemp, si->ptszName, 21); + if (mir_wstrlen(si->ptszName) > 20) + mir_wstrncpy(szTemp + 20, L"...", 4); + + if (!IsWindowVisible(m_hwnd)) + Show(SW_SHOW); + + CMsgDialog *pDlg = new CMsgDialog(this, si); + pDlg->SetParent(m_hwnd); + m_tab.AddPage(szTemp, nullptr, pDlg); + m_tab.ActivatePage(m_tab.GetCount() - 1); + FixTabIcons(pDlg); + } + else if (insertAt == -1) + m_tab.ActivatePage(indexfound); +} + +CMsgDialog* CTabbedWindow::CurrPage() const +{ + return (m_pEmbed != nullptr) ? m_pEmbed : (CMsgDialog*)m_tab.GetActivePage(); +} + +void CTabbedWindow::DropTab(int begin, int end) +{ + if (begin == end) + return; + + m_tab.SwapPages(begin, end); + + CMsgDialog *pDlg = (CMsgDialog *)m_tab.GetNthPage(end); + if (pDlg) { + FixTabIcons(pDlg); + m_tab.ActivatePage(end); + } + + // fix the "fixed" positions + int tabCount = m_tab.GetCount(); + for (int i = 0; i < tabCount; i++) { + pDlg = (CMsgDialog *)m_tab.GetNthPage(i); + if (pDlg == nullptr) + continue; + + SESSION_INFO *si = pDlg->m_si; + if (si && si->hContact && db_get_w(si->hContact, si->pszModule, "TabPosition", 0) != 0) + db_set_w(si->hContact, si->pszModule, "TabPosition", i + 1); + } +} + +void CTabbedWindow::FixTabIcons(CMsgDialog *pDlg) +{ + if (pDlg == nullptr) + return; + + int image = pDlg->GetImageId(); + + // if tabs are turned off, simply change the window's icon, otherwise set the tab's icon first + if (m_pEmbed == nullptr) { + 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); + } + } + + // set the container's icon only if we're processing the current page + if (pDlg == CurrPage()) { + Window_FreeIcon_IcoLib(m_hwnd); + if (g_plugin.bUseStatusWinIcon) + Window_SetProtoIcon_IcoLib(m_hwnd, pDlg->m_szProto, pDlg->m_wStatus); + else if (pDlg->isChat()) + Window_SetIcon_IcoLib(m_hwnd, g_plugin.getIconHandle(IDI_CHANMGR)); + else + Window_SetSkinIcon_IcoLib(m_hwnd, SKINICON_EVENT_MESSAGE); + } +} + +void CTabbedWindow::RemoveTab(CMsgDialog *pDlg) +{ + int idx = m_tab.GetDlgIndex(pDlg); + if (idx == -1) + return; + + m_tab.RemovePage(idx); + if (m_tab.GetCount() == 0) + PostMessage(m_hwnd, WM_CLOSE, 0, 0); + else { + if (m_tab.GetNthPage(idx) == nullptr) + idx--; + m_tab.ActivatePage(idx); + } +} + +void CTabbedWindow::SaveWindowPosition(bool bUpdateSession) +{ + WINDOWPLACEMENT wp = {}; + wp.length = sizeof(wp); + GetWindowPlacement(m_hwnd, &wp); + + g_Settings.iX = wp.rcNormalPosition.left; + g_Settings.iY = wp.rcNormalPosition.top; + g_Settings.iWidth = wp.rcNormalPosition.right - wp.rcNormalPosition.left; + g_Settings.iHeight = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; + + if (bUpdateSession) { + iX = g_Settings.iX; + iY = g_Settings.iY; + iWidth = g_Settings.iWidth; + iHeight = g_Settings.iHeight; + } +} + +void CTabbedWindow::SetMessageHighlight(CMsgDialog *pDlg) +{ + if (m_tab.GetDlgIndex(pDlg) == -1) + return; + + pDlg->m_si->wState |= GC_EVENT_HIGHLIGHT; + FixTabIcons(pDlg); + if (Chat::bFlashWindowHighlight && pDlg != m_tab.GetActivePage()) + pDlg->StartFlash(); +} + +void CTabbedWindow::SetTabHighlight(CMsgDialog *pDlg) +{ + if (m_tab.GetDlgIndex(pDlg) == -1) + return; + + FixTabIcons(pDlg); + if (Chat::bFlashWindow && pDlg != m_tab.GetActivePage()) + pDlg->StartFlash(); +} + +void CTabbedWindow::SetWindowPosition() +{ + if (m_pEmbed == nullptr) { + Utils_RestoreWindowPosition(m_hwnd, 0, CHAT_MODULE, "room"); + return; + } + + if (iX) { + WINDOWPLACEMENT wp; + wp.length = sizeof(wp); + GetWindowPlacement(m_hwnd, &wp); + + wp.rcNormalPosition.left = iX; + wp.rcNormalPosition.top = iY; + wp.rcNormalPosition.right = wp.rcNormalPosition.left + iWidth; + wp.rcNormalPosition.bottom = wp.rcNormalPosition.top + iHeight; + wp.showCmd = SW_HIDE; + SetWindowPlacement(m_hwnd, &wp); + return; + } + + int flag = m_pEmbed->m_bNoActivate ? RWPF_HIDDEN : 0; + if (Utils_RestoreWindowPosition(m_hwnd, g_plugin.bSavePerContact ? m_pEmbed->m_hContact : 0, CHAT_MODULE, "room", flag)) { + if (g_plugin.bSavePerContact) { + if (Utils_RestoreWindowPosition(m_hwnd, 0, CHAT_MODULE, "room", flag | RWPF_NOMOVE)) + SetWindowPos(m_hwnd, nullptr, 0, 0, 550, 400, SWP_NOZORDER | SWP_NOMOVE | SWP_SHOWWINDOW); + } + else SetWindowPos(m_hwnd, nullptr, 0, 0, 550, 400, SWP_NOZORDER | SWP_NOMOVE | SWP_SHOWWINDOW); + } + + if (!g_plugin.bSavePerContact && g_plugin.bCascade) { + RECT rc, rcMax = {}; + CTabbedWindow *pMaxTab = nullptr; + + for (auto &it : g_arDialogs) { + auto *pTab = it->m_pOwner; + if (pTab == this) + continue; + + GetWindowRect(pTab->GetHwnd(), &rc); + if (rc.left > rcMax.left && rc.top > rcMax.top) { + pMaxTab = pTab; + rcMax = rc; + } + } + + if (pMaxTab) { + m_windowWasCascaded = 1; + int offset = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME); + SetWindowPos(m_hwnd, nullptr, rcMax.left + offset, rcMax.top + offset, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE); + } + } +} + +void CTabbedWindow::SwitchNextTab() +{ + int total = m_tab.GetCount(); + int i = TabCtrl_GetCurSel(m_tab.GetHwnd()); + if (i != -1 && total > 1) { + if (i < total - 1) + i++; + else + i = 0; + m_tab.ActivatePage(i); + TabClicked(); + } +} + +void CTabbedWindow::SwitchPrevTab() +{ + int total = m_tab.GetCount(); + int i = TabCtrl_GetCurSel(m_tab.GetHwnd()); + if (i != -1 && total >= 1) { + if (i > 0) + i--; + else + i = total - 1; + m_tab.ActivatePage(i); + TabClicked(); + } +} + +void CTabbedWindow::SwitchTab(int iNewTab) +{ + int total = m_tab.GetCount(); + int i = TabCtrl_GetCurSel(m_tab.GetHwnd()); + if (i != -1 && total != -1 && total != 1 && i != iNewTab && total > iNewTab) { + m_tab.ActivatePage(iNewTab); + TabClicked(); + } +} + +void CTabbedWindow::TabClicked() +{ + CMsgDialog *pDlg = (CMsgDialog*)m_tab.GetActivePage(); + if (pDlg == nullptr) + return; + + SetFocus(pDlg->m_message.GetHwnd()); + + SESSION_INFO *si = pDlg->m_si; + if (si) { + if (si->wState & STATE_TALK) { + si->wState &= ~STATE_TALK; + db_set_w(si->hContact, si->pszModule, "ApparentMode", 0); + } + + if (si->wState & GC_EVENT_HIGHLIGHT) { + si->wState &= ~GC_EVENT_HIGHLIGHT; + + if (g_clistApi.pfnGetEvent(si->hContact, 0)) + g_clistApi.pfnRemoveEvent(si->hContact, GC_FAKE_EVENT); + } + + if (!si->pDlg) { + g_chatApi.ShowRoom(si); + SendMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); + } + } + + FixTabIcons(pDlg); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +INT_PTR CTabbedWindow::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) +{ + RECT rc; + int idx; + + switch (msg) { + case WM_MOVE: + SaveWindowPosition(false); + break; + + case WM_ENTERSIZEMOVE: + GetClientRect(m_hwnd, &rc); + oldSizeX = rc.right - rc.left; + oldSizeY = rc.bottom - rc.top; + break; + + case WM_EXITSIZEMOVE: + GetClientRect(m_hwnd, &rc); + if (!((rc.right - rc.left) == oldSizeX && (rc.bottom - rc.top) == oldSizeY)) { + CMsgDialog *pDlg = (g_Settings.bTabsEnable) ? (CMsgDialog*)m_tab.GetActivePage() : m_pEmbed; + if (pDlg != nullptr) { + pDlg->m_pLog->ScrollToBottom(); + pDlg->Resize(); + } + } + break; + + case WM_DRAWITEM: + { + LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lParam; + if (dis->hwndItem == m_hwndStatus) { + CMsgDialog *pDlg = (g_Settings.bTabsEnable) ? (CMsgDialog*)m_tab.GetActivePage() : m_pEmbed; + if (pDlg != nullptr) + DrawStatusIcons(pDlg->m_hContact, dis->hDC, dis->rcItem, 2); + return TRUE; + } + } + break; + + case WM_COMMAND: + if (LOWORD(wParam) == IDOK) { + CMsgDialog *pDlg = (g_Settings.bTabsEnable) ? (CMsgDialog*)m_tab.GetActivePage() : m_pEmbed; + if (pDlg != nullptr) { + pDlg->m_btnOk.Click(); + return TRUE; + } + } + break; + + case WM_ACTIVATE: + if (LOWORD(wParam) == WA_INACTIVE) + break; + + if (!m_pEmbed) { + idx = TabCtrl_GetCurSel(m_tab.GetHwnd()); + if (idx != -1) + m_tab.ActivatePage(idx); + } + else m_pEmbed->OnActivate(); + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->hwndFrom == m_hwndStatus) { + if (((LPNMHDR)lParam)->code == NM_CLICK || ((LPNMHDR)lParam)->code == NM_RCLICK) { + NMMOUSE *nm = (NMMOUSE *)lParam; + SendMessage(m_hwndStatus, SB_GETRECT, SendMessage(m_hwndStatus, SB_GETPARTS, 0, 0) - 1, (LPARAM)&rc); + if (nm->pt.x >= rc.left) { + CMsgDialog *pDlg = (g_Settings.bTabsEnable) ? (CMsgDialog*)m_tab.GetActivePage() : m_pEmbed; + if (pDlg != nullptr) + CheckStatusIconClick(pDlg->m_hContact, m_hwndStatus, nm->pt, rc, 2, ((LPNMHDR)lParam)->code == NM_RCLICK ? MBCF_RIGHTBUTTON : 0); + } + return TRUE; + } + } + + if (((LPNMHDR)lParam)->idFrom == IDC_TAB) { + switch (((LPNMHDR)lParam)->code) { + case TCN_SELCHANGE: + m_tab.ActivatePage(TabCtrl_GetCurSel(m_tab.GetHwnd())); + break; + + case NM_RCLICK: + int i = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom); + if (i == -1) + break; + + TCHITTESTINFO tci = {}; + tci.pt.x = (short)LOWORD(GetMessagePos()); + tci.pt.y = (short)HIWORD(GetMessagePos()); + tci.flags = TCHT_ONITEM; + ScreenToClient(GetDlgItem(m_hwnd, IDC_TAB), &tci.pt); + if ((i = TabCtrl_HitTest(((LPNMHDR)lParam)->hwndFrom, &tci)) == -1) + break; + + CMsgDialog *pDlg = (CMsgDialog*)m_tab.GetNthPage(i); + SESSION_INFO *si = pDlg->m_si; + + ClientToScreen(GetDlgItem(m_hwnd, IDC_TAB), &tci.pt); + HMENU hSubMenu = GetSubMenu(g_hMenu, 1); + TranslateMenu(hSubMenu); + + if (si != nullptr) { + uint16_t w = db_get_w(si->hContact, si->pszModule, "TabPosition", 0); + if (w == 0) + CheckMenuItem(hSubMenu, ID_LOCKPOSITION, MF_BYCOMMAND | MF_UNCHECKED); + else + CheckMenuItem(hSubMenu, ID_LOCKPOSITION, MF_BYCOMMAND | MF_CHECKED); + } + else CheckMenuItem(hSubMenu, ID_LOCKPOSITION, MF_BYCOMMAND | MF_UNCHECKED); + + switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, tci.pt.x, tci.pt.y, 0, m_hwnd, nullptr)) { + case ID_CLOSE: + pDlg->CloseTab(); + break; + + case ID_LOCKPOSITION: + if (si != nullptr) { + if (!(GetMenuState(hSubMenu, ID_LOCKPOSITION, MF_BYCOMMAND)&MF_CHECKED)) { + if (si->hContact) + db_set_w(si->hContact, si->pszModule, "TabPosition", (uint16_t)(i + 1)); + } + else db_unset(si->hContact, si->pszModule, "TabPosition"); + } + break; + + case ID_CLOSEOTHER: + int tabCount = m_tab.GetCount(); + if (tabCount > 1) { + while (tabCount--) { + if (tabCount == i) + continue; + + if (pDlg = (CMsgDialog*)m_tab.GetNthPage(tabCount)) + pDlg->CloseTab(); + } + m_tab.ActivatePage(0); + } + break; + } + } + } + break; + } + + return CDlgBase::DlgProc(msg, wParam, lParam); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void UninitTabs() +{ + if (g_pTabDialog != nullptr) { + g_pTabDialog->Close(); + g_pTabDialog = nullptr; + } +} diff --git a/src/core/stdmsg/src/version.h b/src/core/stdmsg/src/version.h index 80b240e521..c2573ed98b 100644 --- a/src/core/stdmsg/src/version.h +++ b/src/core/stdmsg/src/version.h @@ -9,4 +9,4 @@ #define __DESCRIPTION "Core module for send/receive instant messages." #define __AUTHOR "Miranda NG team" #define __AUTHORWEB "https://miranda-ng.org/p/StdMsg" -#define __COPYRIGHT "© 2012-22 Miranda NG team" +#define __COPYRIGHT "© 2012-23 Miranda NG team" -- cgit v1.2.3