📄 ircchanneltabctrl.cpp
字号:
#include "StdAfx.h"
#include <Mmsystem.h>
#include "ircchanneltabctrl.h"
#include "ircwnd.h"
#include "ircmain.h"
#include "emuledlg.h"
#include "OtherFunctions.h"
#include "MenuCmds.h"
#include "emule.h"
#include "HTRichEditCtrl.h"
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(CIrcChannelTabCtrl, CClosableTabCtrl)
BEGIN_MESSAGE_MAP(CIrcChannelTabCtrl, CClosableTabCtrl)
ON_WM_CONTEXTMENU()
ON_WM_LBUTTONUP()
ON_NOTIFY_REFLECT(TCN_SELCHANGE, OnTcnSelchangeTab2)
END_MESSAGE_MAP()
CIrcChannelTabCtrl::CIrcChannelTabCtrl()
{
m_pCurrentChannel = NULL;
m_pParent = NULL;
m_bCloseable = true;
memset(&m_iiCloseButton, 0, sizeof m_iiCloseButton);
m_ptCtxMenu.SetPoint(-1, -1);
}
CIrcChannelTabCtrl::~CIrcChannelTabCtrl()
{
//Remove and delete all our open channels.
DeleteAllChannel();
}
void CIrcChannelTabCtrl::Init()
{
//This adds the two static windows, Status and ChanneList
NewChannel( GetResString(IDS_STATUS), 1 );
NewChannel( GetResString(IDS_IRC_CHANNELLIST), 2);
//Initialize the IRC window to be in the ChannelList
m_pCurrentChannel = (Channel*)channelPtrList.GetTail();
SetCurSel(0);
OnTcnSelchangeTab2( NULL, NULL );
SetAllIcons();
}
void CIrcChannelTabCtrl::OnSysColorChange()
{
CClosableTabCtrl::OnSysColorChange();
SetAllIcons();
}
void CIrcChannelTabCtrl::SetAllIcons()
{
CImageList iml;
iml.Create(16, 16, theApp.m_iDfltImageListColorFlags | ILC_MASK, 0, 1);
iml.Add(CTempIconLoader(_T("Chat")));
iml.Add(CTempIconLoader(_T("Message")));
iml.Add(CTempIconLoader(_T("MessagePending")));
SetImageList(&iml);
m_imlIRC.DeleteImageList();
m_imlIRC.Attach(iml.Detach());
SetPadding(CSize(10, 0));
}
void CIrcChannelTabCtrl::OnContextMenu(CWnd* pWnd, CPoint point)
{
int iCurTab = GetTabUnderMouse(point);
if (iCurTab < 2)
{
return;
}
TCITEM item;
item.mask = TCIF_PARAM;
GetItem(iCurTab, &item);
Channel* chan = FindChannelByName(((Channel*)item.lParam)->name);
if( !chan )
{
return;
}
CTitleMenu ChatMenu;
ChatMenu.CreatePopupMenu();
ChatMenu.AddMenuTitle(GetResString(IDS_IRC)+_T(" : ")+chan->name);
ChatMenu.AppendMenu(MF_STRING, Irc_Close, GetResString(IDS_FD_CLOSE));
if (iCurTab < 2) // no 'Close' for status log and channel list
ChatMenu.EnableMenuItem(Irc_Close, MF_GRAYED);
int totallength = m_sChannelModeSettingsTypeA.GetLength()+m_sChannelModeSettingsTypeB.GetLength()+m_sChannelModeSettingsTypeC.GetLength()+m_sChannelModeSettingsTypeD.GetLength();
int index = 0;
if( totallength > index )
{
int length = m_sChannelModeSettingsTypeA.GetLength();
for( int i = 0; i < length; i++)
{
CString mode = m_sChannelModeSettingsTypeA.Mid(i,1);
if( chan->modesA.Find(mode[0]) == -1 )
{
ChatMenu.AppendMenu(MF_STRING, Irc_ChanCommands+index, _T("Set +") + mode + _T(" ( Not Supported Yet )") );
ChatMenu.EnableMenuItem(Irc_ChanCommands+index, MF_GRAYED);
}
else
{
ChatMenu.AppendMenu(MF_STRING, Irc_ChanCommands+index+50, _T("Set -") + mode + _T(" ( Not Supported Yet )") );
ChatMenu.EnableMenuItem(Irc_ChanCommands+index+50, MF_GRAYED);
}
index++;
}
length = m_sChannelModeSettingsTypeB.GetLength();
for( int i = 0; i < length; i++)
{
CString mode = m_sChannelModeSettingsTypeB.Mid(i,1);
if( chan->modesB.Find(mode[0]) == -1 )
{
ChatMenu.AppendMenu(MF_STRING, Irc_ChanCommands+index, _T("Set +") + mode + _T(" ( Not Supported Yet )") );
ChatMenu.EnableMenuItem(Irc_ChanCommands+index, MF_GRAYED);
}
else
{
ChatMenu.AppendMenu(MF_STRING, Irc_ChanCommands+index+50, _T("Set -") + mode + _T(" ( Not Supported Yet )") );
ChatMenu.EnableMenuItem(Irc_ChanCommands+index+50, MF_GRAYED);
}
index++;
}
length = m_sChannelModeSettingsTypeC.GetLength();
for( int i = 0; i < length; i++)
{
CString mode = m_sChannelModeSettingsTypeC.Mid(i,1);
if( chan->modesC.Find(mode[0]) == -1 )
{
ChatMenu.AppendMenu(MF_STRING, Irc_ChanCommands+index, _T("Set +") + mode + _T(" ( Not Supported Yet )") );
ChatMenu.EnableMenuItem(Irc_ChanCommands+index, MF_GRAYED);
}
else
{
ChatMenu.AppendMenu(MF_STRING, Irc_ChanCommands+index+50, _T("Set -") + mode + _T(" ( Remove ") + mode + _T(" )") );
}
index++;
}
length = m_sChannelModeSettingsTypeD.GetLength();
for( int i = 0; i < length; i++)
{
CString mode = m_sChannelModeSettingsTypeD.Mid(i,1);
if( chan->modesD.Find(mode[0]) == -1 )
{
ChatMenu.AppendMenu(MF_STRING, Irc_ChanCommands+index, _T("Set +") + mode + _T(" ( Add ") + mode + _T(" )") );
}
else
{
ChatMenu.AppendMenu(MF_STRING, Irc_ChanCommands+index+50, _T("Set -") + mode + _T(" ( Remove ") + mode + _T(" )") );
}
index++;
}
}
ChatMenu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
VERIFY( ChatMenu.DestroyMenu() );
}
int CIrcChannelTabCtrl::GetTabUnderMouse(CPoint point)
{
TCHITTESTINFO hitinfo;
CRect rect;
GetWindowRect(&rect);
point.Offset(0-rect.left,0-rect.top);
hitinfo.pt = point;
if( GetItemRect( 0, &rect ) )
if (hitinfo.pt.y< rect.top+30 && hitinfo.pt.y >rect.top-30)
hitinfo.pt.y = rect.top;
// Find the destination tab...
unsigned int nTab = HitTest( &hitinfo );
if( hitinfo.flags != TCHT_NOWHERE )
return nTab;
else
return -1;
}
Channel* CIrcChannelTabCtrl::FindChannelByName(CString name)
{
POSITION pos1, pos2;
for (pos1 = channelPtrList.GetHeadPosition();( pos2 = pos1 ) != NULL;)
{
channelPtrList.GetNext(pos1);
Channel* cur_channel = (Channel*)channelPtrList.GetAt(pos2);
if (cur_channel->name.CompareNoCase(name.Trim()) == 0 && (cur_channel->type == 4 || cur_channel->type == 5))
return cur_channel;
}
return 0;
}
Channel* CIrcChannelTabCtrl::NewChannel( CString name, uint8 type )
{
Channel* toadd = new Channel;
toadd->name = name;
toadd->title = name;
toadd->type = type;
toadd->history_pos = 0;
if (type != 2)
{
CRect rcChannel;
m_pParent->m_serverChannelList.GetWindowRect(&rcChannel);
toadd->log.Create(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VSCROLL | ES_MULTILINE | ES_READONLY, rcChannel, m_pParent, (UINT)-1);
toadd->log.ModifyStyleEx(0, WS_EX_STATICEDGE, SWP_FRAMECHANGED);
toadd->log.SendMessage(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(3, 3));
toadd->log.SetEventMask(toadd->log.GetEventMask() | ENM_LINK);
toadd->log.SetFont(&theApp.emuledlg->m_fontHyperText);
toadd->log.SetTitle(name);
toadd->log.SetProfileSkinKey(_T("IRCChannel"));
toadd->log.ApplySkin();
}
channelPtrList.AddTail(toadd);
TCITEM newitem;
newitem.mask = TCIF_PARAM|TCIF_TEXT|TCIF_IMAGE;
newitem.lParam = (LPARAM)toadd;
newitem.pszText = name.GetBuffer();
newitem.iImage = 1; // 'Message'
uint32 pos = GetItemCount();
InsertItem(pos,&newitem);
if(type == 4)
{
SetCurSel(pos);
SetCurFocus(pos);
OnTcnSelchangeTab2( NULL, NULL );
}
return toadd;
}
void CIrcChannelTabCtrl::RemoveChannel( CString channel )
{
Channel* todel = FindChannelByName( channel );
if( !todel )
return;
TCITEM item;
item.mask = TCIF_PARAM;
item.lParam = -1;
int i;
for (i = 0; i < GetItemCount();i++)
{
GetItem(i,&item);
if (((Channel*)item.lParam) == todel)
break;
}
if (((Channel*)item.lParam) != todel)
return;
DeleteItem(i);
if( todel == m_pCurrentChannel )
{
m_pParent->m_nicklist.DeleteAllItems();
if( GetItemCount() > 2 && i > 1 )
{
if ( i == 2 )
i++;
SetCurSel(i-1);
SetCurFocus(i-1);
OnTcnSelchangeTab2( NULL, NULL );
}
else
{
SetCurSel(0);
SetCurFocus(0);
OnTcnSelchangeTab2( NULL, NULL );
}
}
m_pParent->m_nicklist.DeleteAllNick(todel->name);
channelPtrList.RemoveAt(channelPtrList.Find(todel));
delete todel;
}
void CIrcChannelTabCtrl::DeleteAllChannel()
{
POSITION pos1, pos2;
for (pos1 = channelPtrList.GetHeadPosition();( pos2 = pos1 ) != NULL;)
{
channelPtrList.GetNext(pos1);
Channel* cur_channel = (Channel*)channelPtrList.GetAt(pos2);
m_pParent->m_nicklist.DeleteAllNick(cur_channel->name);
channelPtrList.RemoveAt(pos2);
delete cur_channel;
}
}
bool CIrcChannelTabCtrl::ChangeChanMode( CString channel, CString nick, CString mode )
{
if( channel.Left(1) != _T("#") )
{
//Not a channel, this shouldn't happen
return true;
}
//We are changing a mode to something..
Channel* update = FindChannelByName( channel );
if( !update )
{
//No channel found, this shouldn't happen.
return false;
}
//Update modes.
int modeLevel = m_sChannelModeSettingsTypeA.Find(mode[1]);
if( modeLevel != -1 )
{
//Remove the setting. This takes care of "-" and makes sure we don't add the same symbol twice.
update->modesA.Remove(mode[1]);
if( mode.Left(1) == _T("+") )
{
if( update->modesA == _T("") )
{
//Channel has no modes, just set it..
update->modesA = mode[1];
}
else
{
//The chan does have other modes.. Lets make sure we put things in order..
int index = 0;
//This will pad the mode string..
while( index < m_sChannelModeSettingsTypeA.GetLength() )
{
if( update->modesA.Find(m_sChannelModeSettingsTypeA[index]) == -1 )
update->modesA.Insert(index, _T(" "));
index++;
}
//Insert the new mode
update->modesA.Insert(modeLevel, mode[1]);
//Remove pads
update->modesA.Remove(_T(' '));
}
}
return true;
}
modeLevel = m_sChannelModeSettingsTypeB.Find(mode[1]);
if( modeLevel != -1 )
{
//Remove the setting. This takes care of "-" and makes sure we don't add the same symbol twice.
update->modesB.Remove(mode[1]);
if( mode.Left(1) == _T("+") )
{
if( update->modesB == _T("") )
{
//Channel has no modes, just set it..
update->modesB = mode[1];
}
else
{
//The chan does have other modes.. Lets make sure we put things in order..
int index = 0;
//This will pad the mode string..
while( index < m_sChannelModeSettingsTypeB.GetLength() )
{
if( update->modesB.Find(m_sChannelModeSettingsTypeB[index]) == -1 )
update->modesB.Insert(index, _T(" "));
index++;
}
//Insert the new mode
update->modesB.Insert(modeLevel, mode[1]);
//Remove pads
update->modesB.Remove(_T(' '));
}
}
return true;
}
modeLevel = m_sChannelModeSettingsTypeC.Find(mode[1]);
if( modeLevel != -1 )
{
//Remove the setting. This takes care of "-" and makes sure we don't add the same symbol twice.
update->modesC.Remove(mode[1]);
if( mode.Left(1) == _T("+") )
{
if( update->modesC == _T("") )
{
//Channel has no modes, just set it..
update->modesC = mode[1];
}
else
{
//The chan does have other modes.. Lets make sure we put things in order..
int index = 0;
//This will pad the mode string..
while( index < m_sChannelModeSettingsTypeC.GetLength() )
{
if( update->modesC.Find(m_sChannelModeSettingsTypeC[index]) == -1 )
update->modesC.Insert(index, _T(" "));
index++;
}
//Insert the new mode
update->modesC.Insert(modeLevel, mode[1]);
//Remove pads
update->modesC.Remove(_T(' '));
}
}
return true;
}
modeLevel = m_sChannelModeSettingsTypeD.Find(mode[1]);
if( modeLevel != -1 )
{
//Remove the setting. This takes care of "-" and makes sure we don't add the same symbol twice.
update->modesD.Remove(mode[1]);
if( mode.Left(1) == _T("+") )
{
if( update->modesD == _T("") )
{
//Channel has no modes, just set it..
update->modesD = mode[1];
}
else
{
//The chan does have other modes.. Lets make sure we put things in order..
int index = 0;
//This will pad the mode string..
while( index < m_sChannelModeSettingsTypeD.GetLength() )
{
if( update->modesD.Find(m_sChannelModeSettingsTypeD[index]) == -1 )
update->modesD.Insert(index, _T(" "));
index++;
}
//Insert the new mode
update->modesD.Insert(modeLevel, mode[1]);
//Remove pads
update->modesD.Remove(_T(' '));
}
}
return true;
}
return false;
}
void CIrcChannelTabCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_bCloseable)
{
int iTabs = GetItemCount();
for (int i = 0; i < iTabs; i++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -