📄 ircnicklistctrl.cpp
字号:
#include "StdAfx.h"
#include "ircnicklistctrl.h"
#include "ircwnd.h"
#include "ircmain.h"
#include "emuledlg.h"
#include "OtherFunctions.h"
#include "MenuCmds.h"
#include "emule.h"
#include "HTRichEditCtrl.h"
struct Nick
{
CString nick;
CString modes;
int level;
};
struct Channel
{
CString name;
CString modesA;
CString modesB;
CString modesC;
CString modesD;
CHTRichEditCtrl log;
CString title;
CPtrList nicks;
uint8 type;
CStringArray history;
uint16 history_pos;
// Type is mainly so that we can use this for IRC and the eMule Messages..
// 1-Status, 2-Channel list, 4-Channel, 5-Private Channel, 6-eMule Message(Add later)
};
IMPLEMENT_DYNAMIC(CIrcNickListCtrl, CMuleListCtrl)
BEGIN_MESSAGE_MAP(CIrcNickListCtrl, CMuleListCtrl)
ON_WM_CONTEXTMENU()
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnLvnColumnclick)
ON_NOTIFY_REFLECT(NM_DBLCLK, OnNMDblclk)
END_MESSAGE_MAP()
CIrcNickListCtrl::CIrcNickListCtrl()
{
memset(m_asc_sort, 0, sizeof m_asc_sort);
m_iSortIndex=1;
m_pParent = NULL;
}
void CIrcNickListCtrl::Init()
{
InsertColumn(0,GetResString(IDS_IRC_NICK),LVCFMT_LEFT,90);
InsertColumn(1,GetResString(IDS_STATUS),LVCFMT_LEFT,70);
// TODO restore settings
SetSortArrow(m_iSortIndex, m_asc_sort[m_iSortIndex]);
SortItems(SortProc, m_iSortIndex + ((m_asc_sort[m_iSortIndex]) ? 0 : 10));
}
int CIrcNickListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
Nick* item1 = (Nick*)lParam1;
Nick* item2 = (Nick*)lParam2;
switch(lParamSort)
{
//This will sort the list like MIRC
case 0:
case 1:
case 11:
{
//TODO - MUST FIX THIS NOW THAT MODES ARE DONE DIFFERENT>
if( item1->level == item2->level )
return item1->nick.CompareNoCase(item2->nick);
if( item1->level == -1 )
return 1;
if( item2->level == -1 )
return -1;
return item1->level - item2->level;
}
case 10:
//This will put them in alpha order..
return item1->nick.CompareNoCase(item2->nick);
default:
return 0;
}
}
void CIrcNickListCtrl::OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
m_asc_sort[pNMLV->iSubItem] = !m_asc_sort[pNMLV->iSubItem];
m_iSortIndex=pNMLV->iSubItem;
SetSortArrow(m_iSortIndex, m_asc_sort[m_iSortIndex]);
SortItems(SortProc, m_iSortIndex + ((m_asc_sort[m_iSortIndex]) ? 0 : 10));
*pResult = 0;
}
void CIrcNickListCtrl::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
{
int iCurSel = GetNextItem(-1, LVIS_SELECTED | LVIS_FOCUSED);
if (iCurSel == -1)
{
return;
}
Nick* nick = (Nick*)GetItemData(iCurSel);
if( !nick )
{
return;
}
//TODO - Create resource strings for these!
CTitleMenu NickMenu;
NickMenu.CreatePopupMenu();
NickMenu.AddMenuTitle(GetResString(IDS_IRC_NICK) + _T(" : ") + nick->nick);
NickMenu.AppendMenu(MF_STRING, Irc_Priv, GetResString(IDS_IRC_PRIVMESSAGE));
NickMenu.AppendMenu(MF_STRING, Irc_AddFriend, GetResString(IDS_IRC_ADDTOFRIENDLIST));
if (!m_pParent->GetSendFileString().IsEmpty())
NickMenu.AppendMenu(MF_STRING, Irc_SendLink, GetResString(IDS_IRC_SENDLINK) + m_pParent->GetSendFileString());
else
NickMenu.AppendMenu(MF_STRING, Irc_SendLink, GetResString(IDS_IRC_SENDLINK) + GetResString(IDS_IRC_NOSFS));
NickMenu.AppendMenu(MF_STRING, Irc_Kick, GetResString(IDS_IRC_KICK));
NickMenu.AppendMenu(MF_STRING, Irc_Ban, _T("Ban"));
//Ban currently uses chanserv to ban which seems to kick also.. May change this later..
// NickMenu.AppendMenu(MF_STRING, Irc_KB, _T("Kick/Ban"));
NickMenu.AppendMenu(MF_STRING, Irc_Slap, GetResString(IDS_IRC_SLAP));
int length = m_sUserModeSettings.GetLength();
if( length > 0 )
{
for( int i = 0; i < length; i++)
{
CString mode = m_sUserModeSettings.Mid(i,1);
CString modeSymbol = m_sUserModeSymbols.Mid(i,1);
if( nick->modes.Find(modeSymbol[0]) == -1 )
NickMenu.AppendMenu(MF_STRING, Irc_OpCommands+i, _T("Set +") + mode + _T(" ( Add ") + modeSymbol + _T(" )") );
else
NickMenu.AppendMenu(MF_STRING, Irc_OpCommands+i+25, _T("Set -") + mode + _T(" ( Remove ") + modeSymbol + _T(" )") );
}
}
GetPopupMenuPos(*this, point);
NickMenu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
VERIFY( NickMenu.DestroyMenu() );
}
void CIrcNickListCtrl::OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult)
{
//We double clicked a nick.. Try to open private channel
int nickItem = GetNextItem(-1, LVIS_SELECTED | LVIS_FOCUSED);
if (nickItem != -1)
{
Nick* nick = (Nick*)GetItemData(nickItem);
if (nick)
{
//Valid nick, send a info message to force open a new channel..
m_pParent->AddInfoMessage(nick->nick, GetResString(IDS_IRC_PRIVATECHANSTART));
}
}
*pResult = 0;
}
Nick* CIrcNickListCtrl::FindNickByName(CString channel, CString name)
{
//Find a nick in a specific channel..
Channel* curr_channel = m_pParent->m_channelselect.FindChannelByName(channel);
if( !curr_channel)
{
//Channel does not exist.. Abort.
return NULL;
}
//We have a channel, find nick..
POSITION pos1, pos2;
for (pos1 = curr_channel->nicks.GetHeadPosition();( pos2 = pos1 ) != NULL;)
{
curr_channel->nicks.GetNext(pos1);
Nick* cur_nick = (Nick*)curr_channel->nicks.GetAt(pos2);
if (cur_nick->nick == name)
{
//We found our nick, return it..
return cur_nick;
}
}
//Nick was not in channel..
return NULL;
}
Nick* CIrcNickListCtrl::NewNick( CString channel, CString nick )
{
//Add a new nick to a channel..
Channel* toaddchan = m_pParent->m_channelselect.FindChannelByName( channel );
if( !toaddchan )
{
//Channel wasn't found, abort..
return NULL;
}
//This is a little clumsy and makes you think the previous check wasn't needed,
//But we need the channel object and FindNickByName doesn't do it..
//TODO: Maybe create a special method to merge the two checks..
if( FindNickByName( channel, nick ) )
{
//Check if we already have this nick..
return NULL;
}
Nick* toaddnick=NULL;
toaddnick = new Nick;
//Remove all modes from the front of this nick
while( m_sUserModeSymbols.Find(nick.Left(1)) != -1 )
{
toaddnick->modes += nick.Left(1);
nick = nick.Mid(1);
}
//We now know the true nick
toaddnick->nick = nick;
//Set user level
if( toaddnick->modes.GetLength() > 0 )
toaddnick->level = m_sUserModeSymbols.Find(toaddnick->modes[0]);
else
toaddnick->level = -1;
//Add new nick to channel.
toaddchan->nicks.AddTail(toaddnick);
if( toaddchan == m_pParent->m_channelselect.m_pCurrentChannel )
{
//This is our current channel, add it to our nicklist..
uint16 itemnr = GetItemCount();
itemnr = InsertItem(LVIF_PARAM,itemnr,0,0,0,0,(LPARAM)toaddnick);
SetItemText(itemnr,0,(LPCTSTR)toaddnick->nick);
SetItemText(itemnr,1,(LPCTSTR)toaddnick->modes);
UpdateNickCount();
}
return toaddnick;
}
void CIrcNickListCtrl::RefreshNickList( CString channel )
{
//Hide nickList to speed things up..
ShowWindow(SW_HIDE);
DeleteAllItems();
Channel* refresh = m_pParent->m_channelselect.FindChannelByName( channel );
if(!refresh )
{
//This is not a channel??? shouldn't happen..
UpdateNickCount();
ShowWindow(SW_SHOW);
return;
}
POSITION pos1, pos2;
for (pos1 = refresh->nicks.GetHeadPosition();( pos2 = pos1 ) != NULL;)
{
//Add all nicks to list..
refresh->nicks.GetNext(pos1);
Nick* curr_nick = (Nick*)refresh->nicks.GetAt(pos2);
uint16 itemnr = GetItemCount();
itemnr = InsertItem(LVIF_PARAM,itemnr,0,0,0,0,(LPARAM)curr_nick);
SetItemText(itemnr,0,(LPCTSTR)curr_nick->nick);
SetItemText(itemnr,1,(LPCTSTR)curr_nick->modes);
}
UpdateNickCount();
ShowWindow(SW_SHOW);
}
bool CIrcNickListCtrl::RemoveNick( CString channel, CString nick )
{
//Remove nick from a channel..
Channel* update = m_pParent->m_channelselect.FindChannelByName( channel );
if( !update )
{
//There was no channel..
return false;
}
POSITION pos1, pos2;
for( pos1 = update->nicks.GetHeadPosition();(pos2=pos1)!=NULL;)
{
//Go through nicks
update->nicks.GetNext(pos1);
Nick* curr_nick = (Nick*)update->nicks.GetAt(pos2);
if( curr_nick->nick == nick )
{
//Found nick..
if( update == m_pParent->m_channelselect.m_pCurrentChannel )
{
//If it's our current channel, delete the nick from nickList
LVFINDINFO find;
find.flags = LVFI_PARAM;
find.lParam = (LPARAM)curr_nick;
sint32 result = FindItem(&find);
DeleteItem(result);
UpdateNickCount();
}
//remove nick and delete.
update->nicks.RemoveAt(pos2);
delete curr_nick;
return true;
}
}
return false;
}
void CIrcNickListCtrl::DeleteAllNick( CString channel )
{
//Remove all nicks from a channel..
Channel* curr_channel = m_pParent->m_channelselect.FindChannelByName(channel);
if( !curr_channel )
{
//Channel was not found?
return;
}
POSITION pos3, pos4;
for(pos3 = curr_channel->nicks.GetHeadPosition();( pos4 = pos3) != NULL;)
{
//Remove all nicks..
curr_channel->nicks.GetNext(pos3);
Nick* cur_nick = (Nick*)curr_channel->nicks.GetAt(pos4);
curr_channel->nicks.RemoveAt(pos4);
delete cur_nick;
}
}
void CIrcNickListCtrl::DeleteNickInAll( CString nick, CString message )
{
//Remove a nick in all Channels.
//This is a client that Quit the network, so we have a quit message..
POSITION pos1, pos2;
for (pos1 = m_pParent->m_channelselect.channelPtrList.GetHeadPosition();( pos2 = pos1 ) != NULL;)
{
//Go through all channels..
m_pParent->m_channelselect.channelPtrList.GetNext(pos1);
Channel* cur_channel = (Channel*)(m_pParent->m_channelselect.channelPtrList).GetAt(pos2);
if(RemoveNick( cur_channel->name, nick ))
{
//If nick was in channel, put message in it saying why user quit..
if( !thePrefs.GetIrcIgnoreQuitMessage() )
m_pParent->AddInfoMessage( cur_channel->name, GetResString(IDS_IRC_HASQUIT), nick, message);
}
}
}
bool CIrcNickListCtrl::ChangeNick( CString channel, CString oldnick, CString newnick )
{
//Someone changed there nick..
Channel* update = m_pParent->m_channelselect.FindChannelByName( channel );
if( !update )
{
//Didn't find a channel??
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -