Newer
Older
Steven Bennetts
committed
/**
* @file llchatitemscontainer.cpp
* @brief chat history scrolling panel implementation
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
Steven Bennetts
committed
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
Steven Bennetts
committed
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
Steven Bennetts
committed
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Steven Bennetts
committed
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
Steven Bennetts
committed
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llchatitemscontainerctrl.h"
Steven Bennetts
committed
#include "lltextbox.h"
maxim_productengine
committed
#include "llavataractions.h"
Steven Bennetts
committed
#include "llavatariconctrl.h"
Vadim ProductEngine
committed
#include "llcommandhandler.h"
Steven Bennetts
committed
#include "llfloaterreg.h"
Richard Nelson
committed
#include "lllocalcliprect.h"
Steven Bennetts
committed
#include "lltrans.h"
AlexanderP ProductEngine
committed
#include "llfloaterimnearbychat.h"
Steven Bennetts
committed
#include "llviewercontrol.h"
Steven Bennetts
committed
Yuri Chebotarev
committed
#include "llslurl.h"
static const S32 msg_left_offset = 10;
static const S32 msg_height_pad = 5;
Steven Bennetts
committed
Vadim ProductEngine
committed
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//*******************************************************************************************************************
// LLObjectHandler
//*******************************************************************************************************************
// handle secondlife:///app/object/<ID>/inspect SLURLs
class LLObjectHandler : public LLCommandHandler
{
public:
LLObjectHandler() : LLCommandHandler("object", UNTRUSTED_BLOCK) { }
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
{
if (params.size() < 2) return false;
LLUUID object_id;
if (!object_id.set(params[0], FALSE))
{
return false;
}
const std::string verb = params[1].asString();
if (verb == "inspect")
{
LLFloaterReg::showInstance("inspect_object", LLSD().with("object_id", object_id));
return true;
}
return false;
}
};
LLObjectHandler gObjectHandler;
Steven Bennetts
committed
//*******************************************************************************************************************
AlexanderP ProductEngine
committed
//LLFloaterIMNearbyChatToastPanel
Steven Bennetts
committed
//*******************************************************************************************************************
AlexanderP ProductEngine
committed
LLFloaterIMNearbyChatToastPanel* LLFloaterIMNearbyChatToastPanel::createInstance()
Steven Bennetts
committed
{
AlexanderP ProductEngine
committed
LLFloaterIMNearbyChatToastPanel* item = new LLFloaterIMNearbyChatToastPanel();
item->buildFromFile("panel_chat_item.xml");
Steven Bennetts
committed
return item;
}
AlexanderP ProductEngine
committed
void LLFloaterIMNearbyChatToastPanel::reshape (S32 width, S32 height, BOOL called_from_parent )
Steven Bennetts
committed
{
LLPanel::reshape(width, height,called_from_parent);
// reshape() may be called from LLView::initFromParams() before the children are created.
// We call findChild() instead of getChild() here to avoid creating dummy controls.
LLUICtrl* msg_text = findChild<LLUICtrl>("msg_text", false);
LLUICtrl* icon = findChild<LLUICtrl>("avatar_icon", false);
if (!msg_text || !icon)
{
return;
}
LLRect msg_text_rect = msg_text->getRect();
LLRect avatar_rect = icon->getRect();
avatar_rect.setLeftTopAndSize(2,height-2,avatar_rect.getWidth(),avatar_rect.getHeight());
icon->setRect(avatar_rect);
msg_text_rect.setLeftTopAndSize( avatar_rect.mRight + msg_left_offset,
height - msg_height_pad,
width - avatar_rect.mRight - msg_left_offset - msg_right_offset,
height - 2*msg_height_pad);
msg_text->reshape( msg_text_rect.getWidth(), msg_text_rect.getHeight(), 1);
msg_text->setRect(msg_text_rect);
Steven Bennetts
committed
}
AlexanderP ProductEngine
committed
BOOL LLFloaterIMNearbyChatToastPanel::postBuild()
Steven Bennetts
committed
{
return LLPanel::postBuild();
}
AlexanderP ProductEngine
committed
void LLFloaterIMNearbyChatToastPanel::addMessage(LLSD& notification)
Steven Bennetts
committed
{
std::string messageText = notification["message"].asString(); // UTF-8 line of text
Steven Bennetts
committed
std::string color_name = notification["text_color"].asString();
LLColor4 textColor = LLUIColorTable::instance().getColor(color_name);
textColor.mV[VALPHA] =notification["color_alpha"].asReal();
S32 font_size = notification["font_size"].asInteger();
Steven Bennetts
committed
LLFontGL* messageFont;
switch(font_size)
{
case 0: messageFont = LLFontGL::getFontSansSerifSmall(); break;
default:
case 1: messageFont = LLFontGL::getFontSansSerif(); break;
case 2: messageFont = LLFontGL::getFontSansSerifBig(); break;
}
Steven Bennetts
committed
//append text
{
LLStyle::Params style_params;
style_params.color(textColor);
std::string font_name = LLFontGL::nameFromFont(messageFont);
std::string font_style_size = LLFontGL::sizeFromFont(messageFont);
style_params.font.name(font_name);
style_params.font.size(font_style_size);
Steven Bennetts
committed
int chat_type = notification["chat_type"].asInteger();
if(notification["chat_style"].asInteger()== CHAT_STYLE_IRC)
{
style_params.font.style = "ITALIC";
}
else if( chat_type == CHAT_TYPE_SHOUT)
{
style_params.font.style = "BOLD";
}
else if( chat_type == CHAT_TYPE_WHISPER)
{
style_params.font.style = "ITALIC";
}
mMsgText->appendText(messageText, TRUE, style_params);
}
snapToMessageHeight();
Steven Bennetts
committed
}
AlexanderP ProductEngine
committed
void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification)
Steven Bennetts
committed
{
std::string messageText = notification["message"].asString(); // UTF-8 line of text
std::string fromName = notification["from"].asString(); // agent or object name
mFromID = notification["from_id"].asUUID(); // agent id or object id
Igor Borovkov
committed
mFromName = fromName;
int sType = notification["source"].asInteger();
mSourceType = (EChatSourceType)sType;
std::string color_name = notification["text_color"].asString();
LLColor4 textColor = LLUIColorTable::instance().getColor(color_name);
textColor.mV[VALPHA] =notification["color_alpha"].asReal();
S32 font_size = notification["font_size"].asInteger();
LLFontGL* messageFont;
switch(font_size)
{
case 0: messageFont = LLFontGL::getFontSansSerifSmall(); break;
case 1: messageFont = LLFontGL::getFontSansSerif(); break;
case 2: messageFont = LLFontGL::getFontSansSerifBig(); break;
mMsgText = getChild<LLChatMsgBox>("msg_text", false);
mMsgText->setContentTrusted(false);
maxim_productengine
committed
mMsgText->setIsFriendCallback(LLAvatarActions::isFriend);
mMsgText->setText(std::string(""));
if ( notification["chat_style"].asInteger() != CHAT_STYLE_IRC )
{
std::string str_sender;
Vadim ProductEngine
committed
str_sender = fromName;
Steven Bennetts
committed
str_sender+=" ";
Vadim ProductEngine
committed
//append sender name
if (mSourceType == CHAT_SOURCE_AGENT || mSourceType == CHAT_SOURCE_OBJECT)
{
LLStyle::Params style_params_name;
Seth ProductEngine
committed
LLColor4 user_name_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
style_params_name.color(user_name_color);
std::string font_name = LLFontGL::nameFromFont(messageFont);
std::string font_style_size = LLFontGL::sizeFromFont(messageFont);
style_params_name.font.name(font_name);
style_params_name.font.size(font_style_size);
Vadim ProductEngine
committed
style_params_name.link_href = notification["sender_slurl"].asString();
Vadim ProductEngine
committed
style_params_name.is_link = true;
Yuri Chebotarev
committed
mMsgText->appendText(str_sender, FALSE, style_params_name);
}
Vadim ProductEngine
committed
else
{
mMsgText->appendText(str_sender, false);
Vadim ProductEngine
committed
}
Mnikolenko Productengine
committed
S32 chars_in_line = mMsgText->getRect().getWidth() / messageFont->getWidth("c");
S32 max_lines = notification["available_height"].asInteger() / (mMsgText->getTextPixelHeight() + 4);
int lines = 0;
int chars = 0;
Mnikolenko Productengine
committed
//Remove excessive chars if message does not fit in available height. MAINT-6891
std::string::iterator it;
for (it = messageText.begin(); it < messageText.end() && lines < max_lines; it++)
Mnikolenko Productengine
committed
{
if (*it == '\n')
++lines;
else
++chars;
if (chars >= chars_in_line)
Mnikolenko Productengine
committed
{
chars = 0;
++lines;
Mnikolenko Productengine
committed
}
}
if (it < messageText.end())
{
messageText.erase(it, messageText.end());
Mnikolenko Productengine
committed
messageText += " ...";
}
LLStyle::Params style_params;
style_params.color(textColor);
std::string font_name = LLFontGL::nameFromFont(messageFont);
std::string font_style_size = LLFontGL::sizeFromFont(messageFont);
style_params.font.name(font_name);
style_params.font.size(font_style_size);
int chat_type = notification["chat_type"].asInteger();
if(notification["chat_style"].asInteger()== CHAT_STYLE_IRC)
style_params.font.style = "ITALIC";
else if( chat_type == CHAT_TYPE_SHOUT)
{
style_params.font.style = "BOLD";
}
else if( chat_type == CHAT_TYPE_WHISPER)
{
style_params.font.style = "ITALIC";
}
mMsgText->appendText(messageText, FALSE, style_params);
snapToMessageHeight();
AlexanderP ProductEngine
committed
void LLFloaterIMNearbyChatToastPanel::snapToMessageHeight ()
S32 new_height = llmax (mMsgText->getTextPixelHeight() + 2*mMsgText->getVPad() + 2*msg_height_pad, 25);
panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth(), new_height);
reshape( getRect().getWidth(), getRect().getHeight(), 1);
AlexanderP ProductEngine
committed
void LLFloaterIMNearbyChatToastPanel::onMouseLeave (S32 x, S32 y, MASK mask)
Steven Bennetts
committed
{
}
AlexanderP ProductEngine
committed
void LLFloaterIMNearbyChatToastPanel::onMouseEnter (S32 x, S32 y, MASK mask)
Steven Bennetts
committed
{
Steven Bennetts
committed
}
AlexanderP ProductEngine
committed
BOOL LLFloaterIMNearbyChatToastPanel::handleMouseDown (S32 x, S32 y, MASK mask)
Yuri Chebotarev
committed
{
return LLPanel::handleMouseDown(x,y,mask);
}
AlexanderP ProductEngine
committed
BOOL LLFloaterIMNearbyChatToastPanel::handleMouseUp (S32 x, S32 y, MASK mask)
Steven Bennetts
committed
{
Ychebotarev ProductEngine
committed
/*
fix for request EXT-4780
leaving this commented since I don't remember why ew block those messages...
Yuri Chebotarev
committed
return LLPanel::handleMouseUp(x,y,mask);
Ychebotarev ProductEngine
committed
*/
Yuri Chebotarev
committed
S32 local_x = x - mMsgText->getRect().mLeft;
S32 local_y = y - mMsgText->getRect().mBottom;
Yuri Chebotarev
committed
//if text_box process mouse up (ussually this is click on url) - we didn't show nearby_chat.
if (mMsgText->pointInView(local_x, local_y) )
Yuri Chebotarev
committed
{
if (mMsgText->handleMouseUp(local_x,local_y,mask) == TRUE)
Yuri Chebotarev
committed
return TRUE;
else
{
Mnikolenko ProductEngine
committed
LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")->showHistory();
Yuri Chebotarev
committed
return FALSE;
}
}
Mnikolenko ProductEngine
committed
LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")->showHistory();
Yuri Chebotarev
committed
return LLPanel::handleMouseUp(x,y,mask);
Steven Bennetts
committed
}
AlexanderP ProductEngine
committed
void LLFloaterIMNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
Steven Bennetts
committed
{
LLUICtrl* icon = getChild<LLUICtrl>("avatar_icon", false);
if(icon)
icon->setVisible(e == CHATITEMHEADER_SHOW_ONLY_ICON || e==CHATITEMHEADER_SHOW_BOTH);
Steven Bennetts
committed
}
AlexanderP ProductEngine
committed
bool LLFloaterIMNearbyChatToastPanel::canAddText ()
Steven Bennetts
committed
{
LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text");
if(!msg_text)
return false;
James Cook
committed
return msg_text->getLineCount()<10;
Steven Bennetts
committed
}
AlexanderP ProductEngine
committed
BOOL LLFloaterIMNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
LLUICtrl* avatar_icon = getChild<LLUICtrl>("avatar_icon", false);
S32 local_x = x - avatar_icon->getRect().mLeft;
S32 local_y = y - avatar_icon->getRect().mBottom;
if(avatar_icon->pointInView(local_x, local_y) && mSourceType != CHAT_SOURCE_AGENT)
return TRUE;
return LLPanel::handleRightMouseDown(x,y,mask);
}
AlexanderP ProductEngine
committed
void LLFloaterIMNearbyChatToastPanel::draw()
Steven Bennetts
committed
{
LLPanel::draw();
Steven Bennetts
committed
{
LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon", false);
if(icon)
{
icon->setDrawTooltip(mSourceType == CHAT_SOURCE_AGENT);
Yuri Chebotarev
committed
if(mSourceType == CHAT_SOURCE_OBJECT)
icon->setValue(LLSD("OBJECT_Icon"));
Dmitry Zaporozhan
committed
else if(mSourceType == CHAT_SOURCE_SYSTEM)
icon->setValue(LLSD("SL_Logo"));
Yuri Chebotarev
committed
else if(mSourceType == CHAT_SOURCE_AGENT)
icon->setValue(mFromID);
else if(!mFromID.isNull())
icon->setValue(mFromID);
}