⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chatpage.cpp

📁 Last change: 2008-02-03 This is the source code of KCeasy。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*
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 + -