summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcharacter/llcharacter.cpp28
-rw-r--r--indra/llcharacter/llcharacter.h15
-rw-r--r--indra/llcharacter/llvisualparam.cpp2
-rw-r--r--indra/llcharacter/llvisualparam.h8
-rw-r--r--indra/llmessage/tests/llhost_test.cpp3
-rw-r--r--indra/llui/CMakeLists.txt458
-rw-r--r--indra/llui/lldockablefloater.cpp12
-rw-r--r--indra/llui/lldockablefloater.h2
-rw-r--r--indra/llui/lldockcontrol.h4
-rw-r--r--indra/llui/llhandle.h14
-rw-r--r--indra/llui/lllayoutstack.cpp2
-rw-r--r--indra/llui/llnotifications.cpp3033
-rw-r--r--indra/llui/llnotifications.h3
-rw-r--r--indra/llui/llpanel.cpp7
-rw-r--r--indra/llui/llrngwriter.cpp3
-rw-r--r--indra/llui/llscrollbar.cpp18
-rw-r--r--indra/llui/llscrollbar.h4
-rw-r--r--indra/llui/lltextbase.cpp68
-rw-r--r--indra/llui/lltextbase.h5
-rw-r--r--indra/llui/lltexteditor.cpp4
-rw-r--r--indra/llui/lltexteditor.h2
-rw-r--r--indra/llui/lluicolortable.cpp2
-rw-r--r--indra/llui/lluictrlfactory.cpp45
-rw-r--r--indra/llui/lluictrlfactory.h50
-rw-r--r--indra/llui/lluistring.cpp2
-rw-r--r--indra/llui/lluistring.h2
-rw-r--r--indra/llxuixml/llinitparam.cpp2
-rw-r--r--indra/llxuixml/llinitparam.h76
-rw-r--r--indra/llxuixml/lltrans.cpp4
-rw-r--r--indra/llxuixml/llxuiparser.cpp12
-rw-r--r--indra/llxuixml/llxuiparser.h7
-rw-r--r--indra/media_plugins/gstreamer010/CMakeLists.txt6
-rw-r--r--indra/newview/CMakeLists.txt10
-rw-r--r--indra/newview/app_settings/settings.xml48
-rw-r--r--indra/newview/llagentpicksinfo.cpp130
-rw-r--r--indra/newview/llagentpicksinfo.h106
-rw-r--r--indra/newview/llagentwearables.cpp15
-rw-r--r--indra/newview/llappearancemgr.cpp2
-rw-r--r--indra/newview/llappearancemgr.h2
-rw-r--r--indra/newview/llavatarlist.cpp14
-rw-r--r--indra/newview/llavatarlist.h7
-rw-r--r--indra/newview/llavatarlistitem.cpp4
-rw-r--r--indra/newview/llavatarlistitem.h2
-rw-r--r--indra/newview/llavatarpropertiesprocessor.cpp6
-rw-r--r--indra/newview/llbottomtray.cpp3
-rw-r--r--indra/newview/llchannelmanager.cpp13
-rw-r--r--indra/newview/llchathistory.cpp12
-rw-r--r--indra/newview/llchiclet.cpp149
-rw-r--r--indra/newview/llchiclet.h78
-rw-r--r--indra/newview/llconfirmationmanager.cpp1
-rw-r--r--indra/newview/lldndbutton.cpp60
-rw-r--r--indra/newview/lldndbutton.h89
-rw-r--r--indra/newview/lldriverparam.cpp19
-rw-r--r--indra/newview/lldriverparam.h4
-rw-r--r--indra/newview/llfirstuse.cpp4
-rw-r--r--indra/newview/llfloatercamera.cpp10
-rw-r--r--indra/newview/llfloatercamera.h7
-rw-r--r--indra/newview/llfloaterinventory.cpp77
-rw-r--r--indra/newview/llfloaterinventory.h14
-rw-r--r--indra/newview/llfloateruipreview.cpp53
-rw-r--r--indra/newview/llfolderview.cpp10
-rw-r--r--indra/newview/llfolderviewitem.cpp6
-rw-r--r--indra/newview/llfolderviewitem.h1
-rw-r--r--indra/newview/llfriendcard.cpp87
-rw-r--r--indra/newview/llfriendcard.h6
-rw-r--r--indra/newview/llimfloater.cpp39
-rw-r--r--indra/newview/llimfloater.h9
-rw-r--r--indra/newview/llimpanel.cpp20
-rw-r--r--indra/newview/llimpanel.h4
-rw-r--r--indra/newview/llimview.cpp143
-rw-r--r--indra/newview/llimview.h42
-rw-r--r--indra/newview/llinventorybridge.cpp71
-rw-r--r--indra/newview/llinventorybridge.h1
-rw-r--r--indra/newview/lllocaltextureobject.cpp16
-rw-r--r--indra/newview/lllocaltextureobject.h8
-rw-r--r--indra/newview/lllocationinputctrl.cpp2
-rw-r--r--indra/newview/llmimetypes.cpp1
-rw-r--r--indra/newview/llmoveview.cpp4
-rw-r--r--indra/newview/llmoveview.h4
-rw-r--r--indra/newview/llmutelist.h8
-rw-r--r--indra/newview/llnearbychat.cpp269
-rw-r--r--indra/newview/llnearbychat.h34
-rw-r--r--indra/newview/llnearbychathandler.cpp2
-rw-r--r--indra/newview/llnotificationtiphandler.cpp1
-rw-r--r--indra/newview/llpanelavatar.cpp4
-rw-r--r--indra/newview/llpaneleditwearable.cpp9
-rw-r--r--indra/newview/llpanellandmarks.cpp217
-rw-r--r--indra/newview/llpanellandmarks.h18
-rw-r--r--indra/newview/llpanelpick.cpp13
-rw-r--r--indra/newview/llpanelpick.h1
-rw-r--r--indra/newview/llpanelpicks.cpp24
-rw-r--r--indra/newview/llpanelpicks.h1
-rw-r--r--indra/newview/llpanelplaceinfo.cpp77
-rw-r--r--indra/newview/llpanelplaceinfo.h14
-rw-r--r--indra/newview/llpanelplaces.cpp13
-rw-r--r--indra/newview/llpanelplaces.h1
-rw-r--r--indra/newview/llpanelprofile.cpp3
-rw-r--r--indra/newview/llpanelprofileview.cpp5
-rw-r--r--indra/newview/llpanelteleporthistory.cpp80
-rw-r--r--indra/newview/llpanelteleporthistory.h5
-rw-r--r--indra/newview/llparticipantlist.cpp56
-rw-r--r--indra/newview/llparticipantlist.h48
-rw-r--r--indra/newview/llpolymesh.cpp2
-rw-r--r--indra/newview/llpolymesh.h2
-rw-r--r--indra/newview/llpolymorph.cpp2
-rw-r--r--indra/newview/llpolymorph.h2
-rw-r--r--indra/newview/llrootview.h22
-rw-r--r--indra/newview/llscreenchannel.cpp28
-rw-r--r--indra/newview/llscreenchannel.h4
-rw-r--r--indra/newview/llsearchcombobox.cpp5
-rw-r--r--indra/newview/llsidetray.cpp22
-rw-r--r--indra/newview/llstartup.cpp3
-rw-r--r--indra/newview/llsyswellwindow.cpp6
-rw-r--r--indra/newview/llteleporthistorystorage.cpp13
-rw-r--r--indra/newview/llteleporthistorystorage.h5
-rw-r--r--indra/newview/lltexglobalcolor.cpp2
-rw-r--r--indra/newview/lltexglobalcolor.h2
-rw-r--r--indra/newview/lltexlayer.cpp12
-rw-r--r--indra/newview/lltexlayer.h7
-rw-r--r--indra/newview/lltexlayerparams.cpp4
-rw-r--r--indra/newview/lltexlayerparams.h8
-rw-r--r--indra/newview/lltoast.cpp52
-rw-r--r--indra/newview/lltoast.h52
-rw-r--r--indra/newview/lltransientdockablefloater.cpp96
-rw-r--r--indra/newview/lltransientdockablefloater.h57
-rw-r--r--indra/newview/lltransientfloatermgr.cpp110
-rw-r--r--indra/newview/lltransientfloatermgr.h63
-rw-r--r--indra/newview/llviewerfloaterreg.cpp1
-rw-r--r--indra/newview/llviewerinventory.cpp15
-rw-r--r--indra/newview/llviewerinventory.h3
-rw-r--r--indra/newview/llviewermenu.cpp11
-rw-r--r--indra/newview/llviewerprecompiledheaders.h1
-rw-r--r--indra/newview/llviewertexturelist.cpp2
-rw-r--r--indra/newview/llviewervisualparam.h2
-rw-r--r--indra/newview/llvoavatar.cpp186
-rw-r--r--indra/newview/llvoavatar.h2
-rw-r--r--indra/newview/llvoavatarself.cpp198
-rw-r--r--indra/newview/llvoavatarself.h18
-rw-r--r--indra/newview/llwearable.cpp39
-rw-r--r--indra/newview/llwearable.h12
-rw-r--r--indra/newview/llwldaycycle.cpp1
-rw-r--r--indra/newview/skins/default/textures/textures.xml2
-rw-r--r--indra/newview/skins/default/xui/en/favorites_bar_button.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_critical.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_customize.xml60
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_nearby_chat.xml36
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_notecard.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_script_preview.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_select_key.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_tos.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_wearable_save_as.xml1
-rw-r--r--indra/newview/skins/default/xui/en/menu_landmark.xml3
-rw-r--r--indra/newview/skins/default/xui/en/menu_login.xml6
-rw-r--r--indra/newview/skins/default/xui/en/menu_place.xml3
-rw-r--r--indra/newview/skins/default/xui/en/menu_places_gear_folder.xml9
-rw-r--r--indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml12
-rw-r--r--indra/newview/skins/default/xui/en/menu_teleport_history_item.xml6
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_avatar_list_item.xml7
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_profile.xml71
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_general.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_land_money.xml18
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_list_item.xml27
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_notices.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_landmarks.xml5
-rw-r--r--indra/newview/skins/default/xui/en/panel_navigation_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_notification.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_people.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_advanced.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_general.xml81
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml38
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_setup.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_sound.xml38
-rw-r--r--indra/newview/skins/default/xui/en/panel_side_tray.xml19
-rw-r--r--indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml3
-rw-r--r--indra/newview/skins/default/xui/en/panel_toast.xml8
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml54
-rw-r--r--indra/newview/skins/default/xui/en/widgets/location_input.xml4
180 files changed, 4694 insertions, 3159 deletions
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp
index 20ff7bab34..e68672d46f 100644
--- a/indra/llcharacter/llcharacter.cpp
+++ b/indra/llcharacter/llcharacter.cpp
@@ -276,7 +276,7 @@ void LLCharacter::removeAnimationData(std::string name)
BOOL LLCharacter::setVisualParamWeight(LLVisualParam* which_param, F32 weight, BOOL set_by_user)
{
S32 index = which_param->getID();
- VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index);
+ visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index);
if (index_iter != mVisualParamIndexMap.end())
{
index_iter->second->setWeight(weight, set_by_user);
@@ -293,7 +293,7 @@ BOOL LLCharacter::setVisualParamWeight(const char* param_name, F32 weight, BOOL
std::string tname(param_name);
LLStringUtil::toLower(tname);
char *tableptr = sVisualParamNames.checkString(tname);
- VisualParamNameMap_t::iterator name_iter = mVisualParamNameMap.find(tableptr);
+ visual_param_name_map_t::iterator name_iter = mVisualParamNameMap.find(tableptr);
if (name_iter != mVisualParamNameMap.end())
{
name_iter->second->setWeight(weight, set_by_user);
@@ -308,7 +308,7 @@ BOOL LLCharacter::setVisualParamWeight(const char* param_name, F32 weight, BOOL
//-----------------------------------------------------------------------------
BOOL LLCharacter::setVisualParamWeight(S32 index, F32 weight, BOOL set_by_user)
{
- VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index);
+ visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index);
if (index_iter != mVisualParamIndexMap.end())
{
index_iter->second->setWeight(weight, set_by_user);
@@ -324,7 +324,7 @@ BOOL LLCharacter::setVisualParamWeight(S32 index, F32 weight, BOOL set_by_user)
F32 LLCharacter::getVisualParamWeight(LLVisualParam *which_param)
{
S32 index = which_param->getID();
- VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index);
+ visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index);
if (index_iter != mVisualParamIndexMap.end())
{
return index_iter->second->getWeight();
@@ -344,7 +344,7 @@ F32 LLCharacter::getVisualParamWeight(const char* param_name)
std::string tname(param_name);
LLStringUtil::toLower(tname);
char *tableptr = sVisualParamNames.checkString(tname);
- VisualParamNameMap_t::iterator name_iter = mVisualParamNameMap.find(tableptr);
+ visual_param_name_map_t::iterator name_iter = mVisualParamNameMap.find(tableptr);
if (name_iter != mVisualParamNameMap.end())
{
return name_iter->second->getWeight();
@@ -358,7 +358,7 @@ F32 LLCharacter::getVisualParamWeight(const char* param_name)
//-----------------------------------------------------------------------------
F32 LLCharacter::getVisualParamWeight(S32 index)
{
- VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index);
+ visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index);
if (index_iter != mVisualParamIndexMap.end())
{
return index_iter->second->getWeight();
@@ -415,7 +415,7 @@ LLVisualParam* LLCharacter::getVisualParam(const char *param_name)
std::string tname(param_name);
LLStringUtil::toLower(tname);
char *tableptr = sVisualParamNames.checkString(tname);
- VisualParamNameMap_t::iterator name_iter = mVisualParamNameMap.find(tableptr);
+ visual_param_name_map_t::iterator name_iter = mVisualParamNameMap.find(tableptr);
if (name_iter != mVisualParamNameMap.end())
{
return name_iter->second;
@@ -430,7 +430,7 @@ LLVisualParam* LLCharacter::getVisualParam(const char *param_name)
void LLCharacter::addSharedVisualParam(LLVisualParam *param)
{
S32 index = param->getID();
- VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index);
+ visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index);
LLVisualParam* current_param = 0;
if (index_iter != mVisualParamIndexMap.end())
current_param = index_iter->second;
@@ -457,13 +457,13 @@ void LLCharacter::addVisualParam(LLVisualParam *param)
{
S32 index = param->getID();
// Add Index map
- std::pair<VisualParamIndexMap_t::iterator, bool> idxres;
- idxres = mVisualParamIndexMap.insert(VisualParamIndexMap_t::value_type(index, param));
+ std::pair<visual_param_index_map_t::iterator, bool> idxres;
+ idxres = mVisualParamIndexMap.insert(visual_param_index_map_t::value_type(index, param));
if (!idxres.second)
{
llwarns << "Visual parameter " << param->getName() << " already exists with same ID as " <<
param->getName() << llendl;
- VisualParamIndexMap_t::iterator index_iter = idxres.first;
+ visual_param_index_map_t::iterator index_iter = idxres.first;
index_iter->second = param;
}
@@ -473,12 +473,12 @@ void LLCharacter::addVisualParam(LLVisualParam *param)
std::string tname(param->getName());
LLStringUtil::toLower(tname);
char *tableptr = sVisualParamNames.addString(tname);
- std::pair<VisualParamNameMap_t::iterator, bool> nameres;
- nameres = mVisualParamNameMap.insert(VisualParamNameMap_t::value_type(tableptr, param));
+ std::pair<visual_param_name_map_t::iterator, bool> nameres;
+ nameres = mVisualParamNameMap.insert(visual_param_name_map_t::value_type(tableptr, param));
if (!nameres.second)
{
// Already exists, copy param
- VisualParamNameMap_t::iterator name_iter = nameres.first;
+ visual_param_name_map_t::iterator name_iter = nameres.first;
name_iter->second = param;
}
}
diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h
index 1507686f67..cb44a32e8a 100644
--- a/indra/llcharacter/llcharacter.h
+++ b/indra/llcharacter/llcharacter.h
@@ -233,12 +233,12 @@ public:
LLVisualParam* getVisualParam(S32 id) const
{
- VisualParamIndexMap_t::const_iterator iter = mVisualParamIndexMap.find(id);
+ visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(id);
return (iter == mVisualParamIndexMap.end()) ? 0 : iter->second;
}
S32 getVisualParamID(LLVisualParam *id)
{
- VisualParamIndexMap_t::iterator iter;
+ visual_param_index_map_t::iterator iter;
for (iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++)
{
if (iter->second == id)
@@ -276,11 +276,12 @@ protected:
private:
// visual parameter stuff
- typedef std::map<S32, LLVisualParam *> VisualParamIndexMap_t;
- VisualParamIndexMap_t mVisualParamIndexMap;
- VisualParamIndexMap_t::iterator mCurIterator;
- typedef std::map<char *, LLVisualParam *> VisualParamNameMap_t;
- VisualParamNameMap_t mVisualParamNameMap;
+ typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
+ typedef std::map<char *, LLVisualParam *> visual_param_name_map_t;
+
+ visual_param_index_map_t::iterator mCurIterator;
+ visual_param_index_map_t mVisualParamIndexMap;
+ visual_param_name_map_t mVisualParamNameMap;
static LLStringTable sVisualParamNames;
};
diff --git a/indra/llcharacter/llvisualparam.cpp b/indra/llcharacter/llvisualparam.cpp
index c4763c6331..9e4957342c 100644
--- a/indra/llcharacter/llvisualparam.cpp
+++ b/indra/llcharacter/llvisualparam.cpp
@@ -305,7 +305,7 @@ void LLVisualParam::stopAnimating(BOOL set_by_user)
}
//virtual
-BOOL LLVisualParam::linkDrivenParams(visual_param_mapper mapper, bool only_cross_params)
+BOOL LLVisualParam::linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params)
{
// nothing to do for non-driver parameters
return TRUE;
diff --git a/indra/llcharacter/llvisualparam.h b/indra/llcharacter/llvisualparam.h
index e6503d611d..0b516b9374 100644
--- a/indra/llcharacter/llvisualparam.h
+++ b/indra/llcharacter/llvisualparam.h
@@ -96,10 +96,9 @@ protected:
//-----------------------------------------------------------------------------
class LLVisualParam
{
-protected:
- typedef boost::function<LLVisualParam*(S32)> visual_param_mapper;
-
public:
+ typedef boost::function<LLVisualParam*(S32)> visual_param_mapper;
+
LLVisualParam();
virtual ~LLVisualParam();
@@ -119,7 +118,7 @@ public:
virtual void animate(F32 delta, BOOL set_by_user);
virtual void stopAnimating(BOOL set_by_user);
- virtual BOOL linkDrivenParams(visual_param_mapper mapper, bool only_cross_params);
+ virtual BOOL linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params);
virtual void resetDrivenParams();
// Interface methods
@@ -161,7 +160,6 @@ protected:
S32 mID; // id for storing weight/morphtarget compares compactly
LLVisualParamInfo *mInfo;
-
};
#endif // LL_LLVisualParam_H
diff --git a/indra/llmessage/tests/llhost_test.cpp b/indra/llmessage/tests/llhost_test.cpp
index e0c562dbf4..f7e7eee88b 100644
--- a/indra/llmessage/tests/llhost_test.cpp
+++ b/indra/llmessage/tests/llhost_test.cpp
@@ -157,8 +157,7 @@ namespace tut
template<> template<>
void host_object::test<9>()
{
- skip("setHostByName(\"google.com\"); getHostName() -> (e.g.) \"yx-in-f100.1e100.net\"");
- std::string hostStr = "google.com";
+ skip("setHostByName(\"linux.org\"); getHostName() -> (e.g.) \"yx-in-f100.1e100.net\"");
LLHost host;
host.setHostByName(hostStr);
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 4bd5a83e37..f0b4436df5 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -1,230 +1,228 @@
-# -*- cmake -*-
-
-project(llui)
-
-include(00-Common)
-include(LLCommon)
-include(LLImage)
-include(LLMath)
-include(LLMessage)
-include(LLRender)
-include(LLWindow)
-include(LLVFS)
-include(LLXML)
-include(LLXUIXML)
-
-include_directories(
- ${LLCOMMON_INCLUDE_DIRS}
- ${LLIMAGE_INCLUDE_DIRS}
- ${LLMATH_INCLUDE_DIRS}
- ${LLMESSAGE_INCLUDE_DIRS}
- ${LLRENDER_INCLUDE_DIRS}
- ${LLWINDOW_INCLUDE_DIRS}
- ${LLVFS_INCLUDE_DIRS}
- ${LLXML_INCLUDE_DIRS}
- ${LLXUIXML_INCLUDE_DIRS}
- )
-
-set(llui_SOURCE_FILES
- llalertdialog.cpp
- llbutton.cpp
- llcheckboxctrl.cpp
- llclipboard.cpp
- llcombobox.cpp
- llconsole.cpp
- llcontainerview.cpp
- llctrlselectioninterface.cpp
- lldockablefloater.cpp
- lldockcontrol.cpp
- lldraghandle.cpp
- lleditmenuhandler.cpp
- llf32uictrl.cpp
- llfiltereditor.cpp
- llflatlistview.cpp
- llfloater.cpp
- llfloaterreg.cpp
- llfloaterreglistener.cpp
- llflyoutbutton.cpp
- llfocusmgr.cpp
- llfunctorregistry.cpp
- lliconctrl.cpp
- llkeywords.cpp
- lllayoutstack.cpp
- lllineeditor.cpp
- lllocalcliprect.cpp
- llmenubutton.cpp
- llmenugl.cpp
- llmodaldialog.cpp
- llmultifloater.cpp
- llmultislider.cpp
- llmultisliderctrl.cpp
- llnotifications.cpp
- llnotificationslistener.cpp
- llpanel.cpp
- llprogressbar.cpp
- llradiogroup.cpp
- llresizebar.cpp
- llresizehandle.cpp
- llresmgr.cpp
- llrngwriter.cpp
- llscrollbar.cpp
- llscrollcontainer.cpp
- llscrollingpanellist.cpp
- llscrolllistcell.cpp
- llscrolllistcolumn.cpp
- llscrolllistctrl.cpp
- llscrolllistitem.cpp
- llsdparam.cpp
- llsearcheditor.cpp
- llslider.cpp
- llsliderctrl.cpp
- llspinctrl.cpp
- llstatbar.cpp
- llstatgraph.cpp
- llstatview.cpp
- llstyle.cpp
- lltabcontainer.cpp
- lltextbase.cpp
- lltextbox.cpp
- lltexteditor.cpp
- lltextparser.cpp
- lltransientfloatermgr.cpp
- lltransutil.cpp
- lltoggleablemenu.cpp
- lltooltip.cpp
- llui.cpp
- lluicolortable.cpp
- lluictrl.cpp
- lluictrlfactory.cpp
- lluiimage.cpp
- lluistring.cpp
- llundo.cpp
- llurlaction.cpp
- llurlentry.cpp
- llurlmatch.cpp
- llurlregistry.cpp
- llviewborder.cpp
- llviewmodel.cpp
- llview.cpp
- llviewquery.cpp
- )
-
-set(llui_HEADER_FILES
- CMakeLists.txt
-
- llalertdialog.h
- llbutton.h
- llcallbackmap.h
- llcheckboxctrl.h
- llclipboard.h
- llcombobox.h
- llconsole.h
- llcontainerview.h
- llctrlselectioninterface.h
- lldraghandle.h
- lldockablefloater.h
- lldockcontrol.h
- lleditmenuhandler.h
- llf32uictrl.h
- llfiltereditor.h
- llflatlistview.h
- llfloater.h
- llfloaterreg.h
- llfloaterreglistener.h
- llflyoutbutton.h
- llfocusmgr.h
- llfunctorregistry.h
- llhandle.h
- llhelp.h
- lliconctrl.h
- llkeywords.h
- lllayoutstack.h
- lllazyvalue.h
- lllineeditor.h
- lllocalcliprect.h
- llmenubutton.h
- llmenugl.h
- llmodaldialog.h
- llmultifloater.h
- llmultisliderctrl.h
- llmultislider.h
- llnotifications.h
- llnotificationslistener.h
- llpanel.h
- llprogressbar.h
- llradiogroup.h
- llresizebar.h
- llresizehandle.h
- llresmgr.h
- llrngwriter.h
- llsearcheditor.h
- llscrollbar.h
- llscrollcontainer.h
- llscrollingpanellist.h
- llscrolllistcell.h
- llscrolllistcolumn.h
- llscrolllistctrl.h
- llscrolllistitem.h
- llsdparam.h
- llsliderctrl.h
- llslider.h
- llspinctrl.h
- llstatbar.h
- llstatgraph.h
- llstatview.h
- llstyle.h
- lltabcontainer.h
- lltextbase.h
- lltextbox.h
- lltexteditor.h
- lltextparser.h
- lltoggleablemenu.h
- lltooltip.h
- lltransientfloatermgr.h
- lltransutil.h
- lluicolortable.h
- lluiconstants.h
- lluictrlfactory.h
- lluictrl.h
- lluifwd.h
- llui.h
- lluiimage.h
- lluistring.h
- llundo.h
- llurlaction.h
- llurlentry.h
- llurlmatch.h
- llurlregistry.h
- llviewborder.h
- llviewmodel.h
- llview.h
- llviewquery.h
- )
-
-set_source_files_properties(${llui_HEADER_FILES}
- PROPERTIES HEADER_FILE_ONLY TRUE)
-
-list(APPEND llui_SOURCE_FILES ${llui_HEADER_FILES})
-
-add_library (llui ${llui_SOURCE_FILES})
-# Libraries on which this library depends, needed for Linux builds
-# Sort by high-level to low-level
-target_link_libraries(llui
- ${LLMESSAGE_LIBRARIES}
- ${LLRENDER_LIBRARIES}
- ${LLWINDOW_LIBRARIES}
- ${LLIMAGE_LIBRARIES}
- ${LLVFS_LIBRARIES} # ugh, just for LLDir
- ${LLXUIXML_LIBRARIES}
- ${LLXML_LIBRARIES}
- ${LLMATH_LIBRARIES}
- ${LLCOMMON_LIBRARIES} # must be after llimage, llwindow, llrender
- )
-
-# Add tests
-include(LLAddBuildTest)
-SET(llui_TEST_SOURCE_FILES
- llurlmatch.cpp
- llurlentry.cpp
- )
-LL_ADD_PROJECT_UNIT_TESTS(llui "${llui_TEST_SOURCE_FILES}")
+# -*- cmake -*-
+
+project(llui)
+
+include(00-Common)
+include(LLCommon)
+include(LLImage)
+include(LLMath)
+include(LLMessage)
+include(LLRender)
+include(LLWindow)
+include(LLVFS)
+include(LLXML)
+include(LLXUIXML)
+
+include_directories(
+ ${LLCOMMON_INCLUDE_DIRS}
+ ${LLIMAGE_INCLUDE_DIRS}
+ ${LLMATH_INCLUDE_DIRS}
+ ${LLMESSAGE_INCLUDE_DIRS}
+ ${LLRENDER_INCLUDE_DIRS}
+ ${LLWINDOW_INCLUDE_DIRS}
+ ${LLVFS_INCLUDE_DIRS}
+ ${LLXML_INCLUDE_DIRS}
+ ${LLXUIXML_INCLUDE_DIRS}
+ )
+
+set(llui_SOURCE_FILES
+ llalertdialog.cpp
+ llbutton.cpp
+ llcheckboxctrl.cpp
+ llclipboard.cpp
+ llcombobox.cpp
+ llconsole.cpp
+ llcontainerview.cpp
+ llctrlselectioninterface.cpp
+ lldockablefloater.cpp
+ lldockcontrol.cpp
+ lldraghandle.cpp
+ lleditmenuhandler.cpp
+ llf32uictrl.cpp
+ llfiltereditor.cpp
+ llflatlistview.cpp
+ llfloater.cpp
+ llfloaterreg.cpp
+ llfloaterreglistener.cpp
+ llflyoutbutton.cpp
+ llfocusmgr.cpp
+ llfunctorregistry.cpp
+ lliconctrl.cpp
+ llkeywords.cpp
+ lllayoutstack.cpp
+ lllineeditor.cpp
+ lllocalcliprect.cpp
+ llmenubutton.cpp
+ llmenugl.cpp
+ llmodaldialog.cpp
+ llmultifloater.cpp
+ llmultislider.cpp
+ llmultisliderctrl.cpp
+ llnotifications.cpp
+ llnotificationslistener.cpp
+ llpanel.cpp
+ llprogressbar.cpp
+ llradiogroup.cpp
+ llresizebar.cpp
+ llresizehandle.cpp
+ llresmgr.cpp
+ llrngwriter.cpp
+ llscrollbar.cpp
+ llscrollcontainer.cpp
+ llscrollingpanellist.cpp
+ llscrolllistcell.cpp
+ llscrolllistcolumn.cpp
+ llscrolllistctrl.cpp
+ llscrolllistitem.cpp
+ llsdparam.cpp
+ llsearcheditor.cpp
+ llslider.cpp
+ llsliderctrl.cpp
+ llspinctrl.cpp
+ llstatbar.cpp
+ llstatgraph.cpp
+ llstatview.cpp
+ llstyle.cpp
+ lltabcontainer.cpp
+ lltextbase.cpp
+ lltextbox.cpp
+ lltexteditor.cpp
+ lltextparser.cpp
+ lltransutil.cpp
+ lltoggleablemenu.cpp
+ lltooltip.cpp
+ llui.cpp
+ lluicolortable.cpp
+ lluictrl.cpp
+ lluictrlfactory.cpp
+ lluiimage.cpp
+ lluistring.cpp
+ llundo.cpp
+ llurlaction.cpp
+ llurlentry.cpp
+ llurlmatch.cpp
+ llurlregistry.cpp
+ llviewborder.cpp
+ llviewmodel.cpp
+ llview.cpp
+ llviewquery.cpp
+ )
+
+set(llui_HEADER_FILES
+ CMakeLists.txt
+
+ llalertdialog.h
+ llbutton.h
+ llcallbackmap.h
+ llcheckboxctrl.h
+ llclipboard.h
+ llcombobox.h
+ llconsole.h
+ llcontainerview.h
+ llctrlselectioninterface.h
+ lldraghandle.h
+ lldockablefloater.h
+ lldockcontrol.h
+ lleditmenuhandler.h
+ llf32uictrl.h
+ llfiltereditor.h
+ llflatlistview.h
+ llfloater.h
+ llfloaterreg.h
+ llfloaterreglistener.h
+ llflyoutbutton.h
+ llfocusmgr.h
+ llfunctorregistry.h
+ llhandle.h
+ llhelp.h
+ lliconctrl.h
+ llkeywords.h
+ lllayoutstack.h
+ lllazyvalue.h
+ lllineeditor.h
+ lllocalcliprect.h
+ llmenubutton.h
+ llmenugl.h
+ llmodaldialog.h
+ llmultifloater.h
+ llmultisliderctrl.h
+ llmultislider.h
+ llnotifications.h
+ llnotificationslistener.h
+ llpanel.h
+ llprogressbar.h
+ llradiogroup.h
+ llresizebar.h
+ llresizehandle.h
+ llresmgr.h
+ llrngwriter.h
+ llsearcheditor.h
+ llscrollbar.h
+ llscrollcontainer.h
+ llscrollingpanellist.h
+ llscrolllistcell.h
+ llscrolllistcolumn.h
+ llscrolllistctrl.h
+ llscrolllistitem.h
+ llsdparam.h
+ llsliderctrl.h
+ llslider.h
+ llspinctrl.h
+ llstatbar.h
+ llstatgraph.h
+ llstatview.h
+ llstyle.h
+ lltabcontainer.h
+ lltextbase.h
+ lltextbox.h
+ lltexteditor.h
+ lltextparser.h
+ lltoggleablemenu.h
+ lltooltip.h
+ lltransutil.h
+ lluicolortable.h
+ lluiconstants.h
+ lluictrlfactory.h
+ lluictrl.h
+ lluifwd.h
+ llui.h
+ lluiimage.h
+ lluistring.h
+ llundo.h
+ llurlaction.h
+ llurlentry.h
+ llurlmatch.h
+ llurlregistry.h
+ llviewborder.h
+ llviewmodel.h
+ llview.h
+ llviewquery.h
+ )
+
+set_source_files_properties(${llui_HEADER_FILES}
+ PROPERTIES HEADER_FILE_ONLY TRUE)
+
+list(APPEND llui_SOURCE_FILES ${llui_HEADER_FILES})
+
+add_library (llui ${llui_SOURCE_FILES})
+# Libraries on which this library depends, needed for Linux builds
+# Sort by high-level to low-level
+target_link_libraries(llui
+ ${LLMESSAGE_LIBRARIES}
+ ${LLRENDER_LIBRARIES}
+ ${LLWINDOW_LIBRARIES}
+ ${LLIMAGE_LIBRARIES}
+ ${LLVFS_LIBRARIES} # ugh, just for LLDir
+ ${LLXUIXML_LIBRARIES}
+ ${LLXML_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLCOMMON_LIBRARIES} # must be after llimage, llwindow, llrender
+ )
+
+# Add tests
+include(LLAddBuildTest)
+SET(llui_TEST_SOURCE_FILES
+ llurlmatch.cpp
+ llurlentry.cpp
+ )
+LL_ADD_PROJECT_UNIT_TESTS(llui "${llui_TEST_SOURCE_FILES}")
diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp
index 228d0e701f..35b3e486af 100644
--- a/indra/llui/lldockablefloater.cpp
+++ b/indra/llui/lldockablefloater.cpp
@@ -99,7 +99,7 @@ void LLDockableFloater::toggleInstance(const LLSD& sdname)
{
instance->setMinimized(FALSE);
instance->setVisible(TRUE);
- instance->setFocus(TRUE);
+ gFloaterView->bringToFront(instance);
}
}
@@ -141,6 +141,16 @@ void LLDockableFloater::setMinimized(BOOL minimize)
LLFloater::setMinimized(minimize);
}
+LLView * LLDockableFloater::getDockWidget()
+{
+ LLView * res = NULL;
+ if (getDockControl() != NULL) {
+ res = getDockControl()->getDock();
+ }
+
+ return res;
+}
+
void LLDockableFloater::onDockHidden()
{
setCanDock(FALSE);
diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h
index 499ce9ae8d..46491d8a29 100644
--- a/indra/llui/lldockablefloater.h
+++ b/indra/llui/lldockablefloater.h
@@ -78,6 +78,8 @@ public:
*/
/*virtual*/ void setMinimized(BOOL minimize);
+ LLView * getDockWidget();
+
virtual void onDockHidden();
virtual void onDockShown();
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index e8ffcac0ac..756a2900d3 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -63,6 +63,10 @@ public:
void on();
void off();
void setDock(LLView* dockWidget);
+ LLView* getDock()
+ {
+ return mDockWidget;
+ }
void repositionDockable();
void drawToungue();
bool isDockVisible();
diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h
index 10a7fd4544..899f6b9326 100644
--- a/indra/llui/llhandle.h
+++ b/indra/llui/llhandle.h
@@ -60,7 +60,7 @@ template <typename T>
class LLHandle
{
public:
- LLHandle() : mTombStone(sDefaultTombStone) {}
+ LLHandle() : mTombStone(getDefaultTombStone()) {}
const LLHandle<T>& operator =(const LLHandle<T>& other)
{
mTombStone = other.mTombStone;
@@ -74,7 +74,7 @@ public:
void markDead()
{
- mTombStone = sDefaultTombStone;
+ mTombStone = getDefaultTombStone();
}
T* get() const
@@ -104,13 +104,13 @@ protected:
LLPointer<LLTombStone<T> > mTombStone;
private:
- static LLPointer<LLTombStone<T> > sDefaultTombStone;
+ static LLPointer<LLTombStone<T> >& getDefaultTombStone()
+ {
+ static LLPointer<LLTombStone<T> > sDefaultTombStone = new LLTombStone<T>;
+ return sDefaultTombStone;
+ }
};
-// initialize static "empty" tombstone pointer
-template <typename T> LLPointer<LLTombStone<T> > LLHandle<T>::sDefaultTombStone = new LLTombStone<T>();
-
-
template <typename T>
class LLRootHandle : public LLHandle<T>
{
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 5eade72b61..24fd380bb1 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -229,7 +229,7 @@ static void get_attribute_bool_and_write(LLXMLNodePtr node,
LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)
{
LLLayoutStack::Params p(LLUICtrlFactory::getDefaultParams<LLLayoutStack>());
- LLXUIParser::instance().readXUI(node, p);
+ LLXUIParser::instance().readXUI(node, p, LLUICtrlFactory::getInstance()->getCurFileName());
// Export must happen before setupParams() mungles rectangles and before
// this item gets added to parent (otherwise screws up last_child_rect
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index a68b9cae57..ef222bad60 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1,1516 +1,1517 @@
-/**
-* @file llnotifications.cpp
-* @brief Non-UI queue manager for keeping a prioritized list of notifications
-*
-* $LicenseInfo:firstyear=2008&license=viewergpl$
-*
-* Copyright (c) 2008-2009, 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 "linden_common.h"
-
-#include "llnotifications.h"
-
-#include "lluictrl.h"
-#include "lluictrlfactory.h"
-#include "lldir.h"
-#include "llsdserialize.h"
-#include "lltrans.h"
-#include "llnotificationslistener.h"
-
-#include <algorithm>
-#include <boost/regex.hpp>
-
-
-const std::string NOTIFICATION_PERSIST_VERSION = "0.93";
-
-// local channel for notification history
-class LLNotificationHistoryChannel : public LLNotificationChannel
-{
- LOG_CLASS(LLNotificationHistoryChannel);
-public:
- LLNotificationHistoryChannel(const std::string& filename) :
- LLNotificationChannel("History", "Visible", &historyFilter, LLNotificationComparators::orderByUUID()),
- mFileName(filename)
- {
- connectChanged(boost::bind(&LLNotificationHistoryChannel::historyHandler, this, _1));
- loadPersistentNotifications();
- }
-
-private:
- bool historyHandler(const LLSD& payload)
- {
- // we ignore "load" messages, but rewrite the persistence file on any other
- std::string sigtype = payload["sigtype"];
- if (sigtype != "load")
- {
- savePersistentNotifications();
- }
- return false;
- }
-
- // The history channel gets all notifications except those that have been cancelled
- static bool historyFilter(LLNotificationPtr pNotification)
- {
- return !pNotification->isCancelled();
- }
-
- void savePersistentNotifications()
- {
- llinfos << "Saving open notifications to " << mFileName << llendl;
-
- llofstream notify_file(mFileName.c_str());
- if (!notify_file.is_open())
- {
- llwarns << "Failed to open " << mFileName << llendl;
- return;
- }
-
- LLSD output;
- output["version"] = NOTIFICATION_PERSIST_VERSION;
- LLSD& data = output["data"];
-
- for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
- {
- if (!LLNotifications::instance().templateExists((*it)->getName())) continue;
-
- // only store notifications flagged as persisting
- LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate((*it)->getName());
- if (!templatep->mPersist) continue;
-
- data.append((*it)->asLLSD());
- }
-
- LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
- formatter->format(output, notify_file, LLSDFormatter::OPTIONS_PRETTY);
- }
-
- void loadPersistentNotifications()
- {
- llinfos << "Loading open notifications from " << mFileName << llendl;
-
- llifstream notify_file(mFileName.c_str());
- if (!notify_file.is_open())
- {
- llwarns << "Failed to open " << mFileName << llendl;
- return;
- }
-
- LLSD input;
- LLPointer<LLSDParser> parser = new LLSDXMLParser();
- if (parser->parse(notify_file, input, LLSDSerialize::SIZE_UNLIMITED) < 0)
- {
- llwarns << "Failed to parse open notifications" << llendl;
- return;
- }
-
- if (input.isUndefined()) return;
- std::string version = input["version"];
- if (version != NOTIFICATION_PERSIST_VERSION)
- {
- llwarns << "Bad open notifications version: " << version << llendl;
- return;
- }
- LLSD& data = input["data"];
- if (data.isUndefined()) return;
-
- LLNotifications& instance = LLNotifications::instance();
- for (LLSD::array_const_iterator notification_it = data.beginArray();
- notification_it != data.endArray();
- ++notification_it)
- {
- instance.add(LLNotificationPtr(new LLNotification(*notification_it)));
- }
- }
-
- //virtual
- void onDelete(LLNotificationPtr pNotification)
- {
- // we want to keep deleted notifications in our log
- mItems.insert(pNotification);
-
- return;
- }
-
-private:
- std::string mFileName;
-};
-
-bool filterIgnoredNotifications(LLNotificationPtr notification)
-{
- // filter everything if we are to ignore ALL
- if(LLNotifications::instance().getIgnoreAllNotifications())
- {
- return false;
- }
-
- LLNotificationFormPtr form = notification->getForm();
- // Check to see if the user wants to ignore this alert
- if (form->getIgnoreType() != LLNotificationForm::IGNORE_NO)
- {
- return LLUI::sSettingGroups["ignores"]->getBOOL(notification->getName());
- }
-
- return true;
-}
-
-bool handleIgnoredNotification(const LLSD& payload)
-{
- if (payload["sigtype"].asString() == "add")
- {
- LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID());
- if (!pNotif) return false;
-
- LLNotificationFormPtr form = pNotif->getForm();
- LLSD response;
- switch(form->getIgnoreType())
- {
- case LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE:
- response = pNotif->getResponseTemplate(LLNotification::WITH_DEFAULT_BUTTON);
- break;
- case LLNotificationForm::IGNORE_WITH_LAST_RESPONSE:
- response = LLUI::sSettingGroups["ignores"]->getLLSD("Default" + pNotif->getName());
- break;
- case LLNotificationForm::IGNORE_SHOW_AGAIN:
- break;
- default:
- return false;
- }
- pNotif->setIgnored(true);
- pNotif->respond(response);
- return true; // don't process this item any further
- }
- return false;
-}
-
-namespace LLNotificationFilters
-{
- // a sample filter
- bool includeEverything(LLNotificationPtr p)
- {
- return true;
- }
-};
-
-LLNotificationForm::LLNotificationForm()
-: mFormData(LLSD::emptyArray()),
- mIgnore(IGNORE_NO)
-{
-}
-
-
-LLNotificationForm::LLNotificationForm(const std::string& name, const LLXMLNodePtr xml_node)
-: mFormData(LLSD::emptyArray()),
- mIgnore(IGNORE_NO)
-{
- if (!xml_node->hasName("form"))
- {
- llwarns << "Bad xml node for form: " << xml_node->getName() << llendl;
- }
- LLXMLNodePtr child = xml_node->getFirstChild();
- while(child)
- {
- child = LLNotifications::instance().checkForXMLTemplate(child);
-
- LLSD item_entry;
- std::string element_name = child->getName()->mString;
-
- if (element_name == "ignore" )
- {
- bool save_option = false;
- child->getAttribute_bool("save_option", save_option);
- if (!save_option)
- {
- mIgnore = IGNORE_WITH_DEFAULT_RESPONSE;
- }
- else
- {
- // remember last option chosen by user and automatically respond with that in the future
- mIgnore = IGNORE_WITH_LAST_RESPONSE;
- LLUI::sSettingGroups["ignores"]->declareLLSD(std::string("Default") + name, "", std::string("Default response for notification " + name));
- }
- child->getAttributeString("text", mIgnoreMsg);
- BOOL show_notification = TRUE;
- LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Ignore notification with this name", TRUE);
- }
- else
- {
- // flatten xml form entry into single LLSD map with type==name
- item_entry["type"] = element_name;
- const LLXMLAttribList::iterator attrib_end = child->mAttributes.end();
- for(LLXMLAttribList::iterator attrib_it = child->mAttributes.begin();
- attrib_it != attrib_end;
- ++attrib_it)
- {
- item_entry[std::string(attrib_it->second->getName()->mString)] = attrib_it->second->getValue();
- }
- item_entry["value"] = child->getTextContents();
- mFormData.append(item_entry);
- }
-
- child = child->getNextSibling();
- }
-}
-
-LLNotificationForm::LLNotificationForm(const LLSD& sd)
-{
- if (sd.isArray())
- {
- mFormData = sd;
- }
- else
- {
- llwarns << "Invalid form data " << sd << llendl;
- mFormData = LLSD::emptyArray();
- }
-}
-
-LLSD LLNotificationForm::asLLSD() const
-{
- return mFormData;
-}
-
-LLSD LLNotificationForm::getElement(const std::string& element_name)
-{
- for (LLSD::array_const_iterator it = mFormData.beginArray();
- it != mFormData.endArray();
- ++it)
- {
- if ((*it)["name"].asString() == element_name) return (*it);
- }
- return LLSD();
-}
-
-
-bool LLNotificationForm::hasElement(const std::string& element_name)
-{
- for (LLSD::array_const_iterator it = mFormData.beginArray();
- it != mFormData.endArray();
- ++it)
- {
- if ((*it)["name"].asString() == element_name) return true;
- }
- return false;
-}
-
-void LLNotificationForm::addElement(const std::string& type, const std::string& name, const LLSD& value)
-{
- LLSD element;
- element["type"] = type;
- element["name"] = name;
- element["text"] = name;
- element["value"] = value;
- element["index"] = mFormData.size();
- mFormData.append(element);
-}
-
-void LLNotificationForm::append(const LLSD& sub_form)
-{
- if (sub_form.isArray())
- {
- for (LLSD::array_const_iterator it = sub_form.beginArray();
- it != sub_form.endArray();
- ++it)
- {
- mFormData.append(*it);
- }
- }
-}
-
-void LLNotificationForm::formatElements(const LLSD& substitutions)
-{
- for (LLSD::array_iterator it = mFormData.beginArray();
- it != mFormData.endArray();
- ++it)
- {
- // format "text" component of each form element
- if ((*it).has("text"))
- {
- std::string text = (*it)["text"].asString();
- LLStringUtil::format(text, substitutions);
- (*it)["text"] = text;
- }
- if ((*it)["type"].asString() == "text" && (*it).has("value"))
- {
- std::string value = (*it)["value"].asString();
- LLStringUtil::format(value, substitutions);
- (*it)["value"] = value;
- }
- }
-}
-
-std::string LLNotificationForm::getDefaultOption()
-{
- for (LLSD::array_const_iterator it = mFormData.beginArray();
- it != mFormData.endArray();
- ++it)
- {
- if ((*it)["default"]) return (*it)["name"].asString();
- }
- return "";
-}
-
-LLNotificationTemplate::LLNotificationTemplate() :
- mExpireSeconds(0),
- mExpireOption(-1),
- mURLOption(-1),
- mURLOpenExternally(-1),
- mUnique(false),
- mPriority(NOTIFICATION_PRIORITY_NORMAL)
-{
- mForm = LLNotificationFormPtr(new LLNotificationForm());
-}
-
-LLNotification::LLNotification(const LLNotification::Params& p) :
- mTimestamp(p.time_stamp),
- mSubstitutions(p.substitutions),
- mPayload(p.payload),
- mExpiresAt(0),
- mTemporaryResponder(false),
- mRespondedTo(false),
- mPriority(p.priority),
- mCancelled(false),
- mIgnored(false)
-{
- if (p.functor.name.isChosen())
- {
- mResponseFunctorName = p.functor.name;
- }
- else if (p.functor.function.isChosen())
- {
- mResponseFunctorName = LLUUID::generateNewID().asString();
- LLNotificationFunctorRegistry::instance().registerFunctor(mResponseFunctorName, p.functor.function());
-
- mTemporaryResponder = true;
- }
-
- mId.generate();
- init(p.name, p.form_elements);
-}
-
-
-LLNotification::LLNotification(const LLSD& sd) :
- mTemporaryResponder(false),
- mRespondedTo(false),
- mCancelled(false),
- mIgnored(false)
-{
- mId.generate();
- mSubstitutions = sd["substitutions"];
- mPayload = sd["payload"];
- mTimestamp = sd["time"];
- mExpiresAt = sd["expiry"];
- mPriority = (ENotificationPriority)sd["priority"].asInteger();
- mResponseFunctorName = sd["responseFunctor"].asString();
- std::string templatename = sd["name"].asString();
- init(templatename, LLSD());
- // replace form with serialized version
- mForm = LLNotificationFormPtr(new LLNotificationForm(sd["form"]));
-}
-
-
-LLSD LLNotification::asLLSD()
-{
- LLSD output;
- output["name"] = mTemplatep->mName;
- output["form"] = getForm()->asLLSD();
- output["substitutions"] = mSubstitutions;
- output["payload"] = mPayload;
- output["time"] = mTimestamp;
- output["expiry"] = mExpiresAt;
- output["priority"] = (S32)mPriority;
- output["responseFunctor"] = mResponseFunctorName;
- return output;
-}
-
-void LLNotification::update()
-{
- LLNotifications::instance().update(shared_from_this());
-}
-
-void LLNotification::updateFrom(LLNotificationPtr other)
-{
- // can only update from the same notification type
- if (mTemplatep != other->mTemplatep) return;
-
- // NOTE: do NOT change the ID, since it is the key to
- // this given instance, just update all the metadata
- //mId = other->mId;
-
- mPayload = other->mPayload;
- mSubstitutions = other->mSubstitutions;
- mTimestamp = other->mTimestamp;
- mExpiresAt = other->mExpiresAt;
- mCancelled = other->mCancelled;
- mIgnored = other->mIgnored;
- mPriority = other->mPriority;
- mForm = other->mForm;
- mResponseFunctorName = other->mResponseFunctorName;
- mRespondedTo = other->mRespondedTo;
- mTemporaryResponder = other->mTemporaryResponder;
-
- update();
-}
-
-const LLNotificationFormPtr LLNotification::getForm()
-{
- return mForm;
-}
-
-void LLNotification::cancel()
-{
- mCancelled = true;
-}
-
-LLSD LLNotification::getResponseTemplate(EResponseTemplateType type)
-{
- LLSD response = LLSD::emptyMap();
- for (S32 element_idx = 0;
- element_idx < mForm->getNumElements();
- ++element_idx)
- {
- LLSD element = mForm->getElement(element_idx);
- if (element.has("name"))
- {
- response[element["name"].asString()] = element["value"];
- }
-
- if ((type == WITH_DEFAULT_BUTTON)
- && element["default"].asBoolean())
- {
- response[element["name"].asString()] = true;
- }
- }
- return response;
-}
-
-//static
-S32 LLNotification::getSelectedOption(const LLSD& notification, const LLSD& response)
-{
- LLNotificationForm form(notification["form"]);
-
- for (S32 element_idx = 0;
- element_idx < form.getNumElements();
- ++element_idx)
- {
- LLSD element = form.getElement(element_idx);
-
- // only look at buttons
- if (element["type"].asString() == "button"
- && response[element["name"].asString()].asBoolean())
- {
- return element["index"].asInteger();
- }
- }
-
- return -1;
-}
-
-//static
-std::string LLNotification::getSelectedOptionName(const LLSD& response)
-{
- for (LLSD::map_const_iterator response_it = response.beginMap();
- response_it != response.endMap();
- ++response_it)
- {
- if (response_it->second.isBoolean() && response_it->second.asBoolean())
- {
- return response_it->first;
- }
- }
- return "";
-}
-
-
-void LLNotification::respond(const LLSD& response)
-{
- mRespondedTo = true;
- // look up the functor
- LLNotificationFunctorRegistry::ResponseFunctor functor =
- LLNotificationFunctorRegistry::instance().getFunctor(mResponseFunctorName);
- // and then call it
- functor(asLLSD(), response);
-
- if (mTemporaryResponder)
- {
- LLNotificationFunctorRegistry::instance().unregisterFunctor(mResponseFunctorName);
- mResponseFunctorName = "";
- mTemporaryResponder = false;
- }
-
- if (mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)
- {
- BOOL show_notification = mIgnored ? FALSE : TRUE;
- LLUI::sSettingGroups["ignores"]->setBOOL(getName(), show_notification);
- if (mIgnored && mForm->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
- {
- LLUI::sSettingGroups["ignores"]->setLLSD("Default" + getName(), response);
- }
- }
-
- update();
-}
-
-void LLNotification::setIgnored(bool ignore)
-{
- mIgnored = ignore;
-}
-
-void LLNotification::setResponseFunctor(std::string const &responseFunctorName)
-{
- if (mTemporaryResponder)
- // get rid of the old one
- LLNotificationFunctorRegistry::instance().unregisterFunctor(mResponseFunctorName);
- mResponseFunctorName = responseFunctorName;
- mTemporaryResponder = false;
-}
-
-bool LLNotification::payloadContainsAll(const std::vector<std::string>& required_fields) const
-{
- for(std::vector<std::string>::const_iterator required_fields_it = required_fields.begin();
- required_fields_it != required_fields.end();
- required_fields_it++)
- {
- std::string required_field_name = *required_fields_it;
- if( ! getPayload().has(required_field_name))
- {
- return false; // a required field was not found
- }
- }
- return true; // all required fields were found
-}
-
-bool LLNotification::isEquivalentTo(LLNotificationPtr that) const
-{
- if (this->mTemplatep->mName != that->mTemplatep->mName)
- {
- return false; // must have the same template name or forget it
- }
- if (this->mTemplatep->mUnique)
- {
- // highlander bit sez there can only be one of these
- return
- this->payloadContainsAll(that->mTemplatep->mUniqueContext) &&
- that->payloadContainsAll(this->mTemplatep->mUniqueContext);
- }
- return false;
-}
-
-void LLNotification::init(const std::string& template_name, const LLSD& form_elements)
-{
- mTemplatep = LLNotifications::instance().getTemplate(template_name);
- if (!mTemplatep) return;
-
- // add default substitutions
- const LLStringUtil::format_map_t& default_args = LLTrans::getDefaultArgs();
- for (LLStringUtil::format_map_t::const_iterator iter = default_args.begin();
- iter != default_args.end(); ++iter)
- {
- mSubstitutions[iter->first] = iter->second;
- }
- mSubstitutions["_URL"] = getURL();
- mSubstitutions["_NAME"] = template_name;
- // TODO: something like this so that a missing alert is sensible:
- //mSubstitutions["_ARGS"] = get_all_arguments_as_text(mSubstitutions);
-
- mForm = LLNotificationFormPtr(new LLNotificationForm(*mTemplatep->mForm));
- mForm->append(form_elements);
-
- // apply substitution to form labels
- mForm->formatElements(mSubstitutions);
-
- LLDate rightnow = LLDate::now();
- if (mTemplatep->mExpireSeconds)
- {
- mExpiresAt = LLDate(rightnow.secondsSinceEpoch() + mTemplatep->mExpireSeconds);
- }
-
- if (mPriority == NOTIFICATION_PRIORITY_UNSPECIFIED)
- {
- mPriority = mTemplatep->mPriority;
- }
-}
-
-std::string LLNotification::summarize() const
-{
- std::string s = "Notification(";
- s += getName();
- s += ") : ";
- s += mTemplatep ? mTemplatep->mMessage : "";
- // should also include timestamp and expiration time (but probably not payload)
- return s;
-}
-
-std::string LLNotification::getMessage() const
-{
- // all our callers cache this result, so it gives us more flexibility
- // to do the substitution at call time rather than attempting to
- // cache it in the notification
- if (!mTemplatep)
- return std::string();
-
- std::string message = mTemplatep->mMessage;
- LLStringUtil::format(message, mSubstitutions);
- return message;
-}
-
-std::string LLNotification::getLabel() const
-{
- std::string label = mTemplatep->mLabel;
- LLStringUtil::format(label, mSubstitutions);
- return (mTemplatep ? label : "");
-}
-
-std::string LLNotification::getURL() const
-{
- if (!mTemplatep)
- return std::string();
- std::string url = mTemplatep->mURL;
- LLStringUtil::format(url, mSubstitutions);
- return (mTemplatep ? url : "");
-}
-
-// =========================================================
-// LLNotificationChannel implementation
-// ---
-LLBoundListener LLNotificationChannelBase::connectChangedImpl(const LLEventListener& slot)
-{
- // when someone wants to connect to a channel, we first throw them
- // all of the notifications that are already in the channel
- // we use a special signal called "load" in case the channel wants to care
- // only about new notifications
- for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
- {
- slot(LLSD().insert("sigtype", "load").insert("id", (*it)->id()));
- }
- // and then connect the signal so that all future notifications will also be
- // forwarded.
- return mChanged.connect(slot);
-}
-
-LLBoundListener LLNotificationChannelBase::connectAtFrontChangedImpl(const LLEventListener& slot)
-{
- for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
- {
- slot(LLSD().insert("sigtype", "load").insert("id", (*it)->id()));
- }
- return mChanged.connect(slot, boost::signals2::at_front);
-}
-
-LLBoundListener LLNotificationChannelBase::connectPassedFilterImpl(const LLEventListener& slot)
-{
- // these two filters only fire for notifications added after the current one, because
- // they don't participate in the hierarchy.
- return mPassedFilter.connect(slot);
-}
-
-LLBoundListener LLNotificationChannelBase::connectFailedFilterImpl(const LLEventListener& slot)
-{
- return mFailedFilter.connect(slot);
-}
-
-// external call, conforms to our standard signature
-bool LLNotificationChannelBase::updateItem(const LLSD& payload)
-{
- // first check to see if it's in the master list
- LLNotificationPtr pNotification = LLNotifications::instance().find(payload["id"]);
- if (!pNotification)
- return false; // not found
-
- return updateItem(payload, pNotification);
-}
-
-
-//FIX QUIT NOT WORKING
-
-
-// internal call, for use in avoiding lookup
-bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPtr pNotification)
-{
- std::string cmd = payload["sigtype"];
- LLNotificationSet::iterator foundItem = mItems.find(pNotification);
- bool wasFound = (foundItem != mItems.end());
- bool passesFilter = mFilter(pNotification);
-
- // first, we offer the result of the filter test to the simple
- // signals for pass/fail. One of these is guaranteed to be called.
- // If either signal returns true, the change processing is NOT performed
- // (so don't return true unless you know what you're doing!)
- bool abortProcessing = false;
- if (passesFilter)
- {
- abortProcessing = mPassedFilter(payload);
- }
- else
- {
- abortProcessing = mFailedFilter(payload);
- }
-
- if (abortProcessing)
- {
- return true;
- }
-
- if (cmd == "load")
- {
- // should be no reason we'd ever get a load if we already have it
- // if passes filter send a load message, else do nothing
- assert(!wasFound);
- if (passesFilter)
- {
- // not in our list, add it and say so
- mItems.insert(pNotification);
- abortProcessing = mChanged(payload);
- onLoad(pNotification);
- }
- }
- else if (cmd == "change")
- {
- // if it passes filter now and was found, we just send a change message
- // if it passes filter now and wasn't found, we have to add it
- // if it doesn't pass filter and wasn't found, we do nothing
- // if it doesn't pass filter and was found, we need to delete it
- if (passesFilter)
- {
- if (wasFound)
- {
- // it already existed, so this is a change
- // since it changed in place, all we have to do is resend the signal
- abortProcessing = mChanged(payload);
- onChange(pNotification);
- }
- else
- {
- // not in our list, add it and say so
- mItems.insert(pNotification);
- // our payload is const, so make a copy before changing it
- LLSD newpayload = payload;
- newpayload["sigtype"] = "add";
- abortProcessing = mChanged(newpayload);
- onChange(pNotification);
- }
- }
- else
- {
- if (wasFound)
- {
- // it already existed, so this is a delete
- mItems.erase(pNotification);
- // our payload is const, so make a copy before changing it
- LLSD newpayload = payload;
- newpayload["sigtype"] = "delete";
- abortProcessing = mChanged(newpayload);
- onChange(pNotification);
- }
- // didn't pass, not on our list, do nothing
- }
- }
- else if (cmd == "add")
- {
- // should be no reason we'd ever get an add if we already have it
- // if passes filter send an add message, else do nothing
- assert(!wasFound);
- if (passesFilter)
- {
- // not in our list, add it and say so
- mItems.insert(pNotification);
- abortProcessing = mChanged(payload);
- onAdd(pNotification);
- }
- }
- else if (cmd == "delete")
- {
- // if we have it in our list, pass on the delete, then delete it, else do nothing
- if (wasFound)
- {
- abortProcessing = mChanged(payload);
- mItems.erase(pNotification);
- onDelete(pNotification);
- }
- }
- return abortProcessing;
-}
-
-/* static */
-LLNotificationChannelPtr LLNotificationChannel::buildChannel(const std::string& name,
- const std::string& parent,
- LLNotificationFilter filter,
- LLNotificationComparator comparator)
-{
- // note: this is not a leak; notifications are self-registering.
- // This factory helps to prevent excess deletions by making sure all smart
- // pointers to notification channels come from the same source
- new LLNotificationChannel(name, parent, filter, comparator);
- return LLNotifications::instance().getChannel(name);
-}
-
-
-LLNotificationChannel::LLNotificationChannel(const std::string& name,
- const std::string& parent,
- LLNotificationFilter filter,
- LLNotificationComparator comparator) :
-LLNotificationChannelBase(filter, comparator),
-mName(name),
-mParent(parent)
-{
- // store myself in the channel map
- LLNotifications::instance().addChannel(LLNotificationChannelPtr(this));
- // bind to notification broadcast
- if (parent.empty())
- {
- LLNotifications::instance().connectChanged(
- boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
- }
- else
- {
- LLNotificationChannelPtr p = LLNotifications::instance().getChannel(parent);
- p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
- }
-}
-
-
-void LLNotificationChannel::setComparator(LLNotificationComparator comparator)
-{
- mComparator = comparator;
- LLNotificationSet s2(mComparator);
- s2.insert(mItems.begin(), mItems.end());
- mItems.swap(s2);
-
- // notify clients that we've been resorted
- mChanged(LLSD().insert("sigtype", "sort"));
-}
-
-bool LLNotificationChannel::isEmpty() const
-{
- return mItems.empty();
-}
-
-LLNotificationChannel::Iterator LLNotificationChannel::begin()
-{
- return mItems.begin();
-}
-
-LLNotificationChannel::Iterator LLNotificationChannel::end()
-{
- return mItems.end();
-}
-
-std::string LLNotificationChannel::summarize()
-{
- std::string s("Channel '");
- s += mName;
- s += "'\n ";
- for (LLNotificationChannel::Iterator it = begin(); it != end(); ++it)
- {
- s += (*it)->summarize();
- s += "\n ";
- }
- return s;
-}
-
-
-// ---
-// END OF LLNotificationChannel implementation
-// =========================================================
-
-
-// =========================================================
-// LLNotifications implementation
-// ---
-LLNotifications::LLNotifications() : LLNotificationChannelBase(LLNotificationFilters::includeEverything,
- LLNotificationComparators::orderByUUID()),
- mIgnoreAllNotifications(false)
-{
- LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
-
- mListener.reset(new LLNotificationsListener(*this));
-}
-
-
-// The expiration channel gets all notifications that are cancelled
-bool LLNotifications::expirationFilter(LLNotificationPtr pNotification)
-{
- return pNotification->isCancelled() || pNotification->isRespondedTo();
-}
-
-bool LLNotifications::expirationHandler(const LLSD& payload)
-{
- if (payload["sigtype"].asString() != "delete")
- {
- // anything added to this channel actually should be deleted from the master
- cancel(find(payload["id"]));
- return true; // don't process this item any further
- }
- return false;
-}
-
-bool LLNotifications::uniqueFilter(LLNotificationPtr pNotif)
-{
- if (!pNotif->hasUniquenessConstraints())
- {
- return true;
- }
-
- // checks against existing unique notifications
- for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
- existing_it != mUniqueNotifications.end();
- ++existing_it)
- {
- LLNotificationPtr existing_notification = existing_it->second;
- if (pNotif != existing_notification
- && pNotif->isEquivalentTo(existing_notification))
- {
- return false;
- }
- }
-
- return true;
-}
-
-bool LLNotifications::uniqueHandler(const LLSD& payload)
-{
- LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID());
- if (pNotif && pNotif->hasUniquenessConstraints())
- {
- if (payload["sigtype"].asString() == "add")
- {
- // not a duplicate according to uniqueness criteria, so we keep it
- // and store it for future uniqueness checks
- mUniqueNotifications.insert(std::make_pair(pNotif->getName(), pNotif));
- }
- else if (payload["sigtype"].asString() == "delete")
- {
- mUniqueNotifications.erase(pNotif->getName());
- }
- }
-
- return false;
-}
-
-bool LLNotifications::failedUniquenessTest(const LLSD& payload)
-{
- LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID());
-
- if (!pNotif || !pNotif->hasUniquenessConstraints())
- {
- return false;
- }
-
- // checks against existing unique notifications
- for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
- existing_it != mUniqueNotifications.end();
- ++existing_it)
- {
- LLNotificationPtr existing_notification = existing_it->second;
- if (pNotif != existing_notification
- && pNotif->isEquivalentTo(existing_notification))
- {
- // copy notification instance data over to oldest instance
- // of this unique notification and update it
- existing_notification->updateFrom(pNotif);
- // then delete the new one
- pNotif->cancel();
- }
- }
-
- return false;
-}
-
-
-void LLNotifications::addChannel(LLNotificationChannelPtr pChan)
-{
- mChannels[pChan->getName()] = pChan;
-}
-
-LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelName)
-{
- ChannelMap::iterator p = mChannels.find(channelName);
- if(p == mChannels.end())
- {
- llerrs << "Did not find channel named " << channelName << llendl;
- }
- return p->second;
-}
-
-
-// this function is called once at construction time, after the object is constructed.
-void LLNotifications::initSingleton()
-{
- loadTemplates();
- createDefaultChannels();
-}
-
-void LLNotifications::createDefaultChannels()
-{
- // now construct the various channels AFTER loading the notifications,
- // because the history channel is going to rewrite the stored notifications file
- LLNotificationChannel::buildChannel("Expiration", "",
- boost::bind(&LLNotifications::expirationFilter, this, _1));
- LLNotificationChannel::buildChannel("Unexpired", "",
- !boost::bind(&LLNotifications::expirationFilter, this, _1)); // use negated bind
- LLNotificationChannel::buildChannel("Unique", "Unexpired",
- boost::bind(&LLNotifications::uniqueFilter, this, _1));
- LLNotificationChannel::buildChannel("Ignore", "Unique",
- filterIgnoredNotifications);
- LLNotificationChannel::buildChannel("Visible", "Ignore",
- &LLNotificationFilters::includeEverything);
-
- // create special history channel
- //std::string notifications_log_file = gDirUtilp->getExpandedFilename ( LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml" );
- // use ^^^ when done debugging notifications serialization
- std::string notifications_log_file = gDirUtilp->getExpandedFilename ( LL_PATH_USER_SETTINGS, "open_notifications.xml" );
- // this isn't a leak, don't worry about the empty "new"
- new LLNotificationHistoryChannel(notifications_log_file);
-
- // connect action methods to these channels
- LLNotifications::instance().getChannel("Expiration")->
- connectChanged(boost::bind(&LLNotifications::expirationHandler, this, _1));
- // uniqueHandler slot should be added as first slot of the signal due to
- // usage LLStopWhenHandled combiner in LLStandardSignal
- LLNotifications::instance().getChannel("Unique")->
- connectAtFrontChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1));
-// failedUniquenessTest slot isn't necessary
-// LLNotifications::instance().getChannel("Unique")->
-// connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1));
- LLNotifications::instance().getChannel("Ignore")->
- connectFailedFilter(&handleIgnoredNotification);
-}
-
-bool LLNotifications::addTemplate(const std::string &name,
- LLNotificationTemplatePtr theTemplate)
-{
- if (mTemplates.count(name))
- {
- llwarns << "LLNotifications -- attempted to add template '" << name << "' twice." << llendl;
- return false;
- }
- mTemplates[name] = theTemplate;
- return true;
-}
-
-LLNotificationTemplatePtr LLNotifications::getTemplate(const std::string& name)
-{
- if (mTemplates.count(name))
- {
- return mTemplates[name];
- }
- else
- {
- return mTemplates["MissingAlert"];
- }
-}
-
-bool LLNotifications::templateExists(const std::string& name)
-{
- return (mTemplates.count(name) != 0);
-}
-
-void LLNotifications::clearTemplates()
-{
- mTemplates.clear();
-}
-
-void LLNotifications::forceResponse(const LLNotification::Params& params, S32 option)
-{
- LLNotificationPtr temp_notify(new LLNotification(params));
- LLSD response = temp_notify->getResponseTemplate();
- LLSD selected_item = temp_notify->getForm()->getElement(option);
-
- if (selected_item.isUndefined())
- {
- llwarns << "Invalid option" << option << " for notification " << (std::string)params.name << llendl;
- return;
- }
- response[selected_item["name"].asString()] = true;
-
- temp_notify->respond(response);
-}
-
-LLNotifications::TemplateNames LLNotifications::getTemplateNames() const
-{
- TemplateNames names;
- for (TemplateMap::const_iterator it = mTemplates.begin(); it != mTemplates.end(); ++it)
- {
- names.push_back(it->first);
- }
- return names;
-}
-
-typedef std::map<std::string, std::string> StringMap;
-void replaceSubstitutionStrings(LLXMLNodePtr node, StringMap& replacements)
-{
- //llwarns << "replaceSubstitutionStrings" << llendl;
- // walk the list of attributes looking for replacements
- for (LLXMLAttribList::iterator it=node->mAttributes.begin();
- it != node->mAttributes.end(); ++it)
- {
- std::string value = it->second->getValue();
- if (value[0] == '$')
- {
- value.erase(0, 1); // trim off the $
- std::string replacement;
- StringMap::const_iterator found = replacements.find(value);
- if (found != replacements.end())
- {
- replacement = found->second;
- //llwarns << "replaceSubstituionStrings: value: " << value << " repl: " << replacement << llendl;
-
- it->second->setValue(replacement);
- }
- else
- {
- llwarns << "replaceSubstituionStrings FAILURE: value: " << value << " repl: " << replacement << llendl;
- }
- }
- }
-
- // now walk the list of children and call this recursively.
- for (LLXMLNodePtr child = node->getFirstChild();
- child.notNull(); child = child->getNextSibling())
- {
- replaceSubstitutionStrings(child, replacements);
- }
-}
-
-// private to this file
-// returns true if the template request was invalid and there's nothing else we
-// can do with this node, false if you should keep processing (it may have
-// replaced the contents of the node referred to)
-LLXMLNodePtr LLNotifications::checkForXMLTemplate(LLXMLNodePtr item)
-{
- if (item->hasName("usetemplate"))
- {
- std::string replacementName;
- if (item->getAttributeString("name", replacementName))
- {
- StringMap replacements;
- for (LLXMLAttribList::const_iterator it=item->mAttributes.begin();
- it != item->mAttributes.end(); ++it)
- {
- replacements[it->second->getName()->mString] = it->second->getValue();
- }
- if (mXmlTemplates.count(replacementName))
- {
- item=LLXMLNode::replaceNode(item, mXmlTemplates[replacementName]);
-
- // walk the nodes looking for $(substitution) here and replace
- replaceSubstitutionStrings(item, replacements);
- }
- else
- {
- llwarns << "XML template lookup failure on '" << replacementName << "' " << llendl;
- }
- }
- }
- return item;
-}
-
-bool LLNotifications::loadTemplates()
-{
- const std::string xml_filename = "notifications.xml";
- LLXMLNodePtr root;
-
- BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
-
- if (!success || root.isNull() || !root->hasName( "notifications" ))
- {
- llerrs << "Problem reading UI Notifications file: " << xml_filename << llendl;
- return false;
- }
-
- clearTemplates();
-
- for (LLXMLNodePtr item = root->getFirstChild();
- item.notNull(); item = item->getNextSibling())
- {
- // we do this FIRST so that item can be changed if we
- // encounter a usetemplate -- we just replace the
- // current xml node and keep processing
- item = checkForXMLTemplate(item);
-
- if (item->hasName("global"))
- {
- std::string global_name;
- if (item->getAttributeString("name", global_name))
- {
- mGlobalStrings[global_name] = item->getTextContents();
- }
- continue;
- }
-
- if (item->hasName("template"))
- {
- // store an xml template; templates must have a single node (can contain
- // other nodes)
- std::string name;
- item->getAttributeString("name", name);
- LLXMLNodePtr ptr = item->getFirstChild();
- mXmlTemplates[name] = ptr;
- continue;
- }
-
- if (!item->hasName("notification"))
- {
- llwarns << "Unexpected entity " << item->getName()->mString <<
- " found in " << xml_filename << llendl;
- continue;
- }
-
- // now we know we have a notification entry, so let's build it
- LLNotificationTemplatePtr pTemplate(new LLNotificationTemplate());
-
- if (!item->getAttributeString("name", pTemplate->mName))
- {
- llwarns << "Unable to parse notification with no name" << llendl;
- continue;
- }
-
- //llinfos << "Parsing " << pTemplate->mName << llendl;
-
- pTemplate->mMessage = item->getTextContents();
- pTemplate->mDefaultFunctor = pTemplate->mName;
- item->getAttributeString("type", pTemplate->mType);
- item->getAttributeString("icon", pTemplate->mIcon);
- item->getAttributeString("label", pTemplate->mLabel);
- item->getAttributeU32("duration", pTemplate->mExpireSeconds);
- item->getAttributeU32("expireOption", pTemplate->mExpireOption);
-
- std::string priority;
- item->getAttributeString("priority", priority);
- pTemplate->mPriority = NOTIFICATION_PRIORITY_NORMAL;
- if (!priority.empty())
- {
- if (priority == "low") pTemplate->mPriority = NOTIFICATION_PRIORITY_LOW;
- if (priority == "normal") pTemplate->mPriority = NOTIFICATION_PRIORITY_NORMAL;
- if (priority == "high") pTemplate->mPriority = NOTIFICATION_PRIORITY_HIGH;
- if (priority == "critical") pTemplate->mPriority = NOTIFICATION_PRIORITY_CRITICAL;
- }
-
- item->getAttributeString("functor", pTemplate->mDefaultFunctor);
-
- BOOL persist = false;
- item->getAttributeBOOL("persist", persist);
- pTemplate->mPersist = persist;
-
- std::string sound;
- item->getAttributeString("sound", sound);
- if (!sound.empty())
- {
- // test for bad sound effect name / missing effect
- if (LLUI::sSettingGroups["config"]->controlExists(sound))
- {
- pTemplate->mSoundEffect =
- LLUUID(LLUI::sSettingGroups["config"]->getString(sound));
- }
- else
- {
- llwarns << "Unknown sound effect control name " << sound
- << llendl;
- }
- }
-
- for (LLXMLNodePtr child = item->getFirstChild();
- !child.isNull(); child = child->getNextSibling())
- {
- child = checkForXMLTemplate(child);
-
- // <url>
- if (child->hasName("url"))
- {
- pTemplate->mURL = child->getTextContents();
- child->getAttributeU32("option", pTemplate->mURLOption);
- child->getAttributeU32("openexternally", pTemplate->mURLOpenExternally);
- }
-
- if (child->hasName("unique"))
- {
- pTemplate->mUnique = true;
- for (LLXMLNodePtr formitem = child->getFirstChild();
- !formitem.isNull(); formitem = formitem->getNextSibling())
- {
- if (formitem->hasName("context"))
- {
- std::string key;
- formitem->getAttributeString("key", key);
- pTemplate->mUniqueContext.push_back(key);
- //llwarns << "adding " << key << " to unique context" << llendl;
- }
- else
- {
- llwarns << "'unique' has unrecognized subelement "
- << formitem->getName()->mString << llendl;
- }
- }
- }
-
- // <form>
- if (child->hasName("form"))
- {
- pTemplate->mForm = LLNotificationFormPtr(new LLNotificationForm(pTemplate->mName, child));
- }
- }
- addTemplate(pTemplate->mName, pTemplate);
- }
-
- //std::ostringstream ostream;
- //root->writeToOstream(ostream, "\n ");
- //llwarns << ostream.str() << llendl;
-
- return true;
-}
-
-// Add a simple notification (from XUI)
-void LLNotifications::addFromCallback(const LLSD& name)
-{
- add(LLNotification::Params().name(name.asString()));
-}
-
-// we provide a couple of simple add notification functions so that it's reasonable to create notifications in one line
-LLNotificationPtr LLNotifications::add(const std::string& name,
- const LLSD& substitutions,
- const LLSD& payload)
-{
- LLNotification::Params::Functor functor_p;
- functor_p.name = name;
- return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
-}
-
-LLNotificationPtr LLNotifications::add(const std::string& name,
- const LLSD& substitutions,
- const LLSD& payload,
- const std::string& functor_name)
-{
- LLNotification::Params::Functor functor_p;
- functor_p.name = functor_name;
- return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
-}
-
-LLNotificationPtr LLNotifications::add(const std::string& name,
- const LLSD& substitutions,
- const LLSD& payload,
- LLNotificationFunctorRegistry::ResponseFunctor functor)
-{
- LLNotification::Params::Functor functor_p;
- functor_p.function = functor;
- return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
-}
-
-// generalized add function that takes a parameter block object for more complex instantiations
-LLNotificationPtr LLNotifications::add(const LLNotification::Params& p)
-{
- LLNotificationPtr pNotif(new LLNotification(p));
- add(pNotif);
- return pNotif;
-}
-
-
-void LLNotifications::add(const LLNotificationPtr pNotif)
-{
- // first see if we already have it -- if so, that's a problem
- LLNotificationSet::iterator it=mItems.find(pNotif);
- if (it != mItems.end())
- {
- llerrs << "Notification added a second time to the master notification channel." << llendl;
- }
-
- updateItem(LLSD().insert("sigtype", "add").insert("id", pNotif->id()), pNotif);
-}
-
-void LLNotifications::cancel(LLNotificationPtr pNotif)
-{
- LLNotificationSet::iterator it=mItems.find(pNotif);
- if (it == mItems.end())
- {
- llerrs << "Attempted to delete nonexistent notification " << pNotif->getName() << llendl;
- }
- pNotif->cancel();
- updateItem(LLSD().insert("sigtype", "delete").insert("id", pNotif->id()), pNotif);
-}
-
-void LLNotifications::update(const LLNotificationPtr pNotif)
-{
- LLNotificationSet::iterator it=mItems.find(pNotif);
- if (it != mItems.end())
- {
- updateItem(LLSD().insert("sigtype", "change").insert("id", pNotif->id()), pNotif);
- }
-}
-
-
-LLNotificationPtr LLNotifications::find(LLUUID uuid)
-{
- LLNotificationPtr target = LLNotificationPtr(new LLNotification(uuid));
- LLNotificationSet::iterator it=mItems.find(target);
- if (it == mItems.end())
- {
- llwarns << "Tried to dereference uuid '" << uuid << "' as a notification key but didn't find it." << llendl;
- return LLNotificationPtr((LLNotification*)NULL);
- }
- else
- {
- return *it;
- }
-}
-
-void LLNotifications::forEachNotification(NotificationProcess process)
-{
- std::for_each(mItems.begin(), mItems.end(), process);
-}
-
-std::string LLNotifications::getGlobalString(const std::string& key) const
-{
- GlobalStringMap::const_iterator it = mGlobalStrings.find(key);
- if (it != mGlobalStrings.end())
- {
- return it->second;
- }
- else
- {
- // if we don't have the key as a global, return the key itself so that the error
- // is self-diagnosing.
- return key;
- }
-}
-
-void LLNotifications::setIgnoreAllNotifications(bool setting)
-{
- mIgnoreAllNotifications = setting;
-}
-bool LLNotifications::getIgnoreAllNotifications()
-{
- return mIgnoreAllNotifications;
-}
-
-// ---
-// END OF LLNotifications implementation
-// =========================================================
-
-std::ostream& operator<<(std::ostream& s, const LLNotification& notification)
-{
- s << notification.summarize();
- return s;
-}
-
+/**
+* @file llnotifications.cpp
+* @brief Non-UI queue manager for keeping a prioritized list of notifications
+*
+* $LicenseInfo:firstyear=2008&license=viewergpl$
+*
+* Copyright (c) 2008-2009, 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 "linden_common.h"
+
+#include "llnotifications.h"
+
+#include "llxmlnode.h"
+#include "lluictrl.h"
+#include "lluictrlfactory.h"
+#include "lldir.h"
+#include "llsdserialize.h"
+#include "lltrans.h"
+#include "llnotificationslistener.h"
+
+#include <algorithm>
+#include <boost/regex.hpp>
+
+
+const std::string NOTIFICATION_PERSIST_VERSION = "0.93";
+
+// local channel for notification history
+class LLNotificationHistoryChannel : public LLNotificationChannel
+{
+ LOG_CLASS(LLNotificationHistoryChannel);
+public:
+ LLNotificationHistoryChannel(const std::string& filename) :
+ LLNotificationChannel("History", "Visible", &historyFilter, LLNotificationComparators::orderByUUID()),
+ mFileName(filename)
+ {
+ connectChanged(boost::bind(&LLNotificationHistoryChannel::historyHandler, this, _1));
+ loadPersistentNotifications();
+ }
+
+private:
+ bool historyHandler(const LLSD& payload)
+ {
+ // we ignore "load" messages, but rewrite the persistence file on any other
+ std::string sigtype = payload["sigtype"];
+ if (sigtype != "load")
+ {
+ savePersistentNotifications();
+ }
+ return false;
+ }
+
+ // The history channel gets all notifications except those that have been cancelled
+ static bool historyFilter(LLNotificationPtr pNotification)
+ {
+ return !pNotification->isCancelled();
+ }
+
+ void savePersistentNotifications()
+ {
+ llinfos << "Saving open notifications to " << mFileName << llendl;
+
+ llofstream notify_file(mFileName.c_str());
+ if (!notify_file.is_open())
+ {
+ llwarns << "Failed to open " << mFileName << llendl;
+ return;
+ }
+
+ LLSD output;
+ output["version"] = NOTIFICATION_PERSIST_VERSION;
+ LLSD& data = output["data"];
+
+ for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
+ {
+ if (!LLNotifications::instance().templateExists((*it)->getName())) continue;
+
+ // only store notifications flagged as persisting
+ LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate((*it)->getName());
+ if (!templatep->mPersist) continue;
+
+ data.append((*it)->asLLSD());
+ }
+
+ LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
+ formatter->format(output, notify_file, LLSDFormatter::OPTIONS_PRETTY);
+ }
+
+ void loadPersistentNotifications()
+ {
+ llinfos << "Loading open notifications from " << mFileName << llendl;
+
+ llifstream notify_file(mFileName.c_str());
+ if (!notify_file.is_open())
+ {
+ llwarns << "Failed to open " << mFileName << llendl;
+ return;
+ }
+
+ LLSD input;
+ LLPointer<LLSDParser> parser = new LLSDXMLParser();
+ if (parser->parse(notify_file, input, LLSDSerialize::SIZE_UNLIMITED) < 0)
+ {
+ llwarns << "Failed to parse open notifications" << llendl;
+ return;
+ }
+
+ if (input.isUndefined()) return;
+ std::string version = input["version"];
+ if (version != NOTIFICATION_PERSIST_VERSION)
+ {
+ llwarns << "Bad open notifications version: " << version << llendl;
+ return;
+ }
+ LLSD& data = input["data"];
+ if (data.isUndefined()) return;
+
+ LLNotifications& instance = LLNotifications::instance();
+ for (LLSD::array_const_iterator notification_it = data.beginArray();
+ notification_it != data.endArray();
+ ++notification_it)
+ {
+ instance.add(LLNotificationPtr(new LLNotification(*notification_it)));
+ }
+ }
+
+ //virtual
+ void onDelete(LLNotificationPtr pNotification)
+ {
+ // we want to keep deleted notifications in our log
+ mItems.insert(pNotification);
+
+ return;
+ }
+
+private:
+ std::string mFileName;
+};
+
+bool filterIgnoredNotifications(LLNotificationPtr notification)
+{
+ // filter everything if we are to ignore ALL
+ if(LLNotifications::instance().getIgnoreAllNotifications())
+ {
+ return false;
+ }
+
+ LLNotificationFormPtr form = notification->getForm();
+ // Check to see if the user wants to ignore this alert
+ if (form->getIgnoreType() != LLNotificationForm::IGNORE_NO)
+ {
+ return LLUI::sSettingGroups["ignores"]->getBOOL(notification->getName());
+ }
+
+ return true;
+}
+
+bool handleIgnoredNotification(const LLSD& payload)
+{
+ if (payload["sigtype"].asString() == "add")
+ {
+ LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID());
+ if (!pNotif) return false;
+
+ LLNotificationFormPtr form = pNotif->getForm();
+ LLSD response;
+ switch(form->getIgnoreType())
+ {
+ case LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE:
+ response = pNotif->getResponseTemplate(LLNotification::WITH_DEFAULT_BUTTON);
+ break;
+ case LLNotificationForm::IGNORE_WITH_LAST_RESPONSE:
+ response = LLUI::sSettingGroups["ignores"]->getLLSD("Default" + pNotif->getName());
+ break;
+ case LLNotificationForm::IGNORE_SHOW_AGAIN:
+ break;
+ default:
+ return false;
+ }
+ pNotif->setIgnored(true);
+ pNotif->respond(response);
+ return true; // don't process this item any further
+ }
+ return false;
+}
+
+namespace LLNotificationFilters
+{
+ // a sample filter
+ bool includeEverything(LLNotificationPtr p)
+ {
+ return true;
+ }
+};
+
+LLNotificationForm::LLNotificationForm()
+: mFormData(LLSD::emptyArray()),
+ mIgnore(IGNORE_NO)
+{
+}
+
+
+LLNotificationForm::LLNotificationForm(const std::string& name, const LLXMLNodePtr xml_node)
+: mFormData(LLSD::emptyArray()),
+ mIgnore(IGNORE_NO)
+{
+ if (!xml_node->hasName("form"))
+ {
+ llwarns << "Bad xml node for form: " << xml_node->getName() << llendl;
+ }
+ LLXMLNodePtr child = xml_node->getFirstChild();
+ while(child)
+ {
+ child = LLNotifications::instance().checkForXMLTemplate(child);
+
+ LLSD item_entry;
+ std::string element_name = child->getName()->mString;
+
+ if (element_name == "ignore" )
+ {
+ bool save_option = false;
+ child->getAttribute_bool("save_option", save_option);
+ if (!save_option)
+ {
+ mIgnore = IGNORE_WITH_DEFAULT_RESPONSE;
+ }
+ else
+ {
+ // remember last option chosen by user and automatically respond with that in the future
+ mIgnore = IGNORE_WITH_LAST_RESPONSE;
+ LLUI::sSettingGroups["ignores"]->declareLLSD(std::string("Default") + name, "", std::string("Default response for notification " + name));
+ }
+ child->getAttributeString("text", mIgnoreMsg);
+ BOOL show_notification = TRUE;
+ LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Ignore notification with this name", TRUE);
+ }
+ else
+ {
+ // flatten xml form entry into single LLSD map with type==name
+ item_entry["type"] = element_name;
+ const LLXMLAttribList::iterator attrib_end = child->mAttributes.end();
+ for(LLXMLAttribList::iterator attrib_it = child->mAttributes.begin();
+ attrib_it != attrib_end;
+ ++attrib_it)
+ {
+ item_entry[std::string(attrib_it->second->getName()->mString)] = attrib_it->second->getValue();
+ }
+ item_entry["value"] = child->getTextContents();
+ mFormData.append(item_entry);
+ }
+
+ child = child->getNextSibling();
+ }
+}
+
+LLNotificationForm::LLNotificationForm(const LLSD& sd)
+{
+ if (sd.isArray())
+ {
+ mFormData = sd;
+ }
+ else
+ {
+ llwarns << "Invalid form data " << sd << llendl;
+ mFormData = LLSD::emptyArray();
+ }
+}
+
+LLSD LLNotificationForm::asLLSD() const
+{
+ return mFormData;
+}
+
+LLSD LLNotificationForm::getElement(const std::string& element_name)
+{
+ for (LLSD::array_const_iterator it = mFormData.beginArray();
+ it != mFormData.endArray();
+ ++it)
+ {
+ if ((*it)["name"].asString() == element_name) return (*it);
+ }
+ return LLSD();
+}
+
+
+bool LLNotificationForm::hasElement(const std::string& element_name)
+{
+ for (LLSD::array_const_iterator it = mFormData.beginArray();
+ it != mFormData.endArray();
+ ++it)
+ {
+ if ((*it)["name"].asString() == element_name) return true;
+ }
+ return false;
+}
+
+void LLNotificationForm::addElement(const std::string& type, const std::string& name, const LLSD& value)
+{
+ LLSD element;
+ element["type"] = type;
+ element["name"] = name;
+ element["text"] = name;
+ element["value"] = value;
+ element["index"] = mFormData.size();
+ mFormData.append(element);
+}
+
+void LLNotificationForm::append(const LLSD& sub_form)
+{
+ if (sub_form.isArray())
+ {
+ for (LLSD::array_const_iterator it = sub_form.beginArray();
+ it != sub_form.endArray();
+ ++it)
+ {
+ mFormData.append(*it);
+ }
+ }
+}
+
+void LLNotificationForm::formatElements(const LLSD& substitutions)
+{
+ for (LLSD::array_iterator it = mFormData.beginArray();
+ it != mFormData.endArray();
+ ++it)
+ {
+ // format "text" component of each form element
+ if ((*it).has("text"))
+ {
+ std::string text = (*it)["text"].asString();
+ LLStringUtil::format(text, substitutions);
+ (*it)["text"] = text;
+ }
+ if ((*it)["type"].asString() == "text" && (*it).has("value"))
+ {
+ std::string value = (*it)["value"].asString();
+ LLStringUtil::format(value, substitutions);
+ (*it)["value"] = value;
+ }
+ }
+}
+
+std::string LLNotificationForm::getDefaultOption()
+{
+ for (LLSD::array_const_iterator it = mFormData.beginArray();
+ it != mFormData.endArray();
+ ++it)
+ {
+ if ((*it)["default"]) return (*it)["name"].asString();
+ }
+ return "";
+}
+
+LLNotificationTemplate::LLNotificationTemplate() :
+ mExpireSeconds(0),
+ mExpireOption(-1),
+ mURLOption(-1),
+ mURLOpenExternally(-1),
+ mUnique(false),
+ mPriority(NOTIFICATION_PRIORITY_NORMAL)
+{
+ mForm = LLNotificationFormPtr(new LLNotificationForm());
+}
+
+LLNotification::LLNotification(const LLNotification::Params& p) :
+ mTimestamp(p.time_stamp),
+ mSubstitutions(p.substitutions),
+ mPayload(p.payload),
+ mExpiresAt(0),
+ mTemporaryResponder(false),
+ mRespondedTo(false),
+ mPriority(p.priority),
+ mCancelled(false),
+ mIgnored(false)
+{
+ if (p.functor.name.isChosen())
+ {
+ mResponseFunctorName = p.functor.name;
+ }
+ else if (p.functor.function.isChosen())
+ {
+ mResponseFunctorName = LLUUID::generateNewID().asString();
+ LLNotificationFunctorRegistry::instance().registerFunctor(mResponseFunctorName, p.functor.function());
+
+ mTemporaryResponder = true;
+ }
+
+ mId.generate();
+ init(p.name, p.form_elements);
+}
+
+
+LLNotification::LLNotification(const LLSD& sd) :
+ mTemporaryResponder(false),
+ mRespondedTo(false),
+ mCancelled(false),
+ mIgnored(false)
+{
+ mId.generate();
+ mSubstitutions = sd["substitutions"];
+ mPayload = sd["payload"];
+ mTimestamp = sd["time"];
+ mExpiresAt = sd["expiry"];
+ mPriority = (ENotificationPriority)sd["priority"].asInteger();
+ mResponseFunctorName = sd["responseFunctor"].asString();
+ std::string templatename = sd["name"].asString();
+ init(templatename, LLSD());
+ // replace form with serialized version
+ mForm = LLNotificationFormPtr(new LLNotificationForm(sd["form"]));
+}
+
+
+LLSD LLNotification::asLLSD()
+{
+ LLSD output;
+ output["name"] = mTemplatep->mName;
+ output["form"] = getForm()->asLLSD();
+ output["substitutions"] = mSubstitutions;
+ output["payload"] = mPayload;
+ output["time"] = mTimestamp;
+ output["expiry"] = mExpiresAt;
+ output["priority"] = (S32)mPriority;
+ output["responseFunctor"] = mResponseFunctorName;
+ return output;
+}
+
+void LLNotification::update()
+{
+ LLNotifications::instance().update(shared_from_this());
+}
+
+void LLNotification::updateFrom(LLNotificationPtr other)
+{
+ // can only update from the same notification type
+ if (mTemplatep != other->mTemplatep) return;
+
+ // NOTE: do NOT change the ID, since it is the key to
+ // this given instance, just update all the metadata
+ //mId = other->mId;
+
+ mPayload = other->mPayload;
+ mSubstitutions = other->mSubstitutions;
+ mTimestamp = other->mTimestamp;
+ mExpiresAt = other->mExpiresAt;
+ mCancelled = other->mCancelled;
+ mIgnored = other->mIgnored;
+ mPriority = other->mPriority;
+ mForm = other->mForm;
+ mResponseFunctorName = other->mResponseFunctorName;
+ mRespondedTo = other->mRespondedTo;
+ mTemporaryResponder = other->mTemporaryResponder;
+
+ update();
+}
+
+const LLNotificationFormPtr LLNotification::getForm()
+{
+ return mForm;
+}
+
+void LLNotification::cancel()
+{
+ mCancelled = true;
+}
+
+LLSD LLNotification::getResponseTemplate(EResponseTemplateType type)
+{
+ LLSD response = LLSD::emptyMap();
+ for (S32 element_idx = 0;
+ element_idx < mForm->getNumElements();
+ ++element_idx)
+ {
+ LLSD element = mForm->getElement(element_idx);
+ if (element.has("name"))
+ {
+ response[element["name"].asString()] = element["value"];
+ }
+
+ if ((type == WITH_DEFAULT_BUTTON)
+ && element["default"].asBoolean())
+ {
+ response[element["name"].asString()] = true;
+ }
+ }
+ return response;
+}
+
+//static
+S32 LLNotification::getSelectedOption(const LLSD& notification, const LLSD& response)
+{
+ LLNotificationForm form(notification["form"]);
+
+ for (S32 element_idx = 0;
+ element_idx < form.getNumElements();
+ ++element_idx)
+ {
+ LLSD element = form.getElement(element_idx);
+
+ // only look at buttons
+ if (element["type"].asString() == "button"
+ && response[element["name"].asString()].asBoolean())
+ {
+ return element["index"].asInteger();
+ }
+ }
+
+ return -1;
+}
+
+//static
+std::string LLNotification::getSelectedOptionName(const LLSD& response)
+{
+ for (LLSD::map_const_iterator response_it = response.beginMap();
+ response_it != response.endMap();
+ ++response_it)
+ {
+ if (response_it->second.isBoolean() && response_it->second.asBoolean())
+ {
+ return response_it->first;
+ }
+ }
+ return "";
+}
+
+
+void LLNotification::respond(const LLSD& response)
+{
+ mRespondedTo = true;
+ // look up the functor
+ LLNotificationFunctorRegistry::ResponseFunctor functor =
+ LLNotificationFunctorRegistry::instance().getFunctor(mResponseFunctorName);
+ // and then call it
+ functor(asLLSD(), response);
+
+ if (mTemporaryResponder)
+ {
+ LLNotificationFunctorRegistry::instance().unregisterFunctor(mResponseFunctorName);
+ mResponseFunctorName = "";
+ mTemporaryResponder = false;
+ }
+
+ if (mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)
+ {
+ BOOL show_notification = mIgnored ? FALSE : TRUE;
+ LLUI::sSettingGroups["ignores"]->setBOOL(getName(), show_notification);
+ if (mIgnored && mForm->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
+ {
+ LLUI::sSettingGroups["ignores"]->setLLSD("Default" + getName(), response);
+ }
+ }
+
+ update();
+}
+
+void LLNotification::setIgnored(bool ignore)
+{
+ mIgnored = ignore;
+}
+
+void LLNotification::setResponseFunctor(std::string const &responseFunctorName)
+{
+ if (mTemporaryResponder)
+ // get rid of the old one
+ LLNotificationFunctorRegistry::instance().unregisterFunctor(mResponseFunctorName);
+ mResponseFunctorName = responseFunctorName;
+ mTemporaryResponder = false;
+}
+
+bool LLNotification::payloadContainsAll(const std::vector<std::string>& required_fields) const
+{
+ for(std::vector<std::string>::const_iterator required_fields_it = required_fields.begin();
+ required_fields_it != required_fields.end();
+ required_fields_it++)
+ {
+ std::string required_field_name = *required_fields_it;
+ if( ! getPayload().has(required_field_name))
+ {
+ return false; // a required field was not found
+ }
+ }
+ return true; // all required fields were found
+}
+
+bool LLNotification::isEquivalentTo(LLNotificationPtr that) const
+{
+ if (this->mTemplatep->mName != that->mTemplatep->mName)
+ {
+ return false; // must have the same template name or forget it
+ }
+ if (this->mTemplatep->mUnique)
+ {
+ // highlander bit sez there can only be one of these
+ return
+ this->payloadContainsAll(that->mTemplatep->mUniqueContext) &&
+ that->payloadContainsAll(this->mTemplatep->mUniqueContext);
+ }
+ return false;
+}
+
+void LLNotification::init(const std::string& template_name, const LLSD& form_elements)
+{
+ mTemplatep = LLNotifications::instance().getTemplate(template_name);
+ if (!mTemplatep) return;
+
+ // add default substitutions
+ const LLStringUtil::format_map_t& default_args = LLTrans::getDefaultArgs();
+ for (LLStringUtil::format_map_t::const_iterator iter = default_args.begin();
+ iter != default_args.end(); ++iter)
+ {
+ mSubstitutions[iter->first] = iter->second;
+ }
+ mSubstitutions["_URL"] = getURL();
+ mSubstitutions["_NAME"] = template_name;
+ // TODO: something like this so that a missing alert is sensible:
+ //mSubstitutions["_ARGS"] = get_all_arguments_as_text(mSubstitutions);
+
+ mForm = LLNotificationFormPtr(new LLNotificationForm(*mTemplatep->mForm));
+ mForm->append(form_elements);
+
+ // apply substitution to form labels
+ mForm->formatElements(mSubstitutions);
+
+ LLDate rightnow = LLDate::now();
+ if (mTemplatep->mExpireSeconds)
+ {
+ mExpiresAt = LLDate(rightnow.secondsSinceEpoch() + mTemplatep->mExpireSeconds);
+ }
+
+ if (mPriority == NOTIFICATION_PRIORITY_UNSPECIFIED)
+ {
+ mPriority = mTemplatep->mPriority;
+ }
+}
+
+std::string LLNotification::summarize() const
+{
+ std::string s = "Notification(";
+ s += getName();
+ s += ") : ";
+ s += mTemplatep ? mTemplatep->mMessage : "";
+ // should also include timestamp and expiration time (but probably not payload)
+ return s;
+}
+
+std::string LLNotification::getMessage() const
+{
+ // all our callers cache this result, so it gives us more flexibility
+ // to do the substitution at call time rather than attempting to
+ // cache it in the notification
+ if (!mTemplatep)
+ return std::string();
+
+ std::string message = mTemplatep->mMessage;
+ LLStringUtil::format(message, mSubstitutions);
+ return message;
+}
+
+std::string LLNotification::getLabel() const
+{
+ std::string label = mTemplatep->mLabel;
+ LLStringUtil::format(label, mSubstitutions);
+ return (mTemplatep ? label : "");
+}
+
+std::string LLNotification::getURL() const
+{
+ if (!mTemplatep)
+ return std::string();
+ std::string url = mTemplatep->mURL;
+ LLStringUtil::format(url, mSubstitutions);
+ return (mTemplatep ? url : "");
+}
+
+// =========================================================
+// LLNotificationChannel implementation
+// ---
+LLBoundListener LLNotificationChannelBase::connectChangedImpl(const LLEventListener& slot)
+{
+ // when someone wants to connect to a channel, we first throw them
+ // all of the notifications that are already in the channel
+ // we use a special signal called "load" in case the channel wants to care
+ // only about new notifications
+ for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
+ {
+ slot(LLSD().insert("sigtype", "load").insert("id", (*it)->id()));
+ }
+ // and then connect the signal so that all future notifications will also be
+ // forwarded.
+ return mChanged.connect(slot);
+}
+
+LLBoundListener LLNotificationChannelBase::connectAtFrontChangedImpl(const LLEventListener& slot)
+{
+ for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
+ {
+ slot(LLSD().insert("sigtype", "load").insert("id", (*it)->id()));
+ }
+ return mChanged.connect(slot, boost::signals2::at_front);
+}
+
+LLBoundListener LLNotificationChannelBase::connectPassedFilterImpl(const LLEventListener& slot)
+{
+ // these two filters only fire for notifications added after the current one, because
+ // they don't participate in the hierarchy.
+ return mPassedFilter.connect(slot);
+}
+
+LLBoundListener LLNotificationChannelBase::connectFailedFilterImpl(const LLEventListener& slot)
+{
+ return mFailedFilter.connect(slot);
+}
+
+// external call, conforms to our standard signature
+bool LLNotificationChannelBase::updateItem(const LLSD& payload)
+{
+ // first check to see if it's in the master list
+ LLNotificationPtr pNotification = LLNotifications::instance().find(payload["id"]);
+ if (!pNotification)
+ return false; // not found
+
+ return updateItem(payload, pNotification);
+}
+
+
+//FIX QUIT NOT WORKING
+
+
+// internal call, for use in avoiding lookup
+bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPtr pNotification)
+{
+ std::string cmd = payload["sigtype"];
+ LLNotificationSet::iterator foundItem = mItems.find(pNotification);
+ bool wasFound = (foundItem != mItems.end());
+ bool passesFilter = mFilter(pNotification);
+
+ // first, we offer the result of the filter test to the simple
+ // signals for pass/fail. One of these is guaranteed to be called.
+ // If either signal returns true, the change processing is NOT performed
+ // (so don't return true unless you know what you're doing!)
+ bool abortProcessing = false;
+ if (passesFilter)
+ {
+ abortProcessing = mPassedFilter(payload);
+ }
+ else
+ {
+ abortProcessing = mFailedFilter(payload);
+ }
+
+ if (abortProcessing)
+ {
+ return true;
+ }
+
+ if (cmd == "load")
+ {
+ // should be no reason we'd ever get a load if we already have it
+ // if passes filter send a load message, else do nothing
+ assert(!wasFound);
+ if (passesFilter)
+ {
+ // not in our list, add it and say so
+ mItems.insert(pNotification);
+ abortProcessing = mChanged(payload);
+ onLoad(pNotification);
+ }
+ }
+ else if (cmd == "change")
+ {
+ // if it passes filter now and was found, we just send a change message
+ // if it passes filter now and wasn't found, we have to add it
+ // if it doesn't pass filter and wasn't found, we do nothing
+ // if it doesn't pass filter and was found, we need to delete it
+ if (passesFilter)
+ {
+ if (wasFound)
+ {
+ // it already existed, so this is a change
+ // since it changed in place, all we have to do is resend the signal
+ abortProcessing = mChanged(payload);
+ onChange(pNotification);
+ }
+ else
+ {
+ // not in our list, add it and say so
+ mItems.insert(pNotification);
+ // our payload is const, so make a copy before changing it
+ LLSD newpayload = payload;
+ newpayload["sigtype"] = "add";
+ abortProcessing = mChanged(newpayload);
+ onChange(pNotification);
+ }
+ }
+ else
+ {
+ if (wasFound)
+ {
+ // it already existed, so this is a delete
+ mItems.erase(pNotification);
+ // our payload is const, so make a copy before changing it
+ LLSD newpayload = payload;
+ newpayload["sigtype"] = "delete";
+ abortProcessing = mChanged(newpayload);
+ onChange(pNotification);
+ }
+ // didn't pass, not on our list, do nothing
+ }
+ }
+ else if (cmd == "add")
+ {
+ // should be no reason we'd ever get an add if we already have it
+ // if passes filter send an add message, else do nothing
+ assert(!wasFound);
+ if (passesFilter)
+ {
+ // not in our list, add it and say so
+ mItems.insert(pNotification);
+ abortProcessing = mChanged(payload);
+ onAdd(pNotification);
+ }
+ }
+ else if (cmd == "delete")
+ {
+ // if we have it in our list, pass on the delete, then delete it, else do nothing
+ if (wasFound)
+ {
+ abortProcessing = mChanged(payload);
+ mItems.erase(pNotification);
+ onDelete(pNotification);
+ }
+ }
+ return abortProcessing;
+}
+
+/* static */
+LLNotificationChannelPtr LLNotificationChannel::buildChannel(const std::string& name,
+ const std::string& parent,
+ LLNotificationFilter filter,
+ LLNotificationComparator comparator)
+{
+ // note: this is not a leak; notifications are self-registering.
+ // This factory helps to prevent excess deletions by making sure all smart
+ // pointers to notification channels come from the same source
+ new LLNotificationChannel(name, parent, filter, comparator);
+ return LLNotifications::instance().getChannel(name);
+}
+
+
+LLNotificationChannel::LLNotificationChannel(const std::string& name,
+ const std::string& parent,
+ LLNotificationFilter filter,
+ LLNotificationComparator comparator) :
+LLNotificationChannelBase(filter, comparator),
+mName(name),
+mParent(parent)
+{
+ // store myself in the channel map
+ LLNotifications::instance().addChannel(LLNotificationChannelPtr(this));
+ // bind to notification broadcast
+ if (parent.empty())
+ {
+ LLNotifications::instance().connectChanged(
+ boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
+ }
+ else
+ {
+ LLNotificationChannelPtr p = LLNotifications::instance().getChannel(parent);
+ p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
+ }
+}
+
+
+void LLNotificationChannel::setComparator(LLNotificationComparator comparator)
+{
+ mComparator = comparator;
+ LLNotificationSet s2(mComparator);
+ s2.insert(mItems.begin(), mItems.end());
+ mItems.swap(s2);
+
+ // notify clients that we've been resorted
+ mChanged(LLSD().insert("sigtype", "sort"));
+}
+
+bool LLNotificationChannel::isEmpty() const
+{
+ return mItems.empty();
+}
+
+LLNotificationChannel::Iterator LLNotificationChannel::begin()
+{
+ return mItems.begin();
+}
+
+LLNotificationChannel::Iterator LLNotificationChannel::end()
+{
+ return mItems.end();
+}
+
+std::string LLNotificationChannel::summarize()
+{
+ std::string s("Channel '");
+ s += mName;
+ s += "'\n ";
+ for (LLNotificationChannel::Iterator it = begin(); it != end(); ++it)
+ {
+ s += (*it)->summarize();
+ s += "\n ";
+ }
+ return s;
+}
+
+
+// ---
+// END OF LLNotificationChannel implementation
+// =========================================================
+
+
+// =========================================================
+// LLNotifications implementation
+// ---
+LLNotifications::LLNotifications() : LLNotificationChannelBase(LLNotificationFilters::includeEverything,
+ LLNotificationComparators::orderByUUID()),
+ mIgnoreAllNotifications(false)
+{
+ LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
+
+ mListener.reset(new LLNotificationsListener(*this));
+}
+
+
+// The expiration channel gets all notifications that are cancelled
+bool LLNotifications::expirationFilter(LLNotificationPtr pNotification)
+{
+ return pNotification->isCancelled() || pNotification->isRespondedTo();
+}
+
+bool LLNotifications::expirationHandler(const LLSD& payload)
+{
+ if (payload["sigtype"].asString() != "delete")
+ {
+ // anything added to this channel actually should be deleted from the master
+ cancel(find(payload["id"]));
+ return true; // don't process this item any further
+ }
+ return false;
+}
+
+bool LLNotifications::uniqueFilter(LLNotificationPtr pNotif)
+{
+ if (!pNotif->hasUniquenessConstraints())
+ {
+ return true;
+ }
+
+ // checks against existing unique notifications
+ for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
+ existing_it != mUniqueNotifications.end();
+ ++existing_it)
+ {
+ LLNotificationPtr existing_notification = existing_it->second;
+ if (pNotif != existing_notification
+ && pNotif->isEquivalentTo(existing_notification))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool LLNotifications::uniqueHandler(const LLSD& payload)
+{
+ LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID());
+ if (pNotif && pNotif->hasUniquenessConstraints())
+ {
+ if (payload["sigtype"].asString() == "add")
+ {
+ // not a duplicate according to uniqueness criteria, so we keep it
+ // and store it for future uniqueness checks
+ mUniqueNotifications.insert(std::make_pair(pNotif->getName(), pNotif));
+ }
+ else if (payload["sigtype"].asString() == "delete")
+ {
+ mUniqueNotifications.erase(pNotif->getName());
+ }
+ }
+
+ return false;
+}
+
+bool LLNotifications::failedUniquenessTest(const LLSD& payload)
+{
+ LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID());
+
+ if (!pNotif || !pNotif->hasUniquenessConstraints())
+ {
+ return false;
+ }
+
+ // checks against existing unique notifications
+ for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
+ existing_it != mUniqueNotifications.end();
+ ++existing_it)
+ {
+ LLNotificationPtr existing_notification = existing_it->second;
+ if (pNotif != existing_notification
+ && pNotif->isEquivalentTo(existing_notification))
+ {
+ // copy notification instance data over to oldest instance
+ // of this unique notification and update it
+ existing_notification->updateFrom(pNotif);
+ // then delete the new one
+ pNotif->cancel();
+ }
+ }
+
+ return false;
+}
+
+
+void LLNotifications::addChannel(LLNotificationChannelPtr pChan)
+{
+ mChannels[pChan->getName()] = pChan;
+}
+
+LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelName)
+{
+ ChannelMap::iterator p = mChannels.find(channelName);
+ if(p == mChannels.end())
+ {
+ llerrs << "Did not find channel named " << channelName << llendl;
+ }
+ return p->second;
+}
+
+
+// this function is called once at construction time, after the object is constructed.
+void LLNotifications::initSingleton()
+{
+ loadTemplates();
+ createDefaultChannels();
+}
+
+void LLNotifications::createDefaultChannels()
+{
+ // now construct the various channels AFTER loading the notifications,
+ // because the history channel is going to rewrite the stored notifications file
+ LLNotificationChannel::buildChannel("Expiration", "",
+ boost::bind(&LLNotifications::expirationFilter, this, _1));
+ LLNotificationChannel::buildChannel("Unexpired", "",
+ !boost::bind(&LLNotifications::expirationFilter, this, _1)); // use negated bind
+ LLNotificationChannel::buildChannel("Unique", "Unexpired",
+ boost::bind(&LLNotifications::uniqueFilter, this, _1));
+ LLNotificationChannel::buildChannel("Ignore", "Unique",
+ filterIgnoredNotifications);
+ LLNotificationChannel::buildChannel("Visible", "Ignore",
+ &LLNotificationFilters::includeEverything);
+
+ // create special history channel
+ //std::string notifications_log_file = gDirUtilp->getExpandedFilename ( LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml" );
+ // use ^^^ when done debugging notifications serialization
+ std::string notifications_log_file = gDirUtilp->getExpandedFilename ( LL_PATH_USER_SETTINGS, "open_notifications.xml" );
+ // this isn't a leak, don't worry about the empty "new"
+ new LLNotificationHistoryChannel(notifications_log_file);
+
+ // connect action methods to these channels
+ LLNotifications::instance().getChannel("Expiration")->
+ connectChanged(boost::bind(&LLNotifications::expirationHandler, this, _1));
+ // uniqueHandler slot should be added as first slot of the signal due to
+ // usage LLStopWhenHandled combiner in LLStandardSignal
+ LLNotifications::instance().getChannel("Unique")->
+ connectAtFrontChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1));
+// failedUniquenessTest slot isn't necessary
+// LLNotifications::instance().getChannel("Unique")->
+// connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1));
+ LLNotifications::instance().getChannel("Ignore")->
+ connectFailedFilter(&handleIgnoredNotification);
+}
+
+bool LLNotifications::addTemplate(const std::string &name,
+ LLNotificationTemplatePtr theTemplate)
+{
+ if (mTemplates.count(name))
+ {
+ llwarns << "LLNotifications -- attempted to add template '" << name << "' twice." << llendl;
+ return false;
+ }
+ mTemplates[name] = theTemplate;
+ return true;
+}
+
+LLNotificationTemplatePtr LLNotifications::getTemplate(const std::string& name)
+{
+ if (mTemplates.count(name))
+ {
+ return mTemplates[name];
+ }
+ else
+ {
+ return mTemplates["MissingAlert"];
+ }
+}
+
+bool LLNotifications::templateExists(const std::string& name)
+{
+ return (mTemplates.count(name) != 0);
+}
+
+void LLNotifications::clearTemplates()
+{
+ mTemplates.clear();
+}
+
+void LLNotifications::forceResponse(const LLNotification::Params& params, S32 option)
+{
+ LLNotificationPtr temp_notify(new LLNotification(params));
+ LLSD response = temp_notify->getResponseTemplate();
+ LLSD selected_item = temp_notify->getForm()->getElement(option);
+
+ if (selected_item.isUndefined())
+ {
+ llwarns << "Invalid option" << option << " for notification " << (std::string)params.name << llendl;
+ return;
+ }
+ response[selected_item["name"].asString()] = true;
+
+ temp_notify->respond(response);
+}
+
+LLNotifications::TemplateNames LLNotifications::getTemplateNames() const
+{
+ TemplateNames names;
+ for (TemplateMap::const_iterator it = mTemplates.begin(); it != mTemplates.end(); ++it)
+ {
+ names.push_back(it->first);
+ }
+ return names;
+}
+
+typedef std::map<std::string, std::string> StringMap;
+void replaceSubstitutionStrings(LLXMLNodePtr node, StringMap& replacements)
+{
+ //llwarns << "replaceSubstitutionStrings" << llendl;
+ // walk the list of attributes looking for replacements
+ for (LLXMLAttribList::iterator it=node->mAttributes.begin();
+ it != node->mAttributes.end(); ++it)
+ {
+ std::string value = it->second->getValue();
+ if (value[0] == '$')
+ {
+ value.erase(0, 1); // trim off the $
+ std::string replacement;
+ StringMap::const_iterator found = replacements.find(value);
+ if (found != replacements.end())
+ {
+ replacement = found->second;
+ //llwarns << "replaceSubstituionStrings: value: " << value << " repl: " << replacement << llendl;
+
+ it->second->setValue(replacement);
+ }
+ else
+ {
+ llwarns << "replaceSubstituionStrings FAILURE: value: " << value << " repl: " << replacement << llendl;
+ }
+ }
+ }
+
+ // now walk the list of children and call this recursively.
+ for (LLXMLNodePtr child = node->getFirstChild();
+ child.notNull(); child = child->getNextSibling())
+ {
+ replaceSubstitutionStrings(child, replacements);
+ }
+}
+
+// private to this file
+// returns true if the template request was invalid and there's nothing else we
+// can do with this node, false if you should keep processing (it may have
+// replaced the contents of the node referred to)
+LLXMLNodePtr LLNotifications::checkForXMLTemplate(LLXMLNodePtr item)
+{
+ if (item->hasName("usetemplate"))
+ {
+ std::string replacementName;
+ if (item->getAttributeString("name", replacementName))
+ {
+ StringMap replacements;
+ for (LLXMLAttribList::const_iterator it=item->mAttributes.begin();
+ it != item->mAttributes.end(); ++it)
+ {
+ replacements[it->second->getName()->mString] = it->second->getValue();
+ }
+ if (mXmlTemplates.count(replacementName))
+ {
+ item=LLXMLNode::replaceNode(item, mXmlTemplates[replacementName]);
+
+ // walk the nodes looking for $(substitution) here and replace
+ replaceSubstitutionStrings(item, replacements);
+ }
+ else
+ {
+ llwarns << "XML template lookup failure on '" << replacementName << "' " << llendl;
+ }
+ }
+ }
+ return item;
+}
+
+bool LLNotifications::loadTemplates()
+{
+ const std::string xml_filename = "notifications.xml";
+ LLXMLNodePtr root;
+
+ BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
+
+ if (!success || root.isNull() || !root->hasName( "notifications" ))
+ {
+ llerrs << "Problem reading UI Notifications file: " << xml_filename << llendl;
+ return false;
+ }
+
+ clearTemplates();
+
+ for (LLXMLNodePtr item = root->getFirstChild();
+ item.notNull(); item = item->getNextSibling())
+ {
+ // we do this FIRST so that item can be changed if we
+ // encounter a usetemplate -- we just replace the
+ // current xml node and keep processing
+ item = checkForXMLTemplate(item);
+
+ if (item->hasName("global"))
+ {
+ std::string global_name;
+ if (item->getAttributeString("name", global_name))
+ {
+ mGlobalStrings[global_name] = item->getTextContents();
+ }
+ continue;
+ }
+
+ if (item->hasName("template"))
+ {
+ // store an xml template; templates must have a single node (can contain
+ // other nodes)
+ std::string name;
+ item->getAttributeString("name", name);
+ LLXMLNodePtr ptr = item->getFirstChild();
+ mXmlTemplates[name] = ptr;
+ continue;
+ }
+
+ if (!item->hasName("notification"))
+ {
+ llwarns << "Unexpected entity " << item->getName()->mString <<
+ " found in " << xml_filename << llendl;
+ continue;
+ }
+
+ // now we know we have a notification entry, so let's build it
+ LLNotificationTemplatePtr pTemplate(new LLNotificationTemplate());
+
+ if (!item->getAttributeString("name", pTemplate->mName))
+ {
+ llwarns << "Unable to parse notification with no name" << llendl;
+ continue;
+ }
+
+ //llinfos << "Parsing " << pTemplate->mName << llendl;
+
+ pTemplate->mMessage = item->getTextContents();
+ pTemplate->mDefaultFunctor = pTemplate->mName;
+ item->getAttributeString("type", pTemplate->mType);
+ item->getAttributeString("icon", pTemplate->mIcon);
+ item->getAttributeString("label", pTemplate->mLabel);
+ item->getAttributeU32("duration", pTemplate->mExpireSeconds);
+ item->getAttributeU32("expireOption", pTemplate->mExpireOption);
+
+ std::string priority;
+ item->getAttributeString("priority", priority);
+ pTemplate->mPriority = NOTIFICATION_PRIORITY_NORMAL;
+ if (!priority.empty())
+ {
+ if (priority == "low") pTemplate->mPriority = NOTIFICATION_PRIORITY_LOW;
+ if (priority == "normal") pTemplate->mPriority = NOTIFICATION_PRIORITY_NORMAL;
+ if (priority == "high") pTemplate->mPriority = NOTIFICATION_PRIORITY_HIGH;
+ if (priority == "critical") pTemplate->mPriority = NOTIFICATION_PRIORITY_CRITICAL;
+ }
+
+ item->getAttributeString("functor", pTemplate->mDefaultFunctor);
+
+ BOOL persist = false;
+ item->getAttributeBOOL("persist", persist);
+ pTemplate->mPersist = persist;
+
+ std::string sound;
+ item->getAttributeString("sound", sound);
+ if (!sound.empty())
+ {
+ // test for bad sound effect name / missing effect
+ if (LLUI::sSettingGroups["config"]->controlExists(sound))
+ {
+ pTemplate->mSoundEffect =
+ LLUUID(LLUI::sSettingGroups["config"]->getString(sound));
+ }
+ else
+ {
+ llwarns << "Unknown sound effect control name " << sound
+ << llendl;
+ }
+ }
+
+ for (LLXMLNodePtr child = item->getFirstChild();
+ !child.isNull(); child = child->getNextSibling())
+ {
+ child = checkForXMLTemplate(child);
+
+ // <url>
+ if (child->hasName("url"))
+ {
+ pTemplate->mURL = child->getTextContents();
+ child->getAttributeU32("option", pTemplate->mURLOption);
+ child->getAttributeU32("openexternally", pTemplate->mURLOpenExternally);
+ }
+
+ if (child->hasName("unique"))
+ {
+ pTemplate->mUnique = true;
+ for (LLXMLNodePtr formitem = child->getFirstChild();
+ !formitem.isNull(); formitem = formitem->getNextSibling())
+ {
+ if (formitem->hasName("context"))
+ {
+ std::string key;
+ formitem->getAttributeString("key", key);
+ pTemplate->mUniqueContext.push_back(key);
+ //llwarns << "adding " << key << " to unique context" << llendl;
+ }
+ else
+ {
+ llwarns << "'unique' has unrecognized subelement "
+ << formitem->getName()->mString << llendl;
+ }
+ }
+ }
+
+ // <form>
+ if (child->hasName("form"))
+ {
+ pTemplate->mForm = LLNotificationFormPtr(new LLNotificationForm(pTemplate->mName, child));
+ }
+ }
+ addTemplate(pTemplate->mName, pTemplate);
+ }
+
+ //std::ostringstream ostream;
+ //root->writeToOstream(ostream, "\n ");
+ //llwarns << ostream.str() << llendl;
+
+ return true;
+}
+
+// Add a simple notification (from XUI)
+void LLNotifications::addFromCallback(const LLSD& name)
+{
+ add(LLNotification::Params().name(name.asString()));
+}
+
+// we provide a couple of simple add notification functions so that it's reasonable to create notifications in one line
+LLNotificationPtr LLNotifications::add(const std::string& name,
+ const LLSD& substitutions,
+ const LLSD& payload)
+{
+ LLNotification::Params::Functor functor_p;
+ functor_p.name = name;
+ return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
+}
+
+LLNotificationPtr LLNotifications::add(const std::string& name,
+ const LLSD& substitutions,
+ const LLSD& payload,
+ const std::string& functor_name)
+{
+ LLNotification::Params::Functor functor_p;
+ functor_p.name = functor_name;
+ return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
+}
+
+LLNotificationPtr LLNotifications::add(const std::string& name,
+ const LLSD& substitutions,
+ const LLSD& payload,
+ LLNotificationFunctorRegistry::ResponseFunctor functor)
+{
+ LLNotification::Params::Functor functor_p;
+ functor_p.function = functor;
+ return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
+}
+
+// generalized add function that takes a parameter block object for more complex instantiations
+LLNotificationPtr LLNotifications::add(const LLNotification::Params& p)
+{
+ LLNotificationPtr pNotif(new LLNotification(p));
+ add(pNotif);
+ return pNotif;
+}
+
+
+void LLNotifications::add(const LLNotificationPtr pNotif)
+{
+ // first see if we already have it -- if so, that's a problem
+ LLNotificationSet::iterator it=mItems.find(pNotif);
+ if (it != mItems.end())
+ {
+ llerrs << "Notification added a second time to the master notification channel." << llendl;
+ }
+
+ updateItem(LLSD().insert("sigtype", "add").insert("id", pNotif->id()), pNotif);
+}
+
+void LLNotifications::cancel(LLNotificationPtr pNotif)
+{
+ LLNotificationSet::iterator it=mItems.find(pNotif);
+ if (it == mItems.end())
+ {
+ llerrs << "Attempted to delete nonexistent notification " << pNotif->getName() << llendl;
+ }
+ pNotif->cancel();
+ updateItem(LLSD().insert("sigtype", "delete").insert("id", pNotif->id()), pNotif);
+}
+
+void LLNotifications::update(const LLNotificationPtr pNotif)
+{
+ LLNotificationSet::iterator it=mItems.find(pNotif);
+ if (it != mItems.end())
+ {
+ updateItem(LLSD().insert("sigtype", "change").insert("id", pNotif->id()), pNotif);
+ }
+}
+
+
+LLNotificationPtr LLNotifications::find(LLUUID uuid)
+{
+ LLNotificationPtr target = LLNotificationPtr(new LLNotification(uuid));
+ LLNotificationSet::iterator it=mItems.find(target);
+ if (it == mItems.end())
+ {
+ llwarns << "Tried to dereference uuid '" << uuid << "' as a notification key but didn't find it." << llendl;
+ return LLNotificationPtr((LLNotification*)NULL);
+ }
+ else
+ {
+ return *it;
+ }
+}
+
+void LLNotifications::forEachNotification(NotificationProcess process)
+{
+ std::for_each(mItems.begin(), mItems.end(), process);
+}
+
+std::string LLNotifications::getGlobalString(const std::string& key) const
+{
+ GlobalStringMap::const_iterator it = mGlobalStrings.find(key);
+ if (it != mGlobalStrings.end())
+ {
+ return it->second;
+ }
+ else
+ {
+ // if we don't have the key as a global, return the key itself so that the error
+ // is self-diagnosing.
+ return key;
+ }
+}
+
+void LLNotifications::setIgnoreAllNotifications(bool setting)
+{
+ mIgnoreAllNotifications = setting;
+}
+bool LLNotifications::getIgnoreAllNotifications()
+{
+ return mIgnoreAllNotifications;
+}
+
+// ---
+// END OF LLNotifications implementation
+// =========================================================
+
+std::ostream& operator<<(std::ostream& s, const LLNotification& notification)
+{
+ s << notification.summarize();
+ return s;
+}
+
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 0335a265b6..0d7cb74f70 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -102,7 +102,6 @@
#include "llfunctorregistry.h"
#include "llpointer.h"
#include "llinitparam.h"
-#include "llxmlnode.h"
#include "llnotificationslistener.h"
class LLNotification;
@@ -161,7 +160,7 @@ public:
LLNotificationForm();
LLNotificationForm(const LLSD& sd);
LLNotificationForm(const std::string& name,
- const LLPointer<LLXMLNode> xml_node);
+ const LLPointer<class LLXMLNode> xml_node);
LLSD asLLSD() const;
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 742427525b..095200ddc3 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -474,7 +474,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu
{
//if we are exporting, we want to export the current xml
//not the referenced xml
- LLXUIParser::instance().readXUI(node, params);
+ LLXUIParser::instance().readXUI(node, params, xml_filename);
Params output_params(params);
setupParamsForExport(output_params, parent);
output_node->setName(node->getName()->mString);
@@ -490,14 +490,15 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu
return FALSE;
}
- LLXUIParser::instance().readXUI(referenced_xml, params);
+ LLXUIParser::instance().readXUI(referenced_xml, params, xml_filename);
// add children using dimensions from referenced xml for consistent layout
setShape(params.rect);
LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instance());
}
- LLXUIParser::instance().readXUI(node, params);
+ // ask LLUICtrlFactory for filename, since xml_filename might be empty
+ LLXUIParser::instance().readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName());
if (output_node)
{
diff --git a/indra/llui/llrngwriter.cpp b/indra/llui/llrngwriter.cpp
index cf23e3af15..7e3d4b92d3 100644
--- a/indra/llui/llrngwriter.cpp
+++ b/indra/llui/llrngwriter.cpp
@@ -108,7 +108,8 @@ void LLRNGWriter::addDefinition(const std::string& type_name, const LLInitParam:
LLXMLNodePtr old_element_node = mElementNode;
LLXMLNodePtr old_child_node = mChildrenNode;
- addDefinition(child_name, (*LLDefaultParamBlockRegistry::instance().getValue(type))());
+ //FIXME: add LLDefaultParamBlockRegistry back when working on schema generation
+ //addDefinition(child_name, (*LLDefaultParamBlockRegistry::instance().getValue(type))());
mElementNode = old_element_node;
mChildrenNode = old_child_node;
diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp
index 0d674528dc..dfd315d451 100644
--- a/indra/llui/llscrollbar.cpp
+++ b/indra/llui/llscrollbar.cpp
@@ -149,7 +149,8 @@ void LLScrollbar::setDocParams( S32 size, S32 pos )
updateThumbRect();
}
-void LLScrollbar::setDocPos(S32 pos, BOOL update_thumb)
+// returns true if document position really changed
+bool LLScrollbar::setDocPos(S32 pos, BOOL update_thumb)
{
pos = llclamp(pos, 0, getDocPosMax());
if (pos != mDocPos)
@@ -166,7 +167,9 @@ void LLScrollbar::setDocPos(S32 pos, BOOL update_thumb)
{
updateThumbRect();
}
+ return true;
}
+ return false;
}
void LLScrollbar::setDocSize(S32 size)
@@ -409,13 +412,8 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- S32 pos = llclamp(mDocPos + clicks * mStepSize, 0, getDocPosMax());
- if (pos != mDocPos)
- {
- setDocPos(pos, TRUE);
- return TRUE;
- }
- return FALSE;
+ BOOL handled = changeLine( clicks * mStepSize, TRUE );
+ return handled;
}
BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
@@ -578,9 +576,9 @@ void LLScrollbar::draw()
} // end draw
-void LLScrollbar::changeLine( S32 delta, BOOL update_thumb )
+bool LLScrollbar::changeLine( S32 delta, BOOL update_thumb )
{
- setDocPos(mDocPos + delta, update_thumb);
+ return setDocPos(mDocPos + delta, update_thumb);
}
void LLScrollbar::setValue(const LLSD& value)
diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h
index 865a1db409..a9f028f9ae 100644
--- a/indra/llui/llscrollbar.h
+++ b/indra/llui/llscrollbar.h
@@ -109,7 +109,7 @@ public:
// How many "lines" the "document" has scrolled.
// 0 <= DocPos <= DocSize - DocVisibile
- void setDocPos( S32 pos, BOOL update_thumb = TRUE );
+ bool setDocPos( S32 pos, BOOL update_thumb = TRUE );
S32 getDocPos() const { return mDocPos; }
BOOL isAtBeginning();
@@ -133,7 +133,7 @@ public:
private:
void updateThumbRect();
- void changeLine(S32 delta, BOOL update_thumb );
+ bool changeLine(S32 delta, BOOL update_thumb );
callback_t mChangeCallback;
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 1d36a16ea7..22cce755b0 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1825,27 +1825,26 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round
return pos;
}
-LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const
+// returns rectangle of insertion caret
+// in document coordinate frame from given index into text
+LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
{
- LLRect local_rect;
if (mLineInfoList.empty())
{
- local_rect = mTextRect;
- local_rect.mBottom = local_rect.mTop - (S32)(mDefaultFont->getLineHeight());
- return local_rect;
+ return LLRect();
}
+ LLRect doc_rect;
+
// clamp pos to valid values
pos = llclamp(pos, 0, mLineInfoList.back().mDocIndexEnd - 1);
-
// find line that contains cursor
line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), pos, line_end_compare());
- LLRect scrolled_view_rect = getVisibleDocumentRect();
- local_rect.mLeft = mTextRect.mLeft - scrolled_view_rect.mLeft + line_iter->mRect.mLeft;
- local_rect.mBottom = mTextRect.mBottom + (line_iter->mRect.mBottom - scrolled_view_rect.mBottom);
- local_rect.mTop = mTextRect.mBottom + (line_iter->mRect.mTop - scrolled_view_rect.mBottom);
+ doc_rect.mLeft = line_iter->mRect.mLeft;
+ doc_rect.mBottom = line_iter->mRect.mBottom;
+ doc_rect.mTop = line_iter->mRect.mTop;
segment_set_t::iterator line_seg_iter;
S32 line_seg_offset;
@@ -1863,7 +1862,7 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const
// cursor advanced to right based on difference in offset of cursor to start of line
S32 segment_width, segment_height;
segmentp->getDimensions(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height);
- local_rect.mLeft += segment_width;
+ doc_rect.mLeft += segment_width;
break;
}
@@ -1872,7 +1871,7 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const
// add remainder of current text segment to cursor position
S32 segment_width, segment_height;
segmentp->getDimensions(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height);
- local_rect.mLeft += segment_width;
+ doc_rect.mLeft += segment_width;
// offset will be 0 for all segments after the first
line_seg_offset = 0;
// go to next text segment on this line
@@ -1880,7 +1879,31 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const
}
}
- local_rect.mRight = local_rect.mLeft;
+ // set rect to 0 width
+ doc_rect.mRight = doc_rect.mLeft;
+
+ return doc_rect;
+}
+
+LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const
+{
+ LLRect local_rect;
+ if (mLineInfoList.empty())
+ {
+ // return default height rect in upper left
+ local_rect = mTextRect;
+ local_rect.mBottom = local_rect.mTop - (S32)(mDefaultFont->getLineHeight());
+ return local_rect;
+ }
+
+ // get the rect in document coordinates
+ LLRect doc_rect = getDocRectFromDocIndex(pos);
+
+ // compensate for scrolled, inset view of doc
+ LLRect scrolled_view_rect = getVisibleDocumentRect();
+ local_rect = doc_rect;
+ local_rect.translate(mTextRect.mLeft - scrolled_view_rect.mLeft,
+ mTextRect.mBottom - scrolled_view_rect.mBottom);
return local_rect;
}
@@ -2416,10 +2439,12 @@ void LLNormalTextSegment::dump() const
// LLInlineViewSegment
//
-LLInlineViewSegment::LLInlineViewSegment(LLView* view, S32 start, S32 end, bool force_new_line)
+LLInlineViewSegment::LLInlineViewSegment(LLView* view, S32 start, S32 end, bool force_new_line, S32 hpad, S32 vpad)
: LLTextSegment(start, end),
mView(view),
- mForceNewLine(force_new_line)
+ mForceNewLine(force_new_line),
+ mHPad(hpad), // one sided padding (applied to left and right)
+ mVPad(vpad)
{
}
@@ -2439,8 +2464,8 @@ void LLInlineViewSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
}
else
{
- width = mView->getRect().getWidth();
- height = mView->getRect().getHeight();
+ width = mHPad * 2 + mView->getRect().getWidth();
+ height = mVPad * 2 + mView->getRect().getHeight();
}
}
@@ -2462,14 +2487,15 @@ S32 LLInlineViewSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
void LLInlineViewSegment::updateLayout(const LLTextBase& editor)
{
- LLRect start_rect = editor.getLocalRectFromDocIndex(mStart);
- LLRect doc_rect = editor.getDocumentView()->getRect();
- mView->setOrigin(doc_rect.mLeft + start_rect.mLeft, doc_rect.mBottom + start_rect.mBottom);
+ LLRect start_rect = editor.getDocRectFromDocIndex(mStart);
+ mView->setOrigin(start_rect.mLeft + mHPad, start_rect.mBottom + mVPad);
}
F32 LLInlineViewSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
{
- return (F32)(draw_rect.mLeft + mView->getRect().getWidth());
+ // return padded width of widget
+ // widget is actually drawn during mDocumentView's draw()
+ return (F32)(draw_rect.mLeft + mView->getRect().getWidth() + mHPad * 2);
}
void LLInlineViewSegment::unlinkFromDocument(LLTextBase* editor)
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index c05a31baec..f0b8878491 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -157,6 +157,7 @@ public:
S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const;
LLRect getLocalRectFromDocIndex(S32 pos) const;
+ LLRect getDocRectFromDocIndex(S32 pos) const;
void setReadOnly(bool read_only) { mReadOnly = read_only; }
bool getReadOnly() { return mReadOnly; }
@@ -458,7 +459,7 @@ public:
class LLInlineViewSegment : public LLTextSegment
{
public:
- LLInlineViewSegment(LLView* widget, S32 start, S32 end, bool force_new_line);
+ LLInlineViewSegment(LLView* widget, S32 start, S32 end, bool force_new_line, S32 hpad = 0, S32 vpad = 0);
~LLInlineViewSegment();
/*virtual*/ void getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
/*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
@@ -469,6 +470,8 @@ public:
/*virtual*/ void linkToDocument(class LLTextBase* editor);
private:
+ S32 mHPad;
+ S32 mVPad;
LLView* mView;
bool mForceNewLine;
};
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 953c5b292f..d507cf7ce4 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2276,7 +2276,7 @@ void LLTextEditor::insertText(const std::string &new_text)
setEnabled( enabled );
}
-void LLTextEditor::appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool force_new_line)
+void LLTextEditor::appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool force_new_line, S32 hpad, S32 vpad)
{
// Save old state
S32 selection_start = mSelectionStart;
@@ -2295,7 +2295,7 @@ void LLTextEditor::appendWidget(LLView* widget, const std::string &widget_text,
// Add carriage return if not first line
widget_wide_text = utf8str_to_wstring(widget_text);
- LLTextSegmentPtr segment = new LLInlineViewSegment(widget, old_length, old_length + widget_text.size(), force_new_line);
+ LLTextSegmentPtr segment = new LLInlineViewSegment(widget, old_length, old_length + widget_text.size(), force_new_line, hpad, vpad);
insert(getLength(), widget_wide_text, FALSE, segment);
needsReflow();
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 82f3956855..481a4d1a78 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -165,7 +165,7 @@ public:
// inserts text at cursor
void insertText(const std::string &text);
- void appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool force_newline);
+ void appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool force_newline, S32 hpad, S32 vpad);
// Non-undoable
void setText(const LLStringExplicit &utf8str);
diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp
index 087a99c2b0..5827c0d627 100644
--- a/indra/llui/lluicolortable.cpp
+++ b/indra/llui/lluicolortable.cpp
@@ -278,7 +278,7 @@ bool LLUIColorTable::loadFromFilename(const std::string& filename)
}
Params params;
- LLXUIParser::instance().readXUI(root, params);
+ LLXUIParser::instance().readXUI(root, params, filename);
if(params.validateBlock())
{
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index 209ee76940..c3c0daed0f 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -34,6 +34,8 @@
#include "lluictrlfactory.h"
+#include "llxmlnode.h"
+
#include <fstream>
#include <boost/tokenizer.hpp>
@@ -83,8 +85,9 @@ LLUICtrlFactory::LLUICtrlFactory()
LLUICtrlFactory::~LLUICtrlFactory()
{
- delete mDummyPanel;
- mDummyPanel = NULL;
+ // go ahead and leak mDummyPanel since this is static destructor time
+ //delete mDummyPanel;
+ //mDummyPanel = NULL;
}
void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitParam::BaseBlock& block)
@@ -94,7 +97,7 @@ void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitPa
if (LLUICtrlFactory::getLayeredXMLNode(filename, root_node))
{
- LLXUIParser::instance().readXUI(root_node, block);
+ LLXUIParser::instance().readXUI(root_node, block, filename);
}
}
@@ -410,3 +413,39 @@ void LLUICtrlFactory::popFactoryFunctions()
mFactoryStack.pop_back();
}
}
+
+//static
+void LLUICtrlFactory::copyName(LLXMLNodePtr src, LLXMLNodePtr dest)
+{
+ dest->setName(src->getName()->mString);
+}
+
+// adds a widget and its param block to various registries
+//static
+void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, dummy_widget_creator_func_t creator_func, const std::string& tag)
+{
+ // associate parameter block type with template .xml file
+ std::string* existing_tag = LLWidgetNameRegistry::instance().getValue(param_block_type);
+ if (existing_tag != NULL && *existing_tag != tag)
+ {
+ llerrs << "Duplicate entry for T::Params, try creating empty param block in derived classes that inherit T::Params" << llendl;
+ }
+ LLWidgetNameRegistry ::instance().defaultRegistrar().add(param_block_type, tag);
+ // associate widget type with factory function
+ LLDefaultWidgetRegistry::instance().defaultRegistrar().add(widget_type, creator_func);
+ LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type);
+ //FIXME: comment this in when working on schema generation
+ //LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type, &getEmptyParamBlock<T>);
+}
+
+//static
+dummy_widget_creator_func_t* LLUICtrlFactory::getDefaultWidgetFunc(const std::type_info* widget_type)
+{
+ return LLDefaultWidgetRegistry::instance().getValue(widget_type);
+}
+
+//static
+const std::string* LLUICtrlFactory::getWidgetTag(const std::type_info* widget_type)
+{
+ return LLWidgetNameRegistry::instance().getValue(widget_type);
+}
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index 5e6dad312c..17e32dc7a9 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -36,7 +36,7 @@
#include "llcallbackmap.h"
#include "llinitparam.h"
#include "llregistry.h"
-#include "llxmlnode.h"
+#include "v4color.h"
#include "llfasttimer.h"
#include "llxuiparser.h"
@@ -98,10 +98,11 @@ class LLDefaultWidgetRegistry
{};
// lookup function for generating empty param block by widget type
-typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)();
-class LLDefaultParamBlockRegistry
-: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry, LLCompareTypeID>
-{};
+// this is used for schema generation
+//typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)();
+//class LLDefaultParamBlockRegistry
+//: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry, LLCompareTypeID>
+//{};
extern LLFastTimer::DeclareTimer FTM_WIDGET_SETUP;
extern LLFastTimer::DeclareTimer FTM_WIDGET_CONSTRUCTION;
@@ -124,7 +125,7 @@ private:
// recursively initialize from base class param block
((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY>::instance().get());
// after initializing base classes, look up template file for this param block
- std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK));
+ const std::string* param_block_tag = getWidgetTag(&typeid(PARAM_BLOCK));
if (param_block_tag)
{
LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, mPrototype);
@@ -241,7 +242,7 @@ fail:
template<class T>
static T* getDefaultWidget(const std::string& name)
{
- dummy_widget_creator_func_t* dummy_func = LLDefaultWidgetRegistry::instance().getValue(&typeid(T));
+ dummy_widget_creator_func_t* dummy_func = getDefaultWidgetFunc(&typeid(T));
return dummy_func ? dynamic_cast<T*>((*dummy_func)(name)) : NULL;
}
@@ -254,6 +255,8 @@ fail:
return create<T>(params);
}
+ static void copyName(LLXMLNodePtr src, LLXMLNodePtr dest);
+
template<typename T>
static T* defaultBuilder(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)
{
@@ -262,7 +265,7 @@ fail:
//#pragma message("Generating LLUICtrlFactory::defaultBuilder")
typename T::Params params(getDefaultParams<T>());
- LLXUIParser::instance().readXUI(node, params);
+ LLXUIParser::instance().readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName());
if (output_node)
{
@@ -271,7 +274,7 @@ fail:
T::setupParamsForExport(output_params, parent);
// Export only the differences between this any default params
typename T::Params default_params(getDefaultParams<T>());
- output_node->setName(node->getName()->mString);
+ copyName(node, output_node);
LLXUIParser::instance().writeXUI(
output_node, output_params, &default_params);
}
@@ -320,7 +323,15 @@ fail:
static void loadWidgetTemplate(const std::string& widget_tag, LLInitParam::BaseBlock& block);
+ // helper function for adding widget type info to various registries
+ static void registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, dummy_widget_creator_func_t creator_func, const std::string& tag);
+
private:
+ // return default widget instance factory func for a given type
+ static dummy_widget_creator_func_t* getDefaultWidgetFunc(const std::type_info* widget_type);
+
+ static const std::string* getWidgetTag(const std::type_info* widget_type);
+
// this exists to get around dependency on llview
static void setCtrlParent(LLView* view, LLView* parent, S32 tab_group);
@@ -347,23 +358,12 @@ template<typename T>
LLChildRegistry<DERIVED>::Register<T>::Register(const char* tag, LLWidgetCreatorFunc func)
: LLChildRegistry<DERIVED>::StaticRegistrar(tag, func.empty() ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder<T> : func)
{
- const std::type_info* widget_type_infop = &typeid(T);
- // associate parameter block type with template .xml file
- std::string* existing_tag = LLWidgetNameRegistry ::instance().getValue(&typeid(typename T::Params));
- if (existing_tag != NULL && *existing_tag != tag)
- {
- // duplicate entry for T::Params
- // try creating empty param block in derived classes that inherit T::Params
- int* crash = 0;
- *crash = 0;
- }
- LLWidgetNameRegistry ::instance().defaultRegistrar().add(&typeid(typename T::Params), tag);
- // associate widget type with factory function
- LLDefaultWidgetRegistry::instance().defaultRegistrar().add(widget_type_infop, &LLUICtrlFactory::createDefaultWidget<T>);
- LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type_infop);
- LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type_infop, &getEmptyParamBlock<T>);
+ // add this widget to various registries
+ LLUICtrlFactory::instance().registerWidget(&typeid(T), &typeid(typename T::Params), &LLUICtrlFactory::createDefaultWidget<T>, tag);
+
+ // since registry_t depends on T, do this in line here
typedef typename T::child_registry_t registry_t;
- LLChildRegistryRegistry::instance().defaultRegistrar().add(widget_type_infop, registry_t::instance());
+ LLChildRegistryRegistry::instance().defaultRegistrar().add(&typeid(T), registry_t::instance());
}
diff --git a/indra/llui/lluistring.cpp b/indra/llui/lluistring.cpp
index 20ff71378e..3a1e656364 100644
--- a/indra/llui/lluistring.cpp
+++ b/indra/llui/lluistring.cpp
@@ -35,8 +35,6 @@
#include "llsd.h"
#include "lltrans.h"
-const LLStringUtil::format_map_t LLUIString::sNullArgs;
-
LLFastTimer::DeclareTimer FTM_UI_STRING("UI String");
diff --git a/indra/llui/lluistring.h b/indra/llui/lluistring.h
index 195f21a6a7..763de4d6a3 100644
--- a/indra/llui/lluistring.h
+++ b/indra/llui/lluistring.h
@@ -95,8 +95,6 @@ public:
void insert(S32 charidx, const LLWString& wchars);
void replace(S32 charidx, llwchar wc);
- static const LLStringUtil::format_map_t sNullArgs;
-
private:
void format();
diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
index 6dd1f93baf..318a0348a2 100644
--- a/indra/llxuixml/llinitparam.cpp
+++ b/indra/llxuixml/llinitparam.cpp
@@ -38,8 +38,6 @@
namespace LLInitParam
{
- BlockDescriptor BaseBlock::sBlockDescriptor;
-
//
// Param
//
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 4c936197c9..9fb464ca7b 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -46,6 +46,7 @@
namespace LLInitParam
{
+
template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value >
struct ParamCompare
{
@@ -474,7 +475,11 @@ namespace LLInitParam
BlockDescriptor* mBlockDescriptor; // most derived block descriptor
- static BlockDescriptor sBlockDescriptor;
+ static BlockDescriptor& blockDescriptor()
+ {
+ static BlockDescriptor sBlockDescriptor;
+ return sBlockDescriptor;
+ }
private:
const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
@@ -493,13 +498,13 @@ namespace LLInitParam
// that derive from BaseBlock and those that don't
// this is supposedly faster than boost::is_convertible and its ilk
template<typename T, typename Void = void>
- struct is_BaseBlock
+ struct IsBaseBlock
{
static const bool value = false;
};
template<typename T>
- struct is_BaseBlock<T, typename T::baseblock_base_class_t>
+ struct IsBaseBlock<T, typename T::baseblock_base_class_t>
{
static const bool value = true;
};
@@ -509,7 +514,7 @@ namespace LLInitParam
template<typename T,
typename NAME_VALUE_LOOKUP = TypeValues<T>,
bool HAS_MULTIPLE_VALUES = false,
- bool VALUE_IS_BLOCK = is_BaseBlock<T>::value>
+ bool VALUE_IS_BLOCK = IsBaseBlock<T>::value>
class TypedParam
: public Param
{
@@ -1246,7 +1251,7 @@ namespace LLInitParam
bool overwriteFrom(const self_t& other)
{
mCurChoice = other.mCurChoice;
- return BaseBlock::overwriteFromImpl(sBlockDescriptor, other);
+ return BaseBlock::overwriteFromImpl(blockDescriptor(), other);
}
// take all provided params that are not already provided, and apply to self
@@ -1277,7 +1282,7 @@ namespace LLInitParam
Choice()
: mCurChoice(0)
{
- BaseBlock::init(sBlockDescriptor, BaseBlock::sBlockDescriptor, sizeof(DERIVED_BLOCK));
+ BaseBlock::init(blockDescriptor(), BaseBlock::blockDescriptor(), sizeof(DERIVED_BLOCK));
}
// Alternatives are mutually exclusive wrt other Alternatives in the same block.
@@ -1290,16 +1295,16 @@ namespace LLInitParam
friend class Choice<DERIVED_BLOCK>;
typedef Alternative<T, NAME_VALUE_LOOKUP> self_t;
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, is_BaseBlock<T>::value> super_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBaseBlock<T>::value> super_t;
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::sBlockDescriptor, name, val, NULL, 0, 1),
+ : super_t(DERIVED_BLOCK::blockDescriptor(), name, val, NULL, 0, 1),
mOriginalValue(val)
{
// assign initial choice to first declared option
- DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::sBlockDescriptor.mCurrentBlockPtr);
- if (DERIVED_BLOCK::sBlockDescriptor.mInitializationState == BlockDescriptor::INITIALIZING
+ DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::blockDescriptor().mCurrentBlockPtr);
+ if (DERIVED_BLOCK::blockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING
&& blockp->mCurChoice == 0)
{
blockp->mCurChoice = Param::enclosingBlock().getHandleFromParam(this);
@@ -1345,7 +1350,11 @@ namespace LLInitParam
};
protected:
- static BlockDescriptor sBlockDescriptor;
+ static BlockDescriptor& blockDescriptor()
+ {
+ static BlockDescriptor sBlockDescriptor;
+ return sBlockDescriptor;
+ }
private:
param_handle_t mCurChoice;
@@ -1356,15 +1365,6 @@ namespace LLInitParam
}
};
- template<typename DERIVED_BLOCK>
- BlockDescriptor
- Choice<DERIVED_BLOCK>::sBlockDescriptor;
-
- //struct CardinalityConstraint
- //{
- // virtual std::pair<S32, S32> getRange() = 0;
- //};
-
struct AnyAmount
{
static U32 minCount() { return 0; }
@@ -1412,19 +1412,19 @@ namespace LLInitParam
// take all provided params from other and apply to self
bool overwriteFrom(const self_t& other)
{
- return BaseBlock::overwriteFromImpl(sBlockDescriptor, other);
+ return BaseBlock::overwriteFromImpl(blockDescriptor(), other);
}
// take all provided params that are not already provided, and apply to self
bool fillFrom(const self_t& other)
{
- return BaseBlock::fillFromImpl(sBlockDescriptor, other);
+ return BaseBlock::fillFromImpl(blockDescriptor(), other);
}
protected:
Block()
{
//#pragma message("Parsing LLInitParam::Block")
- BaseBlock::init(sBlockDescriptor, BASE_BLOCK::sBlockDescriptor, sizeof(DERIVED_BLOCK));
+ BaseBlock::init(blockDescriptor(), BASE_BLOCK::blockDescriptor(), sizeof(DERIVED_BLOCK));
}
//
@@ -1434,11 +1434,11 @@ namespace LLInitParam
class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>
{
public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, is_BaseBlock<T>::value> super_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBaseBlock<T>::value> super_t;
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::sBlockDescriptor, name, val, NULL, 0, 1)
+ : super_t(DERIVED_BLOCK::blockDescriptor(), name, val, NULL, 0, 1)
{
//#pragma message("Parsing LLInitParam::Block::Optional")
}
@@ -1461,13 +1461,13 @@ namespace LLInitParam
class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
{
public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, is_BaseBlock<T>::value> super_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBaseBlock<T>::value> super_t;
typedef Mandatory<T, NAME_VALUE_LOOKUP> self_t;
typedef typename super_t::value_assignment_t value_assignment_t;
// mandatory parameters require a name to be parseable
explicit Mandatory(const char* name = "", value_assignment_t val = DefaultInitializer<T>::get())
- : super_t(DERIVED_BLOCK::sBlockDescriptor, name, val, &validate, 1, 1)
+ : super_t(DERIVED_BLOCK::blockDescriptor(), name, val, &validate, 1, 1)
{}
Mandatory& operator=(value_assignment_t val)
@@ -1495,7 +1495,7 @@ namespace LLInitParam
class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
{
public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, true, is_BaseBlock<T>::value> super_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBaseBlock<T>::value> super_t;
typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP> self_t;
typedef typename super_t::container_t container_t;
typedef typename super_t::value_assignment_t value_assignment_t;
@@ -1503,7 +1503,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::sBlockDescriptor, name, val, &validate, RANGE::minCount(), RANGE::maxCount())
+ : super_t(DERIVED_BLOCK::blockDescriptor(), name, val, &validate, RANGE::minCount(), RANGE::maxCount())
{}
using super_t::operator();
@@ -1531,9 +1531,9 @@ namespace LLInitParam
{
public:
explicit Deprecated(const char* name)
- : Param(DERIVED_BLOCK::sBlockDescriptor.mCurrentBlockPtr)
+ : Param(DERIVED_BLOCK::blockDescriptor().mCurrentBlockPtr)
{
- BlockDescriptor& block_descriptor = DERIVED_BLOCK::sBlockDescriptor;
+ BlockDescriptor& block_descriptor = DERIVED_BLOCK::blockDescriptor();
if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
{
ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
@@ -1563,13 +1563,13 @@ namespace LLInitParam
typedef Deprecated Ignored;
protected:
- static BlockDescriptor sBlockDescriptor;
+ static BlockDescriptor& blockDescriptor()
+ {
+ static BlockDescriptor sBlockDescriptor;
+ return sBlockDescriptor;
+ }
};
- template<typename DERIVED_BLOCK, typename BASE_BLOCK>
- BlockDescriptor
- Block<DERIVED_BLOCK, BASE_BLOCK>::sBlockDescriptor;
-
template<typename T, typename DERIVED = TypedParam<T> >
class BlockValue
: public Block<TypedParam<T, TypeValues<T>, false> >,
@@ -1803,11 +1803,11 @@ namespace LLInitParam
// assign individual parameters
if (overwrite)
{
- dst_typed_param.BaseBlock::overwriteFromImpl(block_t::sBlockDescriptor, src_param);
+ dst_typed_param.BaseBlock::overwriteFromImpl(block_t::blockDescriptor(), src_param);
}
else
{
- dst_typed_param.BaseBlock::fillFromImpl(block_t::sBlockDescriptor, src_param);
+ dst_typed_param.BaseBlock::fillFromImpl(block_t::blockDescriptor(), src_param);
}
// then copy actual value
dst_typed_param.mData.mValue = src_param.get();
diff --git a/indra/llxuixml/lltrans.cpp b/indra/llxuixml/lltrans.cpp
index e974dbd0ba..4c800a502d 100644
--- a/indra/llxuixml/lltrans.cpp
+++ b/indra/llxuixml/lltrans.cpp
@@ -72,7 +72,7 @@ bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set<std::string>& defa
}
StringTable string_table;
- LLXUIParser::instance().readXUI(root, string_table);
+ LLXUIParser::instance().readXUI(root, string_table, xml_filename);
if (!string_table.validateBlock())
{
@@ -115,7 +115,7 @@ bool LLTrans::parseLanguageStrings(LLXMLNodePtr &root)
}
StringTable string_table;
- LLXUIParser::instance().readXUI(root, string_table);
+ LLXUIParser::instance().readXUI(root, string_table, xml_filename);
if (!string_table.validateBlock())
{
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index e28e52fd16..17399865e5 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -34,6 +34,7 @@
#include "llxuiparser.h"
+#include "llxmlnode.h"
#include <fstream>
#include <boost/tokenizer.hpp>
@@ -401,10 +402,11 @@ LLXUIParser::LLXUIParser()
static LLFastTimer::DeclareTimer FTM_PARSE_XUI("XUI Parsing");
-void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, bool silent)
+void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, const std::string& filename, bool silent)
{
LLFastTimer timer(FTM_PARSE_XUI);
mNameStack.clear();
+ mCurFileName = filename;
mCurReadDepth = 0;
setParseSilently(silent);
@@ -946,9 +948,9 @@ bool LLXUIParser::writeSDValue(const void* val_ptr, const name_stack_t& stack)
void LLXUIParser::parserWarning(const std::string& message)
{
-#if 0 //#ifdef LL_WINDOWS
+#ifdef LL_WINDOWS
// use Visual Studo friendly formatting of output message for easy access to originating xml
- llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", LLUICtrlFactory::getInstance()->getCurFileName().c_str(), mCurReadNode->getLineNumber(), message.c_str()).c_str());
+ llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()).c_str());
utf16str += '\n';
OutputDebugString(utf16str.c_str());
#else
@@ -958,8 +960,8 @@ void LLXUIParser::parserWarning(const std::string& message)
void LLXUIParser::parserError(const std::string& message)
{
-#if 0 //#ifdef LL_WINDOWS
- llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", LLUICtrlFactory::getInstance()->getCurFileName().c_str(), mCurReadNode->getLineNumber(), message.c_str()).c_str());
+#ifdef LL_WINDOWS
+ llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()).c_str());
utf16str += '\n';
OutputDebugString(utf16str.c_str());
#else
diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h
index 6f000f2422..884f4f7578 100644
--- a/indra/llxuixml/llxuiparser.h
+++ b/indra/llxuixml/llxuiparser.h
@@ -34,9 +34,9 @@
#define LLXUIPARSER_H
#include "llinitparam.h"
-#include "llxmlnode.h"
#include "llfasttimer.h"
#include "llregistry.h"
+#include "llpointer.h"
#include <boost/function.hpp>
#include <iosfwd>
@@ -48,6 +48,8 @@
class LLView;
+typedef LLPointer<class LLXMLNode> LLXMLNodePtr;
+
// lookup widget type by name
class LLWidgetTypeRegistry
@@ -114,7 +116,7 @@ public:
/*virtual*/ void parserWarning(const std::string& message);
/*virtual*/ void parserError(const std::string& message);
- void readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, bool silent=false);
+ void readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, const std::string& filename = LLStringUtil::null, bool silent=false);
void writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const LLInitParam::BaseBlock* diff_block = NULL);
private:
@@ -168,6 +170,7 @@ private:
S32 mLastWriteGeneration;
LLXMLNodePtr mLastWrittenChild;
S32 mCurReadDepth;
+ std::string mCurFileName;
};
diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt
index 5c0ce3ee17..a9f7938b41 100644
--- a/indra/media_plugins/gstreamer010/CMakeLists.txt
+++ b/indra/media_plugins/gstreamer010/CMakeLists.txt
@@ -42,12 +42,12 @@ set(media_plugin_gstreamer010_HEADER_FILES
llmediaimplgstreamertriviallogging.h
)
-if (${CXX_VERSION} MATCHES "4.[23]")
+if (${CXX_VERSION} MATCHES "4[23].")
# Work around a bad interaction between broken gstreamer headers and
# g++ 4.3's increased strictness.
set_source_files_properties(llmediaimplgstreamervidplug.cpp PROPERTIES
- COMPILE_FLAGS -Wno-error=write-strings)
-endif (${CXX_VERSION} MATCHES "4.[23]")
+ COMPILE_FLAGS -Wno-write-strings)
+endif (${CXX_VERSION} MATCHES "4[23].")
add_library(media_plugin_gstreamer010
SHARED
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 1e5a798202..5fdf13b078 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -70,6 +70,7 @@ set(viewer_SOURCE_FILES
llagentaccess.cpp
llagentdata.cpp
llagentlanguage.cpp
+ llagentpicksinfo.cpp
llagentpilot.cpp
llagentui.cpp
llagentwearables.cpp
@@ -113,6 +114,7 @@ set(viewer_SOURCE_FILES
lldebugview.cpp
lldelayedgestureerror.cpp
lldirpicker.cpp
+ lldndbutton.cpp
lldrawable.cpp
lldrawpoolalpha.cpp
lldrawpoolavatar.cpp
@@ -341,6 +343,7 @@ set(viewer_SOURCE_FILES
llpanelteleporthistory.cpp
llpanelvolume.cpp
llparcelselection.cpp
+ llparticipantlist.cpp
llpatchvertexarray.cpp
llplacesinventorybridge.cpp
llpolymesh.cpp
@@ -414,6 +417,8 @@ set(viewer_SOURCE_FILES
lltoolselectland.cpp
lltoolselectrect.cpp
lltracker.cpp
+ lltransientdockablefloater.cpp
+ lltransientfloatermgr.cpp
lluilistener.cpp
lluploaddialog.cpp
llurl.cpp
@@ -540,6 +545,7 @@ set(viewer_HEADER_FILES
llagentaccess.h
llagentdata.h
llagentlanguage.h
+ llagentpicksinfo.h
llagentpilot.h
llagentui.h
llagentwearables.h
@@ -585,6 +591,7 @@ set(viewer_HEADER_FILES
lldebugview.h
lldelayedgestureerror.h
lldirpicker.h
+ lldndbutton.h
lldrawable.h
lldrawpool.h
lldrawpoolalpha.h
@@ -810,6 +817,7 @@ set(viewer_HEADER_FILES
llpanelteleporthistory.h
llpanelvolume.h
llparcelselection.h
+ llparticipantlist.h
llpatchvertexarray.h
llplacesinventorybridge.h
llpolymesh.h
@@ -886,6 +894,8 @@ set(viewer_HEADER_FILES
lltoolselectland.h
lltoolselectrect.h
lltracker.h
+ lltransientdockablefloater.h
+ lltransientfloatermgr.h
lluiconstants.h
lluilistener.h
lluploaddialog.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 91d5e04665..fd0e05e7e2 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4842,10 +4842,10 @@
<key>Value</key>
<integer>350</integer>
</map>
- <key>NotificationToastTime</key>
+ <key>NotificationToastLifeTime</key>
<map>
<key>Comment</key>
- <string>Width of notification messages</string>
+ <string>Number of seconds while a notification toast exists</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -4853,21 +4853,32 @@
<key>Value</key>
<integer>5</integer>
</map>
+ <key>NotificationTipToastLifeTime</key>
+ <map>
+ <key>Comment</key>
+ <string>Number of seconds while a notification tip toast exist</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>10</integer>
+ </map>
<key>ToastOpaqueTime</key>
<map>
<key>Comment</key>
- <string>Width of notification messages</string>
+ <string>Number of seconds while a toast is fading </string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
- <integer>4</integer>
+ <integer>1</integer>
</map>
- <key>StartUpToastTime</key>
+ <key>StartUpToastLifeTime</key>
<map>
<key>Comment</key>
- <string>Width of notification messages</string>
+ <string>Number of seconds while a StartUp toast exist</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -4875,10 +4886,10 @@
<key>Value</key>
<integer>5</integer>
</map>
- <key>ToastMargin</key>
+ <key>ToastGap</key>
<map>
<key>Comment</key>
- <string>Width of notification messages</string>
+ <string>Gap between toasts on a screen</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -4889,7 +4900,7 @@
<key>ChannelBottomPanelMargin</key>
<map>
<key>Comment</key>
- <string>Width of notification messages</string>
+ <string>Space from a lower toast to the Bottom Tray</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -4900,7 +4911,7 @@
<key>NotificationChannelRightMargin</key>
<map>
<key>Comment</key>
- <string>Width of notification messages</string>
+ <string>Space between toasts and a right border of an area where they can appear</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -4911,7 +4922,7 @@
<key>OverflowToastHeight</key>
<map>
<key>Comment</key>
- <string>Width of notification messages</string>
+ <string>Height of an overflow toast</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8559,13 +8570,13 @@
<key>ToolTipVisibleTimeNear</key>
<map>
<key>Comment</key>
- <string>Fade tooltip after after time passes (seconds) while mouse near tooltip</string>
+ <string>Fade tooltip after after time passes (seconds) while mouse near tooltip or original position</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>5.0</real>
+ <real>10.0</real>
</map>
<key>ToolTipVisibleTimeOver</key>
<map>
@@ -10526,6 +10537,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>ShowDeviceSettings</key>
+ <map>
+ <key>Comment</key>
+ <string>Show device settings</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>soundsbeacon</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llagentpicksinfo.cpp b/indra/newview/llagentpicksinfo.cpp
new file mode 100644
index 0000000000..6e5835bace
--- /dev/null
+++ b/indra/newview/llagentpicksinfo.cpp
@@ -0,0 +1,130 @@
+/**
+ * @file llagentpicksinfo.cpp
+ * @brief LLAgentPicksInfo class implementation
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, 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 "llagentpicksinfo.h"
+
+#include "llagent.h"
+#include "llavatarconstants.h"
+#include "llavatarpropertiesprocessor.h"
+
+class LLAgentPicksInfo::LLAgentPicksObserver : public LLAvatarPropertiesObserver
+{
+public:
+ LLAgentPicksObserver()
+ {
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(gAgent.getID(), this);
+ }
+
+ ~LLAgentPicksObserver()
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(gAgent.getID(), this);
+ }
+
+ void sendAgentPicksRequest()
+ {
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(gAgent.getID());
+ }
+
+ typedef boost::function<void(LLAvatarPicks*)> server_respond_callback_t;
+
+ void setServerRespondCallback(const server_respond_callback_t& cb)
+ {
+ mServerRespondCallback = cb;
+ }
+
+ virtual void processProperties(void* data, EAvatarProcessorType type)
+ {
+ if(APT_PICKS == type)
+ {
+ LLAvatarPicks* picks = static_cast<LLAvatarPicks*>(data);
+ if(picks && gAgent.getID() == picks->target_id)
+ {
+ if(mServerRespondCallback)
+ {
+ mServerRespondCallback(picks);
+ }
+ }
+ }
+ }
+
+private:
+
+ server_respond_callback_t mServerRespondCallback;
+};
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLAgentPicksInfo::LLAgentPicksInfo()
+ : mAgentPicksObserver(NULL)
+ , mMaxNumberOfPicks(MAX_AVATAR_PICKS)
+ // Disable Pick creation until we get number of Picks from server - in case
+ // avatar has maximum number of Picks.
+ , mNumberOfPicks(mMaxNumberOfPicks)
+{
+}
+
+LLAgentPicksInfo::~LLAgentPicksInfo()
+{
+ delete mAgentPicksObserver;
+}
+
+void LLAgentPicksInfo::requestNumberOfPicks()
+{
+ if(!mAgentPicksObserver)
+ {
+ mAgentPicksObserver = new LLAgentPicksObserver();
+
+ mAgentPicksObserver->setServerRespondCallback(boost::bind(
+ &LLAgentPicksInfo::onServerRespond, this, _1));
+ }
+
+ mAgentPicksObserver->sendAgentPicksRequest();
+}
+
+bool LLAgentPicksInfo::isPickLimitReached()
+{
+ return getNumberOfPicks() >= getMaxNumberOfPicks();
+}
+
+void LLAgentPicksInfo::onServerRespond(LLAvatarPicks* picks)
+{
+ if(!picks)
+ {
+ llerrs << "Unexpected value" << llendl;
+ return;
+ }
+
+ setNumberOfPicks(picks->picks_list.size());
+}
diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h
new file mode 100644
index 0000000000..0e30f2c5a0
--- /dev/null
+++ b/indra/newview/llagentpicksinfo.h
@@ -0,0 +1,106 @@
+/**
+ * @file llagentpicksinfo.h
+ * @brief LLAgentPicksInfo class header file
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, 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_LLAGENTPICKS_H
+#define LL_LLAGENTPICKS_H
+
+#include "llsingleton.h"
+
+struct LLAvatarPicks;
+
+/**
+ * Class that provides information about Agent Picks
+ */
+class LLAgentPicksInfo : public LLSingleton<LLAgentPicksInfo>
+{
+ class LLAgentPicksObserver;
+
+public:
+
+ LLAgentPicksInfo();
+
+ virtual ~LLAgentPicksInfo();
+
+ /**
+ * Requests number of picks from server.
+ *
+ * Number of Picks is requested from server, thus it is not available immediately.
+ */
+ void requestNumberOfPicks();
+
+ /**
+ * Returns number of Picks.
+ */
+ S32 getNumberOfPicks() { return mNumberOfPicks; }
+
+ /**
+ * Returns maximum number of Picks.
+ */
+ S32 getMaxNumberOfPicks() { return mMaxNumberOfPicks; }
+
+ /**
+ * Returns TRUE if Agent has maximum allowed number of Picks.
+ */
+ bool isPickLimitReached();
+
+ /**
+ * After creating or deleting a Pick we can assume operation on server will be
+ * completed successfully. Incrementing/decrementing number of picks makes new number
+ * of picks available immediately. Actual number of picks will be updated when we receive
+ * response from server.
+ */
+ void incrementNumberOfPicks() { ++mNumberOfPicks; }
+
+ void decrementNumberOfPicks() { --mNumberOfPicks; }
+
+private:
+
+ void onServerRespond(LLAvatarPicks* picks);
+
+ /**
+ * Sets number of Picks.
+ */
+ void setNumberOfPicks(S32 number) { mNumberOfPicks = number; }
+
+ /**
+ * Sets maximum number of Picks.
+ */
+ void setMaxNumberOfPicks(S32 max_picks) { mMaxNumberOfPicks = max_picks; }
+
+private:
+
+ LLAgentPicksObserver* mAgentPicksObserver;
+ S32 mMaxNumberOfPicks;
+ S32 mNumberOfPicks;
+};
+
+#endif //LL_LLAGENTPICKS_H
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 34d2c00007..bb00468d40 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -68,8 +68,11 @@ public:
EWearableType mType;
LLUUID mItemID;
LLUUID mAssetID;
- InitialWearableData(EWearableType type, LLUUID itemID, LLUUID assetID) :
- mType(type), mItemID(itemID), mAssetID(assetID) { }
+ InitialWearableData(EWearableType type, LLUUID& itemID, LLUUID& assetID) :
+ mType(type),
+ mItemID(itemID),
+ mAssetID(assetID)
+ {}
};
typedef std::vector<InitialWearableData> initial_wearable_data_vec_t;
@@ -654,7 +657,7 @@ U32 LLAgentWearables::pushWearable(const EWearableType type, LLWearable *wearabl
if (wearable == NULL)
{
// no null wearables please!
- //TODO: insert llwarns
+ llwarns << "Null wearable sent for type " << type << llendl;
return MAX_WEARABLES_PER_TYPE;
}
if (type < WT_COUNT || mWearableDatas[type].size() < MAX_WEARABLES_PER_TYPE)
@@ -1090,7 +1093,7 @@ void LLAgentWearables::getAllWearablesArray(LLDynamicArray<S32>& wearables)
{
for( S32 i = 0; i < WT_COUNT; ++i )
{
- if (getWearableCount( (EWearableType) i) != 0 )
+ if (getWearableCount((EWearableType) i) != 0)
{
wearables.push_back(i);
}
@@ -1300,8 +1303,8 @@ void LLAgentWearables::addWearableToAgentInventory(LLPointer<LLInventoryCallback
void LLAgentWearables::removeWearable(const EWearableType type, bool do_remove_all, U32 index)
{
- if ((gAgent.isTeen())
- && (type == WT_UNDERSHIRT || type == WT_UNDERPANTS))
+ if (gAgent.isTeen() &&
+ (type == WT_UNDERSHIRT || type == WT_UNDERPANTS))
{
// Can't take off underclothing in simple UI mode or on PG accounts
// TODO: enable the removing of a single undershirt/underpants if multiple are worn. - Nyx
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 0cf28f590a..1eaabd7ec3 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -966,7 +966,7 @@ void LLAppearanceManager::wearEnsemble( LLInventoryCategory* cat, bool do_update
}
/* static */
-void LLAppearanceManager::removeItemLinks(LLUUID& item_id, bool do_update)
+void LLAppearanceManager::removeItemLinks(const LLUUID& item_id, bool do_update)
{
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 928b5f2bcd..828af32101 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -62,7 +62,7 @@ public:
static LLUUID getCOF();
// Remove COF entries
- static void removeItemLinks(LLUUID& item_id, bool do_update = true);
+ static void removeItemLinks(const LLUUID& item_id, bool do_update = true);
// For debugging - could be moved elsewhere.
static void dumpCat(const LLUUID& cat_id, std::string str);
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index ef48420490..2034f98517 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -57,17 +57,13 @@ static const LLAvatarItemNameComparator NAME_COMPARATOR;
static const LLFlatListView::ItemReverseComparator REVERSE_NAME_COMPARATOR(NAME_COMPARATOR);
LLAvatarList::Params::Params()
-:
-volume_column_width("volume_column_width", 0)
-, online_go_first("online_go_first", true)
+: ignore_online_status("ignore_online_status", false)
{
}
-
-
LLAvatarList::LLAvatarList(const Params& p)
: LLFlatListView(p)
-, mOnlineGoFirst(p.online_go_first)
+, mIgnoreOnlineStatus(p.ignore_online_status)
, mContextMenu(NULL)
, mDirty(true) // to force initial update
{
@@ -194,15 +190,15 @@ void LLAvatarList::refresh()
}
-void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
+void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_online, EAddPosition pos)
{
LLAvatarListItem* item = new LLAvatarListItem();
item->showStatus(false);
item->showInfoBtn(true);
item->showSpeakingIndicator(true);
item->setName(name);
- item->setAvatarId(id);
- item->setOnline(is_bold);
+ item->setAvatarId(id, mIgnoreOnlineStatus);
+ item->setOnline(mIgnoreOnlineStatus ? true : is_online);
item->setContextMenu(mContextMenu);
item->childSetVisible("info_btn", false);
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index ec801645fe..7372538006 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -55,8 +55,7 @@ public:
struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>
{
- Optional<S32> volume_column_width;
- Optional<bool> online_go_first;
+ Optional<bool> ignore_online_status; // show all items as online
Params();
};
@@ -76,7 +75,7 @@ public:
protected:
void refresh();
- void addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
+ void addNewItem(const LLUUID& id, const std::string& name, BOOL is_online, EAddPosition pos = ADD_BOTTOM);
void computeDifference(
const std::vector<LLUUID>& vnew,
std::vector<LLUUID>& vadded,
@@ -84,7 +83,7 @@ protected:
private:
- bool mOnlineGoFirst;
+ bool mIgnoreOnlineStatus;
bool mDirty;
std::string mNameFilter;
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 90408beca0..732db90cdb 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -180,7 +180,7 @@ void LLAvatarListItem::setName(const std::string& name)
mAvatarName->setToolTip(name);
}
-void LLAvatarListItem::setAvatarId(const LLUUID& id)
+void LLAvatarListItem::setAvatarId(const LLUUID& id, bool ignore_status_changes)
{
if (mAvatarId.notNull())
LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarId, this);
@@ -190,7 +190,7 @@ void LLAvatarListItem::setAvatarId(const LLUUID& id)
mSpeakingIndicator->setSpeakerId(id);
// We'll be notified on avatar online status changes
- if (mAvatarId.notNull())
+ if (!ignore_status_changes && mAvatarId.notNull())
LLAvatarTracker::instance().addParticularFriendObserver(mAvatarId, this);
// Set avatar name.
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index 2330db5249..ca75e3898f 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -64,7 +64,7 @@ public:
void setStatus(const std::string& status);
void setOnline(bool online);
void setName(const std::string& name);
- void setAvatarId(const LLUUID& id);
+ void setAvatarId(const LLUUID& id, bool ignore_status_changes = false);
const LLUUID& getAvatarId() const;
const std::string getAvatarName() const;
diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp
index f58c85d8c5..fb43b5a7d7 100644
--- a/indra/newview/llavatarpropertiesprocessor.cpp
+++ b/indra/newview/llavatarpropertiesprocessor.cpp
@@ -36,6 +36,7 @@
// Viewer includes
#include "llagent.h"
+#include "llagentpicksinfo.h"
#include "llviewergenericmessage.h"
// Linden library includes
@@ -438,6 +439,9 @@ void LLAvatarPropertiesProcessor::sendPickDelete( const LLUUID& pick_id )
msg->nextBlock(_PREHASH_Data);
msg->addUUID(_PREHASH_PickID, pick_id);
gAgent.sendReliableMessage();
+
+ LLAgentPicksInfo::getInstance()->requestNumberOfPicks();
+ LLAgentPicksInfo::getInstance()->decrementNumberOfPicks();
}
void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick)
@@ -470,6 +474,8 @@ void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick)
msg->addBOOL(_PREHASH_Enabled, new_pick->enabled);
gAgent.sendReliableMessage();
+
+ LLAgentPicksInfo::getInstance()->requestNumberOfPicks();
}
void LLAvatarPropertiesProcessor::sendPickInfoRequest(const LLUUID& creator_id, const LLUUID& pick_id)
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 8987f14e97..da84303863 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -134,8 +134,9 @@ LLIMChiclet* LLBottomTray::createIMChiclet(const LLUUID& session_id)
case LLIMChiclet::TYPE_IM:
return getChicletPanel()->createChiclet<LLIMP2PChiclet>(session_id);
case LLIMChiclet::TYPE_GROUP:
- case LLIMChiclet::TYPE_AD_HOC:
return getChicletPanel()->createChiclet<LLIMGroupChiclet>(session_id);
+ case LLIMChiclet::TYPE_AD_HOC:
+ return getChicletPanel()->createChiclet<LLAdHocChiclet>(session_id);
case LLIMChiclet::TYPE_UNKNOWN:
break;
}
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index c4619dc57a..77f941eef0 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -39,6 +39,7 @@
#include "llimview.h"
#include "llbottomtray.h"
#include "llviewerwindow.h"
+#include "llrootview.h"
#include <algorithm>
@@ -121,6 +122,8 @@ void LLChannelManager::onLoginCompleted()
return;
}
+ gViewerWindow->getRootView()->addChild(mStartUpChannel);
+
// init channel's position and size
S32 channel_right_bound = gViewerWindow->getWorldViewRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
@@ -128,7 +131,7 @@ void LLChannelManager::onLoginCompleted()
mStartUpChannel->setShowToasts(true);
mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this));
- mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("ChannelBottomPanelMargin"), gSavedSettings.getS32("StartUpToastTime"));
+ mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("StartUpToastLifeTime"));
}
//--------------------------------------------------------------------------
@@ -139,19 +142,11 @@ void LLChannelManager::onStartUpToastClose()
mStartUpChannel->setVisible(FALSE);
mStartUpChannel->closeStartUpToast();
removeChannelByID(LLUUID(gSavedSettings.getString("StartUpChannelUUID")));
- delete mStartUpChannel;
mStartUpChannel = NULL;
}
// set StartUp Toast Flag to allow all other channels to show incoming toasts
LLScreenChannel::setStartUpToastShown();
-
- // force NEARBY CHAT CHANNEL to repost all toasts if present
- //LLScreenChannelBase* nearby_channel = findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
- //!!!!!!!!!!!!!!
- //FIXME
- //nearby_channel->loadStoredToastsToChannel();
- //nearby_channel->setCanStoreToasts(false);
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index cc21b636f1..ebf46a6e3f 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -101,12 +101,12 @@ void LLChatHistory::appendWidgetMessage(const LLUUID& avatar_id, std::string& fr
if (mLastFromName == from)
{
view = getSeparator();
- view_text = "\n";
+ view_text = " ";
}
else
{
view = getHeader(avatar_id, from, time);
- view_text = from + MESSAGE_USERNAME_DATE_SEPARATOR + time;
+ view_text = "\n" + from + MESSAGE_USERNAME_DATE_SEPARATOR + time;
}
//Prepare the rect for the view
LLRect target_rect = getDocumentView()->getRect();
@@ -115,12 +115,12 @@ void LLChatHistory::appendWidgetMessage(const LLUUID& avatar_id, std::string& fr
view->reshape(target_rect.getWidth(), view->getRect().getHeight());
view->setOrigin(target_rect.mLeft, view->getRect().mBottom);
- this->appendWidget(view, view_text, FALSE, TRUE);
+ appendWidget(view, view_text, FALSE, TRUE, mLeftWidgetPad, 0);
//Append the text message
- this->appendText(message, TRUE, style_params);
+ appendText(message, TRUE, style_params);
mLastFromName = from;
- this->blockUndo();
- this->setCursorAndScrollToEnd();
+ blockUndo();
+ setCursorAndScrollToEnd();
}
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 340b0fa22c..2ebbae33ad 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -468,6 +468,115 @@ void LLIMP2PChiclet::setShowSpeaker(bool show)
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
+LLAdHocChiclet::Params::Params()
+: avatar_icon("avatar_icon")
+, unread_notifications("unread_notifications")
+, speaker("speaker")
+, show_speaker("show_speaker")
+{
+ // *TODO Vadim: Get rid of hardcoded values.
+ rect(LLRect(0, 25, 45, 0));
+
+ avatar_icon.name("avatar_icon");
+ avatar_icon.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
+
+ // *NOTE dzaporozhan
+ // Changed icon height from 25 to 24 to fix ticket EXT-794.
+ // In some cases(after changing UI scale) 25 pixel height icon was
+ // drawn incorrectly, i'm not sure why.
+ avatar_icon.rect(LLRect(0, 24, 25, 0));
+ avatar_icon.mouse_opaque(false);
+
+ unread_notifications.name("unread");
+ unread_notifications.rect(LLRect(25, 25, 45, 0));
+ unread_notifications.font(LLFontGL::getFontSansSerif());
+ unread_notifications.font_halign(LLFontGL::HCENTER);
+ unread_notifications.v_pad(5);
+ unread_notifications.text_color(LLColor4::white);
+ unread_notifications.mouse_opaque(false);
+
+ speaker.name("speaker");
+ speaker.rect(LLRect(45, 25, 65, 0));
+
+ show_speaker = false;
+}
+
+LLAdHocChiclet::LLAdHocChiclet(const Params& p)
+: LLIMChiclet(p)
+, mChicletIconCtrl(NULL)
+, mCounterCtrl(NULL)
+, mSpeakerCtrl(NULL)
+, mPopupMenu(NULL)
+{
+ LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon;
+ mChicletIconCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params);
+ addChild(mChicletIconCtrl);
+
+ LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
+ mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
+ addChild(mCounterCtrl);
+
+ setCounter(getCounter());
+ setShowCounter(getShowCounter());
+
+ LLChicletSpeakerCtrl::Params speaker_params = p.speaker;
+ mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params);
+ addChild(mSpeakerCtrl);
+
+ setShowSpeaker(p.show_speaker);
+}
+
+void LLAdHocChiclet::setSessionId(const LLUUID& session_id)
+{
+ LLChiclet::setSessionId(session_id);
+ LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id);
+ mChicletIconCtrl->setValue(im_session->mOtherParticipantID);
+}
+
+void LLAdHocChiclet::setCounter(S32 counter)
+{
+ mCounterCtrl->setCounter(counter);
+
+ if(getShowCounter())
+ {
+ LLRect counter_rect = mCounterCtrl->getRect();
+ LLRect required_rect = mCounterCtrl->getRequiredRect();
+ bool needs_resize = required_rect.getWidth() != counter_rect.getWidth();
+
+ if(needs_resize)
+ {
+ counter_rect.mRight = counter_rect.mLeft + required_rect.getWidth();
+ mCounterCtrl->reshape(counter_rect.getWidth(), counter_rect.getHeight());
+ mCounterCtrl->setRect(counter_rect);
+
+ onChicletSizeChanged();
+ }
+ }
+}
+
+LLRect LLAdHocChiclet::getRequiredRect()
+{
+ LLRect rect(0, 0, mChicletIconCtrl->getRect().getWidth(), 0);
+ if(getShowCounter())
+ {
+ rect.mRight += mCounterCtrl->getRequiredRect().getWidth();
+ }
+ if(getShowSpeaker())
+ {
+ rect.mRight += mSpeakerCtrl->getRect().getWidth();
+ }
+ return rect;
+}
+
+BOOL LLAdHocChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ return TRUE;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
LLIMGroupChiclet::Params::Params()
: group_icon("group_icon")
{
@@ -752,25 +861,36 @@ void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){
BOOL LLChicletPanel::postBuild()
{
LLPanel::postBuild();
- LLIMModel::instance().addChangedCallback(boost::bind(im_chiclet_callback, this, _1));
+ LLIMModel::instance().addNewMsgCallback(boost::bind(im_chiclet_callback, this, _1));
+ LLIMModel::instance().addNoUnreadMsgsCallback(boost::bind(im_chiclet_callback, this, _1));
LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLChicletPanel::findChiclet<LLChiclet>, this, _1));
return TRUE;
}
+S32 LLChicletPanel::calcChickletPanleWidth()
+{
+ S32 res = 0;
+
+ for (chiclet_list_t::iterator it = mChicletList.begin(); it
+ != mChicletList.end(); it++)
+ {
+ res = (*it)->getRect().getWidth() + getChicletPadding();
+ }
+ return res;
+}
+
bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index)
{
if(mScrollArea->addChild(chiclet))
{
+ // chicklets should be aligned to right edge of scroll panel
S32 offset = 0;
- // if index == 0 and chickelt list isn't empty insert chiclet before first in the list
- // without scrolling, so other visible chicklets aren't change screen position
- if (0 == index && !mChicletList.empty())
+ if (!canScrollLeft())
{
- offset = getChiclet(0)->getRect().mLeft
- - (chiclet->getRequiredRect().getWidth()
- + getChicletPadding());
+ offset = mScrollArea->getRect().getWidth()
+ - chiclet->getRect().getWidth() - calcChickletPanleWidth();
}
mChicletList.insert(mChicletList.begin() + index, chiclet);
@@ -963,25 +1083,16 @@ void LLChicletPanel::arrange()
void LLChicletPanel::trimChiclets()
{
// trim right
- if(canScrollLeft() && !canScrollRight())
+ if(!mChicletList.empty())
{
S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight;
+ S32 first_chiclet_left = getChiclet(0)->getRect().mLeft;
S32 scroll_width = mScrollArea->getRect().getWidth();
- if(last_chiclet_right < scroll_width)
+ if(last_chiclet_right < scroll_width || first_chiclet_left > 0)
{
shiftChiclets(scroll_width - last_chiclet_right);
}
}
-
- // trim left
- if(!mChicletList.empty())
- {
- LLRect first_chiclet_rect = getChiclet(0)->getRect();
- if(first_chiclet_rect.mLeft > 0)
- {
- shiftChiclets( - first_chiclet_rect.mLeft);
- }
- }
}
void LLChicletPanel::showScrollButtonsIfNeeded()
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 458bc73bc4..1713c0258d 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -442,6 +442,65 @@ private:
};
/**
+ * Implements AD-HOC chiclet.
+ */
+class LLAdHocChiclet : public LLIMChiclet
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
+ {
+ Optional<LLChicletAvatarIconCtrl::Params> avatar_icon;
+
+ Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
+
+ Optional<LLChicletSpeakerCtrl::Params> speaker;
+
+ Optional<bool> show_speaker;
+
+ Params();
+ };
+
+ /**
+ * Sets session id.
+ * Session ID for group chat is actually Group ID.
+ */
+ /*virtual*/ void setSessionId(const LLUUID& session_id);
+
+ /*
+ * Sets number of unread messages. Will update chiclet's width if number text
+ * exceeds size of counter and notify it's parent about size change.
+ */
+ /*virtual*/ void setCounter(S32);
+
+ /*
+ * Returns number of unread messages.
+ */
+ /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
+
+ /*
+ * Returns rect, required to display chiclet.
+ * Width is the only valid value.
+ */
+ /*virtual*/ LLRect getRequiredRect();
+
+protected:
+ LLAdHocChiclet(const Params& p);
+ friend class LLUICtrlFactory;
+
+ /*
+ * Displays popup menu.
+ */
+ virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+private:
+
+ LLChicletAvatarIconCtrl* mChicletIconCtrl;
+ LLChicletNotificationCounterCtrl* mCounterCtrl;
+ LLChicletSpeakerCtrl* mSpeakerCtrl;
+ LLMenuGL* mPopupMenu;
+};
+
+/**
* Implements Group chat chiclet.
*/
class LLIMGroupChiclet : public LLIMChiclet, public LLGroupMgrObserver
@@ -594,9 +653,14 @@ public:
virtual ~LLChicletPanel();
/*
- * Creates chiclet and adds it to chiclet list.
+ * Creates chiclet and adds it to chiclet list at specified index.
*/
- template<class T> T* createChiclet(const LLUUID& session_id = LLUUID::null, S32 index = 0);
+ template<class T> T* createChiclet(const LLUUID& session_id, S32 index);
+
+ /*
+ * Creates chiclet and adds it to chiclet list at right.
+ */
+ template<class T> T* createChiclet(const LLUUID& session_id);
/*
* Returns pointer to chiclet of specified type at specified index.
@@ -664,6 +728,8 @@ protected:
LLChicletPanel(const Params&p);
friend class LLUICtrlFactory;
+ S32 calcChickletPanleWidth();
+
/*
* Adds chiclet to list and rearranges all chiclets.
*/
@@ -804,7 +870,7 @@ private:
};
template<class T>
-T* LLChicletPanel::createChiclet(const LLUUID& session_id /*= LLUUID::null*/, S32 index /*= 0*/)
+T* LLChicletPanel::createChiclet(const LLUUID& session_id, S32 index)
{
typename T::Params params;
T* chiclet = LLUICtrlFactory::create<T>(params);
@@ -831,6 +897,12 @@ T* LLChicletPanel::createChiclet(const LLUUID& session_id /*= LLUUID::null*/, S3
}
template<class T>
+T* LLChicletPanel::createChiclet(const LLUUID& session_id)
+{
+ return createChiclet<T>(session_id, mChicletList.size());
+}
+
+template<class T>
T* LLChicletPanel::findChiclet(const LLUUID& im_session_id)
{
if(im_session_id.isNull())
diff --git a/indra/newview/llconfirmationmanager.cpp b/indra/newview/llconfirmationmanager.cpp
index 225f177546..5813943ad3 100644
--- a/indra/newview/llconfirmationmanager.cpp
+++ b/indra/newview/llconfirmationmanager.cpp
@@ -39,6 +39,7 @@
// viewer includes
#include "llnotifications.h"
#include "llstring.h"
+#include "llxmlnode.h"
LLConfirmationManager::ListenerBase::~ListenerBase()
{
diff --git a/indra/newview/lldndbutton.cpp b/indra/newview/lldndbutton.cpp
new file mode 100644
index 0000000000..22f2bb1d16
--- /dev/null
+++ b/indra/newview/lldndbutton.cpp
@@ -0,0 +1,60 @@
+/**
+ * @file lldndbutton.cpp
+ * @brief Implementation of the drag-n-drop button.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, 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 "lldndbutton.h"
+
+
+static LLDefaultChildRegistry::Register<LLDragAndDropButton> r("dnd_button");
+
+LLDragAndDropButton::Params::Params()
+{
+
+}
+
+LLDragAndDropButton::LLDragAndDropButton(Params& params)
+: LLButton(params)
+{
+
+}
+
+BOOL LLDragAndDropButton::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg)
+{
+ if (mDragDropHandler)
+ {
+ return mDragDropHandler(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+ }
+ return false;
+}
+
+// EOF
diff --git a/indra/newview/lldndbutton.h b/indra/newview/lldndbutton.h
new file mode 100644
index 0000000000..c888268187
--- /dev/null
+++ b/indra/newview/lldndbutton.h
@@ -0,0 +1,89 @@
+/**
+ * @file lldndbutton.h
+ * @brief Declaration of the drag-n-drop button.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, 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_LLDNDBUTTON_H
+#define LL_LLDNDBUTTON_H
+
+#include "llbutton.h"
+
+/**
+ * Class representing a button which can handle Drag-And-Drop event.
+ *
+ * LLDragAndDropButton does not contain any logic to handle Drag-And-Drop itself.
+ * Instead it provides drag_drop_handler_t which can be set to the button.
+ * Then each Drag-And-Drop will be delegated to this handler without any pre/post processing.
+ *
+ * All xml parameters are the same as LLButton has.
+ *
+ * @see LLLandmarksPanel for example of usage of this class.
+ */
+class LLDragAndDropButton : public LLButton
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLButton::Params>
+ {
+ Params();
+ };
+
+ LLDragAndDropButton(Params& params);
+
+ typedef boost::function<bool (
+ S32 /*x*/, S32 /*y*/, MASK /*mask*/, BOOL /*drop*/,
+ EDragAndDropType /*cargo_type*/,
+ void* /*cargo_data*/,
+ EAcceptance* /*accept*/,
+ std::string& /*tooltip_msg*/)> drag_drop_handler_t;
+
+
+ /**
+ * Sets a handler which should process Drag-And-Drop.
+ */
+ void setDragAndDropHandler(drag_drop_handler_t handler) { mDragDropHandler = handler; }
+
+
+ /**
+ * Process Drag-And-Drop by delegating the event to drag_drop_handler_t.
+ *
+ * @return BOOL - value returned by drag_drop_handler_t if it is set, FALSE otherwise.
+ */
+ /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+
+private:
+ drag_drop_handler_t mDragDropHandler;
+};
+
+
+#endif // LL_LLDNDBUTTON_H
diff --git a/indra/newview/lldriverparam.cpp b/indra/newview/lldriverparam.cpp
index e7295512c1..45f4b4fbd0 100644
--- a/indra/newview/lldriverparam.cpp
+++ b/indra/newview/lldriverparam.cpp
@@ -156,13 +156,17 @@ void LLDriverParamInfo::toStream(std::ostream &out)
// LLDriverParam
//-----------------------------------------------------------------------------
-LLDriverParam::LLDriverParam(LLVOAvatar *avatarp)
- : mCurrentDistortionParam( NULL ), mAvatarp(avatarp), mWearablep(NULL)
+LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) :
+ mCurrentDistortionParam( NULL ),
+ mAvatarp(avatarp),
+ mWearablep(NULL)
{
}
-LLDriverParam::LLDriverParam(LLWearable *wearablep)
- : mCurrentDistortionParam( NULL ), mAvatarp(NULL), mWearablep(wearablep)
+LLDriverParam::LLDriverParam(LLWearable *wearablep) :
+ mCurrentDistortionParam( NULL ),
+ mAvatarp(NULL),
+ mWearablep(wearablep)
{
}
@@ -201,7 +205,7 @@ void LLDriverParam::setAvatar(LLVOAvatar *avatarp)
}
}
-/*virtual*/ LLViewerVisualParam * LLDriverParam::cloneParam(LLWearable* wearable) const
+/*virtual*/ LLViewerVisualParam* LLDriverParam::cloneParam(LLWearable* wearable) const
{
LLDriverParam *new_param;
if (wearable)
@@ -481,7 +485,7 @@ void LLDriverParam::stopAnimating(BOOL set_by_user)
}
/*virtual*/
-BOOL LLDriverParam::linkDrivenParams(visual_param_mapper mapper, bool only_cross_params)
+BOOL LLDriverParam::linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params)
{
BOOL success = TRUE;
LLDriverParamInfo::entry_info_list_t::iterator iter;
@@ -584,7 +588,8 @@ F32 LLDriverParam::getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight
void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool set_by_user)
{
LLVOAvatarSelf *avatar_self = gAgent.getAvatarObject();
- if(mWearablep && driven->mParam->getCrossWearable() &&
+ if(mWearablep &&
+ driven->mParam->getCrossWearable() &&
mWearablep->isOnTop())
{
// call setWeight through LLVOAvatarSelf so other wearables can be updated with the correct values
diff --git a/indra/newview/lldriverparam.h b/indra/newview/lldriverparam.h
index c73e740574..069e71a2cb 100644
--- a/indra/newview/lldriverparam.h
+++ b/indra/newview/lldriverparam.h
@@ -94,7 +94,7 @@ public:
void setWearable(LLWearable *wearablep);
void setAvatar(LLVOAvatar *avatarp);
- /*virtual*/ LLViewerVisualParam * cloneParam(LLWearable* wearable) const;
+ /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
// LLVisualParam Virtual functions
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
@@ -102,7 +102,7 @@ public:
/*virtual*/ void setWeight(F32 weight, BOOL set_by_user);
/*virtual*/ void setAnimationTarget( F32 target_value, BOOL set_by_user );
/*virtual*/ void stopAnimating(BOOL set_by_user);
- /*virtual*/ BOOL linkDrivenParams(visual_param_mapper mapper, bool only_cross_params);
+ /*virtual*/ BOOL linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params);
/*virtual*/ void resetDrivenParams();
// LLViewerVisualParam Virtual functions
diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp
index de079b7123..893b12ec35 100644
--- a/indra/newview/llfirstuse.cpp
+++ b/indra/newview/llfirstuse.cpp
@@ -272,6 +272,8 @@ void LLFirstUse::useMedia()
{
gWarningSettings.setBOOL("FirstMedia", FALSE);
- LLNotifications::instance().add("FirstMedia");
+ // Popup removed as a short-term fix for EXT-1643.
+ // Ultimately, the plan is to kill all First Use dialogs
+ //LLNotifications::instance().add("FirstMedia");
}
}
diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp
index db20b11efd..fc661772a6 100644
--- a/indra/newview/llfloatercamera.cpp
+++ b/indra/newview/llfloatercamera.cpp
@@ -125,9 +125,15 @@ void LLFloaterCamera::onOpen(const LLSD& key)
}
+void LLFloaterCamera::onClose(bool app_quitting)
+{
+ //We don't care of camera mode if app is quitting
+ if(!app_quitting)
+ switchMode(CAMERA_CTRL_MODE_ORBIT);
+}
LLFloaterCamera::LLFloaterCamera(const LLSD& val)
-: LLDockableFloater(NULL, val),
+: LLTransientDockableFloater(NULL, true, val),
mCurrMode(CAMERA_CTRL_MODE_ORBIT),
mPrevMode(CAMERA_CTRL_MODE_ORBIT)
{
@@ -286,7 +292,7 @@ void LLFloaterCamera::updateState()
//-------------LLFloaterCameraPresets------------------------
LLFloaterCameraPresets::LLFloaterCameraPresets(const LLSD& key):
-LLDockableFloater(NULL, key)
+LLTransientDockableFloater(NULL, true, key)
{}
BOOL LLFloaterCameraPresets::postBuild()
diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h
index 69df861a20..ba943e66ed 100644
--- a/indra/newview/llfloatercamera.h
+++ b/indra/newview/llfloatercamera.h
@@ -33,7 +33,7 @@
#ifndef LLFLOATERCAMERA_H
#define LLFLOATERCAMERA_H
-#include "lldockablefloater.h"
+#include "lltransientdockablefloater.h"
class LLJoystickCameraRotate;
class LLJoystickCameraZoom;
@@ -49,7 +49,7 @@ enum ECameraControlMode
};
class LLFloaterCamera
- : public LLDockableFloater
+ : public LLTransientDockableFloater
{
friend class LLFloaterReg;
@@ -69,6 +69,7 @@ public:
static void updateIfNotInAvatarViewMode();
virtual void onOpen(const LLSD& key);
+ virtual void onClose(bool app_quitting);
LLJoystickCameraRotate* mRotate;
LLJoystickCameraZoom* mZoom;
@@ -111,7 +112,7 @@ private:
};
-class LLFloaterCameraPresets : public LLDockableFloater
+class LLFloaterCameraPresets : public LLTransientDockableFloater
{
friend class LLFloaterReg;
public:
diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp
index a33a605f50..4596ae7739 100644
--- a/indra/newview/llfloaterinventory.cpp
+++ b/indra/newview/llfloaterinventory.cpp
@@ -1174,7 +1174,6 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p)
mHasInventoryConnection(false),
mStartFolderString(p.start_folder)
, mBuildDefaultHierarchy(true)
-, mRootInventoryItemUUID(LLUUID::null)
, mInvFVBridgeBuilder(NULL)
{
mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
@@ -1241,7 +1240,19 @@ BOOL LLInventoryPanel::postBuild()
// determine the root folder, if any, so inventory contents show just the children
// of that folder (i.e. not including the folder itself).
const LLAssetType::EType preferred_type = LLAssetType::lookupHumanReadable(mStartFolderString);
- mStartFolderID = (preferred_type != LLAssetType::AT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);
+
+ if ("inventory" == mStartFolderString)
+ {
+ mStartFolderID = gInventory.getRootFolderID();
+ }
+ else if ("library" == mStartFolderString)
+ {
+ mStartFolderID = gInventory.getLibraryRootFolderID();
+ }
+ else
+ {
+ mStartFolderID = (preferred_type != LLAssetType::AT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);
+ }
// build view of inventory if we need default full hierarchy and inventory ready, otherwise wait for modelChanged() callback
if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mHasInventoryConnection)
@@ -1462,24 +1473,6 @@ void LLInventoryPanel::modelChanged(U32 mask)
}
}
-void LLInventoryPanel::setInvFVBridgeBuilder(const LLInventoryFVBridgeBuilder* bridge_builder)
-{
- if (NULL == bridge_builder)
- {
- llwarns << "NULL is passed as Inventory Bridge Builder. Default will be used." << llendl;
- }
- else
- {
- mInvFVBridgeBuilder = bridge_builder;
- }
-
- if (mInventory->isInventoryUsable() && !mHasInventoryConnection)
- {
- rebuildViewsFor(mRootInventoryItemUUID);
- mHasInventoryConnection = true;
- }
-}
-
void LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
{
@@ -1508,14 +1501,28 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
objectp = gInventory.getObject(id);
if (objectp)
{
+ const LLUUID &parent_id = objectp->getParentUUID();
+ // If this item's parent is the starting folder, then just add it to the top level (recall that
+ // the starting folder isn't actually represented in the view, parent_folder would be NULL in
+ // this case otherwise).
+ LLFolderViewFolder* parent_folder = (parent_id == mStartFolderID ?
+ mFolders : (LLFolderViewFolder*)mFolders->getItemByID(parent_id));
+
+ // This item exists outside the inventory's hierarchy, so don't add it.
+ if (!parent_folder)
+ {
+ return;
+ }
+
if (objectp->getType() <= LLAssetType::AT_NONE ||
objectp->getType() >= LLAssetType::AT_COUNT)
{
- llwarns << "LLInventoryPanel::buildNewViews called with objectp->mType == "
- << ((S32) objectp->getType())
- << " (shouldn't happen)" << llendl;
+ llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : " <<
+ ((S32) objectp->getType()) << llendl;
+ return;
}
- else if (objectp->getType() == LLAssetType::AT_CATEGORY &&
+
+ if (objectp->getType() == LLAssetType::AT_CATEGORY &&
objectp->getActualType() != LLAssetType::AT_LINK_FOLDER)
{
LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(),
@@ -1563,27 +1570,7 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
if (itemp)
{
-
- const LLUUID &parent_id = objectp->getParentUUID();
- LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolders->getItemByID(parent_id);
-
- // If this item's parent is the starting folder, then just add it to the top level (recall that
- // the starting folder isn't actually represented in the view, parent_folder would be NULL in
- // this case otherwise).
- if (parent_id == mStartFolderID)
- {
- parent_folder = mFolders;
- }
-
- if (parent_folder)
- {
- itemp->addToFolder(parent_folder, mFolders);
- }
- else
- {
- llwarns << "Couldn't find parent folder for child " << itemp->getLabel() << llendl;
- delete itemp;
- }
+ itemp->addToFolder(parent_folder, mFolders);
}
}
}
diff --git a/indra/newview/llfloaterinventory.h b/indra/newview/llfloaterinventory.h
index 1666f18c05..4c9ac5d4c6 100644
--- a/indra/newview/llfloaterinventory.h
+++ b/indra/newview/llfloaterinventory.h
@@ -175,9 +175,6 @@ protected:
void rebuildViewsFor(const LLUUID& id);
virtual void buildNewViews(const LLUUID& id); // made virtual to support derived classes. EXT-719
- // Be sure that passed pointer will be destroyed where it was created.
- void setInvFVBridgeBuilder(const LLInventoryFVBridgeBuilder* bridge_builder);
-
protected:
LLInventoryModel* mInventory;
LLInventoryObserver* mInventoryObserver;
@@ -187,6 +184,12 @@ protected:
//private: // Can not make these private - needed by llinventorysubtreepanel
LLFolderView* mFolders;
std::string mStartFolderString;
+
+ /**
+ * Contains UUID of Inventory item from which hierarchy should be built.
+ * Can be set with the "start_folder" xml property.
+ * Default is LLUUID::null that means total Inventory hierarchy.
+ */
LLUUID mStartFolderID;
LLScrollContainer* mScroller;
bool mHasInventoryConnection;
@@ -196,11 +199,6 @@ protected:
*/
bool mBuildDefaultHierarchy;
- /**
- * Contains UUID of Inventory item from which hierarchy should be built.
- * Should be set by derived class before modelChanged() is called.
- * Default is LLUUID::null that means total Inventory hierarchy.
- */
LLUUID mRootInventoryItemUUID;
/**
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index de0b995f8f..ac743df4f1 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -553,32 +553,33 @@ void LLFloaterUIPreview::onLanguageComboSelect(LLUICtrl* ctrl)
void LLFloaterUIPreview::onClickExportSchema()
{
- gViewerWindow->setCursor(UI_CURSOR_WAIT);
- std::string template_path = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "xui", "schema");
-
- typedef LLWidgetTypeRegistry::Registrar::registry_map_t::const_iterator registry_it;
- registry_it end_it = LLWidgetTypeRegistry::defaultRegistrar().endItems();
- for(registry_it it = LLWidgetTypeRegistry::defaultRegistrar().beginItems();
- it != end_it;
- ++it)
- {
- std::string widget_name = it->first;
- const LLInitParam::BaseBlock& block =
- (*LLDefaultParamBlockRegistry::instance().getValue(*LLWidgetTypeRegistry::instance().getValue(widget_name)))();
- LLXMLNodePtr root_nodep = new LLXMLNode();
- LLRNGWriter().writeRNG(widget_name, root_nodep, block, "http://www.lindenlab.com/xui");
-
- std::string file_name(template_path + gDirUtilp->getDirDelimiter() + widget_name + ".rng");
-
- LLFILE* rng_file = LLFile::fopen(file_name.c_str(), "w");
- {
- LLXMLNode::writeHeaderToFile(rng_file);
- const bool use_type_decorations = false;
- root_nodep->writeToFile(rng_file, std::string(), use_type_decorations);
- }
- fclose(rng_file);
- }
- gViewerWindow->setCursor(UI_CURSOR_ARROW);
+ //NOTE: schema generation not complete
+ //gViewerWindow->setCursor(UI_CURSOR_WAIT);
+ //std::string template_path = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "xui", "schema");
+
+ //typedef LLWidgetTypeRegistry::Registrar::registry_map_t::const_iterator registry_it;
+ //registry_it end_it = LLWidgetTypeRegistry::defaultRegistrar().endItems();
+ //for(registry_it it = LLWidgetTypeRegistry::defaultRegistrar().beginItems();
+ // it != end_it;
+ // ++it)
+ //{
+ // std::string widget_name = it->first;
+ // const LLInitParam::BaseBlock& block =
+ // (*LLDefaultParamBlockRegistry::instance().getValue(*LLWidgetTypeRegistry::instance().getValue(widget_name)))();
+ // LLXMLNodePtr root_nodep = new LLXMLNode();
+ // LLRNGWriter().writeRNG(widget_name, root_nodep, block, "http://www.lindenlab.com/xui");
+
+ // std::string file_name(template_path + gDirUtilp->getDirDelimiter() + widget_name + ".rng");
+
+ // LLFILE* rng_file = LLFile::fopen(file_name.c_str(), "w");
+ // {
+ // LLXMLNode::writeHeaderToFile(rng_file);
+ // const bool use_type_decorations = false;
+ // root_nodep->writeToFile(rng_file, std::string(), use_type_decorations);
+ // }
+ // fclose(rng_file);
+ //}
+ //gViewerWindow->setCursor(UI_CURSOR_ARROW);
}
void LLFloaterUIPreview::onClickShowRectangles(const LLSD& data)
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 155262ee13..de18e74752 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -189,9 +189,9 @@ LLFolderView::LLFolderView(const Params& p)
mMinWidth(0),
mDragAndDropThisFrame(FALSE),
mCallbackRegistrar(NULL),
- mParentPanel(p.parent_panel)
-, mUseEllipses(false)
-, mDraggingOverItem(NULL)
+ mParentPanel(p.parent_panel),
+ mUseEllipses(false),
+ mDraggingOverItem(NULL)
{
LLRect rect = p.rect;
LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
@@ -1240,7 +1240,9 @@ BOOL LLFolderView::canCut() const
{
const LLFolderViewItem* item = *selected_it;
const LLFolderViewEventListener* listener = item->getListener();
- if (!listener || !listener->isItemMovable())
+
+ // *WARKAROUND: it is too many places where the "isItemRemovable" method should be changed with "const" modifier
+ if (!listener || !(const_cast<LLFolderViewEventListener*>(listener))->isItemRemovable())
{
return FALSE;
}
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 9208beec9e..f83a426cda 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -890,11 +890,11 @@ void LLFolderViewItem::draw()
llfloor(getRect().getHeight() - font->getLineHeight() - ICON_PAD),
sHighlightFgColor, FALSE);
}
- if (getRect().getHeight() > llround(font->getLineHeight()) + ICON_PAD + 2)
+ if (getRect().getHeight() > llround(font->getLineHeight()) + ICON_PAD + 4)
{
gl_rect_2d(
0,
- llfloor(getRect().getHeight() - font->getLineHeight() - ICON_PAD) - 2,
+ llfloor(getRect().getHeight() - font->getLineHeight() - ICON_PAD) - 4,
getRect().getWidth() - 2,
2,
sHighlightFgColor, FALSE);
@@ -902,7 +902,7 @@ void LLFolderViewItem::draw()
{
gl_rect_2d(
0,
- llfloor(getRect().getHeight() - font->getLineHeight() - ICON_PAD) - 2,
+ llfloor(getRect().getHeight() - font->getLineHeight() - ICON_PAD) - 4,
getRect().getWidth() - 2,
2,
sHighlightBgColor, TRUE);
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index 90c346b381..62a4b9a187 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -202,6 +202,7 @@ public:
virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
virtual S32 getItemHeight();
void setDontShowInHierarchy(bool dont_show) { mDontShowInHierarhy = dont_show; }
+ bool getDontShowInHierarchy() { return mDontShowInHierarhy; }
// applies filters to control visibility of inventory items
virtual void filter( LLInventoryFilter& filter);
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index 97b7f3e9ad..fbcaeee01f 100644
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -166,6 +166,93 @@ bool LLFriendCardsManager::isItemInAnyFriendsList(const LLViewerInventoryItem* i
return items.count() > 0;
}
+
+bool LLFriendCardsManager::isObjDirectDescendentOfCategory(const LLInventoryObject* obj,
+ const LLViewerInventoryCategory* cat) const
+{
+ // we need both params to proceed.
+ if ( !obj || !cat )
+ return false;
+
+ // Need to check that target category is in the Calling Card/Friends folder.
+ // In other case function returns unpredictable result.
+ if ( !isCategoryInFriendFolder(cat) )
+ return false;
+
+ bool result = false;
+
+ LLInventoryModel::item_array_t* items;
+ LLInventoryModel::cat_array_t* cats;
+
+ gInventory.lockDirectDescendentArrays(cat->getUUID(), cats, items);
+ if ( items )
+ {
+ if ( obj->getType() == LLAssetType::AT_CALLINGCARD )
+ {
+ // For CALLINGCARD compare items by creator's id, if they are equal assume
+ // that it is same card and return true. Note: UUID's of compared items
+ // may be not equal. Also, we already know that obj should be type of LLInventoryItem,
+ // but in case inventory database is broken check what dynamic_cast returns.
+ const LLInventoryItem* item = dynamic_cast < const LLInventoryItem* > (obj);
+ if ( item )
+ {
+ LLUUID creator_id = item->getCreatorUUID();
+ LLViewerInventoryItem* cur_item = NULL;
+ for ( S32 i = items->count() - 1; i >= 0; --i )
+ {
+ cur_item = items->get(i);
+ if ( creator_id == cur_item->getCreatorUUID() )
+ {
+ result = true;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ // Else check that items have same type and name.
+ // Note: UUID's of compared items also may be not equal.
+ std::string obj_name = obj->getName();
+ LLViewerInventoryItem* cur_item = NULL;
+ for ( S32 i = items->count() - 1; i >= 0; --i )
+ {
+ cur_item = items->get(i);
+ if ( obj->getType() != cur_item->getType() )
+ continue;
+ if ( obj_name == cur_item->getName() )
+ {
+ result = true;
+ break;
+ }
+ }
+ }
+ }
+ if ( !result && cats )
+ {
+ // There is no direct descendent in items, so check categories.
+ // If target obj and descendent category have same type and name
+ // then return true. Note: UUID's of compared items also may be not equal.
+ std::string obj_name = obj->getName();
+ LLViewerInventoryCategory* cur_cat = NULL;
+ for ( S32 i = cats->count() - 1; i >= 0; --i )
+ {
+ cur_cat = cats->get(i);
+ if ( obj->getType() != cur_cat->getType() )
+ continue;
+ if ( obj_name == cur_cat->getName() )
+ {
+ result = true;
+ break;
+ }
+ }
+ }
+ gInventory.unlockDirectDescendentArrays(cat->getUUID());
+
+ return result;
+}
+
+
bool LLFriendCardsManager::isCategoryInFriendFolder(const LLViewerInventoryCategory* cat) const
{
if (NULL == cat)
diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h
index aa391ce2c1..6ada342831 100644
--- a/indra/newview/llfriendcard.h
+++ b/indra/newview/llfriendcard.h
@@ -72,6 +72,12 @@ public:
bool isItemInAnyFriendsList(const LLViewerInventoryItem* item);
/**
+ * Checks if specified category is contained in the Calling Card/Friends folder and
+ * determines if specified Inventory Object exists in that category.
+ */
+ bool isObjDirectDescendentOfCategory(const LLInventoryObject* obj, const LLViewerInventoryCategory* cat) const;
+
+ /**
* Checks is the specified category is in the Calling Card/Friends folder
*/
bool isCategoryInFriendFolder(const LLViewerInventoryCategory* cat) const;
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index a35c04440b..8f0186ce24 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -55,7 +55,7 @@
LLIMFloater::LLIMFloater(const LLUUID& session_id)
- : LLDockableFloater(NULL, session_id),
+ : LLTransientDockableFloater(NULL, true, session_id),
mControlPanel(NULL),
mSessionID(session_id),
mLastMessageIndex(-1),
@@ -81,17 +81,22 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
}
}
+}
+
+void LLIMFloater::onFocusLost()
+{
+ LLIMModel::getInstance()->resetActiveSessionID();
+}
- LLTransientFloaterMgr::getInstance()->registerTransientFloater(this);
+void LLIMFloater::onFocusReceived()
+{
+ LLIMModel::getInstance()->setActiveSessionID(mSessionID);
}
// virtual
void LLIMFloater::onClose(bool app_quitting)
{
- LLIMModel::instance().sendLeaveSession(mSessionID, mOtherParticipantUUID);
-
- //*TODO - move to the IMModel::sendLeaveSession() for the integrity (IB)
- gIMMgr->removeSession(mSessionID);
+ gIMMgr->leaveSession(mSessionID);
}
/* static */
@@ -116,6 +121,23 @@ void LLIMFloater::newIMCallback(const LLSD& data){
}
}
+void LLIMFloater::onVisibilityChange(const LLSD& new_visibility)
+{
+ bool visible = new_visibility.asBoolean();
+
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+
+ if (visible && voice_channel &&
+ voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED)
+ {
+ LLFloaterReg::showInstance("voice_call", mSessionID);
+ }
+ else
+ {
+ LLFloaterReg::hideInstance("voice_call", mSessionID);
+ }
+}
+
void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata )
{
LLIMFloater* self = (LLIMFloater*) userdata;
@@ -163,7 +185,6 @@ void LLIMFloater::sendMsg()
LLIMFloater::~LLIMFloater()
{
- LLTransientFloaterMgr::getInstance()->unregisterTransientFloater(this);
}
//virtual
@@ -297,7 +318,7 @@ void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
(LLNotificationsUI::LLChannelManager::getInstance()->
findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
- LLDockableFloater::setDocked(docked, pop_on_undock);
+ LLTransientDockableFloater::setDocked(docked, pop_on_undock);
// update notification channel state
if(channel)
@@ -311,7 +332,7 @@ void LLIMFloater::setVisible(BOOL visible)
LLNotificationsUI::LLScreenChannel* channel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>
(LLNotificationsUI::LLChannelManager::getInstance()->
findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
- LLDockableFloater::setVisible(visible);
+ LLTransientDockableFloater::setVisible(visible);
// update notification channel state
if(channel)
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 9b519ee7e3..8fd0c7cde9 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -33,7 +33,7 @@
#ifndef LL_IMFLOATER_H
#define LL_IMFLOATER_H
-#include "lldockablefloater.h"
+#include "lltransientdockablefloater.h"
#include "lllogchat.h"
class LLLineEditor;
@@ -45,7 +45,7 @@ class LLViewerTextEditor;
* Individual IM window that appears at the bottom of the screen,
* optionally "docked" to the bottom tray.
*/
-class LLIMFloater : public LLDockableFloater
+class LLIMFloater : public LLTransientDockableFloater
{
public:
LLIMFloater(const LLUUID& session_id);
@@ -84,7 +84,12 @@ public:
// called when docked floater's position has been set by chiclet
void setPositioned(bool b) { mPositioned = b; };
+ void onVisibilityChange(const LLSD& new_visibility);
+
private:
+ // process focus events to set a currently active session
+ /* virtual */ void onFocusLost();
+ /* virtual */ void onFocusReceived();
static void onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata );
static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 0ff3bd24e9..163984f740 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -951,7 +951,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
mSentTypingState(TRUE),
mNumUnreadMessages(0),
mShowSpeakersOnConnect(TRUE),
- mAutoConnect(FALSE),
mTextIMPossible(TRUE),
mProfileButtonEnabled(TRUE),
mCallBackEnabled(TRUE),
@@ -1179,12 +1178,6 @@ void LLFloaterIMPanel::draw()
mInputEditor->setLabel(getString("default_text_label"));
}
- if (mAutoConnect && enable_connect)
- {
- onClickStartCall(this);
- mAutoConnect = FALSE;
- }
-
// show speakers window when voice first connects
if (mShowSpeakersOnConnect && voice_channel->isActive())
{
@@ -1525,7 +1518,7 @@ void LLFloaterIMPanel::onClickStartCall(void* userdata)
{
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
- LLIMModel::getInstance()->getVoiceChannel(self->mSessionUUID)->activate();
+ gIMMgr->startCall(self->mSessionUUID);
}
// static
@@ -1533,7 +1526,7 @@ void LLFloaterIMPanel::onClickEndCall(void* userdata)
{
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
- LLIMModel::getInstance()->getVoiceChannel(self->mSessionUUID)->deactivate();
+ gIMMgr->endCall(self->mSessionUUID);
}
// static
@@ -1593,9 +1586,7 @@ void LLFloaterIMPanel::onClose(bool app_quitting)
{
setTyping(FALSE);
- LLIMModel::instance().sendLeaveSession(mSessionUUID, mOtherParticipantUUID);
-
- gIMMgr->removeSession(mSessionUUID);
+ gIMMgr->leaveSession(mSessionUUID);
// *HACK hide the voice floater
LLFloaterReg::hideInstance("voice_call", mSessionUUID);
@@ -1712,11 +1703,6 @@ void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id)
}
}
-void LLFloaterIMPanel::requestAutoConnect()
-{
- mAutoConnect = TRUE;
-}
-
void LLFloaterIMPanel::setTyping(BOOL typing)
{
LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionUUID);
diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h
index 57379b2c0d..4e306c7fab 100644
--- a/indra/newview/llimpanel.h
+++ b/indra/newview/llimpanel.h
@@ -250,8 +250,6 @@ public:
EInstantMessage getDialogType() const { return mDialog; }
void setDialogType(EInstantMessage dialog) { mDialog = dialog; }
- void requestAutoConnect();
-
void sessionInitReplyReceived(const LLUUID& im_session_id);
// Handle other participant in the session typing.
@@ -336,8 +334,6 @@ private:
BOOL mShowSpeakersOnConnect;
- BOOL mAutoConnect;
-
BOOL mTextIMPossible;
BOOL mProfileButtonEnabled;
BOOL mCallBackEnabled;
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 619e7044b4..9486698c89 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -93,30 +93,45 @@ std::map<LLUUID, LLIMModel::LLIMSession*> LLIMModel::sSessionsMap;
void toast_callback(const LLSD& msg){
- // do not show toast in busy mode
- if (gAgent.getBusy())
+ // do not show toast in busy mode or it goes from agent
+ if (gAgent.getBusy() || gAgent.getID() == msg["from_id"])
{
return;
}
-
- //we send notifications to reset counter also
- if (msg["num_unread"].asInteger())
+
+ // check whether incoming IM belongs to an active session or not
+ if (LLIMModel::getInstance()->getActiveSessionID() == msg["session_id"])
{
- LLSD args;
- args["MESSAGE"] = msg["message"];
- args["TIME"] = msg["time"];
- args["FROM"] = msg["from"];
- args["FROM_ID"] = msg["from_id"];
- args["SESSION_ID"] = msg["session_id"];
+ return;
+ }
+
+ LLSD args;
+ args["MESSAGE"] = msg["message"];
+ args["TIME"] = msg["time"];
+ args["FROM"] = msg["from"];
+ args["FROM_ID"] = msg["from_id"];
+ args["SESSION_ID"] = msg["session_id"];
- LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::show, msg["session_id"].asUUID()));
+ LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::show, msg["session_id"].asUUID()));
+}
+
+void LLIMModel::setActiveSessionID(const LLUUID& session_id)
+{
+ // check if such an ID really exists
+ if (!findIMSession(session_id))
+ {
+ llwarns << "Trying to set as active a non-existent session!" << llendl;
+ return;
}
+
+ mActiveSessionID = session_id;
}
LLIMModel::LLIMModel()
{
- addChangedCallback(LLIMFloater::newIMCallback);
- addChangedCallback(toast_callback);
+ addNewMsgCallback(LLIMFloater::newIMCallback);
+ addNoUnreadMsgsCallback(LLIMFloater::newIMCallback);
+ addNewMsgCallback(toast_callback);
}
@@ -311,7 +326,7 @@ std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index)
LLSD arg;
arg["session_id"] = session_id;
arg["num_unread"] = 0;
- mChangedSignal(arg);
+ mNoUnreadMsgsSignal(arg);
// TODO: in the future is there a more efficient way to return these
//of course there is - return as parameter (IB)
@@ -390,7 +405,7 @@ bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id,
arg["from"] = from;
arg["from_id"] = from_id;
arg["time"] = LLLogChat::timestamp(false);
- mChangedSignal(arg);
+ mNewMsgSignal(arg);
return true;
}
@@ -620,14 +635,8 @@ void LLIMModel::sendMessage(const std::string& utf8_text,
}
// Add the recipient to the recent people list.
- //*TODO should be deleted, because speaker manager updates through callback the recent list
LLRecentPeople::instance().add(other_participant_id);
}
-
-boost::signals2::connection LLIMModel::addChangedCallback( boost::function<void (const LLSD& data)> cb )
-{
- return mChangedSignal.connect(cb);
-}
void session_starter_helper(
const LLUUID& temp_session_id,
@@ -854,23 +863,18 @@ public:
//in case of race conditions
speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(mSessionID));
}
-
- LLFloaterIMPanel* floaterp =
- gIMMgr->findFloaterBySession(mSessionID);
- if (floaterp)
+ if (LLIMMgr::INVITATION_TYPE_VOICE == mInvitiationType)
{
- if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE )
- {
- floaterp->requestAutoConnect();
- LLFloaterIMPanel::onClickStartCall(floaterp);
- // always open IM window when connecting to voice
- LLFloaterReg::showInstance("communicate", LLSD(), TRUE);
- }
- else if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE )
- {
- LLFloaterReg::showInstance("communicate", LLSD(), TRUE);
- }
+ gIMMgr->startCall(mSessionID);
+ }
+
+ if ((mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE
+ || mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE)
+ && LLIMModel::getInstance()->findIMSession(mSessionID))
+ {
+ // always open IM window when connecting to voice
+ LLIMFloater::show(mSessionID);
}
gIMMgr->clearPendingAgentListUpdates(mSessionID);
@@ -1041,20 +1045,13 @@ void LLIncomingCallDialog::processCallResponse(S32 response)
if (voice)
{
- LLFloaterIMPanel* im_floater =
- gIMMgr->findFloaterBySession(
- session_id);
-
- if (im_floater)
+ if (gIMMgr->startCall(session_id))
{
- im_floater->requestAutoConnect();
- LLFloaterIMPanel::onClickStartCall(im_floater);
+ // always open IM window when connecting to voice
+ LLIMFloater::show(session_id);
}
}
- // always open IM window when connecting to voice
- LLFloaterReg::showInstance("communicate", session_id);
-
gIMMgr->clearPendingAgentListUpdates(session_id);
gIMMgr->clearPendingInvitation(session_id);
}
@@ -1159,15 +1156,10 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
payload["session_handle"].asString(),
payload["session_uri"].asString());
- LLFloaterIMPanel* im_floater =
- gIMMgr->findFloaterBySession(
- session_id);
- if (im_floater)
+ if (gIMMgr->startCall(session_id))
{
- im_floater->requestAutoConnect();
- LLFloaterIMPanel::onClickStartCall(im_floater);
// always open IM window when connecting to voice
- LLFloaterReg::showInstance("communicate", session_id, TRUE);
+ LLIMFloater::show(session_id);
}
gIMMgr->clearPendingAgentListUpdates(session_id);
@@ -1291,13 +1283,6 @@ void LLIMMgr::addMessage(
return;
}
- //not sure why...but if it is from ourselves we set the target_id
- //to be NULL
- if( other_participant_id == gAgent.getID() )
- {
- other_participant_id = LLUUID::null;
- }
-
LLFloaterIMPanel* floater;
LLUUID new_session_id = session_id;
if (new_session_id.isNull())
@@ -1429,12 +1414,10 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
}
else // going to IM session
{
- LLFloaterIMPanel* floaterp = findFloaterBySession(session_id);
- if (floaterp)
+ if (hasSession(session_id))
{
- message = floaterp->getString(message_name);
+ message = LLTrans::getString(message_name + "-im");
message.setArgs(args);
-
gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString());
}
}
@@ -1566,6 +1549,16 @@ LLUUID LLIMMgr::addSession(
return session_id;
}
+bool LLIMMgr::leaveSession(const LLUUID& session_id)
+{
+ LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id);
+ if (!im_session) return false;
+
+ LLIMModel::getInstance()->sendLeaveSession(session_id, im_session->mOtherParticipantID);
+ gIMMgr->removeSession(session_id);
+ return true;
+}
+
// This removes the panel referenced by the uuid, and then restores
// internal consistency. The internal pointer is not deleted? Did you mean
// a pointer to the corresponding LLIMSession? Session data is cleared now.
@@ -1779,7 +1772,7 @@ LLFloaterIMPanel* LLIMMgr::findFloaterBySession(const LLUUID& session_id)
BOOL LLIMMgr::hasSession(const LLUUID& session_id)
{
- return (findFloaterBySession(session_id) != NULL);
+ return LLIMModel::getInstance()->findIMSession(session_id) != NULL;
}
void LLIMMgr::clearPendingInvitation(const LLUUID& session_id)
@@ -1905,6 +1898,24 @@ void LLIMMgr::removeSessionObserver(LLIMSessionObserver *observer)
mSessionObservers.remove(observer);
}
+bool LLIMMgr::startCall(const LLUUID& session_id)
+{
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id);
+ if (!voice_channel) return false;
+
+ voice_channel->activate();
+ return true;
+}
+
+bool LLIMMgr::endCall(const LLUUID& session_id)
+{
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id);
+ if (!voice_channel) return false;
+
+ voice_channel->deactivate();
+ return true;
+}
+
// create a floater and update internal representation for
// consistency. Returns the pointer, caller (the class instance since
// it is a private method) is not responsible for deleting the
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 84646a9a6f..f9db6d8ed2 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -75,10 +75,20 @@ public:
LLIMModel();
+
+ //we should control the currently active session
+ LLUUID mActiveSessionID;
+ void setActiveSessionID(const LLUUID& session_id);
+ void resetActiveSessionID() { mActiveSessionID.setNull(); }
+ LLUUID getActiveSessionID() { return mActiveSessionID; }
+
//*TODO make it non-static as LLIMMOdel is a singleton (IB)
static std::map<LLUUID, LLIMSession*> sSessionsMap; //mapping session_id to session
- boost::signals2::signal<void(const LLSD&)> mChangedSignal;
+ typedef boost::signals2::signal<void(const LLSD&)> session_signal_t;
+ typedef boost::function<void(const LLSD&)> session_callback_t;
+ session_signal_t mNewMsgSignal;
+ session_signal_t mNoUnreadMsgsSignal;
/**
* Find an IM Session corresponding to session_id
@@ -91,7 +101,8 @@ public:
*/
void updateSessionID(const LLUUID& old_session_id, const LLUUID& new_session_id);
- boost::signals2::connection addChangedCallback( boost::function<void (const LLSD& data)> cb );
+ boost::signals2::connection addNewMsgCallback( session_callback_t cb ) { return mNewMsgSignal.connect(cb); }
+ boost::signals2::connection addNoUnreadMsgsCallback( session_callback_t cb ) { return mNoUnreadMsgsSignal.connect(cb); }
bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id,
const std::vector<LLUUID>& ids = std::vector<LLUUID>());
@@ -219,10 +230,12 @@ public:
const std::string& voice_session_handle,
const std::string& caller_uri = LLStringUtil::null);
- // This removes the panel referenced by the uuid, and then
- // restores internal consistency. The internal pointer is not
- // deleted.
- void removeSession(LLUUID session_id);
+ /**
+ * Leave the session with session id. Send leave session notification
+ * to the server and removes all associated session data
+ * @return false if the session with specified id was not exist
+ */
+ bool leaveSession(const LLUUID& session_id);
void inviteToSession(
const LLUUID& session_id,
@@ -282,7 +295,24 @@ public:
void addSessionObserver(LLIMSessionObserver *);
void removeSessionObserver(LLIMSessionObserver *);
+ /**
+ * Start call in a session
+ * @return false if voice channel doesn't exist
+ **/
+ bool startCall(const LLUUID& session_id);
+
+ /**
+ * End call in a session
+ * @return false if voice channel doesn't exist
+ **/
+ bool endCall(const LLUUID& session_id);
+
private:
+ // This removes the panel referenced by the uuid, and then
+ // restores internal consistency. The internal pointer is not
+ // deleted.
+ void removeSession(LLUUID session_id);
+
// create a panel and update internal representation for
// consistency. Returns the pointer, caller (the class instance
// since it is a private method) is not responsible for deleting
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index db7d4f4c8f..d876647692 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1462,6 +1462,39 @@ BOOL LLFolderBridge::copyToClipboard() const
return FALSE;
}
+BOOL LLFolderBridge::isClipboardPasteable() const
+{
+ if ( ! LLInvFVBridge::isClipboardPasteable() )
+ return FALSE;
+
+ // Don't allow pasting duplicates to the Calling Card/Friends subfolders, see bug EXT-1599
+ if ( LLFriendCardsManager::instance().isCategoryInFriendFolder( getCategory() ) )
+ {
+ LLInventoryModel* model = getInventoryModel();
+ if ( !model )
+ {
+ return FALSE;
+ }
+
+ LLDynamicArray<LLUUID> objects;
+ LLInventoryClipboard::instance().retrieve(objects);
+ const LLViewerInventoryCategory *current_cat = getCategory();
+
+ // Search for the direct descendent of current Friends subfolder among all pasted items,
+ // and return false if is found.
+ for(S32 i = objects.count() - 1; i >= 0; --i)
+ {
+ const LLUUID &obj_id = objects.get(i);
+ if ( LLFriendCardsManager::instance().isObjDirectDescendentOfCategory(model->getObject(obj_id), current_cat) )
+ {
+ return FALSE;
+ }
+ }
+
+ }
+ return TRUE;
+}
+
BOOL LLFolderBridge::isClipboardPasteableAsLink() const
{
// Check normal paste-as-link permissions
@@ -1479,13 +1512,15 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const
const LLViewerInventoryCategory *current_cat = getCategory();
if (current_cat)
{
+ const BOOL is_in_friend_folder = LLFriendCardsManager::instance().isCategoryInFriendFolder( current_cat );
const LLUUID &current_cat_id = current_cat->getUUID();
LLDynamicArray<LLUUID> objects;
LLInventoryClipboard::instance().retrieve(objects);
S32 count = objects.count();
for(S32 i = 0; i < count; i++)
{
- const LLInventoryCategory *cat = model->getCategory(objects.get(i));
+ const LLUUID &obj_id = objects.get(i);
+ const LLInventoryCategory *cat = model->getCategory(obj_id);
if (cat)
{
const LLUUID &cat_id = cat->getUUID();
@@ -1496,6 +1531,17 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const
return FALSE;
}
}
+ // Don't allow pasting duplicates to the Calling Card/Friends subfolders, see bug EXT-1599
+ if ( is_in_friend_folder )
+ {
+ // If object is direct descendent of current Friends subfolder than return false.
+ // Note: We can't use 'const LLInventoryCategory *cat', because it may be null
+ // in case type of obj_id is LLInventoryItem.
+ if ( LLFriendCardsManager::instance().isObjDirectDescendentOfCategory(model->getObject(obj_id), current_cat) )
+ {
+ return FALSE;
+ }
+ }
}
}
return TRUE;
@@ -1547,6 +1593,12 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
// BAP - restrictions?
is_movable = true;
}
+
+ if (mUUID == gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE))
+ {
+ is_movable = FALSE; // It's generally movable but not into Favorites folder. EXT-1604
+ }
+
if( is_movable )
{
gInventory.collectDescendents( cat_id, descendent_categories, descendent_items, FALSE );
@@ -2813,6 +2865,17 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
break;
}
}
+
+ if ( is_movable )
+ {
+ // Don't allow creating duplicates in the Calling Card/Friends
+ // subfolders, see bug EXT-1599. Check is item direct descendent
+ // of target folder and forbid item's movement if it so.
+ // Note: isItemDirectDescendentOfCategory checks if
+ // passed category is in the Calling Card/Friends folder
+ is_movable = ! LLFriendCardsManager::instance()
+ .isObjDirectDescendentOfCategory (inv_item, getCategory());
+ }
LLUUID favorites_id = model->findCategoryUUIDForType(LLAssetType::AT_FAVORITE);
@@ -3755,12 +3818,14 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model
else if ("detach" == action)
{
LLInventoryItem* item = gInventory.getItem(mUUID);
- if( item )
+ // In case we clicked on a link, detach the base object instead of the link.
+ LLInventoryItem* base_item = gInventory.getItem(item->getLinkedUUID());
+ if(base_item)
{
gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
gMessageSystem->nextBlockFast(_PREHASH_ObjectData );
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_ItemID, item->getUUID() );
+ gMessageSystem->addUUIDFast(_PREHASH_ItemID, base_item->getUUID() );
gMessageSystem->sendReliable( gAgent.getRegion()->getHost() );
}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index d1d2c57f07..6b2a2d32de 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -315,6 +315,7 @@ public:
virtual BOOL isItemMovable() const ;
virtual BOOL isUpToDate() const;
virtual BOOL isItemCopyable() const;
+ virtual BOOL isClipboardPasteable() const;
virtual BOOL isClipboardPasteableAsLink() const;
virtual BOOL copyToClipboard() const;
diff --git a/indra/newview/lllocaltextureobject.cpp b/indra/newview/lllocaltextureobject.cpp
index 99c98ec16e..0bd3e42556 100644
--- a/indra/newview/lllocaltextureobject.cpp
+++ b/indra/newview/lllocaltextureobject.cpp
@@ -47,18 +47,18 @@ LLLocalTextureObject::LLLocalTextureObject() :
mImage = NULL;
}
-LLLocalTextureObject::LLLocalTextureObject(LLViewerFetchedTexture *image, LLUUID id)
+LLLocalTextureObject::LLLocalTextureObject(LLViewerFetchedTexture* image, LLUUID& id)
{
mImage = image;
gGL.getTexUnit(0)->bind(mImage);
mID = id;
}
-LLLocalTextureObject::LLLocalTextureObject(const LLLocalTextureObject &lto) :
-mImage(lto.mImage),
-mID(lto.mID),
-mIsBakedReady(lto.mIsBakedReady),
-mDiscard(lto.mDiscard)
+LLLocalTextureObject::LLLocalTextureObject(const LLLocalTextureObject& lto) :
+ mImage(lto.mImage),
+ mID(lto.mID),
+ mIsBakedReady(lto.mIsBakedReady),
+ mDiscard(lto.mDiscard)
{
U32 num_layers = lto.getNumTexLayers();
mTexLayers.reserve(num_layers);
@@ -97,7 +97,7 @@ LLTexLayer* LLLocalTextureObject::getTexLayer(U32 index) const
LLTexLayer* LLLocalTextureObject::getTexLayer(const std::string &name)
{
- for( tex_layer_p::iterator iter = mTexLayers.begin(); iter != mTexLayers.end(); iter++)
+ for( tex_layer_vec_t::iterator iter = mTexLayers.begin(); iter != mTexLayers.end(); iter++)
{
LLTexLayer *layer = *iter;
if (layer->getName().compare(name) == 0)
@@ -190,7 +190,7 @@ BOOL LLLocalTextureObject::removeTexLayer(U32 index)
{
return FALSE;
}
- tex_layer_p::iterator iter = mTexLayers.begin();
+ tex_layer_vec_t::iterator iter = mTexLayers.begin();
iter += index;
delete *iter;
diff --git a/indra/newview/lllocaltextureobject.h b/indra/newview/lllocaltextureobject.h
index 138bbad677..461756ee46 100644
--- a/indra/newview/lllocaltextureobject.h
+++ b/indra/newview/lllocaltextureobject.h
@@ -49,8 +49,8 @@ class LLLocalTextureObject
{
public:
LLLocalTextureObject();
- LLLocalTextureObject(LLViewerFetchedTexture *image, LLUUID id);
- LLLocalTextureObject(const LLLocalTextureObject &lto);
+ LLLocalTextureObject(LLViewerFetchedTexture* image, LLUUID& id);
+ LLLocalTextureObject(const LLLocalTextureObject& lto);
~LLLocalTextureObject();
LLViewerFetchedTexture* getImage() const;
@@ -79,8 +79,8 @@ private:
// NOTE: LLLocalTextureObject should be the exclusive owner of mTexEntry and mTexLayer
// using shared pointers here only for smart assignment & cleanup
// do NOT create new shared pointers to these objects, or keep pointers to them around
- typedef std::vector<LLTexLayer*> tex_layer_p;
- tex_layer_p mTexLayers;
+ typedef std::vector<LLTexLayer*> tex_layer_vec_t;
+ tex_layer_vec_t mTexLayers;
LLUUID mID;
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 42838b311b..00f12ae2eb 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -264,6 +264,8 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
mAddLandmarkTooltip = LLTrans::getString("LocationCtrlAddLandmarkTooltip");
mEditLandmarkTooltip = LLTrans::getString("LocationCtrlEditLandmarkTooltip");
+ getChild<LLView>("Location History")->setToolTip(LLTrans::getString("LocationCtrlComboBtnTooltip"));
+ getChild<LLView>("Place Information")->setToolTip(LLTrans::getString("LocationCtrlInfoBtnTooltip"));
}
LLLocationInputCtrl::~LLLocationInputCtrl()
diff --git a/indra/newview/llmimetypes.cpp b/indra/newview/llmimetypes.cpp
index 525e89cdff..235487cf46 100644
--- a/indra/newview/llmimetypes.cpp
+++ b/indra/newview/llmimetypes.cpp
@@ -34,6 +34,7 @@
#include "llviewerprecompiledheaders.h"
#include "llmimetypes.h"
+#include "llxmlnode.h"
#include "lluictrlfactory.h"
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 1bbcc3f98e..4fc552c8b1 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -70,7 +70,7 @@ const std::string BOTTOM_TRAY_BUTTON_NAME = "movement_btn";
// protected
LLFloaterMove::LLFloaterMove(const LLSD& key)
-: LLDockableFloater(NULL, key),
+: LLTransientDockableFloater(NULL, true, key),
mForwardButton(NULL),
mBackwardButton(NULL),
mTurnLeftButton(NULL),
@@ -499,6 +499,8 @@ void LLFloaterMove::setDocked(bool docked, bool pop_on_undock/* = true*/)
LLDockableFloater::setDocked(docked, pop_on_undock);
bool show_mode_buttons = isDocked() || !gAgent.getFlying();
updateHeight(show_mode_buttons);
+
+ LLTransientDockableFloater::setDocked(docked, pop_on_undock);
}
void LLFloaterMove::setModeButtonToggleState(const EMovementMode mode)
diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h
index cbed36f10d..cee6078ee9 100644
--- a/indra/newview/llmoveview.h
+++ b/indra/newview/llmoveview.h
@@ -34,7 +34,7 @@
#define LL_LLMOVEVIEW_H
// Library includes
-#include "lldockablefloater.h"
+#include "lltransientdockablefloater.h"
class LLButton;
class LLJoystickAgentTurn;
@@ -44,7 +44,7 @@ class LLJoystickAgentSlide;
// Classes
//
class LLFloaterMove
-: public LLDockableFloater
+: public LLTransientDockableFloater
{
friend class LLFloaterReg;
diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h
index dec8d7576e..409b637bf2 100644
--- a/indra/newview/llmutelist.h
+++ b/indra/newview/llmutelist.h
@@ -153,7 +153,13 @@ private:
{
bool operator()(const LLMute& a, const LLMute& b) const
{
- return a.mName < b.mName;
+ std::string name1 = a.mName;
+ std::string name2 = b.mName;
+
+ LLStringUtil::toUpper(name1);
+ LLStringUtil::toUpper(name2);
+
+ return name1 < name2;
}
};
struct compare_by_id
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 7160cce5cb..6e90d22d89 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -54,17 +54,15 @@
#include "llstylemap.h"
#include "lldraghandle.h"
-
+#include "lltrans.h"
static const S32 RESIZE_BAR_THICKNESS = 3;
LLNearbyChat::LLNearbyChat(const LLSD& key) :
- LLFloater(key),
- mEChatTearofState(CHAT_PINNED),
- mChatCaptionPanel(NULL),
- mChatHistory(NULL)
+ LLFloater(key)
+ ,mChatHistory(NULL)
{
- m_isDirty = false;
+
}
LLNearbyChat::~LLNearbyChat()
@@ -73,25 +71,6 @@ LLNearbyChat::~LLNearbyChat()
BOOL LLNearbyChat::postBuild()
{
- //resize bars
- setCanResize(true);
-
- mResizeBar[LLResizeBar::BOTTOM]->setVisible(false);
- mResizeBar[LLResizeBar::LEFT]->setVisible(false);
- mResizeBar[LLResizeBar::RIGHT]->setVisible(false);
-
- mResizeBar[LLResizeBar::BOTTOM]->setResizeLimits(120,500);
- mResizeBar[LLResizeBar::TOP]->setResizeLimits(120,500);
- mResizeBar[LLResizeBar::LEFT]->setResizeLimits(220,600);
- mResizeBar[LLResizeBar::RIGHT]->setResizeLimits(220,600);
-
- mResizeHandle[0]->setVisible(false);
- mResizeHandle[1]->setVisible(false);
- mResizeHandle[2]->setVisible(false);
- mResizeHandle[3]->setVisible(false);
-
- getDragHandle()->setVisible(false);
-
//menu
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
@@ -101,17 +80,15 @@ BOOL LLNearbyChat::postBuild()
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-
if(menu)
mPopupMenuHandle = menu->getHandle();
gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true);
- mChatCaptionPanel = getChild<LLPanel>("chat_caption", false);
mChatHistory = getChild<LLChatHistory>("chat_history");
- reshape(getRect().getWidth(), getRect().getHeight(), FALSE);
-
+ setCanResize(true);
+
return LLFloater::postBuild();
}
@@ -181,6 +158,22 @@ LLColor4 nearbychat_get_text_color(const LLChat& chat)
return text_color;
}
+std::string formatCurrentTime()
+{
+ time_t utc_time;
+ utc_time = time_corrected();
+ std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
+ +LLTrans::getString("TimeMin")+"] ";
+
+ LLSD substitution;
+
+ substitution["datetime"] = (S32) utc_time;
+ LLStringUtil::format (timeStr, substitution);
+
+ return timeStr;
+}
+
+
void LLNearbyChat::add_timestamped_line(const LLChat& chat, const LLColor4& color)
{
S32 font_size = gSavedSettings.getS32("ChatFontSize");
@@ -205,7 +198,7 @@ void LLNearbyChat::add_timestamped_line(const LLChat& chat, const LLColor4& colo
style_params.font(fontp);
LLUUID uuid = chat.mFromID;
std::string from = chat.mFromName;
- std::string time = "";
+ std::string time = formatCurrentTime();
std::string message = chat.mText;
mChatHistory->appendWidgetMessage(uuid, from, time, message, style_params);
}
@@ -239,193 +232,6 @@ void LLNearbyChat::onNearbySpeakers()
LLSideTray::getInstance()->showPanel("panel_people",param);
}
-void LLNearbyChat::onTearOff()
-{
- if(mEChatTearofState == CHAT_PINNED)
- float_panel();
- else
- pinn_panel();
-}
-
-void LLNearbyChat::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
-
- LLFloater::reshape(width, height, called_from_parent);
-
- LLRect resize_rect;
- resize_rect.setLeftTopAndSize( 0, height, width, RESIZE_BAR_THICKNESS);
- if (mResizeBar[LLResizeBar::TOP])
- {
- mResizeBar[LLResizeBar::TOP]->reshape(width,RESIZE_BAR_THICKNESS);
- mResizeBar[LLResizeBar::TOP]->setRect(resize_rect);
- }
-
- resize_rect.setLeftTopAndSize( 0, RESIZE_BAR_THICKNESS, width, RESIZE_BAR_THICKNESS);
- if (mResizeBar[LLResizeBar::BOTTOM])
- {
- mResizeBar[LLResizeBar::BOTTOM]->reshape(width,RESIZE_BAR_THICKNESS);
- mResizeBar[LLResizeBar::BOTTOM]->setRect(resize_rect);
- }
-
- resize_rect.setLeftTopAndSize( 0, height, RESIZE_BAR_THICKNESS, height);
- if (mResizeBar[LLResizeBar::LEFT])
- {
- mResizeBar[LLResizeBar::LEFT]->reshape(RESIZE_BAR_THICKNESS,height);
- mResizeBar[LLResizeBar::LEFT]->setRect(resize_rect);
- }
-
- resize_rect.setLeftTopAndSize( width - RESIZE_BAR_THICKNESS, height, RESIZE_BAR_THICKNESS, height);
- if (mResizeBar[LLResizeBar::RIGHT])
- {
- mResizeBar[LLResizeBar::RIGHT]->reshape(RESIZE_BAR_THICKNESS,height);
- mResizeBar[LLResizeBar::RIGHT]->setRect(resize_rect);
- }
-
- // *NOTE: we must check mChatCaptionPanel and mChatHistory against NULL because reshape is called from the
- // LLView::initFromParams BEFORE postBuild is called and child controls are not exist yet
- LLRect caption_rect;
- if (NULL != mChatCaptionPanel)
- {
- caption_rect = mChatCaptionPanel->getRect();
- caption_rect.setLeftTopAndSize( 2, height - RESIZE_BAR_THICKNESS, width - 4, caption_rect.getHeight());
- mChatCaptionPanel->reshape( width - 4, caption_rect.getHeight(), 1);
- mChatCaptionPanel->setRect(caption_rect);
- }
-
- if (NULL != mChatHistory)
- {
- LLRect scroll_rect = mChatHistory->getRect();
- scroll_rect.setLeftTopAndSize( 2, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS, width - 4, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS*2);
- mChatHistory->reshape( width - 4, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS*2, 1);
- mChatHistory->setRect(scroll_rect);
- }
-
- //
- if(mEChatTearofState == CHAT_PINNED)
- {
- const LLRect& parent_rect = gViewerWindow->getRootView()->getRect();
-
- LLRect panel_rect;
- panel_rect.setLeftTopAndSize( parent_rect.mLeft+2, parent_rect.mBottom+height+4, width, height);
- setRect(panel_rect);
- }
- else
- {
- LLRect panel_rect;
- panel_rect.setLeftTopAndSize( getRect().mLeft, getRect().mTop, width, height);
- setRect(panel_rect);
- }
-
-}
-
-BOOL LLNearbyChat::handleMouseDown (S32 x, S32 y, MASK mask)
-{
- LLUICtrl* nearby_speakers_btn = mChatCaptionPanel->getChild<LLUICtrl>("nearby_speakers_btn");
- LLUICtrl* tearoff_btn = mChatCaptionPanel->getChild<LLUICtrl>("tearoff_btn");
- LLUICtrl* close_btn = mChatCaptionPanel->getChild<LLUICtrl>("close_btn");
-
- S32 caption_local_x = x - mChatCaptionPanel->getRect().mLeft;
- S32 caption_local_y = y - mChatCaptionPanel->getRect().mBottom;
-
- S32 local_x = caption_local_x - nearby_speakers_btn->getRect().mLeft;
- S32 local_y = caption_local_y - nearby_speakers_btn->getRect().mBottom;
- if(nearby_speakers_btn->pointInView(local_x, local_y))
- {
-
- onNearbySpeakers();
- bringToFront( x, y );
- return true;
- }
- local_x = caption_local_x - tearoff_btn->getRect().mLeft;
- local_y = caption_local_y- tearoff_btn->getRect().mBottom;
- if(tearoff_btn->pointInView(local_x, local_y))
- {
- onTearOff();
- bringToFront( x, y );
- return true;
- }
-
- local_x = caption_local_x - close_btn->getRect().mLeft;
- local_y = caption_local_y - close_btn->getRect().mBottom;
- if(close_btn->pointInView(local_x, local_y))
- {
- setVisible(false);
- bringToFront( x, y );
- return true;
- }
-
- if(mEChatTearofState == CHAT_UNPINNED && mChatCaptionPanel->pointInView(caption_local_x, caption_local_y) )
- {
- //start draggind
- gFocusMgr.setMouseCapture(this);
- mStart_Y = y;
- mStart_X = x;
- bringToFront( x, y );
- return true;
- }
-
- return LLFloater::handleMouseDown(x,y,mask);
-}
-
-BOOL LLNearbyChat::handleMouseUp(S32 x, S32 y, MASK mask)
-{
- if( hasMouseCapture() )
- {
- // Release the mouse
- gFocusMgr.setMouseCapture( NULL );
- mStart_X = 0;
- mStart_Y = 0;
- return true;
- }
-
- return LLFloater::handleMouseUp(x,y,mask);
-}
-
-BOOL LLNearbyChat::handleHover(S32 x, S32 y, MASK mask)
-{
- if( hasMouseCapture() )
- {
- translate(x-mStart_X,y-mStart_Y);
- return true;
- }
- return LLFloater::handleHover(x,y,mask);
-}
-
-void LLNearbyChat::pinn_panel()
-{
- mEChatTearofState = CHAT_PINNED;
- LLIconCtrl* tearoff_btn = mChatCaptionPanel->getChild<LLIconCtrl>("tearoff_btn",false);
-
- tearoff_btn->setValue("Inv_Landmark");
-
- const LLRect& parent_rect = gViewerWindow->getRootView()->getRect();
-
- LLRect panel_rect;
- panel_rect.setLeftTopAndSize( parent_rect.mLeft+2, parent_rect.mBottom+getRect().getHeight()+4, getRect().getWidth(), getRect().getHeight());
- setRect(panel_rect);
-
- mResizeBar[LLResizeBar::BOTTOM]->setVisible(false);
- mResizeBar[LLResizeBar::LEFT]->setVisible(false);
- mResizeBar[LLResizeBar::RIGHT]->setVisible(false);
-
- getDragHandle()->setVisible(false);
-
-}
-
-void LLNearbyChat::float_panel()
-{
- mEChatTearofState = CHAT_UNPINNED;
- LLIconCtrl* tearoff_btn = mChatCaptionPanel->getChild<LLIconCtrl>("tearoff_btn", false);
-
- tearoff_btn->setValue("Inv_Landmark");
- mResizeBar[LLResizeBar::BOTTOM]->setVisible(true);
- mResizeBar[LLResizeBar::LEFT]->setVisible(true);
- mResizeBar[LLResizeBar::RIGHT]->setVisible(true);
-
- getDragHandle()->setVisible(true);
-
- translate(4,4);
-}
void LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata)
{
@@ -438,23 +244,6 @@ bool LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)
return false;
}
-BOOL LLNearbyChat::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
- if(mChatCaptionPanel->pointInView(x - mChatCaptionPanel->getRect().mLeft, y - mChatCaptionPanel->getRect().mBottom) )
- {
- LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
-
- if(menu)
- {
- menu->buildDrawLabels();
- menu->updateParent(LLMenuGL::sMenuContainer);
- LLMenuGL::showPopup(this, menu, x, y);
- }
- return true;
- }
- return LLFloater::handleRightMouseDown(x, y, mask);
-}
-
void LLNearbyChat::onOpen(const LLSD& key )
{
LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
@@ -464,9 +253,15 @@ void LLNearbyChat::onOpen(const LLSD& key )
}
}
-void LLNearbyChat::draw ()
+void LLNearbyChat::setDocked (bool docked, bool pop_on_undock)
{
- LLFloater::draw();
-}
+ LLFloater::setDocked(docked, pop_on_undock);
+ if(docked)
+ {
+ //move nearby_chat to right bottom
+ LLRect rect = gFloaterView->getRect();
+ setRect(LLRect(rect.mLeft,getRect().getHeight(),rect.mLeft+getRect().getWidth(),0));
+ }
+}
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 47cae8ed0d..63e780c4bf 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -43,55 +43,27 @@ class LLChatHistory;
class LLNearbyChat: public LLFloater
{
public:
- // enumerations used by the chat system
- typedef enum e_chat_tearof_state
- {
- CHAT_PINNED = 0,
- CHAT_UNPINNED = 1,
- } EChatTearofState;
-
- enum { RESIZE_BAR_COUNT=4 };
-
LLNearbyChat(const LLSD& key);
~LLNearbyChat();
BOOL postBuild ();
- void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE);
-
- BOOL handleMouseDown (S32 x, S32 y, MASK mask);
- BOOL handleMouseUp (S32 x, S32 y, MASK mask);
- BOOL handleHover (S32 x, S32 y, MASK mask);
-
- BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
-
void addMessage (const LLChat& message);
- void onNearbySpeakers ();
- void onTearOff();
-
void onNearbyChatContextMenuItemClicked(const LLSD& userdata);
bool onNearbyChatCheckContextMenuItem(const LLSD& userdata);
- /*virtual*/ void onOpen (const LLSD& key);
+ void setDocked (bool docked, bool pop_on_undock);
- /*virtual*/ void draw ();
+ /*virtual*/ void onOpen (const LLSD& key);
private:
+ void onNearbySpeakers ();
void add_timestamped_line(const LLChat& chat, const LLColor4& color);
- void pinn_panel();
- void float_panel();
private:
- EChatTearofState mEChatTearofState;
- S32 mStart_X;
- S32 mStart_Y;
-
LLHandle<LLView> mPopupMenuHandle;
- LLPanel* mChatCaptionPanel;
LLChatHistory* mChatHistory;
-
- bool m_isDirty;
};
#endif
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index 59b19b6dcb..4aefbd1a33 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -225,7 +225,7 @@ void LLNearbyChatScreenChannel::showToastsBottom()
LLRect toast_rect;
S32 bottom = getRect().mBottom;
- S32 margin = gSavedSettings.getS32("ToastMargin");
+ S32 margin = gSavedSettings.getS32("ToastGap");
for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
{
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index c08f92b983..7239f49b7f 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -91,6 +91,7 @@ bool LLTipHandler::processNotification(const LLSD& notify)
LLToast::Params p;
p.notif_id = notification->getID();
p.notification = notification;
+ p.lifetime_secs = gSavedSettings.getS32("NotificationTipToastLifeTime");
p.panel = notify_box;
p.is_tip = true;
p.can_be_stored = false;
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 7670a5120c..1a2ef8e1bb 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -336,10 +336,10 @@ BOOL LLPanelAvatarProfile::postBuild()
childSetCommitCallback("share",(boost::bind(&LLPanelAvatarProfile::onShareButtonClick,this)),NULL);
LLTextureCtrl* pic = getChild<LLTextureCtrl>("2nd_life_pic");
- pic->setFallbackImageName("default_land_picture.j2c");
+ pic->setFallbackImageName("default_profile_picture.j2c");
pic = getChild<LLTextureCtrl>("real_world_pic");
- pic->setFallbackImageName("default_land_picture.j2c");
+ pic->setFallbackImageName("default_profile_picture.j2c");
resetControls();
resetData();
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index c2c32527fb..e2057bbbd7 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -601,15 +601,14 @@ LLPanel* LLPanelEditWearable::getPanel(EWearableType type)
void LLPanelEditWearable::getSortedParams(value_map_t &sorted_params, const std::string &edit_group)
{
- LLWearable::visualParamCluster_t param_list;
+ LLWearable::visual_param_vec_t param_list;
ESex avatar_sex = gAgent.getAvatarObject()->getSex();
mWearablePtr->getVisualParams(param_list);
- LLWearable::visualParamCluster_t::iterator iter = param_list.begin();
- LLWearable::visualParamCluster_t::iterator end = param_list.end();
-
- for (; iter != end; ++iter)
+ for (LLWearable::visual_param_vec_t::iterator iter = param_list.begin();
+ iter != param_list.end();
+ ++iter)
{
LLViewerVisualParam *param = (LLViewerVisualParam*) *iter;
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 521e145816..d81cbb3e5d 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -40,7 +40,9 @@
#include "llaccordionctrltab.h"
#include "llagent.h"
+#include "llagentpicksinfo.h"
#include "llagentui.h"
+#include "lldndbutton.h"
#include "llfloaterworldmap.h"
#include "llfolderviewitem.h"
#include "llinventorysubtreepanel.h"
@@ -58,7 +60,6 @@ static const std::string ADD_LANDMARK_BUTTON_NAME = "add_landmark_btn";
static const std::string ADD_FOLDER_BUTTON_NAME = "add_folder_btn";
static const std::string TRASH_BUTTON_NAME = "trash_btn";
-static const LLPlacesInventoryBridgeBuilder PLACES_INVENTORY_BUILDER;
// helper functions
static void filter_list(LLInventorySubTreePanel* inventory_list, const std::string& string);
@@ -214,6 +215,17 @@ bool LLLandmarksPanel::isLandmarkSelected() const
return false;
}
+bool LLLandmarksPanel::isReceivedFolderSelected() const
+{
+ // Received Folder can be only in Landmarks accordion
+ if (mCurrentSelectedList != mLandmarksInventoryPanel) return false;
+
+ // *TODO: it should be filled with logic when EXT-976 is done.
+
+ llwarns << "Not implemented yet until EXT-976 is done." << llendl;
+
+ return false;
+}
LLLandmark* LLLandmarksPanel::getCurSelectedLandmark() const
{
@@ -317,9 +329,7 @@ void LLLandmarksPanel::initFavoritesInventroyPanel()
{
mFavoritesInventoryPanel = getChild<LLInventorySubTreePanel>("favorites_list");
- LLUUID start_folder_id = mFavoritesInventoryPanel->getModel()->findCategoryUUIDForType(LLAssetType::AT_FAVORITE);
-
- initLandmarksPanel(mFavoritesInventoryPanel, start_folder_id);
+ initLandmarksPanel(mFavoritesInventoryPanel);
initAccordion("tab_favorites", mFavoritesInventoryPanel);
}
@@ -328,9 +338,8 @@ void LLLandmarksPanel::initLandmarksInventroyPanel()
{
mLandmarksInventoryPanel = getChild<LLInventorySubTreePanel>("landmarks_list");
- LLUUID start_folder_id = mLandmarksInventoryPanel->getModel()->findCategoryUUIDForType(LLAssetType::AT_LANDMARK);
+ initLandmarksPanel(mLandmarksInventoryPanel);
- initLandmarksPanel(mLandmarksInventoryPanel, start_folder_id);
mLandmarksInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
// subscribe to have auto-rename functionality while creating New Folder
@@ -343,9 +352,7 @@ void LLLandmarksPanel::initMyInventroyPanel()
{
mMyInventoryPanel= getChild<LLInventorySubTreePanel>("my_inventory_list");
- LLUUID start_folder_id = mMyInventoryPanel->getModel()->getRootFolderID();
-
- initLandmarksPanel(mMyInventoryPanel, start_folder_id);
+ initLandmarksPanel(mMyInventoryPanel);
initAccordion("tab_inventory", mMyInventoryPanel);
}
@@ -354,18 +361,13 @@ void LLLandmarksPanel::initLibraryInventroyPanel()
{
mLibraryInventoryPanel = getChild<LLInventorySubTreePanel>("library_list");
- LLUUID start_folder_id = mLibraryInventoryPanel->getModel()->getLibraryRootFolderID();
-
- initLandmarksPanel(mLibraryInventoryPanel, start_folder_id);
+ initLandmarksPanel(mLibraryInventoryPanel);
initAccordion("tab_library", mLibraryInventoryPanel);
}
-
-void LLLandmarksPanel::initLandmarksPanel(LLInventorySubTreePanel* inventory_list, const LLUUID& start_folder_id)
+void LLLandmarksPanel::initLandmarksPanel(LLInventorySubTreePanel* inventory_list)
{
- inventory_list->buildSubtreeViewsFor(start_folder_id, &PLACES_INVENTORY_BUILDER);
-
inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK);
inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2));
@@ -378,6 +380,10 @@ void LLLandmarksPanel::initLandmarksPanel(LLInventorySubTreePanel* inventory_lis
root_folder->setupMenuHandle(LLInventoryType::IT_CATEGORY, mGearFolderMenu->getHandle());
root_folder->setupMenuHandle(LLInventoryType::IT_LANDMARK, mGearLandmarkMenu->getHandle());
}
+
+ // save initial folder state to avoid incorrect work while switching between Landmarks & Teleport History tabs
+ // See EXT-1609.
+ inventory_list->saveFolderState();
}
void LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLInventorySubTreePanel* inventory_list)
@@ -432,8 +438,15 @@ void LLLandmarksPanel::initListCommandsHandlers()
mListCommands->childSetAction(TRASH_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onTrashButtonClick, this));
+ LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>(TRASH_BUTTON_NAME);
+ trash_btn->setDragAndDropHandler(boost::bind(&LLLandmarksPanel::handleDragAndDropToTrash, this
+ , _4 // BOOL drop
+ , _5 // EDragAndDropType cargo_type
+ , _7 // EAcceptance* accept
+ ));
+
mCommitCallbackRegistrar.add("Places.LandmarksGear.Add.Action", boost::bind(&LLLandmarksPanel::onAddAction, this, _2));
- mCommitCallbackRegistrar.add("Places.LandmarksGear.CopyPaste.Action", boost::bind(&LLLandmarksPanel::onCopyPasteAction, this, _2));
+ mCommitCallbackRegistrar.add("Places.LandmarksGear.CopyPaste.Action", boost::bind(&LLLandmarksPanel::onClipboardAction, this, _2));
mCommitCallbackRegistrar.add("Places.LandmarksGear.Custom.Action", boost::bind(&LLLandmarksPanel::onCustomAction, this, _2));
mCommitCallbackRegistrar.add("Places.LandmarksGear.Folding.Action", boost::bind(&LLLandmarksPanel::onFoldingAction, this, _2));
mEnableCallbackRegistrar.add("Places.LandmarksGear.Enable", boost::bind(&LLLandmarksPanel::isActionEnabled, this, _2));
@@ -444,20 +457,8 @@ void LLLandmarksPanel::initListCommandsHandlers()
void LLLandmarksPanel::updateListCommands()
{
- // TODO: should be false when "Received" folder is selected
- bool add_folder_enabled = mCurrentSelectedList == mLandmarksInventoryPanel;
- bool trash_enabled = false; // TODO: should be false when "Received" folder is selected
-
- LLFolderViewItem* current_item = getCurSelectedItem();
-
- if (current_item)
- {
- LLFolderViewEventListener* listenerp = current_item->getListener();
- if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
- {
- trash_enabled = mCurrentSelectedList != mLibraryInventoryPanel;
- }
- }
+ bool add_folder_enabled = isActionEnabled("category");
+ bool trash_enabled = isActionEnabled("delete");
// keep Options & Add Landmark buttons always enabled
mListCommands->childSetEnabled(ADD_FOLDER_BUTTON_NAME, add_folder_enabled);
@@ -515,31 +516,29 @@ void LLLandmarksPanel::onAddFolderButtonClick() const
LLFolderViewItem* item = getCurSelectedItem();
if(item && mCurrentSelectedList == mLandmarksInventoryPanel)
{
- LLFolderBridge *parentBridge = NULL;
+ LLFolderViewEventListener* folder_bridge = NULL;
if(item-> getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
{
- parentBridge = dynamic_cast<LLFolderBridge*>(item->getParentFolder()->getListener());
- /*WORKAROUND:*
- LLFolderView::doIdle() is calling in each frame,
- it changes selected items before LLFolderView::startRenamingSelectedItem.
- To avoid it we have to change keyboardFocus.
- */
- gFocusMgr.setKeyboardFocus(item->getParentFolder());
+ // for a landmark get parent folder bridge
+ folder_bridge = item->getParentFolder()->getListener();
}
else if (item-> getListener()->getInventoryType() == LLInventoryType::IT_CATEGORY)
{
- parentBridge = dynamic_cast<LLFolderBridge*>(item->getListener());
- gFocusMgr.setKeyboardFocus(item);
+ // for a folder get its own bridge
+ folder_bridge = item->getListener();
}
- menu_create_inventory_item(mCurrentSelectedList->getRootFolder(),parentBridge, LLSD("category"));
+
+ menu_create_inventory_item(mCurrentSelectedList->getRootFolder()
+ , dynamic_cast<LLFolderBridge*>(folder_bridge)
+ , LLSD("category")
+ , gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK)
+ );
}
}
void LLLandmarksPanel::onTrashButtonClick() const
{
- if(!mCurrentSelectedList) return;
-
- mCurrentSelectedList->getRootFolder()->doToSelected(mCurrentSelectedList->getModel(), "delete");
+ onClipboardAction("delete");
}
void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
@@ -555,7 +554,7 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
}
}
-void LLLandmarksPanel::onCopyPasteAction(const LLSD& userdata) const
+void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const
{
if(!mCurrentSelectedList)
return;
@@ -613,13 +612,25 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata)
bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
{
std::string command_name = userdata.asString();
+
+ LLPlacesFolderView* rootFolderView = mCurrentSelectedList ?
+ static_cast<LLPlacesFolderView*>(mCurrentSelectedList->getRootFolder()) : NULL;
+
+ if (NULL == rootFolderView) return false;
+
if("category" == command_name)
{
- return mCurrentSelectedList == mLandmarksInventoryPanel;
+ // we can add folder only in Landmarks Accordion
+ if (mCurrentSelectedList == mLandmarksInventoryPanel)
+ {
+ // ... but except Received folder
+ return !isReceivedFolderSelected();
+ }
+ else return false;
}
- else if("paste" == command_name)
+ else if("paste" == command_name || "rename" == command_name || "cut" == command_name || "delete" == command_name)
{
- return mCurrentSelectedList ? mCurrentSelectedList->getRootFolder()->canPaste() : false;
+ return canSelectedBeModified(command_name);
}
else if ( "sort_by_date" == command_name)
{
@@ -628,13 +639,15 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
// do not allow teleport and more info for multi-selections
else if ("teleport" == command_name || "more_info" == command_name)
{
- return mCurrentSelectedList ?
- static_cast<LLPlacesFolderView*>(mCurrentSelectedList->getRootFolder())->getSelectedCount() == 1 : false;
+ return rootFolderView->getSelectedCount() == 1;
}
- // we can add folder, or change item/folder only in Landmarks Accordion
- else if ("add_folder" == command_name || "rename" == command_name || "delete" == command_name)
+ else if("create_pick" == command_name)
{
- return mLandmarksInventoryPanel == mCurrentSelectedList;
+ return !LLAgentPicksInfo::getInstance()->isPickLimitReached();
+ }
+ else
+ {
+ llwarns << "Unprocessed command has come: " << command_name << llendl;
}
return true;
@@ -699,6 +712,75 @@ void LLLandmarksPanel::onCustomAction(const LLSD& userdata)
}
}
+/*
+Processes such actions: cut/rename/delete/paste actions
+
+Rules:
+ 1. We can't perform any action in Library
+ 2. For Landmarks we can:
+ - cut/rename/delete in any other accordions
+ - paste - only in Favorites, Landmarks accordions
+ 3. For Folders we can: perform any action in Landmarks accordion, except Received folder
+ 4. We can not paste folders from Clipboard (processed by LLFolderView::canPaste())
+ 5. Check LLFolderView/Inventory Bridges rules
+ */
+bool LLLandmarksPanel::canSelectedBeModified(const std::string& command_name) const
+{
+ // validate own rules first
+
+ // nothing can be modified in Library
+ if (mLibraryInventoryPanel == mCurrentSelectedList) return false;
+
+ bool can_be_modified = false;
+
+ // landmarks can be modified in any other accordion...
+ if (isLandmarkSelected())
+ {
+ can_be_modified = true;
+
+ // we can modify landmarks anywhere except paste to My Inventory
+ if ("paste" == command_name)
+ {
+ can_be_modified = (mCurrentSelectedList != mMyInventoryPanel);
+ }
+ }
+ else
+ {
+ // ...folders only in the Landmarks accordion...
+ can_be_modified = mLandmarksInventoryPanel == mCurrentSelectedList;
+
+ // ...except "Received" folder
+ can_be_modified &= !isReceivedFolderSelected();
+ }
+
+ // then ask LLFolderView permissions
+ if (can_be_modified)
+ {
+ if ("cut" == command_name)
+ {
+ can_be_modified = mCurrentSelectedList->getRootFolder()->canCut();
+ }
+ else if ("rename" == command_name)
+ {
+ can_be_modified = getCurSelectedItem()->getListener()->isItemRenameable();
+ }
+ else if ("delete" == command_name)
+ {
+ can_be_modified = getCurSelectedItem()->getListener()->isItemRemovable();
+ }
+ else if("paste" == command_name)
+ {
+ return mCurrentSelectedList->getRootFolder()->canPaste();
+ }
+ else
+ {
+ llwarns << "Unprocessed command has come: " << command_name << llendl;
+ }
+ }
+
+ return can_be_modified;
+}
+
void LLLandmarksPanel::onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params)
{
pick_panel->setVisible(FALSE);
@@ -710,6 +792,33 @@ void LLLandmarksPanel::onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* own
pick_panel = NULL;
}
+bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept)
+{
+ *accept = ACCEPT_NO;
+
+ switch (cargo_type)
+ {
+
+ case DAD_LANDMARK:
+ case DAD_CATEGORY:
+ {
+ bool is_enabled = isActionEnabled("delete");
+
+ if (is_enabled) *accept = ACCEPT_YES_MULTI;
+
+ if (is_enabled && drop)
+ {
+ onClipboardAction("delete");
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
//////////////////////////////////////////////////////////////////////////
// HELPER FUNCTIONS
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index 389a04a76f..11d703dcde 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -66,6 +66,7 @@ protected:
* @return true - if current selected panel is not null and selected item is a landmark
*/
bool isLandmarkSelected() const;
+ bool isReceivedFolderSelected() const;
LLLandmark* getCurSelectedLandmark() const;
LLFolderViewItem* getCurSelectedItem () const;
void updateSortOrder(LLInventoryPanel* panel, bool byDate);
@@ -80,7 +81,7 @@ private:
void initLandmarksInventroyPanel();
void initMyInventroyPanel();
void initLibraryInventroyPanel();
- void initLandmarksPanel(LLInventorySubTreePanel* inventory_list, const LLUUID& start_folder_id);
+ void initLandmarksPanel(LLInventorySubTreePanel* inventory_list);
void initAccordion(const std::string& accordion_tab_name, LLInventorySubTreePanel* inventory_list);
void onAccordionExpandedCollapsed(const LLSD& param, LLInventorySubTreePanel* inventory_list);
void deselectOtherThan(const LLInventorySubTreePanel* inventory_list);
@@ -93,12 +94,25 @@ private:
void onAddFolderButtonClick() const;
void onTrashButtonClick() const;
void onAddAction(const LLSD& command_name) const;
- void onCopyPasteAction(const LLSD& command_name) const;
+ void onClipboardAction(const LLSD& command_name) const;
void onFoldingAction(const LLSD& command_name);
bool isActionEnabled(const LLSD& command_name) const;
void onCustomAction(const LLSD& command_name);
+
+ /**
+ * Determines if selected item can be modified via context/gear menu.
+ *
+ * It validates Places Landmarks rules first. And then LLFolderView permissions.
+ * For now it checks cut/rename/delete/paste actions.
+ */
+ bool canSelectedBeModified(const std::string& command_name) const;
void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params);
+ /**
+ * Processes drag-n-drop of the Landmarks and folders into trash button.
+ */
+ bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept);
+
private:
LLInventorySubTreePanel* mFavoritesInventoryPanel;
LLInventorySubTreePanel* mLandmarksInventoryPanel;
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index 664ebfd7a4..cb9f641bf8 100644
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
@@ -38,6 +38,7 @@
#include "llpanel.h"
#include "message.h"
#include "llagent.h"
+#include "llagentpicksinfo.h"
#include "llbutton.h"
#include "lllineeditor.h"
#include "llparcel.h"
@@ -310,6 +311,7 @@ LLPanelPickEdit::LLPanelPickEdit()
: LLPanelPickInfo()
, mLocationChanged(false)
, mNeedData(true)
+ , mNewPick(false)
{
}
@@ -325,6 +327,8 @@ void LLPanelPickEdit::onOpen(const LLSD& key)
// creating new Pick
if(pick_id.isNull())
{
+ mNewPick = true;
+
setAvatarId(gAgent.getID());
resetData();
@@ -356,6 +360,7 @@ void LLPanelPickEdit::onOpen(const LLSD& key)
// editing existing pick
else
{
+ mNewPick = false;
LLPanelPickInfo::onOpen(key);
enableSaveButton(false);
@@ -463,6 +468,14 @@ void LLPanelPickEdit::sendUpdate()
pick_data.enabled = TRUE;
LLAvatarPropertiesProcessor::instance().sendPickInfoUpdate(&pick_data);
+
+ if(mNewPick)
+ {
+ // Assume a successful create pick operation, make new number of picks
+ // available immediately. Actual number of picks will be requested in
+ // LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond.
+ LLAgentPicksInfo::getInstance()->incrementNumberOfPicks();
+ }
}
void LLPanelPickEdit::onPickChanged(LLUICtrl* ctrl)
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
index c5b13c69ea..9b605cd6b1 100644
--- a/indra/newview/llpanelpick.h
+++ b/indra/newview/llpanelpick.h
@@ -235,6 +235,7 @@ protected:
bool mLocationChanged;
bool mNeedData;
+ bool mNewPick;
};
#endif // LL_LLPANELPICK_H
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index 073da5cc06..1219a08c6c 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -33,6 +33,7 @@
#include "llviewerprecompiledheaders.h"
#include "llagent.h"
+#include "llagentpicksinfo.h"
#include "llavatarconstants.h"
#include "llflatlistview.h"
#include "llfloaterreg.h"
@@ -91,7 +92,12 @@ void* LLPanelPicks::create(void* data /* = NULL */)
void LLPanelPicks::updateData()
{
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(getAvatarId());
+ // Send Picks request only when we need to, not on every onOpen(during tab switch).
+ if(isDirty())
+ {
+ mPicksList->clear();
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(getAvatarId());
+ }
}
void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
@@ -134,6 +140,7 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
}
+ resetDirty();
LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
updateButtons();
}
@@ -183,8 +190,6 @@ void LLPanelPicks::onOpen(const LLSD& key)
// Disable buttons when viewing profile for first time
if(getAvatarId() != id)
{
- clear();
-
childSetEnabled(XML_BTN_INFO,FALSE);
childSetEnabled(XML_BTN_TELEPORT,FALSE);
childSetEnabled(XML_BTN_SHOW_ON_MAP,FALSE);
@@ -204,6 +209,8 @@ void LLPanelPicks::onOpen(const LLSD& key)
if(getAvatarId() != id)
{
mPicksList->goToTop();
+ // Set dummy value to make panel dirty and make it reload picks
+ setValue(LLSD());
}
LLPanelProfileTab::onOpen(key);
@@ -296,14 +303,13 @@ void LLPanelPicks::onDoubleClickItem(LLUICtrl* item)
void LLPanelPicks::updateButtons()
{
- int picks_num = mPicksList->size();
bool has_selected = mPicksList->numSelected();
childSetEnabled(XML_BTN_INFO, has_selected);
if (getAvatarId() == gAgentID)
{
- childSetEnabled(XML_BTN_NEW, picks_num < MAX_AVATAR_PICKS);
+ childSetEnabled(XML_BTN_NEW, !LLAgentPicksInfo::getInstance()->isPickLimitReached());
childSetEnabled(XML_BTN_DELETE, has_selected);
}
@@ -358,6 +364,12 @@ void LLPanelPicks::onPanelPickClose(LLPanel* panel)
panel->setVisible(FALSE);
}
+void LLPanelPicks::onPanelPickSave(LLPanel* panel)
+{
+ onPanelPickClose(panel);
+ updateButtons();
+}
+
void LLPanelPicks::createPickInfoPanel()
{
if(!mPanelPickInfo)
@@ -375,7 +387,7 @@ void LLPanelPicks::createPickEditPanel()
{
mPanelPickEdit = LLPanelPickEdit::create();
mPanelPickEdit->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit));
- mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit));
+ mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelPickSave, this, mPanelPickEdit));
mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit));
mPanelPickEdit->setVisible(FALSE);
}
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
index 6264a19318..7cf8f2de2a 100644
--- a/indra/newview/llpanelpicks.h
+++ b/indra/newview/llpanelpicks.h
@@ -86,6 +86,7 @@ private:
void onClickNew();
void onClickInfo();
void onPanelPickClose(LLPanel* panel);
+ void onPanelPickSave(LLPanel* panel);
void onPanelPickEdit();
void onClickMenuEdit();
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 6d1a5fb184..cb9f7184f0 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -56,10 +56,12 @@
#include "llagentui.h"
#include "llavatarpropertiesprocessor.h"
#include "llfloaterworldmap.h"
+#include "llfloaterbuycurrency.h"
#include "llinventorymodel.h"
#include "lllandmarkactions.h"
#include "llpanelpick.h"
#include "lltexturectrl.h"
+#include "llstatusbar.h"
#include "llviewerinventory.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
@@ -88,7 +90,10 @@ LLPanelPlaceInfo::LLPanelPlaceInfo()
mMinHeight(0),
mScrollingPanel(NULL),
mInfoPanel(NULL),
- mMediaPanel(NULL)
+ mMediaPanel(NULL),
+ mForSalePanel(NULL),
+ mYouAreHerePanel(NULL),
+ mSelectedParcelID(-1)
{}
LLPanelPlaceInfo::~LLPanelPlaceInfo()
@@ -104,14 +109,15 @@ BOOL LLPanelPlaceInfo::postBuild()
mTitle = getChild<LLTextBox>("panel_title");
mCurrentTitle = mTitle->getText();
- mForSaleIcon = getChild<LLIconCtrl>("icon_for_sale");
+ mForSalePanel = getChild<LLPanel>("for_sale_panel");
+ mYouAreHerePanel = getChild<LLPanel>("here_panel");
+ LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&LLPanelPlaceInfo::updateYouAreHereBanner,this));
+
+ //Icon value should contain sale price of last selected parcel.
+ mForSalePanel->getChild<LLIconCtrl>("icon_for_sale")->
+ setMouseDownCallback(boost::bind(&LLPanelPlaceInfo::onForSaleBannerClick, this));
- // Since this is only used in the directory browser, always
- // disable the snapshot control. Otherwise clicking on it will
- // open a texture picker.
mSnapshotCtrl = getChild<LLTextureCtrl>("logo");
- mSnapshotCtrl->setEnabled(FALSE);
-
mRegionName = getChild<LLTextBox>("region_title");
mParcelName = getChild<LLTextBox>("parcel_title");
mDescEditor = getChild<LLTextEditor>("description");
@@ -267,7 +273,8 @@ void LLPanelPlaceInfo::resetLocation()
mRequestedID.setNull();
mLandmarkID.setNull();
mPosRegion.clearVec();
- mForSaleIcon->setVisible(FALSE);
+ mForSalePanel->setVisible(FALSE);
+ mYouAreHerePanel->setVisible(FALSE);
std::string not_available = getString("not_available");
mMaturityRatingText->setValue(not_available);
mParcelOwner->setValue(not_available);
@@ -480,9 +487,9 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
//update for_sale banner, here we should use DFQ_FOR_SALE instead of PF_FOR_SALE
//because we deal with remote parcel response format
- bool isForSale = (parcel_data.flags & DFQ_FOR_SALE) &&
+ bool is_for_sale = (parcel_data.flags & DFQ_FOR_SALE) &&
mInfoType == AGENT ? TRUE : FALSE;
- mForSaleIcon->setVisible(isForSale);
+ mForSalePanel->setVisible(is_for_sale);
S32 region_x;
S32 region_y;
@@ -798,11 +805,11 @@ void LLPanelPlaceInfo::displaySelectedParcelInfo(LLParcel* parcel,
}
}
+ mSelectedParcelID = parcel->getLocalID();
+ mLastSelectedRegionID = region->getRegionID();
processParcelInfo(parcel_data);
- // TODO: If agent is in currently within the selected parcel
- // show the "You Are Here" banner.
-
+ mYouAreHerePanel->setVisible(is_current_parcel);
getChild<LLAccordionCtrlTab>("sales_tab")->setVisible(for_sale);
}
@@ -979,6 +986,50 @@ void LLPanelPlaceInfo::populateFoldersList()
mFolderCombo->add(it->second, LLSD(it->first));
}
+void LLPanelPlaceInfo::updateYouAreHereBanner()
+{
+ //YouAreHere Banner should be displayed only for selected places,
+ // If you want to display it for landmark or teleport history item, you should check by mParcelId
+
+ bool is_you_are_here = false;
+ if (mSelectedParcelID != S32(-1) && !mLastSelectedRegionID.isNull())
+ {
+ is_you_are_here = gAgent.getRegion()->getRegionID()== mLastSelectedRegionID &&
+ mSelectedParcelID == LLViewerParcelMgr::getInstance()->getAgentParcel()->getLocalID();
+ }
+ mYouAreHerePanel->setVisible(is_you_are_here);
+}
+
+void LLPanelPlaceInfo::onForSaleBannerClick()
+{
+ LLViewerParcelMgr* mgr = LLViewerParcelMgr::getInstance();
+ LLParcelSelectionHandle hParcel = mgr->getFloatingParcelSelection();
+ LLViewerRegion* selected_region = mgr->getSelectionRegion();
+ if(!hParcel.isNull() && selected_region)
+ {
+ if(hParcel->getParcel()->getLocalID() == mSelectedParcelID &&
+ mLastSelectedRegionID ==selected_region->getRegionID())
+ {
+ if(hParcel->getParcel()->getSalePrice() - gStatusBar->getBalance() > 0)
+ {
+ LLFloaterBuyCurrency::buyCurrency("Buying selected land ", hParcel->getParcel()->getSalePrice());
+ }
+ else
+ {
+ LLViewerParcelMgr::getInstance()->startBuyLand();
+ }
+ }
+ else
+ {
+ LL_WARNS("Places") << "User is trying to buy remote parcel.Operation is not supported"<< LL_ENDL;
+ }
+
+ }
+
+
+}
+
+
static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right)
{
return left.second < right.second;
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 06fee2224e..7b3a8f050b 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -135,7 +135,12 @@ public:
private:
void populateFoldersList();
+ void updateYouAreHereBanner();
+ void onForSaleBannerClick();
+ /**
+ * mParcelID is valid only for remote places, in other cases it's null. See resetLocation()
+ */
LLUUID mParcelID;
LLUUID mRequestedID;
LLUUID mLandmarkID;
@@ -144,8 +149,15 @@ private:
S32 mMinHeight;
INFO_TYPE mInfoType;
+ /**
+ * Hold last displayed parcel. Needs for YouAreHere banner.
+ */
+ S32 mSelectedParcelID;
+ LLUUID mLastSelectedRegionID;
+
LLTextBox* mTitle;
- LLIconCtrl* mForSaleIcon;
+ LLPanel* mForSalePanel;
+ LLPanel* mYouAreHerePanel;
LLTextureCtrl* mSnapshotCtrl;
LLTextBox* mRegionName;
LLTextBox* mParcelName;
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index f30bb1a0a6..5ab823b6e5 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -50,6 +50,7 @@
#include "lluictrlfactory.h"
#include "llagent.h"
+#include "llagentpicksinfo.h"
#include "llavatarpropertiesprocessor.h"
#include "llfloaterworldmap.h"
#include "llinventorybridge.h"
@@ -178,6 +179,8 @@ BOOL LLPanelPlaces::postBuild()
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("Places.OverflowMenu.Action", boost::bind(&LLPanelPlaces::onOverflowMenuItemClicked, this, _2));
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+ enable_registrar.add("Places.OverflowMenu.Enable", boost::bind(&LLPanelPlaces::onOverflowMenuItemEnable, this, _2));
mPlaceMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_place.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (!mPlaceMenu)
@@ -606,6 +609,16 @@ void LLPanelPlaces::onOverflowButtonClicked()
LLMenuGL::showPopup(this, menu, rect.mRight, rect.mTop);
}
+bool LLPanelPlaces::onOverflowMenuItemEnable(const LLSD& param)
+{
+ std::string value = param.asString();
+ if("can_create_pick" == value)
+ {
+ return !LLAgentPicksInfo::getInstance()->isPickLimitReached();
+ }
+ return true;
+}
+
void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
{
std::string item = param.asString();
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 70c50b2058..e2d281dd84 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -77,6 +77,7 @@ private:
void onCancelButtonClicked();
void onOverflowButtonClicked();
void onOverflowMenuItemClicked(const LLSD& param);
+ bool onOverflowMenuItemEnable(const LLSD& param);
void onCreateLandmarkButtonClicked(const LLUUID& folder_id);
void onBackButtonClicked();
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 08d2baf6cd..bec670cdaa 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -192,8 +192,9 @@ void LLPanelProfile::openPanel(LLPanel* panel, const LLSD& params)
void LLPanelProfile::notifyParent(const LLSD& info)
{
+ std::string action = info["action"];
// lets update Picks list after Pick was saved
- if("save_new_pick" == info["action"])
+ if("save_new_pick" == action)
{
onOpen(info);
return;
diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp
index f1db2416e4..1d16c4ef5e 100644
--- a/indra/newview/llpanelprofileview.cpp
+++ b/indra/newview/llpanelprofileview.cpp
@@ -46,6 +46,7 @@ static LLRegisterPanelClassWrapper<LLPanelProfileView> t_panel_target_profile("p
static std::string PANEL_NOTES = "panel_notes";
static const std::string PANEL_PROFILE = "panel_profile";
+static const std::string PANEL_PICKS = "panel_picks";
LLPanelProfileView::LLPanelProfileView()
: LLPanelProfile()
@@ -103,6 +104,10 @@ BOOL LLPanelProfileView::postBuild()
void LLPanelProfileView::onBackBtnClick()
{
+ // Set dummy value to make picks panel dirty,
+ // This will make Picks reload on next open.
+ getTabContainer()[PANEL_PICKS]->setValue(LLSD());
+
LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
if(parent)
{
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index 207ed723b2..7dd9df674c 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -60,6 +60,7 @@ public:
virtual BOOL postBuild();
S32 getIndex() { return mIndex; }
+ void setIndex(S32 index) { mIndex = index; }
const std::string& getRegionName() { return mRegionName;}
/*virtual*/ void setValue(const LLSD& value);
@@ -180,7 +181,7 @@ LLContextMenu* LLTeleportHistoryPanel::ContextMenu::createMenu()
registrar.add("TeleportHistory.Teleport", boost::bind(&LLTeleportHistoryPanel::ContextMenu::onTeleport, this));
registrar.add("TeleportHistory.MoreInformation",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onInfo, this));
- registrar.add("TeleportHistory.Copy", boost::bind(&LLTeleportHistoryPanel::ContextMenu::onCopy, this));
+ registrar.add("TeleportHistory.CopyToClipboard",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard, this));
// create the context menu from the XUI
return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
@@ -203,11 +204,11 @@ void LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback(const std::string& sl
gClipboard.copyFromString(utf8str_to_wstring(slurl));
}
-void LLTeleportHistoryPanel::ContextMenu::onCopy()
+void LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard()
{
LLVector3d globalPos = LLTeleportHistoryStorage::getInstance()->getItems()[mIndex].mGlobalPos;
LLLandmarkActions::getSLURLfromPosGlobal(globalPos,
- boost::bind(&LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback, _1), false);
+ boost::bind(&LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback, _1));
}
// Not yet implemented; need to remove buildPanel() from constructor when we switch
@@ -237,7 +238,7 @@ BOOL LLTeleportHistoryPanel::postBuild()
mTeleportHistory = LLTeleportHistoryStorage::getInstance();
if (mTeleportHistory)
{
- mTeleportHistory->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryPanel::onTeleportHistoryChange, this));
+ mTeleportHistory->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryPanel::onTeleportHistoryChange, this, _1));
}
mHistoryAccordion = getChild<LLAccordionCtrl>("history_accordion");
@@ -488,7 +489,7 @@ void LLTeleportHistoryPanel::refresh()
if (mLastSelectedItemIndex == mCurrentItem)
curr_flat_view->selectItem(item, true);
}
-
+
mCurrentItem--;
if (++added_items >= ADD_LIMIT)
@@ -503,10 +504,75 @@ void LLTeleportHistoryPanel::refresh()
mDirty = false;
}
-void LLTeleportHistoryPanel::onTeleportHistoryChange()
+void LLTeleportHistoryPanel::onTeleportHistoryChange(S32 removed_index)
{
mLastSelectedItemIndex = -1;
- showTeleportHistory();
+
+ if (-1 == removed_index)
+ showTeleportHistory(); // recreate all items
+ else
+ replaceItem(removed_index); // replace removed item by most recent
+}
+
+void LLTeleportHistoryPanel::replaceItem(S32 removed_index)
+{
+ // Flat list for 'Today' (mItemContainers keeps accordion tabs in reverse order)
+ LLFlatListView* fv = getFlatListViewFromTab(mItemContainers[mItemContainers.size() - 1]);
+
+ // Empty flat list for 'Today' means that other flat lists are empty as well,
+ // so all items from teleport history should be added.
+ if (!fv || fv->size() == 0)
+ {
+ showTeleportHistory();
+ return;
+ }
+
+ const LLTeleportHistoryStorage::slurl_list_t& history_items = mTeleportHistory->getItems();
+ LLTeleportHistoryFlatItem* item = new LLTeleportHistoryFlatItem(history_items.size(), // index will be decremented inside loop below
+ &mContextMenu,
+ history_items[history_items.size() - 1].mTitle); // Most recent item, it was
+ // added instead of removed
+ fv->addItem(item, LLUUID::null, ADD_TOP);
+
+ // Index of each item, from last to removed item should be decremented
+ // to point to the right item in LLTeleportHistoryStorage
+ for (S32 tab_idx = mItemContainers.size() - 1; tab_idx >= 0; --tab_idx)
+ {
+ LLAccordionCtrlTab* tab = mItemContainers.get(tab_idx);
+ if (!tab->getVisible())
+ continue;
+
+ fv = getFlatListViewFromTab(tab);
+ if (!fv)
+ {
+ showTeleportHistory();
+ return;
+ }
+
+ std::vector<LLPanel*> items;
+ fv->getItems(items);
+
+ S32 items_cnt = items.size();
+ for (S32 n = 0; n < items_cnt; ++n)
+ {
+ LLTeleportHistoryFlatItem *item = (LLTeleportHistoryFlatItem*) items[n];
+
+ if (item->getIndex() == removed_index)
+ {
+ fv->removeItem(item);
+
+ // If flat list becames empty, then accordion tab should be hidden
+ if (fv->size() == 0)
+ tab->setVisible(false);
+
+ mHistoryAccordion->arrange();
+
+ return; // No need to decrement idexes for the rest of items
+ }
+
+ item->setIndex(item->getIndex() - 1);
+ }
+ }
}
void LLTeleportHistoryPanel::showTeleportHistory()
diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h
index 49a97c5022..7c1b403432 100644
--- a/indra/newview/llpanelteleporthistory.h
+++ b/indra/newview/llpanelteleporthistory.h
@@ -57,7 +57,7 @@ public:
LLContextMenu* createMenu();
void onTeleport();
void onInfo();
- void onCopy();
+ void onCopyToClipboard();
static void gotSLURLCallback(const std::string& slurl);
@@ -90,7 +90,8 @@ private:
void refresh();
void getNextTab(const LLDate& item_date, S32& curr_tab, LLDate& tab_date);
- void onTeleportHistoryChange();
+ void onTeleportHistoryChange(S32 removed_index);
+ void replaceItem(S32 removed_index);
void showTeleportHistory();
void handleItemSelect(LLFlatListView* );
LLFlatListView* getFlatListViewFromTab(LLAccordionCtrlTab *);
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
new file mode 100644
index 0000000000..f1e585f285
--- /dev/null
+++ b/indra/newview/llparticipantlist.cpp
@@ -0,0 +1,56 @@
+/**
+ * @file llparticipantlist.cpp
+ * @brief LLParticipantList implementing LLSimpleListener listener
+ *
+ * $LicenseInfo:firstyear=2005&license=viewergpl$
+ *
+ * Copyright (c) 2005-2009, 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 "llparticipantlist.h"
+#include "llavatarlist.h"
+#include "llfloateractivespeakers.h"
+
+
+LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list):
+ mSpeakerMgr(data_source),
+ mAvatarList(avatar_list)
+{
+ mSpeakerMgr->addListener(this, "add");
+ mSpeakerMgr->addListener(this, "remove");
+ mSpeakerMgr->addListener(this, "clear");
+ std::string str = "test";
+ mAvatarList->setNoItemsCommentText(str);
+
+ //LLAvatarList::uuid_vector_t& group_members = mAvatarList->getIDs();
+}
+
+bool LLParticipantList::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+ return true;
+}
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
new file mode 100644
index 0000000000..2ec563a356
--- /dev/null
+++ b/indra/newview/llparticipantlist.h
@@ -0,0 +1,48 @@
+/**
+ * @file llparticipantlist.h
+ * @brief LLParticipantList implementing LLSimpleListener listener
+ *
+ * $LicenseInfo:firstyear=2005&license=viewergpl$
+ *
+ * Copyright (c) 2005-2009, 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 "llevent.h"
+
+class LLSpeakerMgr;
+class LLAvatarList;
+
+class LLParticipantList: public LLOldEvents::LLSimpleListener
+{
+ public:
+ LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list);
+ /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
+
+ private:
+ LLSpeakerMgr* mSpeakerMgr;
+ LLAvatarList* mAvatarList;
+};
diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp
index 02e11cefad..d5a2d66bcf 100644
--- a/indra/newview/llpolymesh.cpp
+++ b/indra/newview/llpolymesh.cpp
@@ -1118,7 +1118,7 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
return TRUE;
}
-/*virtual*/ LLViewerVisualParam * LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const
+/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const
{
LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar);
*new_param = *this;
diff --git a/indra/newview/llpolymesh.h b/indra/newview/llpolymesh.h
index 709b176c8d..c2e5451dfe 100644
--- a/indra/newview/llpolymesh.h
+++ b/indra/newview/llpolymesh.h
@@ -417,7 +417,7 @@ public:
// This sets mInfo and calls initialization functions
BOOL setInfo(LLPolySkeletalDistortionInfo *info);
- /*virtual*/ LLViewerVisualParam * cloneParam(LLWearable* wearable) const;
+ /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
// LLVisualParam Virtual functions
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
diff --git a/indra/newview/llpolymorph.cpp b/indra/newview/llpolymorph.cpp
index 924b1a4d6e..80983cad24 100644
--- a/indra/newview/llpolymorph.cpp
+++ b/indra/newview/llpolymorph.cpp
@@ -302,7 +302,7 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info)
return TRUE;
}
-/*virtual*/ LLViewerVisualParam * LLPolyMorphTarget::cloneParam(LLWearable* wearable) const
+/*virtual*/ LLViewerVisualParam* LLPolyMorphTarget::cloneParam(LLWearable* wearable) const
{
LLPolyMorphTarget *new_param = new LLPolyMorphTarget(mMesh);
*new_param = *this;
diff --git a/indra/newview/llpolymorph.h b/indra/newview/llpolymorph.h
index 5089fc2e8a..01731402df 100644
--- a/indra/newview/llpolymorph.h
+++ b/indra/newview/llpolymorph.h
@@ -154,7 +154,7 @@ public:
// This sets mInfo and calls initialization functions
BOOL setInfo(LLPolyMorphTargetInfo *info);
- /*virtual*/ LLViewerVisualParam * cloneParam(LLWearable* wearable) const;
+ /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
// LLVisualParam Virtual functions
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
diff --git a/indra/newview/llrootview.h b/indra/newview/llrootview.h
index f704fecddd..760b1a7a4c 100644
--- a/indra/newview/llrootview.h
+++ b/indra/newview/llrootview.h
@@ -47,5 +47,27 @@ public:
LLRootView(const Params& p)
: LLView(p)
{}
+
+ // added to provide possibility to handle mouse click event inside all application
+ // window without creating any floater
+ typedef boost::signals2::signal<void(S32 x, S32 y, MASK mask)>
+ mouse_signal_t;
+
+ private:
+ mouse_signal_t mMouseDownSignal;
+
+ public:
+ /*virtual*/
+ BOOL handleMouseDown(S32 x, S32 y, MASK mask)
+ {
+ mMouseDownSignal(x, y, mask);
+ return LLView::handleMouseDown(x, y, mask);
+ }
+
+ boost::signals2::connection addMouseDownCallback(
+ const mouse_signal_t::slot_type& cb)
+ {
+ return mMouseDownSignal.connect(cb);
+ }
};
#endif //LL_LLROOTVIEW_H
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index a72100a9b3..1683d113a9 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -138,7 +138,7 @@ void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_wo
}
//--------------------------------------------------------------------------
-void LLScreenChannel::addToast(LLToast::Params p)
+void LLScreenChannel::addToast(const LLToast::Params& p)
{
bool store_toast = false, show_toast = false;
@@ -381,7 +381,7 @@ void LLScreenChannel::showToastsBottom()
if(it != mToastList.rbegin())
{
bottom = (*(it-1)).toast->getRect().mTop;
- toast_margin = gSavedSettings.getS32("ToastMargin");
+ toast_margin = gSavedSettings.getS32("ToastGap");
}
toast_rect = (*it).toast->getRect();
@@ -394,7 +394,7 @@ void LLScreenChannel::showToastsBottom()
{
if( it != mToastList.rend()-1)
{
- stop_showing_toasts = ((*it).toast->getRect().mTop + gSavedSettings.getS32("OverflowToastHeight") + gSavedSettings.getS32("ToastMargin")) > getRect().mTop;
+ stop_showing_toasts = ((*it).toast->getRect().mTop + gSavedSettings.getS32("OverflowToastHeight") + gSavedSettings.getS32("ToastGap")) > getRect().mTop;
}
}
@@ -412,7 +412,7 @@ void LLScreenChannel::showToastsBottom()
(*it).toast->stopTimer();
mHiddenToastsNum++;
}
- createOverflowToast(bottom, gSavedSettings.getS32("NotificationToastTime"));
+ createOverflowToast(bottom, gSavedSettings.getS32("NotificationTipToastLifeTime"));
}
}
@@ -426,7 +426,7 @@ void LLScreenChannel::showToastsCentre()
for(it = mToastList.rbegin(); it != mToastList.rend(); ++it)
{
toast_rect = (*it).toast->getRect();
- toast_rect.setLeftTopAndSize(getRect().mLeft - toast_rect.getWidth() / 2, bottom + toast_rect.getHeight() / 2 + gSavedSettings.getS32("ToastMargin"), toast_rect.getWidth() ,toast_rect.getHeight());
+ toast_rect.setLeftTopAndSize(getRect().mLeft - toast_rect.getWidth() / 2, bottom + toast_rect.getHeight() / 2 + gSavedSettings.getS32("ToastGap"), toast_rect.getWidth() ,toast_rect.getHeight());
(*it).toast->setRect(toast_rect);
(*it).toast->setVisible(TRUE);
@@ -443,13 +443,13 @@ void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer)
{
LLRect toast_rect;
LLToast::Params p;
- p.timer_period = timer;
+ p.lifetime_secs = timer;
mOverflowToastPanel = new LLToast(p);
if(!mOverflowToastPanel)
return;
- mOverflowToastPanel->setOnFadeCallback(boost::bind(&LLScreenChannel::onOverflowToastHide, this));
+ mOverflowToastPanel->setOnFadeCallback(boost::bind(&LLScreenChannel::closeOverflowToastPanel, this));
LLTextBox* text_box = mOverflowToastPanel->getChild<LLTextBox>("toast_text");
LLIconCtrl* icon = mOverflowToastPanel->getChild<LLIconCtrl>("icon");
@@ -465,7 +465,7 @@ void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer)
toast_rect = mOverflowToastPanel->getRect();
mOverflowToastPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true);
- toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), getRect().getWidth(), toast_rect.getHeight());
+ toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastGap"), getRect().getWidth(), toast_rect.getHeight());
mOverflowToastPanel->setRect(toast_rect);
text_box->setValue(text);
@@ -514,11 +514,11 @@ void LLScreenChannel::closeOverflowToastPanel()
}
//--------------------------------------------------------------------------
-void LLScreenChannel::createStartUpToast(S32 notif_num, S32 bottom, F32 timer)
+void LLScreenChannel::createStartUpToast(S32 notif_num, F32 timer)
{
LLRect toast_rect;
LLToast::Params p;
- p.timer_period = timer;
+ p.lifetime_secs = timer;
mStartUpToastPanel = new LLToast(p);
if(!mStartUpToastPanel)
@@ -545,13 +545,15 @@ void LLScreenChannel::createStartUpToast(S32 notif_num, S32 bottom, F32 timer)
toast_rect = mStartUpToastPanel->getRect();
mStartUpToastPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true);
- toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), getRect().getWidth(), toast_rect.getHeight());
+ toast_rect.setLeftTopAndSize(0, toast_rect.getHeight()+gSavedSettings.getS32("ToastGap"), getRect().getWidth(), toast_rect.getHeight());
mStartUpToastPanel->setRect(toast_rect);
text_box->setValue(text);
text_box->setVisible(TRUE);
icon->setVisible(TRUE);
+ addChild(mStartUpToastPanel);
+
mStartUpToastPanel->setVisible(TRUE);
}
@@ -572,7 +574,7 @@ void LLScreenChannel::closeStartUpToast()
{
if(mStartUpToastPanel != NULL)
{
- mStartUpToastPanel->closeFloater();
+ mStartUpToastPanel->setVisible(FALSE);
mStartUpToastPanel = NULL;
}
}
@@ -703,7 +705,7 @@ void LLScreenChannel::updateShowToastsState()
LLRect this_rect = getRect();
if(floater->getVisible() && floater->isDocked())
{
- channel_bottom += (floater->getRect().getHeight() + gSavedSettings.getS32("ToastMargin"));
+ channel_bottom += (floater->getRect().getHeight() + gSavedSettings.getS32("ToastGap"));
}
if(channel_bottom != this_rect.mBottom)
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index 459c28ac7c..987bc4b596 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -158,7 +158,7 @@ public:
// Operating with toasts
// add a toast to a channel
- void addToast(LLToast::Params p);
+ void addToast(const LLToast::Params& p);
// kill or modify a toast by its ID
void killToastByNotificationID(LLUUID id);
void modifyToastByNotificationID(LLUUID id, LLPanel* panel);
@@ -256,7 +256,7 @@ private:
void createOverflowToast(S32 bottom, F32 timer);
// create the StartUp Toast
- void createStartUpToast(S32 notif_num, S32 bottom, F32 timer);
+ void createStartUpToast(S32 notif_num, F32 timer);
// Channel's flags
static bool mWasStartUpToastShown;
diff --git a/indra/newview/llsearchcombobox.cpp b/indra/newview/llsearchcombobox.cpp
index 5123d862ce..f95671685b 100644
--- a/indra/newview/llsearchcombobox.cpp
+++ b/indra/newview/llsearchcombobox.cpp
@@ -85,11 +85,6 @@ LLSearchComboBox::LLSearchComboBox(const Params&p)
setSelectionCallback(boost::bind(&LLSearchComboBox::onSelectionCommit, this));
setPrearrangeCallback(boost::bind(&LLSearchComboBox::onSearchPrearrange, this, _2));
mSearchButton->setCommitCallback(boost::bind(&LLSearchComboBox::onTextCommit, this, _2));
-
- // set tooltip here for now since we don't want to parse /en/widgets
- std::string tool_tip = LLTrans::getString("Search");
- getChild<LLView>("child1")->setToolTip(tool_tip);
- getChild<LLView>("child3")->setToolTip(tool_tip);
}
void LLSearchComboBox::rebuildSearchHistory(const std::string& filter)
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index ff95f8adce..329d7d26ee 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -144,12 +144,6 @@ BOOL LLSideTrayTab::postBuild()
title_panel->getChild<LLTextBox>(TAB_PANEL_CAPTION_TITLE_BOX)->setValue(mTabTitle);
- static LLUIColor default_background_color = LLUIColorTable::instance().getColor("FloaterDefaultBackgroundColor");
- static LLUIColor focus_background_color = LLUIColorTable::instance().getColor("FloaterFocusBackgroundColor");
-
- setTransparentColor(default_background_color);
- setBackgroundColor(focus_background_color);
-
return true;
}
@@ -209,11 +203,6 @@ void LLSideTrayTab::reshape (S32 width, S32 height, BOOL called_from_parent )
void LLSideTrayTab::draw()
{
LLPanel::draw();
-
- //border
- gl_rect_2d(0,0,getRect().getWidth() - 1,getRect().getHeight() - 1,LLColor4::black,false);
-
-
}
void LLSideTrayTab::onOpen (const LLSD& key)
@@ -548,17 +537,15 @@ void LLSideTray::expandSideBar ()
void LLSideTray::highlightFocused()
{
+ /* uncomment in case something change
if(!mActiveTab)
return;
- /* uncomment in case something change
BOOL dependent_has_focus = gFocusMgr.childHasKeyboardFocus(this);
setBackgroundOpaque( dependent_has_focus );
mActiveTab->setBackgroundOpaque( dependent_has_focus );
*/
- mActiveTab->setBackgroundOpaque( true );
-
-
}
+
BOOL LLSideTray::handleScrollWheel(S32 x, S32 y, S32 mask)
{
BOOL ret = LLPanel::handleScrollWheel(x,y,mask);
@@ -576,6 +563,7 @@ BOOL LLSideTray::handleMouseDown (S32 x, S32 y, MASK mask)
setFocus(true);
return ret;
}
+
void LLSideTray::reshape (S32 width, S32 height, BOOL called_from_parent)
{
@@ -686,7 +674,7 @@ void LLSideTray::resetPanelRect ()
static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>());
S32 panel_width = sidetray_params.default_button_width;
- panel_width += mCollapsed ? sidetray_params.default_button_margin : mMaxBarWidth;
+ panel_width += mCollapsed ? 0 : mMaxBarWidth;
S32 panel_height = parent_rect.getHeight()-fake_top_offset;
@@ -703,7 +691,7 @@ void LLSideTray::setPanelRect ()
const LLRect& parent_rect = gViewerWindow->getRootView()->getRect();
S32 panel_width = sidetray_params.default_button_width;
- panel_width += mCollapsed ? sidetray_params.default_button_margin : mMaxBarWidth;
+ panel_width += mCollapsed ? 0 : mMaxBarWidth;
S32 panel_height = parent_rect.getHeight()-fake_top_offset - nav_rect.getHeight();
S32 panel_top = parent_rect.mTop-fake_top_offset - nav_rect.getHeight();
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 3d0e25a734..43b039f94e 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -83,6 +83,7 @@
#include "v3math.h"
#include "llagent.h"
+#include "llagentpicksinfo.h"
#include "llagentwearables.h"
#include "llagentpilot.h"
#include "llfloateravatarpicker.h"
@@ -2088,7 +2089,7 @@ bool idle_startup()
// reset timers now that we are running "logged in" logic
LLFastTimer::reset();
-
+ LLAgentPicksInfo::getInstance()->requestNumberOfPicks();
return TRUE;
}
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 6714fe908f..86290e6695 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -246,6 +246,10 @@ void LLSysWellWindow::toggleWindow()
if(!getVisible() || isMinimized())
{
+ if(mChannel)
+ {
+ mChannel->removeAndStoreAllStorableToasts();
+ }
if(isWindowEmpty())
{
return;
@@ -524,7 +528,7 @@ LLSysWellWindow::RowPanel::~RowPanel()
//---------------------------------------------------------------------------------
void LLSysWellWindow::RowPanel::onClosePanel()
{
- gIMMgr->removeSession(mChiclet->getSessionId());
+ gIMMgr->leaveSession(mChiclet->getSessionId());
// This row panel will be removed from the list in LLSysWellWindow::sessionRemoved().
}
diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp
index a588153ca2..d3bbda1c72 100644
--- a/indra/newview/llteleporthistorystorage.cpp
+++ b/indra/newview/llteleporthistorystorage.cpp
@@ -93,14 +93,12 @@ void LLTeleportHistoryStorage::onTeleportHistoryChange()
addItem(item.mTitle, item.mGlobalPos);
save();
-
- mHistoryChangedSignal();
}
void LLTeleportHistoryStorage::purgeItems()
{
mItems.clear();
- mHistoryChangedSignal();
+ mHistoryChangedSignal(-1);
}
void LLTeleportHistoryStorage::addItem(const std::string title, const LLVector3d& global_pos)
@@ -116,15 +114,16 @@ bool LLTeleportHistoryStorage::compareByTitleAndGlobalPos(const LLTeleportHistor
void LLTeleportHistoryStorage::addItem(const std::string title, const LLVector3d& global_pos, const LLDate& date)
{
-
LLTeleportHistoryPersistentItem item(title, global_pos, date);
slurl_list_t::iterator item_iter = std::find_if(mItems.begin(), mItems.end(),
boost::bind(&LLTeleportHistoryStorage::compareByTitleAndGlobalPos, this, _1, item));
// If there is such item already, remove it, since new item is more recent
+ S32 removed_index = -1;
if (item_iter != mItems.end())
{
+ removed_index = item_iter - mItems.begin();
mItems.erase(item_iter);
}
@@ -141,9 +140,12 @@ void LLTeleportHistoryStorage::addItem(const std::string title, const LLVector3d
// If second to last item is more recent than last, then resort items
if (item_iter->mDate > item.mDate)
{
+ removed_index = -1;
std::sort(mItems.begin(), mItems.end(), LLSortItemsByDate());
}
}
+
+ mHistoryChangedSignal(removed_index);
}
void LLTeleportHistoryStorage::removeItem(S32 idx)
@@ -211,6 +213,8 @@ void LLTeleportHistoryStorage::load()
file.close();
std::sort(mItems.begin(), mItems.end(), LLSortItemsByDate());
+
+ mHistoryChangedSignal(-1);
}
void LLTeleportHistoryStorage::dump() const
@@ -234,7 +238,6 @@ boost::signals2::connection LLTeleportHistoryStorage::setHistoryChangedCallback(
}
void LLTeleportHistoryStorage::goToItem(S32 idx)
-
{
// Validate specified index.
if (idx < 0 || idx >= (S32)mItems.size())
diff --git a/indra/newview/llteleporthistorystorage.h b/indra/newview/llteleporthistorystorage.h
index f67c4e2fb9..2eaa94f2ed 100644
--- a/indra/newview/llteleporthistorystorage.h
+++ b/indra/newview/llteleporthistorystorage.h
@@ -80,8 +80,9 @@ public:
typedef std::vector<LLTeleportHistoryPersistentItem> slurl_list_t;
- typedef boost::function<void()> history_callback_t;
- typedef boost::signals2::signal<void()> history_signal_t;
+ // removed_index is index of removed item, which replaced by more recent
+ typedef boost::function<void(S32 removed_index)> history_callback_t;
+ typedef boost::signals2::signal<void(S32 removed_index)> history_signal_t;
LLTeleportHistoryStorage();
~LLTeleportHistoryStorage();
diff --git a/indra/newview/lltexglobalcolor.cpp b/indra/newview/lltexglobalcolor.cpp
index d0bb9e1cf1..595b24ad47 100644
--- a/indra/newview/lltexglobalcolor.cpp
+++ b/indra/newview/lltexglobalcolor.cpp
@@ -101,7 +101,7 @@ LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color)
{
}
-/*virtual*/ LLViewerVisualParam * LLTexParamGlobalColor::cloneParam(LLWearable* wearable) const
+/*virtual*/ LLViewerVisualParam* LLTexParamGlobalColor::cloneParam(LLWearable* wearable) const
{
LLTexParamGlobalColor *new_param = new LLTexParamGlobalColor(mTexGlobalColor);
*new_param = *this;
diff --git a/indra/newview/lltexglobalcolor.h b/indra/newview/lltexglobalcolor.h
index f0d22d317c..1e6754133f 100644
--- a/indra/newview/lltexglobalcolor.h
+++ b/indra/newview/lltexglobalcolor.h
@@ -78,7 +78,7 @@ class LLTexParamGlobalColor : public LLTexLayerParamColor
{
public:
LLTexParamGlobalColor(LLTexGlobalColor *tex_color);
- /*virtual*/ LLViewerVisualParam * cloneParam(LLWearable* wearable) const;
+ /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
protected:
/*virtual*/ void onGlobalColorChanged(bool set_by_user);
private:
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index de8458c0fa..17547cae39 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -1078,13 +1078,13 @@ BOOL LLTexLayerInterface::setInfo(const LLTexLayerInfo *info, LLWearable* wearab
mInfo = info;
//mID = info->mID; // No ID
- mParamColorList.reserve(mInfo->mParamColorInfoList.size());
+ mParamColorList.reserve(mInfo->mParamColorInfoList.size());
for (param_color_info_list_t::const_iterator iter = mInfo->mParamColorInfoList.begin();
iter != mInfo->mParamColorInfoList.end();
iter++)
{
LLTexLayerParamColor* param_color;
- if (!wearable)
+ if (!wearable)
{
param_color = new LLTexLayerParamColor(this);
if (!param_color->setInfo(*iter, TRUE))
@@ -1105,7 +1105,7 @@ BOOL LLTexLayerInterface::setInfo(const LLTexLayerInfo *info, LLWearable* wearab
mParamColorList.push_back( param_color );
}
- mParamAlphaList.reserve(mInfo->mParamAlphaInfoList.size());
+ mParamAlphaList.reserve(mInfo->mParamAlphaInfoList.size());
for (param_alpha_info_list_t::const_iterator iter = mInfo->mParamAlphaInfoList.begin();
iter != mInfo->mParamAlphaInfoList.end();
iter++)
@@ -1893,13 +1893,13 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i)
//-----------------------------------------------------------------------------
// finds a specific layer based on a passed in name
//-----------------------------------------------------------------------------
-LLTexLayerInterface* LLTexLayerSet::findLayerByName(std::string name)
+LLTexLayerInterface* LLTexLayerSet::findLayerByName(const std::string& name)
{
for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
{
LLTexLayerInterface* layer = *iter;
- if (layer->getName().compare(name) == 0)
+ if (layer->getName() == name)
{
return layer;
}
@@ -1908,7 +1908,7 @@ LLTexLayerInterface* LLTexLayerSet::findLayerByName(std::string name)
{
LLTexLayerInterface* layer = *iter;
- if (layer->getName().compare(name) == 0)
+ if (layer->getName() == name)
{
return layer;
}
diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h
index 2269c3c9a5..e4a6e82ba5 100644
--- a/indra/newview/lltexlayer.h
+++ b/indra/newview/lltexlayer.h
@@ -60,6 +60,11 @@ typedef std::vector<LLTexLayerParamAlpha *> param_alpha_list_t;
typedef std::vector<LLTexLayerParamColorInfo *> param_color_info_list_t;
typedef std::vector<LLTexLayerParamAlphaInfo *> param_alpha_info_list_t;
+
+//-----------------------------------------------------------------------------
+// LLTexLayerInterface
+// Interface class to generalize functionality shared by LLTexLayer and LLTexLayerTemplate.
+
class LLTexLayerInterface
{
public:
@@ -256,7 +261,7 @@ public:
void deleteCaches();
void gatherMorphMaskAlpha(U8 *data, S32 width, S32 height);
void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
- LLTexLayerInterface* findLayerByName(std::string name);
+ LLTexLayerInterface* findLayerByName(const std::string& name);
void cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable* wearable);
LLVOAvatarSelf* getAvatar() const { return mAvatar; }
diff --git a/indra/newview/lltexlayerparams.cpp b/indra/newview/lltexlayerparams.cpp
index 9cd73c4656..ca888899ed 100644
--- a/indra/newview/lltexlayerparams.cpp
+++ b/indra/newview/lltexlayerparams.cpp
@@ -140,7 +140,7 @@ LLTexLayerParamAlpha::~LLTexLayerParamAlpha()
sInstances.remove(this);
}
-/*virtual*/ LLViewerVisualParam * LLTexLayerParamAlpha::cloneParam(LLWearable* wearable) const
+/*virtual*/ LLViewerVisualParam* LLTexLayerParamAlpha::cloneParam(LLWearable* wearable) const
{
LLTexLayerParamAlpha *new_param = new LLTexLayerParamAlpha(mTexLayer);
*new_param = *this;
@@ -409,7 +409,7 @@ LLTexLayerParamColor::~LLTexLayerParamColor()
{
}
-/*virtual*/ LLViewerVisualParam * LLTexLayerParamColor::cloneParam(LLWearable* wearable) const
+/*virtual*/ LLViewerVisualParam* LLTexLayerParamColor::cloneParam(LLWearable* wearable) const
{
LLTexLayerParamColor *new_param = new LLTexLayerParamColor(mTexLayer);
*new_param = *this;
diff --git a/indra/newview/lltexlayerparams.h b/indra/newview/lltexlayerparams.h
index 589bd41054..98365864f9 100644
--- a/indra/newview/lltexlayerparams.h
+++ b/indra/newview/lltexlayerparams.h
@@ -43,8 +43,8 @@ class LLTexLayerParam : public LLViewerVisualParam
public:
LLTexLayerParam(LLTexLayerInterface *layer);
LLTexLayerParam(LLVOAvatar *avatar);
- /* Virtual */ BOOL setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar );
- /*virtual*/ LLViewerVisualParam * cloneParam(LLWearable* wearable) const = 0;
+ /*virtual*/ BOOL setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar );
+ /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const = 0;
protected:
LLTexLayerInterface* mTexLayer;
@@ -61,7 +61,7 @@ public:
LLTexLayerParamAlpha( LLVOAvatar* avatar );
/*virtual*/ ~LLTexLayerParamAlpha();
- /*virtual*/ LLViewerVisualParam * cloneParam(LLWearable* wearable = NULL) const;
+ /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
// LLVisualParam Virtual functions
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
@@ -138,7 +138,7 @@ public:
LLTexLayerParamColor( LLVOAvatar* avatar );
/* virtual */ ~LLTexLayerParamColor();
- /*virtual*/ LLViewerVisualParam * cloneParam(LLWearable* wearable = NULL) const;
+ /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
// LLVisualParam Virtual functions
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 84931e4d2d..eba43d76a6 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -41,17 +41,29 @@
using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
-LLToast::LLToast(LLToast::Params p) : LLModalDialog(LLSD(), p.is_modal),
- mPanel(p.panel),
- mTimerValue(p.timer_period),
- mNotificationID(p.notif_id),
- mSessionID(p.session_id),
- mCanFade(p.can_fade),
- mCanBeStored(p.can_be_stored),
- mHideBtnEnabled(p.enable_hide_btn),
- mHideBtn(NULL),
- mNotification(p.notification),
- mHideBtnPressed(false)
+LLToast::Params::Params()
+: can_fade("can_fade", true),
+ can_be_stored("can_be_stored", true),
+ is_modal("is_modal", false),
+ is_tip("is_tip", false),
+ enable_hide_btn("enable_hide_btn", true),
+ force_show("force_show", false),
+ force_store("force_store", false),
+ lifetime_secs("lifetime_secs", gSavedSettings.getS32("NotificationToastLifeTime"))
+{};
+
+LLToast::LLToast(const LLToast::Params& p)
+: LLModalDialog(LLSD(), p.is_modal),
+ mPanel(p.panel),
+ mToastLifetime(p.lifetime_secs),
+ mNotificationID(p.notif_id),
+ mSessionID(p.session_id),
+ mCanFade(p.can_fade),
+ mCanBeStored(p.can_be_stored),
+ mHideBtnEnabled(p.enable_hide_btn),
+ mHideBtn(NULL),
+ mNotification(p.notification),
+ mHideBtnPressed(false)
{
LLUICtrlFactory::getInstance()->buildFloater(this, "panel_toast.xml", NULL);
@@ -67,11 +79,11 @@ LLToast::LLToast(LLToast::Params p) : LLModalDialog(LLSD(), p.is_modal),
}
// init callbacks if present
- if(!p.on_delete_toast.empty())
- mOnDeleteToastSignal.connect(p.on_delete_toast);
+ if(!p.on_delete_toast().empty())
+ mOnDeleteToastSignal.connect(p.on_delete_toast());
- if(!p.on_mouse_enter.empty())
- mOnMouseEnterSignal.connect(p.on_mouse_enter);
+ if(!p.on_mouse_enter().empty())
+ mOnMouseEnterSignal.connect(p.on_mouse_enter());
}
//--------------------------------------------------------------------------
@@ -103,22 +115,22 @@ void LLToast::setAndStartTimer(F32 period)
{
if(mCanFade)
{
- mTimerValue = period;
+ mToastLifetime = period;
mTimer.start();
}
}
//--------------------------------------------------------------------------
-bool LLToast::timerHasExpired()
+bool LLToast::lifetimeHasExpired()
{
if (mTimer.getStarted())
{
F32 elapsed_time = mTimer.getElapsedTimeF32();
- if (elapsed_time > gSavedSettings.getS32("ToastOpaqueTime"))
+ if ((mToastLifetime - elapsed_time) <= gSavedSettings.getS32("ToastOpaqueTime"))
{
setBackgroundOpaque(FALSE);
}
- if (elapsed_time > mTimerValue)
+ if (elapsed_time > mToastLifetime)
{
return true;
}
@@ -183,7 +195,7 @@ void LLToast::insertPanel(LLPanel* panel)
//--------------------------------------------------------------------------
void LLToast::draw()
{
- if(timerHasExpired())
+ if(lifetimeHasExpired())
{
tick();
}
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index 29c231a01d..1826c13ebc 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -57,37 +57,28 @@ public:
typedef boost::function<void (LLToast* toast)> toast_callback_t;
typedef boost::signals2::signal<void (LLToast* toast)> toast_signal_t;
- struct Params
+ struct Params : public LLInitParam::Block<Params>
{
- LLPanel* panel;
- LLUUID notif_id; //notification ID
- LLUUID session_id; //im session ID
- LLNotificationPtr notification;
- F32 timer_period;
- toast_callback_t on_delete_toast;
- toast_callback_t on_mouse_enter;
- bool can_fade;
- bool can_be_stored;
- bool enable_hide_btn;
- bool is_modal;
- bool is_tip;
- bool force_show;
- bool force_store;
-
- Params() : can_fade(true),
- can_be_stored(true),
- is_modal(false),
- is_tip(false),
- enable_hide_btn(true),
- force_show(false),
- force_store(false),
- panel(NULL),
- timer_period(gSavedSettings.getS32("NotificationToastTime"))
-
- {};
+ Mandatory<LLPanel*> panel;
+ Optional<LLUUID> notif_id, //notification ID
+ session_id; //im session ID
+ Optional<LLNotificationPtr> notification;
+ Optional<F32> lifetime_secs;
+ Optional<toast_callback_t> on_delete_toast,
+ on_mouse_enter;
+ Optional<bool> can_fade,
+ can_be_stored,
+ enable_hide_btn,
+ is_modal,
+ is_tip,
+ force_show,
+ force_store;
+
+
+ Params();
};
- LLToast(LLToast::Params p);
+ LLToast(const LLToast::Params& p);
virtual ~LLToast();
BOOL postBuild();
@@ -153,7 +144,7 @@ public:
private:
// check timer
- bool timerHasExpired();
+ bool lifetimeHasExpired();
// on timer finished function
void tick();
@@ -161,8 +152,9 @@ private:
LLUUID mSessionID;
LLNotificationPtr mNotification;
+ // timer counts a lifetime of a toast
LLTimer mTimer;
- F32 mTimerValue;
+ F32 mToastLifetime; // in seconds
LLPanel* mPanel;
LLButton* mHideBtn;
diff --git a/indra/newview/lltransientdockablefloater.cpp b/indra/newview/lltransientdockablefloater.cpp
new file mode 100644
index 0000000000..7e4d4988d1
--- /dev/null
+++ b/indra/newview/lltransientdockablefloater.cpp
@@ -0,0 +1,96 @@
+/**
+ * @file lltransientdockablefloater.cpp
+ * @brief Creates a panel of a specific kind for a toast
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, 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 "lltransientfloatermgr.h"
+#include "lltransientdockablefloater.h"
+#include "llfloaterreg.h"
+
+
+LLTransientDockableFloater::LLTransientDockableFloater(LLDockControl* dockControl, bool uniqueDocking,
+ const LLSD& key, const Params& params) :
+ LLDockableFloater(dockControl, uniqueDocking, key, params)
+{
+ LLTransientFloaterMgr::getInstance()->registerTransientFloater(this);
+}
+
+LLTransientDockableFloater::~LLTransientDockableFloater()
+{
+ LLTransientFloaterMgr::getInstance()->unregisterTransientFloater(this);
+}
+
+void LLTransientDockableFloater::setVisible(BOOL visible)
+{
+ LLView* dock = getDockWidget();
+ if(visible && isDocked())
+ {
+ LLTransientFloaterMgr::getInstance()->addControlView(this);
+ if (dock != NULL)
+ {
+ LLTransientFloaterMgr::getInstance()->addControlView(dock);
+ }
+ }
+ else
+ {
+ LLTransientFloaterMgr::getInstance()->removeControlView(this);
+ if (dock != NULL)
+ {
+ LLTransientFloaterMgr::getInstance()->removeControlView(dock);
+ }
+ }
+
+ LLDockableFloater::setVisible(visible);
+}
+
+void LLTransientDockableFloater::setDocked(bool docked, bool pop_on_undock)
+{
+ LLView* dock = getDockWidget();
+ if(docked)
+ {
+ LLTransientFloaterMgr::getInstance()->addControlView(this);
+ if (dock != NULL)
+ {
+ LLTransientFloaterMgr::getInstance()->addControlView(dock);
+ }
+ }
+ else
+ {
+ LLTransientFloaterMgr::getInstance()->removeControlView(this);
+ if (dock != NULL)
+ {
+ LLTransientFloaterMgr::getInstance()->removeControlView(dock);
+ }
+ }
+
+ LLDockableFloater::setDocked(docked, pop_on_undock);
+}
diff --git a/indra/newview/lltransientdockablefloater.h b/indra/newview/lltransientdockablefloater.h
new file mode 100644
index 0000000000..6e8a3afd22
--- /dev/null
+++ b/indra/newview/lltransientdockablefloater.h
@@ -0,0 +1,57 @@
+/**
+ * @file lltransientdockablefloater.h
+ * @brief Creates a panel of a specific kind for a toast.
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, 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_TRANSIENTDOCKABLEFLOATER_H
+#define LL_TRANSIENTDOCKABLEFLOATER_H
+
+#include "llerror.h"
+#include "llfloater.h"
+#include "lldockcontrol.h"
+#include "lldockablefloater.h"
+
+/**
+ * Represents floater that can dock and managed by transient floater manager.
+ * Transient floaters should be hidden if user click anywhere except defined view list.
+ */
+class LLTransientDockableFloater : public LLDockableFloater
+{
+public:
+ LOG_CLASS(LLTransientDockableFloater);
+ LLTransientDockableFloater(LLDockControl* dockControl, bool uniqueDocking,
+ const LLSD& key, const Params& params = getDefaultParams());
+ virtual ~LLTransientDockableFloater();
+
+ /*virtual*/ void setVisible(BOOL visible);
+ /* virtual */void setDocked(bool docked, bool pop_on_undock = true);
+};
+
+#endif /* LL_TRANSIENTDOCKABLEFLOATER_H */
diff --git a/indra/newview/lltransientfloatermgr.cpp b/indra/newview/lltransientfloatermgr.cpp
new file mode 100644
index 0000000000..7befb87248
--- /dev/null
+++ b/indra/newview/lltransientfloatermgr.cpp
@@ -0,0 +1,110 @@
+/**
+ * @file lltransientfloatermgr.cpp
+ * @brief LLFocusMgr base class
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, 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 "lltransientfloatermgr.h"
+#include "llfocusmgr.h"
+#include "llrootview.h"
+#include "llviewerwindow.h"
+#include "lldockablefloater.h"
+
+
+LLTransientFloaterMgr::LLTransientFloaterMgr()
+{
+ gViewerWindow->getRootView()->addMouseDownCallback(boost::bind(
+ &LLTransientFloaterMgr::leftMouseClickCallback, this, _1, _2, _3));
+}
+
+void LLTransientFloaterMgr::registerTransientFloater(LLFloater* floater)
+{
+ mTransSet.insert(floater);
+}
+
+void LLTransientFloaterMgr::unregisterTransientFloater(LLFloater* floater)
+{
+ mTransSet.erase(floater);
+}
+
+void LLTransientFloaterMgr::addControlView(LLView* view)
+{
+ mControlsSet.insert(view);
+}
+
+void LLTransientFloaterMgr::removeControlView(LLView* view)
+{
+ // we will still get focus lost callbacks on this view, but that's ok
+ // since we run sanity checking logic every time
+ mControlsSet.erase(view);
+}
+
+void LLTransientFloaterMgr::hideTransientFloaters()
+{
+ for (std::set<LLFloater*>::iterator it = mTransSet.begin(); it
+ != mTransSet.end(); it++)
+ {
+ LLFloater* floater = *it;
+ if (floater->isDocked())
+ {
+ floater->setVisible(FALSE);
+ }
+ }
+}
+
+void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y,
+ MASK mask)
+{
+ bool hide = true;
+ for (controls_set_t::iterator it = mControlsSet.begin(); it
+ != mControlsSet.end(); it++)
+ {
+ LLView* control_view = *it;
+ if (!control_view->getVisible())
+ {
+ continue;
+ }
+
+ LLRect rect = control_view->calcScreenRect();
+ // if click inside view rect
+ if (rect.pointInRect(x, y))
+ {
+ hide = false;
+ break;
+ }
+ }
+
+ if (hide)
+ {
+ hideTransientFloaters();
+ }
+}
+
diff --git a/indra/newview/lltransientfloatermgr.h b/indra/newview/lltransientfloatermgr.h
new file mode 100644
index 0000000000..cef6e1fe45
--- /dev/null
+++ b/indra/newview/lltransientfloatermgr.h
@@ -0,0 +1,63 @@
+/**
+ * @file lltransientfloatermgr.h
+ * @brief LLFocusMgr base class
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, 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_LLTRANSIENTFLOATERMGR_H
+#define LL_LLTRANSIENTFLOATERMGR_H
+
+#include "llui.h"
+#include "llsingleton.h"
+#include "llfloater.h"
+
+
+/**
+ * Provides functionality to hide transient floaters.
+ */
+class LLTransientFloaterMgr: public LLSingleton<LLTransientFloaterMgr>
+{
+public:
+ LLTransientFloaterMgr();
+ void registerTransientFloater(LLFloater* floater);
+ void unregisterTransientFloater(LLFloater* floater);
+ void addControlView(LLView* view);
+ void removeControlView(LLView* view);
+
+private:
+ void hideTransientFloaters();
+ void leftMouseClickCallback(S32 x, S32 y, MASK mask);
+
+private:
+ std::set<LLFloater*> mTransSet;
+ typedef std::set<LLView*> controls_set_t;
+ controls_set_t mControlsSet;
+};
+
+#endif // LL_LLTRANSIENTFLOATERMGR_H
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 81917ec76e..9ccff0c44e 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -190,7 +190,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("syswell_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLSysWellWindow>);
LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationConsole>);
- LLFloaterReg::add("nearby_chat", "floater_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>);
LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>);
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 7e88320f49..1ad60d9a97 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -990,7 +990,7 @@ const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not
const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably not)
const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not)
-void menu_create_inventory_item(LLFolderView* folder, LLFolderBridge *bridge, const LLSD& userdata)
+void menu_create_inventory_item(LLFolderView* folder, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid)
{
std::string type = userdata.asString();
@@ -1003,15 +1003,22 @@ void menu_create_inventory_item(LLFolderView* folder, LLFolderBridge *bridge, co
a_type = LLAssetType::AT_OUTFIT;
if ("my_otfts" == type)
a_type = LLAssetType::AT_MY_OUTFITS;
- LLUUID category;
+
+ LLUUID parent_id;
if (bridge)
{
- category = gInventory.createNewCategory(bridge->getUUID(), a_type, LLStringUtil::null);
+ parent_id = bridge->getUUID();
+ }
+ else if (default_parent_uuid.notNull())
+ {
+ parent_id = default_parent_uuid;
}
else
{
- category = gInventory.createNewCategory(gInventory.getRootFolderID(), a_type, LLStringUtil::null);
+ parent_id = gInventory.getRootFolderID();
}
+
+ LLUUID category = gInventory.createNewCategory(parent_id, a_type, LLStringUtil::null);
gInventory.notifyObservers();
folder->setSelectionByID(category, TRUE);
}
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index f55a695652..d523bf2859 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -341,6 +341,7 @@ void copy_inventory_from_notecard(const LLUUID& object_id,
void menu_create_inventory_item(LLFolderView* folder,
LLFolderBridge* bridge,
- const LLSD& userdata);
+ const LLSD& userdata,
+ const LLUUID& default_parent_uuid = LLUUID::null);
#endif // LL_LLVIEWERINVENTORY_H
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index cb4f4de05e..01d45d0d49 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -3450,6 +3450,15 @@ bool enable_standup_self()
return new_value;
}
+// Used from the login screen to aid in UI work on side tray
+void handle_show_side_tray()
+{
+ LLSideTray* side_tray = LLSideTray::getInstance();
+ LLView* root = gViewerWindow->getRootView();
+ // automatically removes and re-adds if there already
+ root->addChild(side_tray);
+}
+
class LLSelfFriends : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -7934,7 +7943,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedCheckDebugKeys(), "Advanced.CheckDebugKeys");
view_listener_t::addMenu(new LLAdvancedToggleDebugWindowProc(), "Advanced.ToggleDebugWindowProc");
view_listener_t::addMenu(new LLAdvancedCheckDebugWindowProc(), "Advanced.CheckDebugWindowProc");
-
+ commit.add("Advanced.ShowSideTray", boost::bind(&handle_show_side_tray));
// Advanced > XUI
commit.add("Advanced.ReloadColorSettings", boost::bind(&LLUIColorTable::loadFromSettings, LLUIColorTable::getInstance()));
diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h
index 21d4c72428..bb317aeb5f 100644
--- a/indra/newview/llviewerprecompiledheaders.h
+++ b/indra/newview/llviewerprecompiledheaders.h
@@ -105,7 +105,6 @@
#include "llstl.h"
#include "llstrider.h"
#include "llstring.h"
-#include "llstringtable.h"
#include "llsys.h"
#include "llthread.h"
#include "lltimer.h"
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index dac2331ca3..4ad4c8e1ea 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -1474,7 +1474,7 @@ bool LLUIImageList::initFromFile()
}
UIImageDeclarations images;
- LLXUIParser::instance().readXUI(root, images);
+ LLXUIParser::instance().readXUI(root, images, base_file_path);
if (!images.validateBlock()) return false;
diff --git a/indra/newview/llviewervisualparam.h b/indra/newview/llviewervisualparam.h
index 82a694e277..3550a46fbf 100644
--- a/indra/newview/llviewervisualparam.h
+++ b/indra/newview/llviewervisualparam.h
@@ -83,7 +83,7 @@ public:
// This sets mInfo and calls initialization functions
BOOL setInfo(LLViewerVisualParamInfo *info);
- virtual LLViewerVisualParam * cloneParam(LLWearable* wearable) const = 0;
+ virtual LLViewerVisualParam* cloneParam(LLWearable* wearable) const = 0;
// LLVisualParam Virtual functions
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 76e00db91c..0dcd164d83 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -792,7 +792,8 @@ LLVOAvatar::~LLVOAvatar()
mMeshes.clear();
for (std::vector<LLViewerJoint*>::iterator jointIter = mMeshLOD.begin();
- jointIter != mMeshLOD.end(); jointIter++)
+ jointIter != mMeshLOD.end();
+ ++jointIter)
{
LLViewerJoint* joint = (LLViewerJoint *) *jointIter;
std::for_each(joint->mMeshParts.begin(), joint->mMeshParts.end(), DeletePointer());
@@ -943,7 +944,7 @@ void LLVOAvatar::dumpBakedStatus()
for (LLVOAvatarDictionary::BakedTextures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
- iter++)
+ ++iter)
{
const LLVOAvatarDictionary::BakedEntry *baked_dict = iter->second;
const ETextureIndex index = baked_dict->mTextureIndex;
@@ -1135,7 +1136,7 @@ void LLVOAvatar::initInstance(void)
for (LLVOAvatarDictionary::Meshes::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
- iter++)
+ ++iter)
{
const EMeshIndex mesh_index = iter->first;
const LLVOAvatarDictionary::MeshEntry *mesh_dict = iter->second;
@@ -1181,7 +1182,7 @@ void LLVOAvatar::initInstance(void)
//-------------------------------------------------------------------------
for (LLVOAvatarDictionary::Meshes::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
- iter++)
+ ++iter)
{
const EMeshIndex mesh_index = iter->first;
const LLVOAvatarDictionary::MeshEntry *mesh_dict = iter->second;
@@ -1190,7 +1191,8 @@ void LLVOAvatar::initInstance(void)
if (baked_texture_index == BAKED_NUM_INDICES) continue;
for (std::vector<LLViewerJointMesh* >::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin();
- iter != mMeshLOD[mesh_index]->mMeshParts.end(); iter++)
+ iter != mMeshLOD[mesh_index]->mMeshParts.end();
+ ++iter)
{
LLViewerJointMesh* mesh = (LLViewerJointMesh*) *iter;
mBakedTextureDatas[(int)baked_texture_index].mMeshes.push_back(mesh);
@@ -1576,7 +1578,7 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent
// setup children
LLVOAvatarBoneInfo::child_list_t::const_iterator iter;
- for (iter = info->mChildList.begin(); iter != info->mChildList.end(); iter++)
+ for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter)
{
LLVOAvatarBoneInfo *child_info = *iter;
if (!setupBone(child_info, joint, volume_num, joint_num))
@@ -1619,7 +1621,7 @@ BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info)
S32 current_joint_num = 0;
S32 current_volume_num = 0;
LLVOAvatarSkeletonInfo::bone_info_list_t::const_iterator iter;
- for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); iter++)
+ for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter)
{
LLVOAvatarBoneInfo *info = *iter;
if (!setupBone(info, NULL, current_volume_num, current_joint_num))
@@ -1682,11 +1684,11 @@ void LLVOAvatar::buildCharacter()
// clear mesh data
//-------------------------------------------------------------------------
for (std::vector<LLViewerJoint*>::iterator jointIter = mMeshLOD.begin();
- jointIter != mMeshLOD.end(); jointIter++)
+ jointIter != mMeshLOD.end(); ++jointIter)
{
LLViewerJoint* joint = (LLViewerJoint*) *jointIter;
for (std::vector<LLViewerJointMesh*>::iterator meshIter = joint->mMeshParts.begin();
- meshIter != joint->mMeshParts.end(); meshIter++)
+ meshIter != joint->mMeshParts.end(); ++meshIter)
{
LLViewerJointMesh * mesh = (LLViewerJointMesh *) *meshIter;
mesh->setMesh(NULL);
@@ -1831,7 +1833,8 @@ void LLVOAvatar::releaseMeshData()
// cleanup mesh data
for (std::vector<LLViewerJoint*>::iterator iter = mMeshLOD.begin();
- iter != mMeshLOD.end(); iter++)
+ iter != mMeshLOD.end();
+ ++iter)
{
LLViewerJoint* joint = (LLViewerJoint*) *iter;
joint->setValid(FALSE, TRUE);
@@ -1850,10 +1853,10 @@ void LLVOAvatar::releaseMeshData()
}
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerJointAttachment* attachment = iter->second;
if (!attachment->getIsHUDAttachment())
{
attachment->setAttachmentVisibility(FALSE);
@@ -1876,10 +1879,10 @@ void LLVOAvatar::restoreMeshData()
updateJointLODs();
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerJointAttachment* attachment = iter->second;
if (!attachment->getIsHUDAttachment())
{
attachment->setAttachmentVisibility(TRUE);
@@ -2328,10 +2331,10 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
{
LLFastTimer t(FTM_ATTACHMENT_UPDATE);
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerJointAttachment* attachment = iter->second;
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
attachment_iter != attachment->mAttachedObjects.end();
@@ -3554,10 +3557,10 @@ void LLVOAvatar::updateVisibility()
/*llinfos << "SPA: " << sel_pos_agent << llendl;
llinfos << "WPA: " << wrist_right_pos_agent << llendl;*/
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerJointAttachment* attachment = iter->second;
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
attachment_iter != attachment->mAttachedObjects.end();
@@ -3989,32 +3992,32 @@ void LLVOAvatar::updateTextures(LLAgent &agent)
mMaxPixelArea = 0.f;
mMinPixelArea = 99999999.f;
mHasGrey = FALSE; // debug
- for (U32 texture = 0; texture < getNumTEs(); texture++)
+ for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
{
- EWearableType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)texture);
+ EWearableType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)texture_index);
U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
- const LLTextureEntry *te = getTE(texture);
+ const LLTextureEntry *te = getTE(texture_index);
const F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT);
LLViewerFetchedTexture *imagep = NULL;
for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++)
{
- imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture, wearable_index), TRUE);
+ imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE);
if (imagep)
{
- const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)texture);
+ const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)texture_index);
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
if (texture_dict->mIsLocalTexture)
{
- addLocalTextureStats((ETextureIndex)texture, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]);
+ addLocalTextureStats((ETextureIndex)texture_index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]);
}
}
}
- if (isIndexBakedTexture((ETextureIndex) texture))
+ if (isIndexBakedTexture((ETextureIndex) texture_index))
{
const S32 boost_level = getAvatarBakedBoostLevel();
- imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture,0), TRUE);
+ imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE);
// Spam if this is a baked texture, not set to default image, without valid host info
- if (isIndexBakedTexture((ETextureIndex)texture)
+ if (isIndexBakedTexture((ETextureIndex)texture_index)
&& imagep->getID() != IMG_DEFAULT_AVATAR
&& !imagep->getTargetHost().isOk())
{
@@ -4731,7 +4734,7 @@ BOOL LLVOAvatar::loadAvatar()
// avatar_lad.xml : <morph_masks>
for (LLVOAvatarXmlInfo::morph_info_list_t::iterator iter = sAvatarXmlInfo->mMorphMaskInfoList.begin();
iter != sAvatarXmlInfo->mMorphMaskInfoList.end();
- iter++)
+ ++iter)
{
LLVOAvatarXmlInfo::LLVOAvatarMorphInfo *info = *iter;
@@ -4755,7 +4758,7 @@ BOOL LLVOAvatar::loadAvatar()
// avatar_lad.xml : <driver_parameters>
for (LLVOAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin();
iter != sAvatarXmlInfo->mDriverInfoList.end();
- iter++)
+ ++iter)
{
LLDriverParamInfo *info = *iter;
LLDriverParam* driver_param = new LLDriverParam( this );
@@ -4801,7 +4804,8 @@ BOOL LLVOAvatar::loadSkeletonNode ()
mRoot.addChild( &mSkeleton[0] );
for (std::vector<LLViewerJoint *>::iterator iter = mMeshLOD.begin();
- iter != mMeshLOD.end(); iter++)
+ iter != mMeshLOD.end();
+ ++iter)
{
LLViewerJoint *joint = (LLViewerJoint *) *iter;
joint->mUpdateXform = FALSE;
@@ -4837,7 +4841,8 @@ BOOL LLVOAvatar::loadSkeletonNode ()
{
LLVOAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter;
for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin();
- iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end(); iter++)
+ iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end();
+ ++iter)
{
LLPolySkeletalDistortionInfo *info = *iter;
LLPolySkeletalDistortion *param = new LLPolySkeletalDistortion(this);
@@ -4857,7 +4862,8 @@ BOOL LLVOAvatar::loadSkeletonNode ()
{
LLVOAvatarXmlInfo::attachment_info_list_t::iterator iter;
for (iter = sAvatarXmlInfo->mAttachmentInfoList.begin();
- iter != sAvatarXmlInfo->mAttachmentInfoList.end(); iter++)
+ iter != sAvatarXmlInfo->mAttachmentInfoList.end();
+ ++iter)
{
LLVOAvatarXmlInfo::LLVOAvatarAttachmentInfo *info = *iter;
if (!isSelf() && info->mJointName == "mScreen")
@@ -4938,7 +4944,7 @@ BOOL LLVOAvatar::loadMeshNodes()
{
for (LLVOAvatarXmlInfo::mesh_info_list_t::const_iterator meshinfo_iter = sAvatarXmlInfo->mMeshInfoList.begin();
meshinfo_iter != sAvatarXmlInfo->mMeshInfoList.end();
- meshinfo_iter++)
+ ++meshinfo_iter)
{
const LLVOAvatarXmlInfo::LLVOAvatarMeshInfo *info = *meshinfo_iter;
const std::string &type = info->mType;
@@ -4954,7 +4960,7 @@ BOOL LLVOAvatar::loadMeshNodes()
mesh = &mHairMesh0; */
for (LLVOAvatarDictionary::Meshes::const_iterator mesh_iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
mesh_iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
- mesh_iter++)
+ ++mesh_iter)
{
const EMeshIndex mesh_index = mesh_iter->first;
const LLVOAvatarDictionary::MeshEntry *mesh_dict = mesh_iter->second;
@@ -5026,7 +5032,7 @@ BOOL LLVOAvatar::loadMeshNodes()
for (LLVOAvatarXmlInfo::LLVOAvatarMeshInfo::morph_info_list_t::const_iterator xmlinfo_iter = info->mPolyMorphTargetInfoList.begin();
xmlinfo_iter != info->mPolyMorphTargetInfoList.end();
- xmlinfo_iter++)
+ ++xmlinfo_iter)
{
const LLVOAvatarXmlInfo::LLVOAvatarMeshInfo::morph_info_pair_t *info_pair = &(*xmlinfo_iter);
LLPolyMorphTarget *param = new LLPolyMorphTarget(mesh->getMesh());
@@ -5060,7 +5066,7 @@ BOOL LLVOAvatar::loadLayersets()
BOOL success = TRUE;
for (LLVOAvatarXmlInfo::layer_info_list_t::const_iterator layerset_iter = sAvatarXmlInfo->mLayerInfoList.begin();
layerset_iter != sAvatarXmlInfo->mLayerInfoList.end();
- layerset_iter++)
+ ++layerset_iter)
{
// Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
LLTexLayerSetInfo *layerset_info = *layerset_iter;
@@ -5467,7 +5473,7 @@ U32 LLVOAvatar::getNumAttachments() const
U32 num_attachments = 0;
for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
- iter++)
+ ++iter)
{
const LLViewerJointAttachment *attachment_pt = (*iter).second;
num_attachments += attachment_pt->getNumObjects();
@@ -5508,10 +5514,10 @@ void LLVOAvatar::lazyAttach()
void LLVOAvatar::resetHUDAttachments()
{
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerJointAttachment* attachment = iter->second;
if (attachment->getIsHUDAttachment())
{
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
@@ -5534,55 +5540,15 @@ void LLVOAvatar::resetHUDAttachments()
BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)
{
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerJointAttachment* attachment = iter->second;
if (attachment->isObjectAttached(viewer_object))
{
- LLUUID item_id = viewer_object->getItemID();
attachment->removeObject(viewer_object);
- if (isSelf())
- {
- // the simulator should automatically handle
- // permission revocation
-
- stopMotionFromSource(viewer_object->getID());
- LLFollowCamMgr::setCameraActive(viewer_object->getID(), FALSE);
-
- LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* child_objectp = *iter;
- // the simulator should automatically handle
- // permissions revocation
-
- stopMotionFromSource(child_objectp->getID());
- LLFollowCamMgr::setCameraActive(child_objectp->getID(), FALSE);
- }
- }
lldebugs << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << llendl;
- if (isSelf())
- {
- // Then make sure the inventory is in sync with the avatar.
-
- // Update COF contents, don't trigger appearance update.
- if (gAgent.getAvatarObject() == NULL)
- {
- llinfos << "removeItemLinks skipped, avatar is under destruction" << llendl;
- }
- else
- {
- LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Removing attachment link:");
- LLAppearanceManager::removeItemLinks(item_id, false);
- }
-
- // BAP - needs to change for label to track link.
- gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
- gInventory.notifyObservers();
- }
return TRUE;
}
}
@@ -5667,7 +5633,7 @@ void LLVOAvatar::getOffObject()
LLViewerObject::const_child_list_t& child_list = sit_object->getChildren();
for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
+ iter != child_list.end(); ++iter)
{
LLViewerObject* child_objectp = *iter;
@@ -6008,14 +5974,14 @@ void LLVOAvatar::updateMeshTextures()
for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
- baked_iter++)
+ ++baked_iter)
{
const EBakedTextureIndex baked_index = baked_iter->first;
const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
- local_tex_iter++)
+ ++local_tex_iter)
{
const ETextureIndex texture_index = *local_tex_iter;
const BOOL is_baked_ready = (is_layer_baked[baked_index] && mBakedTextureDatas[baked_index].mIsLoaded) || other_culled;
@@ -6039,7 +6005,7 @@ void LLVOAvatar::setLocalTexture( ETextureIndex type, LLViewerTexture* in_tex, B
}
//virtual
-void LLVOAvatar::setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
+void LLVOAvatar::setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
{
// invalid for anyone but self
llassert(0);
@@ -6131,7 +6097,7 @@ void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_com
}
for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin();
- iter != mBakedTextureDatas[index].mMaskedMorphs.end(); iter++)
+ iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter)
{
const LLMaskedMorph* maskedMorph = (*iter);
maskedMorph->mMorphTarget->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert);
@@ -6283,7 +6249,7 @@ void LLVOAvatar::dumpAvatarTEs( const std::string& context )
llinfos << (isSelf() ? "Self: " : "Other: ") << context << llendl;
for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
- iter++)
+ ++iter)
{
const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
// TODO: handle multiple textures for self
@@ -6332,7 +6298,7 @@ BOOL LLVOAvatar::isWearingWearableType(EWearableType type) const
indicator_te = TEX_UPPER_SHIRT; */
for (LLVOAvatarDictionary::Textures::const_iterator tex_iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
tex_iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
- tex_iter++)
+ ++tex_iter)
{
const LLVOAvatarDictionary::TextureEntry *texture_dict = tex_iter->second;
if (texture_dict->mWearableType == type)
@@ -6363,10 +6329,10 @@ void LLVOAvatar::clampAttachmentPositions()
return;
}
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerJointAttachment* attachment = iter->second;
if (attachment)
{
attachment->clampObjectPosition();
@@ -6377,10 +6343,10 @@ void LLVOAvatar::clampAttachmentPositions()
BOOL LLVOAvatar::hasHUDAttachment() const
{
for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::const_iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerJointAttachment* attachment = iter->second;
if (attachment->getIsHUDAttachment() && attachment->getNumObjects() > 0)
{
return TRUE;
@@ -6393,10 +6359,10 @@ LLBBox LLVOAvatar::getHUDBBox() const
{
LLBBox bbox;
for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::const_iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerJointAttachment* attachment = iter->second;
if (attachment->getIsHUDAttachment())
{
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
@@ -6410,7 +6376,8 @@ LLBBox LLVOAvatar::getHUDBBox() const
bbox.addBBoxAgent(attached_object->getBoundingBoxAgent());
LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
+ iter != child_list.end();
+ ++iter)
{
const LLViewerObject* child_objectp = *iter;
bbox.addBBoxAgent(child_objectp->getBoundingBoxAgent());
@@ -6691,7 +6658,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
BOOL found_texture_id = false;
for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
- iter++)
+ ++iter)
{
const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
@@ -6802,9 +6769,9 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
- local_tex_iter++)
+ ++local_tex_iter)
{
- this->setBakedReady(*local_tex_iter, TRUE);
+ setBakedReady(*local_tex_iter, TRUE);
}
// ! BACKWARDS COMPATIBILITY !
@@ -7697,7 +7664,7 @@ const std::string LLVOAvatar::getBakedStatusForPrintout() const
for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
- iter++)
+ ++iter)
{
const ETextureIndex index = iter->first;
const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
@@ -7802,7 +7769,8 @@ U32 calc_shame(const LLVOVolume* volume, std::set<LLUUID> &textures)
LLViewerObject::const_child_list_t& child_list = volume->getChildren();
for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
+ iter != child_list.end();
+ ++iter)
{
const LLViewerObject* child_objectp = *iter;
const LLDrawable* child_drawablep = child_objectp->mDrawable;
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 1180d43438..27f2c77817 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -649,7 +649,7 @@ public:
public:
void clampAttachmentPositions();
virtual const LLViewerJointAttachment* attachObject(LLViewerObject *viewer_object);
- BOOL detachObject(LLViewerObject *viewer_object);
+ virtual BOOL detachObject(LLViewerObject *viewer_object);
static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj);
protected:
LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 99e358f409..de2c30f1a1 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -296,10 +296,10 @@ BOOL LLVOAvatarSelf::buildMenus()
{
BOOL attachment_found = FALSE;
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerJointAttachment* attachment = iter->second;
if (attachment->getGroup() == i)
{
LLMenuItemCallGL::Params item_params;
@@ -315,9 +315,9 @@ BOOL LLVOAvatarSelf::buildMenus()
}
item_params.name =(item_params.label );
item_params.on_click.function_name = "Object.AttachToAvatar";
- item_params.on_click.parameter = curiter->first;
+ item_params.on_click.parameter = iter->first;
item_params.on_enable.function_name = "Object.EnableWear";
- item_params.on_enable.parameter = curiter->first;
+ item_params.on_enable.parameter = iter->first;
LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
gAttachPieMenu->addChild(item);
@@ -342,10 +342,10 @@ BOOL LLVOAvatarSelf::buildMenus()
{
BOOL attachment_found = FALSE;
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerJointAttachment* attachment = iter->second;
if (attachment->getGroup() == i)
{
LLMenuItemCallGL::Params item_params;
@@ -360,9 +360,9 @@ BOOL LLVOAvatarSelf::buildMenus()
}
item_params.name =(item_params.label );
item_params.on_click.function_name = "Attachment.Detach";
- item_params.on_click.parameter = curiter->first;
+ item_params.on_click.parameter = iter->first;
item_params.on_enable.function_name = "Attachment.EnableDetach";
- item_params.on_enable.parameter = curiter->first;
+ item_params.on_enable.parameter = iter->first;
LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
gDetachPieMenu->addChild(item);
@@ -381,10 +381,10 @@ BOOL LLVOAvatarSelf::buildMenus()
// add screen attachments
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerJointAttachment* attachment = iter->second;
if (attachment->getGroup() == 8)
{
LLMenuItemCallGL::Params item_params;
@@ -399,16 +399,16 @@ BOOL LLVOAvatarSelf::buildMenus()
}
item_params.name =(item_params.label );
item_params.on_click.function_name = "Object.AttachToAvatar";
- item_params.on_click.parameter = curiter->first;
+ item_params.on_click.parameter = iter->first;
item_params.on_enable.function_name = "Object.EnableWear";
- item_params.on_enable.parameter = curiter->first;
+ item_params.on_enable.parameter = iter->first;
LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
gAttachScreenPieMenu->addChild(item);
item_params.on_click.function_name = "Attachment.DetachFromPoint";
- item_params.on_click.parameter = curiter->first;
+ item_params.on_click.parameter = iter->first;
item_params.on_enable.function_name = "Attachment.PointFilled";
- item_params.on_enable.parameter = curiter->first;
+ item_params.on_enable.parameter = iter->first;
item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
gDetachScreenPieMenu->addChild(item);
}
@@ -422,10 +422,10 @@ BOOL LLVOAvatarSelf::buildMenus()
break;
}
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerJointAttachment* attachment = iter->second;
if (attachment->getIsHUDAttachment() != (pass == 1))
{
continue;
@@ -442,12 +442,12 @@ BOOL LLVOAvatarSelf::buildMenus()
}
item_params.name =(item_params.label );
item_params.on_click.function_name = "Object.AttachToAvatar";
- item_params.on_click.parameter = curiter->first;
+ item_params.on_click.parameter = iter->first;
item_params.on_enable.function_name = "Object.EnableWear";
- item_params.on_enable.parameter = curiter->first;
+ item_params.on_enable.parameter = iter->first;
//* TODO: Skinning:
//LLSD params;
- //params["index"] = curiter->first;
+ //params["index"] = iter->first;
//params["label"] = attachment->getName();
//item->addEventHandler("on_enable", LLMenuItemCallGL::MenuCallback().function_name("Attachment.Label").parameter(params));
@@ -455,9 +455,9 @@ BOOL LLVOAvatarSelf::buildMenus()
gAttachSubMenu->addChild(item);
item_params.on_click.function_name = "Attachment.DetachFromPoint";
- item_params.on_click.parameter = curiter->first;
+ item_params.on_click.parameter = iter->first;
item_params.on_enable.function_name = "Attachment.PointFilled";
- item_params.on_enable.parameter = curiter->first;
+ item_params.on_enable.parameter = iter->first;
//* TODO: Skinning: item->addEventHandler("on_enable", LLMenuItemCallGL::MenuCallback().function_name("Attachment.Label").parameter(params));
item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
@@ -483,15 +483,15 @@ BOOL LLVOAvatarSelf::buildMenus()
// gather up all attachment points assigned to this group, and throw into map sorted by pie slice number
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerJointAttachment* attachment = iter->second;
if(attachment->getGroup() == group)
{
// use multimap to provide a partial order off of the pie slice key
S32 pie_index = attachment->getPieSlice();
- attachment_pie_menu_map.insert(std::make_pair(pie_index, curiter->first));
+ attachment_pie_menu_map.insert(std::make_pair(pie_index, iter->first));
}
}
@@ -556,7 +556,7 @@ BOOL LLVOAvatarSelf::loadLayersets()
BOOL success = TRUE;
for (LLVOAvatarXmlInfo::layer_info_list_t::const_iterator iter = sAvatarXmlInfo->mLayerInfoList.begin();
iter != sAvatarXmlInfo->mLayerInfoList.end();
- iter++)
+ ++iter)
{
// Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
const LLTexLayerSetInfo *info = *iter;
@@ -574,7 +574,7 @@ BOOL LLVOAvatarSelf::loadLayersets()
EBakedTextureIndex baked_index = BAKED_NUM_INDICES;
for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
- baked_iter++)
+ ++baked_iter)
{
const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
if (layer_set->isBodyRegion(baked_dict->mName))
@@ -597,7 +597,7 @@ BOOL LLVOAvatarSelf::loadLayersets()
// scan morph masks and let any affected layers know they have an associated morph
for (LLVOAvatar::morph_list_t::const_iterator morph_iter = mBakedTextureDatas[baked_index].mMaskedMorphs.begin();
morph_iter != mBakedTextureDatas[baked_index].mMaskedMorphs.end();
- morph_iter++)
+ ++morph_iter)
{
LLMaskedMorph *morph = *morph_iter;
LLTexLayerInterface* layer = layer_set->findLayerByName(morph->mLayer);
@@ -704,6 +704,13 @@ void LLVOAvatarSelf::updateVisualParams()
}
}
+ LLWearable *shape = gAgentWearables.getWearable(WT_SHAPE,0);
+ if (shape)
+ {
+ F32 gender = shape->getVisualParamWeight(80); // param 80 == gender
+ setVisualParamWeight("male",gender ,TRUE);
+ }
+
LLVOAvatar::updateVisualParams();
}
@@ -907,10 +914,10 @@ void LLVOAvatarSelf::restoreMeshData()
void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode)
{
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerJointAttachment* attachment = iter->second;
if (attachment->getIsHUDAttachment())
{
attachment->setAttachmentVisibility(TRUE);
@@ -951,7 +958,7 @@ void LLVOAvatarSelf::wearableUpdated( EWearableType type )
{
for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
- baked_iter++)
+ ++baked_iter)
{
const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
const LLVOAvatarDefines::EBakedTextureIndex index = baked_iter->first;
@@ -959,7 +966,7 @@ void LLVOAvatarSelf::wearableUpdated( EWearableType type )
{
for (LLVOAvatarDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin();
type_iter != baked_dict->mWearables.end();
- type_iter++)
+ ++type_iter)
{
const EWearableType comp_type = *type_iter;
if (comp_type == type)
@@ -980,14 +987,16 @@ void LLVOAvatarSelf::wearableUpdated( EWearableType type )
// isWearingAttachment()
//-----------------------------------------------------------------------------
// Warning: include_linked_items = TRUE makes this operation expensive.
-BOOL LLVOAvatarSelf::isWearingAttachment( const LLUUID& inv_item_id , BOOL include_linked_items ) const
+BOOL LLVOAvatarSelf::isWearingAttachment(const LLUUID& inv_item_id, BOOL include_linked_items) const
{
+ const LLUUID& base_inv_item_id = getBaseAttachmentObject(inv_item_id);
+
for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::const_iterator curiter = iter++;
- const LLViewerJointAttachment* attachment = curiter->second;
- if (attachment->getAttachedObject(inv_item_id))
+ const LLViewerJointAttachment* attachment = iter->second;
+ if (attachment->getAttachedObject(base_inv_item_id))
{
return TRUE;
}
@@ -996,18 +1005,18 @@ BOOL LLVOAvatarSelf::isWearingAttachment( const LLUUID& inv_item_id , BOOL inclu
if (include_linked_items)
{
LLInventoryModel::item_array_t item_array;
- gInventory.collectLinkedItems(inv_item_id, item_array);
+ gInventory.collectLinkedItems(base_inv_item_id, item_array);
for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
iter != item_array.end();
- iter++)
+ ++iter)
{
const LLViewerInventoryItem *linked_item = (*iter);
const LLUUID &item_id = linked_item->getUUID();
for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::const_iterator curiter = iter++;
- const LLViewerJointAttachment* attachment = curiter->second;
+ const LLViewerJointAttachment* attachment = iter->second;
if (attachment->getAttachedObject(item_id))
{
return TRUE;
@@ -1022,14 +1031,15 @@ BOOL LLVOAvatarSelf::isWearingAttachment( const LLUUID& inv_item_id , BOOL inclu
//-----------------------------------------------------------------------------
// getWornAttachment()
//-----------------------------------------------------------------------------
-LLViewerObject* LLVOAvatarSelf::getWornAttachment( const LLUUID& inv_item_id )
+LLViewerObject* LLVOAvatarSelf::getWornAttachment(const LLUUID& inv_item_id)
{
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ const LLUUID& base_inv_item_id = getBaseAttachmentObject(inv_item_id);
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if (LLViewerObject *attached_object = attachment->getAttachedObject(inv_item_id))
+ LLViewerJointAttachment* attachment = iter->second;
+ if (LLViewerObject *attached_object = attachment->getAttachedObject(base_inv_item_id))
{
return attached_object;
}
@@ -1039,12 +1049,13 @@ LLViewerObject* LLVOAvatarSelf::getWornAttachment( const LLUUID& inv_item_id )
const std::string LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id) const
{
+ const LLUUID& base_inv_item_id = getBaseAttachmentObject(inv_item_id);
for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- attachment_map_t::const_iterator curiter = iter++;
- const LLViewerJointAttachment* attachment = curiter->second;
- if (attachment->getAttachedObject(inv_item_id))
+ const LLViewerJointAttachment* attachment = iter->second;
+ if (attachment->getAttachedObject(base_inv_item_id))
{
return attachment->getName();
}
@@ -1076,14 +1087,71 @@ const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *view
LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Adding attachment link:");
LLAppearanceManager::wearItem(item,false); // Add COF link for item.
gInventory.addChangedMask(LLInventoryObserver::LABEL, attachment_id);
+ gInventory.updateLinkedObjects(attachment_id);
}
}
-
gInventory.notifyObservers();
return attachment;
}
+//virtual
+BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)
+{
+ const LLUUID item_id = viewer_object->getItemID();
+ if (LLVOAvatar::detachObject(viewer_object))
+ {
+ // the simulator should automatically handle permission revocation
+
+ stopMotionFromSource(item_id);
+ LLFollowCamMgr::setCameraActive(viewer_object->getID(), FALSE);
+
+ LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end();
+ ++iter)
+ {
+ LLViewerObject* child_objectp = *iter;
+ // the simulator should automatically handle
+ // permissions revocation
+
+ stopMotionFromSource(child_objectp->getID());
+ LLFollowCamMgr::setCameraActive(child_objectp->getID(), FALSE);
+ }
+
+ // Make sure the inventory is in sync with the avatar.
+
+ // Update COF contents, don't trigger appearance update.
+ if (gAgent.getAvatarObject() == NULL)
+ {
+ llinfos << "removeItemLinks skipped, avatar is under destruction" << llendl;
+ }
+ else
+ {
+ LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Removing attachment link:");
+ LLAppearanceManager::removeItemLinks(item_id, false);
+ }
+
+ // BAP - needs to change for label to track link.
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
+ gInventory.updateLinkedObjects(item_id);
+ gInventory.notifyObservers();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+const LLUUID& LLVOAvatarSelf::getBaseAttachmentObject(const LLUUID &object_id) const
+{
+ const LLInventoryItem *item = gInventory.getItem(object_id);
+ if (!item)
+ return LLUUID::null;
+
+ // Find the base object in case this a link (if it's not a link,
+ // this will just be inv_item_id)
+ return item->getLinkedUUID();
+}
+
void LLVOAvatarSelf::getAllAttachmentsArray(LLDynamicArray<S32>& attachments)
{
for (LLVOAvatar::attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
@@ -1235,7 +1303,7 @@ BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLTexLayerSet* layerset)
return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
- baked_iter++)
+ ++baked_iter)
{
const EBakedTextureIndex baked_index = baked_iter->first;
if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
@@ -1244,7 +1312,7 @@ BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLTexLayerSet* layerset)
const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
- local_tex_iter++)
+ ++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
const EWearableType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
@@ -1276,7 +1344,7 @@ BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) cons
const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
- local_tex_iter++)
+ ++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
const EWearableType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
@@ -1562,7 +1630,7 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
setBakedReady(type,baked_version_ready,index);
}
//virtual
-void LLVOAvatarSelf::setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
+void LLVOAvatarSelf::setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
{
if (!isIndexLocalTexture(type)) return;
LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index);
@@ -1583,7 +1651,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const
if (isTextureDefined(baked_equiv[i])) */
for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
- iter++)
+ ++iter)
{
const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
@@ -1773,7 +1841,7 @@ BOOL LLVOAvatarSelf::canGrabLocalTexture(ETextureIndex type, U32 index) const
const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index);
for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin();
iter != baked_dict->mLocalTextures.end();
- iter++)
+ ++iter)
{
const ETextureIndex t_index = (*iter);
lldebugs << "Checking index " << (U32) t_index << llendl;
@@ -1949,7 +2017,7 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**)
TEX_UPPER_BAKED, */
for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
- iter++)
+ ++iter)
{
const ETextureIndex index = iter->first;
const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 0b76d3e960..aaa261cea7 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -198,8 +198,8 @@ protected:
private:
static void onLocalTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
- /*virtual*/ void setImage(const U8 te, LLViewerTexture *imagep, const U32 index);
- /*virtual*/ LLViewerTexture* getImage(const U8 te, const U32 index) const;
+ /*virtual*/ void setImage(const U8 te, LLViewerTexture *imagep, const U32 index);
+ /*virtual*/ LLViewerTexture* getImage(const U8 te, const U32 index) const;
//--------------------------------------------------------------------
@@ -220,7 +220,6 @@ protected:
public:
void requestLayerSetUploads();
void requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i);
-public:
LLTexLayerSet* getLayerSet(LLVOAvatarDefines::ETextureIndex index) const;
//--------------------------------------------------------------------
@@ -267,8 +266,10 @@ protected:
**/
public:
- /*virtual*/ BOOL isWearingWearableType(EWearableType type ) const;
- void wearableUpdated(EWearableType type);
+ /*virtual*/ BOOL isWearingWearableType(EWearableType type) const;
+ void wearableUpdated(EWearableType type);
+protected:
+ U32 getNumWearables(LLVOAvatarDefines::ETextureIndex i) const;
//--------------------------------------------------------------------
// Attachments
@@ -276,17 +277,18 @@ public:
public:
void updateAttachmentVisibility(U32 camera_mode);
BOOL isWearingAttachment(const LLUUID& inv_item_id, BOOL include_linked_items = FALSE) const;
- LLViewerObject* getWornAttachment(const LLUUID& inv_item_id );
+ LLViewerObject* getWornAttachment(const LLUUID& inv_item_id);
const std::string getAttachedPointName(const LLUUID& inv_item_id) const;
/*virtual*/ const LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object);
+ /*virtual*/ BOOL detachObject(LLViewerObject *viewer_object);
void getAllAttachmentsArray(LLDynamicArray<S32>& attachments);
+protected:
+ const LLUUID& getBaseAttachmentObject(const LLUUID &object_id) const;
//--------------------------------------------------------------------
// HUDs
//--------------------------------------------------------------------
private:
- U32 getNumWearables(LLVOAvatarDefines::ETextureIndex i) const;
-
LLViewerJoint* mScreenp; // special purpose joint for HUD attachments
/** Attachments
diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp
index 09e8c522b0..84bb099d55 100644
--- a/indra/newview/llwearable.cpp
+++ b/indra/newview/llwearable.cpp
@@ -138,11 +138,12 @@ BOOL LLWearable::exportFile(LLFILE* file) const
return FALSE;
}
- for (VisualParamIndexMap_t::const_iterator iter = mVisualParamIndexMap.begin();
- iter != mVisualParamIndexMap.end(); ++iter)
+ for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
+ iter != mVisualParamIndexMap.end();
+ ++iter)
{
S32 param_id = iter->first;
- LLVisualParam* param = iter->second;
+ const LLVisualParam* param = iter->second;
F32 param_weight = param->getWeight();
if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight ).c_str() ) < 0 )
{
@@ -173,13 +174,13 @@ BOOL LLWearable::exportFile(LLFILE* file) const
void LLWearable::createVisualParams()
{
LLVOAvatar* avatar = gAgent.getAvatarObject();
- for( LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam();
- param;
- param = (LLViewerVisualParam*) avatar->getNextVisualParam() )
+ for (LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam();
+ param;
+ param = (LLViewerVisualParam*) avatar->getNextVisualParam())
{
- if( (param->getWearableType() == mType) )
+ if (param->getWearableType() == mType)
{
- if( mVisualParamIndexMap[param->getID()] )
+ if (mVisualParamIndexMap[param->getID()])
{
delete mVisualParamIndexMap[param->getID()];
}
@@ -188,7 +189,9 @@ void LLWearable::createVisualParams()
}
// resync driver parameters to point to the newly cloned driven parameters
- for( VisualParamIndexMap_t::iterator param_iter = mVisualParamIndexMap.begin(); param_iter != mVisualParamIndexMap.end(); param_iter++ )
+ for (visual_param_index_map_t::iterator param_iter = mVisualParamIndexMap.begin();
+ param_iter != mVisualParamIndexMap.end();
+ ++param_iter)
{
LLVisualParam* param = param_iter->second;
LLVisualParam*(LLWearable::*wearable_function)(S32)const = &LLWearable::getVisualParam;
@@ -873,7 +876,7 @@ void LLWearable::setVisualParams()
{
LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
- for (VisualParamIndexMap_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++)
+ for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++)
{
S32 id = iter->first;
LLVisualParam *wearable_param = iter->second;
@@ -912,15 +915,15 @@ F32 LLWearable::getVisualParamWeight(S32 param_index) const
LLVisualParam* LLWearable::getVisualParam(S32 index) const
{
- VisualParamIndexMap_t::const_iterator iter = mVisualParamIndexMap.find(index);
+ visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(index);
return (iter == mVisualParamIndexMap.end()) ? NULL : iter->second;
}
-void LLWearable::getVisualParams(visualParamCluster_t &list)
+void LLWearable::getVisualParams(visual_param_vec_t &list)
{
- VisualParamIndexMap_t::iterator iter = mVisualParamIndexMap.begin();
- VisualParamIndexMap_t::iterator end = mVisualParamIndexMap.end();
+ visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
+ visual_param_index_map_t::iterator end = mVisualParamIndexMap.end();
// add all visual params to the passed-in vector
for( ; iter != end; ++iter )
@@ -929,7 +932,7 @@ void LLWearable::getVisualParams(visualParamCluster_t &list)
}
}
-LLColor4 LLWearable::getClothesColor(S32 te)
+LLColor4 LLWearable::getClothesColor(S32 te) const
{
LLColor4 color;
U32 param_name[3];
@@ -973,7 +976,7 @@ void LLWearable::revertValues()
}
}
-BOOL LLWearable::isOnTop()
+BOOL LLWearable::isOnTop() const
{
return (this == gAgentWearables.getTopWearable(mType));
}
@@ -996,7 +999,7 @@ void LLWearable::saveValues()
{
//update saved settings so wearable is no longer dirty
mSavedVisualParamMap.clear();
- for (VisualParamIndexMap_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter)
+ for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter)
{
S32 id = iter->first;
LLVisualParam *wearable_param = iter->second;
@@ -1174,7 +1177,7 @@ std::ostream& operator<<(std::ostream &s, const LLWearable &w)
//w.mSaleInfo
s << " Params:" << "\n";
- for (LLWearable::VisualParamIndexMap_t::const_iterator iter = w.mVisualParamIndexMap.begin();
+ for (LLWearable::visual_param_index_map_t::const_iterator iter = w.mVisualParamIndexMap.begin();
iter != w.mVisualParamIndexMap.end(); ++iter)
{
S32 param_id = iter->first;
diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h
index 201f4f91ef..01bd9652a5 100644
--- a/indra/newview/llwearable.h
+++ b/indra/newview/llwearable.h
@@ -84,7 +84,7 @@ public:
LLLocalTextureObject* getLocalTextureObject(S32 index) const;
public:
- typedef std::vector<LLVisualParam*> visualParamCluster_t;
+ typedef std::vector<LLVisualParam*> visual_param_vec_t;
BOOL isDirty() const;
BOOL isOldVersion() const;
@@ -118,19 +118,19 @@ public:
void setVisualParamWeight(S32 index, F32 value, BOOL set_by_user);
F32 getVisualParamWeight(S32 index) const;
LLVisualParam* getVisualParam(S32 index) const;
- void getVisualParams(visualParamCluster_t &list);
+ void getVisualParams(visual_param_vec_t &list);
- LLColor4 getClothesColor(S32 te);
+ LLColor4 getClothesColor(S32 te) const;
void setClothesColor( S32 te, const LLColor4& new_color, BOOL set_by_user );
void revertValues();
- BOOL isOnTop();
+ BOOL isOnTop() const;
private:
typedef std::map<S32, LLLocalTextureObject*> te_map_t;
- typedef std::map<S32, LLVisualParam *> VisualParamIndexMap_t;
+ typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
void createLayers(S32 te);
void createVisualParams();
@@ -151,7 +151,7 @@ private:
typedef std::map<S32, F32> param_map_t;
param_map_t mSavedVisualParamMap; // last saved version of visual params
- VisualParamIndexMap_t mVisualParamIndexMap;
+ visual_param_index_map_t mVisualParamIndexMap;
te_map_t mTEMap; // maps TE to LocalTextureObject
te_map_t mSavedTEMap; // last saved version of TEMap
diff --git a/indra/newview/llwldaycycle.cpp b/indra/newview/llwldaycycle.cpp
index 10a9703d1a..7f0c1a13f3 100644
--- a/indra/newview/llwldaycycle.cpp
+++ b/indra/newview/llwldaycycle.cpp
@@ -36,6 +36,7 @@
#include "llsdserialize.h"
#include "llwlparammanager.h"
#include "llnotifications.h"
+#include "llxmlnode.h"
#include <map>
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 546a06b93f..eca5130426 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -118,6 +118,8 @@
<texture name="Icon_Dock_Press" file_name="windows/Icon_Dock_Press.png" preload="true" />
<texture name="Icon_For_Sale" file_name="icons/Icon_For_sale.png" preload="false" />
+ <texture name="Banner_ForSale" file_name="Banner_ForSale.png" preload="false" />
+ <texture name="Banner_YouAreHere" file_name="Banner_YouAreHere.png" preload="false" />
<texture name="Icon_Gear_Background" file_name="windows/Icon_Gear_Background.png" preload="false" />
<texture name="Icon_Gear_Foreground" file_name="windows/Icon_Gear_Foreground.png" preload="false" />
diff --git a/indra/newview/skins/default/xui/en/favorites_bar_button.xml b/indra/newview/skins/default/xui/en/favorites_bar_button.xml
index a8d3f440c3..9cd7056866 100644
--- a/indra/newview/skins/default/xui/en/favorites_bar_button.xml
+++ b/indra/newview/skins/default/xui/en/favorites_bar_button.xml
@@ -18,6 +18,6 @@
left="0"
name="favorites_bar_btn"
tab_stop="false"
- top="10"
+ top="0"
use_ellipses="true"
width="120" />
diff --git a/indra/newview/skins/default/xui/en/floater_critical.xml b/indra/newview/skins/default/xui/en/floater_critical.xml
index 7d1a1113b0..5475a1cf6a 100644
--- a/indra/newview/skins/default/xui/en/floater_critical.xml
+++ b/indra/newview/skins/default/xui/en/floater_critical.xml
@@ -5,7 +5,6 @@
height="500"
layout="topleft"
name="modal container"
- help_topic="modal_container"
width="600">
<button
height="20"
diff --git a/indra/newview/skins/default/xui/en/floater_customize.xml b/indra/newview/skins/default/xui/en/floater_customize.xml
index 70468e7474..57f5800f2c 100644
--- a/indra/newview/skins/default/xui/en/floater_customize.xml
+++ b/indra/newview/skins/default/xui/en/floater_customize.xml
@@ -39,10 +39,10 @@
height="18"
image_name="Lock"
layout="topleft"
- left="333"
+ left="315"
mouse_opaque="true"
name="square"
- top="5"
+ top="4"
width="18" />
<icon
height="16"
@@ -335,10 +335,10 @@ scratch and wear it.
height="18"
image_name="Lock"
layout="topleft"
- left="333"
+ left="315"
mouse_opaque="true"
name="square"
- top="5"
+ top="4"
width="18" />
<icon
height="16"
@@ -590,10 +590,10 @@ scratch and wear it.
height="18"
image_name="Lock"
layout="topleft"
- left="333"
+ left="315"
mouse_opaque="true"
name="square"
- top="5"
+ top="4"
width="18" />
<icon
height="16"
@@ -818,10 +818,10 @@ scratch and wear it.
height="18"
image_name="Lock"
layout="topleft"
- left="333"
+ left="315"
mouse_opaque="true"
name="square"
- top="5"
+ top="4"
width="18" />
<icon
height="16"
@@ -1006,10 +1006,10 @@ scratch and wear it.
height="18"
image_name="Lock"
layout="topleft"
- left="333"
+ left="315"
mouse_opaque="true"
name="square"
- top="5"
+ top="4"
width="18" />
<icon
height="16"
@@ -1212,10 +1212,10 @@ scratch and wear it.
height="18"
image_name="Lock"
layout="topleft"
- left="333"
+ left="315"
mouse_opaque="true"
name="square"
- top="5"
+ top="4"
width="18" />
<icon
height="16"
@@ -1418,10 +1418,10 @@ scratch and wear it.
height="18"
image_name="Lock"
layout="topleft"
- left="333"
+ left="315"
mouse_opaque="true"
name="square"
- top="5"
+ top="4"
width="18" />
<icon
height="16"
@@ -1624,10 +1624,10 @@ scratch and wear it.
height="18"
image_name="Lock"
layout="topleft"
- left="333"
+ left="315"
mouse_opaque="true"
name="square"
- top="5"
+ top="4"
width="18" />
<icon
height="16"
@@ -1830,10 +1830,10 @@ scratch and wear it.
height="18"
image_name="Lock"
layout="topleft"
- left="333"
+ left="315"
mouse_opaque="true"
name="square"
- top="5"
+ top="4"
width="18" />
<icon
height="16"
@@ -2048,10 +2048,10 @@ scratch and wear it.
height="18"
image_name="Lock"
layout="topleft"
- left="333"
+ left="315"
mouse_opaque="true"
name="square"
- top="5"
+ top="4"
width="18" />
<icon
height="16"
@@ -2254,10 +2254,10 @@ scratch and wear it.
height="18"
image_name="Lock"
layout="topleft"
- left="333"
+ left="315"
mouse_opaque="true"
name="square"
- top="5"
+ top="4"
width="18" />
<icon
height="16"
@@ -2460,10 +2460,10 @@ scratch and wear it.
height="18"
image_name="Lock"
layout="topleft"
- left="333"
+ left="315"
mouse_opaque="true"
name="square"
- top="5"
+ top="4"
width="18" />
<icon
height="16"
@@ -2666,10 +2666,10 @@ scratch and wear it.
height="18"
image_name="Lock"
layout="topleft"
- left="333"
+ left="315"
mouse_opaque="true"
name="square"
- top="5"
+ top="4"
width="18" />
<icon
height="16"
@@ -2872,10 +2872,10 @@ scratch and wear it.
height="18"
image_name="Lock"
layout="topleft"
- left="333"
+ left="315"
mouse_opaque="true"
name="square"
- top="5"
+ top="4"
width="18" />
<icon
height="16"
@@ -3159,10 +3159,10 @@ scratch and wear it.
height="18"
image_name="Lock"
layout="topleft"
- left="333"
+ left="315"
mouse_opaque="true"
name="square"
- top="5"
+ top="4"
width="18" />
<icon
height="16"
diff --git a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
index 2882f233c2..e3e2decef7 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
@@ -33,10 +33,10 @@
height="18"
image_name="Lock"
layout="topleft"
- left="294"
+ left="276"
mouse_opaque="true"
name="IconLocked"
- top="5"
+ top="4"
width="18" />
<text
type="string"
diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
index 6fbfed5f60..90c5463aa7 100644
--- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
@@ -1,47 +1,31 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater
- background_opaque="false"
- background_visible="true"
- bevel_style="in"
- bg_alpha_color="0.3 0.3 0.3 1.0"
+ can_dock="true"
+ can_minimize="true"
+ can_close="true"
+ center_horiz="true"
height="300"
layout="topleft"
name="nearby_chat"
help_topic="nearby_chat"
save_rect="true"
title="Nearby Chat"
- single_instance="true"
+ save_visibility="true"
width="320">
- <panel top="20" width="320" height="30" background_visible="true" background_opaque="false" bg_alpha_color="0.0 0.0 0.0 1.0" name="chat_caption">
- <text
- width="140" left="25" height="20" follows="left|right|top"
- font="SansSerifBigBold" text_color="white" word_wrap="true"
- mouse_opaque="true" name="sender_name" >NEARBY CHAT </text>
- <icon top="5" left="250"
- width="20" height="20" follows="top|right"
- color="1 1 1 1" enabled="true" image_name="icn_voice-groupfocus.tga"
- mouse_opaque="true" name="nearby_speakers_btn"/>
- <icon top="5" left="275"
- width="20" height="20" follows="top|right"
- color="1 1 1 1" enabled="true" image_name="inv_item_landmark_visited.tga"
- mouse_opaque="true" name="tearoff_btn"/>
- <icon top="5" left="300"
- width="15" height="15" follows="top|right"
- color="1 1 1 1" enabled="true" image_name="closebox.tga"
- name="close_btn"/>
- </panel>
<chat_history
allow_html="true"
bg_readonly_color="ChatHistoryBgColor"
bg_writeable_color="ChatHistoryBgColor"
- follows="left|top|right"
+ follows="all"
+ left="0"
+ top="15"
font="SansSerif"
layout="topleft"
- height="320"
+ height="280"
name="chat_history"
parse_highlights="true"
text_color="ChatHistoryTextColor"
text_readonly_color="ChatHistoryTextColor"
- width="250"/>
+ width="320"/>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
index 448b0fa6af..8cdafe110a 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
@@ -33,10 +33,10 @@
height="18"
image_name="Lock"
layout="topleft"
- left="340"
+ left="322"
mouse_opaque="true"
name="lock"
- top="1"
+ top="4"
width="18" />
<text
type="string"
diff --git a/indra/newview/skins/default/xui/en/floater_script_preview.xml b/indra/newview/skins/default/xui/en/floater_script_preview.xml
index 54ab30124a..a415239867 100644
--- a/indra/newview/skins/default/xui/en/floater_script_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_script_preview.xml
@@ -30,10 +30,10 @@
height="18"
image_name="Lock"
layout="topleft"
- left="444"
+ left="426"
mouse_opaque="true"
name="lock"
- top="3"
+ top="4"
width="18" />
<text
type="string"
diff --git a/indra/newview/skins/default/xui/en/floater_select_key.xml b/indra/newview/skins/default/xui/en/floater_select_key.xml
index 8e1317440e..b89af0ef3e 100644
--- a/indra/newview/skins/default/xui/en/floater_select_key.xml
+++ b/indra/newview/skins/default/xui/en/floater_select_key.xml
@@ -6,7 +6,6 @@
height="100"
layout="topleft"
name="modal container"
- help_topic="modal_container"
width="240">
<button
height="20"
diff --git a/indra/newview/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml
index b290a9c87d..54facbb659 100644
--- a/indra/newview/skins/default/xui/en/floater_tos.xml
+++ b/indra/newview/skins/default/xui/en/floater_tos.xml
@@ -5,7 +5,6 @@
height="500"
layout="topleft"
name="modal container"
- help_topic="modal_container"
width="600">
<floater.string
name="real_url">
diff --git a/indra/newview/skins/default/xui/en/floater_wearable_save_as.xml b/indra/newview/skins/default/xui/en/floater_wearable_save_as.xml
index e698dfe2dc..ee67989d33 100644
--- a/indra/newview/skins/default/xui/en/floater_wearable_save_as.xml
+++ b/indra/newview/skins/default/xui/en/floater_wearable_save_as.xml
@@ -6,7 +6,6 @@
height="100"
layout="topleft"
name="modal container"
- help_topic="modal_container"
width="240">
<button
height="20"
diff --git a/indra/newview/skins/default/xui/en/menu_landmark.xml b/indra/newview/skins/default/xui/en/menu_landmark.xml
index 54a4095967..93b6db222a 100644
--- a/indra/newview/skins/default/xui/en/menu_landmark.xml
+++ b/indra/newview/skins/default/xui/en/menu_landmark.xml
@@ -28,6 +28,9 @@
<menu_item_call.on_click
function="Places.OverflowMenu.Action"
parameter="pick" />
+ <menu_item_call.on_enable
+ function="Places.OverflowMenu.Enable"
+ parameter="can_create_pick" />
</menu_item_call>
<menu_item_call
label="Add to Favorites Bar"
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index 8cb0a69906..c3ee6e250b 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -222,6 +222,12 @@
function="ShowFloater"
parameter="test_inspectors" />
</menu_item_call>
+ <menu_item_call
+ label="Show Side Tray"
+ name="Show Side Tray">
+ <menu_item_call.on_click
+ function="Advanced.ShowSideTray" />
+ </menu_item_call>
<menu_item_separator />
<menu_item_call
label="Show TOS"
diff --git a/indra/newview/skins/default/xui/en/menu_place.xml b/indra/newview/skins/default/xui/en/menu_place.xml
index 01f62985ca..1b96eb51f0 100644
--- a/indra/newview/skins/default/xui/en/menu_place.xml
+++ b/indra/newview/skins/default/xui/en/menu_place.xml
@@ -20,6 +20,9 @@
<menu_item_call.on_click
function="Places.OverflowMenu.Action"
parameter="pick" />
+ <menu_item_call.on_enable
+ function="Places.OverflowMenu.Enable"
+ parameter="can_create_pick" />
</menu_item_call>
<menu_item_separator
layout="topleft"/>
diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml
index c95cf32a5a..29fb4990d0 100644
--- a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml
+++ b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml
@@ -34,6 +34,9 @@
<on_click
function="Places.LandmarksGear.CopyPaste.Action"
parameter="cut" />
+ <on_enable
+ function="Places.LandmarksGear.Enable"
+ parameter="cut" />
</menu_item_call>
<menu_item_call
label="Copy"
@@ -61,6 +64,9 @@
<on_click
function="Places.LandmarksGear.CopyPaste.Action"
parameter="rename" />
+ <on_enable
+ function="Places.LandmarksGear.Enable"
+ parameter="rename" />
</menu_item_call>
<menu_item_call
label="Delete"
@@ -69,6 +75,9 @@
<on_click
function="Places.LandmarksGear.CopyPaste.Action"
parameter="delete" />
+ <on_enable
+ function="Places.LandmarksGear.Enable"
+ parameter="delete" />
</menu_item_call>
<menu_item_separator
layout="topleft" />
diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml
index 0246d775ee..c60f670fa6 100644
--- a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml
+++ b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml
@@ -66,6 +66,9 @@
<on_click
function="Places.LandmarksGear.CopyPaste.Action"
parameter="cut" />
+ <on_enable
+ function="Places.LandmarksGear.Enable"
+ parameter="cut" />
</menu_item_call>
<menu_item_call
label="Copy Landmark"
@@ -101,6 +104,9 @@
<on_click
function="Places.LandmarksGear.CopyPaste.Action"
parameter="rename" />
+ <on_enable
+ function="Places.LandmarksGear.Enable"
+ parameter="rename" />
</menu_item_call>
<menu_item_call
label="Delete"
@@ -109,6 +115,9 @@
<on_click
function="Places.LandmarksGear.CopyPaste.Action"
parameter="delete" />
+ <on_enable
+ function="Places.LandmarksGear.Enable"
+ parameter="delete" />
</menu_item_call>
<menu_item_separator
layout="topleft" />
@@ -146,5 +155,8 @@
<on_click
function="Places.LandmarksGear.Custom.Action"
parameter="create_pick" />
+ <on_enable
+ function="Places.LandmarksGear.Enable"
+ parameter="create_pick" />
</menu_item_call>
</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml
index 515278c23d..0160d52b17 100644
--- a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml
@@ -17,10 +17,10 @@
function="TeleportHistory.MoreInformation" />
</menu_item_call>
<menu_item_call
- label="Copy"
+ label="Copy to Clipboard"
layout="topleft"
- name="Copy">
+ name="CopyToClipboard">
<menu_item_call.on_click
- function="TeleportHistory.Copy" />
+ function="TeleportHistory.CopyToClipboard" />
</menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 495795d14a..cbc94e5e74 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -56,7 +56,7 @@
function="Edit.EnableCustomizeAvatar" />
</menu_item_call>
<menu_item_check
- label="My Things"
+ label="My Inventory"
layout="topleft"
name="Inventory"
shortcut="control|I">
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index 2c9109449c..f747c557e2 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -69,14 +69,14 @@
name="speaking_indicator"
visible="true"
width="20" />
- <button
+ <button
follows="right"
height="16"
image_pressed="Info_Press"
image_hover="Info_Over"
image_unselected="Info_Off"
- layout="topleft"
- left_pad="5"
+ left_pad="3"
+ right="-25"
name="info_btn"
picture_style="true"
width="16" />
@@ -88,6 +88,7 @@
image_unselected="BuyArrow_Press"
layout="topleft"
left_pad="5"
+ right="-5"
name="profile_btn"
picture_style="true"
width="16" />
diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
index d268258f6f..b002034a08 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
+ background_visible="true"
class="edit_profile_panel"
follows="all"
height="535"
@@ -301,76 +302,6 @@
width="285"
word_wrap="true" />
</panel>
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerifSmall"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="10"
- name="title_afk_text"
- text_color="white"
- top_pad="0"
- width="190">
- Away Timeout:
- </text>
- <spinner
- control_name="AFKTimeout"
- decimal_digits="0"
- follows="left|top"
- halign="right"
- height="15"
- increment="1"
- initial_value="300"
- label=""
- label_width="0"
- layout="topleft"
- max_val="600"
- min_val="30"
- name="afk_timeout_spinner"
- left_pad="4"
- width="50" />
- <text
- type="string"
- length="1"
- follows="left|top"
- halign="left"
- height="15"
- layout="topleft"
- left_pad="2"
- name="seconds_textbox"
- width="70">
- seconds
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- font="SansSerifSmall"
- font.style="BOLD"
- text_color="white"
- left="10"
- mouse_opaque="false"
- name="text_box3"
- width="240">
- Busy Mode Response:
- </text>
- <text_editor
- control_name="BusyModeResponse2"
- commit_on_focus_lost = "true"
- follows="left|top"
- height="56"
- layout="topleft"
- left="10"
- name="busy_response"
- width="285"
- word_wrap="true">
- log_in_to_change
- </text_editor>
</panel>
</panel>
</scroll_container>
diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml
index c18b625033..9bd240eccc 100644
--- a/indra/newview/skins/default/xui/en/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_general.xml
@@ -46,6 +46,7 @@ Hover your mouse over the options for more help.
layout="topleft"
left="5"
name="text_owners_and_visible_members"
+ text_color="EmphasisColor"
top_pad="10"
width="270">
Members
@@ -74,6 +75,7 @@ Hover your mouse over the options for more help.
follows="left|top"
height="16"
type="string"
+ text_color="EmphasisColor"
top_pad="10"
font="SansSerifBig"
layout="topleft"
@@ -165,7 +167,7 @@ Hover your mouse over the options for more help.
name="spin_enrollment_fee"
tool_tip="New members must pay this fee to join the group when Enrollment Fee is checked."
top_delta="-2"
- width="75" />
+ width="105" />
<check_box
height="16"
initial_value="true"
diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
index c3b277fb1d..da6cf8891a 100644
--- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
@@ -151,16 +151,16 @@
visible="false"
width="65" />
<accordion layout="topleft" left="2" width="296" top="135" height="500" follows="all" name="group_accordion">
- <accordion_tab min_height="445" title="Group General" name="group_general_tab">
+ <accordion_tab min_height="445" title="General" name="group_general_tab">
<panel class="panel_group_general" filename="panel_group_general.xml" name="group_general_tab_panel"/>
</accordion_tab>
- <accordion_tab min_height="380" title="Group Roles" name="group_roles_tab" expanded="False" can_resize="false">
+ <accordion_tab min_height="380" title="Members &amp; Roles" name="group_roles_tab" expanded="False" can_resize="false">
<panel class="panel_group_roles" filename="panel_group_roles.xml" name="group_roles_tab_panel"/>
</accordion_tab>
- <accordion_tab min_height="530" title="Group Notices" name="group_notices_tab" expanded="False" can_resize="false">
+ <accordion_tab min_height="530" title="Notices" name="group_notices_tab" expanded="False" can_resize="false">
<panel class="panel_group_notices" filename="panel_group_notices.xml" name="group_notices_tab_panel"/>
</accordion_tab>
- <accordion_tab min_height="270" title="Group Land Money" name="group_land_tab" expanded="False" can_resize="false">
+ <accordion_tab min_height="270" title="Land &amp; L$" name="group_land_tab" expanded="False" can_resize="false">
<panel class="panel_group_land_money" filename="panel_group_land_money.xml" name="group_land_tab_panel"/>
</accordion_tab>
</accordion>
diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml
index d61fcf529a..0845ec014e 100644
--- a/indra/newview/skins/default/xui/en/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml
@@ -2,7 +2,7 @@
<panel
border="true"
follows="all"
- height="410"
+ height="510"
label="Land &amp; L$"
layout="topleft"
left="1"
@@ -194,7 +194,7 @@
left_pad="5"
name="your_contribution_units"
top_delta="2">
- ( m² )
+ m²
</text>
<text
type="string"
@@ -239,13 +239,14 @@
layout="topleft"
left="10"
name="group_money_heading"
+ text_color="EmphasisColor"
top_pad="0"
width="150">
Group L$
</text>
<tab_container
follows="all"
- height="100"
+ height="200"
layout="topleft"
left="10"
name="group_money_tab_container"
@@ -268,13 +269,14 @@
bg_readonly_color="0.784314 0.819608 0.8 1"
follows="all"
font="Monospace"
- height="172"
+ height="168"
layout="topleft"
left="8"
max_length="4096"
name="group_money_planning_text"
top="5"
- width="250">
+ width="250"
+ word_wrap="true">
Computing...
</text_editor>
</panel>
@@ -300,7 +302,8 @@
max_length="4096"
name="group_money_details_text"
top="7"
- width="250">
+ width="250"
+ word_wrap="true">
Computing...
</text_editor>
<button
@@ -346,7 +349,8 @@
max_length="4096"
name="group_money_sales_text"
top="7"
- width="250">
+ width="250"
+ word_wrap="true">
Computing...
</text_editor>
<button
diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item.xml b/indra/newview/skins/default/xui/en/panel_group_list_item.xml
index 6eec0ffe7a..7bdcaafe31 100644
--- a/indra/newview/skins/default/xui/en/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_list_item.xml
@@ -31,33 +31,44 @@
follows="top|left"
height="20"
image_name="Generic_Group"
+ name="group_icon"
layout="topleft"
left="5"
mouse_opaque="true"
- name="group_icon"
- top="4"
+ top="2"
width="20" />
- <text
+ <text
follows="left|right"
font="SansSerifSmall"
- height="17"
+ height="15"
layout="topleft"
left_pad="5"
name="group_name"
- top="7"
+ top="6"
use_ellipses="true"
value="Unknown"
- width="263" />
+ width="246" />
<button
follows="right"
height="16"
image_pressed="Info_Press"
image_hover="Info_Over"
image_unselected="Info_Off"
- layout="topleft"
+ left_pad="3"
+ right="-25"
name="info_btn"
picture_style="true"
+ width="16" />
+ <button
+ follows="right"
+ height="16"
+ image_selected="BuyArrow_Press"
+ image_pressed="BuyArrow_Press"
+ image_unselected="BuyArrow_Press"
+ layout="topleft"
+ left_pad="5"
right="-5"
- top="4"
+ name="profile_btn"
+ picture_style="true"
width="16" />
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml
index 82a3c98dd9..d9fb962998 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -52,6 +52,7 @@ the General tab.
layout="topleft"
left_delta="10"
name="lbl2"
+ text_color="EmphasisColor"
top_pad="10"
width="270">
Notices are kept for 14 days. Notice lists are limited to 200 notices per group on a daily basis.
@@ -135,6 +136,7 @@ the General tab.
left="10"
mouse_opaque="false"
name="lbl"
+ text_color="EmphasisColor"
top_pad="0"
width="265">
Create a Notice
@@ -147,6 +149,7 @@ the General tab.
layout="topleft"
left_delta="0"
name="lbl2"
+ text_color="EmphasisColor"
top_pad="4"
width="195">
You can add a single item to a notice by dragging it from your inventory to this panel. Attached items must be copiable and transferrable, and you can&apos;t send a folder.
@@ -289,6 +292,7 @@ the General tab.
left="10"
mouse_opaque="false"
name="lbl"
+ text_color="EmphasisColor"
top_pad="0"
width="265">
Archived Notice
@@ -302,7 +306,7 @@ the General tab.
name="lbl2"
top_pad="4"
width="265">
- To send a new notice, click the &apos;Create New Notice&apos; button above.
+ To send a new notice, click the &apos;New Notice&apos; button above.
</text>
<text
type="string"
diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml
index ad452b16a7..c33f68eaf7 100644
--- a/indra/newview/skins/default/xui/en/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml
@@ -31,6 +31,7 @@
left="0"
mouse_opaque="true"
name="favorites_list"
+ start_folder="favorite"
width="380"/>
</accordion_tab>
<accordion_tab
@@ -62,6 +63,7 @@
left="0"
mouse_opaque="true"
name="my_inventory_list"
+ start_folder="inventory"
width="380"/>
</accordion_tab>
<accordion_tab
@@ -77,6 +79,7 @@
left="0"
mouse_opaque="true"
name="library_list"
+ start_folder="library"
width="380"/>
</accordion_tab>
</accordion>
@@ -127,7 +130,7 @@
picture_style="true"
tool_tip="Add new folder"
width="18" />
- <button
+ <dnd_button
follows="bottom|right"
height="18"
image_selected="TrashItem_Press"
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index 00100693cc..4e1ea0f490 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -137,6 +137,6 @@
name="favorite"
image_drag_indication="Arrow_Down"
chevron_button_tool_tip="Show more of My Favorites"
- top="32"
+ bottom="65"
width="590" />
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_notification.xml b/indra/newview/skins/default/xui/en/panel_notification.xml
index 4d890b1d46..9c2829d92d 100644
--- a/indra/newview/skins/default/xui/en/panel_notification.xml
+++ b/indra/newview/skins/default/xui/en/panel_notification.xml
@@ -12,6 +12,7 @@
width="350">
<panel
background_visible="true"
+ bg_alpha_color="0.3 0.3 0.3 0"
follows="left|right|top"
height="100"
label="info_panel"
@@ -70,6 +71,7 @@
</panel>
<panel
background_visible="true"
+ bg_alpha_color="0.3 0.3 0.3 0"
follows="left|right|bottom"
height="40"
label="control_panel"
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 8274beb538..085b732473 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- Side tray panel -->
<panel
background_visible="true"
- draw_border="false"
follows="all"
height="570"
label="People"
@@ -10,7 +10,6 @@ background_visible="true"
name="people_panel"
top="0"
left="0"
- bevel_style="none"
width="333">
<string
name="no_people"
@@ -69,6 +68,7 @@ background_visible="true"
<avatar_list
follows="all"
height="470"
+ ignore_online_status="true"
layout="topleft"
left="0"
name="avatar_list"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index f7d7d52b68..16fdbd7045 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -196,7 +196,7 @@ Automatic positioning for:
name="heading3"
top_pad="10"
width="270">
-My Avatar:
+Avatars:
</text>
<check_box
control_name="FirstPersonAvatarVisible"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
index a94cfbeec4..975d21aaa6 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
@@ -33,7 +33,7 @@
width="170">
<combo_box.item
enabled="true"
- label="System Default"
+ label="System default"
name="System Default Language"
value="default" />
<combo_box.item
@@ -189,7 +189,7 @@
name="start_location_textbox"
top_delta="20"
width="394">
- Start Location:
+ Start location:
</text>
<combo_box
control_name="LoginLocation"
@@ -213,7 +213,7 @@
control_name="ShowStartLocation"
height="16"
initial_value="true"
- label="Show on Login"
+ label="Show on login"
layout="topleft"
left_delta="175"
name="show_location_checkbox"
@@ -272,7 +272,7 @@
layout="topleft"
left_delta="0"
name="show_my_name_checkbox1"
- top_pad="5"
+ top_pad="-7"
width="300" />
<check_box
enabled_control="AvatarNameTagMode"
@@ -303,7 +303,7 @@
layout="topleft"
left="30"
name="effects_color_textbox"
- top_pad="10"
+ top_pad="5"
width="400">
My Effects:
</text>
@@ -316,7 +316,76 @@
left_delta="50"
name="effect_color_swatch"
tool_tip="Click to open Color Picker"
- top_pad="10"
+ top_pad="5"
width="32" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left="30"
+ name="title_afk_text"
+ text_color="white"
+ top_pad="-5"
+ width="190">
+ Away timeout:
+ </text>
+ <spinner
+ control_name="AFKTimeout"
+ decimal_digits="0"
+ follows="left|top"
+ halign="right"
+ height="15"
+ increment="1"
+ initial_value="300"
+ label=""
+ label_width="0"
+ layout="topleft"
+ left_delta="50"
+ max_val="600"
+ min_val="30"
+ name="afk_timeout_spinner"
+ top_pad="5"
+ width="50" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ halign="left"
+ height="15"
+ layout="topleft"
+ left_pad="2"
+ name="seconds_textbox"
+ width="70">
+ seconds
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ text_color="white"
+ left="30"
+ mouse_opaque="false"
+ name="text_box3"
+ top_pad="10"
+ width="240">
+ Busy mode response:
+ </text>
+ <text_editor
+ control_name="BusyModeResponse2"
+ commit_on_focus_lost = "true"
+ follows="left|top"
+ height="56"
+ layout="topleft"
+ left_delta="50"
+ name="busy_response"
+ width="400"
+ word_wrap="true"
+ top_pad="5">
+ log_in_to_change
+ </text_editor>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 519b469868..b1308a1942 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -92,7 +92,7 @@
name="UI Size:"
top_pad="4"
width="300">
- UI Size:
+ UI size:
</text>
<slider
can_edit_text="true"
@@ -290,7 +290,7 @@
control_name="RenderObjectBump"
height="16"
initial_value="true"
- label="Bump Mapping and Shiny"
+ label="Bump mapping and shiny"
layout="topleft"
left_delta="0"
name="BumpShiny"
@@ -300,7 +300,7 @@
control_name="VertexShaderEnable"
height="16"
initial_value="true"
- label="Basic Shaders"
+ label="Basic shaders"
layout="topleft"
left_delta="0"
name="BasicShaders"
@@ -314,7 +314,7 @@
control_name="WindLightUseAtmosShaders"
height="16"
initial_value="true"
- label="Atmospheric Shaders"
+ label="Atmospheric shaders"
layout="topleft"
left_delta="0"
name="WindLightUseAtmosShaders"
@@ -327,7 +327,7 @@
control_name="RenderWaterReflections"
height="16"
initial_value="true"
- label="Water Reflections"
+ label="Water reflections"
layout="topleft"
left_delta="0"
name="Reflections"
@@ -346,7 +346,7 @@
name="ReflectionDetailText"
top_pad="7"
width="128">
- Reflection Detail:
+ Reflection detail:
</text>
<radio_group
control_name="RenderReflectionDetail"
@@ -359,7 +359,7 @@
width="321">
<radio_item
height="16"
- label="Terrain and Trees"
+ label="Terrain and trees"
layout="topleft"
left="3"
name="0"
@@ -367,7 +367,7 @@
width="315" />
<radio_item
height="16"
- label="All Static Objects"
+ label="All static objects"
layout="topleft"
left_delta="0"
name="1"
@@ -375,7 +375,7 @@
width="315" />
<radio_item
height="16"
- label="All Avatars and Objects"
+ label="All avatars and objects"
layout="topleft"
left_delta="0"
name="2"
@@ -400,13 +400,13 @@
name="AvatarRenderingText"
top_pad="5"
width="128">
- Avatar Rendering:
+ Avatar rendering:
</text>
<check_box
control_name="RenderUseImpostors"
height="16"
initial_value="true"
- label="Avatar Impostors"
+ label="Avatar impostors"
layout="topleft"
left_delta="0"
name="AvatarImpostors"
@@ -416,7 +416,7 @@
control_name="RenderAvatarVP"
height="16"
initial_value="true"
- label="Hardware Skinning"
+ label="Hardware skinning"
layout="topleft"
left_delta="0"
name="AvatarVertexProgram"
@@ -429,7 +429,7 @@
control_name="RenderAvatarCloth"
height="16"
initial_value="true"
- label="Avatar Cloth"
+ label="Avatar cloth"
layout="topleft"
left_delta="0"
name="AvatarCloth"
@@ -443,7 +443,7 @@
height="16"
increment="8"
initial_value="160"
- label="Draw Distance:"
+ label="Draw distance:"
label_width="140"
layout="topleft"
left="216"
@@ -474,7 +474,7 @@
height="16"
increment="256"
initial_value="4096"
- label="Max. Particle Count:"
+ label="Max. particle count:"
label_width="140"
layout="topleft"
left="216"
@@ -489,7 +489,7 @@
height="16"
increment="1"
initial_value="8"
- label="Post Process Quality:"
+ label="Post process quality:"
label_width="140"
layout="topleft"
left_delta="0"
@@ -513,7 +513,7 @@
name="MeshDetailText"
top_pad="5"
width="128">
- Mesh Detail:
+ Mesh detail:
</text>
<slider
control_name="RenderVolumeLODFactor"
@@ -724,7 +724,7 @@
name="LightingDetailText"
top_pad="8"
width="128">
- Lighting Detail:
+ Lighting detail:
</text>
<radio_group
control_name="RenderLightingDetail"
@@ -762,7 +762,7 @@
name="TerrainDetailText"
top="465"
width="128">
- Terrain Detail:
+ Terrain detail:
</text>
<radio_group
control_name="RenderTerrainDetail"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
index df347cfb5f..9cf0bd26d8 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -141,7 +141,7 @@
height="16"
increment="1"
initial_value="80"
- label="Port Number:"
+ label="Port number:"
label_width="75"
layout="topleft"
left_delta="160"
@@ -294,7 +294,7 @@
follows="left|top"
height="16"
initial_value="false"
- label="Web Proxy"
+ label="Web proxy"
left_delta="0"
mouse_opaque="true"
name="web_proxy_enabled"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
index f5f9850a4e..8a28719d98 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
@@ -15,7 +15,7 @@
height="15"
increment="0.05"
initial_value="0.5"
- label="Master Volume"
+ label="Master volume"
label_width="125"
layout="topleft"
left="30"
@@ -314,23 +314,27 @@
Sound out/in:
</text>
<button
- enabled_control="EnableVoiceChat"
+ control_name="ShowDeviceSettings"
follows="left|top"
height="20"
- label="Device Settings"
+ is_toggle="true"
+ label="Device settings"
layout="topleft"
left_delta="55"
name="device_settings_btn"
top_pad="0"
- width="155">
- <button.commit_callback
- function="Floater.Show"
- parameter="pref_voicedevicesettings" />
- </button>
- <panel.string
- name="default_text">
- Default
- </panel.string>
+ width="155" />
+ <panel
+ visiblity_control="ShowDeviceSettings"
+ border="false"
+ follows="top|left"
+ height="260"
+ label="DeviceSettings"
+ layout="topleft"
+ left="0"
+ name="Device Settings"
+ top_pad="5"
+ width="485">
<text
type="string"
length="1"
@@ -339,14 +343,14 @@
layout="topleft"
left="30"
name="Input device (microphone):"
- top_pad="5"
+ top_pad="0"
width="200">
Input device (microphone):
</text>
<combo_box
height="18"
layout="topleft"
- left_delta="70"
+ left_delta="55"
max_chars="128"
name="voice_input_device"
top_pad="2"
@@ -366,7 +370,7 @@
<combo_box
height="18"
layout="topleft"
- left_delta="70"
+ left_delta="55"
max_chars="128"
name="voice_output_device"
top_pad="2"
@@ -381,7 +385,7 @@
name="Input level:"
top_pad="10"
width="200">
- Input Level
+ Input level
</text>
<slider_bar
follows="left|top"
@@ -452,6 +456,6 @@
word_wrap="true">
Adjust the slider to control how loud you sound to other Residents. To test the input level, simply speak into your microphone.
</text>
-
+ </panel>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml
index d3d45640cb..395b574425 100644
--- a/indra/newview/skins/default/xui/en/panel_side_tray.xml
+++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- Side tray cannot show background because it is always
+ partially on screen to hold tab buttons. -->
<side_tray
name="sidebar"
background_visible="false"
@@ -6,6 +8,10 @@
width="333"
collapsed="true"
>
+ <!-- Individual tabs must show background to have seemless
+ appearance up to tray panel header word like "Home".
+ Embedded panels are inset by a pixel and so their
+ backgrounds will not block the world fully. -->
<sidetray_tab
name="sidebar_home"
help_topic="sidebar_home"
@@ -13,14 +19,12 @@
description="Home."
image="TabIcon_Open_Off"
mouse_opaque="false"
- background_opaque="false"
background_visible="true"
>
<panel
name="panel_home"
filename="panel_sidetray_home_tab.xml"
label="home"
- border="true"
/>
</sidetray_tab>
@@ -31,7 +35,6 @@
description="Find your friends, contacts and people nearby."
image="TabIcon_People_Off"
mouse_opaque="false"
- background_opaque="false"
background_visible="true"
>
<panel_container
@@ -42,20 +45,17 @@
class="panel_people"
name="panel_people"
filename="panel_people.xml"
- border="true"
/>
<panel
class="panel_profile_view"
name="panel_profile_view"
filename="panel_profile_view.xml"
- border="true"
/>
<panel
class="panel_group_info_sidetray"
name="panel_group_info_sidetray"
filename="panel_group_info_sidetray.xml"
label="Group Info"
- border="true"
font="SansSerifBold"
/>
<panel
@@ -63,12 +63,12 @@
name="panel_block_list_sidetray"
filename="panel_block_list_sidetray.xml"
label="Blocked Residents &amp; Objects"
- border="true"
font="SansSerifBold"
/>
</panel_container>
</sidetray_tab>
+
<sidetray_tab
name="sidebar_places"
help_topic="sidebar_places"
@@ -84,7 +84,6 @@
name="panel_places"
filename="panel_places.xml"
label="Places"
- border="true"
font="SansSerifBold"
/>
</sidetray_tab>
@@ -103,7 +102,6 @@
name="panel_me_profile"
filename="panel_me_profile.xml"
label="Me"
- border="true"
/>
</sidetray_tab>
@@ -114,18 +112,15 @@
description="Change your appearance and current look."
image="TabIcon_Appearance_Off"
mouse_opaque="false"
- background_opaque="false"
background_visible="true"
>
<panel
class="panel_appearance"
name="panel_appearance"
filename="panel_appearance.xml"
- border="true"
label="Edit Appearance"
font="SansSerifBold"
/>
</sidetray_tab>
-
</side_tray>
diff --git a/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml b/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml
index e991861e94..247054772e 100644
--- a/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml
+++ b/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- Part of side tray, see that XML file for panel config -->
<panel
- background_visible="true"
- bevel_style="out"
follows="all"
height="560"
label="home_tab"
diff --git a/indra/newview/skins/default/xui/en/panel_toast.xml b/indra/newview/skins/default/xui/en/panel_toast.xml
index 01fd84e09d..2e500fc2aa 100644
--- a/indra/newview/skins/default/xui/en/panel_toast.xml
+++ b/indra/newview/skins/default/xui/en/panel_toast.xml
@@ -7,7 +7,7 @@
visible="false"
layout="topleft"
width="350"
- height="72"
+ height="40"
left="100"
top="500"
follows="right|bottom"
@@ -24,18 +24,18 @@
visible="false"
follows="left|top|right|bottom"
font="SansSerifBold"
- height="40"
+ height="28"
layout="topleft"
left="60"
name="toast_text"
word_wrap="true"
text_color="white"
- top="20"
+ top="10"
width="290">
Toast text;
</text>
<icon
- top="20"
+ top="4"
left="10"
width="32"
height="32"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 0ca6c87585..a57c9cd97f 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -16,7 +16,7 @@
<string name="StartupLoading">Loading</string>
<!-- Legacy strings, almost never used -->
- <string name="Fullbright">Fullbright (Legacy)</string>
+ <string name="Fullbright">Fullbright (Legacy)</string> <!-- used in the Build > materials dropdown-->
<!-- Login -->
<string name="LoginInProgress">Logging in. [APP_NAME] may appear frozen. Please wait.</string>
@@ -130,7 +130,7 @@
<string name="AssetErrorPriceMismatch">Viewer and server do not agree on price</string>
<string name="AssetErrorUnknownStatus">Unknown status</string>
- <!-- Asset Type Human Names -->
+ <!-- Asset Type human readable names: these will replace variable [TYPE] in notification FailedToFindWearable* -->
<string name="texture">texture</string>
<string name="sound">sound</string>
<string name="calling card">calling card</string>
@@ -138,23 +138,23 @@
<string name="legacy script">legacy script</string>
<string name="clothing">clothing</string>
<string name="object">object</string>
- <string name="note card">note card</string>
+ <string name="note card">notecard</string>
<string name="folder">folder</string>
<string name="root">root</string>
- <string name="lsl2 script">lsl2 script</string>
- <string name="lsl bytecode">lsl bytecode</string>
+ <string name="lsl2 script">LSL2 script</string>
+ <string name="lsl bytecode">LSL bytecode</string>
<string name="tga texture">tga texture</string>
- <string name="body part">body part</string>
- <string name="snapshot">snapshot</string>
- <string name="lost and found">lost and found</string>
- <string name="targa image">targa image</string>
- <string name="trash">trash</string>
- <string name="jpeg image">jpeg image</string>
- <string name="animation">animation</string>
- <string name="gesture">gesture</string>
- <string name="simstate">simstate</string>
- <string name="favorite">favorite</string>
- <string name="symbolic link">link</string>
+ <string name="body part">body part</string>
+ <string name="snapshot">snapshot</string>
+ <string name="lost and found">Lost and Found</string>
+ <string name="targa image">targa image</string>
+ <string name="trash">Trash</string>
+ <string name="jpeg image">jpeg image</string>
+ <string name="animation">animation</string>
+ <string name="gesture">gesture</string>
+ <string name="simstate">simstate</string>
+ <string name="favorite">favorite</string>
+ <string name="symbolic link">link</string>
<!-- llvoavatar. Displayed in the avatar chat bubble -->
<string name="AvatarEditingAppearance">(Editing Appearance)</string>
@@ -2844,13 +2844,13 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="Wide Lips">Wide Lips</string>
<string name="Wild">Wild</string>
<string name="Wrinkles">Wrinkles</string>
-
- <string name="Search">Search</string>
<!-- Favorites Bar -->
<string name="LocationCtrlAddLandmarkTooltip">Add to My Landmarks</string>
<string name="LocationCtrlEditLandmarkTooltip">Edit My Landmark</string>
-
+ <string name="LocationCtrlInfoBtnTooltip">See more info about the current location</string>
+ <string name="LocationCtrlComboBtnTooltip">My location history</string>
+
<!-- Strings used by the (currently Linux) auto-updater app -->
<string name="UpdaterWindowTitle">
[APP_NAME] Update
@@ -2884,6 +2884,22 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
</string>
<!-- IM system messages -->
+ <string name="ringing-im">
+ Joining Voice Chat...
+ </string>
+ <string name="connected-im">
+ Connected, click End Call to hang up
+ </string>
+ <string name="hang_up-im">
+ Left Voice Chat
+ </string>
+ <string name="answering-im">
+ Connecting...
+ </string>
+ <string name="inventory_item_offered-im">
+ Inventory item offered
+ </string>
+
<string name="only_user_message">
You are the only user in this session.
</string>
diff --git a/indra/newview/skins/default/xui/en/widgets/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml
index 1377a3c945..f2e48c517d 100644
--- a/indra/newview/skins/default/xui/en/widgets/location_input.xml
+++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml
@@ -21,7 +21,6 @@
>
<info_button name="Place Information"
label=""
- tool_tip="See more info about the current location"
width="16"
height="16"
follows="left|top"
@@ -43,8 +42,7 @@
left="-3" />
<combo_button name="Location History"
label=""
- pad_right="0"
- tool_tip="My location history"/>
+ pad_right="0"/>
<combo_list bg_writeable_color="MenuDefaultBgColor" page_lines="10"
scroll_bar_bg_visible="true" />
<combo_editor name="Combo Text Entry"