From 3c06454f9c477704520939e233a483e94e3bc525 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 18 Dec 2023 16:21:25 +0300 Subject: fixes #4062 (IRC: Some modes still in Topic column) --- protocols/IRCG/IRC.vcxproj | 1 + protocols/IRCG/IRC.vcxproj.filters | 3 + protocols/IRCG/src/channelList.cpp | 393 ++++++++++++++++++++++++++++++++++ protocols/IRCG/src/commandmonitor.cpp | 108 ---------- protocols/IRCG/src/input.cpp | 11 +- protocols/IRCG/src/irc_dlg.h | 23 -- protocols/IRCG/src/ircproto.h | 5 +- protocols/IRCG/src/windows.cpp | 248 --------------------- 8 files changed, 402 insertions(+), 390 deletions(-) create mode 100644 protocols/IRCG/src/channelList.cpp (limited to 'protocols') diff --git a/protocols/IRCG/IRC.vcxproj b/protocols/IRCG/IRC.vcxproj index 48f0607e3f..3126d85347 100644 --- a/protocols/IRCG/IRC.vcxproj +++ b/protocols/IRCG/IRC.vcxproj @@ -26,6 +26,7 @@ + diff --git a/protocols/IRCG/IRC.vcxproj.filters b/protocols/IRCG/IRC.vcxproj.filters index 6cd2ce5826..c376b10367 100644 --- a/protocols/IRCG/IRC.vcxproj.filters +++ b/protocols/IRCG/IRC.vcxproj.filters @@ -41,6 +41,9 @@ Source Files + + Source Files + diff --git a/protocols/IRCG/src/channelList.cpp b/protocols/IRCG/src/channelList.cpp new file mode 100644 index 0000000000..bac7b3e0bc --- /dev/null +++ b/protocols/IRCG/src/channelList.cpp @@ -0,0 +1,393 @@ +/* +Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "stdafx.h" + +struct ListViewSortParam +{ + CCtrlListView *pList; + int iSubItem; +}; + +static int CALLBACK ListViewSort(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) +{ + ListViewSortParam *param = (ListViewSortParam *)lParamSort; + if (!param->pList->GetHwnd()) + return 0; + + wchar_t temp1[512]; + wchar_t temp2[512]; + LVITEM lvm; + lvm.mask = LVIF_TEXT; + lvm.iItem = lParam1; + lvm.iSubItem = param->iSubItem; + lvm.pszText = temp1; + lvm.cchTextMax = _countof(temp1); + param->pList->GetItem(&lvm); + lvm.iItem = lParam2; + lvm.pszText = temp2; + param->pList->GetItem(&lvm); + if (param->iSubItem != 1) { + if (mir_wstrlen(temp1) != 0 && mir_wstrlen(temp2) != 0) + return mir_wstrcmpi(temp1, temp2); + + return (*temp1 == 0) ? 1 : -1; + } + + return (_wtoi(temp1) < _wtoi(temp2)) ? 1 : -1; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +class CListDlg : public CIrcBaseDlg +{ + CTimer m_timer; + CCtrlButton m_Join; + CCtrlEdit m_filter, m_status; + +public: + CCtrlListView m_list, m_list2; + + CListDlg(CIrcProto *_pro) : + CIrcBaseDlg(_pro, IDD_LIST), + m_Join(this, IDC_JOIN), + m_list(this, IDC_INFO_LISTVIEW), + m_list2(this, IDC_INFO_LISTVIEW2), + m_timer(this, 10), + m_status(this, IDC_TEXT), + m_filter(this, IDC_FILTER_STRING) + { + m_list.OnColumnClick = Callback(this, &CListDlg::onColumnClick_List); + m_list2.OnDoubleClick = m_list.OnDoubleClick = m_Join.OnClick = Callback(this, &CListDlg::onClick_Join); + m_timer.OnEvent = Callback(this, &CListDlg::onTimer); + m_filter.OnChange = Callback(this, &CListDlg::onChange_Filter); + } + + bool OnInitDialog() override + { + RECT screen; + + SystemParametersInfo(SPI_GETWORKAREA, 0, &screen, 0); + LVCOLUMN lvC; + int COLUMNS_SIZES[4] = { 200, 50, 50, 2000 }; + wchar_t szBuffer[32]; + + lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + lvC.fmt = LVCFMT_LEFT; + for (int index = 0; index < 4; index++) { + lvC.iSubItem = index; + lvC.cx = COLUMNS_SIZES[index]; + + switch (index) { + case 0: mir_wstrcpy(szBuffer, TranslateT("Channel")); break; + case 1: mir_wstrcpy(szBuffer, L"#"); break; + case 2: mir_wstrcpy(szBuffer, TranslateT("Mode")); break; + case 3: mir_wstrcpy(szBuffer, TranslateT("Topic")); break; + } + lvC.pszText = szBuffer; + m_list.InsertColumn(index, &lvC); + m_list2.InsertColumn(index, &lvC); + } + + Utils_RestoreWindowPosition(m_hwnd, NULL, m_proto->m_szModuleName, "channelList_"); + + m_list.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT); + m_list2.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT); + Window_SetIcon_IcoLib(m_hwnd, g_plugin.getIconHandle(IDI_LIST)); + m_status.SetText(TranslateT("Please wait...")); + return true; + } + + void OnDestroy() override + { + m_timer.Stop(); + Utils_SaveWindowPosition(m_hwnd, NULL, m_proto->m_szModuleName, "channelList_"); + + mir_cslock lck(m_proto->m_csList); + m_proto->m_listDlg = nullptr; + } + + int Resizer(UTILRESIZECONTROL *urc) override + { + switch (urc->wId) { + case IDC_INFO_LISTVIEW: + case IDC_INFO_LISTVIEW2: + return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORY_HEIGHT | RD_ANCHORX_WIDTH; + case IDC_FILTER_STRING: + case IDC_FILTER_BTN: + return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM; + case IDC_TEXT: + return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM | RD_ANCHORX_WIDTH; + } + + return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM; + } + + void onTimer(CTimer *pTimer) + { + pTimer->Stop(); + + // Retrieve the input text + wchar_t strFilterText[255]; + wchar_t newTitle[255]; + m_filter.GetText(strFilterText, _countof(strFilterText)); + + if (strFilterText[0]) { + int itemCount = 0; + int j = m_list.GetItemCount(); + if (j <= 0) + return; + + // Empty the filtered list + m_list2.DeleteAllItems(); + + LVITEM lvm; + wchar_t text[255]; + lvm.pszText = text; // Set buffer for texts + lvm.cchTextMax = _countof(text); + lvm.mask = LVIF_TEXT; + for (int i = 0; i < j; i++) { + lvm.iSubItem = 0; // First column + lvm.iItem = i; + m_list.GetItem(&lvm); + + // Match the text? + wchar_t *t = wcsstr(lvm.pszText, strFilterText); + if (t == nullptr) { // If no, then Check if in the topics + m_list.GetItem(&lvm); + + // Match the text? + t = wcsstr(lvm.pszText, strFilterText); + } + + if (t) { + ++itemCount; + + // Column 0 + LVITEM lvItem; + lvItem.iItem = m_list2.GetItemCount(); + lvItem.mask = LVIF_TEXT | LVIF_PARAM; + + lvItem.iSubItem = 0; + lvItem.pszText = lvm.pszText; + lvItem.lParam = lvItem.iItem; + lvItem.iItem = m_list2.InsertItem(&lvItem); + + // Column 2 + lvm.mask = LVIF_TEXT; + lvm.iSubItem = 1; + lvm.iItem = i; + m_list.GetItem(&lvm); + + lvItem.mask = LVIF_TEXT; + lvItem.iSubItem = 1; + lvItem.pszText = lvm.pszText; + m_list2.SetItem(&lvItem); + + // Column 4 + lvm.mask = LVIF_TEXT; + lvm.iSubItem = 3; + lvm.iItem = i; + m_list.GetItem(&lvm); + + lvItem.mask = LVIF_TEXT; + lvItem.pszText = lvm.pszText; + lvItem.iSubItem = 3; + m_list2.SetItem(&lvItem); + } + } + + // Show the list + SetWindowPos(m_list2.GetHwnd(), HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); + ShowWindow(m_list.GetHwnd(), SW_HIDE); + + // New dialog title + mir_snwprintf(newTitle, TranslateT("%s - Filtered - %d items"), strFilterText, itemCount); + SetWindowText(m_hwnd, newTitle); + } + else { + ShowWindow(m_list.GetHwnd(), SW_SHOW); + ShowWindow(m_list2.GetHwnd(), SW_HIDE); + mir_snwprintf(newTitle, TranslateT("Channels on server")); + SetWindowText(m_hwnd, newTitle); + } + } + + void onClick_Join(CCtrlButton *) + { + wchar_t szTemp[255]; + m_filter.GetText(szTemp, _countof(szTemp)); + + if (szTemp[0]) + m_list2.GetItemText(m_list2.GetSelectionMark(), 0, szTemp, 255); + else + m_list.GetItemText(m_list.GetSelectionMark(), 0, szTemp, 255); + m_proto->PostIrcMessage(L"/JOIN %s", szTemp); + } + + void onChange_Filter(CCtrlEdit *) + { + m_timer.Start(200); + } + + void onColumnClick_List(CCtrlListView::TEventInfo *ev) + { + ListViewSortParam param = { &m_list, ev->nmlv->iSubItem }; + m_list.SortItems(ListViewSort, (LPARAM)¶m); + UpdateList(); + } + + void AddChannel(const CIrcMessage *pmsg) + { + LVITEM lvItem; + lvItem.iItem = m_list.GetItemCount(); + lvItem.mask = LVIF_TEXT | LVIF_PARAM; + lvItem.iSubItem = 0; + lvItem.pszText = pmsg->parameters[1].GetBuffer(); + lvItem.lParam = lvItem.iItem; + lvItem.iItem = m_list.InsertItem(&lvItem); + + lvItem.mask = LVIF_TEXT; + lvItem.iSubItem = 1; + lvItem.pszText = pmsg->parameters[pmsg->parameters.getCount() - 2].GetBuffer(); + m_list.SetItem(&lvItem); + + auto &wszTopic = pmsg->parameters[pmsg->parameters.getCount() - 1]; + int iStart = wszTopic.Find(L"[+"); + int iEnd = wszTopic.Find(']') + 1; + if (iStart == 0 && iEnd > 3) { + CMStringW wszMode(wszTopic.Mid(0, iEnd)); + lvItem.iSubItem = 2; + lvItem.pszText = wszMode.GetBuffer(); + m_list.SetItem(&lvItem); + + wszTopic.Delete(0, iEnd); + } + + lvItem.iSubItem = 3; + lvItem.pszText = DoColorCodes(wszTopic, TRUE, FALSE); + m_list.SetItem(&lvItem); + + int percent = 100; + if (m_proto->m_noOfChannels > 0) + percent = (int)(m_proto->m_channelNumber * 100) / m_proto->m_noOfChannels; + + wchar_t text[100]; + if (percent < 100) + mir_snwprintf(text, TranslateT("Downloading list (%u%%) - %u channels"), percent, m_proto->m_channelNumber); + else + mir_snwprintf(text, TranslateT("Downloading list - %u channels"), m_proto->m_channelNumber); + m_status.SetText(text); + } + + void UpdateList(void) + { + int j = m_list.GetItemCount(); + if (j > 0) { + LVITEM lvm; + lvm.mask = LVIF_PARAM; + lvm.iSubItem = 0; + for (int i = 0; i < j; i++) { + lvm.iItem = i; + lvm.lParam = i; + m_list.SetItem(&lvm); + } + } + } +}; + +///////////////////////////////////////////////////////////////////////////////////////// +// Module entry point + +static INT_PTR __stdcall sttShowDlgList(void *param) +{ + CIrcProto *ppro = (CIrcProto *)param; + + mir_cslock lck(ppro->m_csList); + if (ppro->m_listDlg == nullptr) { + ppro->m_listDlg = new CListDlg(ppro); + ppro->m_listDlg->Show(); + } + return 0; +} + +bool CIrcProto::OnIrc_LISTSTART(const CIrcMessage *pmsg) +{ + if (pmsg->m_bIncoming) { + CallFunctionSync(sttShowDlgList, this); + m_channelNumber = 0; + } + + ShowMessage(pmsg); + return true; +} + +bool CIrcProto::OnIrc_LIST(const CIrcMessage *pmsg) +{ + if (!pmsg->m_bIncoming || pmsg->parameters.getCount() <= 2) + return true; + + mir_cslockfull lck(m_csList); + if (auto *pDlg = (CListDlg *)m_listDlg) { + m_channelNumber++; + lck.unlock(); + + pDlg->AddChannel(pmsg); + } + return true; +} + +bool CIrcProto::OnIrc_LISTEND(const CIrcMessage *pmsg) +{ + if (pmsg->m_bIncoming) { + mir_cslock lck(m_csList); + if (auto *pDlg = (CListDlg *)m_listDlg) { + EnableWindow(GetDlgItem(m_listDlg->GetHwnd(), IDC_JOIN), true); + pDlg->m_list.SetSelectionMark(0); + pDlg->m_list.SetColumnWidth(1, LVSCW_AUTOSIZE); + pDlg->m_list.SetColumnWidth(2, LVSCW_AUTOSIZE); + pDlg->m_list.SetColumnWidth(3, LVSCW_AUTOSIZE); + pDlg->UpdateList(); + + wchar_t text[100]; + mir_snwprintf(text, TranslateT("Done: %u channels"), m_channelNumber); + int percent = 100; + if (m_noOfChannels > 0) + percent = (int)(m_channelNumber * 100) / m_noOfChannels; + if (percent < 70) { + mir_wstrcat(text, L" "); + mir_wstrcat(text, TranslateT("(probably truncated by server)")); + } + SetDlgItemText(m_listDlg->GetHwnd(), IDC_TEXT, text); + } + } + ShowMessage(pmsg); + return true; +} + +void CIrcProto::ResetChannelList() +{ + { mir_cslock lck(m_csList); + if (m_listDlg == nullptr) { + m_listDlg = new CListDlg(this); + m_listDlg->Show(); + } + } + SetActiveWindow(m_listDlg->GetHwnd()); + + ListView_DeleteAllItems(GetDlgItem(m_listDlg->GetHwnd(), IDC_INFO_LISTVIEW)); +} diff --git a/protocols/IRCG/src/commandmonitor.cpp b/protocols/IRCG/src/commandmonitor.cpp index 93106c04d1..3055624192 100644 --- a/protocols/IRCG/src/commandmonitor.cpp +++ b/protocols/IRCG/src/commandmonitor.cpp @@ -1434,114 +1434,6 @@ bool CIrcProto::OnIrc_TOPIC(const CIrcMessage *pmsg) return true; } -static INT_PTR __stdcall sttShowDlgList(void* param) -{ - CIrcProto *ppro = (CIrcProto*)param; - - mir_cslock lck(ppro->m_csList); - if (ppro->m_listDlg == nullptr) { - ppro->m_listDlg = new CListDlg(ppro); - ppro->m_listDlg->Show(); - } - return 0; -} - -bool CIrcProto::OnIrc_LISTSTART(const CIrcMessage *pmsg) -{ - if (pmsg->m_bIncoming) { - CallFunctionSync(sttShowDlgList, this); - m_channelNumber = 0; - } - - ShowMessage(pmsg); - return true; -} - -bool CIrcProto::OnIrc_LIST(const CIrcMessage *pmsg) -{ - if (!pmsg->m_bIncoming || pmsg->parameters.getCount() <= 2) - return true; - - mir_cslockfull lck(m_csList); - if (!m_listDlg) - return true; - - m_channelNumber++; - - HWND hListView = GetDlgItem(m_listDlg->GetHwnd(), IDC_INFO_LISTVIEW); - HWND hStatusWnd = m_listDlg->m_status.GetHwnd(); - lck.unlock(); - - LVITEM lvItem; - lvItem.iItem = ListView_GetItemCount(hListView); - lvItem.mask = LVIF_TEXT | LVIF_PARAM; - lvItem.iSubItem = 0; - lvItem.pszText = pmsg->parameters[1].GetBuffer(); - lvItem.lParam = lvItem.iItem; - lvItem.iItem = ListView_InsertItem(hListView, &lvItem); - - lvItem.mask = LVIF_TEXT; - lvItem.iSubItem = 1; - lvItem.pszText = pmsg->parameters[pmsg->parameters.getCount() - 2].GetBuffer(); - ListView_SetItem(hListView, &lvItem); - - auto &wszTopic = pmsg->parameters[pmsg->parameters.getCount() - 1]; - int iStart = wszTopic.Find(L"[+"); - int iEnd = wszTopic.Find(']') + 1; - if (iStart == 0 && iEnd != 0 && iEnd >= 8) { - CMStringW wszMode(wszTopic.Mid(0, iEnd)); - lvItem.iSubItem = 2; - lvItem.pszText = wszMode.GetBuffer(); - ListView_SetItem(hListView, &lvItem); - - wszTopic.Delete(0, iEnd); - } - - lvItem.iSubItem = 3; - lvItem.pszText = DoColorCodes(wszTopic, TRUE, FALSE); - ListView_SetItem(hListView, &lvItem); - - int percent = 100; - if (m_noOfChannels > 0) - percent = (int)(m_channelNumber * 100) / m_noOfChannels; - - wchar_t text[100]; - if (percent < 100) - mir_snwprintf(text, TranslateT("Downloading list (%u%%) - %u channels"), percent, m_channelNumber); - else - mir_snwprintf(text, TranslateT("Downloading list - %u channels"), m_channelNumber); - SetWindowText(hStatusWnd, text); - return true; -} - -bool CIrcProto::OnIrc_LISTEND(const CIrcMessage *pmsg) -{ - if (pmsg->m_bIncoming) { - mir_cslock lck(m_csList); - if (m_listDlg) { - EnableWindow(GetDlgItem(m_listDlg->GetHwnd(), IDC_JOIN), true); - ListView_SetSelectionMark(GetDlgItem(m_listDlg->GetHwnd(), IDC_INFO_LISTVIEW), 0); - ListView_SetColumnWidth(GetDlgItem(m_listDlg->GetHwnd(), IDC_INFO_LISTVIEW), 1, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(GetDlgItem(m_listDlg->GetHwnd(), IDC_INFO_LISTVIEW), 2, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(GetDlgItem(m_listDlg->GetHwnd(), IDC_INFO_LISTVIEW), 3, LVSCW_AUTOSIZE); - m_listDlg->UpdateList(); - - wchar_t text[100]; - mir_snwprintf(text, TranslateT("Done: %u channels"), m_channelNumber); - int percent = 100; - if (m_noOfChannels > 0) - percent = (int)(m_channelNumber * 100) / m_noOfChannels; - if (percent < 70) { - mir_wstrcat(text, L" "); - mir_wstrcat(text, TranslateT("(probably truncated by server)")); - } - SetDlgItemText(m_listDlg->GetHwnd(), IDC_TEXT, text); - } - } - ShowMessage(pmsg); - return true; -} - bool CIrcProto::OnIrc_BANLIST(const CIrcMessage *pmsg) { if (m_managerDlg && pmsg->m_bIncoming && pmsg->parameters.getCount() > 2) { diff --git a/protocols/IRCG/src/input.cpp b/protocols/IRCG/src/input.cpp index 42d91b309c..386f1c1270 100644 --- a/protocols/IRCG/src/input.cpp +++ b/protocols/IRCG/src/input.cpp @@ -470,16 +470,7 @@ BOOL CIrcProto::DoHardcodedCommand(CMStringW text, wchar_t *window, MCONTACT hCo } if (command == L"/list") { - { - mir_cslock lck(m_csList); - if (m_listDlg == nullptr) { - m_listDlg = new CListDlg(this); - m_listDlg->Show(); - } - } - SetActiveWindow(m_listDlg->GetHwnd()); - - ListView_DeleteAllItems(GetDlgItem(m_listDlg->GetHwnd(), IDC_INFO_LISTVIEW)); + ResetChannelList(); PostIrcMessage(L"/lusers"); return false; } diff --git a/protocols/IRCG/src/irc_dlg.h b/protocols/IRCG/src/irc_dlg.h index 082973dd2f..a605cd0034 100644 --- a/protocols/IRCG/src/irc_dlg.h +++ b/protocols/IRCG/src/irc_dlg.h @@ -88,29 +88,6 @@ struct CNickDlg : public CCoolIrcDlg void OnDestroy() override; }; -struct CListDlg : public CIrcBaseDlg -{ - CListDlg(CIrcProto* _pro); - - bool OnInitDialog() override; - void OnDestroy() override; - int Resizer(UTILRESIZECONTROL *urc) override; - - INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override; - - CCtrlListView m_list, m_list2; - CCtrlEdit m_filter, m_status; - UINT_PTR m_timer; - - CCtrlButton m_Join; - void onClick_Join(CCtrlButton*); - - void onChange_Filter(CCtrlEdit *ctrl); - void onColumnClick_List(CCtrlListView::TEventInfo* ev); - - void UpdateList(void); -}; - struct CJoinDlg : public CCoolIrcDlg { CJoinDlg(CIrcProto* _pro); diff --git a/protocols/IRCG/src/ircproto.h b/protocols/IRCG/src/ircproto.h index 8128bf0564..bcaad1cf56 100644 --- a/protocols/IRCG/src/ircproto.h +++ b/protocols/IRCG/src/ircproto.h @@ -177,8 +177,8 @@ struct CIrcProto : public PROTO bool bTempDisableCheck, bTempForceCheck, bEcho, bHandleNickErr, bPerformDone; + CDlgBase *m_listDlg; CJoinDlg *m_joinDlg; - CListDlg *m_listDlg; CNickDlg *m_nickDlg; CWhoisDlg *m_whoisDlg; CManagerDlg *m_managerDlg; @@ -188,6 +188,9 @@ struct CIrcProto : public PROTO CMStringA sChannelModes, sUserModes; CMStringW sChannelPrefixes, sUserModePrefixes, WhoisAwayReply; + // channelList.cpp + void ResetChannelList(); + // clist.cpp MCONTACT CList_AddContact(CONTACT *user, bool InList, bool SetOnline); bool CList_SetAllOffline(uint8_t ChatsToo); diff --git a/protocols/IRCG/src/windows.cpp b/protocols/IRCG/src/windows.cpp index e27c60e6d9..18e8149a72 100644 --- a/protocols/IRCG/src/windows.cpp +++ b/protocols/IRCG/src/windows.cpp @@ -239,254 +239,6 @@ bool CNickDlg::OnApply() return true; } -///////////////////////////////////////////////////////////////////////////////////////// -// 'Change nickname' dialog - -#define LIST_TIMER 10 - -CListDlg::CListDlg(CIrcProto *_pro) : - CIrcBaseDlg(_pro, IDD_LIST), - m_Join(this, IDC_JOIN), - m_list(this, IDC_INFO_LISTVIEW), - m_list2(this, IDC_INFO_LISTVIEW2), - m_status(this, IDC_TEXT), - m_filter(this, IDC_FILTER_STRING) -{ - m_list.OnColumnClick = Callback(this, &CListDlg::onColumnClick_List); - m_list2.OnDoubleClick = m_list.OnDoubleClick = m_Join.OnClick = Callback(this, &CListDlg::onClick_Join); - m_filter.OnChange = Callback(this, &CListDlg::onChange_Filter); -} - -bool CListDlg::OnInitDialog() -{ - RECT screen; - - SystemParametersInfo(SPI_GETWORKAREA, 0, &screen, 0); - LVCOLUMN lvC; - int COLUMNS_SIZES[4] = { 200, 50, 50, 2000 }; - wchar_t szBuffer[32]; - - lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - lvC.fmt = LVCFMT_LEFT; - for (int index = 0; index < 4; index++) { - lvC.iSubItem = index; - lvC.cx = COLUMNS_SIZES[index]; - - switch (index) { - case 0: mir_wstrcpy(szBuffer, TranslateT("Channel")); break; - case 1: mir_wstrcpy(szBuffer, L"#"); break; - case 2: mir_wstrcpy(szBuffer, TranslateT("Mode")); break; - case 3: mir_wstrcpy(szBuffer, TranslateT("Topic")); break; - } - lvC.pszText = szBuffer; - m_list.InsertColumn(index, &lvC); - m_list2.InsertColumn(index, &lvC); - } - - Utils_RestoreWindowPosition(m_hwnd, NULL, m_proto->m_szModuleName, "channelList_"); - - m_list.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT); - m_list2.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT); - Window_SetIcon_IcoLib(m_hwnd, g_plugin.getIconHandle(IDI_LIST)); - m_status.SetText(TranslateT("Please wait...")); - return true; -} - -INT_PTR CListDlg::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (msg == WM_TIMER) { - ::KillTimer(m_hwnd, m_timer); m_timer = 0; - - // Retrieve the input text - wchar_t strFilterText[255]; - wchar_t newTitle[255]; - m_filter.GetText(strFilterText, _countof(strFilterText)); - - if (strFilterText[0]) { - int itemCount = 0; - int j = m_list.GetItemCount(); - if (j <= 0) - return FALSE; - - // Empty the filtered list - m_list2.DeleteAllItems(); - - LVITEM lvm; - wchar_t text[255]; - lvm.pszText = text; // Set buffer for texts - lvm.cchTextMax = _countof(text); - lvm.mask = LVIF_TEXT; - for (int i = 0; i < j; i++) { - lvm.iSubItem = 0; // First column - lvm.iItem = i; - m_list.GetItem(&lvm); - - // Match the text? - wchar_t* t = wcsstr(lvm.pszText, strFilterText); - if (t == nullptr) { // If no, then Check if in the topics - m_list.GetItem(&lvm); - - // Match the text? - t = wcsstr(lvm.pszText, strFilterText); - } - - if (t) { - ++itemCount; - - // Column 0 - LVITEM lvItem; - lvItem.iItem = m_list2.GetItemCount(); - lvItem.mask = LVIF_TEXT | LVIF_PARAM; - - lvItem.iSubItem = 0; - lvItem.pszText = lvm.pszText; - lvItem.lParam = lvItem.iItem; - lvItem.iItem = m_list2.InsertItem(&lvItem); - - // Column 2 - lvm.mask = LVIF_TEXT; - lvm.iSubItem = 1; - lvm.iItem = i; - m_list.GetItem(&lvm); - - lvItem.mask = LVIF_TEXT; - lvItem.iSubItem = 1; - lvItem.pszText = lvm.pszText; - m_list2.SetItem(&lvItem); - - // Column 4 - lvm.mask = LVIF_TEXT; - lvm.iSubItem = 3; - lvm.iItem = i; - m_list.GetItem(&lvm); - - lvItem.mask = LVIF_TEXT; - lvItem.pszText = lvm.pszText; - lvItem.iSubItem = 3; - m_list2.SetItem(&lvItem); - } - } - - // Show the list - SetWindowPos(m_list2.GetHwnd(), HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); - ShowWindow(m_list.GetHwnd(), SW_HIDE); - - // New dialog title - mir_snwprintf(newTitle, TranslateT("%s - Filtered - %d items"), strFilterText, itemCount); - SetWindowText(m_hwnd, newTitle); - } - else { - ShowWindow(m_list.GetHwnd(), SW_SHOW); - ShowWindow(m_list2.GetHwnd(), SW_HIDE); - mir_snwprintf(newTitle, TranslateT("Channels on server")); - SetWindowText(m_hwnd, newTitle); - } - } - - return CProtoDlgBase::DlgProc(msg, wParam, lParam); -} - -void CListDlg::onChange_Filter(CCtrlEdit*) -{ - m_timer = ::SetTimer(m_hwnd, LIST_TIMER, 200, nullptr); -} - -void CListDlg::OnDestroy() -{ - if (m_timer) - ::KillTimer(m_hwnd, m_timer); - Utils_SaveWindowPosition(m_hwnd, NULL, m_proto->m_szModuleName, "channelList_"); - - mir_cslock lck(m_proto->m_csList); - m_proto->m_listDlg = nullptr; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -struct ListViewSortParam -{ - CCtrlListView* pList; - int iSubItem; -}; - -static int CALLBACK ListViewSort(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) -{ - ListViewSortParam* param = (ListViewSortParam*)lParamSort; - if (!param->pList->GetHwnd()) - return 0; - - wchar_t temp1[512]; - wchar_t temp2[512]; - LVITEM lvm; - lvm.mask = LVIF_TEXT; - lvm.iItem = lParam1; - lvm.iSubItem = param->iSubItem; - lvm.pszText = temp1; - lvm.cchTextMax = _countof(temp1); - param->pList->GetItem(&lvm); - lvm.iItem = lParam2; - lvm.pszText = temp2; - param->pList->GetItem(&lvm); - if (param->iSubItem != 1) { - if (mir_wstrlen(temp1) != 0 && mir_wstrlen(temp2) != 0) - return mir_wstrcmpi(temp1, temp2); - - return (*temp1 == 0) ? 1 : -1; - } - - return (_wtoi(temp1) < _wtoi(temp2)) ? 1 : -1; -} - -int CListDlg::Resizer(UTILRESIZECONTROL *urc) -{ - switch (urc->wId) { - case IDC_INFO_LISTVIEW: - case IDC_INFO_LISTVIEW2: - return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORY_HEIGHT | RD_ANCHORX_WIDTH; - case IDC_FILTER_STRING: - case IDC_FILTER_BTN: - return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM; - case IDC_TEXT: - return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM | RD_ANCHORX_WIDTH; - } - - return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM; -} - -void CListDlg::onColumnClick_List(CCtrlListView::TEventInfo *ev) -{ - ListViewSortParam param = { &m_list, ev->nmlv->iSubItem }; - m_list.SortItems(ListViewSort, (LPARAM)¶m); - UpdateList(); -} - -void CListDlg::onClick_Join(CCtrlButton*) -{ - wchar_t szTemp[255]; - m_filter.GetText(szTemp, _countof(szTemp)); - - if (szTemp[0]) - m_list2.GetItemText(m_list2.GetSelectionMark(), 0, szTemp, 255); - else - m_list.GetItemText(m_list.GetSelectionMark(), 0, szTemp, 255); - m_proto->PostIrcMessage(L"/JOIN %s", szTemp); -} - -void CListDlg::UpdateList() -{ - int j = m_list.GetItemCount(); - if (j > 0) { - LVITEM lvm; - lvm.mask = LVIF_PARAM; - lvm.iSubItem = 0; - for (int i = 0; i < j; i++) { - lvm.iItem = i; - lvm.lParam = i; - m_list.SetItem(&lvm); - } - } -} - ///////////////////////////////////////////////////////////////////////////////////////// // 'Join' dialog -- cgit v1.2.3