master
Leyla Farazha 2010-05-25 14:22:56 -07:00
commit 16e3d7ebf5
185 changed files with 4343 additions and 2349 deletions

View File

@ -608,6 +608,7 @@ tenebrous pau
Tharax Ferraris
VWR-605
Thickbrick Sleaford
SNOW-207
VWR-7109
VWR-9287
VWR-13483

View File

@ -99,7 +99,7 @@ void LLAvatarName::fromLLSD(const LLSD& sd)
mExpires = expires.secondsSinceEpoch();
}
std::string LLAvatarName::getNameAndSLID() const
std::string LLAvatarName::getCompleteName() const
{
std::string name;
if (!mUsername.empty())

View File

@ -51,7 +51,7 @@ public:
// For normal names, returns "James Linden (james.linden)"
// When display names are disabled returns just "James Linden"
std::string getNameAndSLID() const;
std::string getCompleteName() const;
// Returns "James Linden" or "bobsmith123 Resident" for backwards
// compatibility with systems like voice and muting

View File

@ -81,6 +81,7 @@ public:
mFromName(),
mFromID(),
mNotifId(),
mOwnerID(),
mSourceType(CHAT_SOURCE_AGENT),
mChatType(CHAT_TYPE_NORMAL),
mAudible(CHAT_AUDIBLE_FULLY),
@ -97,6 +98,7 @@ public:
std::string mFromName; // agent or object name
LLUUID mFromID; // agent id or object id
LLUUID mNotifId;
LLUUID mOwnerID;
EChatSourceType mSourceType;
EChatType mChatType;
EChatAudible mAudible;

View File

@ -582,6 +582,12 @@ boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, co
return res;
}
boost::signals2::connection LLCacheName::getGroup(const LLUUID& group_id,
const LLCacheNameCallback& callback)
{
return get(group_id, true, callback);
}
boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, old_callback_t callback, void* user_data)
{
return get(id, is_group, boost::bind(callback, _1, _2, _3, user_data));

View File

@ -102,7 +102,12 @@ public:
// otherwise, will request the data, and will call the callback when
// available. There is no garuntee the callback will ever be called.
boost::signals2::connection get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback);
// Convenience method for looking up a group name, so you can
// tell the difference between avatar lookup and group lookup
// in global searches
boost::signals2::connection getGroup(const LLUUID& group_id, const LLCacheNameCallback& callback);
// LEGACY
boost::signals2::connection get(const LLUUID& id, bool is_group, old_callback_t callback, void* user_data);
// This method needs to be called from time to time to send out

View File

@ -1285,7 +1285,7 @@ void LLFlatListViewEx::filterItems()
}
}
rearrangeItems();
sort();
notifyParentItemsRectChanged();
}

View File

@ -34,6 +34,8 @@
#include "llnotifications.h"
#include "llavatarnamecache.h"
#include "llcachename.h"
#include "llxmlnode.h"
#include "lluictrl.h"
#include "lluictrlfactory.h"
@ -1488,12 +1490,42 @@ std::ostream& operator<<(std::ostream& s, const LLNotification& notification)
return s;
}
void LLPostponedNotification::onCachedNameReceived(const LLUUID& id,
const std::string& full_name,
bool is_group)
//static
void LLPostponedNotification::lookupName(LLPostponedNotification* thiz,
const LLUUID& id,
bool is_group)
{
// *TODO: This is dumb, just use full_name as given
gCacheName->getFullName(id, mName);
if (is_group)
{
gCacheName->getGroup(id,
boost::bind(&LLPostponedNotification::onGroupNameCache,
thiz, _1, _2, _3));
}
else
{
LLAvatarNameCache::get(id,
boost::bind(&LLPostponedNotification::onAvatarNameCache,
thiz, _1, _2));
}
}
void LLPostponedNotification::onGroupNameCache(const LLUUID& id,
const std::string& full_name,
bool is_group)
{
finalizeName(full_name);
}
void LLPostponedNotification::onAvatarNameCache(const LLUUID& agent_id,
const LLAvatarName& av_name)
{
std::string name = av_name.getCompleteName();
finalizeName(name);
}
void LLPostponedNotification::finalizeName(const std::string& name)
{
mName = name;
modifyNotificationParams();
LLNotifications::instance().add(mParams);
cleanup();

View File

@ -104,8 +104,8 @@
#include "llinitparam.h"
#include "llnotificationslistener.h"
#include "llnotificationptr.h"
#include "llcachename.h"
class LLAvatarName;
typedef enum e_notification_priority
{
@ -1000,16 +1000,20 @@ public:
{
// upcast T to the base type to restrict T derivation from LLPostponedNotification
LLPostponedNotification* thiz = new T();
thiz->mParams = params;
gCacheName->get(id, is_group, boost::bind(
&LLPostponedNotification::onCachedNameReceived, thiz, _1, _2,
_3));
// Avoid header file dependency on llcachename.h
lookupName(thiz, id, is_group);
}
private:
void onCachedNameReceived(const LLUUID& id, const std::string& full_name, bool is_group);
static void lookupName(LLPostponedNotification* thiz, const LLUUID& id, bool is_group);
// only used for groups
void onGroupNameCache(const LLUUID& id, const std::string& full_name, bool is_group);
// only used for avatars
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
// used for both group and avatar names
void finalizeName(const std::string& name);
void cleanup()
{

View File

@ -182,6 +182,11 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
break;
}
notifyParent(LLSD().with("action", "resize")
.with("view_name", mResizingView->getName())
.with("new_height", new_height)
.with("new_width", new_width));
scaled_rect.mTop = scaled_rect.mBottom + new_height;
scaled_rect.mRight = scaled_rect.mLeft + new_width;
mResizingView->setRect(scaled_rect);

View File

@ -1582,11 +1582,8 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
start = match.getStart();
end = match.getEnd()+1;
LLStyle::Params link_params = style_params;
link_params.color = match.getColor();
link_params.readonly_color = match.getColor();
link_params.font.style("UNDERLINE");
link_params.link_href = match.getUrl();
LLStyle::Params link_params(style_params);
link_params.overwriteFrom(match.getStyle());
// output the text before the Url
if (start > 0)
@ -1624,26 +1621,20 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
}
}
// output the styled Url (unless we've been asked to suppress hyperlinking)
if (match.isLinkDisabled())
{
appendAndHighlightText(match.getLabel(), prepend_newline, part, style_params);
}
else
{
appendAndHighlightText(match.getLabel(), prepend_newline, part, link_params);
// output the styled Url
appendAndHighlightText(match.getLabel(), prepend_newline, part, link_params);
// set the tooltip for the Url label
if (! match.getTooltip().empty())
{
segment_set_t::iterator it = getSegIterContaining(getLength()-1);
if (it != mSegments.end())
{
LLTextSegmentPtr segment = *it;
segment->setToolTip(match.getTooltip());
}
}
// set the tooltip for the Url label
if (! match.getTooltip().empty())
{
segment_set_t::iterator it = getSegIterContaining(getLength()-1);
if (it != mSegments.end())
{
LLTextSegmentPtr segment = *it;
segment->setToolTip(match.getTooltip());
}
}
prepend_newline = false;
// move on to the rest of the text after the Url

View File

@ -48,11 +48,8 @@
std::string localize_slapp_label(const std::string& url, const std::string& full_name);
LLUrlEntryBase::LLUrlEntryBase() :
mColor(LLUIColorTable::instance().getColor("HTMLLinkColor")),
mDisabledLink(false)
{
}
LLUrlEntryBase::LLUrlEntryBase()
{}
LLUrlEntryBase::~LLUrlEntryBase()
{
@ -69,6 +66,16 @@ std::string LLUrlEntryBase::getIcon(const std::string &url)
return mIcon;
}
LLStyle::Params LLUrlEntryBase::getStyle() const
{
LLStyle::Params style_params;
style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor");
style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
style_params.font.style = "UNDERLINE";
return style_params;
}
std::string LLUrlEntryBase::getIDStringFromUrl(const std::string &url) const
{
// return the id from a SLURL in the format /app/{cmd}/{id}/about
@ -327,7 +334,6 @@ LLUrlEntryAgent::LLUrlEntryAgent()
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_agent.xml";
mIcon = "Generic_Person";
mColor = LLUIColorTable::instance().getColor("AgentLinkColor");
}
// virtual
@ -352,11 +358,8 @@ void LLUrlEntryAgent::callObservers(const std::string &id,
void LLUrlEntryAgent::onAvatarNameCache(const LLUUID& id,
const LLAvatarName& av_name)
{
std::string label = av_name.mDisplayName;
if (!av_name.mUsername.empty())
{
label += " (" + av_name.mUsername + ")";
}
std::string label = av_name.getCompleteName();
// received the agent name from the server - tell our observers
callObservers(id.asString(), label, mIcon);
}
@ -421,11 +424,8 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
LLAvatarName av_name;
if (LLAvatarNameCache::get(agent_id, &av_name))
{
std::string label = av_name.mDisplayName;
if (!av_name.mUsername.empty())
{
label += " (" + av_name.mUsername + ")";
}
std::string label = av_name.getCompleteName();
// handle suffixes like /mute or /offerteleport
label = localize_slapp_label(url, label);
return label;
@ -440,6 +440,14 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
}
}
LLStyle::Params LLUrlEntryAgent::getStyle() const
{
LLStyle::Params style_params = LLUrlEntryBase::getStyle();
style_params.color = LLUIColorTable::instance().getColor("AgentLinkColor");
style_params.readonly_color = LLUIColorTable::instance().getColor("AgentLinkColor");
return style_params;
}
std::string localize_slapp_label(const std::string& url, const std::string& full_name)
{
// customize label string based on agent SLapp suffix
@ -478,6 +486,135 @@ std::string LLUrlEntryAgent::getIcon(const std::string &url)
return mIcon;
}
//
// LLUrlEntryAgentName describes a Second Life agent name Url, e.g.,
// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
//
LLUrlEntryAgentName::LLUrlEntryAgentName()
{
}
// virtual
void LLUrlEntryAgentName::callObservers(const std::string &id,
const std::string &label,
const std::string &icon)
{
// notify all callbacks waiting on the given uuid
std::multimap<std::string, LLUrlEntryObserver>::iterator it;
for (it = mObservers.find(id); it != mObservers.end();)
{
// call the callback - give it the new label
LLUrlEntryObserver &observer = it->second;
(*observer.signal)(observer.url, label, icon);
// then remove the signal - we only need to call it once
delete observer.signal;
mObservers.erase(it++);
}
}
void LLUrlEntryAgentName::onAvatarNameCache(const LLUUID& id,
const LLAvatarName& av_name)
{
std::string label = getName(av_name);
// received the agent name from the server - tell our observers
callObservers(id.asString(), label, mIcon);
}
std::string LLUrlEntryAgentName::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
{
if (!gCacheName)
{
// probably at the login screen, use short string for layout
return LLTrans::getString("LoadingData");
}
std::string agent_id_string = getIDStringFromUrl(url);
if (agent_id_string.empty())
{
// something went wrong, just give raw url
return unescapeUrl(url);
}
LLUUID agent_id(agent_id_string);
if (agent_id.isNull())
{
return LLTrans::getString("AvatarNameNobody");
}
LLAvatarName av_name;
if (LLAvatarNameCache::get(agent_id, &av_name))
{
return getName(av_name);
}
else
{
LLAvatarNameCache::get(agent_id,
boost::bind(&LLUrlEntryAgentCompleteName::onAvatarNameCache,
this, _1, _2));
addObserver(agent_id_string, url, cb);
return LLTrans::getString("LoadingData");
}
}
std::string LLUrlEntryAgentName::getUrl(const std::string &url) const
{
return LLStringUtil::null;
}
LLStyle::Params LLUrlEntryAgentName::getStyle() const
{
return LLStyle::Params();
}
//
// LLUrlEntryAgentCompleteName describes a Second Life agent complete name Url, e.g.,
// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename
// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename
//
LLUrlEntryAgentCompleteName::LLUrlEntryAgentCompleteName()
{
mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/completename",
boost::regex::perl|boost::regex::icase);
}
std::string LLUrlEntryAgentCompleteName::getName(const LLAvatarName& avatar_name)
{
return avatar_name.getCompleteName();
}
//
// LLUrlEntryAgentDisplayName describes a Second Life agent display name Url, e.g.,
// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/displayname
// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/displayname
//
LLUrlEntryAgentDisplayName::LLUrlEntryAgentDisplayName()
{
mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/displayname",
boost::regex::perl|boost::regex::icase);
}
std::string LLUrlEntryAgentDisplayName::getName(const LLAvatarName& avatar_name)
{
return avatar_name.mDisplayName;
}
//
// LLUrlEntryAgentUserName describes a Second Life agent user name Url, e.g.,
// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/username
// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/username
//
LLUrlEntryAgentUserName::LLUrlEntryAgentUserName()
{
mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/username",
boost::regex::perl|boost::regex::icase);
}
std::string LLUrlEntryAgentUserName::getName(const LLAvatarName& avatar_name)
{
return avatar_name.mUsername.empty() ? avatar_name.getLegacyName() : avatar_name.mUsername;
}
//
// LLUrlEntryGroup Describes a Second Life group Url, e.g.,
// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about
@ -491,7 +628,6 @@ LLUrlEntryGroup::LLUrlEntryGroup()
mMenuName = "menu_url_group.xml";
mIcon = "Generic_Group";
mTooltip = LLTrans::getString("TooltipGroupUrl");
mColor = LLUIColorTable::instance().getColor("GroupLinkColor");
}
void LLUrlEntryGroup::onGroupNameReceived(const LLUUID& id,
@ -529,7 +665,7 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa
}
else
{
gCacheName->get(group_id, true,
gCacheName->getGroup(group_id,
boost::bind(&LLUrlEntryGroup::onGroupNameReceived,
this, _1, _2, _3));
addObserver(group_id_string, url, cb);
@ -537,6 +673,15 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa
}
}
LLStyle::Params LLUrlEntryGroup::getStyle() const
{
LLStyle::Params style_params = LLUrlEntryBase::getStyle();
style_params.color = LLUIColorTable::instance().getColor("GroupLinkColor");
style_params.readonly_color = LLUIColorTable::instance().getColor("GroupLinkColor");
return style_params;
}
//
// LLUrlEntryInventory Describes a Second Life inventory Url, e.g.,
// secondlife:///app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select
@ -824,7 +969,6 @@ LLUrlEntryNoLink::LLUrlEntryNoLink()
{
mPattern = boost::regex("<nolink>[^<]*</nolink>",
boost::regex::perl|boost::regex::icase);
mDisabledLink = true;
}
std::string LLUrlEntryNoLink::getUrl(const std::string &url) const
@ -838,6 +982,12 @@ std::string LLUrlEntryNoLink::getLabel(const std::string &url, const LLUrlLabelC
return getUrl(url);
}
LLStyle::Params LLUrlEntryNoLink::getStyle() const
{
return LLStyle::Params();
}
//
// LLUrlEntryIcon describes an icon with <icon>...</icon> tags
//
@ -845,7 +995,6 @@ LLUrlEntryIcon::LLUrlEntryIcon()
{
mPattern = boost::regex("<icon\\s*>\\s*([^<]*)?\\s*</icon\\s*>",
boost::regex::perl|boost::regex::icase);
mDisabledLink = true;
}
std::string LLUrlEntryIcon::getUrl(const std::string &url) const

View File

@ -36,6 +36,7 @@
#include "lluuid.h"
#include "lluicolor.h"
#include "llstyle.h"
#include <boost/signals2.hpp>
#include <boost/regex.hpp>
#include <string>
@ -82,8 +83,8 @@ public:
/// Return an icon that can be displayed next to Urls of this type
virtual std::string getIcon(const std::string &url);
/// Return the color to render the displayed text
LLUIColor getColor() const { return mColor; }
/// Return the style to render the displayed text
virtual LLStyle::Params getStyle() const;
/// Given a matched Url, return a tooltip string for the hyperlink
virtual std::string getTooltip(const std::string &string) const { return mTooltip; }
@ -94,9 +95,6 @@ public:
/// Return the name of a SL location described by this Url, if any
virtual std::string getLocation(const std::string &url) const { return ""; }
/// is this a match for a URL that should not be hyperlinked?
bool isLinkDisabled() const { return mDisabledLink; }
protected:
std::string getIDStringFromUrl(const std::string &url) const;
std::string escapeUrl(const std::string &url) const;
@ -115,9 +113,7 @@ protected:
std::string mIcon;
std::string mMenuName;
std::string mTooltip;
LLUIColor mColor;
std::multimap<std::string, LLUrlEntryObserver> mObservers;
bool mDisabledLink;
};
///
@ -173,12 +169,73 @@ public:
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ std::string getIcon(const std::string &url);
/*virtual*/ std::string getTooltip(const std::string &string) const;
/*virtual*/ LLStyle::Params getStyle() const;
protected:
/*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon);
private:
void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
};
///
/// LLUrlEntryAgentName Describes a Second Life agent name Url, e.g.,
/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
/// that displays various forms of user name
/// This is a base class for the various implementations of name display
class LLUrlEntryAgentName : public LLUrlEntryBase
{
public:
LLUrlEntryAgentName();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ std::string getUrl(const std::string &string) const;
/*virtual*/ LLStyle::Params getStyle() const;
protected:
/*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon);
// override this to pull out relevant name fields
virtual std::string getName(const LLAvatarName& avatar_name) = 0;
private:
void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
};
///
/// LLUrlEntryAgentCompleteName Describes a Second Life agent name Url, e.g.,
/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename
/// that displays the full display name + user name for an avatar
/// such as "James Linden (james.linden)"
class LLUrlEntryAgentCompleteName : public LLUrlEntryAgentName
{
public:
LLUrlEntryAgentCompleteName();
private:
/*virtual*/ std::string getName(const LLAvatarName& avatar_name);
};
///
/// LLUrlEntryAgentDisplayName Describes a Second Life agent display name Url, e.g.,
/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/displayname
/// that displays the just the display name for an avatar
/// such as "James Linden"
class LLUrlEntryAgentDisplayName : public LLUrlEntryAgentName
{
public:
LLUrlEntryAgentDisplayName();
private:
/*virtual*/ std::string getName(const LLAvatarName& avatar_name);
};
///
/// LLUrlEntryAgentUserName Describes a Second Life agent username Url, e.g.,
/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/username
/// that displays the just the display name for an avatar
/// such as "james.linden"
class LLUrlEntryAgentUserName : public LLUrlEntryAgentName
{
public:
LLUrlEntryAgentUserName();
private:
/*virtual*/ std::string getName(const LLAvatarName& avatar_name);
};
///
/// LLUrlEntryGroup Describes a Second Life group Url, e.g.,
/// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about
@ -188,6 +245,7 @@ class LLUrlEntryGroup : public LLUrlEntryBase
public:
LLUrlEntryGroup();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ LLStyle::Params getStyle() const;
private:
void onGroupNameReceived(const LLUUID& id, const std::string& name, bool is_group);
};
@ -297,6 +355,7 @@ public:
LLUrlEntryNoLink();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ std::string getUrl(const std::string &string) const;
/*virtual*/ LLStyle::Params getStyle() const;
};
///

View File

@ -42,16 +42,14 @@ LLUrlMatch::LLUrlMatch() :
mTooltip(""),
mIcon(""),
mMenuName(""),
mLocation(""),
mDisabledLink(false)
mLocation("")
{
}
void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url,
const std::string &label, const std::string &tooltip,
const std::string &icon, const LLUIColor& color,
const std::string &menu, const std::string &location,
bool disabled_link)
const std::string &icon, const LLStyle::Params& style,
const std::string &menu, const std::string &location)
{
mStart = start;
mEnd = end;
@ -59,8 +57,8 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url,
mLabel = label;
mTooltip = tooltip;
mIcon = icon;
mColor = color;
mStyle = style;
mStyle.link_href = url;
mMenuName = menu;
mLocation = location;
mDisabledLink = disabled_link;
}

View File

@ -38,7 +38,7 @@
#include <string>
#include <vector>
#include "lluicolor.h"
#include "llstyle.h"
///
/// LLUrlMatch describes a single Url that was matched within a string by
@ -75,7 +75,7 @@ public:
std::string getIcon() const { return mIcon; }
/// Return the color to render the displayed text
LLUIColor getColor() const { return mColor; }
LLStyle::Params getStyle() const { return mStyle; }
/// Return the name of a XUI file containing the context menu items
std::string getMenuName() const { return mMenuName; }
@ -83,14 +83,11 @@ public:
/// return the SL location that this Url describes, or "" if none.
std::string getLocation() const { return mLocation; }
/// is this a match for a URL that should not be hyperlinked?
bool isLinkDisabled() const { return mDisabledLink; }
/// Change the contents of this match object (used by LLUrlRegistry)
void setValues(U32 start, U32 end, const std::string &url, const std::string &label,
const std::string &tooltip, const std::string &icon,
const LLUIColor& color, const std::string &menu,
const std::string &location, bool disabled_link);
const LLStyle::Params& style, const std::string &menu,
const std::string &location);
private:
U32 mStart;
@ -101,8 +98,7 @@ private:
std::string mIcon;
std::string mMenuName;
std::string mLocation;
LLUIColor mColor;
bool mDisabledLink;
LLStyle::Params mStyle;
};
#endif

View File

@ -51,6 +51,11 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(new LLUrlEntrySLURL());
registerUrl(new LLUrlEntryHTTP());
registerUrl(new LLUrlEntryHTTPLabel());
registerUrl(new LLUrlEntryAgentCompleteName());
registerUrl(new LLUrlEntryAgentDisplayName());
registerUrl(new LLUrlEntryAgentUserName());
// LLUrlEntryAgent*Name must appear before LLUrlEntryAgent since
// LLUrlEntryAgent is a less specific (catchall for agent urls)
registerUrl(new LLUrlEntryAgent());
registerUrl(new LLUrlEntryGroup());
registerUrl(new LLUrlEntryParcel());
@ -185,10 +190,9 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
match_entry->getLabel(url, cb),
match_entry->getTooltip(url),
match_entry->getIcon(url),
match_entry->getColor(),
match_entry->getStyle(),
match_entry->getMenuName(),
match_entry->getLocation(url),
match_entry->isLinkDisabled());
match_entry->getLocation(url));
return true;
}
@ -219,10 +223,9 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr
match.getLabel(),
match.getTooltip(),
match.getIcon(),
match.getColor(),
match.getStyle(),
match.getMenuName(),
match.getLocation(),
match.isLinkDisabled());
match.getLocation());
return true;
}
return false;

View File

@ -64,6 +64,11 @@ boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, co
return boost::signals2::connection();
}
boost::signals2::connection LLCacheName::getGroup(const LLUUID& id, const LLCacheNameCallback& callback)
{
return boost::signals2::connection();
}
LLCacheName* gCacheName = NULL;
//
@ -79,3 +84,106 @@ std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::
{
return std::string();
}
//
// Stub implementation for LLStyle::Params::Params
//
LLStyle::Params::Params()
{
}
//
// Stub implementations for various LLInitParam classes
//
namespace LLInitParam
{
BaseBlock::BaseBlock() {}
BaseBlock::~BaseBlock() {}
Param::Param(BaseBlock* enclosing_block)
: mIsProvided(false)
{
const U8* my_addr = reinterpret_cast<const U8*>(this);
const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
mEnclosingBlockOffset = (U16)(my_addr - block_addr);
}
void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided) {}
void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name){}
param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}
void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
{
mBlockDescriptor = &descriptor;
descriptor.mCurrentBlockPtr = this;
}
bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack){ return true; }
bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const { return true; }
bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const { return true; }
bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
bool BaseBlock::validateBlock(bool emit_errors) const { return true; }
TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
: super_t(descriptor, name, value, func, min_count, max_count)
{}
void TypedParam<LLUIColor>::setValueFromBlock() const
{}
void TypedParam<LLUIColor>::setBlockFromValue()
{}
void TypeValues<LLUIColor>::declareValues()
{}
bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
{
return false;
}
TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
: super_t(descriptor, _name, value, func, min_count, max_count)
{}
void TypedParam<const LLFontGL*>::setValueFromBlock() const
{}
void TypedParam<const LLFontGL*>::setBlockFromValue()
{}
void TypeValues<LLFontGL::HAlign>::declareValues()
{}
void TypeValues<LLFontGL::VAlign>::declareValues()
{}
void TypeValues<LLFontGL::ShadowType>::declareValues()
{}
void TypedParam<LLUIImage*>::setValueFromBlock() const
{}
void TypedParam<LLUIImage*>::setBlockFromValue()
{}
bool ParamCompare<LLUIImage*, false>::equals(
LLUIImage* const &a,
LLUIImage* const &b)
{
return false;
}
bool ParamCompare<LLUIColor, false>::equals(const LLUIColor &a, const LLUIColor &b)
{
return false;
}
}
//static
LLFontGL* LLFontGL::getFontDefault()
{
return NULL;
}

View File

@ -23,11 +23,111 @@
#include "../llurlmatch.h"
#include "lltut.h"
// link seam
// link seams
LLUIColor::LLUIColor()
: mColorPtr(NULL)
{}
LLStyle::Params::Params()
{
}
namespace LLInitParam
{
BaseBlock::BaseBlock() {}
BaseBlock::~BaseBlock() {}
void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided) {}
void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name){}
param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}
void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
{
mBlockDescriptor = &descriptor;
descriptor.mCurrentBlockPtr = this;
}
Param::Param(BaseBlock* enclosing_block)
: mIsProvided(false)
{
const U8* my_addr = reinterpret_cast<const U8*>(this);
const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
mEnclosingBlockOffset = (U16)(my_addr - block_addr);
}
bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack){ return true; }
bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const { return true; }
bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const { return true; }
bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
bool BaseBlock::validateBlock(bool emit_errors) const { return true; }
TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
: super_t(descriptor, name, value, func, min_count, max_count)
{}
void TypedParam<LLUIColor>::setValueFromBlock() const
{}
void TypedParam<LLUIColor>::setBlockFromValue()
{}
void TypeValues<LLUIColor>::declareValues()
{}
bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
{
return false;
}
TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
: super_t(descriptor, _name, value, func, min_count, max_count)
{}
void TypedParam<const LLFontGL*>::setValueFromBlock() const
{}
void TypedParam<const LLFontGL*>::setBlockFromValue()
{}
void TypeValues<LLFontGL::HAlign>::declareValues()
{}
void TypeValues<LLFontGL::VAlign>::declareValues()
{}
void TypeValues<LLFontGL::ShadowType>::declareValues()
{}
void TypedParam<LLUIImage*>::setValueFromBlock() const
{}
void TypedParam<LLUIImage*>::setBlockFromValue()
{}
bool ParamCompare<LLUIImage*, false>::equals(
LLUIImage* const &a,
LLUIImage* const &b)
{
return false;
}
bool ParamCompare<LLUIColor, false>::equals(const LLUIColor &a, const LLUIColor &b)
{
return false;
}
}
//static
LLFontGL* LLFontGL::getFontDefault()
{
return NULL;
}
namespace tut
{
struct LLUrlMatchData
@ -54,7 +154,7 @@ namespace tut
LLUrlMatch match;
ensure("empty()", match.empty());
match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", LLUIColor(), "", "", false);
match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", LLStyle::Params(), "", "");
ensure("! empty()", ! match.empty());
}
@ -67,7 +167,7 @@ namespace tut
LLUrlMatch match;
ensure_equals("getStart() == 0", match.getStart(), 0);
match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false);
match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "");
ensure_equals("getStart() == 10", match.getStart(), 10);
}
@ -80,7 +180,7 @@ namespace tut
LLUrlMatch match;
ensure_equals("getEnd() == 0", match.getEnd(), 0);
match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false);
match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "");
ensure_equals("getEnd() == 20", match.getEnd(), 20);
}
@ -93,10 +193,10 @@ namespace tut
LLUrlMatch match;
ensure_equals("getUrl() == ''", match.getUrl(), "");
match.setValues(10, 20, "http://slurl.com/", "", "", "", LLUIColor(), "", "", false);
match.setValues(10, 20, "http://slurl.com/", "", "", "", LLStyle::Params(), "", "");
ensure_equals("getUrl() == 'http://slurl.com/'", match.getUrl(), "http://slurl.com/");
match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false);
match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "");
ensure_equals("getUrl() == '' (2)", match.getUrl(), "");
}
@ -109,10 +209,10 @@ namespace tut
LLUrlMatch match;
ensure_equals("getLabel() == ''", match.getLabel(), "");
match.setValues(10, 20, "", "Label", "", "", LLUIColor(), "", "", false);
match.setValues(10, 20, "", "Label", "", "", LLStyle::Params(), "", "");
ensure_equals("getLabel() == 'Label'", match.getLabel(), "Label");
match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false);
match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "");
ensure_equals("getLabel() == '' (2)", match.getLabel(), "");
}
@ -125,10 +225,10 @@ namespace tut
LLUrlMatch match;
ensure_equals("getTooltip() == ''", match.getTooltip(), "");
match.setValues(10, 20, "", "", "Info", "", LLUIColor(), "", "", false);
match.setValues(10, 20, "", "", "Info", "", LLStyle::Params(), "", "");
ensure_equals("getTooltip() == 'Info'", match.getTooltip(), "Info");
match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false);
match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "");
ensure_equals("getTooltip() == '' (2)", match.getTooltip(), "");
}
@ -141,10 +241,10 @@ namespace tut
LLUrlMatch match;
ensure_equals("getIcon() == ''", match.getIcon(), "");
match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "", "", false);
match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "", "");
ensure_equals("getIcon() == 'Icon'", match.getIcon(), "Icon");
match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false);
match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "");
ensure_equals("getIcon() == '' (2)", match.getIcon(), "");
}
@ -157,10 +257,10 @@ namespace tut
LLUrlMatch match;
ensure("getMenuName() empty", match.getMenuName().empty());
match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "", false);
match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "xui_file.xml", "");
ensure_equals("getMenuName() == \"xui_file.xml\"", match.getMenuName(), "xui_file.xml");
match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false);
match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "");
ensure("getMenuName() empty (2)", match.getMenuName().empty());
}
@ -173,10 +273,10 @@ namespace tut
LLUrlMatch match;
ensure("getLocation() empty", match.getLocation().empty());
match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "Paris", false);
match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "xui_file.xml", "Paris");
ensure_equals("getLocation() == \"Paris\"", match.getLocation(), "Paris");
match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false);
match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "");
ensure("getLocation() empty (2)", match.getLocation().empty());
}
}

View File

@ -139,7 +139,7 @@ namespace LLInitParam
bool BaseBlock::validateBlock(bool emit_errors) const
{
const BlockDescriptor& block_data = getBlockDescriptor();
const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
for (BlockDescriptor::param_validation_list_t::const_iterator it = block_data.mValidationList.begin(); it != block_data.mValidationList.end(); ++it)
{
const Param* param = getParamFromHandle(it->first);
@ -159,7 +159,7 @@ namespace LLInitParam
{
// named param is one like LLView::Params::follows
// unnamed param is like LLView::Params::rect - implicit
const BlockDescriptor& block_data = getBlockDescriptor();
const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin();
it != block_data.mUnnamedParams.end();
@ -230,7 +230,7 @@ namespace LLInitParam
{
// named param is one like LLView::Params::follows
// unnamed param is like LLView::Params::rect - implicit
const BlockDescriptor& block_data = getBlockDescriptor();
const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin();
it != block_data.mUnnamedParams.end();
@ -301,7 +301,7 @@ namespace LLInitParam
bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack)
{
BlockDescriptor& block_data = getBlockDescriptor();
BlockDescriptor& block_data = mostDerivedBlockDescriptor();
bool names_left = name_stack.first != name_stack.second;
if (names_left)
@ -386,7 +386,7 @@ namespace LLInitParam
void BaseBlock::addSynonym(Param& param, const std::string& synonym)
{
BlockDescriptor& block_data = getBlockDescriptor();
BlockDescriptor& block_data = mostDerivedBlockDescriptor();
if (block_data.mInitializationState == BlockDescriptor::INITIALIZING)
{
param_handle_t handle = getHandleFromParam(&param);
@ -417,8 +417,8 @@ namespace LLInitParam
{
if (user_provided)
{
mChangeVersion++;
}
mChangeVersion++;
}
}
const std::string& BaseBlock::getParamName(const BlockDescriptor& block_data, const Param* paramp) const
@ -445,7 +445,7 @@ namespace LLInitParam
ParamDescriptor* BaseBlock::findParamDescriptor(param_handle_t handle)
{
BlockDescriptor& descriptor = getBlockDescriptor();
BlockDescriptor& descriptor = mostDerivedBlockDescriptor();
BlockDescriptor::all_params_list_t::iterator end_it = descriptor.mAllParams.end();
for (BlockDescriptor::all_params_list_t::iterator it = descriptor.mAllParams.begin();
it != end_it;
@ -460,7 +460,7 @@ namespace LLInitParam
// NOTE: this requires that "other" is of the same derived type as this
bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
{
bool param_changed = false;
bool some_param_changed = false;
BlockDescriptor::all_params_list_t::const_iterator end_it = block_data.mAllParams.end();
for (BlockDescriptor::all_params_list_t::const_iterator it = block_data.mAllParams.begin();
it != end_it;
@ -471,10 +471,10 @@ namespace LLInitParam
if (merge_func)
{
Param* paramp = getParamFromHandle(it->mParamHandle);
param_changed |= merge_func(*paramp, *other_paramp, overwrite);
some_param_changed |= merge_func(*paramp, *other_paramp, overwrite);
}
}
return param_changed;
return some_param_changed;
}
bool ParamCompare<LLSD, false>::equals(const LLSD &a, const LLSD &b)

View File

@ -477,10 +477,10 @@ namespace LLInitParam
bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack);
bool serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const;
virtual bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t()) const;
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t()) const;
const BlockDescriptor& getBlockDescriptor() const { return *mBlockDescriptor; }
BlockDescriptor& getBlockDescriptor() { return *mBlockDescriptor; }
const BlockDescriptor& mostDerivedBlockDescriptor() const { return *mBlockDescriptor; }
BlockDescriptor& mostDerivedBlockDescriptor() { return *mBlockDescriptor; }
// take all provided params from other and apply to self
bool overwriteFrom(const BaseBlock& other)
@ -507,7 +507,7 @@ namespace LLInitParam
BlockDescriptor* mBlockDescriptor; // most derived block descriptor
static BlockDescriptor& blockDescriptor()
static BlockDescriptor& selfBlockDescriptor()
{
static BlockDescriptor sBlockDescriptor;
return sBlockDescriptor;
@ -559,7 +559,7 @@ namespace LLInitParam
TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
: Param(block_descriptor.mCurrentBlockPtr)
{
if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
&mergeWith,
@ -584,6 +584,7 @@ namespace LLInitParam
{
if (parser.readValue<T>(typed_param.mData.mValue))
{
typed_param.mData.clearKey();
typed_param.setProvided(true);
typed_param.enclosingBlock().setLastChangedParam(param, true);
return true;
@ -690,7 +691,7 @@ namespace LLInitParam
&& (overwrite || !dst_typed_param.isProvided()))
{
dst_typed_param.mData.clearKey();
dst_typed_param = src_typed_param;
dst_typed_param.set(src_typed_param.get());
return true;
}
return false;
@ -722,7 +723,7 @@ namespace LLInitParam
: Param(block_descriptor.mCurrentBlockPtr),
T(value)
{
if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
&mergeWith,
@ -741,6 +742,7 @@ namespace LLInitParam
// attempt to parse block...
if(typed_param.deserializeBlock(parser, name_stack))
{
typed_param.mData.clearKey();
typed_param.enclosingBlock().setLastChangedParam(param, true);
return true;
}
@ -856,21 +858,10 @@ namespace LLInitParam
{
const self_t& src_typed_param = static_cast<const self_t&>(src);
self_t& dst_typed_param = static_cast<self_t&>(dst);
if (overwrite)
if (dst_typed_param.T::merge(selfBlockDescriptor(), src_typed_param, overwrite || !dst_typed_param.isProvided()))
{
if (dst_typed_param.T::overwriteFrom(src_typed_param))
{
dst_typed_param.mData.clearKey();
return true;
}
}
else
{
if (dst_typed_param.T::fillFrom(src_typed_param))
{
dst_typed_param.mData.clearKey();
return true;
}
dst_typed_param.mData.clearKey();
return true;
}
return false;
}
@ -911,7 +902,7 @@ namespace LLInitParam
mValues(value)
{
mCachedKeys.resize(mValues.size());
if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
&mergeWith,
@ -1060,9 +1051,9 @@ namespace LLInitParam
self_t& dst_typed_param = static_cast<self_t&>(dst);
if (src_typed_param.isProvided()
&& (overwrite || !isProvided()))
&& (overwrite || !dst_typed_param.isProvided()))
{
dst_typed_param = src_typed_param;
dst_typed_param.set(src_typed_param.get());
return true;
}
return false;
@ -1094,7 +1085,7 @@ namespace LLInitParam
mLastParamGeneration(0)
{
mCachedKeys.resize(mValues.size());
if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
&mergeWith,
@ -1252,7 +1243,7 @@ namespace LLInitParam
if (src_typed_param.isProvided()
&& (overwrite || !dst_typed_param.isProvided()))
{
dst_typed_param = src_typed_param;
dst_typed_param.set(src_typed_param.get());
return true;
}
return false;
@ -1282,13 +1273,24 @@ namespace LLInitParam
// take all provided params from other and apply to self
bool overwriteFrom(const self_t& other)
{
mCurChoice = other.mCurChoice;
return BaseBlock::merge(blockDescriptor(), other, true);
return merge(selfBlockDescriptor(), other, true);
}
// take all provided params that are not already provided, and apply to self
bool fillFrom(const self_t& other)
{
return merge(selfBlockDescriptor(), other, false);
}
// merge with other block
bool merge(BlockDescriptor& block_data, const self_t& other, bool overwrite)
{
// only merge a choice if we are overwriting with other's contents
if (overwrite)
{
mCurChoice = other.mCurChoice;
return BaseBlock::merge(selfBlockDescriptor(), other, overwrite);
}
return false;
}
@ -1314,7 +1316,7 @@ namespace LLInitParam
Choice()
: mCurChoice(0)
{
BaseBlock::init(blockDescriptor(), BaseBlock::blockDescriptor(), sizeof(DERIVED_BLOCK));
BaseBlock::init(selfBlockDescriptor(), BaseBlock::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
}
// Alternatives are mutually exclusive wrt other Alternatives in the same block.
@ -1331,13 +1333,14 @@ namespace LLInitParam
typedef typename super_t::value_assignment_t value_assignment_t;
explicit Alternative(const char* name, value_assignment_t val = DefaultInitializer<T>::get())
: super_t(DERIVED_BLOCK::blockDescriptor(), name, val, NULL, 0, 1),
: super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),
mOriginalValue(val)
{
// assign initial choice to first declared option
DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::blockDescriptor().mCurrentBlockPtr);
if (DERIVED_BLOCK::blockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING
&& blockp->mCurChoice == 0)
DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr);
if (LL_UNLIKELY(
DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING
&& blockp->mCurChoice == 0))
{
blockp->mCurChoice = Param::enclosingBlock().getHandleFromParam(this);
}
@ -1382,7 +1385,7 @@ namespace LLInitParam
};
protected:
static BlockDescriptor& blockDescriptor()
static BlockDescriptor& selfBlockDescriptor()
{
static BlockDescriptor sBlockDescriptor;
return sBlockDescriptor;
@ -1410,19 +1413,19 @@ namespace LLInitParam
// take all provided params from other and apply to self
bool overwriteFrom(const self_t& other)
{
return BaseBlock::merge(blockDescriptor(), other, true);
return BaseBlock::merge(selfBlockDescriptor(), other, true);
}
// take all provided params that are not already provided, and apply to self
bool fillFrom(const self_t& other)
{
return BaseBlock::merge(blockDescriptor(), other, false);
return BaseBlock::merge(selfBlockDescriptor(), other, false);
}
protected:
Block()
{
//#pragma message("Parsing LLInitParam::Block")
BaseBlock::init(blockDescriptor(), BASE_BLOCK::blockDescriptor(), sizeof(DERIVED_BLOCK));
BaseBlock::init(selfBlockDescriptor(), BASE_BLOCK::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
}
//
@ -1436,7 +1439,7 @@ namespace LLInitParam
typedef typename super_t::value_assignment_t value_assignment_t;
explicit Optional(const char* name = "", value_assignment_t val = DefaultInitializer<T>::get())
: super_t(DERIVED_BLOCK::blockDescriptor(), name, val, NULL, 0, 1)
: super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1)
{
//#pragma message("Parsing LLInitParam::Block::Optional")
}
@ -1465,7 +1468,7 @@ namespace LLInitParam
// mandatory parameters require a name to be parseable
explicit Mandatory(const char* name = "", value_assignment_t val = DefaultInitializer<T>::get())
: super_t(DERIVED_BLOCK::blockDescriptor(), name, val, &validate, 1, 1)
: super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, 1, 1)
{}
Mandatory& operator=(value_assignment_t val)
@ -1501,7 +1504,7 @@ namespace LLInitParam
typedef typename container_t::const_iterator const_iterator;
explicit Multiple(const char* name = "", value_assignment_t val = DefaultInitializer<container_t>::get())
: super_t(DERIVED_BLOCK::blockDescriptor(), name, val, &validate, RANGE::minCount(), RANGE::maxCount())
: super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, RANGE::minCount(), RANGE::maxCount())
{}
using super_t::operator();
@ -1529,10 +1532,10 @@ namespace LLInitParam
{
public:
explicit Deprecated(const char* name)
: Param(DERIVED_BLOCK::blockDescriptor().mCurrentBlockPtr)
: Param(DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr)
{
BlockDescriptor& block_descriptor = DERIVED_BLOCK::blockDescriptor();
if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
NULL,
@ -1561,7 +1564,7 @@ namespace LLInitParam
typedef Deprecated Ignored;
protected:
static BlockDescriptor& blockDescriptor()
static BlockDescriptor& selfBlockDescriptor()
{
static BlockDescriptor sBlockDescriptor;
return sBlockDescriptor;
@ -1574,6 +1577,13 @@ namespace LLInitParam
public Param
{
public:
typedef enum e_value_age
{
OLDER_THAN_BLOCK, // mData.mValue needs to be refreshed from the block parameters
NEWER_THAN_BLOCK, // mData.mValue holds the authoritative value (which has been replicated to the block parameters via setBlockFromValue)
SAME_AS_BLOCK // mData.mValue is derived from the block parameters, which are authoritative
} EValueAge;
typedef BlockValue<T> self_t;
typedef Block<TypedParam<T, TypeValues<T>, false> > block_t;
typedef const T& value_const_ref_t;
@ -1582,9 +1592,9 @@ namespace LLInitParam
BlockValue(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
: Param(block_descriptor.mCurrentBlockPtr),
mData(value)
mData(value, NEWER_THAN_BLOCK)
{
if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
&mergeWith,
@ -1604,7 +1614,7 @@ namespace LLInitParam
static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
{
self_t& typed_param = static_cast<self_t&>(param);
DERIVED& typed_param = static_cast<DERIVED&>(param);
// type to apply parse direct value T
if (name_stack.first == name_stack.second)
{
@ -1612,7 +1622,10 @@ namespace LLInitParam
{
typed_param.enclosingBlock().setLastChangedParam(param, true);
typed_param.setProvided(true);
typed_param.mData.mLastParamVersion = typed_param.BaseBlock::getLastChangeVersion();
typed_param.mData.clearKey();
typed_param.mData.mValueAge = NEWER_THAN_BLOCK;
typed_param.setBlockFromValue();
return true;
}
@ -1628,7 +1641,9 @@ namespace LLInitParam
typed_param.mData.setKey(name);
typed_param.enclosingBlock().setLastChangedParam(param, true);
typed_param.setProvided(true);
typed_param.mData.mLastParamVersion = typed_param.BaseBlock::getLastChangeVersion();
typed_param.mData.mValueAge = NEWER_THAN_BLOCK;
typed_param.setBlockFromValue();
return true;
}
}
@ -1703,16 +1718,18 @@ namespace LLInitParam
bool isProvided() const
{
// either param value provided directly or block is sufficiently filled in
if (!Param::getProvided()) return false;
// block has an updated parameter
// if cached value is stale, regenerate from params
if (Param::getProvided() && mData.mLastParamVersion < BaseBlock::getLastChangeVersion())
if (mData.mValueAge == OLDER_THAN_BLOCK)
{
if (block_t::validateBlock(false))
{
static_cast<const DERIVED*>(this)->setValueFromBlock();
// clear stale keyword associated with old value
mData.clearKey();
mData.mLastParamVersion = BaseBlock::getLastChangeVersion();
mData.mValueAge = SAME_AS_BLOCK;
return true;
}
else
@ -1722,8 +1739,11 @@ namespace LLInitParam
return false;
}
}
// either no data provided, or we have a valid value in hand
return Param::getProvided();
else
{
// we have a valid value in hand
return true;
}
}
void set(value_assignment_t val, bool flag_as_provided = true)
@ -1731,7 +1751,7 @@ namespace LLInitParam
Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
// set param version number to be up to date, so we ignore block contents
mData.mLastParamVersion = BaseBlock::getLastChangeVersion();
mData.mValueAge = NEWER_THAN_BLOCK;
mData.mValue = val;
mData.clearKey();
@ -1756,6 +1776,8 @@ namespace LLInitParam
if (user_provided)
{
setProvided(true); // some component provided
// a parameter changed, so our value is out of date
mData.mValueAge = OLDER_THAN_BLOCK;
}
}
@ -1763,54 +1785,54 @@ namespace LLInitParam
value_assignment_t get() const
{
// if some parameters were provided, issue warnings on invalid blocks
if (Param::getProvided() && (mData.mLastParamVersion < BaseBlock::getLastChangeVersion()))
if (Param::getProvided() && (mData.mValueAge == OLDER_THAN_BLOCK))
{
// go ahead and issue warnings at this point if any param is invalid
if(block_t::validateBlock(true))
{
static_cast<const DERIVED*>(this)->setValueFromBlock();
mData.clearKey();
mData.mLastParamVersion = BaseBlock::getLastChangeVersion();
mData.mValueAge = SAME_AS_BLOCK;
}
}
return mData.mValue;
}
// mutable to allow lazy updates on get
struct Data : public key_cache_t
{
Data(const T& value)
Data(const T& value, EValueAge age)
: mValue(value),
mLastParamVersion(0)
mValueAge(age)
{}
T mValue;
S32 mLastParamVersion;
T mValue;
EValueAge mValueAge;
};
// mutable to allow lazy updates on get
mutable Data mData;
private:
static bool mergeWith(Param& dst, const Param& src, bool overwrite)
{
const self_t& src_typed_param = static_cast<const self_t&>(src);
self_t& dst_typed_param = static_cast<self_t&>(dst);
const DERIVED& src_typed_param = static_cast<const DERIVED&>(src);
DERIVED& dst_typed_param = static_cast<DERIVED&>(dst);
if (src_typed_param.isProvided()
&& (overwrite || !dst_typed_param.isProvided()))
{
// assign individual parameters
dst_typed_param.BaseBlock::merge(block_t::blockDescriptor(), src_typed_param, overwrite);
// then copy actual value
dst_typed_param.mData.mValue = src_typed_param.get();
dst_typed_param.mData.clearKey();
dst_typed_param.setProvided(true);
// Propagate value back to block params since the value was updated during this merge.
// This will result in mData.mValue and the block params being in sync.
static_cast<DERIVED&>(dst_typed_param).setBlockFromValue();
if (src_typed_param.mData.mValueAge == NEWER_THAN_BLOCK)
{
// copy value over
dst_typed_param.set(src_typed_param.get());
}
else
{
// merge individual parameters into destination
dst_typed_param.merge(block_t::selfBlockDescriptor(), src_typed_param, overwrite);
}
return true;
}
return false;

View File

@ -297,11 +297,17 @@ private:
// append details to agent string
LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent );
// TODO: Remove this ifdef when the Linux version of llqtwebkit gets updated with the new WOB constant.
#if !LL_LINUX
// Set up window open behavior
LLQtWebKit::getInstance()->setWindowOpenBehavior(mBrowserWindowId, LLQtWebKit::WOB_SIMULATE_BLANK_HREF_CLICK);
#endif
#if !LL_QTWEBKIT_USES_PIXMAPS
// don't flip bitmap
LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true );
#endif // !LL_QTWEBKIT_USES_PIXMAPS
// set background color
// convert background color channels from [0.0, 1.0] to [0, 255];
LLQtWebKit::getInstance()->setBackgroundColor( mBrowserWindowId, int(mBackgroundR * 255.0f), int(mBackgroundG * 255.0f), int(mBackgroundB * 255.0f) );

View File

@ -91,6 +91,7 @@ set(viewer_SOURCE_FILES
llbottomtray.cpp
llbox.cpp
llbreadcrumbview.cpp
llbuycurrencyhtml.cpp
llcallbacklist.cpp
llcallfloater.cpp
llcallingcard.cpp
@ -159,6 +160,7 @@ set(viewer_SOURCE_FILES
llfloaterbuy.cpp
llfloaterbuycontents.cpp
llfloaterbuycurrency.cpp
llfloaterbuycurrencyhtml.cpp
llfloaterbuyland.cpp
llfloatercamera.cpp
llfloatercolorpicker.cpp
@ -224,6 +226,7 @@ set(viewer_SOURCE_FILES
llfollowcam.cpp
llfriendcard.cpp
llgesturemgr.cpp
llgiveinventory.cpp
llglsandbox.cpp
llgroupactions.cpp
llgroupiconctrl.cpp
@ -606,6 +609,7 @@ set(viewer_HEADER_FILES
llbottomtray.h
llbox.h
llbreadcrumbview.h
llbuycurrencyhtml.h
llcallbacklist.h
llcallfloater.h
llcallingcard.h
@ -676,6 +680,7 @@ set(viewer_HEADER_FILES
llfloaterbuy.h
llfloaterbuycontents.h
llfloaterbuycurrency.h
llfloaterbuycurrencyhtml.h
llfloaterbuyland.h
llfloatercamera.h
llfloatercolorpicker.h
@ -742,6 +747,7 @@ set(viewer_HEADER_FILES
llfollowcam.h
llfriendcard.h
llgesturemgr.h
llgiveinventory.h
llgroupactions.h
llgroupiconctrl.h
llgrouplist.h

View File

@ -4,6 +4,8 @@
<RenderAvatarCloth value="FALSE"/>
<!--Default for now-->
<RenderAvatarLODFactor value="0.5"/>
<!--Default for now-->
<RenderAvatarMaxVisible value="3"/>
<!--NO SHADERS-->
<RenderAvatarVP value="FALSE"/>
<!--Short Range-->

View File

@ -4591,6 +4591,17 @@
<key>Value</key>
<string />
</map>
<key>MarketplaceURL</key>
<map>
<key>Comment</key>
<string>URL to the Marketplace</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>https://www.xstreetsl.com/modules.php?name=Marketplace</string>
</map>
<key>MaxDragDistance</key>
<map>
<key>Comment</key>
@ -6017,6 +6028,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>QuickBuyCurrency</key>
<map>
<key>Comment</key>
<string>Toggle between HTML based currency purchase floater and legacy XUI version</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>RegionTextureSize</key>
<map>
<key>Comment</key>
@ -8173,17 +8195,6 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>ShowCameraButton</key>
<map>
<key>Comment</key>
<string>Show/Hide Camera button in the bottom tray</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>ShowScriptErrors</key>
<map>
<key>Comment</key>
@ -8206,39 +8217,6 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>ShowSnapshotButton</key>
<map>
<key>Comment</key>
<string>Show/Hide Snapshot button button in the bottom tray</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>ShowMoveButton</key>
<map>
<key>Comment</key>
<string>Show/Hide Move button in the bottom tray</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>ShowGestureButton</key>
<map>
<key>Comment</key>
<string>Show/Hide Gesture button in the bottom tray</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>ShowObjectRenderingCost</key>
<map>
<key>Comment</key>
@ -8759,6 +8737,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>SidebarWithButtonsVisibility</key>
<map>
<key>Comment</key>
<string>Sets visibility of sidebar with its tabs' buttons</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>SkinCurrent</key>
<map>
<key>Comment</key>

View File

@ -6623,6 +6623,60 @@ render_pass="bump">
name="head_tattoo">
<texture
local_texture="head_tattoo" />
<param
id="1062"
group="1"
edit_group="colorpicker_driven"
wearable="tattoo"
name="tattoo_head_red"
value_min="0"
value_max="1"
value_default="1">
<param_color>
<value
color="0, 0, 0, 255" />
<value
color="255, 0, 0, 255" />
</param_color>
</param>
<param
id="1063"
group="1"
edit_group="colorpicker_driven"
wearable="tattoo"
name="tattoo_head_green"
value_min="0"
value_max="1"
value_default="1">
<param_color>
<value
color="0, 0, 0, 255" />
<value
color="0, 255, 0, 255" />
</param_color>
</param>
<param
id="1064"
group="1"
edit_group="colorpicker_driven"
wearable="tattoo"
name="tattoo_head_blue"
value_min="0"
value_max="1"
value_default="1">
<param_color>
<value
color="0, 0, 0, 255" />
<value
color="0, 0, 255, 255" />
</param_color>
</param>
</layer>
@ -6745,6 +6799,61 @@ render_pass="bump">
name="upper_tattoo">
<texture
local_texture="upper_tattoo" />
<param
id="1065"
group="1"
edit_group="colorpicker_driven"
wearable="tattoo"
name="tattoo_upper_red"
value_min="0"
value_max="1"
value_default="1">
<param_color>
<value
color="0, 0, 0, 255" />
<value
color="255, 0, 0, 255" />
</param_color>
</param>
<param
id="1066"
group="1"
edit_group="colorpicker_driven"
wearable="tattoo"
name="tattoo_upper_green"
value_min="0"
value_max="1"
value_default="1">
<param_color>
<value
color="0, 0, 0, 255" />
<value
color="0, 255, 0, 255" />
</param_color>
</param>
<param
id="1067"
group="1"
edit_group="colorpicker_driven"
wearable="tattoo"
name="tattoo_upper_blue"
value_min="0"
value_max="1"
value_default="1">
<param_color>
<value
color="0, 0, 0, 255" />
<value
color="0, 0, 255, 255" />
</param_color>
</param>
</layer>
@ -7942,6 +8051,61 @@ render_pass="bump">
name="lower_tattoo">
<texture
local_texture="lower_tattoo" />
<param
id="1068"
group="1"
edit_group="colorpicker_driven"
wearable="tattoo"
name="tattoo_lower_red"
value_min="0"
value_max="1"
value_default="1">
<param_color>
<value
color="0, 0, 0, 255" />
<value
color="255, 0, 0, 255" />
</param_color>
</param>
<param
id="1069"
group="1"
edit_group="colorpicker_driven"
wearable="tattoo"
name="tattoo_lower_green"
value_min="0"
value_max="1"
value_default="1">
<param_color>
<value
color="0, 0, 0, 255" />
<value
color="0, 255, 0, 255" />
</param_color>
</param>
<param
id="1070"
group="1"
edit_group="colorpicker_driven"
wearable="tattoo"
name="tattoo_lower_blue"
value_min="0"
value_max="1"
value_default="1">
<param_color>
<value
color="0, 0, 0, 255" />
<value
color="0, 0, 255, 255" />
</param_color>
</param>
</layer>
<layer
@ -11367,6 +11531,106 @@ render_pass="bump">
</param_driver>
</param>
<param
id="1071"
group="0"
wearable="tattoo"
edit_group="colorpicker"
name="tattoo_red"
value_min="0"
value_max="1"
value_default="1">
<param_driver>
<driven
id="1062"
min1="0"
max1="1"
max2="1"
min2="1" />
<driven
id="1065"
min1="0"
max1="1"
max2="1"
min2="1" />
<driven
id="1068"
min1="0"
max1="1"
max2="1"
min2="1" />
</param_driver>
</param>
<param
id="1072"
group="0"
wearable="tattoo"
edit_group="colorpicker"
name="tattoo_green"
value_min="0"
value_max="1"
value_default="1">
<param_driver>
<driven
id="1063"
min1="0"
max1="1"
max2="1"
min2="1" />
<driven
id="1066"
min1="0"
max1="1"
max2="1"
min2="1" />
<driven
id="1069"
min1="0"
max1="1"
max2="1"
min2="1" />
</param_driver>
</param>
<param
id="1073"
group="0"
wearable="tattoo"
edit_group="colorpicker"
name="tattoo_blue"
value_min="0"
value_max="1"
value_default="1">
<param_driver>
<driven
id="1064"
min1="0"
max1="1"
max2="1"
min2="1" />
<driven
id="1067"
min1="0"
max1="1"
max2="1"
min2="1" />
<driven
id="1070"
min1="0"
max1="1"
max2="1"
min2="1" />
</param_driver>
</param>
</driver_parameters>

View File

@ -65,6 +65,7 @@ list Low
RenderAnisotropic 1 0
RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxVisible 1 3
RenderAvatarVP 1 0
RenderFarClip 1 64
RenderFlexTimeFactor 1 0.5

View File

@ -63,6 +63,7 @@ list Low
RenderAnisotropic 1 0
RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxVisible 1 3
RenderAvatarVP 1 0
RenderFarClip 1 64
RenderFlexTimeFactor 1 0.5

View File

@ -65,6 +65,7 @@ list Low
RenderAnisotropic 1 0
RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxVisible 1 3
RenderAvatarVP 1 0
RenderFarClip 1 64
RenderFlexTimeFactor 1 0.5

View File

@ -117,6 +117,7 @@ UseOcclusion 0 0
list low
RenderVBO 1 0
RenderAniso 1 0
RenderAvatarMaxVisible 1 3
RenderLighting 1 0
list medium

View File

@ -3088,21 +3088,30 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
mesgsys->getUUIDFast(_PREHASH_WearableData, _PREHASH_TextureID, texture_id, texture_block);
mesgsys->getU8Fast(_PREHASH_WearableData, _PREHASH_TextureIndex, texture_index, texture_block);
if ((S32)texture_index < BAKED_NUM_INDICES
&& gAgentQueryManager.mActiveCacheQueries[texture_index] == query_id)
{
if (texture_id.notNull())
if ((S32)texture_index < TEX_NUM_INDICES )
{
const LLVOAvatarDictionary::TextureEntry *texture_entry = LLVOAvatarDictionary::instance().getTexture((ETextureIndex)texture_index);
if (texture_entry)
{
//llinfos << "Received cached texture " << (U32)texture_index << ": " << texture_id << llendl;
gAgentAvatarp->setCachedBakedTexture(LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)texture_index), texture_id);
//gAgentAvatarp->setTETexture( LLVOAvatar::sBakedTextureIndices[texture_index], texture_id );
gAgentQueryManager.mActiveCacheQueries[texture_index] = 0;
num_results++;
}
else
{
// no cache of this bake. request upload.
gAgentAvatarp->requestLayerSetUpload((EBakedTextureIndex)texture_index);
EBakedTextureIndex baked_index = texture_entry->mBakedTextureIndex;
if (gAgentQueryManager.mActiveCacheQueries[baked_index] == query_id)
{
if (texture_id.notNull())
{
//llinfos << "Received cached texture " << (U32)texture_index << ": " << texture_id << llendl;
gAgentAvatarp->setCachedBakedTexture((ETextureIndex)texture_index, texture_id);
//gAgentAvatarp->setTETexture( LLVOAvatar::sBakedTextureIndices[texture_index], texture_id );
gAgentQueryManager.mActiveCacheQueries[baked_index] = 0;
num_results++;
}
else
{
// no cache of this bake. request upload.
gAgentAvatarp->requestLayerSetUpload(baked_index);
}
}
}
}
}
@ -3526,7 +3535,6 @@ void LLAgent::sendAgentSetAppearance()
return;
}
llinfos << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << llendl;
//dumpAvatarTEs( "sendAgentSetAppearance()" );
@ -3577,29 +3585,15 @@ void LLAgent::sendAgentSetAppearance()
llinfos << "TAT: Sending cached texture data" << llendl;
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{
const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
LLUUID hash;
for (U8 i=0; i < baked_dict->mWearables.size(); i++)
{
// LLWearableType::EType wearable_type = gBakedWearableMap[baked_index][wearable_num];
const LLWearableType::EType wearable_type = baked_dict->mWearables[i];
// MULTI-WEARABLE: fixed to 0th - extend to everything once messaging works.
const LLWearable* wearable = gAgentWearables.getWearable(wearable_type,0);
if (wearable)
{
hash ^= wearable->getAssetID();
}
}
LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index);
if (hash.notNull())
{
hash ^= baked_dict->mWearablesHashID;
ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex) baked_index);
msg->nextBlockFast(_PREHASH_WearableData);
msg->addUUIDFast(_PREHASH_CacheID, hash);
msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);
}
const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
msg->nextBlockFast(_PREHASH_WearableData);
msg->addUUIDFast(_PREHASH_CacheID, hash);
msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);
}
msg->nextBlockFast(_PREHASH_ObjectData);
gAgentAvatarp->sendAppearanceMessage( gMessageSystem );

View File

@ -125,7 +125,6 @@ void LLAgentWearables::dump()
}
}
// MULTI-WEARABLE: debugging
struct LLAgentDumper
{
LLAgentDumper(std::string name):
@ -191,7 +190,7 @@ LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCal
* @param todo Bitmask of actions to take on completion.
*/
LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback(
LLPointer<LLRefCount> cb, S32 type, U32 index, LLWearable* wearable, U32 todo) :
LLPointer<LLRefCount> cb, LLWearableType::EType type, U32 index, LLWearable* wearable, U32 todo) :
mType(type),
mIndex(index),
mWearable(wearable),
@ -240,7 +239,7 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i
}
}
void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type,
void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::EType type,
const U32 index,
const LLUUID& item_id,
LLWearable* wearable)
@ -250,7 +249,7 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type,
if (item_id.isNull())
return;
LLUUID old_item_id = getWearableItemID((LLWearableType::EType)type,index);
LLUUID old_item_id = getWearableItemID(type,index);
if (wearable)
{
@ -259,11 +258,11 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type,
if (old_item_id.notNull())
{
gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id);
setWearable((LLWearableType::EType)type,index,wearable);
setWearable(type,index,wearable);
}
else
{
pushWearable((LLWearableType::EType)type,wearable);
pushWearable(type,wearable);
}
}
@ -285,13 +284,12 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type,
void LLAgentWearables::sendAgentWearablesUpdate()
{
// MULTI-WEARABLE: call i "type" or something.
// First make sure that we have inventory items for each wearable
for (S32 type=0; type < LLWearableType::WT_COUNT; ++type)
{
for (U32 j=0; j < getWearableCount((LLWearableType::EType)type); ++j)
for (U32 index=0; index < getWearableCount((LLWearableType::EType)type); ++index)
{
LLWearable* wearable = getWearable((LLWearableType::EType)type,j);
LLWearable* wearable = getWearable((LLWearableType::EType)type,index);
if (wearable)
{
if (wearable->getItemID().isNull())
@ -299,8 +297,8 @@ void LLAgentWearables::sendAgentWearablesUpdate()
LLPointer<LLInventoryCallback> cb =
new addWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
type,
j,
(LLWearableType::EType)type,
index,
wearable,
addWearableToAgentInventoryCallback::CALL_NONE);
addWearableToAgentInventory(cb, wearable);
@ -325,7 +323,7 @@ void LLAgentWearables::sendAgentWearablesUpdate()
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
lldebugs << "sendAgentWearablesUpdate()" << llendl;
// MULTI-WEARABLE: update for multi-wearables after server-side support is in.
// MULTI-WEARABLE: DEPRECATED: HACK: index to 0- server database tables don't support concept of multiwearables.
for (S32 type=0; type < LLWearableType::WT_COUNT; ++type)
{
gMessageSystem->nextBlockFast(_PREHASH_WearableData);
@ -333,7 +331,6 @@ void LLAgentWearables::sendAgentWearablesUpdate()
U8 type_u8 = (U8)type;
gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8);
// MULTI-WEARABLE: TODO: hacked index to 0, needs to loop over all once messages support this.
LLWearable* wearable = getWearable((LLWearableType::EType)type, 0);
if (wearable)
{
@ -405,7 +402,7 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
LLPointer<LLInventoryCallback> cb =
new addWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
(S32)type,
type,
index,
new_wearable,
todo);
@ -871,7 +868,7 @@ BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id) const
return FALSE;
}
// MULTI-WEARABLE: update for multiple
// MULTI-WEARABLE: DEPRECATED (see backwards compatibility)
// static
// ! BACKWARDS COMPATIBILITY ! When we stop supporting viewer1.23, we can assume
// that viewers have a Current Outfit Folder and won't need this message, and thus
@ -909,7 +906,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
//lldebugs << "processAgentInitialWearablesUpdate()" << llendl;
// Add wearables
// MULTI-WEARABLE: TODO: update once messages change. Currently use results to populate the zeroth element.
// MULTI-WEARABLE: DEPRECATED: Message only supports one wearable per type, will be ignored in future.
gAgentWearables.mItemsAwaitingWearableUpdate.clear();
for (S32 i=0; i < num_wearables; i++)
{
@ -939,10 +936,10 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
continue;
}
// MULTI-WEARABLE: TODO: update once messages change. Currently use results to populate the zeroth element.
// MULTI-WEARABLE: DEPRECATED: this message only supports one wearable per type. Should be ignored in future versions
// Store initial wearables data until we know whether we have the current outfit folder or need to use the data.
LLInitialWearablesFetch::InitialWearableData wearable_data(type, item_id, asset_id); // MULTI-WEARABLE: update
LLInitialWearablesFetch::InitialWearableData wearable_data(type, item_id, asset_id);
outfit->add(wearable_data);
}
@ -977,7 +974,6 @@ void LLAgentWearables::recoverMissingWearable(const LLWearableType::EType type,
lldebugs << "Wearable " << LLWearableType::getTypeLabel(type) << " could not be downloaded. Replaced inventory item with default wearable." << llendl;
LLWearable* new_wearable = LLWearableList::instance().createNewWearable(type);
S32 type_s32 = (S32) type;
setWearable(type,index,new_wearable);
//new_wearable->writeToAvatar(TRUE);
@ -988,7 +984,7 @@ void LLAgentWearables::recoverMissingWearable(const LLWearableType::EType type,
LLPointer<LLInventoryCallback> cb =
new addWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
type_s32,
type,
index,
new_wearable,
addWearableToAgentInventoryCallback::CALL_RECOVERDONE);
@ -1172,158 +1168,6 @@ void LLAgentWearables::createStandardWearablesAllDone()
gAgentAvatarp->onFirstTEMessageReceived();
}
// MULTI-WEARABLE: Properly handle multiwearables later.
void LLAgentWearables::getAllWearablesArray(LLDynamicArray<S32>& wearables)
{
for( S32 i = 0; i < LLWearableType::WT_COUNT; ++i )
{
if (getWearableCount((LLWearableType::EType) i) != 0)
{
wearables.push_back(i);
}
}
}
// Note: wearables_to_include should be a list of LLWearableType::EType types
// attachments_to_include should be a list of attachment points
void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name,
const LLDynamicArray<S32>& wearables_to_include,
const LLDynamicArray<S32>& attachments_to_include,
BOOL rename_clothing)
{
if (!isAgentAvatarValid()) return;
// First, make a folder in the Clothes directory.
LLUUID folder_id = gInventory.createNewCategory(
gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING),
LLFolderType::FT_NONE,
new_folder_name);
bool found_first_item = false;
///////////////////
// Wearables
if (wearables_to_include.count())
{
// Then, iterate though each of the wearables and save copies of them in the folder.
S32 i;
S32 count = wearables_to_include.count();
LLDynamicArray<LLUUID> delete_items;
LLPointer<LLRefCount> cbdone = NULL;
for (i = 0; i < count; ++i)
{
const S32 type = wearables_to_include[i];
for (U32 j=0; j<getWearableCount((LLWearableType::EType)i); j++)
{
LLWearable* old_wearable = getWearable((LLWearableType::EType)type, j);
if (old_wearable)
{
std::string new_name;
LLWearable* new_wearable;
new_wearable = LLWearableList::instance().createCopy(old_wearable);
if (rename_clothing)
{
new_name = new_folder_name;
new_name.append(" ");
new_name.append(old_wearable->getTypeLabel());
LLStringUtil::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN);
new_wearable->setName(new_name);
}
LLViewerInventoryItem* item = gInventory.getItem(getWearableItemID((LLWearableType::EType)type,j));
S32 todo = addWearableToAgentInventoryCallback::CALL_NONE;
if (!found_first_item)
{
found_first_item = true;
/* set the focus to the first item */
todo |= addWearableToAgentInventoryCallback::CALL_MAKENEWOUTFITDONE;
/* send the agent wearables update when done */
cbdone = new sendAgentWearablesUpdateCallback;
}
LLPointer<LLInventoryCallback> cb =
new addWearableToAgentInventoryCallback(
cbdone,
type,
j,
new_wearable,
todo);
llassert(item);
if (item)
{
if (isWearableCopyable((LLWearableType::EType)type, j))
{
copy_inventory_item(
gAgent.getID(),
item->getPermissions().getOwner(),
item->getUUID(),
folder_id,
new_name,
cb);
}
else
{
move_inventory_item(
gAgent.getID(),
gAgent.getSessionID(),
item->getUUID(),
folder_id,
new_name,
cb);
}
}
}
}
}
gInventory.notifyObservers();
}
///////////////////
// Attachments
if (attachments_to_include.count())
{
BOOL msg_started = FALSE;
LLMessageSystem* msg = gMessageSystem;
for (S32 i = 0; i < attachments_to_include.count(); i++)
{
S32 attachment_pt = attachments_to_include[i];
LLViewerJointAttachment* attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, attachment_pt, (LLViewerJointAttachment*)NULL);
if (!attachment) continue;
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
LLViewerObject *attached_object = (*attachment_iter);
if(!attached_object) continue;
const LLUUID& item_id = (*attachment_iter)->getItemID();
if(item_id.isNull()) continue;
LLInventoryItem* item = gInventory.getItem(item_id);
if(!item) continue;
if(!msg_started)
{
msg_started = TRUE;
msg->newMessage("CreateNewOutfitAttachments");
msg->nextBlock("AgentData");
msg->addUUID("AgentID", gAgent.getID());
msg->addUUID("SessionID", gAgent.getSessionID());
msg->nextBlock("HeaderData");
msg->addUUID("NewFolderID", folder_id);
}
msg->nextBlock("ObjectData");
msg->addUUID("OldItemID", item_id);
msg->addUUID("OldFolderID", item->getParentUUID());
}
}
if (msg_started)
{
gAgent.sendReliableMessage();
}
}
}
class LLShowCreatedOutfit: public LLInventoryCallback
{
@ -1721,37 +1565,18 @@ void LLAgentWearables::queryWearableCache()
S32 num_queries = 0;
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{
const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
LLMD5 hash;
bool hash_computed = false;
for (U8 i=0; i < baked_dict->mWearables.size(); i++)
LLUUID hash_id = computeBakedTextureHash((EBakedTextureIndex) baked_index);
if (hash_id.notNull())
{
const LLWearableType::EType baked_type = baked_dict->mWearables[i];
const U32 num_wearables = getWearableCount(baked_type);
for (U32 index = 0; index < num_wearables; ++index)
{
const LLWearable* wearable = getWearable(baked_type,index);
if (wearable)
{
LLUUID asset_id = wearable->getAssetID();
hash.update((const unsigned char*)asset_id.mData, UUID_BYTES);
hash_computed = true;
}
}
}
hash.finalize();
if (hash_computed)
{
LLUUID hash_id;
hash.raw_digest(hash_id.mData);
hash_id ^= baked_dict->mWearablesHashID;
num_queries++;
// *NOTE: make sure at least one request gets packed
ETextureIndex te_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
//llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << llendl;
gMessageSystem->nextBlockFast(_PREHASH_WearableData);
gMessageSystem->addUUIDFast(_PREHASH_ID, hash_id);
gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)baked_index);
gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)te_index);
}
gAgentQueryManager.mActiveCacheQueries[baked_index] = gAgentQueryManager.mWearablesCacheQueryID;
@ -1763,6 +1588,39 @@ void LLAgentWearables::queryWearableCache()
gAgentQueryManager.mWearablesCacheQueryID++;
}
LLUUID LLAgentWearables::computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex index)
{
LLUUID hash_id;
bool hash_computed = false;
LLMD5 hash;
const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(index);
for (U8 i=0; i < baked_dict->mWearables.size(); i++)
{
const LLWearableType::EType baked_type = baked_dict->mWearables[i];
const U32 num_wearables = getWearableCount(baked_type);
for (U32 index = 0; index < num_wearables; ++index)
{
const LLWearable* wearable = getWearable(baked_type,index);
if (wearable)
{
LLUUID asset_id = wearable->getAssetID();
hash.update((const unsigned char*)asset_id.mData, UUID_BYTES);
hash_computed = true;
}
}
}
if (hash_computed)
{
hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES);
hash.finalize();
hash.raw_digest(hash_id.mData);
}
return hash_id;
}
// User has picked "remove from avatar" from a menu.
// static
void LLAgentWearables::userRemoveWearable(const LLWearableType::EType &type, const U32 &index)
@ -2010,7 +1868,7 @@ BOOL LLAgentWearables::areWearablesLoaded() const
return mWearablesLoaded;
}
// MULTI-WEARABLE: update for multiple indices.
// MULTI-WEARABLE: DEPRECATED: item pending count relies on old messages that don't support multi-wearables. do not trust to be accurate
void LLAgentWearables::updateWearablesLoaded()
{
mWearablesLoaded = (itemUpdatePendingCount()==0);

View File

@ -62,7 +62,6 @@ public:
void cleanup();
void dump();
protected:
// MULTI-WEARABLE: assuming one per type. Type is called index - rename.
void createStandardWearablesDone(S32 type, U32 index/* = 0*/);
void createStandardWearablesAllDone();
@ -93,7 +92,6 @@ public:
const LLWearable* getWearableFromItemID(const LLUUID& item_id) const;
LLWearable* getWearableFromAssetID(const LLUUID& asset_id);
LLInventoryItem* getWearableInventoryItem(LLWearableType::EType type, U32 index /*= 0*/);
// MULTI-WEARABLE: assuming one per type.
static BOOL selfHasWearable(LLWearableType::EType type);
LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/);
const LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;
@ -128,7 +126,7 @@ protected:
LLWearable* wearable,
const LLUUID& category_id = LLUUID::null,
BOOL notify = TRUE);
void addWearabletoAgentInventoryDone(const S32 type,
void addWearabletoAgentInventoryDone(const LLWearableType::EType type,
const U32 index,
const LLUUID& item_id,
LLWearable* wearable);
@ -152,6 +150,8 @@ protected:
public:
// Processes the initial wearables update message (if necessary, since the outfit folder makes it redundant)
static void processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data);
LLUUID computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex index);
protected:
void sendAgentWearablesUpdate();
void sendAgentWearablesRequest();
@ -163,15 +163,6 @@ protected:
// Outfits
//--------------------------------------------------------------------
public:
void getAllWearablesArray(LLDynamicArray<S32>& wearables);
// Note: wearables_to_include should be a list of LLWearableType::EType types
// attachments_to_include should be a list of attachment points
void makeNewOutfit(const std::string& new_folder_name,
const LLDynamicArray<S32>& wearables_to_include,
const LLDynamicArray<S32>& attachments_to_include,
BOOL rename_clothing);
// Should only be called if we *know* we've never done so before, since users may
// not want the Library outfits to stay in their quick outfit selector and can delete them.
@ -184,7 +175,6 @@ private:
// Save Wearables
//--------------------------------------------------------------------
public:
// MULTI-WEARABLE: assumes one per type.
void saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found);
void saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update = TRUE);
void saveAllWearables();
@ -249,7 +239,7 @@ private:
class addWearableToAgentInventoryCallback : public LLInventoryCallback
{
public:
enum EType
enum ETodo
{
CALL_NONE = 0,
CALL_UPDATE = 1,
@ -259,16 +249,14 @@ private:
CALL_WEARITEM = 16
};
// MULTI-WEARABLE: index is an LLWearableType::EType - more confusing usage.
// MULTI-WEARABLE: need to have type and index args both?
addWearableToAgentInventoryCallback(LLPointer<LLRefCount> cb,
S32 type,
LLWearableType::EType type,
U32 index,
LLWearable* wearable,
U32 todo = CALL_NONE);
virtual void fire(const LLUUID& inv_item);
private:
S32 mType;
LLWearableType::EType mType;
U32 mIndex;
LLWearable* mWearable;
U32 mTodo;

View File

@ -190,7 +190,9 @@ LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy()
void LLUpdateAppearanceOnDestroy::fire(const LLUUID& inv_item)
{
llinfos << "callback fired" << llendl;
LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(inv_item);
const std::string item_name = item ? item->getName() : "ITEM NOT FOUND";
llinfos << "callback fired [ name:" << item_name << " UUID:" << inv_item << " count:" << mFireCount << " ] " << llendl;
mFireCount++;
}
@ -890,7 +892,7 @@ void LLAppearanceMgr::filterWearableItems(
}
// Create links to all listed items.
void LLAppearanceMgr::linkAll(const LLUUID& category,
void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid,
LLInventoryModel::item_array_t& items,
LLPointer<LLInventoryCallback> cb)
{
@ -899,11 +901,16 @@ void LLAppearanceMgr::linkAll(const LLUUID& category,
const LLInventoryItem* item = items.get(i).get();
link_inventory_item(gAgent.getID(),
item->getLinkedUUID(),
category,
cat_uuid,
item->getName(),
item->LLInventoryItem::getDescription(),
LLAssetType::AT_LINK,
cb);
const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid);
const std::string cat_name = cat ? cat->getName() : "CAT NOT FOUND";
llinfos << "Linking Item [ name:" << item->getName() << " UUID:" << item->getUUID() << " ] to Category [ name:" << cat_name << " UUID:" << cat_uuid << " ] " << llendl; // Seraph remove for 2.1
}
}
@ -972,9 +979,13 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
llinfos << "creating LLUpdateAppearanceOnDestroy" << llendl;
LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
llinfos << "Linking body items" << llendl; // Seraph remove for 2.1
linkAll(cof, body_items, link_waiter);
llinfos << "Linking wear items" << llendl; // Seraph remove for 2.1
linkAll(cof, wear_items, link_waiter);
llinfos << "Linking obj items" << llendl; // Seraph remove for 2.1
linkAll(cof, obj_items, link_waiter);
llinfos << "Linking gesture items" << llendl; // Seraph remove for 2.1
linkAll(cof, gest_items, link_waiter);
// Add link to outfit if category is an outfit.
@ -1030,8 +1041,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
LLWearable* wearable = data.mWearable;
if( wearable && ((S32)wearable->getType() == i) )
{
LLViewerInventoryItem* item;
item = (LLViewerInventoryItem*)gInventory.getItem(data.mItemID);
LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(data.mItemID);
if( item && (item->getAssetUUID() == wearable->getAssetID()) )
{
items.put(item);
@ -1469,16 +1479,23 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update
{
// Are these links to the same object?
const LLViewerInventoryItem* inv_item = item_array.get(i).get();
const LLWearableType::EType wearable_type = inv_item->getWearableType();
const bool is_body_part = (wearable_type == LLWearableType::WT_SHAPE)
|| (wearable_type == LLWearableType::WT_HAIR)
|| (wearable_type == LLWearableType::WT_EYES)
|| (wearable_type == LLWearableType::WT_SKIN);
if (inv_item->getLinkedUUID() == vitem->getLinkedUUID())
{
linked_already = true;
}
// Are these links to different items of the same wearable
// Are these links to different items of the same body part
// type? If so, new item will replace old.
// MULTI-WEARABLES: revisit if more than one per type is allowed.
else if (FALSE/*areMatchingWearables(vitem,inv_item)*/)
// TODO: MULTI-WEARABLE: check for wearable limit for clothing types
else if (is_body_part && (vitem->isWearableType()) && (vitem->getWearableType() == wearable_type))
{
if (inv_item->getIsLinkType())
if (inv_item->getIsLinkType() && (vitem->getWearableType() == wearable_type))
{
gInventory.purgeObject(inv_item->getUUID());
}

View File

@ -37,7 +37,7 @@
// viewer includes
#include "llagent.h"
#include "llcompilequeue.h"
#include "llfloaterbuycurrency.h"
#include "llbuycurrencyhtml.h"
#include "llfilepicker.h"
#include "llinventorydefines.h"
#include "llinventoryobserver.h"
@ -186,7 +186,7 @@ void LLAssetUploadResponder::uploadFailure(const LLSD& content)
S32 price = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
LLStringUtil::format_map_t args;
args["AMOUNT"] = llformat("%d", price);
LLFloaterBuyCurrency::buyCurrency(LLTrans::getString("uploading_costs", args), price);
LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("uploading_costs", args), price );
}
else
{

View File

@ -54,7 +54,9 @@
#include "llfloaterreg.h"
#include "llfloaterpay.h"
#include "llfloaterworldmap.h"
#include "llgiveinventory.h"
#include "llinventorymodel.h" // for gInventory.findCategoryUUIDForType
#include "llinventorypanel.h"
#include "llimview.h" // for gIMMgr
#include "llmutelist.h"
#include "llnotificationsutil.h" // for LLNotificationsUtil
@ -190,7 +192,7 @@ void LLAvatarActions::offerTeleport(const uuid_vec_t& ids)
static void on_avatar_name_cache_start_im(const LLUUID& agent_id,
const LLAvatarName& av_name)
{
std::string name = av_name.getNameAndSLID();
std::string name = av_name.getCompleteName();
LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id);
if (session_id != LLUUID::null)
{
@ -225,7 +227,7 @@ void LLAvatarActions::endIM(const LLUUID& id)
static void on_avatar_name_cache_start_call(const LLUUID& agent_id,
const LLAvatarName& av_name)
{
std::string name = av_name.getNameAndSLID();
std::string name = av_name.getCompleteName();
LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id, true);
if (session_id != LLUUID::null)
{
@ -435,13 +437,107 @@ void LLAvatarActions::share(const LLUUID& id)
}
}
namespace action_give_inventory
{
typedef std::set<LLUUID> uuid_set_t;
/**
* Checks My Inventory visibility.
*/
static bool is_give_inventory_acceptable()
{
LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
if (NULL == active_panel) return false;
// check selection in the panel
const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList();
if (inventory_selected_uuids.empty()) return false; // nothing selected
bool acceptable = false;
uuid_set_t::const_iterator it = inventory_selected_uuids.begin();
const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end();
for (; it != it_end; ++it)
{
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
// any category can be offered.
if (inv_cat)
{
acceptable = true;
continue;
}
LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
// check if inventory item can be given
if (LLGiveInventory::isInventoryGiveAcceptable(inv_item))
{
acceptable = true;
continue;
}
// there are neither item nor category in inventory
acceptable = false;
break;
}
return acceptable;
}
/**
* Performs "give inventory" operations for provided avatars.
*
* Sends one requests to give all selected inventory items for each passed avatar.
* Avatars are represent by two vectors: names and UUIDs which must be sychronized with each other.
*
* @param avatar_names - avatar names request to be sent.
* @param avatar_uuids - avatar names request to be sent.
*/
static void give_inventory(const std::vector<std::string>& avatar_names, const uuid_vec_t& avatar_uuids)
{
llassert(avatar_names.size() == avatar_uuids.size());
LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
if (NULL == active_panel) return;
const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList();
if (inventory_selected_uuids.empty()) return;
S32 count = llmin(avatar_names.size(), avatar_uuids.size());
// iterate through avatars
for(S32 i = 0; i < count; ++i)
{
const std::string& avatar_name = avatar_names[i];
const LLUUID& avatar_uuid = avatar_uuids[i];
// Start up IM before give the item
const LLUUID session_id = gIMMgr->addSession(avatar_name, IM_NOTHING_SPECIAL, avatar_uuid);
uuid_set_t::const_iterator it = inventory_selected_uuids.begin();
const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end();
// iterate through selected inventory objects
for (; it != it_end; ++it)
{
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
if (inv_cat)
{
LLGiveInventory::doGiveInventoryCategory(avatar_uuid, inv_cat, session_id);
break;
}
LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id);
}
}
}
}
//static
void LLAvatarActions::shareWithAvatars()
{
LLFloaterAvatarPicker* picker =
LLFloaterAvatarPicker::show(NULL, FALSE, TRUE);
picker->setOkBtnEnableCb(boost::lambda::constant(false));
using namespace action_give_inventory;
LLFloaterAvatarPicker* picker =
LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE);
picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable));
LLNotificationsUtil::add("ShareNotification");
}

View File

@ -34,17 +34,19 @@
#include "llavatariconctrl.h"
// viewer includes
#include "llagent.h"
#include "llavatarconstants.h"
#include "llcallingcard.h" // for LLAvatarTracker
#include "llavataractions.h"
#include "llmenugl.h"
#include "lluictrlfactory.h"
#include "llcachename.h"
#include "llagentdata.h"
#include "llimfloater.h"
// library includes
#include "llavatarnamecache.h"
#define MENU_ITEM_VIEW_PROFILE 0
#define MENU_ITEM_SEND_IM 1
@ -233,6 +235,9 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)
// Check if cache already contains image_id for that avatar
if (!updateFromCache())
{
// *TODO: Consider getting avatar icon/badge directly from
// People API, rather than sending AvatarPropertyRequest
// messages. People API already hits the user table.
LLIconCtrl::setValue(mDefaultIconName);
app->addObserver(mAvatarId, this);
app->sendAvatarPropertiesRequest(mAvatarId);
@ -244,8 +249,9 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)
LLIconCtrl::setValue(value);
}
gCacheName->get(mAvatarId, false,
boost::bind(&LLAvatarIconCtrl::nameUpdatedCallback, this, _1, _2, _3));
LLAvatarNameCache::get(mAvatarId,
boost::bind(&LLAvatarIconCtrl::onAvatarNameCache,
this, _1, _2));
}
bool LLAvatarIconCtrl::updateFromCache()
@ -288,18 +294,17 @@ void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type)
}
}
void LLAvatarIconCtrl::nameUpdatedCallback(
const LLUUID& id,
const std::string& name,
bool is_group)
void LLAvatarIconCtrl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
{
if (id == mAvatarId)
if (agent_id == mAvatarId)
{
mFullName = name;
// Most avatar icon controls are next to a UI element that shows
// a display name, so only show username.
mFullName = av_name.mUsername;
if (mDrawTooltip)
{
setToolTip(name);
setToolTip(mFullName);
}
else
{

View File

@ -37,6 +37,8 @@
#include "llavatarpropertiesprocessor.h"
#include "llviewermenu.h"
class LLAvatarName;
class LLAvatarIconIDCache: public LLSingleton<LLAvatarIconIDCache>
{
public:
@ -90,10 +92,7 @@ public:
// LLAvatarPropertiesProcessor observer trigger
virtual void processProperties(void* data, EAvatarProcessorType type);
void nameUpdatedCallback(
const LLUUID& id,
const std::string& name,
bool is_group);
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
const LLUUID& getAvatarId() const { return mAvatarId; }
const std::string& getFullName() const { return mFullName; }

View File

@ -35,20 +35,32 @@
#define LLBOTTOMTRAY_CPP
#include "llbottomtray.h"
#include "llagentcamera.h"
#include "llchiclet.h"
// library includes
#include "llfloaterreg.h"
#include "llflyoutbutton.h"
#include "llimfloater.h" // for LLIMFloater
#include "lllayoutstack.h"
#include "llnearbychatbar.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "lltexteditor.h"
// newview includes
#include "llagentcamera.h"
#include "llchiclet.h"
#include "llfloatercamera.h"
#include "llimfloater.h" // for LLIMFloater
#include "llnearbychatbar.h"
#include "llspeakbutton.h"
#include "llsplitbutton.h"
#include "llsyswellwindow.h"
#include "llfloatercamera.h"
#include "lltexteditor.h"
#include "llnotifications.h"
#include "lltoolmgr.h"
#include "llviewerparcelmgr.h"
static void update_build_button_enable_state()
{
bool can_edit = LLToolMgr::getInstance()->canEdit();
LLBottomTray::getInstance()->childSetEnabled("build_btn", can_edit);
}
// Build time optimization, generate extern template once in .cpp file
template class LLBottomTray* LLSingleton<class LLBottomTray>::getInstance();
@ -61,7 +73,7 @@ namespace
const std::string& PANEL_CAMERA_NAME = "cam_panel";
const std::string& PANEL_GESTURE_NAME = "gesture_panel";
S32 get_panel_min_width(LLLayoutStack* stack, LLPanel* panel)
S32 get_panel_min_width(LLLayoutStack* stack, LLView* panel)
{
S32 minimal_width = 0;
llassert(stack);
@ -183,6 +195,13 @@ LLBottomTray::~LLBottomTray()
{
LLIMMgr::getInstance()->removeSessionObserver(this);
}
if (mNearbyChatBar)
{
// store custom width of chatbar panel.
S32 custom_width = mNearbyChatBar->getRect().getWidth();
gSavedSettings.setS32("ChatBarCustomWidth", custom_width);
}
}
// *TODO Vadim: why void* ?
@ -361,6 +380,20 @@ S32 LLBottomTray::notifyParent(const LLSD& info)
showWellButton("im_well" == chiclet_name ? RS_IM_WELL : RS_NOTIFICATION_WELL, should_be_visible);
return 1;
}
if (info.has("action") && info["action"] == "resize")
{
const std::string& name = info["view_name"];
// expected only resize of nearby chatbar
if (mNearbyChatBar->getName() != name) return LLPanel::notifyParent(info);
const S32 new_width = info["new_width"];
processChatbarCustomization(new_width);
return 2;
}
return LLPanel::notifyParent(info);
}
@ -487,6 +520,8 @@ BOOL LLBottomTray::postBuild()
showWellButton(RS_IM_WELL, !LLIMWellWindow::getInstance()->isWindowEmpty());
showWellButton(RS_NOTIFICATION_WELL, !LLNotificationWellWindow::getInstance()->isWindowEmpty());
LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&update_build_button_enable_state));
return TRUE;
}
@ -648,6 +683,24 @@ void LLBottomTray::reshape(S32 width, S32 height, BOOL called_from_parent)
if (mNearbyChatBar) log(mNearbyChatBar, "after");
if (mChicletPanel) log(mChicletPanel, "after");
// Restore width of the chatbar on first reshape.
// we can not to do this from postBuild because reshape is called from parent view on startup
// creation after it and reset width according to resize logic.
static bool needs_restore_custom_state = true;
if (mNearbyChatBar && needs_restore_custom_state)
{
// restore custom width of chatbar panel.
S32 new_width = gSavedSettings.getS32("ChatBarCustomWidth");
if (new_width > 0)
{
processChatbarCustomization(new_width);
mNearbyChatBar->reshape(new_width, mNearbyChatBar->getRect().getHeight());
}
needs_restore_custom_state = false;
}
}
S32 LLBottomTray::processWidthDecreased(S32 delta_width)
@ -1130,6 +1183,7 @@ void LLBottomTray::initResizeStateContainers()
mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_MOVEMENT, mMovementPanel));
mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_CAMERA, mCamPanel));
mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_SNAPSHOT, mSnapshotPanel));
mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_SIDEBAR, getChild<LLPanel>("sidebar_btn_panel")));
mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_BUILD, getChild<LLPanel>("build_btn_panel")));
mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_SEARCH, getChild<LLPanel>("search_btn_panel")));
mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_WORLD_MAP, getChild<LLPanel>("world_map_btn_panel")));
@ -1140,6 +1194,7 @@ void LLBottomTray::initResizeStateContainers()
mButtonsProcessOrder.push_back(RS_BUTTON_MOVEMENT);
mButtonsProcessOrder.push_back(RS_BUTTON_CAMERA);
mButtonsProcessOrder.push_back(RS_BUTTON_SNAPSHOT);
mButtonsProcessOrder.push_back(RS_BUTTON_SIDEBAR);
mButtonsProcessOrder.push_back(RS_BUTTON_BUILD);
mButtonsProcessOrder.push_back(RS_BUTTON_SEARCH);
mButtonsProcessOrder.push_back(RS_BUTTON_WORLD_MAP);
@ -1155,6 +1210,7 @@ void LLBottomTray::initResizeStateContainers()
{
const EResizeState button_type = *it;
// is there an appropriate object?
llassert(mStateProcessedObjectMap.count(button_type) > 0);
if (0 == mStateProcessedObjectMap.count(button_type)) continue;
// set default width for it.
@ -1166,28 +1222,51 @@ void LLBottomTray::initResizeStateContainers()
}
// this method must be called before restoring of the chat entry field on startup
// because it resets chatbar's width according to resize logic.
void LLBottomTray::initButtonsVisibility()
{
// *TODO: move control settings of other buttons here
setTrayButtonVisibleIfPossible(RS_BUTTON_BUILD, gSavedSettings.getBOOL("ShowBuildButton"));
setTrayButtonVisibleIfPossible(RS_BUTTON_SEARCH, gSavedSettings.getBOOL("ShowSearchButton"));
setTrayButtonVisibleIfPossible(RS_BUTTON_WORLD_MAP, gSavedSettings.getBOOL("ShowWorldMapButton"));
setTrayButtonVisibleIfPossible(RS_BUTTON_MINI_MAP, gSavedSettings.getBOOL("ShowMiniMapButton"));
setVisibleAndFitWidths(RS_BUTTON_GESTURES, gSavedSettings.getBOOL("ShowGestureButton"));
setVisibleAndFitWidths(RS_BUTTON_MOVEMENT, gSavedSettings.getBOOL("ShowMoveButton"));
setVisibleAndFitWidths(RS_BUTTON_CAMERA, gSavedSettings.getBOOL("ShowCameraButton"));
setVisibleAndFitWidths(RS_BUTTON_SNAPSHOT, gSavedSettings.getBOOL("ShowSnapshotButton"));
setVisibleAndFitWidths(RS_BUTTON_SIDEBAR, gSavedSettings.getBOOL("ShowSidebarButton"));
setVisibleAndFitWidths(RS_BUTTON_BUILD, gSavedSettings.getBOOL("ShowBuildButton"));
setVisibleAndFitWidths(RS_BUTTON_SEARCH, gSavedSettings.getBOOL("ShowSearchButton"));
setVisibleAndFitWidths(RS_BUTTON_WORLD_MAP, gSavedSettings.getBOOL("ShowWorldMapButton"));
setVisibleAndFitWidths(RS_BUTTON_MINI_MAP, gSavedSettings.getBOOL("ShowMiniMapButton"));
}
void LLBottomTray::setButtonsControlsAndListeners()
{
// *TODO: move control settings of other buttons here
gSavedSettings.declareBOOL("ShowGestureButton", TRUE, "Shows/Hides Gesture button in the bottom tray. (Declared in code)");
gSavedSettings.declareBOOL("ShowMoveButton", TRUE, "Shows/Hides Move button in the bottom tray. (Declared in code)");
gSavedSettings.declareBOOL("ShowSnapshotButton", TRUE, "Shows/Hides Snapshot button button in the bottom tray. (Declared in code)");
gSavedSettings.declareBOOL("ShowCameraButton", TRUE, "Show/Hide View button in the bottom tray. (Declared in code)");
gSavedSettings.declareBOOL("ShowSidebarButton", TRUE, "Shows/hides Sidebar button in the bottom tray. (Declared in code)");
gSavedSettings.declareBOOL("ShowBuildButton", TRUE, "Shows/Hides Build button in the bottom tray. (Declared in code)");
gSavedSettings.declareBOOL("ShowSearchButton", TRUE, "Shows/Hides Search button in the bottom tray. (Declared in code)");
gSavedSettings.declareBOOL("ShowWorldMapButton", TRUE, "Shows/Hides Map button in the bottom tray. (Declared in code)");
gSavedSettings.declareBOOL("ShowMiniMapButton", TRUE, "Shows/Hides Mini-Map button in the bottom tray. (Declared in code)");
gSavedSettings.declareS32("ChatBarCustomWidth", 0, "Stores customized width of chat bar. (Declared in code)");
gSavedSettings.getControl("ShowGestureButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_GESTURES, _2));
gSavedSettings.getControl("ShowMoveButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_MOVEMENT, _2));
gSavedSettings.getControl("ShowCameraButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_CAMERA, _2));
gSavedSettings.getControl("ShowSnapshotButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_SNAPSHOT, _2));
gSavedSettings.getControl("ShowSidebarButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_SIDEBAR, _2));
gSavedSettings.getControl("ShowBuildButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_BUILD, _2));
gSavedSettings.getControl("ShowSearchButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_SEARCH, _2));
gSavedSettings.getControl("ShowWorldMapButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_WORLD_MAP, _2));
gSavedSettings.getControl("ShowMiniMapButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_MINI_MAP, _2));
LLButton* build_btn = getChild<LLButton>("build_btn");
// set control name for Build button. It is not enough to link it with Button.SetFloaterToggle in xml
std::string vis_control_name = LLFloaterReg::declareVisibilityControl("build");
// Set the button control value (toggle state) to the floater visibility control (Sets the value as well)
build_btn->setControlVariable(LLUI::sSettingGroups["floater"]->getControl(vis_control_name));
}
bool LLBottomTray::toggleShowButton(LLBottomTray::EResizeState button_type, const LLSD& new_visibility)
@ -1262,17 +1341,18 @@ bool LLBottomTray::setVisibleAndFitWidths(EResizeState object_type, bool visible
const S32 chatbar_shrunk_width =
mNearbyChatBar->getRect().getWidth() - get_panel_min_width(mToolbarStack, mNearbyChatBar);
const S32 sum_of_min_widths =
get_panel_min_width(mToolbarStack, mStateProcessedObjectMap[RS_BUTTON_CAMERA]) +
get_panel_min_width(mToolbarStack, mStateProcessedObjectMap[RS_BUTTON_MOVEMENT]) +
get_panel_min_width(mToolbarStack, mStateProcessedObjectMap[RS_BUTTON_GESTURES]) +
get_panel_min_width(mToolbarStack, mSpeakPanel);
S32 sum_of_min_widths = get_panel_min_width(mToolbarStack, mSpeakPanel);
S32 sum_of_curr_widths = get_curr_width(mSpeakPanel);
const S32 sum_of_curr_widths =
get_curr_width(mStateProcessedObjectMap[RS_BUTTON_CAMERA]) +
get_curr_width(mStateProcessedObjectMap[RS_BUTTON_MOVEMENT]) +
get_curr_width(mStateProcessedObjectMap[RS_BUTTON_GESTURES]) +
get_curr_width(mSpeakPanel);
resize_state_vec_t::const_iterator it = mButtonsProcessOrder.begin();
const resize_state_vec_t::const_iterator it_end = mButtonsProcessOrder.end();
for (; it != it_end; ++it)
{
LLPanel * cur_panel = mStateProcessedObjectMap[*it];
sum_of_min_widths += get_panel_min_width(mToolbarStack, cur_panel);
sum_of_curr_widths += get_curr_width(cur_panel);
}
const S32 possible_shrunk_width =
chatbar_shrunk_width + (sum_of_curr_widths - sum_of_min_widths);
@ -1352,4 +1432,34 @@ void LLBottomTray::showWellButton(EResizeState object_type, bool visible)
}
}
void LLBottomTray::processChatbarCustomization(S32 new_width)
{
if (NULL == mNearbyChatBar) return;
const S32 delta_width = mNearbyChatBar->getRect().getWidth() - new_width;
if (delta_width == 0) return;
LLView * chiclet_layout_panel = mChicletPanel->getParent();
const S32 chiclet_min_width = get_panel_min_width(mToolbarStack, chiclet_layout_panel);
const S32 chiclet_panel_width = chiclet_layout_panel->getRect().getWidth();
const S32 available_chiclet_shrink_width = chiclet_panel_width - chiclet_min_width;
llassert(available_chiclet_shrink_width >= 0);
if (delta_width > 0) // panel gets narrowly
{
S32 total_possible_width = delta_width + available_chiclet_shrink_width;
processShowButtons(total_possible_width);
processExtendButtons(total_possible_width);
}
// here (delta_width < 0) // panel gets wider
else //if (-delta_width > available_chiclet_shrink_width)
{
S32 required_width = delta_width + available_chiclet_shrink_width;
S32 buttons_freed_width = 0;
processShrinkButtons(required_width, buttons_freed_width);
processHideButtons(required_width, buttons_freed_width);
}
}
//EOF

View File

@ -124,6 +124,7 @@ private:
, RS_BUTTON_SEARCH = 0x0400
, RS_BUTTON_WORLD_MAP = 0x0800
, RS_BUTTON_MINI_MAP = 0x1000
, RS_BUTTON_SIDEBAR = 0x2000
/*
Once new button that can be hidden on resize is added don't forget to update related places:
@ -138,6 +139,7 @@ private:
*/
, RS_BUTTONS_CAN_BE_HIDDEN = RS_BUTTON_SNAPSHOT | RS_BUTTON_CAMERA | RS_BUTTON_MOVEMENT | RS_BUTTON_GESTURES
| RS_BUTTON_BUILD | RS_BUTTON_SEARCH | RS_BUTTON_WORLD_MAP | RS_BUTTON_MINI_MAP
| RS_BUTTON_SIDEBAR
}EResizeState;
/**
@ -341,6 +343,17 @@ private:
*/
void showWellButton(EResizeState object_type, bool visible);
/**
* Handles a customization of chatbar width.
*
* When chatbar gets wider layout stack will reduce chiclet panel (it is auto-resizable)
* But once chiclet panel reaches its minimal width Stack will force to reduce buttons width.
* including Speak button. The similar behavior is when chatbar gets narrowly.
* This methods force resize behavior to resize buttons properly in these cases.
*/
void processChatbarCustomization(S32 new_width);
MASK mResizeState;
typedef std::map<EResizeState, LLPanel*> state_object_map_t;

View File

@ -0,0 +1,165 @@
/**
* @file llbuycurrencyhtml.cpp
* @brief Manages Buy Currency HTML floater
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2006-2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterbuycurrency.h"
#include "llbuycurrencyhtml.h"
#include "llfloaterbuycurrencyhtml.h"
#include "llfloaterreg.h"
#include "llcommandhandler.h"
#include "llviewercontrol.h"
// support for secondlife:///app/buycurrencyhtml/{ACTION}/{NEXT_ACTION}/{RETURN_CODE} SLapps
class LLBuyCurrencyHTMLHandler :
public LLCommandHandler
{
public:
// requests will be throttled from a non-trusted browser
LLBuyCurrencyHTMLHandler() : LLCommandHandler( "buycurrencyhtml", UNTRUSTED_ALLOW ) {}
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
{
std::string action( "" );
if ( params.size() >= 1 )
{
action = params[ 0 ].asString();
};
std::string next_action( "" );
if ( params.size() >= 2 )
{
next_action = params[ 1 ].asString();
};
int result_code = 0;
if ( params.size() >= 3 )
{
result_code = params[ 2 ].asInteger();
};
// open the legacy XUI based currency floater
if ( "open_legacy" == next_action )
{
LLFloaterBuyCurrency::buyCurrency();
};
// ask the Buy Currency floater to close
// note: this is the last thing we can do so make
// sure any other actions are processed before this.
if ( "close" == action )
{
LLBuyCurrencyHTML::closeDialog();
};
return true;
};
};
LLBuyCurrencyHTMLHandler gBuyCurrencyHTMLHandler;
////////////////////////////////////////////////////////////////////////////////
// static
// Opens the legacy XUI based floater or new HTML based one based on
// the QuickBuyCurrency value in settings.xml - this overload is for
// the case where the amount is not requested.
void LLBuyCurrencyHTML::openCurrencyFloater()
{
if ( gSavedSettings.getBOOL( "QuickBuyCurrency" ) )
{
// HTML version
LLBuyCurrencyHTML::showDialog( false, "", 0 );
}
else
{
// legacy version
LLFloaterBuyCurrency::buyCurrency();
};
}
////////////////////////////////////////////////////////////////////////////////
// static
// Opens the legacy XUI based floater or new HTML based one based on
// the QuickBuyCurrency value in settings.xml - this overload is for
// the case where the amount and a string to display are requested.
void LLBuyCurrencyHTML::openCurrencyFloater( const std::string& message, S32 sum )
{
if ( gSavedSettings.getBOOL( "QuickBuyCurrency" ) )
{
// HTML version
LLBuyCurrencyHTML::showDialog( true, message, sum );
}
else
{
// legacy version
LLFloaterBuyCurrency::buyCurrency( message, sum );
};
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLBuyCurrencyHTML::showDialog( bool specific_sum_requested, const std::string& message, S32 sum )
{
LLFloaterBuyCurrencyHTML* buy_currency_floater = dynamic_cast< LLFloaterBuyCurrencyHTML* >( LLFloaterReg::getInstance( "buy_currency_html" ) );
if ( buy_currency_floater )
{
// pass on flag indicating if we want to buy specific amount and if so, how much
buy_currency_floater->setParams( specific_sum_requested, message, sum );
// force navigate to new URL
buy_currency_floater->navigateToFinalURL();
// make it visible and raise to front
BOOL visible = TRUE;
buy_currency_floater->setVisible( visible );
BOOL take_focus = TRUE;
buy_currency_floater->setFrontmost( take_focus );
// spec calls for floater to be centered on client window
buy_currency_floater->center();
}
else
{
llwarns << "Buy Currency (HTML) Floater not found" << llendl;
};
}
////////////////////////////////////////////////////////////////////////////////
//
void LLBuyCurrencyHTML::closeDialog()
{
LLFloaterBuyCurrencyHTML* buy_currency_floater = dynamic_cast< LLFloaterBuyCurrencyHTML* >(LLFloaterReg::getInstance( "buy_currency_html" ) );
if ( buy_currency_floater )
{
buy_currency_floater->closeFloater();
};
}

View File

@ -0,0 +1,57 @@
/**
* @file llbuycurrencyhtml.h
* @brief Manages Buy Currency HTML floater
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2006-2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLBUYCURRENCYHTML_H
#define LL_LLBUYCURRENCYHTML_H
#include "llsingleton.h"
class LLFloaterBuyCurrencyHTML;
class LLBuyCurrencyHTML
{
public:
// choke point for opening a legacy or new currency floater - this overload is when the L$ sum is not required
static void openCurrencyFloater();
// choke point for opening a legacy or new currency floater - this overload is when the L$ sum is required
static void openCurrencyFloater( const std::string& message, S32 sum );
// show and give focus to actual currency floater - this is used for both cases
// where the sum is required and where it is not
static void showDialog( bool specific_sum_requested, const std::string& message, S32 sum );
// close (and destroy) the currency floater
static void closeDialog();
};
#endif // LL_LLBUYCURRENCYHTML_H

View File

@ -686,7 +686,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
// for object IMs, create a secondlife:///app/objectim SLapp
std::string url = LLSLURL("objectim", chat.mFromID, "").getSLURLString();
url += "?name=" + chat.mFromName;
url += "&owner=" + args["owner_id"].asString();
url += "&owner=" + chat.mOwnerID.asString();
std::string slurl = args["slurl"].asString();
if (slurl.empty())

View File

@ -49,18 +49,6 @@ const LLSD REARRANGE = LLSD().with("rearrange", LLSD());
static const LLWearableItemNameComparator WEARABLE_NAME_COMPARATOR;
bool LLWearableItemNameComparator::doCompare(const LLPanelWearableListItem* wearable_item1, const LLPanelWearableListItem* wearable_item2) const
{
std::string name1 = wearable_item1->getItemName();
std::string name2 = wearable_item2->getItemName();
LLStringUtil::toUpper(name1);
LLStringUtil::toUpper(name2);
return name1 < name2;
}
LLCOFWearables::LLCOFWearables() : LLPanel(),
mAttachments(NULL),
mClothing(NULL),

View File

@ -33,59 +33,16 @@
#ifndef LL_LLCOFWEARABLES_H
#define LL_LLCOFWEARABLES_H
// llui
#include "llflatlistview.h"
#include "llpanel.h"
#include "llinventorymodel.h"
#include "llappearancemgr.h"
#include "llwearableitemslist.h"
class LLFlatListView;
/** Abstract comparator of wearable list items */
class LLWearableListItemComparator : public LLFlatListView::ItemComparator
{
LOG_CLASS(LLWearableListItemComparator);
public:
LLWearableListItemComparator() {};
virtual ~LLWearableListItemComparator() {};
virtual bool compare(const LLPanel* item1, const LLPanel* item2) const
{
const LLPanelWearableListItem* wearable_item1 = dynamic_cast<const LLPanelWearableListItem*>(item1);
const LLPanelWearableListItem* wearable_item2 = dynamic_cast<const LLPanelWearableListItem*>(item2);
if (!wearable_item1 || !wearable_item2)
{
llwarning("item1 and item2 cannot be null", 0);
return true;
}
return doCompare(wearable_item1, wearable_item2);
}
protected:
/**
* Returns true if wearable_item1 < wearable_item2, false otherwise
* Implement this method in your particular comparator.
*/
virtual bool doCompare(const LLPanelWearableListItem* wearable_item1, const LLPanelWearableListItem* wearable_item2) const = 0;
};
class LLWearableItemNameComparator : public LLWearableListItemComparator
{
LOG_CLASS(LLWearableItemNameComparator);
public:
LLWearableItemNameComparator() {};
virtual ~LLWearableItemNameComparator() {};
protected:
virtual bool doCompare(const LLPanelWearableListItem* wearable_item1, const LLPanelWearableListItem* wearable_item2) const;
};
#include "llinventorymodel.h"
class LLPanelClothingListItem;
class LLPanelBodyPartsListItem;
class LLPanelDeletableWearableListItem;
/**
* Adaptor between LLAccordionCtrlTab and LLFlatListView to facilitate communication between them

View File

@ -113,9 +113,12 @@ void LLDrawPoolTree::render(S32 pass)
iter != mDrawFace.end(); iter++)
{
LLFace *face = *iter;
face->mVertexBuffer->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
face->mVertexBuffer->drawRange(LLRender::TRIANGLES, 0, face->mVertexBuffer->getRequestedVerts()-1, face->mVertexBuffer->getRequestedIndices(), 0);
gPipeline.addTrianglesDrawn(face->mVertexBuffer->getRequestedIndices());
if(face->mVertexBuffer.notNull())
{
face->mVertexBuffer->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
face->mVertexBuffer->drawRange(LLRender::TRIANGLES, 0, face->mVertexBuffer->getRequestedVerts()-1, face->mVertexBuffer->getRequestedIndices(), 0);
gPipeline.addTrianglesDrawn(face->mVertexBuffer->getRequestedIndices());
}
}
}
}
@ -333,7 +336,7 @@ void LLDrawPoolTree::renderTree(BOOL selecting)
S32 stop_depth = 0;
F32 app_angle = treep->getAppAngle()*LLVOTree::sTreeFactor;
F32 alpha = 1.0;
S32 trunk_LOD = 0;
S32 trunk_LOD = LLVOTree::sMAX_NUM_TREE_LOD_LEVELS;
for (S32 j = 0; j < 4; j++)
{
@ -344,6 +347,10 @@ void LLDrawPoolTree::renderTree(BOOL selecting)
break;
}
}
if(trunk_LOD >= LLVOTree::sMAX_NUM_TREE_LOD_LEVELS)
{
continue ; //do not render.
}
if (app_angle < (THRESH_ANGLE_FOR_BILLBOARD - BLEND_RANGE_FOR_BILLBOARD))
{

View File

@ -1376,9 +1376,18 @@ F32 LLFace::getTextureVirtualSize()
texel_area = 1.f;
}
//apply texel area to face area to get accurate ratio
//face_area /= llclamp(texel_area, 1.f/64.f, 16.f);
F32 face_area = mPixelArea / llclamp(texel_area, 0.015625f, 128.f);
F32 face_area;
if (mVObjp->isSculpted() && texel_area > 1.f)
{
//sculpts can break assumptions about texel area
face_area = mPixelArea;
}
else
{
//apply texel area to face area to get accurate ratio
//face_area /= llclamp(texel_area, 1.f/64.f, 16.f);
face_area = mPixelArea / llclamp(texel_area, 0.015625f, 128.f);
}
if(face_area > LLViewerTexture::sMaxSmallImageSize)
{

View File

@ -37,23 +37,21 @@
#include "llinventoryitemslist.h"
#include "llinventorymodel.h"
class LLFindItemsByMask : public LLInventoryCollectFunctor
class LLFindNonLinksByMask : public LLInventoryCollectFunctor
{
public:
LLFindItemsByMask(U64 mask)
LLFindNonLinksByMask(U64 mask)
: mFilterMask(mask)
{}
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
if(item)
if(item && !item->getIsLinkType() && (mFilterMask & (1LL << item->getInventoryType())) )
{
if( mFilterMask & (1LL << item->getInventoryType()) )
{
return TRUE;
}
return true;
}
return FALSE;
return false;
}
private:
@ -96,7 +94,7 @@ void LLFilteredWearableListManager::populateList()
{
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
LLFindItemsByMask collector(mFilterMask);
LLFindNonLinksByMask collector(mFilterMask);
gInventory.collectDescendentsIf(
gInventory.getRootFolderID(),

View File

@ -36,7 +36,7 @@
class LLInventoryItemsList;
// Class that fills LLInventoryItemsList with filtered data.
// Class that fills LLInventoryItemsList with filtered data (original items only (non-links)).
class LLFilteredWearableListManager : public LLInventoryObserver
{
LOG_CLASS(LLFilteredWearableListManager);

View File

@ -323,6 +323,18 @@ void LLFloaterAvatarPicker::populateFriend()
void LLFloaterAvatarPicker::draw()
{
// sometimes it is hard to determine when Select/Ok button should be disabled (see LLAvatarActions::shareWithAvatars).
// lets check this via mOkButtonValidateSignal callback periodically.
static LLFrameTimer timer;
if (timer.hasExpired())
{
timer.setTimerExpirySec(0.33f); // three times per second should be enough.
// simulate list changes.
onList();
timer.start();
}
LLFloater::draw();
if (!mNearMeListComplete && childGetVisibleTab("ResidentChooserTabs") == getChild<LLPanel>("NearMePanel"))
{

View File

@ -0,0 +1,119 @@
/**
* @file llfloaterbuycurrencyhtml.cpp
* @brief buy currency implemented in HTML floater - uses embedded media browser control
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2006-2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterbuycurrencyhtml.h"
#include "llstatusbar.h"
////////////////////////////////////////////////////////////////////////////////
//
LLFloaterBuyCurrencyHTML::LLFloaterBuyCurrencyHTML( const LLSD& key ):
LLFloater( key ),
mSpecificSumRequested( false ),
mMessage( "" ),
mSum( 0 )
{
}
////////////////////////////////////////////////////////////////////////////////
//
BOOL LLFloaterBuyCurrencyHTML::postBuild()
{
// observer media events
mBrowser = getChild<LLMediaCtrl>( "browser" );
mBrowser->addObserver( this );
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////
//
void LLFloaterBuyCurrencyHTML::navigateToFinalURL()
{
// URL for actual currency buy contents is in XUI file
std::string buy_currency_url = getString( "buy_currency_url" );
// replace [LANGUAGE] meta-tag with view language
LLStringUtil::format_map_t replace;
// viewer language
replace[ "[LANGUAGE]" ] = LLUI::getLanguage();
// flag that specific amount requested
replace[ "[SPECIFIC_AMOUNT]" ] = ( mSpecificSumRequested ? "y":"n" );
// amount requested
std::ostringstream codec( "" );
codec << mSum;
replace[ "[SUM]" ] = codec.str();
// users' current balance
codec.clear();
codec.str( "" );
codec << gStatusBar->getBalance();
replace[ "[BAL]" ] = codec.str();
// message - "This cost L$x,xxx for example
replace[ "[MSG]" ] = LLURI::escape( mMessage );
LLStringUtil::format( buy_currency_url, replace );
// kick off the navigation
mBrowser->navigateTo( buy_currency_url );
}
////////////////////////////////////////////////////////////////////////////////
//
void LLFloaterBuyCurrencyHTML::handleMediaEvent( LLPluginClassMedia* self, EMediaEvent event )
{
// placeholder for now - just in case we want to catch media events
if ( LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_COMPLETE == event )
{
};
}
////////////////////////////////////////////////////////////////////////////////
//
void LLFloaterBuyCurrencyHTML::onClose( bool app_quitting )
{
destroy();
}
////////////////////////////////////////////////////////////////////////////////
//
void LLFloaterBuyCurrencyHTML::setParams( bool specific_sum_requested, const std::string& message, S32 sum )
{
// save these away - used to construct URL later
mSpecificSumRequested = specific_sum_requested;
mMessage = message;
mSum = sum;
}

View File

@ -0,0 +1,65 @@
/**
* @file llfloaterbuycurrencyhtml.h
* @brief buy currency implemented in HTML floater - uses embedded media browser control
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2006-2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERBUYCURRENCYHTML_H
#define LL_LLFLOATERBUYCURRENCYHTML_H
#include "llfloater.h"
#include "llmediactrl.h"
class LLFloaterBuyCurrencyHTML :
public LLFloater,
public LLViewerMediaObserver
{
public:
LLFloaterBuyCurrencyHTML( const LLSD& key );
/*virtual*/ BOOL postBuild();
/*virtual*/ void onClose( bool app_quitting );
// inherited from LLViewerMediaObserver
/*virtual*/ void handleMediaEvent( LLPluginClassMedia* self, EMediaEvent event );
// allow our controlling parent to tell us paramters
void setParams( bool specific_sum_requested, const std::string& message, S32 sum );
// parse and construct URL and set browser to navigate there.
void navigateToFinalURL();
private:
LLMediaCtrl* mBrowser;
bool mSpecificSumRequested;
std::string mMessage;
S32 mSum;
};
#endif // LL_LLFLOATERBUYCURRENCYHTML_H

View File

@ -1156,7 +1156,7 @@ void LLPanelObjectTools::callbackAvatarID(const uuid_vec_t& ids, const std::vect
{
if (ids.empty() || names.empty()) return;
mTargetAvatar = ids[0];
childSetValue("target_avatar_name", names[0].getNameAndSLID());
childSetValue("target_avatar_name", names[0].getCompleteName());
refresh();
}

View File

@ -79,9 +79,6 @@ BOOL LLFloaterHUD::postBuild()
mWebBrowser = getChild<LLMediaCtrl>("floater_hud_browser" );
if (mWebBrowser)
{
// Open links in internal browser
mWebBrowser->setOpenInExternalBrowser(false);
// This is a "chrome" floater, so we don't want anything to
// take focus (as the user needs to be able to walk with
// arrow keys during tutorial).

View File

@ -646,9 +646,12 @@ void LLPanelLandGeneral::refresh()
}
// Display claim date
// *TODO:Localize (Time format may need Translating)
time_t claim_date = parcel->getClaimDate();
mTextClaimDate->setText(formatted_time(claim_date));
std::string claim_date_str = getString("time_stamp_template");
LLSD substitution;
substitution["datetime"] = (S32) claim_date;
LLStringUtil::format (claim_date_str, substitution);
mTextClaimDate->setText(claim_date_str);
mTextClaimDate->setEnabled(is_leased);
BOOL enable_auction = (gAgent.getGodLevel() >= GOD_LIAISON)
@ -1607,7 +1610,7 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo
// Placeholder for name.
LLAvatarName av_name;
LLAvatarNameCache::get(owner_id, &av_name);
item_params.columns.add().value(av_name.getNameAndSLID()).font(FONT).column("name");
item_params.columns.add().value(av_name.getCompleteName()).font(FONT).column("name");
object_count_str = llformat("%d", object_count);
item_params.columns.add().value(object_count_str).font(FONT).column("count");

View File

@ -184,7 +184,7 @@ BOOL LLFloaterNotificationConsole::postBuild()
addChannel("Ignore");
addChannel("Visible", true);
// all the ones below attach to the Visible channel
addChannel("History");
addChannel("Persistent");
addChannel("Alerts");
addChannel("AlertModal");
addChannel("Group Notifications");

View File

@ -230,6 +230,7 @@ void handleNameTagOptionChanged(const LLSD& newvalue)
void handleDisplayNamesOptionChanged(const LLSD& newvalue)
{
LLAvatarNameCache::setUseDisplayNames(newvalue.asBoolean());
LLVOAvatar::invalidateNameTags();
}

View File

@ -853,7 +853,7 @@ void LLPanelRegionDebugInfo::callbackAvatarID(const uuid_vec_t& ids, const std::
{
if (ids.empty() || names.empty()) return;
mTargetAvatar = ids[0];
childSetValue("target_avatar_name", names[0].getNameAndSLID());
childSetValue("target_avatar_name", names[0].getCompleteName());
refreshFromRegion( gAgent.getRegion() );
}

View File

@ -299,7 +299,7 @@ void LLFloaterReporter::callbackAvatarID(const uuid_vec_t& ids, const std::vecto
{
if (ids.empty() || names.empty()) return;
childSetText("abuser_name_edit", names[0].getNameAndSLID());
childSetText("abuser_name_edit", names[0].getCompleteName());
mAbuserID = ids[0];
@ -320,10 +320,10 @@ void LLFloaterReporter::onAvatarNameCache(const LLUUID& avatar_id, const LLAvata
{
if (mObjectID == avatar_id)
{
mOwnerName = av_name.getNameAndSLID();
childSetText("object_name", av_name.getNameAndSLID());
childSetToolTip("object_name", av_name.getNameAndSLID());
childSetText("abuser_name_edit", av_name.getNameAndSLID());
mOwnerName = av_name.getCompleteName();
childSetText("object_name", av_name.getCompleteName());
childSetToolTip("object_name", av_name.getCompleteName());
childSetText("abuser_name_edit", av_name.getCompleteName());
}
}

View File

@ -242,7 +242,7 @@ void LLFloaterSellLandUI::updateParcelInfo()
void LLFloaterSellLandUI::onBuyerNameCache(const LLAvatarName& av_name)
{
childSetText("sell_to_agent", av_name.getNameAndSLID());
childSetText("sell_to_agent", av_name.getCompleteName());
childSetToolTip("sell_to_agent", av_name.mUsername);
}
@ -412,7 +412,7 @@ void LLFloaterSellLandUI::callbackAvatarPick(const uuid_vec_t& ids, const std::v
mAuthorizedBuyer = ids[0];
childSetText("sell_to_agent", names[0].getNameAndSLID());
childSetText("sell_to_agent", names[0].getCompleteName());
refreshUI();
}

View File

@ -237,6 +237,7 @@ BOOL LLFloaterTools::postBuild()
childSetValue("checkbox stretch textures",(BOOL)gSavedSettings.getBOOL("ScaleStretchTextures"));
mTextGridMode = getChild<LLTextBox>("text ruler mode");
mComboGridMode = getChild<LLComboBox>("combobox grid mode");
mCheckStretchUniformLabel = getChild<LLTextBox>("checkbox uniform label");
//
// Create Buttons
@ -316,6 +317,7 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mComboGridMode(NULL),
mCheckStretchUniform(NULL),
mCheckStretchTexture(NULL),
mCheckStretchUniformLabel(NULL),
mBtnRotateLeft(NULL),
mBtnRotateReset(NULL),
@ -632,6 +634,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
//mCheckSelectLinked ->setVisible( edit_visible );
if (mCheckStretchUniform) mCheckStretchUniform->setVisible( edit_visible );
if (mCheckStretchTexture) mCheckStretchTexture->setVisible( edit_visible );
if (mCheckStretchUniformLabel) mCheckStretchUniformLabel->setVisible( edit_visible );
// Create buttons
BOOL create_visible = (tool == LLToolCompCreate::getInstance());

View File

@ -149,6 +149,10 @@ public:
LLCheckBoxCtrl* mCheckStretchUniform;
LLCheckBoxCtrl* mCheckStretchTexture;
// !HACK! Replacement of mCheckStretchUniform label because LLCheckBoxCtrl
// doesn't support word_wrap of its label. Need to fix truncation bug EXT-6658
LLTextBox* mCheckStretchUniformLabel;
LLButton *mBtnRotateLeft;
LLButton *mBtnRotateReset;
LLButton *mBtnRotateRight;

View File

@ -0,0 +1,541 @@
/**
* @file llgiveinventory.cpp
* @brief LLGiveInventory class implementation
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llgiveinventory.h"
// library includes
#include "llnotificationsutil.h"
#include "lltrans.h"
// newview includes
#include "llagent.h"
#include "llagentdata.h"
#include "llagentui.h"
#include "llagentwearables.h"
#include "llfloatertools.h" // for gFloaterTool
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
#include "llimview.h"
#include "llinventory.h"
#include "llinventoryfunctions.h"
#include "llmutelist.h"
#include "llrecentpeople.h"
#include "llviewerobjectlist.h"
#include "llvoavatarself.h"
// MAX ITEMS is based on (sizeof(uuid)+2) * count must be < MTUBYTES
// or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a
// bit from there to give some pad.
const S32 MAX_ITEMS = 42;
class LLGiveable : public LLInventoryCollectFunctor
{
public:
LLGiveable() : mCountLosing(0) {}
virtual ~LLGiveable() {}
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item);
S32 countNoCopy() const { return mCountLosing; }
protected:
S32 mCountLosing;
};
bool LLGiveable::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
// All categories can be given.
if (cat)
return true;
bool allowed = false;
if (item)
{
allowed = itemTransferCommonlyAllowed(item);
if (allowed &&
!item->getPermissions().allowOperationBy(PERM_TRANSFER,
gAgent.getID()))
{
allowed = FALSE;
}
if (allowed &&
!item->getPermissions().allowCopyBy(gAgent.getID()))
{
++mCountLosing;
}
}
return allowed;
}
class LLUncopyableItems : public LLInventoryCollectFunctor
{
public:
LLUncopyableItems() {}
virtual ~LLUncopyableItems() {}
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item);
};
bool LLUncopyableItems::operator()(LLInventoryCategory* cat,
LLInventoryItem* item)
{
bool uncopyable = false;
if (item)
{
if (itemTransferCommonlyAllowed(item) &&
!item->getPermissions().allowCopyBy(gAgent.getID()))
{
uncopyable = true;
}
}
return uncopyable;
}
// static
bool LLGiveInventory::isInventoryGiveAcceptable(const LLInventoryItem* item)
{
if (!item) return false;
if (!isAgentAvatarValid()) return false;
if (!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID))
{
return false;
}
bool acceptable = true;
switch(item->getType())
{
case LLAssetType::AT_OBJECT:
if (gAgentAvatarp->isWearingAttachment(item->getUUID()))
{
acceptable = false;
}
break;
case LLAssetType::AT_BODYPART:
case LLAssetType::AT_CLOTHING:
{
BOOL copyable = false;
if (item->getPermissions().allowCopyBy(gAgentID)) copyable = true;
if (!copyable && gAgentWearables.isWearingItem(item->getUUID()))
{
acceptable = false;
}
}
break;
default:
break;
}
return acceptable;
}
// static
bool LLGiveInventory::isInventoryGroupGiveAcceptable(const LLInventoryItem* item)
{
if (!item) return false;
if (!isAgentAvatarValid()) return false;
// These permissions are double checked in the simulator in
// LLGroupNoticeInventoryItemFetch::result().
if (!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID))
{
return false;
}
if (!item->getPermissions().allowCopyBy(gAgent.getID()))
{
return false;
}
bool acceptable = true;
switch(item->getType())
{
case LLAssetType::AT_OBJECT:
if (gAgentAvatarp->isWearingAttachment(item->getUUID()))
{
acceptable = false;
}
break;
default:
break;
}
return acceptable;
}
// static
void LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent,
const LLInventoryItem* item,
const LLUUID& im_session_id/* = LLUUID::null*/)
{
llinfos << "LLGiveInventory::giveInventory()" << llendl;
if (!isInventoryGiveAcceptable(item))
{
return;
}
if (item->getPermissions().allowCopyBy(gAgentID))
{
// just give it away.
LLGiveInventory::commitGiveInventoryItem(to_agent, item, im_session_id);
}
else
{
// ask if the agent is sure.
LLSD payload;
payload["agent_id"] = to_agent;
payload["item_id"] = item->getUUID();
LLNotificationsUtil::add("CannotCopyWarning", LLSD(), payload,
&LLGiveInventory::handleCopyProtectedItem);
}
}
void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
const LLInventoryCategory* cat,
const LLUUID& im_session_id)
{
if (!cat) return;
llinfos << "LLGiveInventory::giveInventoryCategory() - "
<< cat->getUUID() << llendl;
if (!isAgentAvatarValid()) return;
// Test out how many items are being given.
LLViewerInventoryCategory::cat_array_t cats;
LLViewerInventoryItem::item_array_t items;
LLGiveable giveable;
gInventory.collectDescendentsIf (cat->getUUID(),
cats,
items,
LLInventoryModel::EXCLUDE_TRASH,
giveable);
S32 count = cats.count();
bool complete = true;
for(S32 i = 0; i < count; ++i)
{
if (!gInventory.isCategoryComplete(cats.get(i)->getUUID()))
{
complete = false;
break;
}
}
if (!complete)
{
LLNotificationsUtil::add("IncompleteInventory");
return;
}
count = items.count() + cats.count();
if (count > MAX_ITEMS)
{
LLNotificationsUtil::add("TooManyItems");
return;
}
else if (count == 0)
{
LLNotificationsUtil::add("NoItems");
return;
}
else
{
if (0 == giveable.countNoCopy())
{
LLGiveInventory::commitGiveInventoryCategory(to_agent, cat, im_session_id);
}
else
{
LLSD args;
args["COUNT"] = llformat("%d",giveable.countNoCopy());
LLSD payload;
payload["agent_id"] = to_agent;
payload["folder_id"] = cat->getUUID();
LLNotificationsUtil::add("CannotCopyCountItems", args, payload, &LLGiveInventory::handleCopyProtectedCategory);
}
}
}
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//static
void LLGiveInventory::logInventoryOffer(const LLUUID& to_agent, const LLUUID &im_session_id)
{
// compute id of possible IM session with agent that has "to_agent" id
LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, to_agent);
// If this item was given by drag-and-drop into an IM panel, log this action in the IM panel chat.
if (im_session_id.notNull())
{
LLSD args;
gIMMgr->addSystemMessage(im_session_id, "inventory_item_offered", args);
}
// If this item was given by drag-and-drop on avatar while IM panel was open, log this action in the IM panel chat.
else if (LLIMModel::getInstance()->findIMSession(session_id))
{
LLSD args;
gIMMgr->addSystemMessage(session_id, "inventory_item_offered", args);
}
// If this item was given by drag-and-drop on avatar while IM panel wasn't open, log this action to IM history.
else
{
std::string full_name;
if (gCacheName->getFullName(to_agent, full_name))
{
LLIMModel::instance().logToFile(full_name, LLTrans::getString("SECOND_LIFE"), im_session_id, LLTrans::getString("inventory_item_offered-im"));
}
}
}
// static
bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
LLInventoryItem* item = NULL;
switch(option)
{
case 0: // "Yes"
item = gInventory.getItem(notification["payload"]["item_id"].asUUID());
if (item)
{
LLGiveInventory::commitGiveInventoryItem(notification["payload"]["agent_id"].asUUID(),
item);
// delete it for now - it will be deleted on the server
// quickly enough.
gInventory.deleteObject(notification["payload"]["item_id"].asUUID());
gInventory.notifyObservers();
}
else
{
LLNotificationsUtil::add("CannotGiveItem");
}
break;
default: // no, cancel, whatever, who cares, not yes.
LLNotificationsUtil::add("TransactionCancelled");
break;
}
return false;
}
// static
void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent,
const LLInventoryItem* item,
const LLUUID& im_session_id)
{
if (!item) return;
std::string name;
LLAgentUI::buildFullname(name);
LLUUID transaction_id;
transaction_id.generate();
const S32 BUCKET_SIZE = sizeof(U8) + UUID_BYTES;
U8 bucket[BUCKET_SIZE];
bucket[0] = (U8)item->getType();
memcpy(&bucket[1], &(item->getUUID().mData), UUID_BYTES); /* Flawfinder: ignore */
pack_instant_message(
gMessageSystem,
gAgentID,
FALSE,
gAgentSessionID,
to_agent,
name,
item->getName(),
IM_ONLINE,
IM_INVENTORY_OFFERED,
transaction_id,
0,
LLUUID::null,
gAgent.getPositionAgent(),
NO_TIMESTAMP,
bucket,
BUCKET_SIZE);
gAgent.sendReliableMessage();
// VEFFECT: giveInventory
LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
effectp->setSourceObject(gAgentAvatarp);
effectp->setTargetObject(gObjectList.findObject(to_agent));
effectp->setDuration(LL_HUD_DUR_SHORT);
effectp->setColor(LLColor4U(gAgent.getEffectColor()));
gFloaterTools->dirty();
LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY);
logInventoryOffer(to_agent, im_session_id);
// add buddy to recent people list
LLRecentPeople::instance().add(to_agent);
}
// static
bool LLGiveInventory::handleCopyProtectedCategory(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
LLInventoryCategory* cat = NULL;
switch(option)
{
case 0: // "Yes"
cat = gInventory.getCategory(notification["payload"]["folder_id"].asUUID());
if (cat)
{
LLGiveInventory::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(),
cat);
LLViewerInventoryCategory::cat_array_t cats;
LLViewerInventoryItem::item_array_t items;
LLUncopyableItems remove;
gInventory.collectDescendentsIf (cat->getUUID(),
cats,
items,
LLInventoryModel::EXCLUDE_TRASH,
remove);
S32 count = items.count();
for(S32 i = 0; i < count; ++i)
{
gInventory.deleteObject(items.get(i)->getUUID());
}
gInventory.notifyObservers();
}
else
{
LLNotificationsUtil::add("CannotGiveCategory");
}
break;
default: // no, cancel, whatever, who cares, not yes.
LLNotificationsUtil::add("TransactionCancelled");
break;
}
return false;
}
// static
void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
const LLInventoryCategory* cat,
const LLUUID& im_session_id)
{
if (!cat) return;
llinfos << "LLGiveInventory::commitGiveInventoryCategory() - "
<< cat->getUUID() << llendl;
// add buddy to recent people list
LLRecentPeople::instance().add(to_agent);
// Test out how many items are being given.
LLViewerInventoryCategory::cat_array_t cats;
LLViewerInventoryItem::item_array_t items;
LLGiveable giveable;
gInventory.collectDescendentsIf (cat->getUUID(),
cats,
items,
LLInventoryModel::EXCLUDE_TRASH,
giveable);
// MAX ITEMS is based on (sizeof(uuid)+2) * count must be <
// MTUBYTES or 18 * count < 1200 => count < 1200/18 =>
// 66. I've cut it down a bit from there to give some pad.
S32 count = items.count() + cats.count();
if (count > MAX_ITEMS)
{
LLNotificationsUtil::add("TooManyItems");
return;
}
else if (count == 0)
{
LLNotificationsUtil::add("NoItems");
return;
}
else
{
std::string name;
LLAgentUI::buildFullname(name);
LLUUID transaction_id;
transaction_id.generate();
S32 bucket_size = (sizeof(U8) + UUID_BYTES) * (count + 1);
U8* bucket = new U8[bucket_size];
U8* pos = bucket;
U8 type = (U8)cat->getType();
memcpy(pos, &type, sizeof(U8)); /* Flawfinder: ignore */
pos += sizeof(U8);
memcpy(pos, &(cat->getUUID()), UUID_BYTES); /* Flawfinder: ignore */
pos += UUID_BYTES;
S32 i;
count = cats.count();
for(i = 0; i < count; ++i)
{
memcpy(pos, &type, sizeof(U8)); /* Flawfinder: ignore */
pos += sizeof(U8);
memcpy(pos, &(cats.get(i)->getUUID()), UUID_BYTES); /* Flawfinder: ignore */
pos += UUID_BYTES;
}
count = items.count();
for(i = 0; i < count; ++i)
{
type = (U8)items.get(i)->getType();
memcpy(pos, &type, sizeof(U8)); /* Flawfinder: ignore */
pos += sizeof(U8);
memcpy(pos, &(items.get(i)->getUUID()), UUID_BYTES); /* Flawfinder: ignore */
pos += UUID_BYTES;
}
pack_instant_message(
gMessageSystem,
gAgent.getID(),
FALSE,
gAgent.getSessionID(),
to_agent,
name,
cat->getName(),
IM_ONLINE,
IM_INVENTORY_OFFERED,
transaction_id,
0,
LLUUID::null,
gAgent.getPositionAgent(),
NO_TIMESTAMP,
bucket,
bucket_size);
gAgent.sendReliableMessage();
delete[] bucket;
// VEFFECT: giveInventoryCategory
LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
effectp->setSourceObject(gAgentAvatarp);
effectp->setTargetObject(gObjectList.findObject(to_agent));
effectp->setDuration(LL_HUD_DUR_SHORT);
effectp->setColor(LLColor4U(gAgent.getEffectColor()));
gFloaterTools->dirty();
LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY);
logInventoryOffer(to_agent, im_session_id);
}
}
// EOF

View File

@ -0,0 +1,99 @@
/**
* @file llgiveinventory.cpp
* @brief LLGiveInventory class declaration
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLGIVEINVENTORY_H
#define LL_LLGIVEINVENTORY_H
class LLInventoryItem;
class LLInventoryCategory;
/**
* Class represented give inventory related actions.
*
* It has only static methods and is not intended to be instantiated for now.
*/
class LLGiveInventory
{
public:
/**
* Checks if inventory item you are attempting to transfer to a resident can be given.
*
* @return true if you can give, otherwise false.
*/
static bool isInventoryGiveAcceptable(const LLInventoryItem* item);
/**
* Checks if inventory item you are attempting to transfer to a group can be given.
*
* @return true if you can give, otherwise false.
*/
static bool isInventoryGroupGiveAcceptable(const LLInventoryItem* item);
/**
* Gives passed inventory item to specified avatar in specified session.
*/
static void doGiveInventoryItem(const LLUUID& to_agent,
const LLInventoryItem* item,
const LLUUID& im_session_id = LLUUID::null);
/**
* Gives passed inventory category to specified avatar in specified session.
*/
static void doGiveInventoryCategory(const LLUUID& to_agent,
const LLInventoryCategory* item,
const LLUUID &session_id = LLUUID::null);
private:
// this class is not intended to be instantiated.
LLGiveInventory();
/**
* logs "Inventory item offered" to IM
*/
static void logInventoryOffer(const LLUUID& to_agent,
const LLUUID &im_session_id = LLUUID::null);
// give inventory item functionality
static bool handleCopyProtectedItem(const LLSD& notification, const LLSD& response);
static void commitGiveInventoryItem(const LLUUID& to_agent,
const LLInventoryItem* item,
const LLUUID &im_session_id = LLUUID::null);
// give inventory category functionality
static bool handleCopyProtectedCategory(const LLSD& notification, const LLSD& response);
static void commitGiveInventoryCategory(const LLUUID& to_agent,
const LLInventoryCategory* cat,
const LLUUID &im_session_id = LLUUID::null);
};
#endif // LL_LLGIVEINVENTORY_H

View File

@ -331,7 +331,7 @@ void LLIMFloater::onAvatarNameCache(const LLUUID& agent_id,
{
// Use display name only for labels, as the extended name will be in the
// floater title
std::string ui_title = av_name.getNameAndSLID();
std::string ui_title = av_name.getCompleteName();
updateSessionName(ui_title, av_name.mDisplayName);
}

View File

@ -270,7 +270,7 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
// no text notifications
break;
case P2P_SESSION:
gCacheName->getFullName(mOtherParticipantID, other_avatar_name);
gCacheName->getFullName(mOtherParticipantID, other_avatar_name); // voice
if(direction == LLVoiceChannel::INCOMING_CALL)
{
@ -405,13 +405,17 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo
const LLSD& msg = *it;
std::string from = msg[IM_FROM];
LLUUID from_id = LLUUID::null;
if (msg[IM_FROM_ID].isUndefined())
LLUUID from_id;
if (msg[IM_FROM_ID].isDefined())
{
from_id = msg[IM_FROM_ID].asUUID();
}
else
{
// Legacy chat logs only wrote the legacy name, not the agent_id
gCacheName->getUUID(from, from_id);
}
std::string timestamp = msg[IM_TIME];
std::string text = msg[IM_TEXT];
@ -1968,7 +1972,7 @@ void LLIncomingCallDialog::onAvatarNameCache(const LLUUID& agent_id,
const LLAvatarName& av_name,
const std::string& call_type)
{
std::string title = av_name.getNameAndSLID();
std::string title = av_name.getCompleteName();
setCallerName(title, av_name.mDisplayName, call_type);
}
@ -2582,7 +2586,7 @@ void LLIMMgr::inviteToSession(
{
if (caller_name.empty())
{
gCacheName->get(caller_id, false,
gCacheName->get(caller_id, false, // voice
boost::bind(&LLIMMgr::onInviteNameLookup, payload, _1, _2, _3));
}
else
@ -2816,12 +2820,14 @@ void LLIMMgr::noteOfflineUsers(
for(S32 i = 0; i < count; ++i)
{
info = at.getBuddyInfo(ids.get(i));
std::string full_name;
if(info && !info->isOnline()
&& gCacheName->getFullName(ids.get(i), full_name))
LLAvatarName av_name;
if (info
&& !info->isOnline()
&& LLAvatarNameCache::get(ids.get(i), &av_name))
{
LLUIString offline = LLTrans::getString("offline_message");
offline.setArg("[NAME]", full_name);
// Use display name only because this user is your friend
offline.setArg("[NAME]", av_name.mDisplayName);
im_model.proccessOnlineOfflineNotification(session_id, offline);
}
}

View File

@ -709,7 +709,7 @@ void LLInspectAvatar::onToggleMute()
void LLInspectAvatar::onClickReport()
{
LLFloaterReporter::showFromAvatar(mAvatarID, mAvatarName.getNameAndSLID());
LLFloaterReporter::showFromAvatar(mAvatarID, mAvatarName.getCompleteName());
closeFloater();
}

View File

@ -224,7 +224,7 @@ void LLInspectGroup::requestUpdate()
mPropertiesRequest = new LLFetchGroupData(mGroupID, this);
// Name lookup will be faster out of cache, use that
gCacheName->get(mGroupID, true,
gCacheName->getGroup(mGroupID,
boost::bind(&LLInspectGroup::nameUpdatedCallback,
this, _1, _2, _3));
}

View File

@ -48,6 +48,7 @@
#include "llfloaterworldmap.h"
#include "llfriendcard.h"
#include "llgesturemgr.h"
#include "llgiveinventory.h"
#include "llimfloater.h"
#include "llimview.h"
#include "llinventoryclipboard.h"
@ -1017,11 +1018,7 @@ BOOL LLInvFVBridge::canShare() const
{
if (!LLInventoryCollectFunctor::itemTransferCommonlyAllowed(item))
return FALSE;
if (!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
return FALSE;
if (!item->getPermissions().allowCopyBy(gAgent.getID()))
return FALSE;
return TRUE;
return (BOOL)LLGiveInventory::isInventoryGiveAcceptable(item);
}
// All categories can be given.
@ -3763,7 +3760,7 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,
rv = TRUE;
if(drop)
{
LLToolDragAndDrop::giveInventory(item->getCreatorUUID(),
LLGiveInventory::doGiveInventoryItem(item->getCreatorUUID(),
(LLInventoryItem*)cargo_data);
}
}
@ -3784,7 +3781,7 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,
rv = TRUE;
if(drop)
{
LLToolDragAndDrop::giveInventoryCategory(
LLGiveInventory::doGiveInventoryCategory(
item->getCreatorUUID(),
inv_cat);
}
@ -4988,18 +4985,20 @@ void LLWearableBridge::removeAllClothesFromAvatar()
if (itype == LLWearableType::WT_SHAPE || itype == LLWearableType::WT_SKIN || itype == LLWearableType::WT_HAIR || itype == LLWearableType::WT_EYES)
continue;
// MULTI-WEARABLES: fixed to index 0
LLViewerInventoryItem *item = dynamic_cast<LLViewerInventoryItem*>(
gAgentWearables.getWearableInventoryItem((LLWearableType::EType)itype, 0));
if (!item)
continue;
const LLUUID &item_id = gInventory.getLinkedItemID(item->getUUID());
const LLWearable *wearable = gAgentWearables.getWearableFromItemID(item_id);
if (!wearable)
continue;
// Find and remove this item from the COF.
LLAppearanceMgr::instance().removeCOFItemLinks(item_id,false);
for (S32 index = gAgentWearables.getWearableCount(itype)-1; index >= 0 ; --index)
{
LLViewerInventoryItem *item = dynamic_cast<LLViewerInventoryItem*>(
gAgentWearables.getWearableInventoryItem((LLWearableType::EType)itype, index));
if (!item)
continue;
const LLUUID &item_id = gInventory.getLinkedItemID(item->getUUID());
const LLWearable *wearable = gAgentWearables.getWearableFromItemID(item_id);
if (!wearable)
continue;
// Find and remove this item from the COF.
LLAppearanceMgr::instance().removeCOFItemLinks(item_id,false);
}
}
gInventory.notifyObservers();

View File

@ -336,7 +336,9 @@ LLInventoryItemsList::LLInventoryItemsList(const LLInventoryItemsList::Params& p
// virtual
LLInventoryItemsList::~LLInventoryItemsList()
{}
{
gIdleCallbacks.deleteFunction(idle, this);
}
void LLInventoryItemsList::refreshList(const LLInventoryModel::item_array_t item_array)
{

View File

@ -124,6 +124,15 @@ public:
/** Get the name of a corresponding inventory item */
const std::string& getItemName() const { return mItem->getName(); }
/** Get the asset type of a corresponding inventory item */
LLAssetType::EType getType() const { return mItem->getType(); }
/** Get the wearable type of a corresponding inventory item */
LLWearableType::EType getWearableType() const { return mItem->getWearableType(); }
/** Get the description of a corresponding inventory item */
const std::string& getDescription() const { return mItem->getDescription(); }
virtual ~LLPanelInventoryListItemBase(){}
protected:

View File

@ -1245,7 +1245,9 @@ void LLInventoryModel::addCategory(LLViewerInventoryCategory* category)
void LLInventoryModel::addItem(LLViewerInventoryItem* item)
{
//llinfos << "LLInventoryModel::addItem()" << llendl;
const LLViewerInventoryCategory* cat = gInventory.getCategory(item->getParentUUID()); // Seraph remove for 2.1
const std::string cat_name = cat ? cat->getName() : "CAT NOT FOUND"; // Seraph remove for 2.1
llinfos << "Added item [ name:" << item->getName() << " UUID:" << item->getUUID() << " type:" << item->getActualType() << " ] to folder [ name:" << cat_name << " uuid:" << item->getParentUUID() << " ]" << llendl; // Seraph remove for 2.1
llassert(item);
if(item)

View File

@ -426,6 +426,12 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
return;
}
if (im[IM_FROM_ID].isDefined())
{
LLUUID from_id = im[IM_FROM_ID].asUUID();
ostr << '{' << from_id.asString() << '}';
}
if (im[IM_TIME].isDefined())
{
std::string timestamp = im[IM_TIME].asString();
@ -456,15 +462,32 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
}
}
bool LLChatLogParser::parse(std::string& raw, LLSD& im)
bool LLChatLogParser::parse(const std::string& raw, LLSD& im)
{
if (!raw.length()) return false;
im = LLSD::emptyMap();
// In Viewer 2.1 we added UUID to chat/IM logging so we can look up
// display names
std::string line = raw;
if (raw[0] == '{')
{
const S32 UUID_LEN = 36;
size_t pos = line.find_first_of('}');
// If it matches, pos will be 37
if (pos != line.npos && pos > UUID_LEN)
{
std::string uuid_string = line.substr(1, UUID_LEN);
LLUUID from_id(uuid_string);
im[IM_FROM_ID] = from_id;
line = line.substr(pos + 1);
}
}
//matching a timestamp
boost::match_results<std::string::const_iterator> matches;
if (!boost::regex_match(raw, matches, TIMESTAMP_AND_STUFF)) return false;
if (!boost::regex_match(line, matches, TIMESTAMP_AND_STUFF)) return false;
bool has_timestamp = matches[IDX_TIMESTAMP].matched;
if (has_timestamp)

View File

@ -106,7 +106,7 @@ public:
*
* @return false if failed to parse mandatory data - message text
*/
static bool parse(std::string& raw, LLSD& im);
static bool parse(const std::string& raw, LLSD& im);
protected:
LLChatLogParser();

View File

@ -78,8 +78,6 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
mBorder(NULL),
mFrequentUpdates( true ),
mForceUpdate( false ),
mOpenLinksInExternalBrowser( false ),
mOpenLinksInInternalBrowser( false ),
mHomePageUrl( "" ),
mTrusted(false),
mIgnoreUIScale( true ),
@ -166,20 +164,6 @@ void LLMediaCtrl::setTakeFocusOnClick( bool take_focus )
mTakeFocusOnClick = take_focus;
}
////////////////////////////////////////////////////////////////////////////////
// set flag that forces the embedded browser to open links in the external system browser
void LLMediaCtrl::setOpenInExternalBrowser( bool valIn )
{
mOpenLinksInExternalBrowser = valIn;
};
////////////////////////////////////////////////////////////////////////////////
// set flag that forces the embedded browser to open links in the internal browser floater
void LLMediaCtrl::setOpenInInternalBrowser( bool valIn )
{
mOpenLinksInInternalBrowser = valIn;
};
////////////////////////////////////////////////////////////////////////////////
void LLMediaCtrl::setTrusted( bool valIn )
{
@ -944,7 +928,6 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
case MEDIA_EVENT_CLICK_LINK_HREF:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << self->getClickTarget() << "\", uri is " << self->getClickURL() << LL_ENDL;
onClickLinkHref(self);
};
break;
@ -977,95 +960,6 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
emitEvent(self, event);
}
////////////////////////////////////////////////////////////////////////////////
//
void LLMediaCtrl::onClickLinkHref( LLPluginClassMedia* self )
{
// retrieve the event parameters
std::string url = self->getClickURL();
U32 target_type = self->getClickTargetType();
// is there is a target specified for the link?
if (target_type == LLPluginClassMedia::TARGET_EXTERNAL ||
target_type == LLPluginClassMedia::TARGET_BLANK )
{
if (gSavedSettings.getBOOL("UseExternalBrowser"))
{
LLSD payload;
payload["url"] = url;
payload["target_type"] = LLSD::Integer(target_type);
LLNotificationsUtil::add( "WebLaunchExternalTarget", LLSD(), payload, onClickLinkExternalTarget);
}
else
{
clickLinkWithTarget(url, target_type);
}
}
else {
const std::string protocol1( "http://" );
const std::string protocol2( "https://" );
if( mOpenLinksInExternalBrowser )
{
if ( !url.empty() )
{
if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 ||
LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 )
{
LLWeb::loadURLExternal( url );
}
}
}
else
if( mOpenLinksInInternalBrowser )
{
if ( !url.empty() )
{
if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 ||
LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 )
{
llwarns << "Dead, unimplemented path that we used to send to the built-in browser long ago." << llendl;
}
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
// static
bool LLMediaCtrl::onClickLinkExternalTarget(const LLSD& notification, const LLSD& response )
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if ( 0 == option )
{
LLSD payload = notification["payload"];
std::string url = payload["url"].asString();
S32 target_type = payload["target_type"].asInteger();
clickLinkWithTarget(url, target_type);
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLMediaCtrl::clickLinkWithTarget(const std::string& url, const S32& target_type )
{
if (target_type == LLPluginClassMedia::TARGET_EXTERNAL)
{
// load target in an external browser
LLWeb::loadURLExternal(url);
}
else if (target_type == LLPluginClassMedia::TARGET_BLANK)
{
// load target in the user's preferred browser
LLWeb::loadURL(url);
}
else {
// unsupported link target - shouldn't happen
LL_WARNS("LinkTarget") << "Unsupported link target type" << LL_ENDL;
}
}
////////////////////////////////////////////////////////////////////////////////
//
std::string LLMediaCtrl::getCurrentNavUrl()

View File

@ -99,8 +99,6 @@ public:
void navigateToLocalPage( const std::string& subdir, const std::string& filename_in );
bool canNavigateBack();
bool canNavigateForward();
void setOpenInExternalBrowser( bool valIn );
void setOpenInInternalBrowser( bool valIn );
std::string getCurrentNavUrl();
// By default, we do not handle "secondlife:///app/" SLURLs, because
@ -162,24 +160,17 @@ public:
// Incoming media event dispatcher
virtual void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
// handlers for individual events (could be done inside the switch in handleMediaEvent, they're just individual functions for clarity)
void onClickLinkHref( LLPluginClassMedia* self );
protected:
void convertInputCoords(S32& x, S32& y);
private:
void onVisibilityChange ( const LLSD& new_visibility );
static bool onClickLinkExternalTarget( const LLSD&, const LLSD& );
static void clickLinkWithTarget(const std::string& url, const S32& target_type );
const S32 mTextureDepthBytes;
LLUUID mMediaTextureID;
LLViewBorder* mBorder;
bool mFrequentUpdates;
bool mForceUpdate;
bool mOpenLinksInExternalBrowser;
bool mOpenLinksInInternalBrowser;
bool mTrusted;
std::string mHomePageUrl;
std::string mCurrentNavUrl;

View File

@ -131,14 +131,7 @@ void LLMorphView::setVisible(BOOL visible)
if (visible)
{
llassert( !gFloaterCustomize );
gFloaterCustomize = new LLFloaterCustomize();
gFloaterCustomize->fetchInventory();
gFloaterCustomize->openFloater();
// Must do this _after_ gFloaterView is initialized.
gFloaterCustomize->switchToDefaultSubpart();
// TODO: verify some user action has already opened outfit editor? - Nyx
initialize();
// First run dialog
@ -146,13 +139,7 @@ void LLMorphView::setVisible(BOOL visible)
}
else
{
if( gFloaterCustomize )
{
gFloaterView->removeChild( gFloaterCustomize );
delete gFloaterCustomize;
gFloaterCustomize = NULL;
}
// TODO: verify some user action has already closed outfit editor ? - Nyx
shutdown();
}
}

View File

@ -306,7 +306,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
if (mShortNames)
fullname = av_name.mDisplayName;
else
fullname = av_name.getNameAndSLID();
fullname = av_name.getCompleteName();
}
else
{
@ -375,7 +375,7 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,
if (mShortNames)
name = av_name.mDisplayName;
else
name = av_name.getNameAndSLID();
name = av_name.getCompleteName();
item_list::iterator iter;
for (iter = getItemList().begin(); iter != getItemList().end(); iter++)

View File

@ -301,8 +301,12 @@ void LLNearbyChat::loadHistory()
const LLSD& msg = *it;
std::string from = msg[IM_FROM];
LLUUID from_id = LLUUID::null;
if (msg[IM_FROM_ID].isUndefined())
LLUUID from_id;
if (msg[IM_FROM_ID].isDefined())
{
from_id = msg[IM_FROM_ID].asUUID();
}
else
{
gCacheName->getUUID(from, from_id);
}

View File

@ -69,6 +69,33 @@ static LLChatTypeTrigger sChatTypeTriggers[] = {
{ "/shout" , CHAT_TYPE_SHOUT}
};
//ext-7367
//Problem: gesture list control (actually LLScrollListCtrl) didn't actually process mouse wheel message.
// introduce new gesture list subclass to "eat" mouse wheel messages (and probably some other messages)
class LLGestureScrollListCtrl: public LLScrollListCtrl
{
protected:
friend class LLUICtrlFactory;
LLGestureScrollListCtrl(const LLScrollListCtrl::Params& params)
:LLScrollListCtrl(params)
{
}
public:
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks)
{
LLScrollListCtrl::handleScrollWheel( x, y, clicks );
return TRUE;
}
//See EXT-6598
//Mouse hover over separator will result in not processing tooltip message
//So eat this message
BOOL handleToolTip(S32 x, S32 y, MASK mask)
{
LLScrollListCtrl::handleToolTip( x, y, mask );
return TRUE;
}
};
LLGestureComboList::Params::Params()
: combo_button("combo_button"),
combo_list("combo_list")
@ -90,13 +117,14 @@ LLGestureComboList::LLGestureComboList(const LLGestureComboList::Params& p)
addChild(mButton);
LLScrollListCtrl::Params params = p.combo_list;
LLGestureScrollListCtrl::Params params(p.combo_list);
params.name("GestureComboList");
params.commit_callback.function(boost::bind(&LLGestureComboList::onItemSelected, this, _2));
params.visible(false);
params.commit_on_keyboard_movement(false);
mList = LLUICtrlFactory::create<LLScrollListCtrl>(params);
mList = LLUICtrlFactory::create<LLGestureScrollListCtrl>(params);
addChild(mList);
//****************************Gesture Part********************************/

View File

@ -37,6 +37,7 @@
// Library includes (should move below)
#include "indra_constants.h"
#include "llavatarnamecache.h"
#include "llmath.h"
#include "llfloaterreg.h"
#include "llfocusmgr.h"
@ -555,11 +556,14 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask )
// mToolTipMsg = "[AGENT][REGION](Double-click to open Map)"
bool have_agent = false;
LLStringUtil::format_map_t args;
std::string fullname;
if(mClosestAgentToCursor.notNull() && gCacheName->getFullName(mClosestAgentToCursor, fullname))
LLAvatarName av_name;
if(mClosestAgentToCursor.notNull()
&& LLAvatarNameCache::get(mClosestAgentToCursor, &av_name))
{
args["[AGENT]"] = fullname + "\n";
args["[AGENT]"] = av_name.getCompleteName() + "\n";
have_agent = true;
}
else
{
@ -567,7 +571,7 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask )
}
LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) );
if( region )
if( region && !have_agent)
{
args["[REGION]"] = region->getName() + "\n";
}

View File

@ -57,6 +57,8 @@
#include "lltextureentry.h"
#include "llviewercontrol.h" // gSavedSettings
#include "llviewertexturelist.h"
#include "llagentcamera.h"
#include "llmorphview.h"
// register panel with appropriate XML
static LLRegisterPanelClassWrapper<LLPanelEditWearable> t_edit_wearable("panel_edit_wearable");
@ -227,7 +229,7 @@ LLEditWearableDictionary::Wearables::Wearables()
addEntry(LLWearableType::WT_UNDERPANTS, new WearableEntry(LLWearableType::WT_UNDERPANTS,"edit_underpants_title","underpants_desc_text",1,1,1, TEX_LOWER_UNDERPANTS, TEX_LOWER_UNDERPANTS, SUBPART_UNDERPANTS));
addEntry(LLWearableType::WT_SKIRT, new WearableEntry(LLWearableType::WT_SKIRT,"edit_skirt_title","skirt_desc_text",1,1,1, TEX_SKIRT, TEX_SKIRT, SUBPART_SKIRT));
addEntry(LLWearableType::WT_ALPHA, new WearableEntry(LLWearableType::WT_ALPHA,"edit_alpha_title","alpha_desc_text",0,5,1, TEX_LOWER_ALPHA, TEX_UPPER_ALPHA, TEX_HEAD_ALPHA, TEX_EYES_ALPHA, TEX_HAIR_ALPHA, SUBPART_ALPHA));
addEntry(LLWearableType::WT_TATTOO, new WearableEntry(LLWearableType::WT_TATTOO,"edit_tattoo_title","tattoo_desc_text",0,3,1, TEX_LOWER_TATTOO, TEX_UPPER_TATTOO, TEX_HEAD_TATTOO, SUBPART_TATTOO));
addEntry(LLWearableType::WT_TATTOO, new WearableEntry(LLWearableType::WT_TATTOO,"edit_tattoo_title","tattoo_desc_text",1,3,1, TEX_HEAD_TATTOO, TEX_LOWER_TATTOO, TEX_UPPER_TATTOO, TEX_HEAD_TATTOO, SUBPART_TATTOO));
}
LLEditWearableDictionary::WearableEntry::WearableEntry(LLWearableType::EType type,
@ -331,6 +333,7 @@ LLEditWearableDictionary::ColorSwatchCtrls::ColorSwatchCtrls()
addEntry ( TEX_UPPER_GLOVES, new PickerControlEntry (TEX_UPPER_GLOVES, "Color/Tint" ));
addEntry ( TEX_UPPER_UNDERSHIRT, new PickerControlEntry (TEX_UPPER_UNDERSHIRT, "Color/Tint" ));
addEntry ( TEX_LOWER_UNDERPANTS, new PickerControlEntry (TEX_LOWER_UNDERPANTS, "Color/Tint" ));
addEntry ( TEX_HEAD_TATTOO, new PickerControlEntry(TEX_HEAD_TATTOO, "Color/Tint" ));
}
LLEditWearableDictionary::TextureCtrls::TextureCtrls()
@ -950,6 +953,9 @@ void LLPanelEditWearable::initializePanel()
// what edit group do we want to extract params for?
const std::string edit_group = subpart_entry->mEditGroup;
// initialize callback to ensure camera view changes appropriately.
tab->setDropDownStateChangedCallback(boost::bind(&LLPanelEditWearable::onTabExpandedCollapsed,this,_2,index));
// storage for ordered list of visual params
value_map_t sorted_params;
getSortedParams(sorted_params, edit_group);
@ -988,6 +994,52 @@ void LLPanelEditWearable::updateTypeSpecificControls(LLWearableType::EType type)
}
}
void LLPanelEditWearable::onTabExpandedCollapsed(const LLSD& param, U8 index)
{
bool expanded = param.asBoolean();
if (!mWearablePtr || !gAgentCamera.cameraCustomizeAvatar())
{
// we don't have a valid wearable we're editing, or we've left the wearable editor
return;
}
if (expanded)
{
const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(mWearablePtr->getType());
if (!wearable_entry)
{
llinfos << "could not get wearable dictionary entry for wearable type: " << mWearablePtr->getType() << llendl;
return;
}
if (index >= wearable_entry->mSubparts.size())
{
llinfos << "accordion tab expanded for invalid subpart. Wearable type: " << mWearablePtr->getType() << " subpart num: " << index << llendl;
return;
}
ESubpart subpart_e = wearable_entry->mSubparts[index];
const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e);
if (!subpart_entry)
{
llwarns << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << llendl;
return;
}
// Update the camera
gMorphView->setCameraTargetJoint( gAgentAvatarp->getJoint( subpart_entry->mTargetJoint ) );
gMorphView->setCameraTargetOffset( subpart_entry->mTargetOffset );
gMorphView->setCameraOffset( subpart_entry->mCameraOffset );
gMorphView->setCameraDistToDefault();
if (gSavedSettings.getBOOL("AppearanceCameraMovement"))
{
gMorphView->updateCamera();
}
}
}
void LLPanelEditWearable::updateScrollingPanelUI()
{
// do nothing if we don't have a valid wearable we're editing

View File

@ -66,6 +66,8 @@ public:
static void onRevertButtonClicked(void* userdata);
void onCommitSexChange();
void onTabExpandedCollapsed(const LLSD& param, U8 index);
private:
typedef std::map<F32, LLViewerVisualParam*> value_map_t;

View File

@ -389,7 +389,7 @@ void LLPanelGroupInvite::impl::onAvatarNameCache(const LLUUID& agent_id,
std::vector<std::string> names;
uuid_vec_t agent_ids;
agent_ids.push_back(agent_id);
names.push_back(av_name.getNameAndSLID());
names.push_back(av_name.getCompleteName());
selfp->addUsers(names, agent_ids);
}

View File

@ -45,7 +45,6 @@
#include "llfloaterinventory.h"
#include "llagent.h"
#include "llagentui.h"
#include "lltooldraganddrop.h"
#include "lllineeditor.h"
#include "lltexteditor.h"
@ -61,6 +60,7 @@
#include "llviewerwindow.h"
#include "llviewermessage.h"
#include "llnotificationsutil.h"
#include "llgiveinventory.h"
static LLRegisterPanelClassWrapper<LLPanelGroupNotices> t_panel_group_notices("panel_group_notices");
@ -163,7 +163,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
{
LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;
if(gInventory.getItem(inv_item->getUUID())
&& LLToolDragAndDrop::isInventoryGroupGiveAcceptable(inv_item))
&& LLGiveInventory::isInventoryGroupGiveAcceptable(inv_item))
{
// *TODO: get multiple object transfers working
*accept = ACCEPT_YES_COPY_SINGLE;

View File

@ -797,8 +797,37 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root)
void LLPanelGroupMembersSubTab::setGroupID(const LLUUID& id)
{
LLPanelGroupSubTab::setGroupID(id);
//clear members list
if(mMembersList) mMembersList->deleteAllItems();
if(mAssignedRolesList) mAssignedRolesList->deleteAllItems();
if(mAllowedActionsList) mAllowedActionsList->deleteAllItems();
LLPanelGroupSubTab::setGroupID(id);
}
void LLPanelGroupRolesSubTab::setGroupID(const LLUUID& id)
{
if(mRolesList) mRolesList->deleteAllItems();
if(mAssignedMembersList) mAssignedMembersList->deleteAllItems();
if(mAllowedActionsList) mAllowedActionsList->deleteAllItems();
if(mRoleName) mRoleName->clear();
if(mRoleDescription) mRoleDescription->clear();
if(mRoleTitle) mRoleTitle->clear();
setFooterEnabled(FALSE);
LLPanelGroupSubTab::setGroupID(id);
}
void LLPanelGroupActionsSubTab::setGroupID(const LLUUID& id)
{
if(mActionList) mActionList->deleteAllItems();
if(mActionRoles) mActionRoles->deleteAllItems();
if(mActionMembers) mActionMembers->deleteAllItems();
if(mActionDescription) mActionDescription->clear();
LLPanelGroupSubTab::setGroupID(id);
}

View File

@ -257,6 +257,8 @@ public:
void handleDeleteRole();
void saveRoleChanges();
virtual void setGroupID(const LLUUID& id);
protected:
void handleActionCheck(LLUICtrl* ctrl, bool force);
LLSD createRoleItem(const LLUUID& role_id, std::string name, std::string title, S32 members);
@ -294,6 +296,8 @@ public:
virtual void update(LLGroupChange gc);
void handleActionSelect();
virtual void setGroupID(const LLUUID& id);
protected:
LLScrollListCtrl* mActionList;
LLScrollListCtrl* mActionRoles;

View File

@ -269,20 +269,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
web_browser->setTabStop(FALSE);
// web_browser->navigateToLocalPage( "loading", "loading.html" );
if (gSavedSettings.getBOOL("RegInClient"))
{
// need to follow links in the internal browser
web_browser->setOpenInExternalBrowser( false );
getChild<LLView>("login_widgets")->setVisible(false);
}
else
{
// make links open in external browser
web_browser->setOpenInExternalBrowser( true );
reshapeBrowser();
}
reshapeBrowser();
// kick off a request to grab the url manually
gResponsePtr = LLIamHereLogin::build( this );
@ -486,7 +473,6 @@ void LLPanelLogin::showLoginWidgets()
{
sInstance->childSetVisible("login_widgets", true);
LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
web_browser->setOpenInExternalBrowser( true );
sInstance->reshapeBrowser();
// *TODO: Append all the usual login parameters, like first_login=Y etc.
std::string splash_screen_url = sInstance->getString("real_url");
@ -532,7 +518,7 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
std::string login_id = firstname;
if (!lastname.empty() && lastname != "Resident")
{
// support traditional First Last name slurls
// support traditional First Last name SLURLs
login_id += " ";
login_id += lastname;
}

View File

@ -347,12 +347,22 @@ void LLPanelMyProfileEdit::onCacheSetName(bool success,
void LLPanelMyProfileEdit::onDialogSetName(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0)
if (option == 0 || option == 1)
{
LLUUID agent_id = notification["payload"]["agent_id"];
if (agent_id.isNull()) return;
std::string display_name_utf8 = response["display_name"].asString();
std::string display_name_utf8;
if (option == 0)
{
// user gave us a name
display_name_utf8 = response["display_name"].asString();
}
else
{
// reset back to People API default
display_name_utf8 = "";
}
const U32 DISPLAY_NAME_MAX_LENGTH = 31; // characters, not bytes
LLWString display_name_wstr = utf8string_to_wstring(display_name_utf8);

View File

@ -48,7 +48,7 @@
#include "llagent.h"
#include "llavataractions.h"
#include "llcallbacklist.h"
#include "llfloaterbuycurrency.h"
#include "llbuycurrencyhtml.h"
#include "llfloaterreg.h"
#include "llinventorybridge.h"
#include "llinventorydefines.h"
@ -616,7 +616,7 @@ void LLTaskInvFVBridge::performAction(LLInventoryModel* model, std::string actio
{
LLStringUtil::format_map_t args;
args["AMOUNT"] = llformat("%d", price);
LLFloaterBuyCurrency::buyCurrency(LLTrans::getString("this_costs", args), price);
LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("this_costs", args), price );
}
else
{

View File

@ -148,6 +148,8 @@ protected:
else
{
mBaseOutfitId = baseoutfit_id;
mPanel->updateCurrentOutfitName();
if (baseoutfit_id.isNull()) return;
mBaseOutfitLastVersion = getCategoryVersion(mBaseOutfitId);
@ -210,7 +212,8 @@ LLPanelOutfitEdit::LLPanelOutfitEdit()
mCOFWearables(NULL),
mInventoryItemsPanel(NULL),
mCOFObserver(NULL),
mCOFDragAndDropObserver(NULL)
mCOFDragAndDropObserver(NULL),
mInitialized(false)
{
mSavedFolderState = new LLSaveFolderState();
mSavedFolderState->setApply(FALSE);
@ -307,6 +310,16 @@ BOOL LLPanelOutfitEdit::postBuild()
return TRUE;
}
// virtual
void LLPanelOutfitEdit::onOpen(const LLSD& key)
{
if (!mInitialized)
{
displayCurrentOutfit();
mInitialized = true;
}
}
void LLPanelOutfitEdit::moveWearable(bool closer_to_body)
{
LLUUID item_id = mCOFWearables->getSelectedUUID();
@ -339,6 +352,8 @@ void LLPanelOutfitEdit::showFilteredWearablesPanel()
if(switchPanels(mInventoryItemsPanel, mWearableItemsPanel))
{
mFolderViewBtn->setToggleState(FALSE);
mFolderViewBtn->setImageOverlay(getString("folder_view_off"), mFolderViewBtn->getImageOverlayHAlign());
mListViewBtn->setImageOverlay(getString("list_view_on"), mListViewBtn->getImageOverlayHAlign());
}
mListViewBtn->setToggleState(TRUE);
}
@ -348,6 +363,8 @@ void LLPanelOutfitEdit::showFilteredFolderWearablesPanel()
if(switchPanels(mWearableItemsPanel, mInventoryItemsPanel))
{
mListViewBtn->setToggleState(FALSE);
mListViewBtn->setImageOverlay(getString("list_view_off"), mListViewBtn->getImageOverlayHAlign());
mFolderViewBtn->setImageOverlay(getString("folder_view_on"), mFolderViewBtn->getImageOverlayHAlign());
}
mFolderViewBtn->setToggleState(TRUE);
}
@ -446,13 +463,25 @@ void LLPanelOutfitEdit::onSearchEdit(const std::string& string)
void LLPanelOutfitEdit::onAddToOutfitClicked(void)
{
LLFolderViewItem* curr_item = mInventoryItemsPanel->getRootFolder()->getCurSelectedItem();
if (!curr_item) return;
LLUUID selected_id;
if (mInventoryItemsPanel->getVisible())
{
LLFolderViewItem* curr_item = mInventoryItemsPanel->getRootFolder()->getCurSelectedItem();
if (!curr_item) return;
LLFolderViewEventListener* listenerp = curr_item->getListener();
if (!listenerp) return;
LLFolderViewEventListener* listenerp = curr_item->getListener();
if (!listenerp) return;
LLAppearanceMgr::getInstance()->wearItemOnAvatar(listenerp->getUUID());
selected_id = listenerp->getUUID();
}
else if (mWearableItemsPanel->getVisible())
{
selected_id = mWearableItemsList->getSelectedUUID();
}
if (selected_id.isNull()) return;
LLAppearanceMgr::getInstance()->wearItemOnAvatar(selected_id);
}
@ -616,6 +645,13 @@ void LLPanelOutfitEdit::displayCurrentOutfit()
setVisible(TRUE);
}
updateCurrentOutfitName();
update();
}
void LLPanelOutfitEdit::updateCurrentOutfitName()
{
std::string current_outfit_name;
if (LLAppearanceMgr::getInstance()->getBaseOutfitName(current_outfit_name))
{
@ -625,8 +661,6 @@ void LLPanelOutfitEdit::displayCurrentOutfit()
{
mCurrentOutfitName->setText(getString("No Outfit"));
}
update();
}
//private

View File

@ -61,6 +61,7 @@ class LLFilteredWearableListManager;
class LLPanelOutfitEdit : public LLPanel
{
LOG_CLASS(LLPanelOutfitEdit);
public:
// NOTE: initialize mLookItemTypes at the index of any new enum you add in the LLPanelOutfitEdit() constructor
@ -83,6 +84,7 @@ public:
/*virtual*/ ~LLPanelOutfitEdit();
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
void moveWearable(bool closer_to_body);
@ -102,7 +104,8 @@ public:
void onEditWearableClicked(void);
void displayCurrentOutfit();
void updateCurrentOutfitName();
void update();
void updateVerbs();
@ -146,6 +149,7 @@ private:
std::vector<LLLookItemType> mLookItemTypes;
LLCOFWearables* mCOFWearables;
bool mInitialized;
};
#endif // LL_LLPANELOUTFITEDIT_H

View File

@ -73,7 +73,8 @@ static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_o
LLPanelOutfitsInventory::LLPanelOutfitsInventory() :
mMyOutfitsPanel(NULL),
mCurrentOutfitPanel(NULL),
mParent(NULL)
mParent(NULL),
mInitialized(false)
{
mSavedFolderState = new LLSaveFolderState();
mSavedFolderState->setApply(FALSE);
@ -106,6 +107,18 @@ BOOL LLPanelOutfitsInventory::postBuild()
// virtual
void LLPanelOutfitsInventory::onOpen(const LLSD& key)
{
if (!mInitialized)
{
LLSidepanelAppearance* panel_appearance = getAppearanceSP();
if (panel_appearance)
{
// *TODO: move these methods to LLPanelOutfitsInventory?
panel_appearance->fetchInventory();
panel_appearance->refreshCurrentOutfitName();
}
mInitialized = true;
}
// Make sure we know which tab is selected, update the filter,
// and update verbs.
onTabChange();
@ -249,8 +262,7 @@ bool LLPanelOutfitsInventory::onSaveCommit(const LLSD& notification, const LLSD&
{
LLUUID outfit_folder = LLAppearanceMgr::getInstance()->makeNewOutfitLinks(outfit_name);
LLSidepanelAppearance* panel_appearance =
dynamic_cast<LLSidepanelAppearance *>(LLSideTray::getInstance()->getPanel("sidepanel_appearance"));
LLSidepanelAppearance* panel_appearance = getAppearanceSP();
if (panel_appearance)
{
panel_appearance->showOutfitsInventoryPanel();
@ -661,3 +673,11 @@ void LLPanelOutfitsInventory::onWearablesLoaded()
{
setWearablesLoading(false);
}
LLSidepanelAppearance* LLPanelOutfitsInventory::getAppearanceSP()
{
static LLSidepanelAppearance* panel_appearance =
dynamic_cast<LLSidepanelAppearance*>
(LLSideTray::getInstance()->getPanel("sidepanel_appearance"));
return panel_appearance;
}

View File

@ -49,6 +49,7 @@ class LLTabContainer;
class LLPanelOutfitsInventory : public LLPanel
{
LOG_CLASS(LLPanelOutfitsInventory);
public:
LLPanelOutfitsInventory();
virtual ~LLPanelOutfitsInventory();
@ -72,6 +73,7 @@ public:
void setParent(LLSidepanelAppearance *parent);
LLFolderView* getRootFolder();
LLSidepanelAppearance* getAppearanceSP();
static LLPanelOutfitsInventory* findInstance();
@ -132,6 +134,8 @@ private:
// List Commands //
////////////////////////////////////////////////////////////////////////////////
///
bool mInitialized;
};
#endif //LL_LLPANELOUTFITSINVENTORY_H

View File

@ -1165,7 +1165,7 @@ void LLPanelPeople::onActivateButtonClicked()
void LLPanelPeople::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
{
if (!names.empty() && !ids.empty())
LLAvatarActions::requestFriendshipDialog(ids[0], names[0].getNameAndSLID());
LLAvatarActions::requestFriendshipDialog(ids[0], names[0].getCompleteName());
}
void LLPanelPeople::onGroupPlusButtonClicked()

View File

@ -50,8 +50,8 @@
#include "llagentui.h"
#include "llappviewer.h"
#include "llcallbacklist.h"
#include "llfloaterbuycurrency.h"
#include "llslurl.h" // IDEVO
#include "llbuycurrencyhtml.h"
#include "llslurl.h"
#include "llstatusbar.h"
#include "llviewercontrol.h"
#include "llviewerparcelmgr.h"
@ -578,7 +578,7 @@ void LLPanelPlaceProfile::onForSaleBannerClick()
{
LLStringUtil::format_map_t args;
args["AMOUNT"] = llformat("%d", price);
LLFloaterBuyCurrency::buyCurrency(LLTrans::getString("buying_selected_land", args), price);
LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("buying_selected_land", args), price );
}
else
{

View File

@ -73,9 +73,9 @@ LLScrollingPanelParam::LLScrollingPanelParam( const LLPanel::Params& panel_param
F32 min_weight = param->getMinWeight();
F32 max_weight = param->getMaxWeight();
mHintMin = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, (LLViewerVisualParam*) wearable->getVisualParam(param->getID()), min_weight);
mHintMin = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, (LLViewerVisualParam*) wearable->getVisualParam(param->getID()), wearable, min_weight);
pos_x = getChild<LLViewBorder>("right_border")->getRect().mLeft + left_border->getBorderWidth();
mHintMax = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, (LLViewerVisualParam*) wearable->getVisualParam(param->getID()), max_weight );
mHintMax = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, (LLViewerVisualParam*) wearable->getVisualParam(param->getID()), wearable, max_weight );
mHintMin->setAllowsUpdates( FALSE );
mHintMax->setAllowsUpdates( FALSE );

View File

@ -121,7 +121,10 @@ int secapiSSLCertVerifyCallback(X509_STORE_CTX *ctx, void *param)
validation_params[CERT_HOSTNAME] = uri.hostName();
try
{
chain->validate(VALIDATION_POLICY_SSL, store, validation_params);
// we rely on libcurl to validate the hostname, as libcurl does more extensive validation
// leaving our hostname validation call mechanism for future additions with respect to
// OS native (Mac keyring, windows CAPI) validation.
chain->validate(VALIDATION_POLICY_SSL & (~VALIDATION_POLICY_HOSTNAME), store, validation_params);
}
catch (LLCertValidationTrustException& cert_exception)
{

View File

@ -47,6 +47,7 @@
#include "llsidetray.h"
#include "lltextbox.h"
#include "lluictrlfactory.h"
#include "llviewercontrol.h"
#include "llviewerregion.h"
#include "llvoavatarself.h"
#include "llwearable.h"
@ -97,7 +98,8 @@ LLSidepanelAppearance::LLSidepanelAppearance() :
mFilterSubString(LLStringUtil::null),
mFilterEditor(NULL),
mOutfitEdit(NULL),
mCurrOutfitPanel(NULL)
mCurrOutfitPanel(NULL),
mOpened(false)
{
}
@ -116,7 +118,7 @@ BOOL LLSidepanelAppearance::postBuild()
mEditAppearanceBtn = getChild<LLButton>("editappearance_btn");
mEditAppearanceBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditAppearanceButtonClicked, this));
childSetAction("edit_outfit_btn", boost::bind(&LLSidepanelAppearance::onEditOutfitButtonClicked, this));
childSetAction("edit_outfit_btn", boost::bind(&LLSidepanelAppearance::showOutfitEditPanel, this));
mNewOutfitBtn = getChild<LLButton>("newlook_btn");
mNewOutfitBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onNewOutfitButtonClicked, this));
@ -148,7 +150,7 @@ BOOL LLSidepanelAppearance::postBuild()
LLButton* edit_wearable_back_btn = mEditWearable->getChild<LLButton>("back_btn");
if (edit_wearable_back_btn)
{
edit_wearable_back_btn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditWearBackClicked, this));
edit_wearable_back_btn->setClickedCallback(boost::bind(&LLSidepanelAppearance::showOutfitEditPanel, this));
}
}
@ -167,27 +169,36 @@ BOOL LLSidepanelAppearance::postBuild()
// virtual
void LLSidepanelAppearance::onOpen(const LLSD& key)
{
fetchInventory();
refreshCurrentOutfitName();
if (mPanelOutfitsInventory)
{
mPanelOutfitsInventory->onOpen(key);
}
if (!key.has("type"))
return;
{
// No specific panel requested.
// If we're opened for the first time then show My Outfits.
// Else do nothing.
if (!mOpened)
{
showOutfitsInventoryPanel();
}
}
else
{
// Switch to the requested panel.
// *TODO: replace this crap with LLSideTrayPanelContainer
std::string type = key["type"].asString();
if (type == "my_outfits")
{
showOutfitsInventoryPanel();
}
else if (type == "edit_outfit")
{
showOutfitEditPanel();
}
else if (type == "edit_shape")
{
showWearableEditPanel();
}
}
// Switch to the requested panel.
std::string type = key["type"].asString();
if (type == "my_outfits")
{
showOutfitsInventoryPanel();
}
else if (type == "edit_outfit")
{
showOutfitEditPanel(/*update = */ true);
}
mOpened = true;
}
void LLSidepanelAppearance::onFilterEdit(const std::string& search_string)
@ -239,13 +250,6 @@ void LLSidepanelAppearance::onEditAppearanceButtonClicked()
}
}
void LLSidepanelAppearance::onEditOutfitButtonClicked()
{
LLSD key;
key["type"] = "edit_outfit";
LLSideTray::getInstance()->showPanel("sidepanel_appearance", key);
}
void LLSidepanelAppearance::onNewOutfitButtonClicked()
{
if (!mOutfitEdit->getVisible())
@ -254,52 +258,76 @@ void LLSidepanelAppearance::onNewOutfitButtonClicked()
}
}
void LLSidepanelAppearance::onEditWearBackClicked()
{
showOutfitEditPanel(/* update = */ false);
}
void LLSidepanelAppearance::showOutfitsInventoryPanel()
{
toggleWearableEditPanel(FALSE);
toggleOutfitEditPanel(FALSE);
togglMyOutfitsPanel(TRUE);
}
void LLSidepanelAppearance::showOutfitEditPanel(bool update)
void LLSidepanelAppearance::showOutfitEditPanel()
{
if (!mOutfitEdit)
return;
toggleWearableEditPanel(FALSE);
togglMyOutfitsPanel(FALSE);
toggleWearableEditPanel(FALSE, NULL, TRUE); // don't switch out of edit appearance mode
toggleOutfitEditPanel(TRUE);
}
if (update)
void LLSidepanelAppearance::showWearableEditPanel(LLWearable *wearable /* = NULL*/)
{
togglMyOutfitsPanel(FALSE);
toggleOutfitEditPanel(FALSE, TRUE); // don't switch out of edit appearance mode
toggleWearableEditPanel(TRUE, wearable);
}
void LLSidepanelAppearance::togglMyOutfitsPanel(BOOL visible)
{
if (!mPanelOutfitsInventory || mPanelOutfitsInventory->getVisible() == visible)
{
mOutfitEdit->displayCurrentOutfit();
// visibility isn't changing, hence nothing to do
return;
}
mPanelOutfitsInventory->setVisible(visible);
// *TODO: Move these controls to panel_outfits_inventory.xml
// so that we don't need to toggle them explicitly.
mFilterEditor->setVisible(visible);
mNewOutfitBtn->setVisible(visible);
mCurrOutfitPanel->setVisible(visible);
if (visible)
{
mPanelOutfitsInventory->onOpen(LLSD());
}
}
void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible)
void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch)
{
if (!mOutfitEdit)
return;
if (mOutfitEdit->getVisible() == visible)
if (!mOutfitEdit || mOutfitEdit->getVisible() == visible)
{
// visibility isn't changing, hence nothing to do
return;
}
mOutfitEdit->setVisible(visible);
if (mPanelOutfitsInventory) mPanelOutfitsInventory->setVisible(!visible);
mFilterEditor->setVisible(!visible);
mNewOutfitBtn->setVisible(!visible);
mCurrOutfitPanel->setVisible(!visible);
if (visible)
{
mOutfitEdit->onOpen(LLSD());
if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
{
gAgentCamera.changeCameraToCustomizeAvatar();
}
}
else if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
{
gAgentCamera.changeCameraToDefault();
}
}
void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable)
void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable, BOOL disable_camera_switch)
{
if (mEditWearable->getVisible() == visible)
if (!mEditWearable || mEditWearable->getVisible() == visible)
{
// visibility isn't changing, hence nothing to do
return;
@ -309,24 +337,32 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we
{
wearable = gAgentWearables.getWearable(LLWearableType::WT_SHAPE, 0);
}
if (!mEditWearable || !wearable)
if (!wearable)
{
return;
}
// Save changes if closing.
if (!visible)
{
mEditWearable->saveChanges();
}
// Toggle panel visibility.
mCurrOutfitPanel->setVisible(!visible);
mEditWearable->setVisible(visible);
mEditWearable->setWearable(wearable);
mFilterEditor->setVisible(!visible);
mPanelOutfitsInventory->setVisible(!visible);
if (visible)
{
mEditWearable->onOpen(LLSD()); // currently no-op, just for consistency
if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
{
gAgentCamera.changeCameraToCustomizeAvatar();
}
}
else
{
// Save changes if closing.
mEditWearable->saveChanges();
if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
{
gAgentCamera.changeCameraToDefault();
}
}
}
void LLSidepanelAppearance::refreshCurrentOutfitName(const std::string& name)
@ -356,11 +392,13 @@ void LLSidepanelAppearance::refreshCurrentOutfitName(const std::string& name)
}
//static
void LLSidepanelAppearance::editWearable(LLWearable *wearable, void *data)
void LLSidepanelAppearance::editWearable(LLWearable *wearable, LLView *data)
{
LLSidepanelAppearance *panel = (LLSidepanelAppearance*) data;
panel->toggleOutfitEditPanel(FALSE);
panel->toggleWearableEditPanel(TRUE, wearable);
LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(data);
if (panel)
{
panel->showWearableEditPanel(wearable);
}
}
// Fetch currently worn items and only enable the New Look button after everything's been

View File

@ -47,6 +47,7 @@ class LLPanelOutfitsInventory;
class LLSidepanelAppearance : public LLPanel
{
LOG_CLASS(LLSidepanelAppearance);
public:
LLSidepanelAppearance();
virtual ~LLSidepanelAppearance();
@ -56,14 +57,15 @@ public:
void refreshCurrentOutfitName(const std::string& name = "");
static void editWearable(LLWearable *wearable, void *data);
static void editWearable(LLWearable *wearable, LLView *data);
void fetchInventory();
void inventoryFetched();
void onNewOutfitButtonClicked();
void showOutfitsInventoryPanel();
void showOutfitEditPanel(bool update);
void showOutfitEditPanel();
void showWearableEditPanel(LLWearable *wearable = NULL);
void setWearablesLoading(bool val);
private:
@ -71,12 +73,10 @@ private:
void onOpenOutfitButtonClicked();
void onEditAppearanceButtonClicked();
void onEditOutfitButtonClicked();
void onEditWearBackClicked();
//@deprecated use showXXX() methods instead
void toggleOutfitEditPanel(BOOL visible);
void toggleWearableEditPanel(BOOL visible, LLWearable* wearable = NULL);
void togglMyOutfitsPanel(BOOL visible);
void toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch = FALSE);
void toggleWearableEditPanel(BOOL visible, LLWearable* wearable = NULL, BOOL disable_camera_switch = FALSE);
LLFilterEditor* mFilterEditor;
LLPanelOutfitsInventory* mPanelOutfitsInventory;
@ -100,6 +100,9 @@ private:
// Search string for filtering landmarks and teleport
// history locations
std::string mFilterSubString;
// Gets set to true when we're opened for the first time.
bool mOpened;
};
#endif //LL_LLSIDEPANELAPPEARANCE_H

View File

@ -42,6 +42,7 @@
#include "llsidepaneltaskinfo.h"
#include "lltabcontainer.h"
#include "llselectmgr.h"
#include "llweb.h"
static LLRegisterPanelClassWrapper<LLSidepanelInventory> t_inventory("sidepanel_inventory");
@ -70,6 +71,9 @@ BOOL LLSidepanelInventory::postBuild()
mShareBtn = mInventoryPanel->getChild<LLButton>("share_btn");
mShareBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onShareButtonClicked, this));
LLButton* shop_btn = mInventoryPanel->getChild<LLButton>("shop_btn");
shop_btn->setClickedCallback(boost::bind(&LLSidepanelInventory::onShopButtonClicked, this));
mWearBtn = mInventoryPanel->getChild<LLButton>("wear_btn");
mWearBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onWearButtonClicked, this));
@ -155,6 +159,11 @@ void LLSidepanelInventory::onShareButtonClicked()
LLAvatarActions::shareWithAvatars();
}
void LLSidepanelInventory::onShopButtonClicked()
{
LLWeb::loadURLExternal(gSavedSettings.getString("MarketplaceURL"));
}
void LLSidepanelInventory::performActionOnSelection(const std::string &action)
{
LLPanelMainInventory *panel_main_inventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");

Some files were not shown because too many files have changed in this diff Show More