📄 chatpage.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 "ChatPage.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "XiRC"
#pragma link "ChatChannelPage"
#pragma resource "*.dfm"
TChatForm *ChatForm;
//---------------------------------------------------------------------------
__fastcall TChatForm::TChatForm(TComponent* Owner)
: TForm(Owner),
ChatFont(NULL),
Connected(false),
LogRaw(false),
GotInfo(false),
GotMOTD(false),
ListingChannels(false),
StatusFrame(NULL),
NewPort(0)
{
TranslateComponent(this);
LogRaw = Config->GetValueInt("chat/log_raw_messages");
// load font settings
ChatFont = StringToFont(Config->GetValue("chat/font"));
ChatFont->Color = clWindowText; // not loaded so set default
ColNormal = StringToColor(Config->GetValue("chat/color_normal").c_str());
ColOthers = StringToColor(Config->GetValue("chat/color_others").c_str());
ColOwn = StringToColor(Config->GetValue("chat/color_own").c_str());
ColNotice = StringToColor(Config->GetValue("chat/color_notice").c_str());
ColAction = StringToColor(Config->GetValue("chat/color_action").c_str());
ColJoin = StringToColor(Config->GetValue("chat/color_join").c_str());
ColInfo = StringToColor(Config->GetValue("chat/color_info").c_str());
ColWarn = StringToColor(Config->GetValue("chat/color_warn").c_str());
ColDebug = StringToColor(Config->GetValue("chat/color_debug").c_str());
// set font for channels list view
ChannelsListView->Font->Assign(ChatFont);
// init status page
StatusFrame = new TChatChannelFrame(StatusSheet,"<STATUS_FRAME>",true);
StatusFrame->OnCommand = ChannelFrameOnCommand;
StatusFrame->SetChatFont(ChatFont);
StatusFrame->Parent = StatusSheet;
PageCtrl->ActivePage = StatusSheet;
// init irc control with sane defaults
Irc->CTCPInfo->Version = Brand->GetAppName() + " (" +
Brand->GetVersionString() + ") IRC client";
Irc->UserInfo->Nick = "";
Irc->UserInfo->AltNick = "";
Irc->UserInfo->UserName = "";
Irc->UserInfo->Email = "nobody@example.com";
// get nick from config
NickEdit->Text = string_trim(Config->GetValue("chat/nick")).c_str();
if(NickEdit->Text == "") {
// create random nick
#if 0
NickEdit->Text = Brand->GetAppName() + IntToStr(RandomRange(1000,9999));
#endif
}
}
__fastcall TChatForm::~TChatForm()
{
}
void __fastcall TChatForm::Release()
{
// Irc->Disconnect();
TForm::Release();
}
void __fastcall TChatForm::PageActivated()
{
TChatChannelFrame* ChannelFrame;
if(PageCtrl->ActivePage == StatusSheet)
ChannelFrame = StatusFrame;
else
ChannelFrame = (TChatChannelFrame*)PageCtrl->ActivePage->Tag;
if(ChannelFrame)
ChannelFrame->SendEdit->SetFocus();
}
//---------------------------------------------------------------------------
bool TChatForm::Connect(AnsiString Host, unsigned int Port)
{
if(Connected) {
// disconnect and schedule a reconnect if requested
if(Host != "") {
NewHost = Host;
NewPort = Port;
}
Disconnect();
} else {
if(NickEdit->Text == "") {
// TRANSLATOR: message box when no chat nick is specified
MessageDlg(_("You have to choose a nickname before you can connect."),
mtError,TMsgDlgButtons() << mbOK,0);
return false;
}
GotInfo = false;
GotMOTD = false;
ListingChannels = false;
LogRaw = Config->GetValueInt("chat/log_raw_messages");
// load irc server settings
if(Host != "") {
Irc->Host = Host;
Irc->Port = Port;
} else {
Irc->Host = Config->GetValue("chat/host").c_str();
Irc->Port = Config->GetValueInt("chat/port");
}
Irc->UserInfo->Nick = NickEdit->Text;
Irc->UserInfo->UserName = NickEdit->Text;
Config->SetValue("chat/nick", NickEdit->Text.c_str());
Irc->Connect();
// TRANSLATOR: Chat connect button
ConnectBtn->Caption = _("Disconnect");
PrintStatus("Connecting to " + Irc->Host + ":" + IntToStr(Irc->Port),ColInfo,true,true);
NickEdit->Enabled = false;
Connected = true;
// switch to status page
PageCtrl->ActivePage = StatusSheet;
StatusFrame->SendEdit->SetFocus();
}
return true;
}
bool TChatForm::Disconnect()
{
Irc->Disconnect();
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::ConnectBtnClick(TObject *Sender)
{
if(Connected)
Disconnect();
else
Connect();
}
void __fastcall TChatForm::NickEditKeyPress(TObject *Sender, char &Key)
{
if(Key == 13) {
Key = 0;
ConnectBtn->Click();
}
}
void __fastcall TChatForm::RefreshChannelsBtnClick(TObject *Sender)
{
if(Connected)
ChannelFrameOnCommand(StatusFrame,"/list");
}
void __fastcall TChatForm::CloseChannelBtnClick(TObject *Sender)
{
TChatChannelFrame* ChannelFrame = (TChatChannelFrame*)PageCtrl->ActivePage->Tag;
if(ChannelFrame)
ChannelFrameOnCommand(ChannelFrame,"/close");
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::IrcConnect()
{
PrintStatus("Connected",ColInfo,true,true);
PrintStatus("--",ColNormal,false,false);
}
void __fastcall TChatForm::IrcDisConnect()
{
// TRANSLATOR: Chat connect button
ConnectBtn->Caption = _("Connect");
NickEdit->Enabled = true;
Connected = false;
// cleanup all channel pages
for(int i = 0; i < PageCtrl->PageCount; i++) {
TChatChannelFrame* ChannelFrame = (TChatChannelFrame*)PageCtrl->Pages[i]->Tag;
if(ChannelFrame) {
DeleteChannelFrame(ChannelFrame);
i = 0; // restart since index changed
}
}
// Cleanup channel list
ChannelsListView->Clear();
ListingChannels = false;
PrintStatus("Disconnected",ColInfo,true,true);
// reconnect if scheduled
if(NewHost != "") {
Connect(NewHost,NewPort);
NewHost = "";
NewPort = 0;
}
}
void __fastcall TChatForm::IrcLoggedIn(AnsiString ServerName,
AnsiString NickName)
{
PrintStatus("--",ColNormal,false,false);
PrintStatus("Logged in",ColInfo,true,true);
PrintStatus("--",ColNormal,false,false);
// update config and nick edit if the user changed nick in order to connect
if(Irc->CurrentNick.AnsiCompareIC(NickEdit->Text) != 0) {
NickEdit->Text = Irc->CurrentNick;
Config->SetValue("chat/nick",Irc->CurrentNick.c_str());
}
// identify with nickserv if password is set in config
string Pwd = string_trim(Config->GetValue("chat/nickserv_password"));
if(Pwd != "") {
ChannelFrameOnCommand(StatusFrame,AnsiString("/msg nickserv identify ") + Pwd.c_str());
PrintStatus("--",ColNormal,false,false);
}
// join all channels specified in config
list<string> Chans = string_split(Config->GetValue("chat/channels"),",");
for(list<string>::iterator itr = Chans.begin(); itr != Chans.end(); ++itr) {
*itr = string_trim(*itr);
if(*itr != "")
Irc->Join((*itr).c_str());
}
}
//---------------------------------------------------------------------------
void __fastcall TChatForm::IrcError(int ErrorNumber, AnsiString ErrorMsg)
{
if(ErrorNumber == 451) // Ignore 'You are not registered' error
return;
PrintStatus(AnsiString("Error: ") + IntToStr(ErrorNumber) + " (" + ErrorMsg + ")",ColWarn,true,true);
PrintStatus("--",ColNormal,false,false);
}
void __fastcall TChatForm::IrcServerError(AnsiString ErrorMsg)
{
PrintStatus(AnsiString("Server Error: ") + ErrorMsg,ColWarn,true,true);
PrintStatus("--",ColNormal,false,false);
}
void __fastcall TChatForm::IrcServerMsg(AnsiString Text)
{
PrintStatus(Text,ColNormal,false,false);
}
void __fastcall TChatForm::IrcRaw(AnsiString Text)
{
if(LogRaw)
PrintStatus(AnsiString("Raw: ") + Text,ColDebug,true,false);
}
void __fastcall TChatForm::IrcNumeric(int Cmd, AnsiString Content,
AnsiString Nick, AnsiString Address)
{
switch(Cmd) {
case 431: // ERR_NONICKNAMEGIVEN
case 432: // ERR_ERRONEUSNICKNAME
PrintStatus("The nickname you chose contains invalid characters or is too long.",ColWarn,true,true);
PrintStatus("Use the command /nick <nickname> to try another one.",ColInfo,true,true);
PrintStatus("--",ColNormal,false,false);
PageCtrl->ActivePage = StatusSheet;
break;
case 433: // ERR_NICKNAMEINUSE
case 437: // ERR_UNAVAILRESOURCE (note: may happen for channels as well)
PrintStatus("The nickname you chose is already in use.",ColWarn,true,true);
PrintStatus("Use the command /nick <nickname> to try another one.",ColInfo,true,true);
PrintStatus("--",ColNormal,false,false);
PageCtrl->ActivePage = StatusSheet;
break;
case 321: // RPL_LISTSTART "Channel :Users Name"
// should already have been done by /list command
ListingChannels = true;
ChannelsListView->Clear();
break;
case 322: // RPL_LIST "<channel> <# visible> :<topic>"
{
TListItem* Item = ChannelsListView->Items->Add();
Item->Caption = GetToken(&Content);
Item->SubItems->Add(GetToken(&Content));
Item->SubItems->Add(FilterColors(Content.SubString(2,Content.Length()-1)));
break;
}
case 323: // RPL_LISTEND ":End of /LIST"
ListingChannels = false;
ChannelsListView->CustomSort(NULL,1); // sort by number of users
// highlight channel tab if not active
if(Config->GetValueInt("chat/highlight_channels") && PageCtrl->ActivePage != ChannelsSheet)
ChannelsSheet->Highlighted = true;
break;
};
}
void __fastcall TChatForm::IrcInfo(AnsiString Info)
{
if(!GotInfo) {
PrintStatus("--",ColNormal,false,false);
GotInfo = true;
}
PrintStatus(Info,ColNormal,false,false);
}
void __fastcall TChatForm::IrcMOTD(AnsiString Content)
{
if(!GotMOTD) {
PrintStatus("--",ColNormal,false,false);
GotMOTD = true;
}
PrintStatus(Content,ColNormal,false,false);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -