📄 chatchannelpage.cpp
字号:
/*
This file is part of KCeasy (http://www.kceasy.com)
Copyright (C) 2002-2005 Markus Kern <mkern@kceasy.com>
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.
*/
//---------------------------------------------------------------------------
#include <vcl.h>
#include <KCeasy.h>
#pragma hdrstop
#include "ChatChannelPage.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TChatChannelFrame *ChatChannelFrame;
//---------------------------------------------------------------------------
__fastcall TChatChannelFrame::TChatChannelFrame(TComponent* Owner,
AnsiString Chan, bool User)
: TFrame(Owner),
ChatFont(NULL),
Channel(Chan),
UserChat(User),
CmdHistoryIndex(-1),
LastSendTime(0)
{
TranslateComponent(this);
TopicStatic->Caption = "";
CmdHistory = new TStringList();
// hide topic and users panel if this is a user-user chat
if(UserChat) {
TopicPanel->Visible = false;
UserPanel->Visible = false;
VSplitter->Visible = false;
}
}
__fastcall TChatChannelFrame::~TChatChannelFrame()
{
for(int i = 0; i < UserListBox->Items->Count; i++)
delete ((TChatUser*)UserListBox->Items->Objects[i]);
UserListBox->Clear();
delete CmdHistory;
}
//---------------------------------------------------------------------------
void TChatChannelFrame::SetChatFont(const TFont* Font)
{
ChatFont = (TFont*)Font;
// update user list box
UserListBox->Font->Assign(ChatFont);
// update send edit
SendEdit->Font->Assign(ChatFont);
}
bool TChatChannelFrame::Print(AnsiString Text, TColor Color, bool PrintTime, bool Star)
{
if(RecvRichEdit->Focused())
RecvRichEdit->SetFocus();
RecvRichEdit->SelLength = 0;
RecvRichEdit->SelStart = RecvRichEdit->Text.Length();
RecvRichEdit->SelAttributes->Assign(ChatFont);
RecvRichEdit->SelAttributes->Color = Color;
if(Star)
Text = AnsiString("* ") + Text;
if(PrintTime)
Text = Time().FormatString("[hh:mm] ") + Text;
RecvRichEdit->Lines->Add(Text);
#if 0
::SendMessage(RecvRichEdit->Handle,WM_VSCROLL,SB_BOTTOM,0);
::SendMessage(RecvRichEdit->Handle,WM_VSCROLL,SB_PAGEUP,0);
#else
RecvRichEdit->SelStart = RecvRichEdit->GetTextLen();
::SendMessage(RecvRichEdit->Handle,EM_SCROLLCARET,0,0);
#endif
// highlight tab if this is not the active page
TTabSheet* Sheet = (TTabSheet*)this->Parent;
if(Config->GetValueInt("chat/highlight_channels") && Sheet->PageControl->ActivePage != Sheet)
Sheet->Highlighted = true;
}
//---------------------------------------------------------------------------
bool TChatChannelFrame::AddUser(AnsiString Name)
{
// isolate modes
TChatUser* User = new TChatUser();
User->Name = Name;
if(Name[1] == '@') {
User->Op = true;
User->Name = User->Name.SubString(2,User->Name.Length()-1);
}
if(Name[1] == '+') {
User->Voice = true;
User->Name = User->Name.SubString(2,User->Name.Length()-1);
}
// recreate decorated name
Name = User->Op ? "@" : (User->Voice ? "+" : "");
Name += User->Name;
// check if we already have this user
for(int i = 0; i < UserListBox->Items->Count; i++) {
if(User->Name.AnsiCompareIC(((TChatUser*)UserListBox->Items->Objects[i])->Name) == 0) {
*((TChatUser*)UserListBox->Items->Objects[i]) = *User;
delete User;
UserListBox->Items->Strings[i] = Name;
return true;
}
}
// add new user
UserListBox->Items->AddObject(Name,User);
return true;
}
bool TChatChannelFrame::RemoveUser(AnsiString Name)
{
for(int i = 0; i < UserListBox->Items->Count; i++) {
TChatUser* User = (TChatUser*)UserListBox->Items->Objects[i];
if(Name.AnsiCompareIC(User->Name) == 0) {
UserListBox->Items->Delete(i);
delete User;
return true;
}
}
return false;
}
bool TChatChannelFrame::ExistsUser(AnsiString Name)
{
for(int i = 0; i < UserListBox->Items->Count; i++) {
TChatUser* User = (TChatUser*)UserListBox->Items->Objects[i];
if(Name.AnsiCompareIC(User->Name) == 0)
return true;
}
return false;
}
bool TChatChannelFrame::JoinUser(AnsiString Name, AnsiString Address, TColor Color)
{
if(AddUser(Name)) {
Print(Name + " (" + Address + ") has joined " + GetChannel(),Color,true,true);
return true;
}
return false;
}
bool TChatChannelFrame::PartUser(AnsiString Name, AnsiString Address,
AnsiString Message, TColor Color)
{
if(RemoveUser(Name)) {
Print(Name + " (" + Address + ") has left " + GetChannel() + " (" + Message + ")",Color,true,true);
return true;
}
return false;
}
bool TChatChannelFrame::RenameUser(AnsiString OldName, AnsiString NewName,
TColor Color)
{
// find old user
for(int i = 0; i < UserListBox->Items->Count; i++) {
TChatUser* User = (TChatUser*)UserListBox->Items->Objects[i];
if(OldName.AnsiCompareIC(User->Name) == 0) {
User->Name = NewName;
// recreate decorated name
NewName = User->Op ? "@" : (User->Voice ? "+" : "");
NewName += User->Name;
UserListBox->Items->Strings[i] = NewName;
Print(OldName + " is now known as " + User->Name,Color,true,true);
return true;
}
}
return false;
}
bool TChatChannelFrame::QuitUser(AnsiString Name, AnsiString Address,
AnsiString Message, TColor Color)
{
if(RemoveUser(Name)) {
Print(Name + " (" + Address + ") Quit (" + Message + ")",Color,true,true);
return true;
}
return false;
}
bool TChatChannelFrame::KickUser(AnsiString Name, AnsiString Reason,
AnsiString Oper, TColor Color)
{
if(RemoveUser(Name)) {
Print(Name + " was kicked by " + Oper + " (" + Reason + ")",Color,true,true);
return true;
}
return false;
}
bool TChatChannelFrame::KillUser(AnsiString Name, AnsiString Reason,
AnsiString Oper, TColor Color)
{
if(RemoveUser(Name)) {
Print(Name + " has been killed by " + Oper + " (" + Reason + ")",Color,true,true);
return true;
}
return false;
}
bool TChatChannelFrame::ModeChange(AnsiString Mode, AnsiString Param,
AnsiString Oper, TColor Color)
{
// Print(Oper + " sets " + Mode + " with param " + Param,Color,true,true);
if(Mode[2] == 'o' || Mode[2] == 'v') {
for(int i = 0; i < UserListBox->Items->Count; i++) {
TChatUser* User = (TChatUser*)UserListBox->Items->Objects[i];
if(Param.AnsiCompareIC(User->Name) == 0) {
if(Mode[2] == 'o')
User->Op = (Mode[1] == '+');
else if(Mode[2] == 'v')
User->Voice = (Mode[1] == '+');
// recreate decorated name
Param = User->Op ? "@" : (User->Voice ? "+" : "");
Param += User->Name;
UserListBox->Items->Strings[i] = Param;
// force resort
UserListBox->Sorted = false;
UserListBox->Sorted = true;
return true;
}
}
}
return false;
}
//---------------------------------------------------------------------------
bool TChatChannelFrame::SetTopic(AnsiString Topic, TColor Color)
{
TopicStatic->Caption = Topic;
Print(AnsiString("Topic is '") + Topic + "'",Color,true,true);
}
bool TChatChannelFrame::ChangeTopic(AnsiString User, AnsiString Topic, TColor Color)
{
TopicStatic->Caption = Topic;
Print(User + " changes topic to '" + Topic + "'",Color,true,true);
}
bool TChatChannelFrame::SetTopicInfo(AnsiString User, TDateTime When,
TColor Color)
{
Print(AnsiString("Set by ") + User + " on " + When,Color,true,true);
}
//---------------------------------------------------------------------------
void __fastcall TChatChannelFrame::SendEditKeyPress(TObject *Sender,
char &Key)
{
if(Key != 13)
return;
Key = 0;
AnsiString Text = SendEdit->Text.TrimLeft();
SendEdit->Clear();
CmdHistoryIndex = -1;
if(Text.Length() == 0) {
::MessageBeep(MB_OK);
return;
}
// 5 seconds flood protection for <up> + <return> sequences
if(LastSendTime != 0 && GetTickCount() - LastSendTime < 1000*5) {
if(CmdHistoryIndex >= 0 && Text == CmdHistory->Strings[CmdHistoryIndex])
{
::MessageBeep(MB_OK);
return;
}
}
// save line in history
CmdHistory->Insert(0,Text);
while(CmdHistory->Count > MaxHistorySize)
CmdHistory->Delete(CmdHistory->Count-1);
// call handler which parses command
LastSendTime = GetTickCount();
if(FOnCommand)
FOnCommand(this,Text);
}
void __fastcall TChatChannelFrame::SendEditKeyDown(TObject *Sender,
WORD &Key, TShiftState Shift)
{
switch(Key) {
case VK_UP:
if(CmdHistoryIndex < CmdHistory->Count - 1) {
CmdHistoryIndex++;
SendEdit->Text = CmdHistory->Strings[CmdHistoryIndex];
SendEdit->SelLength = 0;
SendEdit->SelStart = SendEdit->Text.Length();
} else {
::MessageBeep(MB_OK);
}
Key = 0;
break;
case VK_DOWN:
if(CmdHistoryIndex <= -1) {
if(SendEdit->Text != "")
SendEdit->Text = "";
else
::MessageBeep(MB_OK);
} else {
CmdHistoryIndex--;
if(CmdHistoryIndex >= 0)
SendEdit->Text = CmdHistory->Strings[CmdHistoryIndex];
else
SendEdit->Text = "";
}
SendEdit->SelLength = 0;
SendEdit->SelStart = SendEdit->Text.Length();
Key = 0;
break;
}
}
void __fastcall TChatChannelFrame::RecvRichEditKeyPress(TObject *Sender,
char &Key)
{
// set focus to send edit
SendEdit->SetFocus();
}
//---------------------------------------------------------------------------
void __fastcall TChatChannelFrame::UserListBoxDblClick(TObject *Sender)
{
// open query window for double clicked user
if(UserListBox->ItemIndex == -1)
return;
TChatUser* User = (TChatUser*)UserListBox->Items->Objects[UserListBox->ItemIndex];
if(FOnCommand)
FOnCommand(this,AnsiString("/query ") + User->Name);
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -