From d6101558a171dbd2390792ac1e78d09fc2c27711 Mon Sep 17 00:00:00 2001 From: James Cook Date: Mon, 6 Jul 2009 21:58:04 +0000 Subject: Merge xui-army-5 to viewer-2, includes layout, art, and color changes, also UI color refactoring and new FreeType font library on Linux. svn merge -r126038:126164 svn+ssh://svn.lindenlab.com/svn/linden/branches/skinning/xui-army-5 --- indra/newview/llimpanel.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/newview/llimpanel.cpp') diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 6acd174fc3..fbf990e1af 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -1222,7 +1222,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label, addHistoryLine( session_start, - gSavedSkinSettings.getColor4("SystemChatColor"), + LLUIColorTable::instance().getColor("SystemChatColor"), false); } } @@ -2004,7 +2004,7 @@ void LLFloaterIMPanel::sendMsg() BOOL other_was_typing = mOtherTyping; - addHistoryLine(history_echo, gSavedSkinSettings.getColor("IMChatColor"), true, gAgent.getID()); + addHistoryLine(history_echo, LLUIColorTable::instance().getColor("IMChatColor"), true, gAgent.getID()); if (other_was_typing) { @@ -2175,7 +2175,7 @@ void LLFloaterIMPanel::addTypingIndicator(const std::string &name) mTypingLineStartIndex = mHistoryEditor->getWText().length(); LLUIString typing_start = sTypingStartString; typing_start.setArg("[NAME]", name); - addHistoryLine(typing_start, gSavedSkinSettings.getColor4("SystemChatColor"), false); + addHistoryLine(typing_start, LLUIColorTable::instance().getColor("SystemChatColor"), false); mOtherTypingName = name; mOtherTyping = TRUE; } @@ -2232,7 +2232,7 @@ void LLFloaterIMPanel::chatFromLogFile(LLLogChat::ELogLineType type, std::string } //self->addHistoryLine(line, LLColor4::grey, FALSE); - self->mHistoryEditor->appendColoredText(message, false, true, gSavedSkinSettings.getColor4("ChatHistoryTextColor")); + self->mHistoryEditor->appendColoredText(message, false, true, LLUIColorTable::instance().getColor("ChatHistoryTextColor")); } void LLFloaterIMPanel::showSessionStartError( -- cgit v1.2.3 From 52aeaa32841e7d0b37abab0a2a2540c2be2f16b7 Mon Sep 17 00:00:00 2001 From: James Cook Date: Tue, 7 Jul 2009 00:53:05 +0000 Subject: Merge skinning-14 to viewer-2, including refactoring many floaters to register them with LLFloaterReg, support for introspection of ParamBlock based UI widgets to dump XML schema, splitting llfolderview.cpp into three separate files to unravel dependencies and skeleton for for LLListView widget. Resolved conflicts in these files: lldraghandle.h, lluictrl.h, llchiclet.cpp, llfolderview.h/cpp, lliinventorybridge.cpp, llpanelpicks.cpp, llviewermenu.cpp, floater_mute.xml, floater_preferences.xml, notifications.xml, panel_preferences_audio.xml, panel_preferences_graphics1.xml, panel_region_general.xml svn merge -r124961:126284 svn+ssh://svn.lindenlab.com/svn/linden/branches/skinning/skinning-14 --- indra/newview/llimpanel.cpp | 389 +++++++++++--------------------------------- 1 file changed, 91 insertions(+), 298 deletions(-) (limited to 'indra/newview/llimpanel.cpp') diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index fbf990e1af..e5b05d9f51 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -55,8 +55,7 @@ #include "llimview.h" #include "llinventory.h" #include "llinventorymodel.h" -#include "llinventoryview.h" -#include "llfloateractivespeakers.h" +#include "llfloaterinventory.h" #include "llfloaterchat.h" #include "llkeyboard.h" #include "lllineeditor.h" @@ -101,190 +100,7 @@ LLVoiceChannel* LLVoiceChannel::sSuspendedVoiceChannel = NULL; BOOL LLVoiceChannel::sSuspended = FALSE; -void session_starter_helper( - const LLUUID& temp_session_id, - const LLUUID& other_participant_id, - EInstantMessage im_type) -{ - LLMessageSystem *msg = gMessageSystem; - - msg->newMessageFast(_PREHASH_ImprovedInstantMessage); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - - msg->nextBlockFast(_PREHASH_MessageBlock); - msg->addBOOLFast(_PREHASH_FromGroup, FALSE); - msg->addUUIDFast(_PREHASH_ToAgentID, other_participant_id); - msg->addU8Fast(_PREHASH_Offline, IM_ONLINE); - msg->addU8Fast(_PREHASH_Dialog, im_type); - msg->addUUIDFast(_PREHASH_ID, temp_session_id); - msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary - - std::string name; - gAgent.buildFullname(name); - - msg->addStringFast(_PREHASH_FromAgentName, name); - msg->addStringFast(_PREHASH_Message, LLStringUtil::null); - msg->addU32Fast(_PREHASH_ParentEstateID, 0); - msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null); - msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent()); -} - -void start_deprecated_conference_chat( - const LLUUID& temp_session_id, - const LLUUID& creator_id, - const LLUUID& other_participant_id, - const LLSD& agents_to_invite) -{ - U8* bucket; - U8* pos; - S32 count; - S32 bucket_size; - - // *FIX: this could suffer from endian issues - count = agents_to_invite.size(); - bucket_size = UUID_BYTES * count; - bucket = new U8[bucket_size]; - pos = bucket; - - for(S32 i = 0; i < count; ++i) - { - LLUUID agent_id = agents_to_invite[i].asUUID(); - - memcpy(pos, &agent_id, UUID_BYTES); - pos += UUID_BYTES; - } - - session_starter_helper( - temp_session_id, - other_participant_id, - IM_SESSION_CONFERENCE_START); - - gMessageSystem->addBinaryDataFast( - _PREHASH_BinaryBucket, - bucket, - bucket_size); - - gAgent.sendReliableMessage(); - - delete[] bucket; -} - -class LLStartConferenceChatResponder : public LLHTTPClient::Responder -{ -public: - LLStartConferenceChatResponder( - const LLUUID& temp_session_id, - const LLUUID& creator_id, - const LLUUID& other_participant_id, - const LLSD& agents_to_invite) - { - mTempSessionID = temp_session_id; - mCreatorID = creator_id; - mOtherParticipantID = other_participant_id; - mAgents = agents_to_invite; - } - - virtual void error(U32 statusNum, const std::string& reason) - { - //try an "old school" way. - if ( statusNum == 400 ) - { - start_deprecated_conference_chat( - mTempSessionID, - mCreatorID, - mOtherParticipantID, - mAgents); - } - - //else throw an error back to the client? - //in theory we should have just have these error strings - //etc. set up in this file as opposed to the IMMgr, - //but the error string were unneeded here previously - //and it is not worth the effort switching over all - //the possible different language translations - } - -private: - LLUUID mTempSessionID; - LLUUID mCreatorID; - LLUUID mOtherParticipantID; - - LLSD mAgents; -}; - -// Returns true if any messages were sent, false otherwise. -// Is sort of equivalent to "does the server need to do anything?" -bool send_start_session_messages( - const LLUUID& temp_session_id, - const LLUUID& other_participant_id, - const std::vector& ids, - EInstantMessage dialog) -{ - if ( dialog == IM_SESSION_GROUP_START ) - { - session_starter_helper( - temp_session_id, - other_participant_id, - dialog); - - switch(dialog) - { - case IM_SESSION_GROUP_START: - gMessageSystem->addBinaryDataFast( - _PREHASH_BinaryBucket, - EMPTY_BINARY_BUCKET, - EMPTY_BINARY_BUCKET_SIZE); - break; - default: - break; - } - gAgent.sendReliableMessage(); - return true; - } - else if ( dialog == IM_SESSION_CONFERENCE_START ) - { - LLSD agents; - for (int i = 0; i < (S32) ids.size(); i++) - { - agents.append(ids[i]); - } - - //we have a new way of starting conference calls now - LLViewerRegion* region = gAgent.getRegion(); - if (region) - { - std::string url = region->getCapability( - "ChatSessionRequest"); - LLSD data; - data["method"] = "start conference"; - data["session-id"] = temp_session_id; - - data["params"] = agents; - - LLHTTPClient::post( - url, - data, - new LLStartConferenceChatResponder( - temp_session_id, - gAgent.getID(), - other_participant_id, - data["params"])); - } - else - { - start_deprecated_conference_chat( - temp_session_id, - gAgent.getID(), - other_participant_id, - agents); - } - } - - return false; -} class LLVoiceCallCapResponder : public LLHTTPClient::Responder { @@ -1200,7 +1016,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label, if ( !mSessionInitialized ) { - if ( !send_start_session_messages( + if ( !LLIMModel::instance().sendStartSession( mSessionUUID, mOtherParticipantUUID, mSessionInitialTargetIDs, @@ -1542,19 +1358,21 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4 prepend_newline = false; } + std::string separator_string(": "); + // 'name' is a sender name that we want to hotlink so that clicking on it opens a profile. if (!name.empty()) // If name exists, then add it to the front of the message. { // Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text. if (name == SYSTEM_FROM) { - mHistoryEditor->appendColoredText(name,false,prepend_newline,color); + mHistoryEditor->appendColoredText(name + separator_string, false, prepend_newline, color); } else { // Convert the name to a hotlink and add to message. const LLStyleSP &source_style = LLStyleMap::instance().lookupAgent(source); - mHistoryEditor->appendStyledText(name,false,prepend_newline,source_style); + mHistoryEditor->appendStyledText(name + separator_string, false, prepend_newline, source_style); } prepend_newline = false; } @@ -1565,9 +1383,9 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4 { std::string histstr; if (gSavedPerAccountSettings.getBOOL("IMLogTimestamp")) - histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + name + utf8msg; + histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + name + separator_string + utf8msg; else - histstr = name + utf8msg; + histstr = name + separator_string + utf8msg; LLLogChat::saveHistory(getTitle(),histstr); } @@ -1620,7 +1438,6 @@ void LLFloaterIMPanel::selectNone() mInputEditor->deselect(); } - BOOL LLFloaterIMPanel::handleKeyHere( KEY key, MASK mask ) { BOOL handled = FALSE; @@ -1847,23 +1664,8 @@ void LLFloaterIMPanel::onClose(bool app_quitting) { setTyping(FALSE); - if(mSessionUUID.notNull()) - { - std::string name; - gAgent.buildFullname(name); - pack_instant_message( - gMessageSystem, - gAgent.getID(), - FALSE, - gAgent.getSessionID(), - mOtherParticipantUUID, - name, - LLStringUtil::null, - IM_ONLINE, - IM_SESSION_LEAVE, - mSessionUUID); - gAgent.sendReliableMessage(); - } + LLIMModel::instance().sendLeaveSession(mSessionUUID, mOtherParticipantUUID); + gIMMgr->removeSession(mSessionUUID); // *HACK hide the voice floater @@ -1884,79 +1686,6 @@ void LLFloaterIMPanel::onVisibilityChange(BOOL new_visibility) mSessionUUID); } -void deliver_message(const std::string& utf8_text, - const LLUUID& im_session_id, - const LLUUID& other_participant_id, - EInstantMessage dialog) -{ - std::string name; - bool sent = false; - gAgent.buildFullname(name); - - const LLRelationship* info = NULL; - info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id); - - U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE; - - if((offline == IM_OFFLINE) && (LLVoiceClient::getInstance()->isOnlineSIP(other_participant_id))) - { - // User is online through the OOW connector, but not with a regular viewer. Try to send the message via SLVoice. - sent = gVoiceClient->sendTextMessage(other_participant_id, utf8_text); - } - - if(!sent) - { - // Send message normally. - - // default to IM_SESSION_SEND unless it's nothing special - in - // which case it's probably an IM to everyone. - U8 new_dialog = dialog; - - if ( dialog != IM_NOTHING_SPECIAL ) - { - new_dialog = IM_SESSION_SEND; - } - pack_instant_message( - gMessageSystem, - gAgent.getID(), - FALSE, - gAgent.getSessionID(), - other_participant_id, - name.c_str(), - utf8_text.c_str(), - offline, - (EInstantMessage)new_dialog, - im_session_id); - gAgent.sendReliableMessage(); - } - - // If there is a mute list and this is not a group chat... - if ( LLMuteList::getInstance() ) - { - // ... the target should not be in our mute list for some message types. - // Auto-remove them if present. - switch( dialog ) - { - case IM_NOTHING_SPECIAL: - case IM_GROUP_INVITATION: - case IM_INVENTORY_OFFERED: - case IM_SESSION_INVITE: - case IM_SESSION_P2P_INVITE: - case IM_SESSION_CONFERENCE_START: - case IM_SESSION_SEND: // This one is marginal - erring on the side of hearing. - case IM_LURE_USER: - case IM_GODLIKE_LURE_USER: - case IM_FRIENDSHIP_OFFERED: - LLMuteList::getInstance()->autoRemove(other_participant_id, LLMuteList::AR_IM); - break; - default: ; // do nothing - } - } - - // Add the recipient to the recent people list. - LLRecentPeople::instance().add(other_participant_id); -} - void LLFloaterIMPanel::sendMsg() { if (!gAgent.isGodlike() @@ -1978,7 +1707,7 @@ void LLFloaterIMPanel::sendMsg() if ( mSessionInitialized ) { - deliver_message(utf8_text, + LLIMModel::sendMessage(utf8_text, mSessionUUID, mOtherParticipantUUID, mDialog); @@ -2084,7 +1813,7 @@ void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id) iter != mQueuedMsgsForInit.endArray(); ++iter) { - deliver_message( + LLIMModel::sendMessage( iter->asString(), mSessionUUID, mOtherParticipantUUID, @@ -2135,23 +1864,10 @@ void LLFloaterIMPanel::sendTypingState(BOOL typing) // much network traffic. Only send in person-to-person IMs. if (mDialog != IM_NOTHING_SPECIAL) return; - std::string name; - gAgent.buildFullname(name); - - pack_instant_message( - gMessageSystem, - gAgent.getID(), - FALSE, - gAgent.getSessionID(), - mOtherParticipantUUID, - name, - std::string("typing"), - IM_ONLINE, - (typing ? IM_TYPING_START : IM_TYPING_STOP), - mSessionUUID); - gAgent.sendReliableMessage(); + LLIMModel::instance().sendTypingState(mSessionUUID, mOtherParticipantUUID, typing); } + void LLFloaterIMPanel::processIMTyping(const LLIMInfo* im_info, BOOL typing) { if (typing) @@ -2320,3 +2036,80 @@ bool LLFloaterIMPanel::onConfirmForceCloseError(const LLSD& notification, const } +std::map LLIMFloater::sIMFloaterMap; + +LLIMFloater::LLIMFloater(const LLUUID& session_id, + const std::string title, + EInstantMessage dialog) +: mSessionID(session_id), + mIndex(0) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im_session.xml"); + sIMFloaterMap[mSessionID] = this; + + setTitle(title); +} + +LLIMFloater::~LLIMFloater() +{ + sIMFloaterMap.erase(mSessionID); +} + + +void LLIMFloater::show(const LLUUID& session_id, S32 center_x) +{ + + LLIMFloater* floater = get_if_there(sIMFloaterMap, session_id, (LLIMFloater*)NULL); + + if (floater == NULL) + { + floater = new LLIMFloater(session_id, LLIMModel::instance().getName(session_id), IM_NOTHING_SPECIAL); + } + + //hide all + for (std::map::iterator iter = sIMFloaterMap.begin(); + iter != sIMFloaterMap.end(); ++iter) + { + LLIMFloater* floater = (*iter).second; + floater->setVisible(false); + } + + floater->setVisibleAndFrontmost(true); + + floater->updateMessages(session_id); + + floater->translate(center_x - floater->getRect().getCenterX(), gFloaterView->getRect().mBottom - floater->getRect().mBottom); + +} + +void LLIMFloater::updateMessages(const LLUUID& session_id) +{ + + LLTextEditor* text_editor = getChild("im_text", true, false); + + if (!text_editor) + { + llwarns << "Text editor not found! " << llendl; + return; + } + + std::list messages = LLIMModel::instance().getMessages(mSessionID, mIndex); + + if (messages.size()) + { + std::ostringstream message; + std::list::const_reverse_iterator iter = messages.rbegin(); + std::list::const_reverse_iterator iter_end = messages.rend(); + for (; iter != iter_end; ++iter) + { + LLSD msg = *iter; + + message << msg["from"].asString() << " : " << msg["time"].asString() << "\n " << msg["message"].asString() << "\n"; + + mIndex = msg["index"].asInteger(); + } + + text_editor->setText(message.str()); + } + +} -- cgit v1.2.3 From 8016e73cc0a2a27062fae27e609535e002eef362 Mon Sep 17 00:00:00 2001 From: Leyla Farazha Date: Thu, 9 Jul 2009 22:30:15 +0000 Subject: svn merge -r126726:126727 svn+ssh://svn.lindenlab.com/linden/branches/skinning/skinning-15/ DEV-35109 Nav bar does not record teleports taken by any method other than typing into nav bar DEV-35117 Hard to open local chat, needs bottom bar widget for now hiding test IM floaters --- indra/newview/llimpanel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llimpanel.cpp') diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index e5b05d9f51..9bf147584a 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -2074,7 +2074,7 @@ void LLIMFloater::show(const LLUUID& session_id, S32 center_x) floater->setVisible(false); } - floater->setVisibleAndFrontmost(true); + //floater->setVisibleAndFrontmost(true); floater->updateMessages(session_id); -- cgit v1.2.3 From 73a97010e6c8c7874fdc1778ab46e492f77d9394 Mon Sep 17 00:00:00 2001 From: Steven Bennetts Date: Tue, 21 Jul 2009 00:57:23 +0000 Subject: merge https://svn.aws.productengine.com/secondlife/export-from-ll/viewer-2-0/indra@1059 https://svn.aws.productengine.com/secondlife/pe/stable-1/indra@1070 -> svn+ssh://svn.lindenlab.com/svn/linden/branches/viewer/viewer-2.0.0-3 --- indra/newview/llimpanel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llimpanel.cpp') diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 9bf147584a..0652119f18 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -51,7 +51,7 @@ #include "llfloater.h" #include "llfloatercall.h" #include "llfloatergroupinfo.h" -#include "llfriendactions.h" +#include "llavataractions.h" #include "llimview.h" #include "llinventory.h" #include "llinventorymodel.h" @@ -1569,7 +1569,7 @@ void LLFloaterIMPanel::onClickProfile( void* userdata ) if (self->getOtherParticipantID().notNull()) { - LLFriendActions::showProfile(self->getOtherParticipantID()); + LLAvatarActions::showProfile(self->getOtherParticipantID()); } } -- cgit v1.2.3 From ca51e8f33dfa0cd455438f11902fb1d839bf6206 Mon Sep 17 00:00:00 2001 From: James Cook Date: Mon, 27 Jul 2009 16:50:01 +0000 Subject: Merge xui-army-8 to pick up 2+ weeks of art, colors, and dialog layout changes. svn merge -r128075:128364 svn+ssh://svn.lindenlab.com/svn/linden/branches/skinning/xui-army-8 --- indra/newview/llimpanel.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'indra/newview/llimpanel.cpp') diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 0652119f18..5b4f711099 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -1377,17 +1377,23 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4 prepend_newline = false; } mHistoryEditor->appendColoredText(utf8msg, false, prepend_newline, color); - - if (log_to_file - && gSavedPerAccountSettings.getBOOL("LogInstantMessages") ) + S32 im_log_option = gSavedPerAccountSettings.getS32("IMLogOptions"); + if (log_to_file && (im_log_option!=LOG_CHAT)) { std::string histstr; - if (gSavedPerAccountSettings.getBOOL("IMLogTimestamp")) + if (gSavedPerAccountSettings.getBOOL("LogTimestamp")) histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + name + separator_string + utf8msg; else histstr = name + separator_string + utf8msg; - LLLogChat::saveHistory(getTitle(),histstr); + if(im_log_option==LOG_BOTH_TOGETHER) + { + LLLogChat::saveHistory(std::string("chat"),histstr); + } + else + { + LLLogChat::saveHistory(getTitle(),histstr); + } } if (!isInVisibleChain()) @@ -1922,19 +1928,19 @@ void LLFloaterIMPanel::chatFromLogFile(LLLogChat::ELogLineType type, std::string { LLFloaterIMPanel* self = (LLFloaterIMPanel*)userdata; std::string message = line; - + S32 im_log_option = gSavedPerAccountSettings.getS32("IMLogOptions"); switch (type) { case LLLogChat::LOG_EMPTY: // add warning log enabled message - if (gSavedPerAccountSettings.getBOOL("LogInstantMessages")) + if (im_log_option!=LOG_CHAT) { message = LLTrans::getString("IM_logging_string"); } break; case LLLogChat::LOG_END: // add log end message - if (gSavedPerAccountSettings.getBOOL("LogInstantMessages")) + if (im_log_option!=LOG_CHAT) { message = LLTrans::getString("IM_logging_string"); } -- cgit v1.2.3 From 8f7ec64899c54dcee6caa0307510cc4003ba7bdd Mon Sep 17 00:00:00 2001 From: James Cook Date: Mon, 27 Jul 2009 17:56:26 +0000 Subject: Merged skinning-17 into viewer-2 for bug fixes. Commented out new IM window for now, not complete. Merging revisions 127913-128319 of svn+ssh://svn.lindenlab.com/svn/linden/branches/skinning/skinning-17 into D:\viewer-2.0.0-3, respecting ancestry --- indra/newview/llimpanel.cpp | 235 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 216 insertions(+), 19 deletions(-) (limited to 'indra/newview/llimpanel.cpp') diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 5b4f711099..248a8dbc4c 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -45,8 +45,10 @@ #include "llagent.h" #include "llbutton.h" +#include "llbottomtray.h" #include "llcallingcard.h" #include "llchat.h" +#include "llchiclet.h" #include "llconsole.h" #include "llfloater.h" #include "llfloatercall.h" @@ -57,9 +59,12 @@ #include "llinventorymodel.h" #include "llfloaterinventory.h" #include "llfloaterchat.h" +#include "lliconctrl.h" +#include "llimview.h" // for LLIMModel to get other avatar id in chat #include "llkeyboard.h" #include "lllineeditor.h" #include "llnotify.h" +#include "llpanelimcontrolpanel.h" #include "llrecentpeople.h" #include "llresmgr.h" #include "lltrans.h" @@ -2040,7 +2045,7 @@ bool LLFloaterIMPanel::onConfirmForceCloseError(const LLSD& notification, const } return false; } - + std::map LLIMFloater::sIMFloaterMap; @@ -2048,23 +2053,183 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id, const std::string title, EInstantMessage dialog) : mSessionID(session_id), - mIndex(0) + mLastMessageIndex(-1), + mDialog(dialog) { LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im_session.xml"); sIMFloaterMap[mSessionID] = this; + LLPanelIMControlPanel* im_control_panel = getChild("panel_im_control_panel"); + + LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, session_id, (LLIMModel::LLIMSession*)NULL); + if(session) + { + mOtherParticipantUUID = session->mOtherParticipantID; + im_control_panel->setAvatarId(session->mOtherParticipantID); + } + + LLButton* slide_left = getChild("slide_left_btn"); + slide_left->setVisible(im_control_panel->getVisible()); + slide_left->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this)); + + LLButton* slide_right = getChild("slide_right_btn"); + slide_right->setVisible(!im_control_panel->getVisible()); + slide_right->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this)); + setTitle(title); + setDocked(true); + + mInputEditor = getChild("chat_editor"); + + + mInputEditor->setMaxTextLength(1023); + // enable line history support for instant message bar + mInputEditor->setEnableLineHistory(TRUE); + + mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this ); + mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this ); + mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this ); + mInputEditor->setCommitOnFocusLost( FALSE ); + mInputEditor->setRevertOnEsc( FALSE ); + mInputEditor->setReplaceNewlinesWithSpaces( FALSE ); + + childSetCommitCallback("chat_editor", onSendMsg, this); +} + +/* static */ +void LLIMFloater::newIMCallback(const LLSD& data){ + + if (data["num_unread"].asInteger() > 0) + { + LLUUID session_id = data["session_id"].asUUID(); + + LLIMFloater* floater = get_if_there(sIMFloaterMap, session_id, (LLIMFloater*)NULL); + + if (floater == NULL) + { + llwarns << "new_im_callback for non-existent session_id " << session_id << llendl; + return; + } + + // update if visible, otherwise will be updated when opened + if (floater->getVisible()) + { + floater->updateMessages(); + } + } +} + +void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata ) +{ + LLIMFloater* self = (LLIMFloater*) userdata; + self->sendMsg(); } +void LLIMFloater::sendMsg() +{ + if (!gAgent.isGodlike() + && (mDialog == IM_NOTHING_SPECIAL) + && mOtherParticipantUUID.isNull()) + { + llinfos << "Cannot send IM to everyone unless you're a god." << llendl; + return; + } + + if (mInputEditor) + { + LLWString text = mInputEditor->getConvertedText(); + if(!text.empty()) + { + // Truncate and convert to UTF8 for transport + std::string utf8_text = wstring_to_utf8str(text); + utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1); + + LLIMModel::sendMessage(utf8_text, + mSessionID, + mOtherParticipantUUID, + mDialog); + + mInputEditor->setText(LLStringUtil::null); + + updateMessages(); + } + } +} + + + LLIMFloater::~LLIMFloater() { sIMFloaterMap.erase(mSessionID); } +//virtual +BOOL LLIMFloater::postBuild() +{ + mHistoryEditor = getChild("im_text", true, false); + mChiclet = LLBottomTray::getInstance()->getChicletPanel()->findChiclet(mSessionID); + + if (!mChiclet) + { + llwarns << "No chiclet found for the IMFloter" << llendl; + } + setDocked(false); + return TRUE; +} + +const U32 UNDOCK_LEAP_HEIGHT = 12; +const U32 DOCK_ICON_HEIGHT = 6; -void LLIMFloater::show(const LLUUID& session_id, S32 center_x) +//virtual +void LLIMFloater::onFocusLost() { + // spec says close if docked to bottom tray and user has clicked away + // (hence we are no longer focused) + if (isDocked()) + { + // app not quitting + closeFloater(false); + } +} + +//virtual +void LLIMFloater::setDocked(bool docked, bool pop_on_undock) +{ + LLFloater::setDocked(docked); + mChiclet->setDockTongueVisible(docked); + if (docked) + { + S32 x, y; + mChiclet->localPointToScreen((mChiclet->getRect().getWidth())/2, 0, &x, &y); + translate(x - getRect().getCenterX(), DOCK_ICON_HEIGHT - getRect().mBottom); + } + else if (pop_on_undock) + { + // visually pop up a little bit to emphasize the undocking + translate(0, UNDOCK_LEAP_HEIGHT); + } +} + + +void LLIMFloater::onClose(bool app_quitting) +{ + mChiclet->setDockTongueVisible(false); + LLFloater::onClose(app_quitting); +} + +void LLIMFloater::onSlide() +{ + LLPanel* im_control_panel = getChild("panel_im_control_panel"); + im_control_panel->setVisible(!im_control_panel->getVisible()); + + getChild("slide_left_btn")->setVisible(im_control_panel->getVisible()); + getChild("slide_right_btn")->setVisible(!im_control_panel->getVisible()); +} + +//static +LLIMFloater* LLIMFloater::show(const LLUUID& session_id) +{ LLIMFloater* floater = get_if_there(sIMFloaterMap, session_id, (LLIMFloater*)NULL); if (floater == NULL) @@ -2078,28 +2243,25 @@ void LLIMFloater::show(const LLUUID& session_id, S32 center_x) { LLIMFloater* floater = (*iter).second; floater->setVisible(false); + floater->mChiclet->setDockTongueVisible(false); + } - //floater->setVisibleAndFrontmost(true); + floater->setVisibleAndFrontmost(true); - floater->updateMessages(session_id); - - floater->translate(center_x - floater->getRect().getCenterX(), gFloaterView->getRect().mBottom - floater->getRect().mBottom); + if (floater->isDocked()) + { + floater->mChiclet->setDockTongueVisible(true); + } + floater->updateMessages(); + return floater; } -void LLIMFloater::updateMessages(const LLUUID& session_id) +void LLIMFloater::updateMessages() { - LLTextEditor* text_editor = getChild("im_text", true, false); - - if (!text_editor) - { - llwarns << "Text editor not found! " << llendl; - return; - } - - std::list messages = LLIMModel::instance().getMessages(mSessionID, mIndex); + std::list messages = LLIMModel::instance().getMessages(mSessionID, mLastMessageIndex+1); if (messages.size()) { @@ -2112,10 +2274,45 @@ void LLIMFloater::updateMessages(const LLUUID& session_id) message << msg["from"].asString() << " : " << msg["time"].asString() << "\n " << msg["message"].asString() << "\n"; - mIndex = msg["index"].asInteger(); + mLastMessageIndex = msg["index"].asInteger(); } - text_editor->setText(message.str()); + mHistoryEditor->appendText(message.str(), false, false); + mHistoryEditor->setCursorAndScrollToEnd(); } } +// static +void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ) +{ + LLIMFloater* self= (LLIMFloater*) userdata; + self->mHistoryEditor->setCursorAndScrollToEnd(); +} + +// static +void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata) +{ + LLIMFloater* self = (LLIMFloater*) userdata; + self->setTyping(FALSE); +} + +// static +void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata) +{ + LLIMFloater* self = (LLIMFloater*)userdata; + std::string text = self->mInputEditor->getText(); + if (!text.empty()) + { + self->setTyping(TRUE); + } + else + { + // Deleting all text counts as stopping typing. + self->setTyping(FALSE); + } +} + +//just a stub for now +void LLIMFloater::setTyping(BOOL typing) +{ +} -- cgit v1.2.3