void NotificationServer::MessageReceived(BMessage* message) { switch (message->what) { case kNotificationMessage: { // Skip this message if we don't have the window if (!fWindow) return; int32 type = 0; // Emit a sound for this event if (message->FindInt32("type", &type) == B_OK) { if (type < (int32)(sizeof(kSoundNames) / sizeof(const char*))) system_beep(kSoundNames[type]); } // Let the notification window handle this message BMessenger(fWindow).SendMessage(message); break; } default: BApplication::MessageReceived(message); } }
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]); }
/*********************************************************** * PlayNotifySound ***********************************************************/ void HDaemonApp::PlayNotifySound() { // Play notification sound system_beep("New E-mail"); // Change deskbar icon //HWindow *window = cast_as(Window(),HWindow); //if(window) // window->ChangeDeskbarIcon(DESKBAR_NEW_ICON); }
void NotifyFilter::MailboxSynced(status_t status) { if (fNNewMessages == 0) return; if (fStrategy & do_beep) system_beep("New E-mail"); if (fStrategy & alert) { BString text, numString; if (fNNewMessages != 1) text << B_TRANSLATE("You have %num new messages for %name."); else text << B_TRANSLATE("You have %num new message for %name."); numString << fNNewMessages; text.ReplaceFirst("%num", numString); text.ReplaceFirst("%name", fMailProtocol.AccountSettings().Name()); BAlert *alert = new BAlert(B_TRANSLATE("New messages"), text.String(), B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_AS_USUAL); alert->SetFeel(B_NORMAL_WINDOW_FEEL); alert->Go(NULL); } if (fStrategy & blink_leds) be_app->PostMessage('mblk'); if (fStrategy & one_central_beep) be_app->PostMessage('mcbp'); if (fStrategy & big_doozy_alert) { BMessage msg('numg'); msg.AddInt32("num_messages", fNNewMessages); msg.AddString("name", fMailProtocol.AccountSettings().Name()); be_app->PostMessage(&msg); } if (fStrategy & log_window) { BString message, numString; if (fNNewMessages != 1) message << B_TRANSLATE("%num new messages"); else message << B_TRANSLATE("%num new message"); numString << fNNewMessages; message.ReplaceFirst("%num", numString); fMailProtocol.ShowMessage(message.String()); } fNNewMessages = 0; }
void MediaAddonServer::_HandleMessage(int32 code, const void* data, size_t size) { switch (code) { case ADD_ON_SERVER_INSTANTIATE_DORMANT_NODE: { const add_on_server_instantiate_dormant_node_request* request = static_cast< const add_on_server_instantiate_dormant_node_request*>( data); add_on_server_instantiate_dormant_node_reply reply; status_t status = MediaRosterEx(fMediaRoster)->InstantiateDormantNode( request->add_on_id, request->flavor_id, request->creator_team, &reply.node); request->SendReply(status, &reply, sizeof(reply)); break; } case ADD_ON_SERVER_RESCAN_ADD_ON_FLAVORS: { const add_on_server_rescan_flavors_command* command = static_cast< const add_on_server_rescan_flavors_command*>(data); BMediaAddOn* addOn = gDormantNodeManager->GetAddOn(command->add_on_id); if (addOn == NULL) { ERROR("rescan flavors: Can't find a addon object for id %d\n", (int)command->add_on_id); break; } _ScanAddOnFlavors(addOn); gDormantNodeManager->PutAddOn(command->add_on_id); break; } case ADD_ON_SERVER_RESCAN_FINISHED_NOTIFY: if (fStartupSound) { system_beep(MEDIA_SOUNDS_STARTUP); fStartupSound = false; } break; default: ERROR("media_addon_server: received unknown message code %#08lx\n", code); break; } }
void NotifyCallback::Callback(status_t result) { parent->callback = NULL; if (num_messages == 0) return; if (strategy & do_beep) system_beep("New E-mail"); if (strategy & alert) { BString text; MDR_DIALECT_CHOICE ( text << "You have " << num_messages << " new message" << ((num_messages != 1) ? "s" : "") << " for " << chainrunner->Chain()->Name() << ".", text << chainrunner->Chain()->Name() << "より\n" << num_messages << " 通のメッセージが届きました"); BAlert *alert = new BAlert(MDR_DIALECT_CHOICE ("New messages","新着メッセージ"), text.String(), "OK", NULL, NULL, B_WIDTH_AS_USUAL); alert->SetFeel(B_NORMAL_WINDOW_FEEL); alert->Go(NULL); } if (strategy & blink_leds) be_app->PostMessage('mblk'); if (strategy & one_central_beep) be_app->PostMessage('mcbp'); if (strategy & big_doozy_alert) { BMessage msg('numg'); msg.AddInt32("num_messages",num_messages); msg.AddString("chain_name",chainrunner->Chain()->Name()); msg.AddInt32("chain_id",chainrunner->Chain()->ID()); be_app->PostMessage(&msg); } if (strategy & log_window) { BString message; message << num_messages << " new message" << ((num_messages != 1) ? "s" : ""); chainrunner->ShowMessage(message.String()); } }
int main(int argc, char* argv[]) { // "beep" can only take a single optional event name if (argc > 2 || (argc == 2 && argv[1][0] == '-')) { fprintf(stdout,"usage: beep [ eventname ]\n"); fprintf(stdout,"Event names are found in the Sounds preferences panel.\n"); fflush(stdout); return B_OK; } // if no event name is specified, play the default "Beep" event if (argc == 1) return beep(); else return system_beep(argv[1]); }
void ChatWindow::startNotify() { if ( fChangedNotActivated ) return; fChangedNotActivated = true; char str[512]; sprintf(str, "√ %s", fTitleCache); SetTitle(str); ((ChatApp*)be_app)->Flash( BMessenger(this) ); // if ( (Workspaces() & (1 << current_workspace())) == 0) // beep if on another workspace if ( !IsActive() ) // beep if not active { system_beep(kImNewMessageSound); } }
void MessageReceived(BMessage *msg) { switch (msg->what) { case InfoPopper::AddMessage: { int8 type = 0; if (msg->FindInt8("type", &type) == B_OK) { if (type < (sizeof(kSoundNames)/sizeof(const char *))) system_beep(kSoundNames[type]); }; BMessenger(fWin).SendMessage(msg); } break; case InfoPopper::GetIconSize: { BMessage reply(B_REPLY); reply.AddInt16("iconSize", fWin->IconSize()); msg->SendReply(&reply); } break; default: BApplication::MessageReceived(msg); }; };
void ChannelAgent::MessageReceived(BMessage* msg) { int32 i(0); switch (msg->what) { case M_USER_QUIT: { const char* nick(NULL); msg->FindString("nick", &nick); if (RemoveUser(nick)) { BMessage display; if (msg->FindMessage("display", &display) == B_NO_ERROR) ClientAgent::MessageReceived(&display); } } break; case M_USER_ADD: { const char* nick(NULL); bool ignore(false); int32 iStatus(STATUS_NORMAL_BIT); msg->FindString("nick", &nick); msg->FindBool("ignore", &ignore); if (nick == NULL) { printf("ERROR: attempted to AddUser an empty nick in ChannelAgent, channel: %s\n", fId.String()); break; } if (ignore) iStatus |= STATUS_IGNORE_BIT; AddUser(nick, iStatus); BMessage display; if (msg->FindMessage("display", &display) == B_NO_ERROR) ClientAgent::MessageReceived(&display); } break; case M_CHANGE_NICK: { const char* oldNick(NULL), *newNick(NULL); NameItem* item(NULL); int32 thePos(-1); if ((msg->FindString("oldnick", &oldNick) != B_OK) || (msg->FindString("newnick", &newNick) != B_OK)) { printf("Error: invalid pointer, ChannelAgent::MessageReceived, M_CHANGE_NICK"); break; } if (fMyNick.ICompare(oldNick) == 0 && !IsHidden()) vision_app->pClientWin()->pStatusView()->SetItemValue(STATUS_NICK, newNick); if (((thePos = FindPosition(oldNick)) >= 0) && ((item = (static_cast<NameItem*>(fNamesList->ItemAt(thePos)))) != 0)) { item->SetName(newNick); fNamesList->SortItems(SortNames); if (fLastExpansion.ICompare(oldNick, fLastExpansion.Length()) == 0) { int32 count(fRecentNicks.CountItems()); BString* name(NULL); for (i = 0; i < count; i++) if ((name = fRecentNicks.ItemAt(i))->ICompare(oldNick) == 0) { if (fLastExpansion.ICompare(newNick, fLastExpansion.Length()) == 0) name->SetTo(newNick); else delete fRecentNicks.RemoveItemAt(i); break; } count = fCompletionNicks.CountItems(); for (i = 0; i < count; i++) if ((name = fCompletionNicks.ItemAt(i))->ICompare(oldNick) == 0) { if (fLastExpansion.ICompare(newNick, fLastExpansion.Length()) == 0) name->SetTo(newNick); else delete fCompletionNicks.RemoveItemAt(i); break; } } } else break; ClientAgent::MessageReceived(msg); } break; case M_CHANNEL_NAMES: { for (i = 0; msg->HasString("nick", i); ++i) { const char* nick(NULL); bool founder(false), protect(false), op(false), voice(false), helper(false), ignored(false); msg->FindString("nick", i, &nick); msg->FindBool("founder", i, &founder); msg->FindBool("protect", i, &protect); msg->FindBool("op", i, &op); msg->FindBool("voice", i, &voice); msg->FindBool("helper", i, &helper); msg->FindBool("ignored", i, &ignored); if (FindPosition(nick) < 0) { int32 iStatus(ignored ? STATUS_IGNORE_BIT : 0); if (founder) { ++nick; ++fOpsCount; iStatus |= STATUS_FOUNDER_BIT; } else if (protect) { ++nick; ++fOpsCount; iStatus |= STATUS_PROTECTED_BIT; } else if (op) { ++nick; ++fOpsCount; iStatus |= STATUS_OP_BIT; } else if (voice) { ++nick; iStatus |= STATUS_VOICE_BIT; } else if (helper) { ++nick; iStatus |= STATUS_HELPER_BIT; } else iStatus |= STATUS_NORMAL_BIT; fUserCount++; fNamesList->AddItem(new NameItem(nick, iStatus)); } } fNamesList->SortItems(SortNames); if (!IsHidden()) { BString buffer; buffer << fOpsCount; vision_app->pClientWin()->pStatusView()->SetItemValue(STATUS_OPS, buffer.String()); buffer = ""; buffer << fUserCount; vision_app->pClientWin()->pStatusView()->SetItemValue(STATUS_USERS, buffer.String()); } } break; case M_RESIZE_VIEW: { BPoint point; msg->FindPoint("loc", &point); point.x -= Frame().left; float offset((int32)(point.x - (fNamesScroll->Frame().left))); fResize->MoveBy(offset, 0.0); fTextScroll->ResizeBy(offset, 0.0); fNamesScroll->ResizeBy(-offset, 0.0); fNamesScroll->MoveBy(offset, 0.0); BRect namesRect(0, 0, fNamesScroll->Bounds().Width(), 0); vision_app->SetRect("namesListRect", namesRect); } break; case M_SERVER_DISCONNECT: { // clear names list on disconnect fNamesList->ClearList(); fOpsCount = 0; fUserCount = 0; // clear heuristics completion list - this ensures that no stale nicks are left // over in it after reconnect -- list will quickly be rebuilt anyhow if there // is any conversation whatsoever going on while (fRecentNicks.CountItems() > 0) delete fRecentNicks.RemoveItemAt(0L); } break; case M_REJOIN: { const char* newNick(NULL); if (msg->FindString("nickname", &newNick) != B_OK) { printf("Error: ChannelAgent::MessageReceived, M_REJOIN: invalid pointer\n"); break; } fMyNick = newNick; // update nickname (might have changed on reconnect) if (!IsHidden()) vision_app->pClientWin()->pStatusView()->SetItemValue(STATUS_NICK, fMyNick.String()); Display(S_CHANNEL_RECON_REJOIN B_UTF8_ELLIPSIS "\n", C_ERROR, C_BACKGROUND, F_SERVER); // send join cmd BMessage send(M_SERVER_SEND); AddSend(&send, "JOIN "); AddSend(&send, fId); if (fChanKey != "") { AddSend(&send, " "); AddSend(&send, fChanKey); } AddSend(&send, endl); } break; case M_CHANNEL_TOPIC: { const char* theTopic(NULL); BString buffer; if (msg->FindString("topic", &theTopic) != B_OK) { printf("ChannelAgent::MessageReceived, M_CHANNEL_TOPIC: invalid pointer\n"); break; } fTopic = theTopic; if (!IsHidden()) vision_app->pClientWin()->pStatusView()->SetItemValue( STATUS_META, FilterCrap(theTopic, true).String()); BMessage display; if (msg->FindMessage("display", &display) == B_NO_ERROR) ClientAgent::MessageReceived(&display); } break; case M_OPEN_MSGAGENT: { const char* theNick(NULL); msg->FindString("nick", &theNick); if (theNick == NULL) { NameItem* myUser; int32 pos = fNamesList->CurrentSelection(); if (pos >= 0) { myUser = static_cast<NameItem*>(fNamesList->ItemAt(pos)); BString targetNick = myUser->Name(); msg->AddString("nick", targetNick.String()); } } fSMsgr.SendMessage(msg); } break; case M_CHANNEL_GOT_KICKED: { const char* theChannel(NULL), *kicker(NULL), *rest(NULL); if ((msg->FindString("channel", &theChannel) != B_OK) || (msg->FindString("kicker", &kicker) != B_OK) || (msg->FindString("rest", &rest) != B_OK)) { printf("Error: ClientAgent::MessageReceived, M_CHANNEL_GOT_KICKED, invalid pointer\n"); break; } BMessage wegotkicked(M_DISPLAY); // "you were kicked" BString buffer; buffer += S_CHANNEL_GOT_KICKED; buffer += theChannel; buffer += " " S_CHANNEL_GOT_KICKED2 " "; buffer += kicker; buffer += " ("; buffer += rest; buffer += ")\n"; PackDisplay(&wegotkicked, buffer.String(), C_QUIT, C_BACKGROUND, F_TEXT); // clean up fNamesList->ClearList(); fOpsCount = 0; fUserCount = 0; fMsgr.SendMessage(&wegotkicked); BMessage attemptrejoin(M_DISPLAY); // "you were kicked" buffer = S_CHANNEL_REJOIN; buffer += theChannel; buffer += B_UTF8_ELLIPSIS "\n"; PackDisplay(&attemptrejoin, buffer.String(), C_QUIT, C_BACKGROUND, F_TEXT); fMsgr.SendMessage(&attemptrejoin); BMessage send(M_SERVER_SEND); AddSend(&send, "JOIN "); AddSend(&send, theChannel); if (fChanKey != "") { AddSend(&send, " "); AddSend(&send, fChanKey); } AddSend(&send, endl); } break; case M_CHANNEL_MODE: { ModeEvent(msg); } break; case M_CHANNEL_MSG: { bool hasNick(false); BString tempString, theNick, knownAs; msg->FindString("msgz", &tempString); msg->FindString("nick", &theNick); if (theNick != fMyNick) FirstKnownAs(tempString, knownAs, &hasNick); if (IsHidden()) { UpdateStatus((hasNick) ? WIN_NICK_BIT : WIN_NEWS_BIT); if (hasNick) { if (tempString[0] == '\1') { tempString.RemoveFirst("\1ACTION "); tempString.RemoveLast("\1"); } BNotification notification(B_INFORMATION_NOTIFICATION); notification.SetGroup(BString("Vision")); entry_ref ref = vision_app->AppRef(); notification.SetOnClickFile(&ref); notification.SetTitle(fServerName.String()); BString content; content.SetToFormat("%s - %s said: %s", fId.String(), theNick.String(), tempString.String()); notification.SetContent(content); notification.Send(); } } else if (hasNick) system_beep(kSoundEventNames[(uint32)seNickMentioned]); ClientAgent::MessageReceived(msg); } break; case M_CHANNEL_MODES: { const char* mode(NULL), *chan(NULL), *msgz(NULL); if ((msg->FindString("mode", &mode) != B_OK) || (msg->FindString("chan", &chan) != B_OK) || (msg->FindString("msgz", &msgz) != B_OK)) { printf("Error: ChannelAgent::MessageReceived, M_CHANNEL_MODES: invalid pointer\n"); break; } if (fId.ICompare(chan) == 0) { BString realMode(GetWord(mode, 1)); int32 place(2); if (realMode.FindFirst("l") >= 0) fChanLimit = GetWord(mode, place++); if (realMode.FindFirst("k") >= 0) { fChanKey = GetWord(mode, place++); // u2 may not send the channel key, thats why we stored the /join cmd // in a string in ParseCmd if (fChanKey == "*" && fIrcdtype == IRCD_UNDERNET) { BString tempId(fId); tempId.Remove(0, 1); // remove any #, &, !, blah. if (vision_app->pClientWin()->joinStrings.FindFirst(tempId) < 1) { // can't find the join cmd for this channel in joinStrings! } else { BString joinStringsL(vision_app->pClientWin()->joinStrings); // FindLast to make sure we get the last attempt (user might have // tried several keys) int32 idPos(joinStringsL.FindLast(tempId)); BString tempKeyString; joinStringsL.MoveInto(tempKeyString, idPos, joinStringsL.Length()); fChanKey = GetWord(tempKeyString.String(), 2); } } // end u2-kludge stuff } fChanMode = mode; if (!IsHidden()) vision_app->pClientWin()->pStatusView()->SetItemValue(STATUS_MODES, fChanMode.String()); } BMessage dispMsg(M_DISPLAY); PackDisplay(&dispMsg, msgz, C_OP, C_BACKGROUND, F_TEXT); BMessenger display(this); display.SendMessage(&dispMsg); } break; case M_NAMES_POPUP_MODE: { const char* inaction(NULL); msg->FindString("action", &inaction); int32 count(0), index(0); BString victims, targetNick, action(inaction), modechar, polarity; NameItem* myUser(NULL); /// action /// if (action.FindFirst("voice") >= 0) modechar = "v"; else if (action.FindFirst("op") >= 0) modechar = "o"; else break; /// polarity /// if (action.FindFirst("de") >= 0) polarity += " -"; else polarity += " +"; /// iterate /// while ((i = fNamesList->CurrentSelection(index++)) >= 0) { myUser = static_cast<NameItem*>(fNamesList->ItemAt(i)); targetNick = myUser->Name(); victims += " "; victims += targetNick; count++; } BString command("/mode "); command += fId; command += polarity; for (i = 0; i < count; i++) command += modechar; command += victims; ParseCmd(command.String()); } break; case M_NAMES_POPUP_CTCP: { const char* inaction(NULL); msg->FindString("action", &inaction); int32 index(0); BString victims, targetNick, action(inaction); NameItem* myUser(NULL); action.ToUpper(); /// iterate /// while ((i = fNamesList->CurrentSelection(index++)) >= 0) { myUser = static_cast<NameItem*>(fNamesList->ItemAt(i)); targetNick = myUser->Name(); victims += targetNick; victims += ","; } victims.RemoveLast(","); BString command("/ctcp "); command += victims; command += " "; command += action; ParseCmd(command.String()); } break; case M_NAMES_POPUP_WHOIS: { int32 index(0); BString victims, targetNick; NameItem* myUser(NULL); /// iterate /// while ((i = fNamesList->CurrentSelection(index++)) >= 0) { myUser = static_cast<NameItem*>(fNamesList->ItemAt(i)); targetNick = myUser->Name(); victims += targetNick; victims += ","; } victims.RemoveLast(","); BString command("/whois "); command += victims; ParseCmd(command.String()); } break; case M_NAMES_POPUP_NOTIFY: { int32 index(0); BString victims, targetNick; NameItem* myUser(NULL); /// iterate /// while ((i = fNamesList->CurrentSelection(index++)) >= 0) { myUser = static_cast<NameItem*>(fNamesList->ItemAt(i)); targetNick = myUser->Name(); victims += targetNick; victims += " "; } victims.RemoveLast(","); BString command("/notify "); command += victims; ParseCmd(command.String()); } break; case M_NAMES_POPUP_DCCCHAT: { int32 index(0); BString targetNick; NameItem* myUser(NULL); /// iterate /// while ((i = fNamesList->CurrentSelection(index++)) >= 0) { myUser = static_cast<NameItem*>(fNamesList->ItemAt(i)); targetNick = myUser->Name(); BString command("/dcc chat "); command += targetNick; ParseCmd(command.String()); } } break; case M_NAMES_POPUP_DCCSEND: { int32 index(0); BString targetNick; NameItem* myUser(NULL); /// iterate /// while ((i = fNamesList->CurrentSelection(index++)) >= 0) { myUser = static_cast<NameItem*>(fNamesList->ItemAt(i)); targetNick = myUser->Name(); BString command("/dcc send "); command += targetNick; ParseCmd(command.String()); } } break; case M_NAMES_POPUP_KICK: { int32 index(0); BString targetNick, kickMsg(vision_app->GetCommand(CMD_KICK)); NameItem* myUser(NULL); /// iterate /// while ((i = fNamesList->CurrentSelection(index++)) >= 0) { myUser = static_cast<NameItem*>(fNamesList->ItemAt(i)); targetNick = myUser->Name(); BString command("/kick "); command += targetNick; command += " "; command += kickMsg; ParseCmd(command.String()); } } break; case M_STATUS_ADDITEMS: { vision_app->pClientWin()->pStatusView()->AddItem(new StatusItem(0, ""), true); vision_app->pClientWin()->pStatusView()->AddItem( new StatusItem(S_STATUS_LAG, "", STATUS_ALIGN_LEFT), true); vision_app->pClientWin()->pStatusView()->AddItem(new StatusItem(0, "", STATUS_ALIGN_LEFT), true); vision_app->pClientWin()->pStatusView()->AddItem(new StatusItem(S_STATUS_USERS, ""), true); vision_app->pClientWin()->pStatusView()->AddItem(new StatusItem(S_STATUS_OPS, ""), true); vision_app->pClientWin()->pStatusView()->AddItem(new StatusItem(S_STATUS_MODES, ""), true); vision_app->pClientWin()->pStatusView()->AddItem(new StatusItem("", "", STATUS_ALIGN_LEFT), true); // The false bool for SetItemValue() tells the StatusView not to Invalidate() the view. // We send true on the last SetItemValue(). vision_app->pClientWin()->pStatusView()->SetItemValue(STATUS_SERVER, fServerName.String(), false); vision_app->pClientWin()->pStatusView()->SetItemValue(STATUS_LAG, fMyLag.String(), false); vision_app->pClientWin()->pStatusView()->SetItemValue(STATUS_NICK, fMyNick.String(), false); vision_app->pClientWin()->pStatusView()->SetItemValue(STATUS_MODES, fChanMode.String(), false); vision_app->pClientWin()->pStatusView()->SetItemValue( STATUS_META, FilterCrap(fTopic.String(), true).String()); BString buffer; buffer << fUserCount; vision_app->pClientWin()->pStatusView()->SetItemValue(STATUS_USERS, buffer.String(), false); buffer = ""; buffer << fOpsCount; vision_app->pClientWin()->pStatusView()->SetItemValue(STATUS_OPS, buffer.String(), true); } break; case M_CHANNEL_OPTIONS_SHOW: { if (fChanOpt) fChanOpt->Activate(); else { fChanOpt = new ChannelOptions(fId.String(), this); fChanOpt->Show(); } } break; case M_CHANNEL_OPTIONS_CLOSE: { fChanOpt = NULL; } break; case M_CLIENT_QUIT: { if ((msg->HasBool("vision:part") && msg->FindBool("vision:part")) || (msg->HasBool("vision:winlist") && msg->FindBool("vision:winlist"))) { BMessage send(M_SERVER_SEND); AddSend(&send, "PART "); AddSend(&send, fId); if (msg->HasString("vision:partmsg")) { AddSend(&send, " :"); AddSend(&send, msg->FindString("vision:partmsg")); } AddSend(&send, endl); } ClientAgent::MessageReceived(msg); } break; default: ClientAgent::MessageReceived(msg); } }
status_t beep() { return system_beep(NULL); }
status_t AGMSBayesianSpamFilter::_CheckForSpam(BFile* file) { // Get a connection to the spam database server. Launch if needed, should // only need it once, unless another e-mail thread shuts down the server // inbetween messages. This code used to be in InitCheck, but apparently // that isn't called. printf("Checking for Spam Server.\n"); if (fLaunchAttemptCount == 0 || !fMessengerToServer.IsValid ()) { if (_GetTokenizeMode() != B_OK) return B_ERROR; } off_t dataSize; file->GetSize(&dataSize); char* stringBuffer = new char[dataSize + 1]; file->Read(stringBuffer, dataSize); stringBuffer[dataSize] = 0; // Add an end of string NUL, just in case. float spamRatio; if (_GetSpamRatio(stringBuffer, dataSize, spamRatio) != B_OK) return B_ERROR; // If we are auto-training, feed back the message to the server as a // training example (don't train if it is uncertain). if (fAutoTraining && (spamRatio >= fSpamCutoffRatio || spamRatio < fGenuineCutoffRatio)) { _TrainServer(stringBuffer, dataSize, spamRatio); } delete[] stringBuffer; // write attributes const char *classificationString; classificationString = (spamRatio >= fSpamCutoffRatio) ? "Spam" : ((spamRatio < fGenuineCutoffRatio) ? "Genuine" : "Uncertain"); file->WriteAttr("MAIL:classification", B_STRING_TYPE, 0 /* offset */, classificationString, strlen(classificationString) + 1); // Store the spam ratio in an attribute called MAIL:ratio_spam, // attached to the eventual output file. file->WriteAttr("MAIL:ratio_spam", B_FLOAT_TYPE, 0 /* offset */, &spamRatio, sizeof(spamRatio)); // Also add it to the subject, if requested. if (fAddSpamToSubject && spamRatio >= fSpamCutoffRatio) _AddSpamToSubject(file, spamRatio); // Beep using different sounds for spam and genuine, as Jeremy Friesner // nudged me to get around to implementing. And add uncertain to that, as // "BiPolar" suggested. If the user doesn't want to hear the sound, they // can turn it off in the system sound preferences. if (spamRatio >= fSpamCutoffRatio) { system_beep(kAGMSBayesBeepSpamName); } else if (spamRatio < fGenuineCutoffRatio) { system_beep(kAGMSBayesBeepGenuineName); } else { system_beep(kAGMSBayesBeepUncertainName); } return B_OK; }
status_t AGMSBayesianSpamFilter::ProcessMailMessage ( BPositionIO** io_message, BEntry* io_entry, BMessage* io_headers, BPath* io_folder, const char* io_uid) { ssize_t amountRead; attr_info attributeInfo; const char *classificationString; off_t dataSize; BPositionIO *dataStreamPntr = *io_message; status_t errorCode = B_OK; int32 headerLength; BString headerString; BString newSubjectString; BNode nodeForOutputFile; bool nodeForOutputFileInitialised = false; const char *oldSubjectStringPntr; char percentageString [30]; BMessage replyMessage; BMessage scriptingMessage; team_id serverTeam; float spamRatio; char *stringBuffer = NULL; char tempChar; status_t tempErrorCode; const char *tokenizeModeStringPntr; // Set up a BNode to the final output file so that we can write custom // attributes to it. Non-custom attributes are stored separately in // io_headers. if (io_entry != NULL && B_OK == nodeForOutputFile.SetTo (io_entry)) nodeForOutputFileInitialised = true; // Get a connection to the spam database server. Launch if needed, should // only need it once, unless another e-mail thread shuts down the server // inbetween messages. This code used to be in InitCheck, but apparently // that isn't called. printf("Checking for Spam Server.\n"); if (fLaunchAttemptCount == 0 || !fMessengerToServer.IsValid ()) { if (fLaunchAttemptCount > 3) goto ErrorExit; // Don't try to start the server too many times. fLaunchAttemptCount++; // Make sure the server is running. if (!be_roster->IsRunning (kServerSignature)) { errorCode = be_roster->Launch (kServerSignature); if (errorCode != B_OK) { BPath path; entry_ref ref; directory_which places[] = {B_COMMON_BIN_DIRECTORY,B_BEOS_BIN_DIRECTORY}; for (int32 i = 0; i < 2; i++) { find_directory(places[i],&path); path.Append("spamdbm"); if (!BEntry(path.Path()).Exists()) continue; get_ref_for_path(path.Path(),&ref); if ((errorCode = be_roster->Launch (&ref)) == B_OK) break; } if (errorCode != B_OK) goto ErrorExit; } } // Set up the messenger to the database server. serverTeam = be_roster->TeamFor (kServerSignature); if (serverTeam < 0) goto ErrorExit; fMessengerToServer = BMessenger (kServerSignature, serverTeam, &errorCode); if (!fMessengerToServer.IsValid ()) goto ErrorExit; // Check if the server is running in headers only mode. If so, we only // need to download the header rather than the entire message. scriptingMessage.MakeEmpty (); scriptingMessage.what = B_GET_PROPERTY; scriptingMessage.AddSpecifier ("TokenizeMode"); replyMessage.MakeEmpty (); if ((errorCode = fMessengerToServer.SendMessage (&scriptingMessage, &replyMessage)) != B_OK) goto ErrorExit; if ((errorCode = replyMessage.FindInt32 ("error", &tempErrorCode)) != B_OK) goto ErrorExit; if ((errorCode = tempErrorCode) != B_OK) goto ErrorExit; if ((errorCode = replyMessage.FindString ("result", &tokenizeModeStringPntr)) != B_OK) goto ErrorExit; fHeaderOnly = (tokenizeModeStringPntr != NULL && strcmp (tokenizeModeStringPntr, "JustHeader") == 0); } // See if the message has already been classified. Happens for messages // which are partially downloaded when you have auto-training on. Could // untrain the partial part before training on the complete message, but we // don't know how big it was, so instead just ignore the message. if (nodeForOutputFileInitialised) { if (nodeForOutputFile.GetAttrInfo ("MAIL:classification", &attributeInfo) == B_OK) return B_OK; } // Copy the message to a string so that we can pass it to the spam database // (the even messier alternative is a temporary file). Do it in a fashion // which allows NUL bytes in the string. This method of course limits the // message size to a few hundred megabytes. If we're using header mode, // only read the header rather than the full message. if (fHeaderOnly) { // Read just the header, it ends with an empty CRLF line. dataStreamPntr->Seek (0, SEEK_SET); while ((errorCode = dataStreamPntr->Read (&tempChar, 1)) == 1) { headerString.Append (tempChar, 1); headerLength = headerString.Length(); if (headerLength >= 4 && strcmp (headerString.String() + headerLength - 4, "\r\n\r\n") == 0) break; } if (errorCode < 0) goto ErrorExit; dataSize = headerString.Length(); stringBuffer = new char [dataSize + 1]; memcpy (stringBuffer, headerString.String(), dataSize); stringBuffer[dataSize] = 0; } else { // Read the whole file. The seek to the end may take a while since // that triggers downloading of the entire message (and caching in a // slave file - see the MessageIO class). dataSize = dataStreamPntr->Seek (0, SEEK_END); if (dataSize <= 0) goto ErrorExit; try { stringBuffer = new char [dataSize + 1]; } catch (...) { errorCode = ENOMEM; goto ErrorExit; } dataStreamPntr->Seek (0, SEEK_SET); amountRead = dataStreamPntr->Read (stringBuffer, dataSize); if (amountRead != dataSize) goto ErrorExit; stringBuffer[dataSize] = 0; // Add an end of string NUL, just in case. } // Send off a scripting command to the database server, asking it to // evaluate the string for spaminess. Note that it can return ENOMSG // when there are no words (a good indicator of spam which is pure HTML // if you are using plain text only tokenization), so we could use that // as a spam marker too. Code copied for the reevaluate stuff below. scriptingMessage.MakeEmpty (); scriptingMessage.what = B_SET_PROPERTY; scriptingMessage.AddSpecifier ("EvaluateString"); errorCode = scriptingMessage.AddData ("data", B_STRING_TYPE, stringBuffer, dataSize + 1, false /* fixed size */); if (errorCode != B_OK) goto ErrorExit; replyMessage.MakeEmpty (); errorCode = fMessengerToServer.SendMessage (&scriptingMessage, &replyMessage); if (errorCode != B_OK || replyMessage.FindInt32 ("error", &errorCode) != B_OK) goto ErrorExit; // Unable to read the return code. if (errorCode == ENOMSG && fNoWordsMeansSpam) spamRatio = fSpamCutoffRatio; // Yes, no words and that means spam. else if (errorCode != B_OK || replyMessage.FindFloat ("result", &spamRatio) != B_OK) goto ErrorExit; // Classification failed in one of many ways. // If we are auto-training, feed back the message to the server as a // training example (don't train if it is uncertain). Also redo the // evaluation after training. if (fAutoTraining) { if (spamRatio >= fSpamCutoffRatio || spamRatio < fGenuineCutoffRatio) { scriptingMessage.MakeEmpty (); scriptingMessage.what = B_SET_PROPERTY; scriptingMessage.AddSpecifier ((spamRatio >= fSpamCutoffRatio) ? "SpamString" : "GenuineString"); errorCode = scriptingMessage.AddData ("data", B_STRING_TYPE, stringBuffer, dataSize + 1, false /* fixed size */); if (errorCode != B_OK) goto ErrorExit; replyMessage.MakeEmpty (); errorCode = fMessengerToServer.SendMessage (&scriptingMessage, &replyMessage); if (errorCode != B_OK || replyMessage.FindInt32 ("error", &errorCode) != B_OK) goto ErrorExit; // Unable to read the return code. if (errorCode != B_OK) goto ErrorExit; // Failed to set a good example. } // Note the kind of example made so that the user doesn't reclassify // the message twice (the spam server looks for this attribute). classificationString = (spamRatio >= fSpamCutoffRatio) ? "Spam" : ((spamRatio < fGenuineCutoffRatio) ? "Genuine" : "Uncertain"); if (nodeForOutputFileInitialised) nodeForOutputFile.WriteAttr ("MAIL:classification", B_STRING_TYPE, 0 /* offset */, classificationString, strlen (classificationString) + 1); // Now that the database has changed due to training, recompute the // spam ratio. Hopefully it will have become more extreme in the // correct direction (not switched from being spam to being genuine). // Code copied from above. scriptingMessage.MakeEmpty (); scriptingMessage.what = B_SET_PROPERTY; scriptingMessage.AddSpecifier ("EvaluateString"); errorCode = scriptingMessage.AddData ("data", B_STRING_TYPE, stringBuffer, dataSize + 1, false /* fixed size */); if (errorCode != B_OK) goto ErrorExit; replyMessage.MakeEmpty (); errorCode = fMessengerToServer.SendMessage (&scriptingMessage, &replyMessage); if (errorCode != B_OK || replyMessage.FindInt32 ("error", &errorCode) != B_OK) goto ErrorExit; // Unable to read the return code. if (errorCode == ENOMSG && fNoWordsMeansSpam) spamRatio = fSpamCutoffRatio; // Yes, no words and that means spam. else if (errorCode != B_OK || replyMessage.FindFloat ("result", &spamRatio) != B_OK) goto ErrorExit; // Classification failed in one of many ways. } // Store the spam ratio in an attribute called MAIL:ratio_spam, // attached to the eventual output file. if (nodeForOutputFileInitialised) nodeForOutputFile.WriteAttr ("MAIL:ratio_spam", B_FLOAT_TYPE, 0 /* offset */, &spamRatio, sizeof (spamRatio)); // Also add it to the subject, if requested. if (fAddSpamToSubject && spamRatio >= fSpamCutoffRatio && io_headers->FindString ("Subject", &oldSubjectStringPntr) == B_OK) { newSubjectString.SetTo ("[Spam "); sprintf (percentageString, "%05.2f", spamRatio * 100.0); newSubjectString << percentageString << "%] "; newSubjectString << oldSubjectStringPntr; io_headers->ReplaceString ("Subject", newSubjectString); } // Beep using different sounds for spam and genuine, as Jeremy Friesner // nudged me to get around to implementing. And add uncertain to that, as // "BiPolar" suggested. If the user doesn't want to hear the sound, they // can turn it off in the system sound preferences. if (spamRatio >= fSpamCutoffRatio) { system_beep (kAGMSBayesBeepSpamName); } else if (spamRatio < fGenuineCutoffRatio) { system_beep (kAGMSBayesBeepGenuineName); } else { system_beep (kAGMSBayesBeepUncertainName); } return B_OK; ErrorExit: fprintf (stderr, "Error exit from " "SpamFilter::ProcessMailMessage, code maybe %ld (%s).\n", errorCode, strerror (errorCode)); delete [] stringBuffer; return B_OK; // Not MD_ERROR so the message doesn't get left on server. }
// /// Main window event handler /// /// \param window the window associated with the event. /// \param message the Windows event type. /// \param wParam the pointer parameter. /// \param lParam the integer parameter. /// /// \return zero, or whatever the default window handler returns. // LRESULT CALLBACK main_window_proc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) { application_t* app(hackery::cast<application_t*>(::GetWindowLongPtr(window, GWLP_USERDATA))); bool handled(true); if (message == WM_CLOSE) { ::PostQuitMessage(0); } if (message == WM_COMMAND) { //HMENU menu(::GetMenu(window)); WORD command(LOWORD(wParam)); switch(command) { case ADOBE_ABOUT: ::MessageBox(NULL, _T("Adobe Begin Copyright 2005-2007 Adobe Systems Incorporated"), _T("About Adobe Begin"), MB_OK); break; case ADOBE_QUIT: ::PostQuitMessage(0); break; case ADOBE_REFRESH_VIEW: app->display_window(); break; case ADOBE_REFRESH_SHEET: app->load_sheet(); break; case ADOBE_NORMAL_DIALOG_SIZE: app->set_dialog_size( size_normal_s ); app->display_window(); break; case ADOBE_SMALL_DIALOG_SIZE: app->set_dialog_size( size_small_s ); app->display_window(); break; case ADOBE_MINI_DIALOG_SIZE: app->set_dialog_size( size_mini_s ); app->display_window(); break; #ifndef NDEBUG case ADOBE_SHOW_WIDGET_FRAMES: app->frame_window(); break; case ADOBE_CLEAR_WIDGET_FRAMES: app->clear_window_frames(); break; #else case ADOBE_SHOW_WIDGET_FRAMES: case ADOBE_CLEAR_WIDGET_FRAMES: system_beep(); break; #endif #if 0 case ADOBE_SERIALIZE_WIDGETS: app->serialize_connections(); break; #endif case ADOBE_RUN_MODAL: app->run_current_as_modal(); break; case ADOBE_LOCALIZATION_ENUS: adobe::implementation::top_frame().attribute_set_m.insert( std::make_pair(adobe::static_token_range("lang"), adobe::static_token_range("en_US"))); app->display_window(); break; case ADOBE_LOCALIZATION_DEDE: adobe::implementation::top_frame().attribute_set_m.insert( std::make_pair(adobe::static_token_range("lang"), adobe::static_token_range("de_DE"))); app->display_window(); break; case ADOBE_LOCALIZATION_JAJP: adobe::implementation::top_frame().attribute_set_m.insert( std::make_pair(adobe::static_token_range("lang"), adobe::static_token_range("ja_JP"))); app->display_window(); break; case ADOBE_LOCALIZATION_KOKR: adobe::implementation::top_frame().attribute_set_m.insert( std::make_pair(adobe::static_token_range("lang"), adobe::static_token_range("ko_KR"))); app->display_window(); break; case ADOBE_LOCALIZATION_PGPG: adobe::implementation::top_frame().attribute_set_m.insert( std::make_pair(adobe::static_token_range("lang"), adobe::static_token_range("pg_PG"))); app->display_window(); break; default: handled = false; } } else if (message == WM_DROPFILES) { HDROP drop(reinterpret_cast<HDROP>(wParam)); UINT numfiles(::DragQueryFile(drop, 0xFFFFFFFF, NULL, 0)); for (UINT i(0); i < numfiles; ++i) { UINT size_needed(::DragQueryFile(drop, i, NULL, 0)); std::string buffer(size_needed + 1, 0); ::DragQueryFileA(drop, i, &buffer[0], size_needed + 1); std::string temp(&buffer[0]); if (temp.rfind(".adm") == temp.size() - 4) app->set_adam_file(boost::filesystem::path(temp.c_str(), boost::filesystem::native)); else if (temp.rfind(".eve") == temp.size() - 4) app->set_eve_file(boost::filesystem::path(temp.c_str(), boost::filesystem::native)); } ::DragFinish(drop); app->load_sheet(); } else if (message == WM_DESTROY) { } else { handled = false; } // // Pass it to the default window procedure if we haven't handled it. // return handled ? 0 : DefWindowProcW(window, message, wParam, lParam); }
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 M_LOOKUP_WEBSTER: { BString lookup; msg->FindString("string", &lookup); lookup = StringToURI(lookup.String()); lookup.Prepend("http://www.m-w.com/cgi-bin/dictionary?va="); vision_app->LoadURL(lookup.String()); } break; case M_LOOKUP_GOOGLE: { BString lookup; msg->FindString("string", &lookup); lookup = StringToURI(lookup.String()); lookup.Prepend("http://www.google.com/search?q="); vision_app->LoadURL(lookup.String()); } break; case M_LOOKUP_ACRONYM: { BString lookup; msg->FindString("string", &lookup); lookup = StringToURI(lookup.String()); lookup.Prepend("http://www.acronymfinder.com/af-query.asp?String=exact&Acronym="); lookup.Append("&Find=Find"); vision_app->LoadURL(lookup.String()); } 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); } }