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

📄 chatpage.cpp

📁 Last change: 2008-02-03 This is the source code of KCeasy。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        ChannelFrame->SendEdit->SetFocus();
    // remove highlight from new page
    PageCtrl->ActivePage->Highlighted = false;
}
//---------------------------------------------------------------------------
AnsiString TChatForm::FilterColors(AnsiString Text)
{
    char* src = Text.c_str();
    AnsiString Dst;

    // This horror documented at:
    // http://www.visualirc.net/tech-attrs.php
    // http://www.ircle.com/colorfaq.shtml
    // http://www.mirc.co.uk/help/color.txt

    while(*src) {
        switch(*src) {
        case 2: // bold
        case 15: // normal
        case 17: // fixed pitch
        case 18: // inverse
        case 22: // italic
        case 29: // italic
        case 31: // underline
            src++;
            break;
        case 3: // mirc color joyride
            // Theory of operation: Remove aggressively. People who use colors
            // tend to not have anything interesting to say anyway.
            src++;
            if(!isdigit(*src))
                break;
            for(int i = 0; i < 2 && isdigit(*src) && *src != ','; i++)
                src++;
            if(*src != ',')
                break;
            src++;
            for(int i = 0; i < 2 && isdigit(*src); i++)
                src++;
            break;
        case 4: // 6 digit hex color
            src++;
            for(int i = 0; i < 6 && *src; i++)
                src++;
            break;
        default:
            Dst += *src;
            src++;
        }
    }

    return Dst;
}

AnsiString TChatForm::GetToken(AnsiString* Text)
{
    int pos = Text->Pos(" ");

    if(pos == 0) {
        AnsiString Token = *Text;
        *Text = "";
        return Token;
    } else {
        AnsiString Token = Text->SubString(1,pos-1);
        *Text = Text->SubString(pos+1,Text->Length()-pos);
        return Token;
    }
}

typedef struct
{
    char* Name;           // command name
    char* Args;           // arguments
    char* Descr;          // command description
    bool MustBeConnected; // true if command requires being connected
    bool AllowedInStatus; // true if command is allowed in status window
} TIrcCmd;

static const TIrcCmd IrcCmdTable[] =
{
    { "help",   "",              "Shows list of available commands",                          false, true },
    { "topic",  "",              "Show current topic",                                        true,  false },
    { "query",  "<user> [text]", "Open new window for this user and optionally send message", true,  false },
    { "msg",    "<user> <text>", "Send message to user without opening new window",           true,  true },
    { "notice", "<user> <text>", "Send notice to user",                                       true,  true },
    { "me",     "<action>",      "Perform action",                                            true,  false },
    { "join",   "<room>",        "Join room",                                                 true,  true },
    { "part",   "[room]",        "Leave room",                                                true,  true },
    { "whois",  "<user>",        "Show info about user in status window",                     true,  true },
    { "list",   "",              "Refresh list of rooms",                                     true,  true },
    { "nick",   "<nickname>",    "Change your current nickname",                              true,  true },
    { "clear",  "",              "Clear screen",                                              false, true },
    { "close",  "",              "Close window, leaves room if necessary",                    false, false},
    { "quit",   "[message]",     "Quit with message",                                         true,  true },
    { "raw",    "<command>",     "Send raw command to server",                                true,  true },
    { "server", "[host] [port]", "Connect to another IRC server",                             false, true },
    { NULL, NULL, NULL, false, false }
};

void __fastcall TChatForm::ChannelFrameOnCommand(TChatChannelFrame* ChannelFrame,
                                                 AnsiString Text)
{
#define PRINT ChannelFrame->Print
    const TIrcCmd* Cmd = NULL;

    if(Text.Length() == 0)
        return;

    if(Text[1] == '/') {
        AnsiString Name = GetToken(&Text).LowerCase();

        for(int i = 0; IrcCmdTable[i].Name; i++) {
            if(stricmp(IrcCmdTable[i].Name,Name.c_str() + 1) == 0) {
                Cmd = &IrcCmdTable[i];
                break;
            }
        }

        if(!Cmd) {
            PRINT(AnsiString("Unknown command: " + Name + " " + Text),ColInfo,false,true);
            return;
        }
    } else {
        // message to either channel or user but not a command
        if(ChannelFrame == StatusFrame) {
            PRINT(AnsiString("You are not in a room"),ColInfo,false,true);
            return;
        }

        if(!Connected) {
            PRINT("Not connected",ColInfo,false,true);
            return;
        }

        PRINT(AnsiString("<") + Irc->UserInfo->Nick + "> " + Text,ColOwn,true);
        Irc->Say(ChannelFrame->GetChannel(), Text);
        return;
    }

    // filter commands invalid in status window
    if(ChannelFrame == StatusFrame && !Cmd->AllowedInStatus) {
        PRINT(AnsiString("This command is only valid in a room"),ColInfo,false,true);
        return;
    }

    // filter commands invalid while not connected
    if(Cmd->MustBeConnected && !Connected) {
        PRINT(AnsiString("This command is only valid when connected"),ColInfo,false,true);
        return;
    }

    // now handle the commands
    string CmdName = Cmd->Name;

    if(CmdName == "help") {
        PRINT("Available commands:",ColInfo,false,true);
        for(int i = 0; IrcCmdTable[i].Name; i++) {
            AnsiString Line;
            Line.printf("/%-6s %-13s - %s", IrcCmdTable[i].Name,
                        IrcCmdTable[i].Args, IrcCmdTable[i].Descr);
            PRINT(Line,ColInfo,false,true);
        }

    } else if(CmdName == "topic") {
        if(ChannelFrame->IsUserChat()) {
            PRINT("Your a not in a room",ColInfo,false,true);
            return;
        }
        Irc->GetTopic(ChannelFrame->GetChannel());

    } else if(CmdName == "query") {
        AnsiString User = GetToken(&Text);
        if(User == "") {
            PRINT("/query: Insufficient parameters",ColInfo,false,true);
            return;
        }
        // now either find window for this user or create one
        TChatChannelFrame* NewFrame = GetChannelFrame(User);
        if(!NewFrame) {
            // only open window if user exists in channel this was typed into
            if(!ChannelFrame->ExistsUser(User) && ChannelFrame != StatusFrame) {
                PRINT("/query: User '" + User + "' not in this channel",ColInfo,false,true);
                return;
            }
            NewFrame = NewChannelFrame(User,true);
            NewFrame->Print(AnsiString("Now talking to ") + User,ColJoin,true,true);
        }

        // if user specified a message, send it
        if(Text != "") {
            NewFrame->Print(AnsiString("<") + Irc->UserInfo->Nick + "> " + Text,ColOwn,true);
            Irc->Say(User,Text);
        }

    } else if(CmdName == "msg") {
        AnsiString User = GetToken(&Text);
        if(User == "" || Text == "") {
            PRINT("/msg: Insufficient parameters",ColInfo,false,true);
            return;
        }
        PRINT(AnsiString("-> *") + User + "* " + Text,ColOwn,true,false);
        Irc->Say(User,Text);

    } else if(CmdName == "notice") {
        AnsiString User = GetToken(&Text);
        if(User == "" || Text == "") {
            PRINT("/notice: Insufficient parameters",ColInfo,false,true);
            return;
        }
        PRINT(AnsiString("-> -") + User + "- " + Text,ColOwn,true,false);
        Irc->Notice(User,Text);

    } else if(CmdName == "me") {
        if(Text == "") {
            PRINT("/me: Insufficient parameters",ColInfo,false,true);
            return;
        }
        PRINT(Irc->CurrentNick + " " + Text,ColAction,true,true);
        Irc->CTCPQuery(ChannelFrame->GetChannel(),"ACTION",Text);

    } else if(CmdName == "join") {
        if(Text == "") {
            PRINT("/join: Insufficient parameters",ColInfo,false,true);
            return;
        }
        // if there is already a window for the channel switch now
        TChatChannelFrame* Frame = GetChannelFrame(Text);
        if(Frame)
            PageCtrl->ActivePage = (TTabSheet*)Frame->Parent;
        // actually join channel
        Irc->Join(Text);

    } else if(CmdName == "part") {
        if(Text == "" && !ChannelFrame->IsUserChat())
            Text = ChannelFrame->GetChannel();

        if(Text == "") {
            PRINT("/part: Insufficient parameters",ColInfo,false,true);
            return;
        }
        Irc->Part(Text,"");

    } else if(CmdName == "whois") {
        if(Text == "") {
            PRINT("/whois: Insufficient parameters",ColInfo,false,true);
            return;
        }
        Irc->Raw(AnsiString("WHOIS ") + Text);

    } else if(CmdName == "list") {
        if(ListingChannels) {
            PRINT("/list: Already refreshing rooms",ColInfo,false,true);
            return;
        }
        ChannelsListView->Clear();
        ListingChannels = true;
        Irc->Raw("LIST");

    } else if(CmdName == "nick") {
        if(Text == "") {
            PRINT("/nick: Insufficient parameters",ColInfo,false,true);
            return;
        }
        Irc->Raw(AnsiString("NICK ") + Text);

    } else if(CmdName == "raw") {
        if(Text == "") {
            PRINT("/raw: Insufficient parameters",ColInfo,false,true);
            return;
        }
        Irc->Raw(Text);

    } else if(CmdName == "quit") {
        Irc->Quit(Text);

    } else if(CmdName == "server") {
        AnsiString Host = GetToken(&Text);

        if(Host == "")
            Connect();
        else if (Text == "" || StrToInt64(Text) <= 0)
            Connect(Host,6667);
        else
            Connect(Host,StrToInt64(Text));

    } else if(CmdName == "clear") {
        ChannelFrame->RecvRichEdit->Clear();
        if(ChannelFrame->RecvRichEdit->Focused())
            ChannelFrame->SendEdit->SetFocus();

    } else if(CmdName == "close") {
        // part just in case
        if(!ChannelFrame->IsUserChat())
            Irc->Part(ChannelFrame->GetChannel(),"");
        DeleteChannelFrame(ChannelFrame);

    } else {
        PRINT("Known command not handled. This is a bug!",ColWarn,false,true);
        return;
    }
#undef PRINT
}
//---------------------------------------------------------------------------

void __fastcall TChatForm::ChannelsListViewCompare(TObject *Sender,
      TListItem *Item1, TListItem *Item2, int Data, int &Compare)
{
    switch(Data) {
    case 1: // users
    {
        int a = Item1->SubItems->Strings[0].ToInt();
        int b = Item2->SubItems->Strings[0].ToInt();
        Compare = a < b ? 1 : (a > b ? -1 : 0);
        break;
    }
    case 2: // topic
        Compare = Item1->SubItems->Strings[1].AnsiCompareIC(Item2->SubItems->Strings[1]);
        break;
    case 0: // channel name
    default:
        Compare = Item1->Caption.AnsiCompareIC(Item2->Caption);
        break;
    };
}

void __fastcall TChatForm::ChannelsListViewColumnClick(TObject *Sender,
      TListColumn *Column)
{
    ChannelsListView->CustomSort(NULL,Column->Index);
}

void __fastcall TChatForm::ChannelsListViewDblClick(TObject *Sender)
{
    if(!ChannelsListView->ItemFocused)
        return;
    // simulate join command from status window
    ChannelFrameOnCommand(StatusFrame,AnsiString("/join ") + ChannelsListView->ItemFocused->Caption);
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -