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

📄 chatchannelpage.cpp

📁 Last change: 2008-02-03 This is the source code of KCeasy。
💻 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 + -