12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193 |
- /*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is Vision.
- *
- * The Initial Developer of the Original Code is The Vision Team.
- * Portions created by The Vision Team are
- * Copyright (C) 1999, 2000, 2001 The Vision Team. All Rights
- * Reserved.
- *
- * Contributor(s): Wade Majors <wade@ezri.org>
- * Rene Gollent
- * Todd Lair
- * Andrew Bazan
- * Jamie Wilkinson
- */
- #include <Beep.h>
- #include <Clipboard.h>
- #include <File.h>
- #include <MenuItem.h>
- #include <Path.h>
- #include <PopUpMenu.h>
- #include <ScrollView.h>
- #include <ctype.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "ClientWindow.h"
- #include "ClientAgent.h"
- #include "ClientAgentInputFilter.h"
- #include "ClientAgentLogger.h"
- #include "HistoryList.h"
- #include "ResizeView.h"
- #include "RunView.h"
- #include "StatusView.h"
- #include "Utilities.h"
- #include "Theme.h"
- #include "Vision.h"
- #include "VTextControl.h"
- #include "WindowList.h"
- const char *ClientAgent::endl ("\1\1\1\1\1");
- ClientAgent::ClientAgent (
- const char *id_,
- const char *serverName_,
- const char *myNick_,
- BRect frame_)
- : BView (
- frame_,
- id_,
- B_FOLLOW_ALL_SIDES,
- B_WILL_DRAW | B_FRAME_EVENTS),
- fCancelMLPaste(false),
- fActiveTheme (vision_app->ActiveTheme()),
- fId (id_),
- fServerName (serverName_),
- fMyNick (myNick_),
- fTimeStampState (vision_app->GetBool ("timestamp")),
- fIsLogging (vision_app->GetBool ("log_enabled")),
- fFrame (frame_)
- {
- Init();
- }
- ClientAgent::ClientAgent (
- const char *id_,
- const char *serverName_,
- const char *myNick_,
- const BMessenger &sMsgr_,
- BRect frame_)
- : BView (
- frame_,
- id_,
- B_FOLLOW_ALL_SIDES,
- B_WILL_DRAW),
- fSMsgr (sMsgr_),
- fActiveTheme (vision_app->ActiveTheme()),
- fId (id_),
- fServerName (serverName_),
- fMyNick (myNick_),
- fTimeStampState (vision_app->GetBool ("timestamp")),
- fIsLogging (vision_app->GetBool ("log_enabled")),
- fFrame (frame_)
- {
- fMyLag = "0.000";
- Init();
- // force server agent to post a lag meter update immediately
- fSMsgr.SendMessage (M_LAG_CHANGED);
- }
- ClientAgent::~ClientAgent (void)
- {
- delete fAgentWinItem;
- delete fHistory;
- }
- void
- ClientAgent::AttachedToWindow (void)
- {
- BView::AttachedToWindow();
- fActiveTheme->WriteLock();
- fActiveTheme->AddView (this);
- fActiveTheme->WriteUnlock();
- }
- void
- ClientAgent::DetachedFromWindow (void)
- {
- BView::DetachedFromWindow ();
- fActiveTheme->WriteLock();
- fActiveTheme->RemoveView (this);
- fActiveTheme->WriteUnlock();
- }
- void
- ClientAgent::AllAttached (void)
- {
- fMsgr = BMessenger (this);
- // we initialize the color constants for the fInput control here
- // because BTextControl ignores them prior to being attached for some reason
- fActiveTheme->ReadLock();
- rgb_color fInputColor (fActiveTheme->ForegroundAt (C_INPUT));
- fInput->TextView()->SetFontAndColor (&fActiveTheme->FontAt (F_INPUT), B_FONT_ALL,
- &fInputColor);
- fInput->TextView()->SetViewColor (fActiveTheme->ForegroundAt (C_INPUT_BACKGROUND));
- fInput->TextView()->SetColorSpace (B_RGB32);
- fActiveTheme->ReadUnlock();
- if (fIsLogging)
- {
- BMessage logMessage (M_REGISTER_LOGGER);
- logMessage.AddString ("name", fId.String());
- fSMsgr.SendMessage (&logMessage);
- }
- }
- void
- ClientAgent::Show (void)
- {
- Window()->PostMessage (M_STATUS_CLEAR);
- this->fMsgr.SendMessage (M_STATUS_ADDITEMS);
- BMessage statusMsg (M_CW_UPDATE_STATUS);
- statusMsg.AddPointer ("item", fAgentWinItem);
- statusMsg.AddInt32 ("status", WIN_NORMAL_BIT);
- statusMsg.AddBool ("hidden", false);
- Window()->PostMessage (&statusMsg);
-
- const BRect *agentRect (dynamic_cast<ClientWindow *>(Window())->AgentRect());
-
- if (*agentRect != Frame())
- {
- ResizeTo (agentRect->Width(), agentRect->Height());
- MoveTo (agentRect->left, agentRect->top);
- }
- // make RunView recalculate itself
- fText->Show();
- BView::Show();
- }
- void
- ClientAgent::Init (void)
- {
- SetViewColor (ui_color(B_PANEL_BACKGROUND_COLOR));
- fInput = new VTextControl (
- BRect (
- 0,
- fFrame.top, // tmp. will be moved
- fFrame.right - fFrame.left - 4,
- fFrame.bottom),
- "Input", 0, 0,
- 0,
- B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM);
-
- fInput->SetDivider (0);
- fInput->ResizeToPreferred();
- fInput->MoveTo (
- 0,
- fFrame.bottom - fInput->Frame().Height() - 3);
- AddChild (fInput);
- fInput->TextView()->AddFilter (new ClientAgentInputFilter (this));
- fInput->Invalidate();
-
- fHistory = new HistoryList ();
-
- BRect textrect (
- 2,
- fFrame.top,
- fFrame.right - fFrame.left - 1 - B_V_SCROLL_BAR_WIDTH,
- fFrame.bottom - fInput->Frame().Height() - 8);
-
- fText = new RunView (
- textrect,
- fId.String(),
- fActiveTheme,
- B_FOLLOW_ALL);
-
- fText->SetClippingName (fId.String());
-
- if (vision_app->GetBool ("timestamp"))
- fText->SetTimeStampFormat (vision_app->GetString ("timestamp_format"));
-
- fTextScroll = new BScrollView (
- "textscroll",
- fText,
- B_FOLLOW_ALL,
- 0,
- false,
- true,
- B_PLAIN_BORDER);
-
- AddChild (fTextScroll);
- }
- void
- ClientAgent::ScrollRange (float *scrollMin, float *scrollMax) const
- {
- fTextScroll->ScrollBar(B_VERTICAL)->GetRange (scrollMin, scrollMax);
- }
- float
- ClientAgent::ScrollPos (void) const
- {
- return fTextScroll->ScrollBar (B_VERTICAL)->Value();
- }
- void
- ClientAgent::SetScrollPos (float value)
- {
- fTextScroll->ScrollBar (B_VERTICAL)->SetValue(value);
- }
- void
- ClientAgent::SetServerName (const char *name)
- {
- fServerName = name;
- }
- void
- ClientAgent::SetEditStates (BMenu *menu, bool targetonly)
- {
- if (menu != NULL)
- {
- if (targetonly)
- {
- menu->SetTargetForItems(fInput->TextView());
- return;
- }
- BMenuItem *menuItem (menu->FindItem(S_CW_EDIT_CUT));
- int32 start (0), finish (0);
- fInput->TextView()->GetSelection(&start, &finish);
- if (start == finish)
- {
- menuItem->SetEnabled (false);
- }
- else
- {
- menuItem->SetEnabled (true);
- menuItem->SetTarget (fInput->TextView());
- }
- menuItem = menu->FindItem(S_CW_EDIT_COPY);
- if (start == finish)
- {
- BString string;
- // check text display
- fText->GetSelectionText(string);
- if (string.Length() > 0)
- {
- menuItem->SetTarget (fInput->TextView());
- menuItem->SetEnabled (true);
- }
- else
- {
- menuItem->SetEnabled (false);
- }
- }
- else
- {
- menuItem->SetTarget (fInput->TextView());
- menuItem->SetEnabled (true);
- }
- menuItem = menu->FindItem(S_CW_EDIT_PASTE);
- menuItem->SetTarget (fInput->TextView());
- BClipboard clipboard("system");
- BMessage *clip ((BMessage *)NULL);
- if (clipboard.Lock()) {
- if ((clip = clipboard.Data()))
- if (clip->HasData ("text/plain", B_MIME_TYPE))
- menuItem->SetEnabled(true);
- else
- menuItem->SetEnabled(false);
- clipboard.Unlock();
- }
- menuItem = menu->FindItem(S_CW_EDIT_SELECT_ALL);
- if (fInput->TextView()->TextLength() == 0)
- menuItem->SetTarget (fText);
- else
- menuItem->SetTarget (fInput->TextView());
- }
- }
- BString
- ClientAgent::FilterCrap (const char *data, bool force)
- {
- BString outData ("", 440);
- int32 theChars (strlen (data));
- bool ViewCodes (false);
- int32 i (0), j(0);
- for (i = 0; i < theChars; ++i)
- {
- if (data[i] == 3 && !force && !vision_app->GetBool ("stripcolors"))
- outData << data[i];
- else if (data[i] > 1 && data[i] < 32)
- {
- if (data[i] == 3)
- {
- if (ViewCodes)
- outData << "[0x03]{";
- ++i;
-
- // filter foreground
- for (j = 0; j < 2; j++)
- if (data[i] >= '0' && data[i] <= '9')
- {
- if (ViewCodes)
- outData << data[i];
- ++i;
- }
- else break;
-
- if (data[i] == ',')
- {
- if (ViewCodes)
- outData << data[i];
- ++i;
- for (j = 0; j < 2; j++)
- if (data[i] >= '0' && data[i] <= '9')
- {
- if (ViewCodes)
- outData << data[i];
- ++i;
- }
- else break;
- }
- --i;
-
- if (ViewCodes)
- outData << "}";
- }
- else if (ViewCodes)
- {
- char buffer[16];
- sprintf (buffer, "[0x%02x]", data[i]);
- outData << buffer;
- }
- }
- else
- outData << data[i];
- }
- return outData;
- }
- void
- ClientAgent::Submit (
- const char *buffer,
- bool clear,
- bool fHistoryAdd)
- {
- BString cmd;
-
- if (fHistoryAdd)
- cmd = fHistory->Submit (buffer);
- else
- cmd = buffer;
- if (clear) fInput->SetText ("");
- if (cmd.Length()
- && !SlashParser (cmd.String())
- && cmd[0] != '/')
- {
- BString tmp;
- // break strings up by 440 lens to ensure user doesn't lose data
- while (cmd.Length() > 0)
- {
- cmd.MoveInto (tmp, 0, Get440Len(cmd.String()));
- Parser (tmp.String());
- tmp = "";
- }
- }
- }
- int32
- ClientAgent::TimedSubmit (void *arg)
- {
- BMessage *msg (reinterpret_cast<BMessage *>(arg));
- ClientAgent *agent;
- ClientWindow *window;
- BString buffer;
- int32 i;
- bool addtofHistory (true);
- if (msg->FindPointer ("agent", reinterpret_cast<void **>(&agent)) != B_OK)
- {
- printf (":ERROR: no valid agent pointer found in TimedSubmit, bailing...\n");
- return -1;
- }
- if (msg->FindPointer ("window", reinterpret_cast<void **>(&window)) != B_OK)
- {
- printf (":ERROR: no valid window pointer found in TimedSubmit, bailing...\n");
- return -1;
- }
- bool delay (!msg->HasBool ("delay"));
- bool autoexec (msg->FindBool ("autoexec"));
- if (autoexec)
- addtofHistory = false;
- BMessenger agentMsgr (agent);
- BMessage submitMsg (M_SUBMIT);
- submitMsg.AddBool ("history", addtofHistory);
- submitMsg.AddBool ("clear", false);
-
- for (i = 0; (msg->HasString ("data", i)) && (agentMsgr.IsValid()) && (false == agent->CancelMultilineTextPaste()); ++i)
- {
- BString data;
- msg->FindString ("data", i, &data);
-
- // add a space so /'s don't get triggered as commands
- if (!autoexec)
- data.Prepend (" ");
-
- if (!submitMsg.HasString ("input"))
- submitMsg.AddString ("input", data);
- else
- submitMsg.ReplaceString ("input", data);
- // :TODO: wade 020101 move locks to ParseCmd?
- if (agentMsgr.IsValid())
- {
- agentMsgr.SendMessage (&submitMsg);
- // A small attempt to appease the
- // kicker gods
- if (delay)
- snooze (600000);
- }
- }
- delete msg;
- return 0;
- }
- void
- ClientAgent::PackDisplay (
- BMessage *msg,
- const char *buffer,
- uint32 fore,
- uint32 back,
- uint32 font)
- {
- BMessage packed;
-
- packed.AddString ("msgz", buffer);
- packed.AddInt32 ("fore", fore);
- packed.AddInt32 ("back", back);
- packed.AddInt32 ("font", font);
-
- if (msg->HasMessage ("packed"))
- msg->ReplaceMessage ("packed", &packed);
- else
- msg->AddMessage ("packed", &packed);
- }
- void
- ClientAgent::Display (
- const char *buffer,
- uint32 fore,
- uint32 back,
- uint32 font)
- {
- // displays normal text if no color codes are present
- // (i.e. if the text has already been filtered by ServerAgent::FilterCrap
- ParsemIRCColors (buffer, fore, back, font);
- if (IsHidden())
- {
- BMessage statusMsg (M_CW_UPDATE_STATUS);
- statusMsg.AddPointer ("item", fAgentWinItem);
- statusMsg.AddInt32 ("status", WIN_PAGESIX_BIT);
- Window()->PostMessage (&statusMsg);
- }
- if (fIsLogging)
- {
- BMessage logMessage (M_CLIENT_LOG);
- logMessage.AddString ("name", fId.String());
- logMessage.AddString ("data", buffer);
- fSMsgr.SendMessage (&logMessage);
- }
- }
- void
- ClientAgent::ParsemIRCColors (
- const char *buffer,
- uint32 fore,
- uint32 back,
- uint32 font)
- {
- int mircFore (fore),
- mircBack (back),
- mircFont (font),
- i (0);
- const char *start (NULL);
-
- while (buffer && *buffer)
- {
- start = buffer;
- while (*buffer)
- {
- if (*buffer != 3)
- {
- ++buffer;
- continue;
- }
- if (*buffer == 3 && start != buffer)
- break;
- ++buffer;
- if (!isdigit (*buffer))
- {
- // reset
- mircFore = fore;
- mircBack = back;
- mircFont = font;
- break;
- }
- else
- {
- // parse colors
- mircFore = 0;
- for (i = 0; i < 2; i++)
- {
- if (!isdigit (*buffer))
- break;
- mircFore = mircFore * 10 + *buffer++ - '0';
- }
- mircFore = (mircFore % 16) + C_MIRC_WHITE;
-
- if (*buffer == ',')
- {
- ++buffer;
- mircBack = 0;
- for (i = 0; i < 2; i++)
- {
- if (!isdigit (*buffer))
- break;
- mircBack = mircBack * 10 + *buffer++ - '0';
- }
- mircBack = (mircFore % 16) + C_MIRC_WHITE;
- }
- }
- // set start to text portion (we have recorded the mirc stuff)
- start = buffer;
- }
- if (buffer > start)
- fText->Append (start, buffer - start, mircFore, mircBack, mircFont);
- }
- }
- void
- ClientAgent::Parser (const char *)
- {
- // do nothing
- }
- void
- ClientAgent::TabExpansion (void)
- {
- // do nothing
- }
- void
- ClientAgent::DroppedFile (BMessage *)
- {
- // do nothing
- }
- bool
- ClientAgent::SlashParser (const char *data)
- {
- BString first (GetWord (data, 1).ToUpper());
- if (ParseCmd (data))
- return true;
- return false;
- }
- void
- ClientAgent::UpdateStatus (int32 status)
- {
- BMessage statusMsg (M_CW_UPDATE_STATUS);
- statusMsg.AddPointer ("item", fAgentWinItem);
- statusMsg.AddInt32 ("status", status);
- Window()->PostMessage (&statusMsg);
- if (status == WIN_NICK_BIT)
- system_beep(kSoundEventNames[(uint32)seNickMentioned]);
- }
- void
- ClientAgent::MessageReceived (BMessage *msg)
- {
- switch (msg->what)
- {
- // 22/8/99: this will now look for "text" to add to the
- // fInput view. -jamie
- case M_INPUT_FOCUS:
- {
- if (msg->HasString ("text"))
- {
- BString newtext;
- newtext = fInput->Text();
- newtext.Append (msg->FindString("text"));
- fInput->SetText (newtext.String());
- }
- fInput->MakeFocus (true);
- // We don't like your silly selecting-on-focus.
- fInput->TextView()->Select (fInput->TextView()->TextLength(),
- fInput->TextView()->TextLength());
- }
- break;
- case M_CLIENT_QUIT:
- {
- if (fIsLogging &&
- !(msg->HasBool("vision:shutdown") && msg->FindBool("vision:shutdown")))
- {
- BMessage logMessage (M_UNREGISTER_LOGGER);
- logMessage.AddString ("name", fId.String());
- fSMsgr.SendMessage(&logMessage);
- }
-
- BMessage deathchant (M_CLIENT_SHUTDOWN);
- deathchant.AddPointer("agent", this);
- fSMsgr.SendMessage (&deathchant);
- }
- break;
- case M_THEME_FOREGROUND_CHANGE:
- {
- int16 which (msg->FindInt16 ("which"));
- if (which == C_INPUT || which == C_INPUT_BACKGROUND)
- {
- fActiveTheme->ReadLock();
- rgb_color fInputColor (fActiveTheme->ForegroundAt (C_INPUT));
- fInput->TextView()->SetFontAndColor (&fActiveTheme->FontAt(F_INPUT), B_FONT_ALL,
- &fInputColor);
- fInput->TextView()->SetViewColor (fActiveTheme->ForegroundAt (C_INPUT_BACKGROUND));
- fActiveTheme->ReadUnlock();
- fInput->TextView()->Invalidate();
- }
- }
- break;
-
- case M_THEME_FONT_CHANGE:
- {
- int16 which (msg->FindInt16 ("which"));
- if (which == F_INPUT)
- {
- fActiveTheme->ReadLock();
- rgb_color fInputColor (fActiveTheme->ForegroundAt (C_INPUT));
- fInput->TextView()->SetFontAndColor (&fActiveTheme->FontAt (F_INPUT), B_FONT_ALL,
- &fInputColor);
- fActiveTheme->ReadUnlock();
- Invalidate();
- }
- }
- break;
- case M_STATE_CHANGE:
- {
- if (msg->HasBool ("bool"))
- {
- bool shouldStamp (vision_app->GetBool ("timestamp"));
- if (fTimeStampState != shouldStamp)
- {
- if ((fTimeStampState = shouldStamp))
- fText->SetTimeStampFormat (vision_app->GetString ("timestamp_format"));
- else
- fText->SetTimeStampFormat (NULL);
- }
-
- bool shouldLog = vision_app->GetBool ("log_enabled");
-
- if (fIsLogging != shouldLog)
- {
- if ((fIsLogging = shouldLog))
- {
- BMessage logMessage (M_REGISTER_LOGGER);
- logMessage.AddString ("name", fId.String());
- fSMsgr.SendMessage (&logMessage);
- }
- else
- {
- BMessage logMessage (M_UNREGISTER_LOGGER);
- logMessage.AddString ("name", fId.String());
- fSMsgr.SendMessage (&logMessage);
- }
- }
- }
- else if (msg->HasBool ("string"))
- {
- BString which (msg->FindString ("which"));
- if (which == "timestamp_format")
- fText->SetTimeStampFormat (vision_app->GetString ("timestamp_format"));
- }
- }
- break;
-
- case M_SUBMIT_INPUT:
- {
- fCancelMLPaste = false;
- int32 which (0);
- msg->FindInt32 ("which", &which);
- if (msg->HasPointer ("invoker"))
- {
- BInvoker *invoker (NULL);
- msg->FindPointer ("invoker", reinterpret_cast<void **>(&invoker));
- delete invoker;
- }
-
- switch (which)
- {
- case PASTE_CANCEL:
- break;
-
- case PASTE_MULTI:
- case PASTE_MULTI_NODELAY:
- {
- BMessage *buffer (new BMessage (*msg));
- thread_id tid;
-
- // if there is some text in the input control already, submit it before
- // starting the timed paste
- if (fInput->TextView()->TextLength() != 0)
- {
- BString inputData (fInput->TextView()->Text());
- Submit(inputData.String(), true, true);
- }
- buffer->AddPointer ("agent", this);
- buffer->AddPointer ("window", Window());
- if (which == PASTE_MULTI_NODELAY)
- buffer->AddBool ("delay", false);
- tid = spawn_thread (
- TimedSubmit,
- "Timed Submit",
- B_LOW_PRIORITY,
- buffer);
- resume_thread (tid);
- }
- break;
-
- case PASTE_SINGLE:
- {
- BString buffer;
- for (int32 i = 0; msg->HasString ("data", i); ++i)
- {
- const char *data;
- msg->FindString ("data", i, &data);
- buffer += (i ? " " : "");
- buffer += data;
- }
-
- int32 start, finish;
-
- if (msg->FindInt32 ("selstart", &start) == B_OK)
- {
- msg->FindInt32 ("selend", &finish);
- if (start != finish)
- fInput->TextView()->Delete (start, finish);
- if ((start == 0) && (finish == 0))
- {
- fInput->TextView()->Insert (fInput->TextView()->TextLength(),
- buffer.String(), buffer.Length());
- fInput->TextView()->Select (fInput->TextView()->TextLength(),
- fInput->TextView()->TextLength());
- }
- else
- {
- fInput->TextView()->Insert (start, buffer.String(), buffer.Length());
- fInput->TextView()->Select (start + buffer.Length(),
- start + buffer.Length());
- }
- }
- else
- {
- fInput->TextView()->Insert (buffer.String());
- fInput->TextView()->Select (fInput->TextView()->TextLength(),
- fInput->TextView()->TextLength());
- }
- fInput->TextView()->ScrollToSelection();
- }
- break;
-
- default:
- break;
- }
- }
- break;
- case M_PREVIOUS_INPUT:
- {
- fHistory->PreviousBuffer (fInput);
- }
- break;
- case M_NEXT_INPUT:
- {
- fHistory->NextBuffer (fInput);
- }
- break;
- case M_SUBMIT:
- {
- const char *buffer (NULL);
- bool clear (true),
- add2history (true);
- msg->FindString ("input", &buffer);
- if (msg->HasBool ("clear"))
- msg->FindBool ("clear", &clear);
- if (msg->HasBool ("history"))
- msg->FindBool ("history", &add2history);
- Submit (buffer, clear, add2history);
- }
- break;
- case M_LAG_CHANGED:
- {
- msg->FindString ("lag", &fMyLag);
- if (!IsHidden())
- vision_app->pClientWin()->pStatusView()->SetItemValue (STATUS_LAG, fMyLag.String());
- }
- break;
- case M_DISPLAY:
- {
- const char *buffer;
- for (int32 i = 0; msg->HasMessage ("packed", i); ++i)
- {
- BMessage packed;
- msg->FindMessage ("packed", i, &packed);
- packed.FindString ("msgz", &buffer);
- Display (buffer, packed.FindInt32 ("fore"), packed.FindInt32 ("back"), packed.FindInt32 ("font"));
- }
- }
- break;
- case M_CHANNEL_MSG:
- {
- BString theNick;
- const char *theMessage (NULL);
- bool hasNick (false);
- bool isAction (false);
- BString knownAs;
- msg->FindString("nick", &theNick);
- msg->FindString("msgz", &theMessage);
- BString tempString;
- BString nickString;
-
- if (theMessage[0] == '\1')
- {
- BString aMessage (theMessage);
- aMessage.RemoveFirst ("\1ACTION ");
- aMessage.RemoveLast ("\1");
-
- tempString = " ";
- tempString += aMessage;
- tempString += "\n";
-
- nickString = "* ";
- nickString += theNick;
- isAction = true;
- }
- else
- {
- Display ("<", theNick == fMyNick ? C_MYNICK : C_NICK);
- Display (theNick.String(), C_NICKDISPLAY);
- Display (">", theNick == fMyNick ? C_MYNICK : C_NICK);
- tempString += " ";
- tempString += theMessage;
- tempString += '\n';
- }
- // scan for presence of nickname, highlight if present
- if (theNick != fMyNick)
- FirstKnownAs (tempString, knownAs, &hasNick);
- tempString.Prepend (nickString);
-
- int32 dispColor = C_TEXT;
- if (hasNick)
- {
- BWindow *window (NULL);
- dispColor = C_MYNICK;
- if ((window = Window()) != NULL && !window->IsActive())
- system_beep(kSoundEventNames[(uint32)seNickMentioned]);
- }
- else if (isAction)
- dispColor = C_ACTION;
-
- Display (tempString.String(), dispColor);
- }
- break;
- case M_CHANGE_NICK:
- {
- const char *oldNick (NULL);
- msg->FindString ("oldnick", &oldNick);
- if (fMyNick.ICompare (oldNick) == 0)
- fMyNick = msg->FindString ("newnick");
-
- BMessage display;
- if (msg->FindMessage ("display", &display) == B_NO_ERROR)
- ClientAgent::MessageReceived (&display);
- }
- break;
-
- case B_ESCAPE:
- fCancelMLPaste = true;
- break;
-
- case M_DCC_COMPLETE:
- {
- /// set up ///
- BString nick,
- file,
- size,
- type,
- completionMsg ("[@] "),
- fAck;
- int32 rate,
- xfersize;
- bool completed (true);
- msg->FindString ("nick", &nick);
- msg->FindString ("file", &file);
- msg->FindString ("size", &size);
- msg->FindString ("type", &type);
- msg->FindInt32 ("transferred", &xfersize);
- msg->FindInt32 ("transferRate", &rate);
-
- BPath pFile (file.String());
- fAck << xfersize;
-
- if (size.ICompare (fAck))
- completed = false;
- /// send mesage ///
- if (completed)
- completionMsg << S_CLIENT_DCC_SUCCESS;
- else completionMsg << S_CLIENT_DCC_FAILED;
-
- if (type == "SEND")
- completionMsg << S_CLIENT_DCC_SENDTYPE << pFile.Leaf() << S_CLIENT_DCC_TO;
- else completionMsg << S_CLIENT_DCC_RECVTYPE << pFile.Leaf() << S_CLIENT_DCC_FROM;
-
- completionMsg << nick << " (";
- if (!completed)
- completionMsg << fAck << "/";
-
- completionMsg << size << S_CLIENT_DCC_SIZE_UNITS "), ";
- completionMsg << rate << S_CLIENT_DCC_SPEED_UNITS "\n";
-
- Display (completionMsg.String(), C_CTCP_RPY);
- }
- break;
- default:
- BView::MessageReceived (msg);
- }
- }
- const BString &
- ClientAgent::Id (void) const
- {
- return fId;
- }
- int32
- ClientAgent::FirstKnownAs (
- const BString &data,
- BString &result,
- bool *me) const
- {
- BString myAKA (vision_app->GetString ("alsoKnownAs"));
- int32 hit (data.Length()),
- i,
- place;
- BString target;
-
- if ((place = FirstSingleKnownAs (data, fMyNick)) != B_ERROR)
- {
- result = fMyNick;
- hit = place;
- *me = true;
- }
- for (i = 1; (target = GetWord (myAKA.String(), i)) != "-9z99"; ++i)
- {
- if ((place = FirstSingleKnownAs (data, target)) != B_ERROR
- && place < hit)
- {
- result = target;
- hit = place;
- *me = true;
- }
- }
- return hit < data.Length() ? hit : B_ERROR;
- }
- int32
- ClientAgent::FirstSingleKnownAs (const BString &data, const BString &target) const
- {
- int32 place;
- if ((place = data.IFindFirst (target)) != B_ERROR
- && (place == 0
- || isspace (data[place - 1])
- || ispunct (data[place - 1]))
- && (place + target.Length() == data.Length()
- || isspace (data[place + target.Length()])
- || ispunct (data[place + target.Length()])
- || (int)data[place + target.Length()] <= 0xa)) // null or newline
- return place;
- return B_ERROR;
- }
- void
- ClientAgent::AddSend (BMessage *msg, const char *buffer) const
- {
- if (strcmp (buffer, endl) == 0)
- {
- if (fSMsgr.IsValid())
- fSMsgr.SendMessage (msg);
- msg->MakeEmpty();
- }
- else
- msg->AddString ("data", buffer);
- }
- void
- ClientAgent::AddSend (BMessage *msg, const BString &buffer) const
- {
- AddSend (msg, buffer.String());
- }
- void
- ClientAgent::AddSend (BMessage *msg, int32 value) const
- {
- BString buffer;
- buffer << value;
- AddSend (msg, buffer.String());
- }
- void
- ClientAgent::ChannelMessage (
- const char *msgz,
- const char *nick,
- const char *ident,
- const char *address)
- {
- BMessage msg (M_CHANNEL_MSG);
- msg.AddString ("msgz", msgz);
- if (nick)
- msg.AddString ("nick", nick);
- if (ident)
- msg.AddString ("ident", ident);
- if (address)
- msg.AddString ("address", address);
- fMsgr.SendMessage (&msg);
- }
- void
- ClientAgent::ActionMessage (
- const char *msgz,
- const char *nick)
- {
- BMessage actionSend (M_SERVER_SEND);
- AddSend (&actionSend, "PRIVMSG ");
- AddSend (&actionSend, fId);
- AddSend (&actionSend, " :\1ACTION ");
- AddSend (&actionSend, msgz);
- AddSend (&actionSend, "\1");
- AddSend (&actionSend, endl);
- BString theAction ("\1ACTION ");
- theAction += msgz;
- theAction += "\1";
- ChannelMessage (theAction.String(), nick);
- }
- void
- ClientAgent::CTCPAction (BString theTarget, BString theMsg)
- {
- BString theCTCP (GetWord (theMsg.String(), 1).ToUpper()),
- theRest (RestOfString (theMsg.String(), 2)),
- tempString ("[CTCP->");
- tempString += theTarget;
- tempString += "] ";
- tempString += theCTCP;
- if (theRest != "-9z99")
- {
- tempString += " ";
- tempString += theRest;
- tempString += '\n';
- }
- else
- tempString += '\n';
- Display (tempString.String(), C_CTCP_REQ, C_BACKGROUND, F_SERVER);
- }
|