summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/cmake/00-Common.cmake6
-rw-r--r--indra/llcharacter/llcharacter.cpp12
-rw-r--r--indra/llcharacter/llcharacter.h6
-rw-r--r--indra/llcharacter/llvisualparam.cpp18
-rw-r--r--indra/llcharacter/llvisualparam.h8
-rw-r--r--indra/llcommon/CMakeLists.txt3
-rw-r--r--indra/llcommon/lleventapi.cpp30
-rw-r--r--indra/llcommon/lleventapi.h53
-rw-r--r--indra/llcommon/lleventdispatcher.cpp12
-rw-r--r--indra/llcommon/lleventdispatcher.h35
-rw-r--r--indra/llcommon/llevents.h2
-rw-r--r--indra/llcommon/llinstancetracker.h112
-rw-r--r--indra/llcommon/lltimer.cpp12
-rw-r--r--indra/llcommon/tests/llinstancetracker_test.cpp160
-rw-r--r--indra/llmath/llinterp.h7
-rw-r--r--indra/llmessage/llares.cpp2
-rw-r--r--indra/llmessage/llareslistener.cpp13
-rw-r--r--indra/llmessage/llareslistener.h9
-rw-r--r--indra/llprimitive/tests/llmediaentry_test.cpp9
-rw-r--r--indra/llrender/llrendertarget.cpp52
-rw-r--r--indra/llrender/llrendertarget.h7
-rw-r--r--indra/llui/lldockcontrol.cpp2
-rw-r--r--indra/llui/llfloater.cpp77
-rw-r--r--indra/llui/llfloaterreg.cpp2
-rw-r--r--indra/llui/llfloaterreglistener.cpp30
-rw-r--r--indra/llui/llfloaterreglistener.h6
-rw-r--r--indra/llui/lllayoutstack.cpp4
-rw-r--r--indra/llui/llnotificationslistener.cpp8
-rw-r--r--indra/llui/llnotificationslistener.h4
-rw-r--r--indra/llui/llpanel.cpp2
-rw-r--r--indra/llui/llscrolllistcell.cpp22
-rw-r--r--indra/llui/llscrolllistcell.h8
-rw-r--r--indra/llui/llscrolllistctrl.cpp2
-rw-r--r--indra/llui/lltextbase.cpp10
-rw-r--r--indra/llui/lltextbase.h2
-rw-r--r--indra/llui/lltooltip.cpp32
-rw-r--r--indra/llui/lltooltip.h18
-rw-r--r--indra/llui/lluicolortable.cpp13
-rw-r--r--indra/llui/lluictrl.cpp4
-rw-r--r--indra/llui/llurlentry.cpp44
-rw-r--r--indra/llui/llurlentry.h12
-rw-r--r--indra/llui/llurlregistry.cpp1
-rw-r--r--indra/newview/CMakeLists.txt6
-rw-r--r--indra/newview/app_settings/logcontrol.xml1
-rw-r--r--indra/newview/app_settings/settings.xml26
-rw-r--r--indra/newview/llagentlistener.cpp18
-rw-r--r--indra/newview/llagentlistener.h4
-rw-r--r--indra/newview/llagentui.cpp6
-rw-r--r--indra/newview/llagentwearables.cpp11
-rw-r--r--indra/newview/llagentwearables.h2
-rw-r--r--indra/newview/llappearancemgr.cpp21
-rw-r--r--indra/newview/llappearancemgr.h1
-rw-r--r--indra/newview/llappviewer.cpp2
-rw-r--r--indra/newview/llappviewerlistener.cpp14
-rw-r--r--indra/newview/llappviewerlistener.h9
-rw-r--r--indra/newview/llavataractions.cpp53
-rw-r--r--indra/newview/llavataractions.h13
-rw-r--r--indra/newview/llavatariconctrl.cpp83
-rw-r--r--indra/newview/llavatariconctrl.h8
-rw-r--r--indra/newview/llavatarpropertiesprocessor.cpp120
-rw-r--r--indra/newview/llavatarpropertiesprocessor.h52
-rw-r--r--indra/newview/llbottomtray.cpp443
-rw-r--r--indra/newview/llbottomtray.h40
-rw-r--r--indra/newview/llchathistory.cpp23
-rw-r--r--indra/newview/llchathistory.h4
-rw-r--r--indra/newview/llchiclet.cpp311
-rw-r--r--indra/newview/llchiclet.h105
-rw-r--r--indra/newview/lldriverparam.cpp24
-rw-r--r--indra/newview/lldriverparam.h8
-rw-r--r--indra/newview/llfloaterabout.cpp12
-rw-r--r--indra/newview/llfloaterpreference.cpp69
-rw-r--r--indra/newview/llfloaterpreference.h5
-rw-r--r--indra/newview/llfloatersearch.cpp16
-rw-r--r--indra/newview/llfloateruipreview.cpp1
-rw-r--r--indra/newview/llgrouplist.cpp10
-rw-r--r--indra/newview/llimfloater.cpp24
-rw-r--r--indra/newview/llimpanel.cpp7
-rw-r--r--indra/newview/llimview.cpp159
-rw-r--r--indra/newview/llimview.h25
-rw-r--r--indra/newview/llinspectremoteobject.cpp200
-rw-r--r--indra/newview/llinspectremoteobject.h40
-rw-r--r--indra/newview/llinventorymodel.cpp569
-rw-r--r--indra/newview/llinventorymodel.h259
-rw-r--r--indra/newview/llinventoryobserver.cpp564
-rw-r--r--indra/newview/llinventoryobserver.h249
-rw-r--r--indra/newview/llinventorypanel.cpp24
-rw-r--r--indra/newview/llinventorypanel.h2
-rw-r--r--indra/newview/lllogininstance.cpp9
-rw-r--r--indra/newview/llnamelistctrl.cpp4
-rw-r--r--indra/newview/llnavigationbar.cpp2
-rw-r--r--indra/newview/llnearbychatbar.cpp33
-rw-r--r--indra/newview/llnearbychatbar.h10
-rw-r--r--indra/newview/llnetmap.cpp4
-rw-r--r--indra/newview/llnotificationofferhandler.cpp5
-rw-r--r--indra/newview/llpanelclassified.cpp549
-rw-r--r--indra/newview/llpanelclassified.h137
-rw-r--r--indra/newview/llpanelgrouproles.cpp6
-rw-r--r--indra/newview/llpanelimcontrolpanel.cpp49
-rw-r--r--indra/newview/llpanelimcontrolpanel.h7
-rw-r--r--indra/newview/llpanellandmarkinfo.cpp31
-rw-r--r--indra/newview/llpanelmaininventory.cpp5
-rw-r--r--indra/newview/llpanelpeople.cpp135
-rw-r--r--indra/newview/llpanelpeople.h5
-rw-r--r--indra/newview/llpanelpick.cpp3
-rw-r--r--indra/newview/llpanelpicks.cpp491
-rw-r--r--indra/newview/llpanelpicks.h90
-rw-r--r--indra/newview/llpanelplaceinfo.cpp25
-rw-r--r--indra/newview/llpanelplaceinfo.h3
-rw-r--r--indra/newview/llpanelplaceprofile.cpp48
-rw-r--r--indra/newview/llpanelplaceprofile.h4
-rw-r--r--indra/newview/llpanelplaces.cpp1
-rw-r--r--indra/newview/llpanelprimmediacontrols.cpp64
-rw-r--r--indra/newview/llpanelprofile.cpp1
-rw-r--r--indra/newview/llparticipantlist.cpp148
-rw-r--r--indra/newview/llparticipantlist.h24
-rw-r--r--indra/newview/llrecentpeople.cpp17
-rw-r--r--indra/newview/llsidetray.cpp54
-rw-r--r--indra/newview/llsidetray.h6
-rw-r--r--indra/newview/llspeakbutton.cpp10
-rw-r--r--indra/newview/llspeakbutton.h5
-rw-r--r--indra/newview/llstartup.cpp11
-rw-r--r--indra/newview/lltexglobalcolor.cpp4
-rw-r--r--indra/newview/lltexglobalcolor.h2
-rw-r--r--indra/newview/lltexlayer.cpp2
-rw-r--r--indra/newview/lltexlayerparams.cpp34
-rw-r--r--indra/newview/lltexlayerparams.h14
-rw-r--r--indra/newview/lltexturecache.cpp17
-rw-r--r--indra/newview/lltoastimpanel.cpp14
-rw-r--r--indra/newview/lluilistener.cpp12
-rw-r--r--indra/newview/lluilistener.h6
-rw-r--r--indra/newview/llurldispatcher.cpp6
-rw-r--r--indra/newview/llviewercontrollistener.cpp20
-rw-r--r--indra/newview/llviewercontrollistener.h4
-rw-r--r--indra/newview/llviewerfloaterreg.cpp4
-rw-r--r--indra/newview/llviewermedia.cpp16
-rw-r--r--indra/newview/llviewermenu.cpp8
-rw-r--r--indra/newview/llviewermessage.cpp54
-rw-r--r--indra/newview/llviewerwindow.cpp33
-rw-r--r--indra/newview/llviewerwindowlistener.cpp16
-rw-r--r--indra/newview/llviewerwindowlistener.h9
-rw-r--r--indra/newview/llvoavatar.cpp42
-rw-r--r--indra/newview/llvoavatar.h11
-rw-r--r--indra/newview/llvoavatarself.cpp38
-rw-r--r--indra/newview/llvoavatarself.h12
-rw-r--r--indra/newview/llvoicechannel.cpp18
-rw-r--r--indra/newview/llvoicechannel.h8
-rw-r--r--indra/newview/llvoiceclient.cpp4
-rw-r--r--indra/newview/llwearable.cpp49
-rw-r--r--indra/newview/llwearable.h12
-rw-r--r--indra/newview/pipeline.cpp29
-rw-r--r--indra/newview/pipeline.h2
-rw-r--r--indra/newview/skins/default/colors.xml2
-rw-r--r--indra/newview/skins/default/textures/textures.xml4
-rw-r--r--indra/newview/skins/default/textures/widgets/Tooltip.pngbin0 -> 2910 bytes
-rw-r--r--indra/newview/skins/default/xui/en/floater_avatar_picker.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_incoming_call.xml40
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_media_settings.xml12
-rw-r--r--indra/newview/skins/default/xui/en/floater_outgoing_call.xml69
-rw-r--r--indra/newview/skins/default/xui/en/floater_search.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_widgets.xml10
-rw-r--r--indra/newview/skins/default/xui/en/inspect_remote_object.xml99
-rw-r--r--indra/newview/skins/default/xui/en/menu_login.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_participant_list.xml31
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml39
-rw-r--r--indra/newview/skins/default/xui/en/menu_picks_plus.xml22
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml22
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml18
-rw-r--r--indra/newview/skins/default/xui/en/panel_avatar_list_item.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml77
-rw-r--r--indra/newview/skins/default/xui/en/panel_classified_info.xml183
-rw-r--r--indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml83
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_classified.xml255
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_pick.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_general.xml20
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml60
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_land_money.xml40
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_notices.xml16
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_roles.xml85
-rw-r--r--indra/newview/skins/default/xui/en/panel_instant_message.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_landmark_info.xml28
-rw-r--r--indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_people.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_picks.xml44
-rw-r--r--indra/newview/skins/default/xui/en/panel_place_profile.xml523
-rw-r--r--indra/newview/skins/default/xui/en/panel_places.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_chat.xml82
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml14
-rw-r--r--indra/newview/skins/default/xui/en/panel_side_tray.xml6
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml4
-rw-r--r--indra/newview/skins/default/xui/en/widgets/avatar_icon.xml4
-rw-r--r--indra/newview/skins/default/xui/en/widgets/ui_ctrl.xml5
-rw-r--r--indra/newview/tests/lllogininstance_test.cpp1
-rw-r--r--indra/viewer_components/login/lllogin.cpp29
-rw-r--r--indra/viewer_components/login/tests/lllogin_test.cpp37
195 files changed, 6571 insertions, 2433 deletions
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index db5495091e..b159092592 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -35,13 +35,13 @@ if (WINDOWS)
# Don't build DLLs.
set(BUILD_SHARED_LIBS OFF)
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd"
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /MP"
CACHE STRING "C++ compiler debug options" FORCE)
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
- "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD"
+ "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP"
CACHE STRING "C++ compiler release-with-debug options" FORCE)
set(CMAKE_CXX_FLAGS_RELEASE
- "${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD"
+ "${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP"
CACHE STRING "C++ compiler release options" FORCE)
set(CMAKE_CXX_STANDARD_LIBRARIES "")
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp
index e68672d46f..528a7bb4a5 100644
--- a/indra/llcharacter/llcharacter.cpp
+++ b/indra/llcharacter/llcharacter.cpp
@@ -273,13 +273,13 @@ void LLCharacter::removeAnimationData(std::string name)
//-----------------------------------------------------------------------------
// setVisualParamWeight()
//-----------------------------------------------------------------------------
-BOOL LLCharacter::setVisualParamWeight(LLVisualParam* which_param, F32 weight, BOOL set_by_user)
+BOOL LLCharacter::setVisualParamWeight(LLVisualParam* which_param, F32 weight, BOOL upload_bake)
{
S32 index = which_param->getID();
visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index);
if (index_iter != mVisualParamIndexMap.end())
{
- index_iter->second->setWeight(weight, set_by_user);
+ index_iter->second->setWeight(weight, upload_bake);
return TRUE;
}
return FALSE;
@@ -288,7 +288,7 @@ BOOL LLCharacter::setVisualParamWeight(LLVisualParam* which_param, F32 weight, B
//-----------------------------------------------------------------------------
// setVisualParamWeight()
//-----------------------------------------------------------------------------
-BOOL LLCharacter::setVisualParamWeight(const char* param_name, F32 weight, BOOL set_by_user)
+BOOL LLCharacter::setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake)
{
std::string tname(param_name);
LLStringUtil::toLower(tname);
@@ -296,7 +296,7 @@ BOOL LLCharacter::setVisualParamWeight(const char* param_name, F32 weight, BOOL
visual_param_name_map_t::iterator name_iter = mVisualParamNameMap.find(tableptr);
if (name_iter != mVisualParamNameMap.end())
{
- name_iter->second->setWeight(weight, set_by_user);
+ name_iter->second->setWeight(weight, upload_bake);
return TRUE;
}
llwarns << "LLCharacter::setVisualParamWeight() Invalid visual parameter: " << param_name << llendl;
@@ -306,12 +306,12 @@ BOOL LLCharacter::setVisualParamWeight(const char* param_name, F32 weight, BOOL
//-----------------------------------------------------------------------------
// setVisualParamWeight()
//-----------------------------------------------------------------------------
-BOOL LLCharacter::setVisualParamWeight(S32 index, F32 weight, BOOL set_by_user)
+BOOL LLCharacter::setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake)
{
visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index);
if (index_iter != mVisualParamIndexMap.end())
{
- index_iter->second->setWeight(weight, set_by_user);
+ index_iter->second->setWeight(weight, upload_bake);
return TRUE;
}
llwarns << "LLCharacter::setVisualParamWeight() Invalid visual parameter index: " << index << llendl;
diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h
index cb44a32e8a..27e2a51c62 100644
--- a/indra/llcharacter/llcharacter.h
+++ b/indra/llcharacter/llcharacter.h
@@ -203,9 +203,9 @@ public:
void addVisualParam(LLVisualParam *param);
void addSharedVisualParam(LLVisualParam *param);
- virtual BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL set_by_user = FALSE );
- virtual BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL set_by_user = FALSE );
- virtual BOOL setVisualParamWeight(S32 index, F32 weight, BOOL set_by_user = FALSE );
+ virtual BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
+ virtual BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE );
+ virtual BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE );
// get visual param weight by param or name
F32 getVisualParamWeight(LLVisualParam *distortion);
diff --git a/indra/llcharacter/llvisualparam.cpp b/indra/llcharacter/llvisualparam.cpp
index 6232c7588b..297322fe58 100644
--- a/indra/llcharacter/llvisualparam.cpp
+++ b/indra/llcharacter/llvisualparam.cpp
@@ -225,7 +225,7 @@ BOOL LLVisualParam::parseData(LLXmlTreeNode *node)
//-----------------------------------------------------------------------------
// setWeight()
//-----------------------------------------------------------------------------
-void LLVisualParam::setWeight(F32 weight, BOOL set_by_user)
+void LLVisualParam::setWeight(F32 weight, BOOL upload_bake)
{
if (mIsAnimating)
{
@@ -243,19 +243,19 @@ void LLVisualParam::setWeight(F32 weight, BOOL set_by_user)
if (mNext)
{
- mNext->setWeight(weight, set_by_user);
+ mNext->setWeight(weight, upload_bake);
}
}
//-----------------------------------------------------------------------------
// setAnimationTarget()
//-----------------------------------------------------------------------------
-void LLVisualParam::setAnimationTarget(F32 target_value, BOOL set_by_user)
+void LLVisualParam::setAnimationTarget(F32 target_value, BOOL upload_bake)
{
// don't animate dummy parameters
if (mIsDummy)
{
- setWeight(target_value, set_by_user);
+ setWeight(target_value, upload_bake);
return;
}
@@ -274,7 +274,7 @@ void LLVisualParam::setAnimationTarget(F32 target_value, BOOL set_by_user)
if (mNext)
{
- mNext->setAnimationTarget(target_value, set_by_user);
+ mNext->setAnimationTarget(target_value, upload_bake);
}
}
@@ -291,24 +291,24 @@ void LLVisualParam::setNextParam( LLVisualParam *next )
//-----------------------------------------------------------------------------
// animate()
//-----------------------------------------------------------------------------
-void LLVisualParam::animate( F32 delta, BOOL set_by_user )
+void LLVisualParam::animate( F32 delta, BOOL upload_bake )
{
if (mIsAnimating)
{
F32 new_weight = ((mTargetWeight - mCurWeight) * delta) + mCurWeight;
- setWeight(new_weight, set_by_user);
+ setWeight(new_weight, upload_bake);
}
}
//-----------------------------------------------------------------------------
// stopAnimating()
//-----------------------------------------------------------------------------
-void LLVisualParam::stopAnimating(BOOL set_by_user)
+void LLVisualParam::stopAnimating(BOOL upload_bake)
{
if (mIsAnimating && getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
{
mIsAnimating = FALSE;
- setWeight(mTargetWeight, set_by_user);
+ setWeight(mTargetWeight, upload_bake);
}
}
diff --git a/indra/llcharacter/llvisualparam.h b/indra/llcharacter/llvisualparam.h
index eec56d7844..12b45e6ebe 100644
--- a/indra/llcharacter/llvisualparam.h
+++ b/indra/llcharacter/llvisualparam.h
@@ -113,10 +113,10 @@ public:
//virtual BOOL parseData( LLXmlTreeNode *node ) = 0;
virtual void apply( ESex avatar_sex ) = 0;
// Default functions
- virtual void setWeight(F32 weight, BOOL set_by_user);
- virtual void setAnimationTarget( F32 target_value, BOOL set_by_user );
- virtual void animate(F32 delta, BOOL set_by_user);
- virtual void stopAnimating(BOOL set_by_user);
+ virtual void setWeight(F32 weight, BOOL upload_bake);
+ virtual void setAnimationTarget( F32 target_value, BOOL upload_bake );
+ virtual void animate(F32 delta, BOOL upload_bake);
+ virtual void stopAnimating(BOOL upload_bake);
virtual BOOL linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params);
virtual void resetDrivenParams();
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index f40359790a..e41c75846b 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -41,6 +41,7 @@ set(llcommon_SOURCE_FILES
llerror.cpp
llerrorthread.cpp
llevent.cpp
+ lleventapi.cpp
lleventcoro.cpp
lleventdispatcher.cpp
lleventfilter.cpp
@@ -140,6 +141,7 @@ set(llcommon_HEADER_FILES
llerrorlegacy.h
llerrorthread.h
llevent.h
+ lleventapi.h
lleventcoro.h
lleventdispatcher.h
lleventfilter.h
@@ -276,6 +278,7 @@ LL_ADD_INTEGRATION_TEST(lldate "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lldependencies "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llerror "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llframetimer "" "${test_libs}")
+LL_ADD_INTEGRATION_TEST(llinstancetracker "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lllazy "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}")
diff --git a/indra/llcommon/lleventapi.cpp b/indra/llcommon/lleventapi.cpp
new file mode 100644
index 0000000000..1dd104da8f
--- /dev/null
+++ b/indra/llcommon/lleventapi.cpp
@@ -0,0 +1,30 @@
+/**
+ * @file lleventapi.cpp
+ * @author Nat Goodspeed
+ * @date 2009-11-10
+ * @brief Implementation for lleventapi.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "lleventapi.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+
+LLEventAPI::LLEventAPI(const std::string& name, const std::string& desc, const std::string& field):
+ lbase(name, field),
+ ibase(name),
+ mDesc(desc)
+{
+}
+
+LLEventAPI::~LLEventAPI()
+{
+}
diff --git a/indra/llcommon/lleventapi.h b/indra/llcommon/lleventapi.h
new file mode 100644
index 0000000000..2cd3b5bf89
--- /dev/null
+++ b/indra/llcommon/lleventapi.h
@@ -0,0 +1,53 @@
+/**
+ * @file lleventapi.h
+ * @author Nat Goodspeed
+ * @date 2009-10-28
+ * @brief LLEventAPI is the base class for every class that wraps a C++ API
+ * in an event API
+ * (see https://wiki.lindenlab.com/wiki/Incremental_Viewer_Automation/Event_API).
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLEVENTAPI_H)
+#define LL_LLEVENTAPI_H
+
+#include "lleventdispatcher.h"
+#include "llinstancetracker.h"
+#include <string>
+
+/**
+ * LLEventAPI not only provides operation dispatch functionality, inherited
+ * from LLDispatchListener -- it also gives us event API introspection.
+ * Deriving from LLInstanceTracker lets us enumerate instances.
+ */
+class LL_COMMON_API LLEventAPI: public LLDispatchListener,
+ public LLInstanceTracker<LLEventAPI, std::string>
+{
+ typedef LLDispatchListener lbase;
+ typedef LLInstanceTracker<LLEventAPI, std::string> ibase;
+
+public:
+ /**
+ * @param name LLEventPump name on which this LLEventAPI will listen. This
+ * also serves as the LLInstanceTracker instance key.
+ * @param desc Documentation string shown to a client trying to discover
+ * available event APIs.
+ * @param field LLSD::Map key used by LLDispatchListener to look up the
+ * subclass method to invoke [default "op"].
+ */
+ LLEventAPI(const std::string& name, const std::string& desc, const std::string& field="op");
+ virtual ~LLEventAPI();
+
+ /// Get the string name of this LLEventAPI
+ std::string getName() const { return ibase::getKey(); }
+ /// Get the documentation string
+ std::string getDesc() const { return mDesc; }
+
+private:
+ std::string mDesc;
+};
+
+#endif /* ! defined(LL_LLEVENTAPI_H) */
diff --git a/indra/llcommon/lleventdispatcher.cpp b/indra/llcommon/lleventdispatcher.cpp
index 6b1413d054..017bf3a521 100644
--- a/indra/llcommon/lleventdispatcher.cpp
+++ b/indra/llcommon/lleventdispatcher.cpp
@@ -36,9 +36,11 @@ LLEventDispatcher::~LLEventDispatcher()
}
/// Register a callable by name
-void LLEventDispatcher::add(const std::string& name, const Callable& callable, const LLSD& required)
+void LLEventDispatcher::add(const std::string& name, const std::string& desc,
+ const Callable& callable, const LLSD& required)
{
- mDispatch[name] = DispatchMap::mapped_type(callable, required);
+ mDispatch.insert(DispatchMap::value_type(name,
+ DispatchMap::mapped_type(callable, desc, required)));
}
void LLEventDispatcher::addFail(const std::string& name, const std::string& classname) const
@@ -98,14 +100,14 @@ bool LLEventDispatcher::attemptCall(const std::string& name, const LLSD& event)
}
// Found the name, so it's plausible to even attempt the call. But first,
// validate the syntax of the event itself.
- std::string mismatch(llsd_matches(found->second.second, event));
+ std::string mismatch(llsd_matches(found->second.mRequired, event));
if (! mismatch.empty())
{
LL_ERRS("LLEventDispatcher") << "LLEventDispatcher(" << mDesc << ") calling '" << name
<< "': bad request: " << mismatch << LL_ENDL;
}
// Event syntax looks good, go for it!
- (found->second.first)(event);
+ (found->second.mFunc)(event);
return true; // tell caller we were able to call
}
@@ -116,7 +118,7 @@ LLEventDispatcher::Callable LLEventDispatcher::get(const std::string& name) cons
{
return Callable();
}
- return found->second.first;
+ return found->second.mFunc;
}
LLDispatchListener::LLDispatchListener(const std::string& pumpname, const std::string& key):
diff --git a/indra/llcommon/lleventdispatcher.h b/indra/llcommon/lleventdispatcher.h
index 5a86b90bff..eba7b607f1 100644
--- a/indra/llcommon/lleventdispatcher.h
+++ b/indra/llcommon/lleventdispatcher.h
@@ -44,7 +44,10 @@ public:
* is used to validate the structure of each incoming event (see
* llsd_matches()).
*/
- void add(const std::string& name, const Callable& callable, const LLSD& required=LLSD());
+ void add(const std::string& name,
+ const std::string& desc,
+ const Callable& callable,
+ const LLSD& required=LLSD());
/**
* Special case: a subclass of this class can pass an unbound member
@@ -52,18 +55,22 @@ public:
* <tt>boost::bind()</tt> expression.
*/
template <class CLASS>
- void add(const std::string& name, void (CLASS::*method)(const LLSD&),
+ void add(const std::string& name,
+ const std::string& desc,
+ void (CLASS::*method)(const LLSD&),
const LLSD& required=LLSD())
{
- addMethod<CLASS>(name, method, required);
+ addMethod<CLASS>(name, desc, method, required);
}
/// Overload for both const and non-const methods
template <class CLASS>
- void add(const std::string& name, void (CLASS::*method)(const LLSD&) const,
+ void add(const std::string& name,
+ const std::string& desc,
+ void (CLASS::*method)(const LLSD&) const,
const LLSD& required=LLSD())
{
- addMethod<CLASS>(name, method, required);
+ addMethod<CLASS>(name, desc, method, required);
}
/// Unregister a callable
@@ -86,7 +93,8 @@ public:
private:
template <class CLASS, typename METHOD>
- void addMethod(const std::string& name, const METHOD& method, const LLSD& required)
+ void addMethod(const std::string& name, const std::string& desc,
+ const METHOD& method, const LLSD& required)
{
CLASS* downcast = dynamic_cast<CLASS*>(this);
if (! downcast)
@@ -95,7 +103,7 @@ private:
}
else
{
- add(name, boost::bind(method, downcast, _1), required);
+ add(name, desc, boost::bind(method, downcast, _1), required);
}
}
void addFail(const std::string& name, const std::string& classname) const;
@@ -103,7 +111,18 @@ private:
bool attemptCall(const std::string& name, const LLSD& event) const;
std::string mDesc, mKey;
- typedef std::map<std::string, std::pair<Callable, LLSD> > DispatchMap;
+ struct DispatchEntry
+ {
+ DispatchEntry(const Callable& func, const std::string& desc, const LLSD& required):
+ mFunc(func),
+ mDesc(desc),
+ mRequired(required)
+ {}
+ Callable mFunc;
+ std::string mDesc;
+ LLSD mRequired;
+ };
+ typedef std::map<std::string, DispatchEntry> DispatchMap;
DispatchMap mDispatch;
};
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h
index 192d79b27d..f52cf33fd8 100644
--- a/indra/llcommon/llevents.h
+++ b/indra/llcommon/llevents.h
@@ -45,10 +45,12 @@
#include "llsingleton.h"
#include "lldependencies.h"
+/*==========================================================================*|
// override this to allow binding free functions with more parameters
#ifndef LLEVENTS_LISTENER_ARITY
#define LLEVENTS_LISTENER_ARITY 10
#endif
+|*==========================================================================*/
// hack for testing
#ifndef testable
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index ea50acbbc5..11fe523651 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -38,42 +38,73 @@
#include "string_table.h"
#include <boost/utility.hpp>
-
-// This mix-in class adds support for tracking all instances of the specified class parameter T
-// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
-// If KEY is not provided, then instances are stored in a simple set
-// *NOTE: see explicit specialization below for default KEY==T* case
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+#include <boost/iterator/indirect_iterator.hpp>
+
+/// This mix-in class adds support for tracking all instances of the specified class parameter T
+/// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
+/// If KEY is not provided, then instances are stored in a simple set
+/// @NOTE: see explicit specialization below for default KEY==T* case
template<typename T, typename KEY = T*>
class LLInstanceTracker : boost::noncopyable
{
+ typedef typename std::map<KEY, T*> InstanceMap;
+ typedef boost::function<const KEY&(typename InstanceMap::value_type&)> KeyGetter;
+ typedef boost::function<T*(typename InstanceMap::value_type&)> InstancePtrGetter;
public:
- typedef typename std::map<KEY, T*>::iterator instance_iter;
- typedef typename std::map<KEY, T*>::const_iterator instance_const_iter;
-
- static T* getInstance(const KEY& k) { instance_iter found = getMap().find(k); return (found == getMap().end()) ? NULL : found->second; }
+ /// Dereferencing key_iter gives you a const KEY&
+ typedef boost::transform_iterator<KeyGetter, typename InstanceMap::iterator> key_iter;
+ /// Dereferencing instance_iter gives you a T&
+ typedef boost::indirect_iterator< boost::transform_iterator<InstancePtrGetter, typename InstanceMap::iterator> > instance_iter;
+
+ static T* getInstance(const KEY& k)
+ {
+ typename InstanceMap::const_iterator found = getMap_().find(k);
+ return (found == getMap_().end()) ? NULL : found->second;
+ }
- static instance_iter beginInstances() { return getMap().begin(); }
- static instance_iter endInstances() { return getMap().end(); }
- static S32 instanceCount() { return getMap().size(); }
+ static key_iter beginKeys()
+ {
+ return boost::make_transform_iterator(getMap_().begin(),
+ boost::bind(&InstanceMap::value_type::first, _1));
+ }
+ static key_iter endKeys()
+ {
+ return boost::make_transform_iterator(getMap_().end(),
+ boost::bind(&InstanceMap::value_type::first, _1));
+ }
+ static instance_iter beginInstances()
+ {
+ return instance_iter(boost::make_transform_iterator(getMap_().begin(),
+ boost::bind(&InstanceMap::value_type::second, _1)));
+ }
+ static instance_iter endInstances()
+ {
+ return instance_iter(boost::make_transform_iterator(getMap_().end(),
+ boost::bind(&InstanceMap::value_type::second, _1)));
+ }
+ static S32 instanceCount() { return getMap_().size(); }
protected:
- LLInstanceTracker(KEY key) { add(key); }
- virtual ~LLInstanceTracker() { remove(); }
- virtual void setKey(KEY key) { remove(); add(key); }
+ LLInstanceTracker(KEY key) { add_(key); }
+ virtual ~LLInstanceTracker() { remove_(); }
+ virtual void setKey(KEY key) { remove_(); add_(key); }
virtual const KEY& getKey() const { return mKey; }
private:
- void add(KEY key)
+ void add_(KEY key)
{
mKey = key;
- getMap()[key] = static_cast<T*>(this);
+ getMap_()[key] = static_cast<T*>(this);
}
- void remove() { getMap().erase(mKey); }
+ void remove_() { getMap_().erase(mKey); }
- static std::map<KEY, T*>& getMap()
+ static InstanceMap& getMap_()
{
if (! sInstances)
{
- sInstances = new std::map<KEY, T*>;
+ sInstances = new InstanceMap;
}
return *sInstances;
}
@@ -81,41 +112,48 @@ private:
private:
KEY mKey;
- static std::map<KEY, T*>* sInstances;
+ static InstanceMap* sInstances;
};
-// explicit specialization for default case where KEY is T*
-// use a simple std::set<T*>
+/// explicit specialization for default case where KEY is T*
+/// use a simple std::set<T*>
template<typename T>
class LLInstanceTracker<T, T*>
{
+ typedef typename std::set<T*> InstanceSet;
public:
- typedef typename std::set<T*>::iterator instance_iter;
- typedef typename std::set<T*>::const_iterator instance_const_iter;
-
- static instance_iter beginInstances() { return getSet().begin(); }
- static instance_iter endInstances() { return getSet().end(); }
- static S32 instanceCount() { return getSet().size(); }
+ /// Dereferencing key_iter gives you a T* (since T* is the key)
+ typedef typename InstanceSet::iterator key_iter;
+ /// Dereferencing instance_iter gives you a T&
+ typedef boost::indirect_iterator<key_iter> instance_iter;
+
+ /// for completeness of analogy with the generic implementation
+ static T* getInstance(T* k) { return k; }
+ static key_iter beginKeys() { return getSet_().begin(); }
+ static key_iter endKeys() { return getSet_().end(); }
+ static instance_iter beginInstances() { return instance_iter(getSet_().begin()); }
+ static instance_iter endInstances() { return instance_iter(getSet_().end()); }
+ static S32 instanceCount() { return getSet_().size(); }
protected:
- LLInstanceTracker() { getSet().insert(static_cast<T*>(this)); }
- virtual ~LLInstanceTracker() { getSet().erase(static_cast<T*>(this)); }
+ LLInstanceTracker() { getSet_().insert(static_cast<T*>(this)); }
+ virtual ~LLInstanceTracker() { getSet_().erase(static_cast<T*>(this)); }
- LLInstanceTracker(const LLInstanceTracker& other) { getSet().insert(static_cast<T*>(this)); }
+ LLInstanceTracker(const LLInstanceTracker& other) { getSet_().insert(static_cast<T*>(this)); }
- static std::set<T*>& getSet() // called after getReady() but before go()
+ static InstanceSet& getSet_() // called after getReady() but before go()
{
if (! sInstances)
{
- sInstances = new std::set<T*>;
+ sInstances = new InstanceSet;
}
return *sInstances;
}
- static std::set<T*>* sInstances;
+ static InstanceSet* sInstances;
};
-template <typename T, typename KEY> std::map<KEY, T*>* LLInstanceTracker<T, KEY>::sInstances = NULL;
-template <typename T> std::set<T*>* LLInstanceTracker<T, T*>::sInstances = NULL;
+template <typename T, typename KEY> typename LLInstanceTracker<T, KEY>::InstanceMap* LLInstanceTracker<T, KEY>::sInstances = NULL;
+template <typename T> typename LLInstanceTracker<T, T*>::InstanceSet* LLInstanceTracker<T, T*>::sInstances = NULL;
#endif
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index ea5b0c03ef..ef3e8dbc94 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -583,13 +583,13 @@ void LLEventTimer::updateClass()
std::list<LLEventTimer*> completed_timers;
for (instance_iter iter = beginInstances(); iter != endInstances(); )
{
- LLEventTimer* timer = *iter++;
- F32 et = timer->mEventTimer.getElapsedTimeF32();
- if (timer->mEventTimer.getStarted() && et > timer->mPeriod) {
- timer->mEventTimer.reset();
- if ( timer->tick() )
+ LLEventTimer& timer = *iter++;
+ F32 et = timer.mEventTimer.getElapsedTimeF32();
+ if (timer.mEventTimer.getStarted() && et > timer.mPeriod) {
+ timer.mEventTimer.reset();
+ if ( timer.tick() )
{
- completed_timers.push_back( timer );
+ completed_timers.push_back( &timer );
}
}
}
diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp
new file mode 100644
index 0000000000..7415f2d33b
--- /dev/null
+++ b/indra/llcommon/tests/llinstancetracker_test.cpp
@@ -0,0 +1,160 @@
+/**
+ * @file llinstancetracker_test.cpp
+ * @author Nat Goodspeed
+ * @date 2009-11-10
+ * @brief Test for llinstancetracker.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llinstancetracker.h"
+// STL headers
+#include <string>
+#include <vector>
+#include <set>
+#include <algorithm> // std::sort()
+// std headers
+// external library headers
+#include <boost/scoped_ptr.hpp>
+// other Linden headers
+#include "../test/lltut.h"
+
+struct Keyed: public LLInstanceTracker<Keyed, std::string>
+{
+ Keyed(const std::string& name):
+ LLInstanceTracker<Keyed, std::string>(name),
+ mName(name)
+ {}
+ std::string mName;
+};
+
+struct Unkeyed: public LLInstanceTracker<Unkeyed>
+{
+};
+
+/*****************************************************************************
+* TUT
+*****************************************************************************/
+namespace tut
+{
+ struct llinstancetracker_data
+ {
+ };
+ typedef test_group<llinstancetracker_data> llinstancetracker_group;
+ typedef llinstancetracker_group::object object;
+ llinstancetracker_group llinstancetrackergrp("llinstancetracker");
+
+ template<> template<>
+ void object::test<1>()
+ {
+ ensure_equals(Keyed::instanceCount(), 0);
+ {
+ Keyed one("one");
+ ensure_equals(Keyed::instanceCount(), 1);
+ Keyed* found = Keyed::getInstance("one");
+ ensure("couldn't find stack Keyed", found);
+ ensure_equals("found wrong Keyed instance", found, &one);
+ {
+ boost::scoped_ptr<Keyed> two(new Keyed("two"));
+ ensure_equals(Keyed::instanceCount(), 2);
+ Keyed* found = Keyed::getInstance("two");
+ ensure("couldn't find heap Keyed", found);
+ ensure_equals("found wrong Keyed instance", found, two.get());
+ }
+ ensure_equals(Keyed::instanceCount(), 1);
+ }
+ Keyed* found = Keyed::getInstance("one");
+ ensure("Keyed key lives too long", ! found);
+ ensure_equals(Keyed::instanceCount(), 0);
+ }
+
+ template<> template<>
+ void object::test<2>()
+ {
+ ensure_equals(Unkeyed::instanceCount(), 0);
+ {
+ Unkeyed one;
+ ensure_equals(Unkeyed::instanceCount(), 1);
+ Unkeyed* found = Unkeyed::getInstance(&one);
+ ensure_equals(found, &one);
+ {
+ boost::scoped_ptr<Unkeyed> two(new Unkeyed);
+ ensure_equals(Unkeyed::instanceCount(), 2);
+ Unkeyed* found = Unkeyed::getInstance(two.get());
+ ensure_equals(found, two.get());
+ }
+ ensure_equals(Unkeyed::instanceCount(), 1);
+ }
+ ensure_equals(Unkeyed::instanceCount(), 0);
+ }
+
+ template<> template<>
+ void object::test<3>()
+ {
+ Keyed one("one"), two("two"), three("three");
+ // We don't want to rely on the underlying container delivering keys
+ // in any particular order. That allows us the flexibility to
+ // reimplement LLInstanceTracker using, say, a hash map instead of a
+ // std::map. We DO insist that every key appear exactly once.
+ typedef std::vector<std::string> StringVector;
+ StringVector keys(Keyed::beginKeys(), Keyed::endKeys());
+ std::sort(keys.begin(), keys.end());
+ StringVector::const_iterator ki(keys.begin());
+ ensure_equals(*ki++, "one");
+ ensure_equals(*ki++, "three");
+ ensure_equals(*ki++, "two");
+ // Use ensure() here because ensure_equals would want to display
+ // mismatched values, and frankly that wouldn't help much.
+ ensure("didn't reach end", ki == keys.end());
+
+ // Use a somewhat different approach to order independence with
+ // beginInstances(): explicitly capture the instances we know in a
+ // set, and delete them as we iterate through.
+ typedef std::set<Keyed*> InstanceSet;
+ InstanceSet instances;
+ instances.insert(&one);
+ instances.insert(&two);
+ instances.insert(&three);
+ for (Keyed::instance_iter ii(Keyed::beginInstances()), iend(Keyed::endInstances());
+ ii != iend; ++ii)
+ {
+ Keyed& ref = *ii;
+ ensure_equals("spurious instance", instances.erase(&ref), 1);
+ }
+ ensure_equals("unreported instance", instances.size(), 0);
+ }
+
+ template<> template<>
+ void object::test<4>()
+ {
+ Unkeyed one, two, three;
+ typedef std::set<Unkeyed*> KeySet;
+ KeySet keys;
+ keys.insert(&one);
+ keys.insert(&two);
+ keys.insert(&three);
+ for (Unkeyed::key_iter ki(Unkeyed::beginKeys()), kend(Unkeyed::endKeys());
+ ki != kend; ++ki)
+ {
+ ensure_equals("spurious key", keys.erase(*ki), 1);
+ }
+ ensure_equals("unreported key", keys.size(), 0);
+
+ KeySet instances;
+ instances.insert(&one);
+ instances.insert(&two);
+ instances.insert(&three);
+ for (Unkeyed::instance_iter ii(Unkeyed::beginInstances()), iend(Unkeyed::endInstances());
+ ii != iend; ++ii)
+ {
+ Unkeyed& ref = *ii;
+ ensure_equals("spurious instance", instances.erase(&ref), 1);
+ }
+ ensure_equals("unreported instance", instances.size(), 0);
+ }
+} // namespace tut
diff --git a/indra/llmath/llinterp.h b/indra/llmath/llinterp.h
index 8beeef480b..36ca2e9865 100644
--- a/indra/llmath/llinterp.h
+++ b/indra/llmath/llinterp.h
@@ -32,6 +32,13 @@
#ifndef LL_LLINTERP_H
#define LL_LLINTERP_H
+#if defined(LL_WINDOWS)
+// macro definitions for common math constants (e.g. M_PI) are declared under the _USE_MATH_DEFINES
+// on Windows system.
+// So, let's define _USE_MATH_DEFINES before including math.h
+ #define _USE_MATH_DEFINES
+#endif
+
#include "math.h"
// Class from which different types of interpolators can be derived
diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp
index acbf51d75c..104629c157 100644
--- a/indra/llmessage/llares.cpp
+++ b/indra/llmessage/llares.cpp
@@ -106,7 +106,7 @@ void LLAres::QueryResponder::queryError(int code)
LLAres::LLAres() :
chan_(NULL),
mInitSuccess(false),
- mListener(new LLAresListener("LLAres", this))
+ mListener(new LLAresListener(this))
{
if (ares_init(&chan_) != ARES_SUCCESS)
{
diff --git a/indra/llmessage/llareslistener.cpp b/indra/llmessage/llareslistener.cpp
index a8beb8cbde..7db3675b77 100644
--- a/indra/llmessage/llareslistener.cpp
+++ b/indra/llmessage/llareslistener.cpp
@@ -22,13 +22,18 @@
#include "llevents.h"
#include "llsdutil.h"
-LLAresListener::LLAresListener(const std::string& pumpname, LLAres* llares):
- LLDispatchListener(pumpname, "op"),
+LLAresListener::LLAresListener(LLAres* llares):
+ LLEventAPI("LLAres",
+ "LLAres listener to request DNS operations"),
mAres(llares)
{
// add() every method we want to be able to invoke via this event API.
- // Optional third parameter validates expected LLSD request structure.
- add("rewriteURI", &LLAresListener::rewriteURI,
+ // Optional last parameter validates expected LLSD request structure.
+ add("rewriteURI",
+ "Given [\"uri\"], return on [\"reply\"] an array of alternative URIs.\n"
+ "On failure, returns an array containing only the original URI, so\n"
+ "failure case can be processed like success case.",
+ &LLAresListener::rewriteURI,
LLSD().insert("uri", LLSD()).insert("reply", LLSD()));
}
diff --git a/indra/llmessage/llareslistener.h b/indra/llmessage/llareslistener.h
index bf093b3d3d..33cef79c09 100644
--- a/indra/llmessage/llareslistener.h
+++ b/indra/llmessage/llareslistener.h
@@ -14,18 +14,17 @@
#if ! defined(LL_LLARESLISTENER_H)
#define LL_LLARESLISTENER_H
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
class LLAres;
class LLSD;
/// Listen on an LLEventPump with specified name for LLAres request events.
-class LLAresListener: public LLDispatchListener
+class LLAresListener: public LLEventAPI
{
public:
- /// Specify the pump name on which to listen, and bind the LLAres instance
- /// to use (e.g. gAres)
- LLAresListener(const std::string& pumpname, LLAres* llares);
+ /// Bind the LLAres instance to use (e.g. gAres)
+ LLAresListener(LLAres* llares);
private:
/// command["op"] == "rewriteURI"
diff --git a/indra/llprimitive/tests/llmediaentry_test.cpp b/indra/llprimitive/tests/llmediaentry_test.cpp
index dfac5f26c7..277e370ca4 100644
--- a/indra/llprimitive/tests/llmediaentry_test.cpp
+++ b/indra/llprimitive/tests/llmediaentry_test.cpp
@@ -9,7 +9,14 @@
#include "linden_common.h"
#include "lltut.h"
-#include "boost/lexical_cast.hpp"
+#if LL_WINDOWS
+#pragma warning (push)
+#pragma warning (disable : 4702) // boost::lexical_cast generates this warning
+#endif
+#include <boost/lexical_cast.hpp>
+#if LL_WINDOWS
+#pragma warning (pop)
+#endif
#include "llstring.h"
#include "llsdutil.h"
#include "llsdserialize.h"
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index d9520b3bf6..f0df3bcf90 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -61,8 +61,11 @@ BOOL LLRenderTarget::sUseFBO = FALSE;
LLRenderTarget::LLRenderTarget() :
mResX(0),
mResY(0),
+ mViewportWidth(0),
+ mViewportHeight(0),
mTex(0),
mFBO(0),
+ mColorFmt(0),
mDepth(0),
mStencil(0),
mUseDepth(FALSE),
@@ -86,13 +89,31 @@ void LLRenderTarget::setSampleBuffer(LLMultisampleBuffer* buffer)
void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo)
{
+ // only reallocate if something changed
+ if (mResX == resx
+ && mResY == resy
+ && mUseDepth == depth
+ && mStencil == stencil
+ && mUsage == usage
+ && (mFBO != 0) == ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
+ && mColorFmt == color_fmt)
+ {
+ // nothing to do
+ return;
+ }
+
stop_glerror();
mResX = resx;
mResY = resy;
+ // default viewport to entire texture
+ mViewportWidth = mResX;
+ mViewportHeight = mResY;
mStencil = stencil;
mUsage = usage;
mUseDepth = depth;
+ mFBO = 0;
+ mColorFmt = color_fmt;
release();
@@ -312,7 +333,7 @@ void LLRenderTarget::bindTarget()
}
}
- glViewport(0, 0, mResX, mResY);
+ glViewport(0, 0, mViewportWidth, mViewportHeight);
sBoundTarget = this;
}
@@ -515,12 +536,18 @@ BOOL LLRenderTarget::isComplete() const
return (!mTex.empty() || mDepth) ? TRUE : FALSE;
}
+void LLRenderTarget::setViewport(U32 width, U32 height)
+{
+ mViewportWidth = llmin(width, mResX);
+ mViewportHeight = llmin(height, mResY);
+}
+
void LLRenderTarget::getViewport(S32* viewport)
{
viewport[0] = 0;
viewport[1] = 0;
- viewport[2] = mResX;
- viewport[3] = mResY;
+ viewport[2] = mViewportWidth;
+ viewport[3] = mViewportHeight;
}
//==================================================
@@ -581,7 +608,7 @@ void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref)
check_framebuffer_status();
- glViewport(0, 0, mResX, mResY);
+ glViewport(0, 0, mViewportWidth, mViewportHeight);
sBoundTarget = this;
}
@@ -593,13 +620,30 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo, U32 samples )
{
+ if (mResX == resx
+ && mResY == resy
+ && mUseDepth == depth
+ && mStencil == stencil
+ && mUsage == usage
+ && (mFBO != 0) == ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
+ && mColorFmt == color_fmt
+ && mSamples == samples)
+ {
+ // nothing to do
+ return;
+ }
+
stop_glerror();
mResX = resx;
mResY = resy;
+ mViewportWidth = mResX;
+ mViewportHeight = mResY;
mUsage = usage;
mUseDepth = depth;
mStencil = stencil;
+ mFBO = 0;
+ mColorFmt = color_fmt;
releaseSampleBuffer();
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index b7ebfc8f7f..125747424c 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -107,6 +107,9 @@ public:
//uses scissor rect if in copy-to-texture mode
void clear(U32 mask = 0xFFFFFFFF);
+ // override default viewport to a smaller size
+ void setViewport(U32 width, U32 height);
+
//get applied viewport
void getViewport(S32* viewport);
@@ -150,12 +153,16 @@ protected:
friend class LLMultisampleBuffer;
U32 mResX;
U32 mResY;
+ U32 mViewportWidth;
+ U32 mViewportHeight;
std::vector<U32> mTex;
U32 mFBO;
+ U32 mColorFmt;
U32 mDepth;
BOOL mStencil;
BOOL mUseDepth;
BOOL mRenderDepth;
+
LLTexUnit::eTextureType mUsage;
U32 mSamples;
LLMultisampleBuffer* mSampleBuffer;
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index 35a854267a..045505af5b 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -256,7 +256,6 @@ void LLDockControl::on()
{
if (isDockVisible())
{
- mDockableFloater->setCanDrag(false);
mEnabled = true;
mRecalculateDocablePosition = true;
}
@@ -264,7 +263,6 @@ void LLDockControl::on()
void LLDockControl::off()
{
- mDockableFloater->setCanDrag(true);
mEnabled = false;
}
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index f2cdad8854..2a0dcaf333 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -1888,41 +1888,50 @@ void LLFloaterView::reshapeFloater(S32 width, S32 height, BOOL called_from_paren
// dependents use same follow flags as their "dependee"
continue;
}
- LLRect r = floaterp->getRect();
-
- // Compute absolute distance from each edge of screen
- S32 left_offset = llabs(r.mLeft - 0);
- S32 right_offset = llabs(old_width - r.mRight);
-
- S32 top_offset = llabs(old_height - r.mTop);
- S32 bottom_offset = llabs(r.mBottom - 0);
// Make if follow the edge it is closest to
U32 follow_flags = 0x0;
- if (left_offset < right_offset)
+ if (floaterp->isMinimized())
{
- follow_flags |= FOLLOWS_LEFT;
+ follow_flags |= (FOLLOWS_LEFT | FOLLOWS_TOP);
}
else
{
- follow_flags |= FOLLOWS_RIGHT;
- }
+ LLRect r = floaterp->getRect();
- // "No vertical adjustment" usually means that the bottom of the view
- // has been pushed up or down. Hence we want the floaters to follow
- // the top.
- if (!adjust_vertical)
- {
- follow_flags |= FOLLOWS_TOP;
- }
- else if (top_offset < bottom_offset)
- {
- follow_flags |= FOLLOWS_TOP;
- }
- else
- {
- follow_flags |= FOLLOWS_BOTTOM;
+ // Compute absolute distance from each edge of screen
+ S32 left_offset = llabs(r.mLeft - 0);
+ S32 right_offset = llabs(old_width - r.mRight);
+
+ S32 top_offset = llabs(old_height - r.mTop);
+ S32 bottom_offset = llabs(r.mBottom - 0);
+
+
+ if (left_offset < right_offset)
+ {
+ follow_flags |= FOLLOWS_LEFT;
+ }
+ else
+ {
+ follow_flags |= FOLLOWS_RIGHT;
+ }
+
+ // "No vertical adjustment" usually means that the bottom of the view
+ // has been pushed up or down. Hence we want the floaters to follow
+ // the top.
+ if (!adjust_vertical)
+ {
+ follow_flags |= FOLLOWS_TOP;
+ }
+ else if (top_offset < bottom_offset)
+ {
+ follow_flags |= FOLLOWS_TOP;
+ }
+ else
+ {
+ follow_flags |= FOLLOWS_BOTTOM;
+ }
}
floaterp->setFollows(follow_flags);
@@ -2172,16 +2181,16 @@ void LLFloaterView::getMinimizePosition(S32 *left, S32 *bottom)
const LLFloater::Params& default_params = LLFloater::getDefaultParams();
S32 floater_header_size = default_params.header_height;
static LLUICachedControl<S32> minimized_width ("UIMinimizedWidth", 0);
- S32 col = 0;
LLRect snap_rect_local = getLocalSnapRect();
- for(S32 row = snap_rect_local.mBottom;
- row < snap_rect_local.getHeight() - floater_header_size;
- row += floater_header_size ) //loop rows
- {
- for(col = snap_rect_local.mLeft;
- col < snap_rect_local.getWidth() - minimized_width;
- col += minimized_width)
+ for(S32 col = snap_rect_local.mLeft;
+ col < snap_rect_local.getWidth() - minimized_width;
+ col += minimized_width)
+ {
+ for(S32 row = snap_rect_local.mTop - floater_header_size;
+ row > floater_header_size;
+ row -= floater_header_size ) //loop rows
{
+
bool foundGap = TRUE;
for(child_list_const_iter_t child_it = getChildList()->begin();
child_it != getChildList()->end();
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index 03925f922c..eb67e3a561 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -46,7 +46,7 @@ LLFloaterReg::instance_map_t LLFloaterReg::sInstanceMap;
LLFloaterReg::build_map_t LLFloaterReg::sBuildMap;
std::map<std::string,std::string> LLFloaterReg::sGroupMap;
-static LLFloaterRegListener sFloaterRegListener("LLFloaterReg");
+static LLFloaterRegListener sFloaterRegListener;
//*******************************************************
diff --git a/indra/llui/llfloaterreglistener.cpp b/indra/llui/llfloaterreglistener.cpp
index 57d148b5af..029d3b6810 100644
--- a/indra/llui/llfloaterreglistener.cpp
+++ b/indra/llui/llfloaterreglistener.cpp
@@ -21,19 +21,35 @@
#include "llfloater.h"
#include "llbutton.h"
-LLFloaterRegListener::LLFloaterRegListener(const std::string& pumpName):
- LLDispatchListener(pumpName, "op")
+LLFloaterRegListener::LLFloaterRegListener():
+ LLEventAPI("LLFloaterReg",
+ "LLFloaterReg listener to (e.g.) show/hide LLFloater instances")
{
- add("getBuildMap", &LLFloaterRegListener::getBuildMap, LLSD().insert("reply", LLSD()));
+ add("getBuildMap",
+ "Return on [\"reply\"] data about all registered LLFloaterReg floater names",
+ &LLFloaterRegListener::getBuildMap,
+ LLSD().insert("reply", LLSD()));
LLSD requiredName;
requiredName["name"] = LLSD();
- add("showInstance", &LLFloaterRegListener::showInstance, requiredName);
- add("hideInstance", &LLFloaterRegListener::hideInstance, requiredName);
- add("toggleInstance", &LLFloaterRegListener::toggleInstance, requiredName);
+ add("showInstance",
+ "Ask to display the floater specified in [\"name\"]",
+ &LLFloaterRegListener::showInstance,
+ requiredName);
+ add("hideInstance",
+ "Ask to hide the floater specified in [\"name\"]",
+ &LLFloaterRegListener::hideInstance,
+ requiredName);
+ add("toggleInstance",
+ "Ask to toggle the state of the floater specified in [\"name\"]",
+ &LLFloaterRegListener::toggleInstance,
+ requiredName);
LLSD requiredNameButton;
requiredNameButton["name"] = LLSD();
requiredNameButton["button"] = LLSD();
- add("clickButton", &LLFloaterRegListener::clickButton, requiredNameButton);
+ add("clickButton",
+ "Simulate clicking the named [\"button\"] in the visible floater named in [\"name\"]",
+ &LLFloaterRegListener::clickButton,
+ requiredNameButton);
}
void LLFloaterRegListener::getBuildMap(const LLSD& event) const
diff --git a/indra/llui/llfloaterreglistener.h b/indra/llui/llfloaterreglistener.h
index 304ecd1090..a38117f6b0 100644
--- a/indra/llui/llfloaterreglistener.h
+++ b/indra/llui/llfloaterreglistener.h
@@ -12,18 +12,18 @@
#if ! defined(LL_LLFLOATERREGLISTENER_H)
#define LL_LLFLOATERREGLISTENER_H
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
#include <string>
class LLSD;
/// Event API wrapper for LLFloaterReg
-class LLFloaterRegListener: public LLDispatchListener
+class LLFloaterRegListener: public LLEventAPI
{
public:
/// As all public LLFloaterReg methods are static, there's no point in
/// binding an LLFloaterReg instance.
- LLFloaterRegListener(const std::string& pumpName);
+ LLFloaterRegListener();
private:
void getBuildMap(const LLSD& event) const;
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 9399ace1f7..14a6ddb7e0 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -792,8 +792,8 @@ void LLLayoutStack::calcMinExtents()
//static
void LLLayoutStack::updateClass()
{
- for (LLInstanceTracker<LLLayoutStack>::instance_iter it = beginInstances(); it != endInstances(); ++it)
+ for (LLLayoutStack::instance_iter it = beginInstances(); it != endInstances(); ++it)
{
- (*it)->updateLayout();
+ it->updateLayout();
}
}
diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp
index 75f4d6177d..fe4fbe7510 100644
--- a/indra/llui/llnotificationslistener.cpp
+++ b/indra/llui/llnotificationslistener.cpp
@@ -16,10 +16,14 @@
#include "llnotifications.h"
LLNotificationsListener::LLNotificationsListener(LLNotifications & notifications) :
- LLDispatchListener("LLNotifications", "op"),
+ LLEventAPI("LLNotifications",
+ "LLNotifications listener to (e.g.) pop up a notification"),
mNotifications(notifications)
{
- add("requestAdd", &LLNotificationsListener::requestAdd);
+ add("requestAdd",
+ "Add a notification with specified [\"name\"], [\"substitutions\"] and [\"payload\"].\n"
+ "If optional [\"reply\"] specified, arrange to send user response on that LLEventPump.",
+ &LLNotificationsListener::requestAdd);
}
void LLNotificationsListener::requestAdd(const LLSD& event_data) const
diff --git a/indra/llui/llnotificationslistener.h b/indra/llui/llnotificationslistener.h
index 6f71a7c781..9b405d7b4b 100644
--- a/indra/llui/llnotificationslistener.h
+++ b/indra/llui/llnotificationslistener.h
@@ -12,12 +12,12 @@
#ifndef LL_LLNOTIFICATIONSLISTENER_H
#define LL_LLNOTIFICATIONSLISTENER_H
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
class LLNotifications;
class LLSD;
-class LLNotificationsListener : public LLDispatchListener
+class LLNotificationsListener : public LLEventAPI
{
public:
LLNotificationsListener(LLNotifications & notifications);
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 07c0f3ce84..89c4656297 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -512,6 +512,8 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu
// add children using dimensions from referenced xml for consistent layout
setShape(params.rect);
LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instance());
+
+ setXMLFilename(xml_filename);
}
// ask LLUICtrlFactory for filename, since xml_filename might be empty
diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp
index a7c268758a..544352176a 100644
--- a/indra/llui/llscrolllistcell.cpp
+++ b/indra/llui/llscrolllistcell.cpp
@@ -71,7 +71,8 @@ LLScrollListCell* LLScrollListCell::create(const LLScrollListCell::Params& cell_
LLScrollListCell::LLScrollListCell(const LLScrollListCell::Params& p)
-: mWidth(p.width)
+: mWidth(p.width),
+ mToolTip(p.tool_tip)
{}
// virtual
@@ -204,13 +205,28 @@ BOOL LLScrollListText::isText() const
return TRUE;
}
+// virtual
+const std::string &LLScrollListText::getToolTip() const
+{
+ // If base class has a tooltip, return that
+ if (! LLScrollListCell::getToolTip().empty())
+ return LLScrollListCell::getToolTip();
+
+ // ...otherwise, return the value itself as the tooltip
+ return mText.getString();
+}
+
+// virtual
BOOL LLScrollListText::needsToolTip() const
{
- // show tooltips for truncated text
+ // If base class has a tooltip, return that
+ if (LLScrollListCell::needsToolTip())
+ return LLScrollListCell::needsToolTip();
+
+ // ...otherwise, show tooltips for truncated text
return mFont->getWidth(mText.getString()) > getWidth();
}
-
//virtual
BOOL LLScrollListText::getVisible() const
{
diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h
index 758623f121..5fecf5aade 100644
--- a/indra/llui/llscrolllistcell.h
+++ b/indra/llui/llscrolllistcell.h
@@ -66,6 +66,7 @@ public:
Optional<void*> userdata;
Optional<LLSD> value;
+ Optional<std::string> tool_tip;
Optional<const LLFontGL*> font;
Optional<LLColor4> font_color;
@@ -80,6 +81,7 @@ public:
enabled("enabled", true),
visible("visible", true),
value("value"),
+ tool_tip("tool_tip", ""),
font("font", LLFontGL::getFontSansSerifSmall()),
font_color("font_color", LLColor4::black),
color("color", LLColor4::white),
@@ -101,11 +103,13 @@ public:
virtual S32 getHeight() const { return 0; }
virtual const LLSD getValue() const;
virtual void setValue(const LLSD& value) { }
+ virtual const std::string &getToolTip() const { return mToolTip; }
+ virtual void setToolTip(const std::string &str) { mToolTip = str; }
virtual BOOL getVisible() const { return TRUE; }
virtual void setWidth(S32 width) { mWidth = width; }
virtual void highlightText(S32 offset, S32 num_chars) {}
virtual BOOL isText() const { return FALSE; }
- virtual BOOL needsToolTip() const { return FALSE; }
+ virtual BOOL needsToolTip() const { return ! mToolTip.empty(); }
virtual void setColor(const LLColor4&) {}
virtual void onCommit() {};
@@ -114,6 +118,7 @@ public:
private:
S32 mWidth;
+ std::string mToolTip;
};
class LLScrollListSpacer : public LLScrollListCell
@@ -143,6 +148,7 @@ public:
/*virtual*/ void setColor(const LLColor4&);
/*virtual*/ BOOL isText() const;
+ /*virtual*/ const std::string & getToolTip() const;
/*virtual*/ BOOL needsToolTip() const;
void setText(const LLStringExplicit& text);
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 1c2c02e1cc..a53a30b501 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1565,7 +1565,7 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
// display tooltip exactly over original cell, in same font
LLToolTipMgr::instance().show(LLToolTip::Params()
- .message(hit_cell->getValue().asString())
+ .message(hit_cell->getToolTip())
.font(LLFontGL::getFontSansSerifSmall())
.pos(LLCoordGL(sticky_rect.mLeft - 5, sticky_rect.mTop + 6))
.delay_time(0.2f)
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 8d36c9c616..9706878a57 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -994,6 +994,12 @@ void LLTextBase::setColor( const LLColor4& c )
mFgColor = c;
}
+//virtual
+void LLTextBase::setReadOnlyColor(const LLColor4 &c)
+{
+ mReadOnlyFgColor = c;
+}
+
//virtual
void LLTextBase::setValue(const LLSD& value )
{
@@ -2369,7 +2375,9 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
height = mFontHeight;
width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
- return num_chars >= 1 && text[mStart + num_chars - 1] == '\n';
+ // if last character is a newline, then return true, forcing line break
+ llwchar last_char = text[mStart + first_char + num_chars - 1];
+ return num_chars >= 1 && last_char == '\n';
}
S32 LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 8cae8fde22..fb01cd1e7c 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -118,6 +118,8 @@ public:
// LLUICtrl interface
/*virtual*/ BOOL acceptsTextInput() const { return !mReadOnly; }
/*virtual*/ void setColor( const LLColor4& c );
+ virtual void setReadOnlyColor(const LLColor4 &c);
+
/*virtual*/ void setValue(const LLSD& value );
/*virtual*/ LLTextViewModel* getViewModel() const;
diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp
index 984a534da6..bb85177811 100644
--- a/indra/llui/lltooltip.cpp
+++ b/indra/llui/lltooltip.cpp
@@ -172,7 +172,6 @@ LLToolTip::Params::Params()
LLToolTip::LLToolTip(const LLToolTip::Params& p)
: LLPanel(p),
- mMaxWidth(p.max_width),
mHasClickCallback(p.click_callback.isProvided()),
mPadding(p.padding),
mTextBox(NULL),
@@ -181,11 +180,9 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p)
mHomePageButton(NULL)
{
LLTextBox::Params params;
- params.initial_value = "tip_text";
params.name = params.initial_value().asString();
// bake textbox padding into initial rect
params.rect = LLRect (mPadding, mPadding + 1, mPadding + 1, mPadding);
- params.follows.flags = FOLLOWS_ALL;
params.h_pad = 0;
params.v_pad = 0;
params.mouse_opaque = false;
@@ -210,7 +207,6 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p)
TOOLTIP_ICON_SIZE = (imagep ? imagep->getWidth() : 16);
icon_rect.setOriginAndSize(mPadding, mPadding, TOOLTIP_ICON_SIZE, TOOLTIP_ICON_SIZE);
icon_params.rect = icon_rect;
- //icon_params.follows.flags = FOLLOWS_LEFT | FOLLOWS_BOTTOM;
icon_params.image_unselected(imagep);
icon_params.image_selected(imagep);
@@ -281,15 +277,30 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p)
}
}
-void LLToolTip::setValue(const LLSD& value)
+void LLToolTip::initFromParams(const LLToolTip::Params& p)
{
+ LLPanel::initFromParams(p);
+
+ // do this *after* we've had our size set in LLPanel::initFromParams();
const S32 REALLY_LARGE_HEIGHT = 10000;
- reshape(mMaxWidth, REALLY_LARGE_HEIGHT);
+ mTextBox->reshape(p.max_width, REALLY_LARGE_HEIGHT);
- mTextBox->setValue(value);
+ if (p.styled_message.isProvided())
+ {
+ for (LLInitParam::ParamIterator<LLToolTip::StyledText>::const_iterator text_it = p.styled_message().begin();
+ text_it != p.styled_message().end();
+ ++text_it)
+ {
+ mTextBox->appendText(text_it->text(), false, text_it->style);
+ }
+ }
+ else
+ {
+ mTextBox->setText(p.message());
+ }
LLRect text_contents_rect = mTextBox->getContentsRect();
- S32 text_width = llmin(mMaxWidth, text_contents_rect.getWidth());
+ S32 text_width = llmin(p.max_width(), text_contents_rect.getWidth());
S32 text_height = text_contents_rect.getHeight();
mTextBox->reshape(text_width, text_height);
@@ -300,7 +311,7 @@ void LLToolTip::setValue(const LLSD& value)
tooltip_rect.mBottom = 0;
tooltip_rect.mLeft = 0;
- setRect(tooltip_rect);
+ setShape(tooltip_rect);
}
void LLToolTip::setVisible(BOOL visible)
@@ -411,9 +422,8 @@ void LLToolTipMgr::createToolTip(const LLToolTip::Params& params)
}
tooltip_params.rect = LLRect (0, 1, 1, 0);
-
mToolTip = LLUICtrlFactory::create<LLToolTip> (tooltip_params);
- mToolTip->setValue(params.message());
+
gToolTipView->addChild(mToolTip);
if (params.pos.isProvided())
diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h
index 774ca507c1..8c8fdf0a4c 100644
--- a/indra/llui/lltooltip.h
+++ b/indra/llui/lltooltip.h
@@ -37,6 +37,7 @@
#include "llsingleton.h"
#include "llinitparam.h"
#include "llpanel.h"
+#include "llstyle.h"
//
// Classes
@@ -65,11 +66,19 @@ public:
class LLToolTip : public LLPanel
{
public:
+
+ struct StyledText : public LLInitParam::Block<StyledText>
+ {
+ Mandatory<std::string> text;
+ Optional<LLStyle::Params> style;
+ };
+
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
typedef boost::function<void(void)> click_callback_t;
- Mandatory<std::string> message;
+ Optional<std::string> message;
+ Multiple<StyledText> styled_message;
Optional<LLCoordGL> pos;
Optional<F32> delay_time,
@@ -85,8 +94,8 @@ public:
Optional<click_callback_t> click_callback,
click_playmedia_callback,
click_homepage_callback;
- Optional<S32> max_width;
- Optional<S32> padding;
+ Optional<S32> max_width,
+ padding;
Optional<bool> wrap;
Params();
@@ -94,7 +103,6 @@ public:
/*virtual*/ void draw();
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
- /*virtual*/ void setValue(const LLSD& value);
/*virtual*/ void setVisible(BOOL visible);
bool isFading();
@@ -102,6 +110,7 @@ public:
bool hasClickCallback();
LLToolTip(const Params& p);
+ void initFromParams(const LLToolTip::Params& params);
private:
class LLTextBox* mTextBox;
@@ -111,7 +120,6 @@ private:
LLFrameTimer mFadeTimer;
LLFrameTimer mVisibleTimer;
- S32 mMaxWidth;
bool mHasClickCallback;
S32 mPadding; // pixels
};
diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp
index 851091f0ca..f1e3000547 100644
--- a/indra/llui/lluicolortable.cpp
+++ b/indra/llui/lluicolortable.cpp
@@ -69,7 +69,14 @@ void LLUIColorTable::insertFromParams(const Params& p)
ColorEntryParams color_entry = *it;
if(color_entry.color.value.isChosen())
{
- setColor(color_entry.name, color_entry.color.value, mLoadedColors);
+ if(mUserSetColors.find(color_entry.name)!=mUserSetColors.end())
+ {
+ setColor(color_entry.name, color_entry.color.value);
+ }
+ else
+ {
+ setColor(color_entry.name, color_entry.color.value, mLoadedColors);
+ }
}
else
{
@@ -213,7 +220,7 @@ bool LLUIColorTable::loadFromSettings()
result |= loadFromFilename(current_filename);
}
- std::string user_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SKIN, "colors.xml");
+ std::string user_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "colors.xml");
loadFromFilename(user_filename);
return result;
@@ -239,7 +246,7 @@ void LLUIColorTable::saveUserSettings() const
if(!output_node->isNull())
{
- const std::string& filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SKIN, "colors.xml");
+ const std::string& filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "colors.xml");
LLFILE *fp = LLFile::fopen(filename, "w");
if(fp != NULL)
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 08fc8fb784..aaadc1b58d 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -38,6 +38,10 @@
#include "llpanel.h"
#include "lluictrlfactory.h"
+// This breaks the ability to construct dummy LLUICtrls for calls like
+// getChild<LLUICtrl>("not-there")
+//static LLWidgetNameRegistry::StaticRegistrar r(&typeid(LLUICtrl::Params), "ui_ctrl");
+// This doesn't appear to read/apply ui_ctrl.xml
static LLDefaultChildRegistry::Register<LLUICtrl> r("ui_ctrl");
LLUICtrl::Params::Params()
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index dae4b512d1..219fae84be 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -512,50 +512,6 @@ std::string LLUrlEntryTeleport::getLocation(const std::string &url) const
return ::getStringAfterToken(url, "app/teleport/");
}
-///
-/// LLUrlEntryObjectIM Describes a Second Life object instant msg Url, e.g.,
-/// secondlife:///app/objectim/<sessionid>
-///
-LLUrlEntryObjectIM::LLUrlEntryObjectIM()
-{
- mPattern = boost::regex("secondlife:///app/objectim/[\\da-f-]+\\??\\S*",
- boost::regex::perl|boost::regex::icase);
- mMenuName = "menu_url_objectim.xml";
- mTooltip = LLTrans::getString("TooltipObjectIMUrl");
-}
-
-std::string LLUrlEntryObjectIM::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
-{
- LLURI uri(url);
- LLSD params = uri.queryMap();
- if (params.has("name"))
- {
- // look for a ?name=<obj-name> param in the url
- // and use that as the label if present.
- std::string name = params.get("name");
- LLStringUtil::trim(name);
- if (name.empty())
- {
- name = LLTrans::getString("Unnamed");
- }
- return name;
- }
-
- return unescapeUrl(url);
-}
-
-std::string LLUrlEntryObjectIM::getLocation(const std::string &url) const
-{
- LLURI uri(url);
- LLSD params = uri.queryMap();
- if (params.has("slurl"))
- {
- return params.get("slurl");
- }
-
- return "";
-}
-
//
// LLUrlEntrySL Describes a generic SLURL, e.g., a Url that starts
// with secondlife:// (used as a catch-all for cases not matched above)
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 4507572b1e..7970b48eb5 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -209,18 +209,6 @@ public:
};
///
-/// LLUrlEntryObjectIM Describes a Second Life object instant msg Url, e.g.,
-/// secondlife:///app/objectim/<sessionid>?name=Foo
-///
-class LLUrlEntryObjectIM : public LLUrlEntryBase
-{
-public:
- LLUrlEntryObjectIM();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ std::string getLocation(const std::string &url) const;
-};
-
-///
/// LLUrlEntrySL Describes a generic SLURL, e.g., a Url that starts
/// with secondlife:// (used as a catch-all for cases not matched above)
///
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index 60275b60bc..a6922b019b 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -52,7 +52,6 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(new LLUrlEntryParcel());
registerUrl(new LLUrlEntryTeleport());
registerUrl(new LLUrlEntryWorldMap());
- registerUrl(new LLUrlEntryObjectIM());
registerUrl(new LLUrlEntryPlace());
registerUrl(new LLUrlEntrySL());
registerUrl(new LLUrlEntrySLLabel());
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 13c381edae..9d44f34ea8 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -246,11 +246,13 @@ set(viewer_SOURCE_FILES
llinspectavatar.cpp
llinspectgroup.cpp
llinspectobject.cpp
+ llinspectremoteobject.cpp
llinventorybridge.cpp
llinventoryclipboard.cpp
llinventoryfilter.cpp
llinventoryfunctions.cpp
llinventorymodel.cpp
+ llinventoryobserver.cpp
llinventorypanel.cpp
llinventorysubtreepanel.cpp
lljoystickbutton.cpp
@@ -741,11 +743,13 @@ set(viewer_HEADER_FILES
llinspectavatar.h
llinspectgroup.h
llinspectobject.h
+ llinspectremoteobject.h
llinventorybridge.h
llinventoryclipboard.h
llinventoryfilter.h
llinventoryfunctions.h
llinventorymodel.h
+ llinventoryobserver.h
llinventorypanel.h
llinventorysubtreepanel.h
lljoystickbutton.h
@@ -1379,7 +1383,7 @@ if (WINDOWS)
${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.sln
--workingdir
${VIEWER_BINARY_NAME}
- "./${CMAKE_CFG_INTDIR}"
+ "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Setting the ${VIEWER_BINARY_NAME} working directory for debugging."
)
endif (NOT UNATTENDED)
diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml
index d7bb64ce8a..ec80d2d014 100644
--- a/indra/newview/app_settings/logcontrol.xml
+++ b/indra/newview/app_settings/logcontrol.xml
@@ -34,6 +34,7 @@
</array>
<key>classes</key>
<array>
+ <string>LLBottomTray</string>
</array>
<key>files</key>
<array>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 15c9499bbc..eb4148f92f 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4259,7 +4259,29 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>LogMessages</key>
+ <key>LoginSRVTimeout</key>
+ <map>
+ <key>Comment</key>
+ <string>Duration in seconds of the login SRV request timeout</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>10.0</real>
+ </map>
+ <key>LoginSRVPump</key>
+ <map>
+ <key>Comment</key>
+ <string>Name of the message pump that handles SRV request</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>LLAres</string>
+ </map>
+ <key>LogMessages</key>
<map>
<key>Comment</key>
<string>Log network traffic</string>
@@ -5501,7 +5523,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>QAMode</key>
<map>
diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp
index 0f00078b33..b3ed7c353e 100644
--- a/indra/newview/llagentlistener.cpp
+++ b/indra/newview/llagentlistener.cpp
@@ -22,12 +22,20 @@
#include "llviewerregion.h"
LLAgentListener::LLAgentListener(LLAgent &agent)
- : LLDispatchListener("LLAgent", "op"),
+ : LLEventAPI("LLAgent",
+ "LLAgent listener to (e.g.) teleport, sit, stand, etc."),
mAgent(agent)
{
- add("requestTeleport", &LLAgentListener::requestTeleport);
- add("requestSit", &LLAgentListener::requestSit);
- add("requestStand", &LLAgentListener::requestStand);
+ add("requestTeleport",
+ "Teleport: [\"regionname\"], [\"x\"], [\"y\"], [\"z\"]\n"
+ "If [\"skip_confirmation\"] is true, use LLURLDispatcher rather than LLCommandDispatcher.",
+ &LLAgentListener::requestTeleport);
+ add("requestSit",
+ "Ask to sit on the object specified in [\"obj_uuid\"]",
+ &LLAgentListener::requestSit);
+ add("requestStand",
+ "Ask to stand up",
+ &LLAgentListener::requestStand);
}
void LLAgentListener::requestTeleport(LLSD const & event_data) const
@@ -40,7 +48,7 @@ void LLAgentListener::requestTeleport(LLSD const & event_data) const
params.append(event_data["y"]);
params.append(event_data["z"]);
LLCommandDispatcher::dispatch("teleport", params, LLSD(), NULL, true);
- // *TODO - lookup other LLCommandHandlers for "agent", "classified", "event", "group", "floater", "objectim", "parcel", "login", login_refresh", "balance", "chat"
+ // *TODO - lookup other LLCommandHandlers for "agent", "classified", "event", "group", "floater", "parcel", "login", login_refresh", "balance", "chat"
// should we just compose LLCommandHandler and LLDispatchListener?
}
else
diff --git a/indra/newview/llagentlistener.h b/indra/newview/llagentlistener.h
index 6f0b5a54c5..eed6922b3e 100644
--- a/indra/newview/llagentlistener.h
+++ b/indra/newview/llagentlistener.h
@@ -13,12 +13,12 @@
#ifndef LL_LLAGENTLISTENER_H
#define LL_LLAGENTLISTENER_H
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
class LLAgent;
class LLSD;
-class LLAgentListener : public LLDispatchListener
+class LLAgentListener : public LLEventAPI
{
public:
LLAgentListener(LLAgent &agent);
diff --git a/indra/newview/llagentui.cpp b/indra/newview/llagentui.cpp
index 2911a35581..568ac4164a 100644
--- a/indra/newview/llagentui.cpp
+++ b/indra/newview/llagentui.cpp
@@ -159,19 +159,19 @@ BOOL LLAgentUI::buildLocationString(std::string& str, ELocationFormat fmt,const
buffer = llformat("%.100s", parcel_name.c_str());
break;
case LOCATION_FORMAT_NORMAL:
- buffer = llformat("%s, %s", region_name.c_str(), parcel_name.c_str());
+ buffer = llformat("%s, %s", parcel_name.c_str(), region_name.c_str());
break;
case LOCATION_FORMAT_WITHOUT_SIM:
buffer = llformat("%s, %s (%d, %d, %d)",
- region_name.c_str(),
parcel_name.c_str(),
+ region_name.c_str(),
pos_x, pos_y, pos_z);
break;
case LOCATION_FORMAT_FULL:
std::string sim_access_string = region->getSimAccessString();
buffer = llformat("%s, %s (%d, %d, %d)%s%s",
- region_name.c_str(),
parcel_name.c_str(),
+ region_name.c_str(),
pos_x, pos_y, pos_z,
sim_access_string.empty() ? "" : " - ",
sim_access_string.c_str());
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 3fc1055acd..9b4986247f 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -887,9 +887,8 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
lldebugs << " " << LLWearableDictionary::getTypeLabel(type) << llendl;
}
- // What we do here is get the complete information on the items in
- // the inventory, and set up an observer that will wait for that to
- // happen.
+ // Get the complete information on the items in the inventory and set up an observer
+ // that will trigger when the complete information is fetched.
LLInventoryFetchDescendentsObserver::folder_ref_t folders;
folders.push_back(current_outfit_id);
outfit->fetchDescendents(folders);
@@ -1985,14 +1984,14 @@ bool LLAgentWearables::canWearableBeRemoved(const LLWearable* wearable) const
return !(((type == WT_SHAPE) || (type == WT_SKIN) || (type == WT_HAIR) || (type == WT_EYES))
&& (getWearableCount(type) <= 1) );
}
-void LLAgentWearables::animateAllWearableParams(F32 delta, BOOL set_by_user)
+void LLAgentWearables::animateAllWearableParams(F32 delta, BOOL upload_bake)
{
for( S32 type = 0; type < WT_COUNT; ++type )
{
for (S32 count = 0; count < (S32)getWearableCount((EWearableType)type); ++count)
{
LLWearable *wearable = getWearable((EWearableType)type,count);
- wearable->animateParams(delta, set_by_user);
+ wearable->animateParams(delta, upload_bake);
}
}
}
@@ -2023,6 +2022,8 @@ void LLInitialWearablesFetch::done()
else
{
processWearablesMessage();
+ // Create links for attachments that may have arrived before the COF existed.
+ LLAppearanceManager::linkRegisteredAttachments();
}
delete this;
}
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index 317f4a7e4f..9017c25fc6 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -80,7 +80,7 @@ public:
// Note: False for shape, skin, eyes, and hair, unless you have MORE than 1.
bool canWearableBeRemoved(const LLWearable* wearable) const;
- void animateAllWearableParams(F32 delta, BOOL set_by_user);
+ void animateAllWearableParams(F32 delta, BOOL upload_bake);
//--------------------------------------------------------------------
// Accessors
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index d14de1c301..0901289dac 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1123,6 +1123,7 @@ void LLAppearanceManager::wearItem( LLInventoryItem* item, bool do_update )
{
if (do_update)
LLAppearanceManager::updateAppearanceFromCOF();
+ return;
}
else
{
@@ -1134,6 +1135,7 @@ void LLAppearanceManager::wearItem( LLInventoryItem* item, bool do_update )
LLAssetType::AT_LINK,
cb);
}
+ return;
}
/* static */
@@ -1281,3 +1283,22 @@ void LLAppearanceManager::unregisterAttachment(const LLUUID& item_id)
//llinfos << "no link changes, inv link not enabled" << llendl;
}
}
+
+/* static */
+void LLAppearanceManager::linkRegisteredAttachments()
+{
+ for (std::set<LLUUID>::iterator it = sRegisteredAttachments.begin();
+ it != sRegisteredAttachments.end();
+ ++it)
+ {
+ LLUUID item_id = *it;
+ LLViewerInventoryItem *item = gInventory.getItem(item_id);
+ if (item)
+ {
+ wearItem(item, false);
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
+ gInventory.notifyObservers();
+ }
+ }
+ sRegisteredAttachments.clear();
+}
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 56f54dfc23..7dea16b6cf 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -71,6 +71,7 @@ public:
static void unregisterAttachment(const LLUUID& item_id);
static void registerAttachment(const LLUUID& item_id);
static void setAttachmentInvLinkEnable(bool val);
+ static void linkRegisteredAttachments();
private:
static void filterWearableItems(LLInventoryModel::item_array_t& items, S32 max_per_type);
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index ddb6589b49..845a264327 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -207,7 +207,7 @@
#pragma warning (disable:4702)
#endif
-static LLAppViewerListener sAppViewerListener("LLAppViewer", LLAppViewer::instance);
+static LLAppViewerListener sAppViewerListener(LLAppViewer::instance);
////// Windows-specific includes to the bottom - nasty defines in these pollute the preprocessor
//
diff --git a/indra/newview/llappviewerlistener.cpp b/indra/newview/llappviewerlistener.cpp
index 3259309eee..adb5f43c1a 100644
--- a/indra/newview/llappviewerlistener.cpp
+++ b/indra/newview/llappviewerlistener.cpp
@@ -19,14 +19,18 @@
// other Linden headers
#include "llappviewer.h"
-LLAppViewerListener::LLAppViewerListener(const std::string& pumpname,
- const LLAppViewerGetter& getter):
- LLDispatchListener(pumpname, "op"),
+LLAppViewerListener::LLAppViewerListener(const LLAppViewerGetter& getter):
+ LLEventAPI("LLAppViewer",
+ "LLAppViewer listener to (e.g.) request shutdown"),
mAppViewerGetter(getter)
{
// add() every method we want to be able to invoke via this event API.
- add("requestQuit", &LLAppViewerListener::requestQuit);
- add("forceQuit", &LLAppViewerListener::forceQuit);
+ add("requestQuit",
+ "Ask to quit nicely",
+ &LLAppViewerListener::requestQuit);
+ add("forceQuit",
+ "Quit abruptly",
+ &LLAppViewerListener::forceQuit);
}
void LLAppViewerListener::requestQuit(const LLSD& event)
diff --git a/indra/newview/llappviewerlistener.h b/indra/newview/llappviewerlistener.h
index 73227cb95a..deedcbc179 100644
--- a/indra/newview/llappviewerlistener.h
+++ b/indra/newview/llappviewerlistener.h
@@ -12,20 +12,19 @@
#if ! defined(LL_LLAPPVIEWERLISTENER_H)
#define LL_LLAPPVIEWERLISTENER_H
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
#include <boost/function.hpp>
class LLAppViewer;
class LLSD;
/// Listen on an LLEventPump with specified name for LLAppViewer request events.
-class LLAppViewerListener: public LLDispatchListener
+class LLAppViewerListener: public LLEventAPI
{
public:
typedef boost::function<LLAppViewer*(void)> LLAppViewerGetter;
- /// Specify the pump name on which to listen, and bind the LLAppViewer
- /// instance to use (e.g. LLAppViewer::instance()).
- LLAppViewerListener(const std::string& pumpname, const LLAppViewerGetter& getter);
+ /// Bind the LLAppViewer instance to use (e.g. LLAppViewer::instance()).
+ LLAppViewerListener(const LLAppViewerGetter& getter);
private:
void requestQuit(const LLSD& event);
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index dae4296a82..ee4a9df15f 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -54,11 +54,15 @@
#include "llmutelist.h"
#include "llrecentpeople.h"
#include "llsidetray.h"
+#include "lltrans.h"
#include "llviewerobjectlist.h"
#include "llviewermessage.h" // for handle_lure
#include "llviewerregion.h"
#include "llimfloater.h"
+#include "lltrans.h"
+// callback connection to auto-call when the IM floater initializes
+boost::signals2::connection gAdhocAutoCall;
// static
void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
@@ -188,7 +192,7 @@ void LLAvatarActions::startIM(const LLUUID& id)
// static
void LLAvatarActions::startCall(const LLUUID& id)
{
- if (id.isNull() || isCalling(id))
+ if (id.isNull())
{
return;
}
@@ -206,6 +210,39 @@ void LLAvatarActions::startCall(const LLUUID& id)
}
// static
+void LLAvatarActions::startAdhocCall(const std::vector<LLUUID>& ids)
+{
+ if (ids.size() == 0)
+ {
+ return;
+ }
+
+ // convert vector into LLDynamicArray for addSession
+ LLDynamicArray<LLUUID> id_array;
+ for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ id_array.push_back(*it);
+ }
+
+ // create the new ad hoc voice session
+ const std::string title = LLTrans::getString("conference-title");
+ LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START,
+ ids[0], id_array);
+ if (session_id == LLUUID::null)
+ {
+ return;
+ }
+
+ // always open IM window when connecting to voice
+ LLIMFloater::show(session_id);
+
+ // start the call once the floater has fully initialized
+ gAdhocAutoCall = LLIMModel::getInstance()->addSessionInitializedCallback(callbackAutoStartCall);
+
+ make_ui_sound("UISndStartIM");
+}
+
+// static
bool LLAvatarActions::isCalling(const LLUUID &id)
{
if (id.isNull())
@@ -226,7 +263,8 @@ void LLAvatarActions::startConference(const std::vector<LLUUID>& ids)
{
id_array.push_back(*it);
}
- LLUUID session_id = gIMMgr->addSession("Friends Conference", IM_SESSION_CONFERENCE_START, ids[0], id_array);
+ const std::string title = LLTrans::getString("conference-title");
+ LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, ids[0], id_array);
if (session_id != LLUUID::null)
{
LLIMFloater::show(session_id);
@@ -394,6 +432,17 @@ bool LLAvatarActions::callbackAddFriend(const LLSD& notification, const LLSD& re
}
// static
+void LLAvatarActions::callbackAutoStartCall(const LLSD& data)
+{
+ // start the adhoc voice call now the IM panel has initialized
+ LLUUID session_id = data["session_id"].asUUID();
+ gIMMgr->startCall(session_id);
+
+ // and deschedule this callback as its work is done now
+ gAdhocAutoCall.disconnect();
+}
+
+// static
void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message)
{
const LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 0ec20ae357..66ea6880db 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -33,6 +33,13 @@
#ifndef LL_LLAVATARACTIONS_H
#define LL_LLAVATARACTIONS_H
+#include "lldarray.h"
+#include "llsd.h"
+#include "lluuid.h"
+
+#include <string>
+#include <vector>
+
/**
* Friend-related actions (add, remove, offer teleport, etc)
*/
@@ -72,6 +79,11 @@ public:
static void startCall(const LLUUID& id);
/**
+ * Start an ad-hoc conference voice call with multiple users
+ */
+ static void startAdhocCall(const std::vector<LLUUID>& ids);
+
+ /**
* Start conference chat with the given avatars.
*/
static void startConference(const std::vector<LLUUID>& ids);
@@ -117,6 +129,7 @@ private:
static bool handleRemove(const LLSD& notification, const LLSD& response);
static bool handlePay(const LLSD& notification, const LLSD& response, LLUUID avatar_id);
static void callback_invite_to_group(LLUUID group_id, LLUUID id);
+ static void callbackAutoStartCall(const LLSD& data);
// Just request friendship, no dialog.
static void requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message);
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index 0ee3e78409..327d80ba34 100644
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -143,7 +143,8 @@ void LLAvatarIconIDCache::remove (const LLUUID& avatar_id)
LLAvatarIconCtrl::Params::Params()
: avatar_id("avatar_id"),
- draw_tooltip("draw_tooltip", true)
+ draw_tooltip("draw_tooltip", true),
+ default_icon_name("default_icon_name")
{
name = "avatar_icon";
}
@@ -151,7 +152,8 @@ LLAvatarIconCtrl::Params::Params()
LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p)
: LLIconCtrl(p),
- mDrawTooltip(p.draw_tooltip)
+ mDrawTooltip(p.draw_tooltip),
+ mDefaultIconName(p.default_icon_name)
{
mPriority = LLViewerFetchedTexture::BOOST_ICON;
@@ -193,16 +195,8 @@ LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p)
}
else
{
- LLIconCtrl::setValue("default_profile_picture.j2c");
+ LLIconCtrl::setValue(mDefaultIconName);
}
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-
- registrar.add("AvatarIcon.Action", boost::bind(&LLAvatarIconCtrl::onAvatarIconContextMenuItemClicked, this, _2));
-
- LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-
- mPopupMenuHandle = menu->getHandle();
}
LLAvatarIconCtrl::~LLAvatarIconCtrl()
@@ -212,8 +206,6 @@ LLAvatarIconCtrl::~LLAvatarIconCtrl()
LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId, this);
// Name callbacks will be automatically disconnected since LLUICtrl is trackable
}
-
- LLView::deleteViewByHandle(mPopupMenuHandle);
}
//virtual
@@ -270,7 +262,7 @@ bool LLAvatarIconCtrl::updateFromCache()
}
else
{
- LLIconCtrl::setValue("default_profile_picture.j2c");
+ LLIconCtrl::setValue(mDefaultIconName);
}
return true;
@@ -295,32 +287,6 @@ void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type)
}
}
-BOOL LLAvatarIconCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
- LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
-
- if(menu)
- {
- bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarId) != NULL;
-
- menu->setItemEnabled("Add Friend", !is_friend);
- menu->setItemEnabled("Remove Friend", is_friend);
-
- if(gAgentID == mAvatarId)
- {
- menu->setItemEnabled("Add Friend", false);
- menu->setItemEnabled("Send IM", false);
- menu->setItemEnabled("Remove Friend", false);
- }
-
- menu->buildDrawLabels();
- menu->updateParent(LLMenuGL::sMenuContainer);
- LLMenuGL::showPopup(this, menu, x, y);
- }
-
- return TRUE;
-}
-
void LLAvatarIconCtrl::nameUpdatedCallback(
const LLUUID& id,
const std::string& first,
@@ -338,40 +304,3 @@ void LLAvatarIconCtrl::nameUpdatedCallback(
}
}
}
-
-void LLAvatarIconCtrl::onAvatarIconContextMenuItemClicked(const LLSD& userdata)
-{
- std::string level = userdata.asString();
- LLUUID id = getAvatarId();
-
- if (level == "profile")
- {
- LLAvatarActions::showProfile(id);
- }
- else if (level == "im")
- {
- std::string name;
- name.assign(getFirstName());
- name.append(" ");
- name.append(getLastName());
-
- LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, id);
- if (session_id != LLUUID::null)
- {
- LLIMFloater::show(session_id);
- }
- }
- else if (level == "add")
- {
- std::string name;
- name.assign(getFirstName());
- name.append(" ");
- name.append(getLastName());
-
- LLAvatarActions::requestFriendshipDialog(id, name);
- }
- else if (level == "remove")
- {
- LLAvatarActions::removeFriendDialog(id);
- }
-}
diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h
index 65b5c86ed5..38616b7852 100644
--- a/indra/newview/llavatariconctrl.h
+++ b/indra/newview/llavatariconctrl.h
@@ -74,6 +74,7 @@ public:
{
Optional <LLUUID> avatar_id;
Optional <bool> draw_tooltip;
+ Optional <std::string> default_icon_name;
Params();
};
@@ -81,8 +82,6 @@ protected:
LLAvatarIconCtrl(const Params&);
friend class LLUICtrlFactory;
- void onAvatarIconContextMenuItemClicked(const LLSD& userdata);
-
public:
virtual ~LLAvatarIconCtrl();
@@ -91,8 +90,6 @@ public:
// LLAvatarPropertiesProcessor observer trigger
virtual void processProperties(void* data, EAvatarProcessorType type);
- BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
-
void nameUpdatedCallback(
const LLUUID& id,
const std::string& first,
@@ -109,9 +106,8 @@ protected:
LLUUID mAvatarId;
std::string mFirstName;
std::string mLastName;
- LLHandle<LLView> mPopupMenuHandle;
bool mDrawTooltip;
-
+ std::string mDefaultIconName;
bool updateFromCache();
};
diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp
index 73e24ca8e7..7cda2d31e6 100644
--- a/indra/newview/llavatarpropertiesprocessor.cpp
+++ b/indra/newview/llavatarpropertiesprocessor.cpp
@@ -158,6 +158,11 @@ void LLAvatarPropertiesProcessor::sendAvatarTexturesRequest(const LLUUID& avatar
removePendingRequest(avatar_id, APT_TEXTURES);
}
+void LLAvatarPropertiesProcessor::sendAvatarClassifiedsRequest(const LLUUID& avatar_id)
+{
+ sendGenericRequest(avatar_id, APT_CLASSIFIEDS, "avatarclassifiedsrequest");
+}
+
void LLAvatarPropertiesProcessor::sendAvatarPropertiesUpdate(const LLAvatarData* avatar_props)
{
llinfos << "Sending avatarinfo update" << llendl;
@@ -284,12 +289,60 @@ void LLAvatarPropertiesProcessor::processAvatarInterestsReply(LLMessageSystem* m
*/
}
-void LLAvatarPropertiesProcessor::processAvatarClassifiedReply(LLMessageSystem* msg, void**)
+void LLAvatarPropertiesProcessor::processAvatarClassifiedsReply(LLMessageSystem* msg, void**)
{
- // avatarclassifiedsrequest is not sent according to new UI design but
- // keep this method according to resolved issues.
+ LLAvatarClassifieds classifieds;
+
+ msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, classifieds.agent_id);
+ msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, classifieds.target_id);
+
+ S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data);
+
+ for(int n = 0; n < block_count; ++n)
+ {
+ LLAvatarClassifieds::classified_data data;
+
+ msg->getUUID(_PREHASH_Data, _PREHASH_ClassifiedID, data.classified_id, n);
+ msg->getString(_PREHASH_Data, _PREHASH_Name, data.name, n);
+
+ classifieds.classifieds_list.push_back(data);
+ }
+
+ LLAvatarPropertiesProcessor* self = getInstance();
+ // Request processed, no longer pending
+ self->removePendingRequest(classifieds.target_id, APT_CLASSIFIEDS);
+ self->notifyObservers(classifieds.target_id,&classifieds,APT_CLASSIFIEDS);
}
+void LLAvatarPropertiesProcessor::processClassifiedInfoReply(LLMessageSystem* msg, void**)
+{
+ LLAvatarClassifiedInfo c_info;
+
+ msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, c_info.agent_id);
+
+ msg->getUUID(_PREHASH_Data, _PREHASH_ClassifiedID, c_info.classified_id);
+ msg->getUUID(_PREHASH_Data, _PREHASH_CreatorID, c_info.creator_id);
+ msg->getU32(_PREHASH_Data, _PREHASH_CreationDate, c_info.creation_date);
+ msg->getU32(_PREHASH_Data, _PREHASH_ExpirationDate, c_info.expiration_date);
+ msg->getU32(_PREHASH_Data, _PREHASH_Category, c_info.category);
+ msg->getString(_PREHASH_Data, _PREHASH_Name, c_info.name);
+ msg->getString(_PREHASH_Data, _PREHASH_Desc, c_info.description);
+ msg->getUUID(_PREHASH_Data, _PREHASH_ParcelID, c_info.parcel_id);
+ msg->getU32(_PREHASH_Data, _PREHASH_ParentEstate, c_info.parent_estate);
+ msg->getUUID(_PREHASH_Data, _PREHASH_SnapshotID, c_info.snapshot_id);
+ msg->getString(_PREHASH_Data, _PREHASH_SimName, c_info.sim_name);
+ msg->getVector3d(_PREHASH_Data, _PREHASH_PosGlobal, c_info.pos_global);
+ msg->getString(_PREHASH_Data, _PREHASH_ParcelName, c_info.parcel_name);
+ msg->getU8(_PREHASH_Data, _PREHASH_ClassifiedFlags, c_info.flags);
+ msg->getS32(_PREHASH_Data, _PREHASH_PriceForListing, c_info.price_for_listing);
+
+ LLAvatarPropertiesProcessor* self = getInstance();
+ // Request processed, no longer pending
+ self->removePendingRequest(c_info.creator_id, APT_CLASSIFIED_INFO);
+ self->notifyObservers(c_info.creator_id, &c_info, APT_CLASSIFIED_INFO);
+}
+
+
void LLAvatarPropertiesProcessor::processAvatarNotesReply(LLMessageSystem* msg, void**)
{
LLAvatarNotes avatar_notes;
@@ -451,6 +504,22 @@ void LLAvatarPropertiesProcessor::sendPickDelete( const LLUUID& pick_id )
LLAgentPicksInfo::getInstance()->decrementNumberOfPicks();
}
+void LLAvatarPropertiesProcessor::sendClassifiedDelete(const LLUUID& classified_id)
+{
+ LLMessageSystem* msg = gMessageSystem;
+
+ msg->newMessage(_PREHASH_ClassifiedDelete);
+
+ msg->nextBlock(_PREHASH_AgentData);
+ msg->addUUID(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
+
+ msg->nextBlock(_PREHASH_Data);
+ msg->addUUID(_PREHASH_ClassifiedID, classified_id);
+
+ gAgent.sendReliableMessage();
+}
+
void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick)
{
if (!new_pick) return;
@@ -485,6 +554,36 @@ void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick)
LLAgentPicksInfo::getInstance()->requestNumberOfPicks();
}
+void LLAvatarPropertiesProcessor::sendClassifiedInfoUpdate(const LLAvatarClassifiedInfo* c_data)
+{
+ if(!c_data)
+ {
+ return;
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+
+ msg->newMessage(_PREHASH_ClassifiedInfoUpdate);
+
+ msg->nextBlock(_PREHASH_AgentData);
+ msg->addUUID(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
+
+ msg->nextBlock(_PREHASH_Data);
+ msg->addUUID(_PREHASH_ClassifiedID, c_data->classified_id);
+ msg->addU32(_PREHASH_Category, c_data->category);
+ msg->addString(_PREHASH_Name, c_data->name);
+ msg->addString(_PREHASH_Desc, c_data->description);
+ msg->addUUID(_PREHASH_ParcelID, c_data->parcel_id);
+ msg->addU32(_PREHASH_ParentEstate, 0);
+ msg->addUUID(_PREHASH_SnapshotID, c_data->snapshot_id);
+ msg->addVector3d(_PREHASH_PosGlobal, c_data->pos_global);
+ msg->addU8(_PREHASH_ClassifiedFlags, c_data->flags);
+ msg->addS32(_PREHASH_PriceForListing, c_data->price_for_listing);
+
+ gAgent.sendReliableMessage();
+}
+
void LLAvatarPropertiesProcessor::sendPickInfoRequest(const LLUUID& creator_id, const LLUUID& pick_id)
{
// Must ask for a pick based on the creator id because
@@ -495,6 +594,21 @@ void LLAvatarPropertiesProcessor::sendPickInfoRequest(const LLUUID& creator_id,
send_generic_message("pickinforequest", request_params);
}
+void LLAvatarPropertiesProcessor::sendClassifiedInfoRequest(const LLUUID& classified_id)
+{
+ LLMessageSystem* msg = gMessageSystem;
+
+ msg->newMessage(_PREHASH_ClassifiedInfoRequest);
+ msg->nextBlock(_PREHASH_AgentData);
+
+ msg->addUUID(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
+
+ msg->nextBlock(_PREHASH_Data);
+ msg->addUUID(_PREHASH_ClassifiedID, classified_id);
+
+ gAgent.sendReliableMessage();
+}
bool LLAvatarPropertiesProcessor::isPendingRequest(const LLUUID& avatar_id, EAvatarProcessorType type)
{
diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h
index e6563024b2..716c1b8065 100644
--- a/indra/newview/llavatarpropertiesprocessor.h
+++ b/indra/newview/llavatarpropertiesprocessor.h
@@ -53,7 +53,9 @@ enum EAvatarProcessorType
APT_GROUPS,
APT_PICKS,
APT_PICK_INFO,
- APT_TEXTURES
+ APT_TEXTURES,
+ APT_CLASSIFIEDS,
+ APT_CLASSIFIED_INFO
};
struct LLAvatarData
@@ -136,6 +138,43 @@ struct LLAvatarGroups
};
};
+struct LLAvatarClassifieds
+{
+ LLUUID agent_id;
+ LLUUID target_id;
+
+ struct classified_data;
+ typedef std::list<classified_data> classifieds_list_t;
+
+ classifieds_list_t classifieds_list;
+
+ struct classified_data
+ {
+ LLUUID classified_id;
+ std::string name;
+ };
+};
+
+struct LLAvatarClassifiedInfo
+{
+ LLUUID agent_id;
+ LLUUID classified_id;
+ LLUUID creator_id;
+ U32 creation_date;
+ U32 expiration_date;
+ U32 category;
+ std::string name;
+ std::string description;
+ LLUUID parcel_id;
+ U32 parent_estate;
+ LLUUID snapshot_id;
+ std::string sim_name;
+ LLVector3d pos_global;
+ std::string parcel_name;
+ U8 flags;
+ S32 price_for_listing;
+};
+
class LLAvatarPropertiesObserver
{
public:
@@ -162,20 +201,27 @@ public:
void sendAvatarNotesRequest(const LLUUID& avatar_id);
void sendAvatarGroupsRequest(const LLUUID& avatar_id);
void sendAvatarTexturesRequest(const LLUUID& avatar_id);
+ void sendAvatarClassifiedsRequest(const LLUUID& avatar_id);
// Duplicate pick info requests are not suppressed.
void sendPickInfoRequest(const LLUUID& creator_id, const LLUUID& pick_id);
+ void sendClassifiedInfoRequest(const LLUUID& classified_id);
+
void sendAvatarPropertiesUpdate(const LLAvatarData* avatar_props);
void sendPickInfoUpdate(const LLPickData* new_pick);
+ void sendClassifiedInfoUpdate(const LLAvatarClassifiedInfo* c_data);
+
void sendFriendRights(const LLUUID& avatar_id, S32 rights);
void sendNotes(const LLUUID& avatar_id, const std::string notes);
void sendPickDelete(const LLUUID& pick_id);
+ void sendClassifiedDelete(const LLUUID& classified_id);
+
// Returns translated, human readable string for account type, such
// as "Resident" or "Linden Employee". Used for profiles, inspectors.
static std::string accountType(const LLAvatarData* avatar_data);
@@ -189,7 +235,9 @@ public:
static void processAvatarInterestsReply(LLMessageSystem* msg, void**);
- static void processAvatarClassifiedReply(LLMessageSystem* msg, void**);
+ static void processAvatarClassifiedsReply(LLMessageSystem* msg, void**);
+
+ static void processClassifiedInfoReply(LLMessageSystem* msg, void**);
static void processAvatarGroupsReply(LLMessageSystem* msg, void**);
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 832694873f..ab685b69ad 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -40,6 +40,7 @@
#include "llimfloater.h" // for LLIMFloater
#include "lllayoutstack.h"
#include "llnearbychatbar.h"
+#include "llspeakbutton.h"
#include "llsplitbutton.h"
#include "llsyswellwindow.h"
#include "llfloatercamera.h"
@@ -50,6 +51,8 @@ LLBottomTray::LLBottomTray(const LLSD&)
mSpeakBtn(NULL),
mNearbyChatBar(NULL),
mToolbarStack(NULL)
+, mMovementButton(NULL)
+// Add more members
{
mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL);
@@ -72,6 +75,8 @@ LLBottomTray::LLBottomTray(const LLSD&)
//destroyed LLBottomTray requires some subsystems that are long gone
//LLUI::getRootView()->addChild(this);
+ initStateProcessedObjectMap();
+
// Necessary for focus movement among child controls
setFocusRoot(TRUE);
}
@@ -181,6 +186,28 @@ void LLBottomTray::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID&
}
}
+// virtual
+void LLBottomTray::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ // Time it takes to connect to voice channel might be pretty long,
+ // so don't expect user login or STATUS_VOICE_ENABLED to be followed by STATUS_JOINED.
+ BOOL enable = FALSE;
+
+ switch (status)
+ {
+ // Do not add STATUS_VOICE_ENABLED because voice chat is
+ // inactive until STATUS_JOINED
+ case STATUS_JOINED:
+ enable = TRUE;
+ break;
+ default:
+ enable = FALSE;
+ break;
+ }
+
+ mSpeakBtn->setEnabled(enable);
+}
+
//virtual
void LLBottomTray::onFocusLost()
{
@@ -254,10 +281,11 @@ void LLBottomTray::showSnapshotButton(BOOL visible)
namespace
{
- const std::string& PANEL_CHICLET_NAME = "chiclet_list_panel";
- const std::string& PANEL_CHATBAR_NAME = "chat_bar";
- const std::string& PANEL_MOVEMENT_NAME = "movement_panel";
- const std::string& PANEL_CAMERA_NAME = "cam_panel";
+ const std::string& PANEL_CHICLET_NAME = "chiclet_list_panel";
+ const std::string& PANEL_CHATBAR_NAME = "chat_bar";
+ const std::string& PANEL_MOVEMENT_NAME = "movement_panel";
+ const std::string& PANEL_CAMERA_NAME = "cam_panel";
+ const std::string& PANEL_GESTURE_NAME = "gesture_panel";
}
BOOL LLBottomTray::postBuild()
@@ -275,6 +303,19 @@ BOOL LLBottomTray::postBuild()
mSnapshotPanel = getChild<LLPanel>("snapshot_panel");
setRightMouseDownCallback(boost::bind(&LLBottomTray::showBottomTrayContextMenu,this, _2, _3,_4));
+ mSpeakBtn = getChild<LLSpeakButton>("talk");
+
+ // Speak button should be initially disabled because
+ // it takes some time between logging in to world and connecting to voice channel.
+ mSpeakBtn->setEnabled(FALSE);
+
+ // Localization tool doesn't understand custom buttons like <talk_button>
+ mSpeakBtn->setSpeakToolTip( getString("SpeakBtnToolTip") );
+ mSpeakBtn->setShowToolTip( getString("VoiceControlBtnToolTip") );
+
+ // Registering Chat Bar to receive Voice client status change notifications.
+ gVoiceClient->addObserver(this);
+
if (mChicletPanel && mToolbarStack && mNearbyChatBar)
{
verifyChildControlsSizes();
@@ -283,159 +324,393 @@ BOOL LLBottomTray::postBuild()
return TRUE;
}
+void LLBottomTray::log(LLView* panel, const std::string& descr)
+{
+ if (NULL == panel) return;
+ LLView* layout = panel->getParent();
+ lldebugs << descr << ": "
+ << "panel: " << panel->getName()
+ << ", rect: " << panel->getRect()
+
+
+ << "layout: " << layout->getName()
+ << ", rect: " << layout->getRect()
+ << llendl
+ ;
+}
+
void LLBottomTray::verifyChildControlsSizes()
{
LLRect rect = mChicletPanel->getRect();
+ /*
if (rect.getWidth() < mChicletPanel->getMinWidth())
{
+ llwarns << "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ: chiclet panel less then min" << llendl;
mChicletPanel->reshape(mChicletPanel->getMinWidth(), rect.getHeight());
}
-
+*/
rect = mNearbyChatBar->getRect();
+/*
if (rect.getWidth() < mNearbyChatBar->getMinWidth())
{
+ llwarns << "WWWWWWWWWWWWWWWWWWWWWWWWWWWWW: near chat panel less then min" << llendl;
mNearbyChatBar->reshape(mNearbyChatBar->getMinWidth(), rect.getHeight());
}
- else if (rect.getWidth() > mNearbyChatBar->getMaxWidth())
+ else
+*/
+ if (rect.getWidth() > mNearbyChatBar->getMaxWidth())
{
+ llerrs << "WWWWWWWWWWWWWWWWWWWWWWWWWWWWW: near chat panel more then max width" << llendl;
+
rect.setLeftTopAndSize(rect.mLeft, rect.mTop, mNearbyChatBar->getMaxWidth(), rect.getHeight());
mNearbyChatBar->reshape(mNearbyChatBar->getMaxWidth(), rect.getHeight());
mNearbyChatBar->setRect(rect);
}
}
-
+#define __FEATURE_EXT_991
void LLBottomTray::reshape(S32 width, S32 height, BOOL called_from_parent)
{
+ lldebugs << "****************************************" << llendl;
+
+ S32 current_width = getRect().getWidth();
+ lldebugs << "Reshaping: "
+ << ", width: " << width
+ << ", height: " << height
+ << ", called_from_parent: " << called_from_parent
+ << ", cur width: " << current_width
+ << ", cur height: " << getRect().getHeight()
+ << llendl;
+
+ if (mNearbyChatBar) log(mNearbyChatBar, "before");
+ if (mChicletPanel) log(mChicletPanel, "before");
if (mChicletPanel && mToolbarStack && mNearbyChatBar)
{
-#ifdef __FEATURE_EXT_991__
- BOOL shrink = width < getRect().getWidth();
- const S32 MIN_RENDERED_CHARS = 3;
-#endif
+ mToolbarStack->updatePanelAutoResize(PANEL_CHICLET_NAME, TRUE);
+ verifyChildControlsSizes();
+ updateResizeState(width, current_width);
+ }
- verifyChildControlsSizes();
- updateResizeState(width, height);
+ LLPanel::reshape(width, height, called_from_parent);
+
+
+ if (mNearbyChatBar) log(mNearbyChatBar, "after");
+ if (mChicletPanel) log(mChicletPanel, "after");
+}
+
+void LLBottomTray::updateResizeState(S32 new_width, S32 cur_width)
+{
+ mResizeState = RS_NORESIZE;
+ MASK compensative_view_item_mask = RS_CHATBAR_INPUT;
+ LLPanel* compansative_view = mNearbyChatBar;
+
+ S32 delta_width = new_width - cur_width;
+// if (delta_width == 0) return;
+ bool shrink = new_width < cur_width;
+
+ const S32 chiclet_panel_width = mChicletPanel->getParent()->getRect().getWidth();
+ const S32 chiclet_panel_min_width = mChicletPanel->getMinWidth();
- switch (mResizeState)
+ const S32 chatbar_panel_width = mNearbyChatBar->getRect().getWidth();
+ const S32 chatbar_panel_min_width = mNearbyChatBar->getMinWidth();
+ const S32 chatbar_panel_max_width = mNearbyChatBar->getMaxWidth();
+
+ lldebugs << "chatbar_panel_width: " << chatbar_panel_width
+ << ", chatbar_panel_min_width: " << chatbar_panel_min_width
+ << ", chatbar_panel_max_width: " << chatbar_panel_max_width
+ << ", chiclet_panel_width: " << chiclet_panel_width
+ << ", chiclet_panel_min_width: " << chiclet_panel_min_width
+ << llendl;
+
+ bool still_should_be_processed = true;
+ // bottom tray is narrowed
+ if (shrink)
+ {
+ S32 compensative_delta_width = 0;
+ if (chiclet_panel_width > chiclet_panel_min_width)
+ {
+ // we have some space to decrease chiclet panel
+ S32 panel_delta_min = chiclet_panel_width - chiclet_panel_min_width;
+ mResizeState |= RS_CHICLET_PANEL;
+
+ S32 delta_panel = llmin(-delta_width, panel_delta_min);
+
+ lldebugs << "delta_width: " << delta_width
+ << ", panel_delta_min: " << panel_delta_min
+ << ", delta_panel: " << delta_panel
+ << llendl;
+
+ // is chiclet panel width enough to process resizing?
+ delta_width += panel_delta_min;
+
+ still_should_be_processed = delta_width < 0;
+
+ mChicletPanel->getParent()->reshape(mChicletPanel->getParent()->getRect().getWidth() - delta_panel, mChicletPanel->getParent()->getRect().getHeight());
+ log(mChicletPanel, "after processing panel decreasing via chiclet panel");
+
+ lldebugs << "RS_CHICLET_PANEL"
+ << ", delta_width: " << delta_width
+ << llendl;
+ }
+
+ if (still_should_be_processed && chatbar_panel_width > chatbar_panel_min_width)
{
- case STATE_CHICLET_PANEL:
- mToolbarStack->updatePanelAutoResize(PANEL_CHICLET_NAME, TRUE);
+ // we have some space to decrease chatbar panel
+ S32 panel_delta_min = chatbar_panel_width - chatbar_panel_min_width;
+ mResizeState |= RS_CHATBAR_INPUT;
- mToolbarStack->updatePanelAutoResize(PANEL_CHATBAR_NAME, FALSE);
- mToolbarStack->updatePanelAutoResize(PANEL_CAMERA_NAME, FALSE);
- mToolbarStack->updatePanelAutoResize(PANEL_MOVEMENT_NAME, FALSE);
+ S32 delta_panel = llmin(-delta_width, panel_delta_min);
- break;
- case STATE_CHATBAR_INPUT:
- mToolbarStack->updatePanelAutoResize(PANEL_CHATBAR_NAME, TRUE);
+ // is chatbar panel width enough to process resizing?
+ delta_width += panel_delta_min;
+
- mToolbarStack->updatePanelAutoResize(PANEL_CHICLET_NAME, FALSE);
- mToolbarStack->updatePanelAutoResize(PANEL_CAMERA_NAME, FALSE);
- mToolbarStack->updatePanelAutoResize(PANEL_MOVEMENT_NAME, FALSE);
+ still_should_be_processed = delta_width < 0;
- break;
+ mNearbyChatBar->reshape(mNearbyChatBar->getRect().getWidth() - delta_panel, mNearbyChatBar->getRect().getHeight());
-#ifdef __FEATURE_EXT_991__
+ lldebugs << "RS_CHATBAR_INPUT"
+ << ", delta_panel: " << delta_panel
+ << ", delta_width: " << delta_width
+ << llendl;
- case STATE_BUTTONS:
- mToolbarStack->updatePanelAutoResize(PANEL_CAMERA_NAME, TRUE);
- mToolbarStack->updatePanelAutoResize(PANEL_MOVEMENT_NAME, TRUE);
+ log(mChicletPanel, "after nearby was processed");
- mToolbarStack->updatePanelAutoResize(PANEL_CHICLET_NAME, FALSE);
- mToolbarStack->updatePanelAutoResize(PANEL_CHATBAR_NAME, FALSE);
+ }
+ if (still_should_be_processed)
+ {
+ mResizeState |= compensative_view_item_mask;
- if (shrink)
+ if (mSnapshotPanel->getVisible())
{
+ mResizeState |= RS_BUTTON_SNAPSHOT;
+ delta_width += mSnapshotPanel->getRect().getWidth();
- if (mSnapshotPanel->getVisible())
+ if (delta_width > 0)
{
- showSnapshotButton(FALSE);
+ compensative_delta_width += delta_width;
}
+ lldebugs << "RS_BUTTON_SNAPSHOT"
+ << ", compensative_delta_width: " << compensative_delta_width
+ << ", delta_width: " << delta_width
+ << llendl;
+ showSnapshotButton(false);
+ }
- if (mCamPanel->getVisible() && mCamButton->getLastDrawCharsCount() < MIN_RENDERED_CHARS)
+ if (delta_width < 0 && mCamPanel->getVisible())
+ {
+ mResizeState |= RS_BUTTON_CAMERA;
+ delta_width += mCamPanel->getRect().getWidth();
+ if (delta_width > 0)
{
- showCameraButton(FALSE);
+ compensative_delta_width += delta_width;
}
+ lldebugs << "RS_BUTTON_CAMERA"
+ << ", compensative_delta_width: " << compensative_delta_width
+ << ", delta_width: " << delta_width
+ << llendl;
+ showCameraButton(false);
+ }
- if (mMovementPanel->getVisible() && mMovementButton->getLastDrawCharsCount() < MIN_RENDERED_CHARS)
+ if (delta_width < 0 && mMovementPanel->getVisible())
+ {
+ mResizeState |= RS_BUTTON_MOVEMENT;
+ delta_width += mMovementPanel->getRect().getWidth();
+ if (delta_width > 0)
{
- showMoveButton(FALSE);
+ compensative_delta_width += delta_width;
}
-
+ lldebugs << "RS_BUTTON_MOVEMENT"
+ << ", compensative_delta_width: " << compensative_delta_width
+ << ", delta_width: " << delta_width
+ << llendl;
+ showMoveButton(false);
}
- else
- {
- showMoveButton(TRUE);
- mMovementPanel->draw();
- if (mMovementButton->getLastDrawCharsCount() >= MIN_RENDERED_CHARS)
- {
- showMoveButton(TRUE);
- }
- else
+ if (delta_width < 0 && mGesturePanel->getVisible())
+ {
+ mResizeState |= RS_BUTTON_GESTURES;
+ delta_width += mGesturePanel->getRect().getWidth();
+ if (delta_width > 0)
{
- showMoveButton(FALSE);
+ compensative_delta_width += delta_width;
}
+ lldebugs << "RS_BUTTON_GESTURES"
+ << ", compensative_delta_width: " << compensative_delta_width
+ << ", delta_width: " << delta_width
+ << llendl;
+ showGestureButton(false);
}
- break;
-#endif
- default:
- break;
+ if (delta_width < 0)
+ {
+ llwarns << "WARNING: there is no enough room for bottom tray, resizing still should be processed" << llendl;
+ }
+
+ if (compensative_delta_width != 0)
+ {
+ if (compansative_view) log(compansative_view, "before applying compensative width: ");
+ compansative_view->reshape(compansative_view->getRect().getWidth() + compensative_delta_width, compansative_view->getRect().getHeight() );
+ if (compansative_view) log(compansative_view, "after applying compensative width: ");
+ lldebugs << compensative_delta_width << llendl;
+
+ }
}
}
+ // bottom tray is widen
+ else
+ {
+ processWidthIncreased(delta_width);
+ }
- LLPanel::reshape(width, height, called_from_parent);
+ lldebugs << "New resize state: " << mResizeState << llendl;
}
-void LLBottomTray::updateResizeState(S32 width, S32 height)
+void LLBottomTray::processWidthDecreased(S32 delta_width)
{
- mResizeState = STATE_BUTTONS;
- const S32 chiclet_panel_width = mChicletPanel->getRect().getWidth();
+}
+
+void LLBottomTray::processWidthIncreased(S32 delta_width)
+{
+ const S32 chiclet_panel_width = mChicletPanel->getParent()->getRect().getWidth();
const S32 chiclet_panel_min_width = mChicletPanel->getMinWidth();
const S32 chatbar_panel_width = mNearbyChatBar->getRect().getWidth();
const S32 chatbar_panel_min_width = mNearbyChatBar->getMinWidth();
const S32 chatbar_panel_max_width = mNearbyChatBar->getMaxWidth();
- // bottom tray is narrowed
- if (width < getRect().getWidth())
+ const S32 chatbar_available_shrink_width = chatbar_panel_width - chatbar_panel_min_width;
+ const S32 available_width_chiclet = chiclet_panel_width - chiclet_panel_min_width;
+
+ // how many room we have to show hidden buttons
+ S32 available_width = delta_width + chatbar_available_shrink_width + available_width_chiclet;
+ S32 buttons_required_width = 0; //How many room will take shown buttons
+
+ if (available_width > 0)
{
- if (chiclet_panel_width > chiclet_panel_min_width)
- {
- mResizeState = STATE_CHICLET_PANEL;
- }
- else if (chatbar_panel_width > chatbar_panel_min_width)
- {
- mResizeState = STATE_CHATBAR_INPUT;
- }
- else
- {
- mResizeState = STATE_BUTTONS;
- }
+ lldebugs << "Trying to process: RS_BUTTON_GESTURES" << llendl;
+ processShowButton(RS_BUTTON_GESTURES, &available_width, &buttons_required_width);
}
- // bottom tray is widen
- else
+
+ if (available_width > 0)
+ {
+ lldebugs << "Trying to process: RS_BUTTON_MOVEMENT" << llendl;
+ processShowButton(RS_BUTTON_MOVEMENT, &available_width, &buttons_required_width);
+ }
+
+ if (available_width > 0)
+ {
+ lldebugs << "Trying to process: RS_BUTTON_CAMERA" << llendl;
+ processShowButton(RS_BUTTON_CAMERA, &available_width, &buttons_required_width);
+ }
+
+ if (available_width > 0)
{
-#ifdef __FEATURE_EXT_991__
- if (!mMovementPanel->getVisible())
+ lldebugs << "Trying to process: RS_BUTTON_SNAPSHOT" << llendl;
+ processShowButton(RS_BUTTON_SNAPSHOT, &available_width, &buttons_required_width);
+ }
+
+ // if we have to show some buttons but whidth increasing is not enough...
+ if (buttons_required_width > 0 && delta_width < buttons_required_width)
+ {
+ // ... let's shrink nearby chat & chiclet panels
+ S32 required_to_process_width = buttons_required_width;
+
+ // 1. use delta width of resizing
+ required_to_process_width -= delta_width;
+
+ // 2. use width available via decreasing of nearby chat panel
+ S32 chatbar_shrink_width = required_to_process_width;
+ if (chatbar_available_shrink_width < chatbar_shrink_width)
{
- mResizeState = STATE_BUTTONS;
+ chatbar_shrink_width = chatbar_available_shrink_width;
}
- else
-#endif
- if (chatbar_panel_width < chatbar_panel_max_width)
+
+ log(mNearbyChatBar, "increase width: before applying compensative width: ");
+ mNearbyChatBar->reshape(mNearbyChatBar->getRect().getWidth() - chatbar_shrink_width, mNearbyChatBar->getRect().getHeight() );
+ if (mNearbyChatBar) log(mNearbyChatBar, "after applying compensative width: ");
+ lldebugs << chatbar_shrink_width << llendl;
+
+ // 3. use width available via decreasing of chiclet panel
+ required_to_process_width -= chatbar_shrink_width;
+
+ if (required_to_process_width > 0)
{
- mResizeState = STATE_CHATBAR_INPUT;
+ mChicletPanel->getParent()->reshape(mChicletPanel->getParent()->getRect().getWidth() - required_to_process_width, mChicletPanel->getParent()->getRect().getHeight());
+ log(mChicletPanel, "after applying compensative width for chiclets: ");
+ lldebugs << required_to_process_width << llendl;
}
- else
+
+ }
+
+ // shown buttons take some space, rest should be processed by nearby chatbar & chiclet panels
+ delta_width -= buttons_required_width;
+
+ // how many space can nearby chatbar take?
+ S32 chatbar_panel_width_ = mNearbyChatBar->getRect().getWidth();
+ if (delta_width > 0 && chatbar_panel_width_ < chatbar_panel_max_width)
+ {
+ mResizeState |= RS_CHATBAR_INPUT;
+ S32 delta_panel_max = chatbar_panel_max_width - chatbar_panel_width_;
+ S32 delta_panel = llmin(delta_width, delta_panel_max);
+ delta_width -= delta_panel_max;
+ mNearbyChatBar->reshape(chatbar_panel_width_ + delta_panel, mNearbyChatBar->getRect().getHeight());
+ }
+}
+
+bool LLBottomTray::processShowButton(EResizeState shown_object_type, S32* available_width, S32* buttons_required_width)
+{
+ LLPanel* panel = mStateProcessedObjectMap[shown_object_type];
+ if (NULL == panel)
+ {
+ lldebugs << "There is no object to process for state: " << shown_object_type << llendl;
+ return false;
+ }
+ bool can_be_shown = canButtonBeShown(panel);
+ if (can_be_shown)
+ {
+ //validate if we have enough room to show this button
+ const S32 required_width = panel->getRect().getWidth();
+ can_be_shown = *available_width >= required_width;
+ if (can_be_shown)
{
- mResizeState = STATE_CHICLET_PANEL;
+ *available_width -= required_width;
+ *buttons_required_width += required_width;
+
+ switch (shown_object_type)
+ {
+ case RS_BUTTON_GESTURES: showGestureButton(true); break;
+ case RS_BUTTON_MOVEMENT: showMoveButton(true); break;
+ case RS_BUTTON_CAMERA: showCameraButton(true); break;
+ case RS_BUTTON_SNAPSHOT: showSnapshotButton(true); break;
+ default:
+ llwarns << "Unexpected type of button to be shown: " << shown_object_type << llendl;
+ }
+
+ lldebugs << "processing object type: " << shown_object_type
+ << ", buttons_required_width: " << buttons_required_width
+ << llendl;
}
}
+ return can_be_shown;
+}
+bool LLBottomTray::canButtonBeShown(LLPanel* panel) const
+{
+ bool can_be_shown = !panel->getVisible();
+ if (can_be_shown)
+ {
+ // *TODO: mantipov: synchronize with situation when button was hidden via context menu;
+ }
+ return can_be_shown;
+}
- // TODO: finish implementation
+void LLBottomTray::initStateProcessedObjectMap()
+{
+ mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_GESTURES, mGesturePanel));
+ mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_MOVEMENT, mMovementPanel));
+ mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_CAMERA, mCamPanel));
+ mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_SNAPSHOT, mSnapshotPanel));
}
+//EOF
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index 02588a1975..c88bdeda1c 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -33,7 +33,7 @@
#ifndef LL_LLBOTTOMPANEL_H
#define LL_LLBOTTOMPANEL_H
-#include <llmenugl.h>
+#include "llmenugl.h"
#include "llpanel.h"
#include "llimview.h"
@@ -51,7 +51,9 @@ class LLBottomTray
: public LLSingleton<LLBottomTray>
, public LLPanel
, public LLIMSessionObserver
+ , public LLVoiceClientStatusObserver
{
+ LOG_CLASS(LLBottomTray);
friend class LLSingleton<LLBottomTray>;
public:
~LLBottomTray();
@@ -74,6 +76,10 @@ public:
virtual void onFocusLost();
virtual void setVisible(BOOL visible);
+ // Implements LLVoiceClientStatusObserver::onChange() to enable the speak
+ // button when voice is available
+ /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+
void showBottomTrayContextMenu(S32 x, S32 y, MASK mask);
void showGestureButton(BOOL visible);
@@ -82,18 +88,32 @@ public:
void showSnapshotButton(BOOL visible);
private:
-
- enum EResizeState
+ typedef enum e_resize_status_type
{
- STATE_CHICLET_PANEL = 1,
- STATE_CHATBAR_INPUT,
- STATE_BUTTONS
- };
-
- void updateResizeState(S32 width, S32 height);
+ RS_NORESIZE = 0x0000
+ , RS_CHICLET_PANEL = 0x0001
+ , RS_CHATBAR_INPUT = 0x0002
+ , RS_BUTTON_SNAPSHOT = 0x0004
+ , RS_BUTTON_CAMERA = 0x0008
+ , RS_BUTTON_MOVEMENT = 0x0010
+ , RS_BUTTON_GESTURES = 0x0020
+ , RS_BUTTON_SPEAK = 0x0040
+ , RS_RESIZABLE_BUTTONS = /*RS_BUTTON_SNAPSHOT | */RS_BUTTON_CAMERA | RS_BUTTON_MOVEMENT | RS_BUTTON_GESTURES
+ }EResizeState;
+
+ void updateResizeState(S32 new_width, S32 cur_width);
void verifyChildControlsSizes();
+ void processWidthDecreased(S32 delta_width);
+ void processWidthIncreased(S32 delta_width);
+ void log(LLView* panel, const std::string& descr);
+ bool processShowButton(EResizeState shown_object_type, S32* available_width, S32* buttons_required_width);
+ bool canButtonBeShown(LLPanel* panel) const;
+ void initStateProcessedObjectMap();
+
+ MASK mResizeState;
- EResizeState mResizeState;
+ typedef std::map<EResizeState, LLPanel*> state_object_map_t;
+ state_object_map_t mStateProcessedObjectMap;
protected:
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 2ccd6b7d35..d1922cfd6e 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -47,7 +47,6 @@
#include "llmutelist.h"
static LLDefaultChildRegistry::Register<LLChatHistory> r("chat_history");
-static const std::string MESSAGE_USERNAME_DATE_SEPARATOR(" ----- ");
std::string formatCurrentTime()
{
@@ -175,7 +174,7 @@ public:
const std::string& getFirstName() const { return mFirstName; }
const std::string& getLastName () const { return mLastName; }
- void setup(const LLChat& chat)
+ void setup(const LLChat& chat,const LLStyle::Params& style_params)
{
mAvatarID = chat.mFromID;
mSourceType = chat.mSourceType;
@@ -185,8 +184,11 @@ public:
mSourceType = CHAT_SOURCE_SYSTEM;
}
-
LLTextBox* userName = getChild<LLTextBox>("user_name");
+
+ LLUIColor color = style_params.color;
+ userName->setReadOnlyColor(color);
+ userName->setColor(color);
if(!chat.mFromName.empty())
{
@@ -198,6 +200,7 @@ public:
std::string SL = LLTrans::getString("SECOND_LIFE");
userName->setValue(SL);
}
+
LLTextBox* timeBox = getChild<LLTextBox>("time_box");
timeBox->setValue(formatCurrentTime());
@@ -323,17 +326,17 @@ LLView* LLChatHistory::getSeparator()
return separator;
}
-LLView* LLChatHistory::getHeader(const LLChat& chat)
+LLView* LLChatHistory::getHeader(const LLChat& chat,const LLStyle::Params& style_params)
{
LLChatHistoryHeader* header = LLChatHistoryHeader::createInstance(mMessageHeaderFilename);
- header->setup(chat);
+ header->setup(chat,style_params);
return header;
}
void LLChatHistory::appendWidgetMessage(const LLChat& chat, LLStyle::Params& style_params)
{
LLView* view = NULL;
- std::string view_text;
+ std::string view_text = "\n[" + formatCurrentTime() + "] " + chat.mFromName + ": ";
LLInlineViewSegment::Params p;
p.force_newline = true;
@@ -343,14 +346,12 @@ void LLChatHistory::appendWidgetMessage(const LLChat& chat, LLStyle::Params& sty
if (mLastFromName == chat.mFromName)
{
view = getSeparator();
- view_text = "\n";
p.top_pad = mTopSeparatorPad;
p.bottom_pad = mBottomSeparatorPad;
}
else
{
- view = getHeader(chat);
- view_text = chat.mFromName + MESSAGE_USERNAME_DATE_SEPARATOR + formatCurrentTime() + '\n';
+ view = getHeader(chat,style_params);
if (getText().size() == 0)
p.top_pad = 0;
else
@@ -370,10 +371,8 @@ void LLChatHistory::appendWidgetMessage(const LLChat& chat, LLStyle::Params& sty
appendWidget(p, view_text, false);
//Append the text message
- std::string message = chat.mText + '\n';
- appendText(message, FALSE, style_params);
+ appendText(chat.mText, FALSE, style_params);
mLastFromName = chat.mFromName;
blockUndo();
- setCursorAndScrollToEnd();
}
diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h
index 3789ebff4e..f0944042af 100644
--- a/indra/newview/llchathistory.h
+++ b/indra/newview/llchathistory.h
@@ -94,11 +94,9 @@ class LLChatHistory : public LLTextEditor
LLView* getSeparator();
/**
* Builds a message header.
- * @param from owner of a message.
- * @param time time of a message.
* @return pointer to LLView header object.
*/
- LLView* getHeader(const LLChat& chat);
+ LLView* getHeader(const LLChat& chat,const LLStyle::Params& style_params);
public:
~LLChatHistory();
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index c200a97058..b919195fb2 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -55,6 +55,13 @@ static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notif
static LLDefaultChildRegistry::Register<LLIMP2PChiclet> t3("chiclet_im_p2p");
static LLDefaultChildRegistry::Register<LLIMGroupChiclet> t4("chiclet_im_group");
+static const LLRect CHICLET_RECT(0, 25, 25, 0);
+static const LLRect CHICLET_ICON_RECT(0, 24, 24, 0);
+static const LLRect VOICE_INDICATOR_RECT(25, 25, 45, 0);
+
+// static
+const S32 LLChicletPanel::s_scroll_ratio = 10;
+
S32 LLNotificationChiclet::mUreadSystemNotifications = 0;
boost::signals2::signal<LLChiclet* (const LLUUID&),
@@ -96,6 +103,7 @@ LLNotificationChiclet::LLNotificationChiclet(const Params& p)
// connect counter handlers to the signals
connectCounterUpdatersToSignal("notify");
connectCounterUpdatersToSignal("groupnotify");
+ connectCounterUpdatersToSignal("offer");
}
LLNotificationChiclet::~LLNotificationChiclet()
@@ -199,7 +207,9 @@ void LLChiclet::setValue(const LLSD& value)
LLIMChiclet::LLIMChiclet(const LLIMChiclet::Params& p)
: LLChiclet(p)
+, mShowSpeaker(false)
, mNewMessagesIcon(NULL)
+, mSpeakerCtrl(NULL)
, mCounterCtrl(NULL)
{
// initialize an overlay icon for new messages
@@ -218,6 +228,40 @@ LLIMChiclet::LLIMChiclet(const LLIMChiclet::Params& p)
setShowCounter(false);
}
+void LLIMChiclet::setShowSpeaker(bool show)
+{
+ bool needs_resize = getShowSpeaker() != show;
+ if(needs_resize)
+ {
+ mShowSpeaker = show;
+ toggleSpeakerControl();
+ onChicletSizeChanged();
+ }
+}
+void LLIMChiclet::initSpeakerControl()
+{
+ // virtual
+}
+
+void LLIMChiclet::toggleSpeakerControl()
+{
+ LLRect speaker_rect = mSpeakerCtrl->getRect();
+ S32 required_width = getRect().getWidth();
+
+ if(getShowSpeaker())
+ {
+ required_width = required_width + speaker_rect.getWidth();
+ initSpeakerControl();
+ }
+ else
+ {
+ required_width = required_width - speaker_rect.getWidth();
+ }
+
+ reshape(required_width, getRect().getHeight());
+ mSpeakerCtrl->setVisible(getShowSpeaker());
+}
+
void LLIMChiclet::setShowNewMessagesIcon(bool show)
{
if(mNewMessagesIcon)
@@ -300,7 +344,7 @@ LLIMP2PChiclet::Params::Params()
, show_speaker("show_speaker")
{
// *TODO Vadim: Get rid of hardcoded values.
- rect(LLRect(0, 25, 25, 0));
+ rect(CHICLET_RECT);
avatar_icon.name("avatar_icon");
avatar_icon.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
@@ -309,11 +353,10 @@ LLIMP2PChiclet::Params::Params()
// 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.rect(CHICLET_ICON_RECT);
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);
@@ -322,7 +365,9 @@ LLIMP2PChiclet::Params::Params()
unread_notifications.visible(false);
speaker.name("speaker");
- speaker.rect(LLRect(45, 25, 65, 0));
+ speaker.rect(VOICE_INDICATOR_RECT);
+ speaker.auto_update(true);
+ speaker.draw_border(false);
show_speaker = false;
}
@@ -330,7 +375,6 @@ LLIMP2PChiclet::Params::Params()
LLIMP2PChiclet::LLIMP2PChiclet(const Params& p)
: LLIMChiclet(p)
, mChicletIconCtrl(NULL)
-, mSpeakerCtrl(NULL)
, mPopupMenu(NULL)
{
LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon;
@@ -358,18 +402,9 @@ void LLIMP2PChiclet::setCounter(S32 counter)
setShowNewMessagesIcon(counter);
}
-LLRect LLIMP2PChiclet::getRequiredRect()
+void LLIMP2PChiclet::initSpeakerControl()
{
- LLRect rect(0, 0, mChicletIconCtrl->getRect().getWidth(), 0);
- if(getShowCounter())
- {
- rect.mRight += mCounterCtrl->getRequiredRect().getWidth();
- }
- if(getShowSpeaker())
- {
- rect.mRight += mSpeakerCtrl->getRect().getWidth();
- }
- return rect;
+ mSpeakerCtrl->setSpeakerId(getOtherParticipantId());
}
void LLIMP2PChiclet::setOtherParticipantId(const LLUUID& other_participant_id)
@@ -446,18 +481,6 @@ void LLIMP2PChiclet::onMenuItemClicked(const LLSD& user_data)
}
}
-void LLIMP2PChiclet::setShowSpeaker(bool show)
-{
- LLIMChiclet::setShowSpeaker(show);
-
- bool needs_resize = getShowSpeaker() != show;
- mSpeakerCtrl->setVisible(getShowSpeaker());
- if(needs_resize)
- {
- onChicletSizeChanged();
- }
-}
-
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
@@ -470,7 +493,7 @@ LLAdHocChiclet::Params::Params()
, avatar_icon_color("avatar_icon_color", LLColor4::green)
{
// *TODO Vadim: Get rid of hardcoded values.
- rect(LLRect(0, 25, 25, 0));
+ rect(CHICLET_RECT);
avatar_icon.name("avatar_icon");
avatar_icon.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
@@ -479,11 +502,10 @@ LLAdHocChiclet::Params::Params()
// 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.rect(CHICLET_ICON_RECT);
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);
@@ -493,7 +515,9 @@ LLAdHocChiclet::Params::Params()
speaker.name("speaker");
- speaker.rect(LLRect(45, 25, 65, 0));
+ speaker.rect(VOICE_INDICATOR_RECT);
+ speaker.auto_update(true);
+ speaker.draw_border(false);
show_speaker = false;
}
@@ -501,7 +525,6 @@ LLAdHocChiclet::Params::Params()
LLAdHocChiclet::LLAdHocChiclet(const Params& p)
: LLIMChiclet(p)
, mChicletIconCtrl(NULL)
-, mSpeakerCtrl(NULL)
, mPopupMenu(NULL)
{
LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon;
@@ -532,24 +555,40 @@ void LLAdHocChiclet::setSessionId(const LLUUID& session_id)
mChicletIconCtrl->setValue(im_session->mOtherParticipantID);
}
-void LLAdHocChiclet::setCounter(S32 counter)
+void LLAdHocChiclet::draw()
{
- mCounterCtrl->setCounter(counter);
- setShowNewMessagesIcon(counter);
+ switchToCurrentSpeaker();
+ LLIMChiclet::draw();
}
-LLRect LLAdHocChiclet::getRequiredRect()
+void LLAdHocChiclet::initSpeakerControl()
{
- LLRect rect(0, 0, mChicletIconCtrl->getRect().getWidth(), 0);
- if(getShowCounter())
- {
- rect.mRight += mCounterCtrl->getRequiredRect().getWidth();
- }
- if(getShowSpeaker())
+ switchToCurrentSpeaker();
+}
+
+void LLAdHocChiclet::switchToCurrentSpeaker()
+{
+ LLUUID speaker_id;
+ LLSpeakerMgr::speaker_list_t speaker_list;
+
+ LLIMModel::getInstance()->findIMSession(getSessionId())->mSpeakers->getSpeakerList(&speaker_list, FALSE);
+ for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
{
- rect.mRight += mSpeakerCtrl->getRect().getWidth();
+ LLPointer<LLSpeaker> s = *i;
+ if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING)
+ {
+ speaker_id = s->mID;
+ break;
+ }
}
- return rect;
+
+ mSpeakerCtrl->setSpeakerId(speaker_id);
+}
+
+void LLAdHocChiclet::setCounter(S32 counter)
+{
+ mCounterCtrl->setCounter(counter);
+ setShowNewMessagesIcon(counter);
}
BOOL LLAdHocChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
@@ -564,7 +603,7 @@ BOOL LLAdHocChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
LLIMGroupChiclet::Params::Params()
: group_icon("group_icon")
{
- rect(LLRect(0, 25, 25, 0));
+ rect(CHICLET_RECT);
group_icon.name("group_icon");
@@ -572,10 +611,9 @@ LLIMGroupChiclet::Params::Params()
// 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.
- group_icon.rect(LLRect(0, 24, 25, 0));
+ group_icon.rect(CHICLET_ICON_RECT);
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);
@@ -583,7 +621,9 @@ LLIMGroupChiclet::Params::Params()
unread_notifications.visible(false);
speaker.name("speaker");
- speaker.rect(LLRect(45, 25, 65, 0));
+ speaker.rect(VOICE_INDICATOR_RECT);
+ speaker.auto_update(true);
+ speaker.draw_border(false);
show_speaker = false;
}
@@ -592,7 +632,6 @@ LLIMGroupChiclet::LLIMGroupChiclet(const Params& p)
: LLIMChiclet(p)
, LLGroupMgrObserver(LLUUID::null)
, mChicletIconCtrl(NULL)
-, mSpeakerCtrl(NULL)
, mPopupMenu(NULL)
{
LLChicletGroupIconCtrl::Params avatar_params = p.group_icon;
@@ -625,18 +664,34 @@ void LLIMGroupChiclet::setCounter(S32 counter)
setShowNewMessagesIcon(counter);
}
-LLRect LLIMGroupChiclet::getRequiredRect()
+void LLIMGroupChiclet::draw()
{
- LLRect rect(0, 0, mChicletIconCtrl->getRect().getWidth(), 0);
- if(getShowCounter())
- {
- rect.mRight += mCounterCtrl->getRequiredRect().getWidth();
- }
- if(getShowSpeaker())
+ switchToCurrentSpeaker();
+ LLIMChiclet::draw();
+}
+
+void LLIMGroupChiclet::initSpeakerControl()
+{
+ switchToCurrentSpeaker();
+}
+
+void LLIMGroupChiclet::switchToCurrentSpeaker()
+{
+ LLUUID speaker_id;
+ LLSpeakerMgr::speaker_list_t speaker_list;
+
+ LLIMModel::getInstance()->findIMSession(getSessionId())->mSpeakers->getSpeakerList(&speaker_list, FALSE);
+ for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
{
- rect.mRight += mSpeakerCtrl->getRect().getWidth();
+ LLPointer<LLSpeaker> s = *i;
+ if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING)
+ {
+ speaker_id = s->mID;
+ break;
+ }
}
- return rect;
+
+ mSpeakerCtrl->setSpeakerId(speaker_id);
}
void LLIMGroupChiclet::setSessionId(const LLUUID& session_id)
@@ -723,17 +778,6 @@ void LLIMGroupChiclet::onMenuItemClicked(const LLSD& user_data)
}
}
-void LLIMGroupChiclet::setShowSpeaker(bool show)
-{
- LLIMChiclet::setShowSpeaker(show);
-
- bool needs_resize = getShowSpeaker() != show;
- mSpeakerCtrl->setVisible(getShowSpeaker());
- if(needs_resize)
- {
- onChicletSizeChanged();
- }
-}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
@@ -742,36 +786,18 @@ void LLIMGroupChiclet::setShowSpeaker(bool show)
LLChicletPanel::Params::Params()
: chiclet_padding("chiclet_padding")
, scrolling_offset("scrolling_offset")
-, left_scroll_button("left_scroll_button")
-, right_scroll_button("right_scroll_button")
, min_width("min_width")
{
chiclet_padding = 3;
scrolling_offset = 40;
+/*
if (!min_width.isProvided())
{
// min_width = 4 chiclets + 3 paddings
- min_width = 179 + 3*chiclet_padding;
+ min_width = 180 + 3*chiclet_padding;
}
-
- LLRect scroll_button_rect(0, 25, 19, 5);
-
- left_scroll_button.name("left_scroll");
- left_scroll_button.label(LLStringUtil::null);
- left_scroll_button.rect(scroll_button_rect);
- left_scroll_button.tab_stop(false);
- left_scroll_button.image_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
- left_scroll_button.image_unselected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
- left_scroll_button.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
-
- right_scroll_button.name("right_scroll");
- right_scroll_button.label(LLStringUtil::null);
- right_scroll_button.rect(scroll_button_rect);
- right_scroll_button.tab_stop(false);
- right_scroll_button.image_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
- right_scroll_button.image_unselected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
- right_scroll_button.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
+*/
};
LLChicletPanel::LLChicletPanel(const Params&p)
@@ -784,24 +810,8 @@ LLChicletPanel::LLChicletPanel(const Params&p)
, mMinWidth(p.min_width)
, mShowControls(true)
{
- LLButton::Params scroll_button_params = p.left_scroll_button;
-
- mLeftScrollButton = LLUICtrlFactory::create<LLButton>(scroll_button_params);
- addChild(mLeftScrollButton);
- LLTransientFloaterMgr::getInstance()->addControlView(mLeftScrollButton);
-
- mLeftScrollButton->setClickedCallback(boost::bind(&LLChicletPanel::onLeftScrollClick,this));
- mLeftScrollButton->setEnabled(false);
-
- scroll_button_params = p.right_scroll_button;
- mRightScrollButton = LLUICtrlFactory::create<LLButton>(scroll_button_params);
- addChild(mRightScrollButton);
- LLTransientFloaterMgr::getInstance()->addControlView(mRightScrollButton);
-
- mRightScrollButton->setClickedCallback(boost::bind(&LLChicletPanel::onRightScrollClick,this));
- mRightScrollButton->setEnabled(false);
-
LLPanel::Params panel_params;
+ panel_params.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT);
mScrollArea = LLUICtrlFactory::create<LLPanel>(panel_params,this);
// important for Show/Hide Camera and Move controls menu in bottom tray to work properly
@@ -851,10 +861,40 @@ BOOL LLChicletPanel::postBuild()
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));
+ LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLChicletPanel::onCurrentVoiceChannelChanged, this, _1));
+
+ mLeftScrollButton=getChild<LLButton>("chicklet_left_scroll_button");
+ LLTransientFloaterMgr::getInstance()->addControlView(mLeftScrollButton);
+ mLeftScrollButton->setMouseDownCallback(boost::bind(&LLChicletPanel::onLeftScrollClick,this));
+ mLeftScrollButton->setHeldDownCallback(boost::bind(&LLChicletPanel::onLeftScrollHeldDown,this));
+ mLeftScrollButton->setEnabled(false);
+
+ mRightScrollButton=getChild<LLButton>("chicklet_right_scroll_button");
+ LLTransientFloaterMgr::getInstance()->addControlView(mRightScrollButton);
+ mRightScrollButton->setMouseDownCallback(boost::bind(&LLChicletPanel::onRightScrollClick,this));
+ mRightScrollButton->setHeldDownCallback(boost::bind(&LLChicletPanel::onRightScrollHeldDown,this));
+ mRightScrollButton->setEnabled(false);
return TRUE;
}
+void LLChicletPanel::onCurrentVoiceChannelChanged(const LLUUID& session_id)
+{
+ for(chiclet_list_t::iterator it = mChicletList.begin(); it != mChicletList.end(); ++it)
+ {
+ LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it);
+ if(chiclet)
+ {
+ if(chiclet->getSessionId() == session_id)
+ {
+ chiclet->setShowSpeaker(true);
+ continue;
+ }
+ chiclet->setShowSpeaker(false);
+ }
+ }
+}
+
S32 LLChicletPanel::calcChickletPanleWidth()
{
S32 res = 0;
@@ -898,23 +938,7 @@ bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index)
void LLChicletPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param)
{
- S32 chiclet_width = ctrl->getRect().getWidth();
- S32 chiclet_new_width = ctrl->getRequiredRect().getWidth();
-
- if(chiclet_new_width == chiclet_width)
- {
- return;
- }
-
- LLRect chiclet_rect = ctrl->getRect();
- chiclet_rect.mRight = chiclet_rect.mLeft + chiclet_new_width;
-
- ctrl->setRect(chiclet_rect);
-
- S32 offset = chiclet_new_width - chiclet_width;
- S32 index = getChicletIndex(ctrl);
-
- shiftChiclets(offset, index + 1);
+ arrange();
trimChiclets();
showScrollButtonsIfNeeded();
}
@@ -1026,23 +1050,24 @@ void LLChicletPanel::reshape(S32 width, S32 height, BOOL called_from_parent )
static const S32 SCROLL_BUTTON_PAD = 5;
+ //Needed once- to avoid error at first call of reshape() before postBuild()
+ if(!mLeftScrollButton||!mRightScrollButton)
+ return;
+
LLRect scroll_button_rect = mLeftScrollButton->getRect();
- mLeftScrollButton->setRect(LLRect(0,height,scroll_button_rect.getWidth(),
- height - scroll_button_rect.getHeight()));
-
+ mLeftScrollButton->setRect(LLRect(0,scroll_button_rect.mTop,scroll_button_rect.getWidth(),
+ scroll_button_rect.mBottom));
scroll_button_rect = mRightScrollButton->getRect();
- mRightScrollButton->setRect(LLRect(width - scroll_button_rect.getWidth(),height,
- width, height - scroll_button_rect.getHeight()));
-
+ mRightScrollButton->setRect(LLRect(width - scroll_button_rect.getWidth(),scroll_button_rect.mTop,
+ width, scroll_button_rect.mBottom));
mScrollArea->setRect(LLRect(scroll_button_rect.getWidth() + SCROLL_BUTTON_PAD,
height, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0));
-
- mShowControls = width > mMinWidth;
+ mShowControls = width >= mMinWidth;
mScrollArea->setVisible(mShowControls);
trimChiclets();
-
showScrollButtonsIfNeeded();
+
}
void LLChicletPanel::arrange()
@@ -1206,6 +1231,22 @@ void LLChicletPanel::onRightScrollClick()
scrollRight();
}
+void LLChicletPanel::onLeftScrollHeldDown()
+{
+ S32 offset = mScrollingOffset;
+ mScrollingOffset = mScrollingOffset / s_scroll_ratio;
+ scrollLeft();
+ mScrollingOffset = offset;
+}
+
+void LLChicletPanel::onRightScrollHeldDown()
+{
+ S32 offset = mScrollingOffset;
+ mScrollingOffset = mScrollingOffset / s_scroll_ratio;
+ scrollRight();
+ mScrollingOffset = offset;
+}
+
boost::signals2::connection LLChicletPanel::setChicletClickedCallback(
const commit_callback_t& cb)
{
@@ -1329,6 +1370,6 @@ void LLChicletGroupIconCtrl::setValue(const LLSD& value )
//////////////////////////////////////////////////////////////////////////
LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p)
- : LLIconCtrl(p)
+ : LLOutputMonitorCtrl(p)
{
}
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index b50702205c..eab4a282f5 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -107,6 +107,7 @@ public:
{
draw_tooltip(FALSE);
mouse_opaque(FALSE);
+ default_icon_name("Generic_Person");
};
};
@@ -128,7 +129,7 @@ public:
Optional<std::string> default_icon;
Params()
- : default_icon("default_icon", "default_land_picture.j2c")
+ : default_icon("default_icon", "Generic_Group")
{
};
};
@@ -147,13 +148,13 @@ protected:
};
/*
- * Class for displaying status of Voice Chat
+ * Class for displaying of speaker's voice indicator
*/
-class LLChicletSpeakerCtrl : public LLIconCtrl
+class LLChicletSpeakerCtrl : public LLOutputMonitorCtrl
{
public:
- struct Params : public LLInitParam::Block<Params, LLIconCtrl::Params>
+ struct Params : public LLInitParam::Block<Params, LLOutputMonitorCtrl::Params>
{
Params(){};
};
@@ -266,8 +267,6 @@ private:
* Base class for Instant Message chiclets.
* IMChiclet displays icon, number of unread messages(optional)
* and voice chat status(optional).
-* Every chiclet should override LLUICtrl::getRequiredRect and return
-* desired width.
*/
class LLIMChiclet : public LLChiclet
{
@@ -306,9 +305,14 @@ public:
virtual LLUUID getOtherParticipantId() { return mOtherParticipantId; }
/*
- * Shows/hides voice chat status control.
+ * Init Speaker Control with speaker's ID
*/
- virtual void setShowSpeaker(bool show) { mShowSpeaker = show; }
+ virtual void initSpeakerControl();
+
+ /*
+ * set status (Shows/Hide) for voice control.
+ */
+ virtual void setShowSpeaker(bool show);
/*
* Returns voice chat status control visibility.
@@ -316,6 +320,11 @@ public:
virtual bool getShowSpeaker() {return mShowSpeaker;};
/*
+ * Shows/Hides for voice control for a chiclet.
+ */
+ virtual void toggleSpeakerControl();
+
+ /*
* Shows/hides overlay icon concerning new unread messages.
*/
virtual void setShowNewMessagesIcon(bool show);
@@ -325,10 +334,7 @@ public:
*/
virtual bool getShowNewMessagesIcon();
- /*
- * Draws border around chiclet.
- */
- /*virtual*/ void draw();
+ virtual void draw();
/**
* Determine whether given ID refers to a group or an IM chat session.
@@ -363,6 +369,8 @@ protected:
LLIconCtrl* mNewMessagesIcon;
LLChicletNotificationCounterCtrl* mCounterCtrl;
+ LLChicletSpeakerCtrl* mSpeakerCtrl;
+
/** the id of another participant, either an avatar id or a group id*/
LLUUID mOtherParticipantId;
@@ -410,8 +418,6 @@ public:
/* virtual */ void setOtherParticipantId(const LLUUID& other_participant_id);
- /*virtual*/ void setShowSpeaker(bool show);
-
/*
* 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.
@@ -419,15 +425,14 @@ public:
/*virtual*/ void setCounter(S32);
/*
- * Returns number of unread messages.
+ * Init Speaker Control with speaker's ID
*/
- /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
+ /*virtual*/ void initSpeakerControl();
/*
- * Returns rect, required to display chiclet.
- * Width is the only valid value.
+ * Returns number of unread messages.
*/
- /*virtual*/ LLRect getRequiredRect();
+ /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
protected:
LLIMP2PChiclet(const Params& p);
@@ -457,7 +462,6 @@ protected:
private:
LLChicletAvatarIconCtrl* mChicletIconCtrl;
- LLChicletSpeakerCtrl* mSpeakerCtrl;
LLMenuGL* mPopupMenu;
};
@@ -495,15 +499,19 @@ public:
/*virtual*/ void setCounter(S32);
/*
- * Returns number of unread messages.
+ * Keep Speaker Control with actual speaker's ID
*/
- /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
+ /*virtual*/ void draw();
/*
- * Returns rect, required to display chiclet.
- * Width is the only valid value.
+ * Init Speaker Control with speaker's ID
*/
- /*virtual*/ LLRect getRequiredRect();
+ /*virtual*/ void initSpeakerControl();
+
+ /*
+ * Returns number of unread messages.
+ */
+ /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
protected:
LLAdHocChiclet(const Params& p);
@@ -514,10 +522,14 @@ protected:
*/
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+ /*
+ * Finds a current speaker and resets the SpeakerControl with speaker's ID
+ */
+ /*virtual*/ void switchToCurrentSpeaker();
+
private:
LLChicletAvatarIconCtrl* mChicletIconCtrl;
- LLChicletSpeakerCtrl* mSpeakerCtrl;
LLMenuGL* mPopupMenu;
};
@@ -547,14 +559,17 @@ public:
*/
/*virtual*/ void setSessionId(const LLUUID& session_id);
+ /*
+ * Keep Speaker Control with actual speaker's ID
+ */
+ /*virtual*/ void draw();
+
/**
* Callback for LLGroupMgrObserver, we get this when group data is available or changed.
* Sets group icon.
*/
/*virtual*/ void changed(LLGroupChange gc);
- /*virtual*/ void setShowSpeaker(bool show);
-
/*
* 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.
@@ -562,15 +577,14 @@ public:
/*virtual*/ void setCounter(S32);
/*
- * Returns number of unread messages.
+ * Init Speaker Control with speaker's ID
*/
- /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
+ /*virtual*/ void initSpeakerControl();
/*
- * Returns rect, required to display chiclet.
- * Width is the only valid value.
+ * Returns number of unread messages.
*/
- /*virtual*/ LLRect getRequiredRect();
+ /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
~LLIMGroupChiclet();
@@ -579,6 +593,11 @@ protected:
friend class LLUICtrlFactory;
/*
+ * Finds a current speaker and resets the SpeakerControl with speaker's ID
+ */
+ /*virtual*/ void switchToCurrentSpeaker();
+
+ /*
* Creates chiclet popup menu. Will create P2P or Group IM Chat menu
* based on other participant's id.
*/
@@ -597,7 +616,6 @@ protected:
private:
LLChicletGroupIconCtrl* mChicletIconCtrl;
- LLChicletSpeakerCtrl* mSpeakerCtrl;
LLMenuGL* mPopupMenu;
};
@@ -660,9 +678,6 @@ public:
Optional<S32> chiclet_padding,
scrolling_offset;
- Optional<LLButton::Params> left_scroll_button,
- right_scroll_button;
-
Optional<S32> min_width;
Params();
@@ -736,6 +751,11 @@ public:
/*virtual*/ BOOL postBuild();
/*
+ * Handler for the Voice Client's signal. Finds a corresponding chiclet and toggles its SpeakerControl
+ */
+ void onCurrentVoiceChannelChanged(const LLUUID& session_id);
+
+ /*
* Reshapes controls and rearranges chiclets if needed.
*/
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE );
@@ -812,6 +832,16 @@ protected:
void onRightScrollClick();
/*
+ * Callback for right scroll button held down event
+ */
+ void onLeftScrollHeldDown();
+
+ /*
+ * Callback for left scroll button held down event
+ */
+ void onRightScrollHeldDown();
+
+ /*
* Callback for mouse wheel scrolled, calls scrollRight() or scrollLeft()
*/
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
@@ -851,6 +881,7 @@ protected:
S32 mScrollingOffset;
S32 mMinWidth;
bool mShowControls;
+ static const S32 s_scroll_ratio;
};
template<class T>
diff --git a/indra/newview/lldriverparam.cpp b/indra/newview/lldriverparam.cpp
index 45f4b4fbd0..3961afe9af 100644
--- a/indra/newview/lldriverparam.cpp
+++ b/indra/newview/lldriverparam.cpp
@@ -242,7 +242,7 @@ BOOL LLDriverParam::parseData(LLXmlTreeNode* node)
}
#endif
-void LLDriverParam::setWeight(F32 weight, BOOL set_by_user)
+void LLDriverParam::setWeight(F32 weight, BOOL upload_bake)
{
F32 min_weight = getMinWeight();
F32 max_weight = getMaxWeight();
@@ -301,7 +301,7 @@ void LLDriverParam::setWeight(F32 weight, BOOL set_by_user)
driven_weight = driven_min;
}
- setDrivenWeight(driven,driven_weight,set_by_user);
+ setDrivenWeight(driven,driven_weight,upload_bake);
continue;
}
else
@@ -325,13 +325,13 @@ void LLDriverParam::setWeight(F32 weight, BOOL set_by_user)
driven_weight = driven_min;
}
- setDrivenWeight(driven,driven_weight,set_by_user);
+ setDrivenWeight(driven,driven_weight,upload_bake);
continue;
}
}
driven_weight = getDrivenWeight(driven, mCurWeight);
- setDrivenWeight(driven,driven_weight,set_by_user);
+ setDrivenWeight(driven,driven_weight,upload_bake);
}
}
@@ -455,9 +455,9 @@ const LLVector3* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_
//-----------------------------------------------------------------------------
// setAnimationTarget()
//-----------------------------------------------------------------------------
-void LLDriverParam::setAnimationTarget( F32 target_value, BOOL set_by_user )
+void LLDriverParam::setAnimationTarget( F32 target_value, BOOL upload_bake )
{
- LLVisualParam::setAnimationTarget(target_value, set_by_user);
+ LLVisualParam::setAnimationTarget(target_value, upload_bake);
for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
{
@@ -466,16 +466,16 @@ void LLDriverParam::setAnimationTarget( F32 target_value, BOOL set_by_user )
// this isn't normally necessary, as driver params handle interpolation of their driven params
// but texture params need to know to assume their final value at beginning of interpolation
- driven->mParam->setAnimationTarget(driven_weight, set_by_user);
+ driven->mParam->setAnimationTarget(driven_weight, upload_bake);
}
}
//-----------------------------------------------------------------------------
// stopAnimating()
//-----------------------------------------------------------------------------
-void LLDriverParam::stopAnimating(BOOL set_by_user)
+void LLDriverParam::stopAnimating(BOOL upload_bake)
{
- LLVisualParam::stopAnimating(set_by_user);
+ LLVisualParam::stopAnimating(upload_bake);
for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
{
@@ -585,7 +585,7 @@ F32 LLDriverParam::getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight
return driven_weight;
}
-void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool set_by_user)
+void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake)
{
LLVOAvatarSelf *avatar_self = gAgent.getAvatarObject();
if(mWearablep &&
@@ -593,10 +593,10 @@ void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bo
mWearablep->isOnTop())
{
// call setWeight through LLVOAvatarSelf so other wearables can be updated with the correct values
- avatar_self->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, set_by_user );
+ avatar_self->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake );
}
else
{
- driven->mParam->setWeight( driven_weight, set_by_user );
+ driven->mParam->setWeight( driven_weight, upload_bake );
}
}
diff --git a/indra/newview/lldriverparam.h b/indra/newview/lldriverparam.h
index 069e71a2cb..4e2daf5ba7 100644
--- a/indra/newview/lldriverparam.h
+++ b/indra/newview/lldriverparam.h
@@ -99,9 +99,9 @@ public:
// LLVisualParam Virtual functions
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
/*virtual*/ void apply( ESex sex ) {} // apply is called separately for each driven param.
- /*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*/ void setWeight(F32 weight, BOOL upload_bake);
+ /*virtual*/ void setAnimationTarget( F32 target_value, BOOL upload_bake );
+ /*virtual*/ void stopAnimating(BOOL upload_bake);
/*virtual*/ BOOL linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params);
/*virtual*/ void resetDrivenParams();
@@ -114,7 +114,7 @@ public:
/*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
protected:
F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight);
- void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool set_by_user);
+ void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake);
LLVector3 mDefaultVec; // temp holder
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index b01293d17c..80b0a430e0 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -64,7 +64,7 @@
#include "llwindow.h"
#include "stringize.h"
#include "llsdutil_math.h"
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
#if LL_WINDOWS
#include "lldxhardware.h"
@@ -302,13 +302,17 @@ static std::string get_viewer_release_notes_url()
return LLWeb::escapeURL(url.str());
}
-class LLFloaterAboutListener: public LLDispatchListener
+class LLFloaterAboutListener: public LLEventAPI
{
public:
LLFloaterAboutListener():
- LLDispatchListener("LLFloaterAbout", "op")
+ LLEventAPI("LLFloaterAbout",
+ "LLFloaterAbout listener to retrieve About box info")
{
- add("getInfo", &LLFloaterAboutListener::getInfo, LLSD().insert("reply", LLSD()));
+ add("getInfo",
+ "Request an LLSD::Map containing information used to populate About box",
+ &LLFloaterAboutListener::getInfo,
+ LLSD().insert("reply", LLSD()));
}
private:
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index f07f9412a2..4434a8013d 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -348,6 +348,8 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.AutoDetectAspect", boost::bind(&LLFloaterPreference::onCommitAutoDetectAspect, this));
mCommitCallbackRegistrar.add("Pref.onSelectAspectRatio", boost::bind(&LLFloaterPreference::onKeystrokeAspectRatio, this));
mCommitCallbackRegistrar.add("Pref.QualityPerformance", boost::bind(&LLFloaterPreference::onChangeQuality, this, _2));
+ mCommitCallbackRegistrar.add("Pref.applyUIColor", boost::bind(&LLFloaterPreference::applyUIColor, this ,_1, _2));
+ mCommitCallbackRegistrar.add("Pref.getUIColor", boost::bind(&LLFloaterPreference::getUIColor, this ,_1, _2));
sSkin = gSavedSettings.getString("SkinCurrent");
@@ -1356,18 +1358,24 @@ void LLFloaterPreference::initWindowSizeControls(LLPanel* panelp)
}
+void LLFloaterPreference::applyUIColor(LLUICtrl* ctrl, const LLSD& param)
+{
+ LLUIColorTable::instance().setColor(param.asString(), LLColor4(ctrl->getValue()));
+}
+
+void LLFloaterPreference::getUIColor(LLUICtrl* ctrl, const LLSD& param)
+{
+ LLColorSwatchCtrl* color_swatch = (LLColorSwatchCtrl*) ctrl;
+ color_swatch->setOriginal(LLUIColorTable::instance().getColor(param.asString()));
+}
+
//----------------------------------------------------------------------------
static LLRegisterPanelClassWrapper<LLPanelPreference> t_places("panel_preference");
LLPanelPreference::LLPanelPreference()
: LLPanel()
{
- mCommitCallbackRegistrar.add("Pref.setControlFalse", boost::bind(&LLPanelPreference::setControlFalse,this, _2));
-}
-
-static void applyUIColor(const std::string& color_name, LLUICtrl* ctrl, const LLSD& param)
-{
- LLUIColorTable::instance().setColor(color_name, LLColor4(param));
+ mCommitCallbackRegistrar.add("Pref.setControlFalse", boost::bind(&LLPanelPreference::setControlFalse,this, _2));
}
//virtual
@@ -1496,55 +1504,6 @@ BOOL LLPanelPreference::postBuild()
refresh();
}
-
- if(hasChild("user") && hasChild("agent") && hasChild("im")
- && hasChild("system") && hasChild("script_error") && hasChild("objects")
- && hasChild("owner") && hasChild("background") && hasChild("links"))
- {
- LLColorSwatchCtrl* color_swatch = getChild<LLColorSwatchCtrl>("user");
- color_swatch->setCommitCallback(boost::bind(&applyUIColor, "UserChatColor", _1, _2));
- color_swatch->setOriginal(LLUIColorTable::instance().getColor("UserChatColor"));
-
- color_swatch = getChild<LLColorSwatchCtrl>("agent");
- color_swatch->setCommitCallback(boost::bind(&applyUIColor, "AgentChatColor", _1, _2));
- color_swatch->setOriginal(LLUIColorTable::instance().getColor("AgentChatColor"));
-
- color_swatch = getChild<LLColorSwatchCtrl>("im");
- color_swatch->setCommitCallback(boost::bind(&applyUIColor, "IMChatColor", _1, _2));
- color_swatch->setOriginal(LLUIColorTable::instance().getColor("IMChatColor"));
-
- color_swatch = getChild<LLColorSwatchCtrl>("system");
- color_swatch->setCommitCallback(boost::bind(&applyUIColor, "SystemChatColor", _1, _2));
- color_swatch->setOriginal(LLUIColorTable::instance().getColor("SystemChatColor"));
-
- color_swatch = getChild<LLColorSwatchCtrl>("script_error");
- color_swatch->setCommitCallback(boost::bind(&applyUIColor, "ScriptErrorColor", _1, _2));
- color_swatch->setOriginal(LLUIColorTable::instance().getColor("ScriptErrorColor"));
-
- color_swatch = getChild<LLColorSwatchCtrl>("objects");
- color_swatch->setCommitCallback(boost::bind(&applyUIColor, "ObjectChatColor", _1, _2));
- color_swatch->setOriginal(LLUIColorTable::instance().getColor("ObjectChatColor"));
-
- color_swatch = getChild<LLColorSwatchCtrl>("owner");
- color_swatch->setCommitCallback(boost::bind(&applyUIColor, "llOwnerSayChatColor", _1, _2));
- color_swatch->setOriginal(LLUIColorTable::instance().getColor("llOwnerSayChatColor"));
-
- color_swatch = getChild<LLColorSwatchCtrl>("background");
- color_swatch->setCommitCallback(boost::bind(&applyUIColor, "BackgroundChatColor", _1, _2));
- color_swatch->setOriginal(LLUIColorTable::instance().getColor("BackgroundChatColor"));
-
- color_swatch = getChild<LLColorSwatchCtrl>("links");
- color_swatch->setCommitCallback(boost::bind(&applyUIColor, "HTMLLinkColor", _1, _2));
- color_swatch->setOriginal(LLUIColorTable::instance().getColor("HTMLLinkColor"));
- }
-
- if(hasChild("effect_color_swatch"))
- {
- LLColorSwatchCtrl* color_swatch = getChild<LLColorSwatchCtrl>("effect_color_swatch");
- color_swatch->setCommitCallback(boost::bind(&applyUIColor, "EffectColor", _1, _2));
- color_swatch->setOriginal(LLUIColorTable::instance().getColor("EffectColor"));
- }
-
apply();
return true;
}
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index b1ad0348c0..10f39e46f1 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -133,7 +133,9 @@ public:
void onCommitAutoDetectAspect();
void applyResolution();
void applyWindowSize();
-
+ void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
+ void getUIColor(LLUICtrl* ctrl, const LLSD& param);
+
static void initWindowSizeControls(LLPanel* panelp);
static void buildLists(void* data);
@@ -159,6 +161,7 @@ public:
virtual void apply();
virtual void cancel();
void setControlFalse(const LLSD& user_data);
+
private:
typedef std::map<LLControlVariable*, LLSD> control_values_map_t;
control_values_map_t mSavedValues;
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index ca2cdffcf8..e2df2ffdf7 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -124,9 +124,19 @@ void LLFloaterSearch::search(const LLSD &key)
url += "&p=" + search_token.asString();
// also append the user's preferred maturity (can be changed via prefs)
- std::string maturity = "pg";
- if (gAgent.prefersMature()) maturity += ",mature";
- if (gAgent.prefersAdult()) maturity += ",adult";
+ std::string maturity;
+ if (gAgent.prefersAdult())
+ {
+ maturity = "42"; // PG,Mature,Adult
+ }
+ else if (gAgent.prefersMature())
+ {
+ maturity = "21"; // PG,Mature
+ }
+ else
+ {
+ maturity = "13"; // PG
+ }
url += "&r=" + maturity;
// and load the URL in the web view
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index 663bd232f7..3613ac803e 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -849,6 +849,7 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save)
{
LLUICtrlFactory::getInstance()->buildFloater(*floaterp, path, NULL); // just build it
(*floaterp)->openFloater((*floaterp)->getKey());
+ (*floaterp)->setCanResize((*floaterp)->isResizable());
}
}
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 010ed23918..cdb85f5b1c 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -181,13 +181,9 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL
// item->setContextMenu(mContextMenu);
item->childSetVisible("info_btn", false);
+ item->childSetVisible("profile_btn", false);
item->setGroupIconVisible(mShowIcons);
- if (id.isNull())
- {
- item->childSetVisible("profile_btn", false);
- }
-
addItem(item, id, pos);
// setCommentVisible(false);
@@ -254,7 +250,10 @@ void LLGroupListItem::onMouseEnter(S32 x, S32 y, MASK mask)
{
childSetVisible("hovered_icon", true);
if (mGroupID.notNull()) // don't show the info button for the "none" group
+ {
mInfoBtn->setVisible(true);
+ childSetVisible("profile_btn", true);
+ }
LLPanel::onMouseEnter(x, y, mask);
}
@@ -263,6 +262,7 @@ void LLGroupListItem::onMouseLeave(S32 x, S32 y, MASK mask)
{
childSetVisible("hovered_icon", false);
mInfoBtn->setVisible(false);
+ childSetVisible("profile_btn", false);
LLPanel::onMouseLeave(x, y, mask);
}
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 5a2331aa06..54fc6f02fb 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -479,11 +479,29 @@ void LLIMFloater::updateMessages()
LLStyle::Params style_params;
style_params.color(chat_color);
- LLChat chat(message);
+ LLChat chat;
chat.mFromID = from_id;
chat.mFromName = from;
- mChatHistory->appendWidgetMessage(chat, style_params);
+ //Handle IRC styled /me messages.
+ std::string prefix = message.substr(0, 4);
+ if (prefix == "/me " || prefix == "/me'")
+ {
+ if (from.size() > 0)
+ {
+ style_params.font.style = "ITALIC";
+ chat.mText = from + " ";
+ mChatHistory->appendWidgetMessage(chat, style_params);
+ }
+ message = message.substr(3);
+ style_params.font.style = "UNDERLINE";
+ mChatHistory->appendText(message, FALSE, style_params);
+ }
+ else
+ {
+ chat.mText = message;
+ mChatHistory->appendWidgetMessage(chat, style_params);
+ }
mLastMessageIndex = msg["index"].asInteger();
}
@@ -499,7 +517,7 @@ void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void*
LLIMModel::LLIMSession* im_session =
LLIMModel::instance().findIMSession(self->mSessionID);
//TODO: While disabled lllineeditor can receive focus we need to check if it is enabled (EK)
- if( im_session && im_session->mTextIMPossible && !self->mInputEditor->getEnabled())
+ if( im_session && im_session->mTextIMPossible && self->mInputEditor->getEnabled())
{
//in disconnected state IM input editor should be disabled
self->mInputEditor->setEnabled(!gDisconnected);
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 0b8b5935f8..87b801d73b 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -848,8 +848,11 @@ void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update)
}
- //update the speakers dropdown too
- mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated);
+ //update the speakers dropdown too, if it's available
+ if (mSpeakerPanel)
+ {
+ mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated);
+ }
}
}
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 8fb7027e82..d48aaf8461 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -46,6 +46,7 @@
#include "llagent.h"
#include "llavatariconctrl.h"
+#include "llbottomtray.h"
#include "llcallingcard.h"
#include "llchat.h"
#include "llresmgr.h"
@@ -73,6 +74,7 @@
#include "llvoicechannel.h"
#include "lltrans.h"
#include "llrecentpeople.h"
+#include "llsyswellwindow.h"
#include "llfirstuse.h"
#include "llagentui.h"
@@ -439,8 +441,11 @@ bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, co
addToHistory(session_id, from, from_id, utf8_text);
if (log2file) logToFile(session_id, from, from_id, utf8_text);
- //we do not count system messages
- if (from_id.notNull()) session->mNumUnread++;
+ //we do not count system messages and our messages
+ if (from_id.notNull() && from_id != gAgentID && SYSTEM_FROM != from)
+ {
+ session->mNumUnread++;
+ }
// notify listeners
LLSD arg;
@@ -651,22 +656,10 @@ void LLIMModel::sendMessage(const std::string& utf8_text,
//local echo for the legacy communicate panel
std::string history_echo;
- std::string utf8_copy = utf8_text;
LLAgentUI::buildFullname(history_echo);
- // Look for IRC-style emotes here.
+ history_echo += ": " + utf8_text;
- std::string prefix = utf8_copy.substr(0, 4);
- if (prefix == "/me " || prefix == "/me'")
- {
- utf8_copy.replace(0,3,"");
- }
- else
- {
- history_echo += ": ";
- }
- history_echo += utf8_copy;
-
LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(im_session_id);
if (floater) floater->addHistoryLine(history_echo, LLUIColorTable::instance().getColor("IMChatColor"), true, gAgent.getID());
@@ -862,7 +855,17 @@ bool LLIMModel::sendStartSession(
return false;
}
-
+// static
+void LLIMModel::sendSessionInitialized(const LLUUID &session_id)
+{
+ LLIMSession* session = getInstance()->findIMSession(session_id);
+ if (session)
+ {
+ LLSD arg;
+ arg["session_id"] = session_id;
+ getInstance()->mSessionInitializedSignal(arg);
+ }
+}
//
// Helper Functions
@@ -1090,16 +1093,90 @@ LLIMMgr::onConfirmForceCloseError(
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLOutgoingCallDialog
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LLOutgoingCallDialog::LLOutgoingCallDialog(const LLSD& payload) :
+ LLDockableFloater(NULL, false, payload),
+ mPayload(payload)
+{
+}
+
+void LLOutgoingCallDialog::getAllowedRect(LLRect& rect)
+{
+ rect = gViewerWindow->getWorldViewRectRaw();
+}
+
+void LLOutgoingCallDialog::onOpen(const LLSD& key)
+{
+ // tell the user which voice channel they are leaving
+ if (!mPayload["old_channel_name"].asString().empty())
+ {
+ childSetTextArg("leaving", "[CURRENT_CHAT]", mPayload["old_channel_name"].asString());
+ }
+ else
+ {
+ childSetTextArg("leaving", "[CURRENT_CHAT]", getString("localchat"));
+ }
+
+ std::string callee_name = mPayload["session_name"].asString();
+ if (callee_name == "anonymous")
+ {
+ callee_name = getString("anonymous");
+ }
+
+ setTitle(callee_name);
+
+ LLSD callee_id = mPayload["other_user_id"];
+ childSetTextArg("calling", "[CALLEE_NAME]", callee_name);
+ LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon");
+ icon->setValue(callee_id);
+
+ // dock the dialog to the sys well, where other sys messages appear
+ setDockControl(new LLDockControl(LLBottomTray::getInstance()->getSysWell(),
+ this, getDockTongue(), LLDockControl::TOP,
+ boost::bind(&LLOutgoingCallDialog::getAllowedRect, this, _1)));
+}
+
+
+//static
+void LLOutgoingCallDialog::onCancel(void* user_data)
+{
+ LLOutgoingCallDialog* self = (LLOutgoingCallDialog*)user_data;
+
+ if (!gIMMgr)
+ return;
+
+ LLUUID session_id = self->mPayload["session_id"].asUUID();
+ gIMMgr->endCall(session_id);
+
+ self->closeFloater();
+}
+
+
+BOOL LLOutgoingCallDialog::postBuild()
+{
+ BOOL success = LLDockableFloater::postBuild();
+
+ childSetAction("Cancel", onCancel, this);
+
+ return success;
+}
+
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLIncomingCallDialog
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LLIncomingCallDialog::LLIncomingCallDialog(const LLSD& payload) :
- LLModalDialog(payload),
+ LLDockableFloater(NULL, false, payload),
mPayload(payload)
{
}
BOOL LLIncomingCallDialog::postBuild()
{
+ LLDockableFloater::postBuild();
+
LLSD caller_id = mPayload["caller_id"];
EInstantMessage type = (EInstantMessage)mPayload["type"].asInteger();
@@ -1118,6 +1195,11 @@ BOOL LLIncomingCallDialog::postBuild()
call_type = getString("VoiceInviteAdHoc");
}
+ // check to see if this is an Avaline call
+ LLUUID session_id = mPayload["session_id"].asUUID();
+ bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
+ childSetVisible("Start IM", is_avatar); // no IM for avaline
+
LLUICtrl* caller_name_widget = getChild<LLUICtrl>("caller name");
caller_name_widget->setValue(caller_name + " " + call_type);
LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon");
@@ -1131,6 +1213,30 @@ BOOL LLIncomingCallDialog::postBuild()
return TRUE;
}
+void LLIncomingCallDialog::getAllowedRect(LLRect& rect)
+{
+ rect = gViewerWindow->getWorldViewRectRaw();
+}
+
+void LLIncomingCallDialog::onOpen(const LLSD& key)
+{
+ // tell the user which voice channel they would be leaving
+ LLVoiceChannel *voice = LLVoiceChannel::getCurrentVoiceChannel();
+ if (voice && !voice->getSessionName().empty())
+ {
+ childSetTextArg("question", "[CURRENT_CHAT]", voice->getSessionName());
+ }
+ else
+ {
+ childSetTextArg("question", "[CURRENT_CHAT]", getString("localchat"));
+ }
+
+ // dock the dialog to the sys well, where other sys messages appear
+ setDockControl(new LLDockControl(LLBottomTray::getInstance()->getSysWell(),
+ this, getDockTongue(), LLDockControl::TOP,
+ boost::bind(&LLIncomingCallDialog::getAllowedRect, this, _1)));
+}
+
//static
void LLIncomingCallDialog::onAccept(void* user_data)
{
@@ -1157,6 +1263,9 @@ void LLIncomingCallDialog::onStartIM(void* user_data)
void LLIncomingCallDialog::processCallResponse(S32 response)
{
+ if (!gIMMgr)
+ return;
+
LLUUID session_id = mPayload["session_id"].asUUID();
EInstantMessage type = (EInstantMessage)mPayload["type"].asInteger();
LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)mPayload["inv_type"].asInteger();
@@ -1254,6 +1363,9 @@ void LLIncomingCallDialog::processCallResponse(S32 response)
bool inviteUserResponse(const LLSD& notification, const LLSD& response)
{
+ if (!gIMMgr)
+ return false;
+
const LLSD& payload = notification["payload"];
LLUUID session_id = payload["session_id"].asUUID();
EInstantMessage type = (EInstantMessage)payload["type"].asInteger();
@@ -2331,15 +2443,6 @@ public:
BOOL is_linden = LLMuteList::getInstance()->isLinden(name);
std::string separator_string(": ");
- int message_offset=0;
-
- //Handle IRC styled /me messages.
- std::string prefix = message.substr(0, 4);
- if (prefix == "/me " || prefix == "/me'")
- {
- separator_string = "";
- message_offset = 3;
- }
chat.mMuted = is_muted && !is_linden;
chat.mFromID = from_id;
@@ -2356,7 +2459,7 @@ public:
{
saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
}
- std::string buffer = saved + message.substr(message_offset);
+ std::string buffer = saved + message;
BOOL is_this_agent = FALSE;
if(from_id == gAgentID)
@@ -2375,7 +2478,7 @@ public:
ll_vector3_from_sd(message_params["position"]),
true);
- chat.mText = std::string("IM: ") + name + separator_string + saved + message.substr(message_offset);
+ chat.mText = std::string("IM: ") + name + separator_string + saved + message;
LLFloaterChat::addChat(chat, TRUE, is_this_agent);
//K now we want to accept the invitation
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index bd55bd2c30..62a54bc081 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -34,9 +34,11 @@
#define LL_LLIMVIEW_H
#include "lldarray.h"
+#include "lldockablefloater.h"
#include "llspeakers.h" //for LLIMSpeakerMgr
#include "llimpanel.h" //for voice channels
#include "llmodaldialog.h"
+#include "lldockablefloater.h"
#include "llinstantmessage.h"
#include "lluuid.h"
#include "llmultifloater.h"
@@ -102,6 +104,7 @@ public:
typedef boost::function<void(const LLSD&)> session_callback_t;
session_signal_t mNewMsgSignal;
session_signal_t mNoUnreadMsgsSignal;
+ session_signal_t mSessionInitializedSignal;
/**
* Find an IM Session corresponding to session_id
@@ -116,6 +119,7 @@ public:
boost::signals2::connection addNewMsgCallback( session_callback_t cb ) { return mNewMsgSignal.connect(cb); }
boost::signals2::connection addNoUnreadMsgsCallback( session_callback_t cb ) { return mNoUnreadMsgsSignal.connect(cb); }
+ boost::signals2::connection addSessionInitializedCallback(session_callback_t cb ) { return mSessionInitializedSignal.connect(cb); }
/**
* Create new session object in a model
@@ -189,6 +193,7 @@ public:
static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id,
const std::vector<LLUUID>& ids, EInstantMessage dialog);
static void sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing);
+ static void sendSessionInitialized(const LLUUID &session_id);
static void sendMessage(const std::string& utf8_text, const LLUUID& im_session_id,
const LLUUID& other_participant_id, EInstantMessage dialog);
@@ -398,12 +403,13 @@ private:
LLSD mPendingAgentListUpdates;
};
-class LLIncomingCallDialog : public LLModalDialog
+class LLIncomingCallDialog : public LLDockableFloater
{
public:
LLIncomingCallDialog(const LLSD& payload);
/*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
static void onAccept(void* user_data);
static void onReject(void* user_data);
@@ -411,6 +417,23 @@ public:
private:
void processCallResponse(S32 response);
+ void getAllowedRect(LLRect& rect);
+
+ LLSD mPayload;
+};
+
+class LLOutgoingCallDialog : public LLDockableFloater
+{
+public:
+ LLOutgoingCallDialog(const LLSD& payload);
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
+
+ static void onCancel(void* user_data);
+
+private:
+ void getAllowedRect(LLRect& rect);
LLSD mPayload;
};
diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp
new file mode 100644
index 0000000000..e4d2eec242
--- /dev/null
+++ b/indra/newview/llinspectremoteobject.cpp
@@ -0,0 +1,200 @@
+/**
+ * @file llinspectremoteobject.cpp
+ *
+ * $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 "llinspectremoteobject.h"
+#include "llinspect.h"
+#include "llslurl.h"
+#include "llmutelist.h"
+#include "llurlaction.h"
+#include "llpanelblockedlist.h"
+#include "llfloaterreg.h"
+#include "llui.h"
+#include "lluictrl.h"
+
+class LLViewerObject;
+
+//////////////////////////////////////////////////////////////////////////////
+// LLInspectRemoteObject
+//////////////////////////////////////////////////////////////////////////////
+
+// Remote Object Inspector, a small information window used to
+// display information about potentially-remote objects. Used
+// to display details about objects sending messages to the user.
+class LLInspectRemoteObject : public LLInspect
+{
+ friend class LLFloaterReg;
+
+public:
+ LLInspectRemoteObject(const LLSD& object_id);
+ virtual ~LLInspectRemoteObject() {};
+
+ /*virtual*/ BOOL postBuild(void);
+ /*virtual*/ void onOpen(const LLSD& avatar_id);
+
+ void onClickMap();
+ void onClickBlock();
+ void onClickClose();
+
+private:
+ void update();
+ static void nameCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data);
+
+private:
+ LLUUID mObjectID;
+ LLUUID mOwnerID;
+ std::string mOwner;
+ std::string mSLurl;
+ std::string mName;
+ bool mGroupOwned;
+};
+
+LLInspectRemoteObject::LLInspectRemoteObject(const LLSD& sd) :
+ LLInspect(LLSD()),
+ mObjectID(NULL),
+ mOwnerID(NULL),
+ mOwner(""),
+ mSLurl(""),
+ mName(""),
+ mGroupOwned(false)
+{
+}
+
+/*virtual*/
+BOOL LLInspectRemoteObject::postBuild(void)
+{
+ // hook up the inspector's buttons
+ getChild<LLUICtrl>("map_btn")->setCommitCallback(
+ boost::bind(&LLInspectRemoteObject::onClickMap, this));
+ getChild<LLUICtrl>("block_btn")->setCommitCallback(
+ boost::bind(&LLInspectRemoteObject::onClickBlock, this));
+ getChild<LLUICtrl>("close_btn")->setCommitCallback(
+ boost::bind(&LLInspectRemoteObject::onClickClose, this));
+
+ return TRUE;
+}
+
+/*virtual*/
+void LLInspectRemoteObject::onOpen(const LLSD& data)
+{
+ // Start animation
+ LLInspect::onOpen(data);
+
+ // Extract appropriate object information from input LLSD
+ // (Eventually, it might be nice to query server for details
+ // rather than require caller to pass in the information.)
+ mObjectID = data["object_id"].asUUID();
+ mName = data["name"].asString();
+ mOwnerID = data["owner_id"].asUUID();
+ mGroupOwned = data["group_owned"].asBoolean();
+ mSLurl = data["slurl"].asString();
+
+ // work out the owner's name
+ mOwner = "";
+ if (gCacheName)
+ {
+ gCacheName->get(mOwnerID, mGroupOwned, nameCallback, this);
+ }
+
+ // update the inspector with the current object state
+ update();
+
+ // Position the inspector relative to the mouse cursor
+ LLUI::positionViewNearMouse(this);
+}
+
+void LLInspectRemoteObject::onClickMap()
+{
+ std::string url = "secondlife://" + mSLurl;
+ LLUrlAction::showLocationOnMap(url);
+ closeFloater();
+}
+
+void LLInspectRemoteObject::onClickBlock()
+{
+ LLMute::EType mute_type = mGroupOwned ? LLMute::GROUP : LLMute::AGENT;
+ LLMute mute(mOwnerID, mOwner, mute_type);
+ LLMuteList::getInstance()->add(mute);
+ LLPanelBlockedList::showPanelAndSelect(mute.mID);
+ closeFloater();
+}
+
+void LLInspectRemoteObject::onClickClose()
+{
+ closeFloater();
+}
+
+//static
+void LLInspectRemoteObject::nameCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data)
+{
+ LLInspectRemoteObject *self = (LLInspectRemoteObject*)data;
+ self->mOwner = first;
+ if (!last.empty())
+ {
+ self->mOwner += " " + last;
+ }
+ self->update();
+}
+
+void LLInspectRemoteObject::update()
+{
+ // show the object name as the inspector's title
+ getChild<LLUICtrl>("object_name")->setValue(mName);
+
+ // show the object's owner - click it to show profile
+ std::string owner = mOwner;
+ if (! mOwnerID.isNull())
+ {
+ if (mGroupOwned)
+ {
+ owner = LLSLURL::buildCommand("group", mOwnerID, "about");
+ }
+ else
+ {
+ owner = LLSLURL::buildCommand("agent", mOwnerID, "about");
+ }
+ }
+ getChild<LLUICtrl>("object_owner")->setValue(owner);
+
+ // display the object's SLurl - click it to teleport
+ std::string url = "secondlife:///app/teleport/" + mSLurl;
+ getChild<LLUICtrl>("object_slurl")->setValue(url);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// LLInspectRemoteObjectUtil
+//////////////////////////////////////////////////////////////////////////////
+void LLInspectRemoteObjectUtil::registerFloater()
+{
+ LLFloaterReg::add("inspect_remote_object", "inspect_remote_object.xml",
+ &LLFloaterReg::build<LLInspectRemoteObject>);
+}
diff --git a/indra/newview/llinspectremoteobject.h b/indra/newview/llinspectremoteobject.h
new file mode 100644
index 0000000000..e756f1caf4
--- /dev/null
+++ b/indra/newview/llinspectremoteobject.h
@@ -0,0 +1,40 @@
+/**
+ * @file llinspectremoteobject.h
+ *
+ * $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 LLINSPECTREMOTEOBJECT_H
+#define LLINSPECTREMOTEOBJECT_H
+
+namespace LLInspectRemoteObjectUtil
+{
+ void registerFloater();
+}
+
+#endif
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 4b7e364cf9..4b0d524906 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -176,6 +176,7 @@ LLInventoryModel::LLInventoryModel()
mRootFolderID(),
mLibraryRootFolderID(),
mLibraryOwnerID(),
+ mIsNotifyObservers(FALSE),
mIsAgentInvUsable(false)
{
}
@@ -537,7 +538,10 @@ void LLInventoryModel::updateLinkedItems(const LLUUID& object_id)
item_array,
LLInventoryModel::INCLUDE_TRASH,
is_linked_item_match);
-
+ if (cat_array.empty() && item_array.empty())
+ {
+ return;
+ }
for (LLInventoryModel::cat_array_t::iterator cat_iter = cat_array.begin();
cat_iter != cat_array.end();
cat_iter++)
@@ -639,6 +643,7 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)
new_item = old_item;
LLUUID old_parent_id = old_item->getParentUUID();
LLUUID new_parent_id = item->getParentUUID();
+
if(old_parent_id != new_parent_id)
{
// need to update the parent-child tree
@@ -1133,6 +1138,15 @@ BOOL LLInventoryModel::containsObserver(LLInventoryObserver* observer) const
// The optional argument 'service_name' is used by Agent Inventory Service [DEV-20328]
void LLInventoryModel::notifyObservers(const std::string service_name)
{
+ if (mIsNotifyObservers)
+ {
+ // Within notifyObservers, something called notifyObservers
+ // again. This type of recursion is unsafe because it causes items to be
+ // processed twice, and this can easily lead to infinite loops.
+ llwarns << "Call was made to notifyObservers within notifyObservers!" << llendl;
+ return;
+ }
+ mIsNotifyObservers = TRUE;
for (observer_list_t::iterator iter = mObservers.begin();
iter != mObservers.end(); )
{
@@ -1154,12 +1168,21 @@ void LLInventoryModel::notifyObservers(const std::string service_name)
mModifyMask = LLInventoryObserver::NONE;
mChangedItemIDs.clear();
+ mIsNotifyObservers = FALSE;
}
// store flag for change
// and id of object change applies to
void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent)
{
+ if (mIsNotifyObservers)
+ {
+ // Something marked an item for change within a call to notifyObservers
+ // (which is in the process of processing the list of items marked for change).
+ // This means the change may fail to be processed.
+ llwarns << "Adding changed mask within notify observers! Change will likely be lost." << llendl;
+ }
+
mModifyMask |= mask;
if (referent.notNull())
{
@@ -1271,8 +1294,11 @@ void LLInventoryModel::fetchInventoryResponder::error(U32 status, const std::str
bool LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id)
{
- if(folder_id.isNull()) return false;
-
+ if(folder_id.isNull())
+ {
+ llwarns << "Calling fetch descendents on NULL folder id!" << llendl;
+ return false;
+ }
LLViewerInventoryCategory* cat = getCategory(folder_id);
if(!cat)
{
@@ -1830,13 +1856,13 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
{
//llinfos << "LLInventoryModel::addItem()" << llendl;
-
- // This can happen if assettype enums change. This can be a backwards compatibility issue
- // in some viewer prototypes prior to when the AT_LINK enum changed from 23 to 24.
+ // This can happen if assettype enums from llassettype.h ever change.
+ // For example, there is a known backwards compatibility issue in some viewer prototypes prior to when
+ // the AT_LINK enum changed from 23 to 24.
if ((item->getType() == LLAssetType::AT_NONE)
|| LLAssetType::lookup(item->getType()) == LLAssetType::badLookup())
{
- llwarns << "Got bad asset type for item ( name: " << item->getName() << " type: " << item->getType() << " inv-type: " << item->getInventoryType() << " ), ignoring." << llendl;
+ llwarns << "Got bad asset type for item [ name: " << item->getName() << " type: " << item->getType() << " inv-type: " << item->getInventoryType() << " ], ignoring." << llendl;
return;
}
if(item)
@@ -1845,7 +1871,7 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
// The item will show up as a broken link.
if (item->getIsBrokenLink())
{
- llinfos << "Adding broken link ( name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << llendl;
+ llinfos << "Adding broken link [ name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << llendl;
}
mItemMap[item->getUUID()] = item;
}
@@ -2173,7 +2199,7 @@ bool LLInventoryModel::loadSkeleton(
// Add all the items loaded which are parented to a
// category with a correctly cached parent
- count = items.count();
+ S32 bad_link_count = 0;
cat_map_t::iterator unparented = mCategoryMap.end();
for(item_array_t::const_iterator item_iter = items.begin();
item_iter != items.end();
@@ -2190,7 +2216,11 @@ bool LLInventoryModel::loadSkeleton(
// This can happen if the linked object's baseobj is removed from the cache but the linked object is still in the cache.
if (item->getIsBrokenLink())
{
- llinfos << "Attempted to add cached link item without baseobj present ( name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ). Ignoring and invalidating " << cat->getName() << " . " << llendl;
+ bad_link_count++;
+ lldebugs << "Attempted to add cached link item without baseobj present ( name: "
+ << item->getName() << " itemID: " << item->getUUID()
+ << " assetID: " << item->getAssetUUID()
+ << " ). Ignoring and invalidating " << cat->getName() << " . " << llendl;
invalid_categories.insert(cit->second);
continue;
}
@@ -2200,6 +2230,12 @@ bool LLInventoryModel::loadSkeleton(
}
}
}
+ if (bad_link_count > 0)
+ {
+ llinfos << "Attempted to add " << bad_link_count
+ << " cached link items without baseobj present. "
+ << "The corresponding categories were invalidated." << llendl;
+ }
}
else
{
@@ -3304,6 +3340,12 @@ void LLInventoryModel::processInventoryDescendents(LLMessageSystem* msg,void**)
for(i = 0; i < count; ++i)
{
titem->unpackMessage(msg, _PREHASH_ItemData, i);
+ // If the item has already been added (e.g. from link prefetch), then it doesn't need to be re-added.
+ if (gInventory.getItem(titem->getUUID()))
+ {
+ llinfos << "Skipping prefetched item [ Name: " << titem->getName() << " | Type: " << titem->getActualType() << " | ItemUUID: " << titem->getUUID() << " ] " << llendl;
+ continue;
+ }
gInventory.updateItem(titem);
}
@@ -3679,513 +3721,6 @@ bool LLNameCategoryCollector::operator()(
return false;
}
-
-
-///----------------------------------------------------------------------------
-/// Observers
-///----------------------------------------------------------------------------
-
-void LLInventoryCompletionObserver::changed(U32 mask)
-{
- // scan through the incomplete items and move or erase them as
- // appropriate.
- if(!mIncomplete.empty())
- {
- for(item_ref_t::iterator it = mIncomplete.begin(); it < mIncomplete.end(); )
- {
- LLViewerInventoryItem* item = gInventory.getItem(*it);
- if(!item)
- {
- it = mIncomplete.erase(it);
- continue;
- }
- if(item->isComplete())
- {
- mComplete.push_back(*it);
- it = mIncomplete.erase(it);
- continue;
- }
- ++it;
- }
- if(mIncomplete.empty())
- {
- done();
- }
- }
-}
-
-void LLInventoryCompletionObserver::watchItem(const LLUUID& id)
-{
- if(id.notNull())
- {
- mIncomplete.push_back(id);
- }
-}
-
-
-void LLInventoryFetchObserver::changed(U32 mask)
-{
- // scan through the incomplete items and move or erase them as
- // appropriate.
- if(!mIncomplete.empty())
- {
- for(item_ref_t::iterator it = mIncomplete.begin(); it < mIncomplete.end(); )
- {
- LLViewerInventoryItem* item = gInventory.getItem(*it);
- if(!item)
- {
- // BUG: This can cause done() to get called prematurely below.
- // This happens with the LLGestureInventoryFetchObserver that
- // loads gestures at startup. JC
- it = mIncomplete.erase(it);
- continue;
- }
- if(item->isComplete())
- {
- mComplete.push_back(*it);
- it = mIncomplete.erase(it);
- continue;
- }
- ++it;
- }
- if(mIncomplete.empty())
- {
- done();
- }
- }
- //llinfos << "LLInventoryFetchObserver::changed() mComplete size " << mComplete.size() << llendl;
- //llinfos << "LLInventoryFetchObserver::changed() mIncomplete size " << mIncomplete.size() << llendl;
-}
-
-bool LLInventoryFetchObserver::isEverythingComplete() const
-{
- return mIncomplete.empty();
-}
-
-void fetch_items_from_llsd(const LLSD& items_llsd)
-{
- if (!items_llsd.size()) return;
- LLSD body;
- body[0]["cap_name"] = "FetchInventory";
- body[1]["cap_name"] = "FetchLib";
- for (S32 i=0; i<items_llsd.size();i++)
- {
- if (items_llsd[i]["owner_id"].asString() == gAgent.getID().asString())
- {
- body[0]["items"].append(items_llsd[i]);
- continue;
- }
- if (items_llsd[i]["owner_id"].asString() == ALEXANDRIA_LINDEN_ID.asString())
- {
- body[1]["items"].append(items_llsd[i]);
- continue;
- }
- }
-
- for (S32 i=0; i<body.size(); i++)
- {
- if (0 >= body[i].size()) continue;
- std::string url = gAgent.getRegion()->getCapability(body[i]["cap_name"].asString());
-
- if (!url.empty())
- {
- body[i]["agent_id"] = gAgent.getID();
- LLHTTPClient::post(url, body[i], new LLInventoryModel::fetchInventoryResponder(body[i]));
- break;
- }
-
- LLMessageSystem* msg = gMessageSystem;
- BOOL start_new_message = TRUE;
- for (S32 j=0; j<body[i]["items"].size(); j++)
- {
- LLSD item_entry = body[i]["items"][j];
- if(start_new_message)
- {
- start_new_message = FALSE;
- msg->newMessageFast(_PREHASH_FetchInventory);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- }
- msg->nextBlockFast(_PREHASH_InventoryData);
- msg->addUUIDFast(_PREHASH_OwnerID, item_entry["owner_id"].asUUID());
- msg->addUUIDFast(_PREHASH_ItemID, item_entry["item_id"].asUUID());
- if(msg->isSendFull(NULL))
- {
- start_new_message = TRUE;
- gAgent.sendReliableMessage();
- }
- }
- if(!start_new_message)
- {
- gAgent.sendReliableMessage();
- }
- }
-}
-
-void LLInventoryFetchObserver::fetchItems(
- const LLInventoryFetchObserver::item_ref_t& ids)
-{
- LLUUID owner_id;
- LLSD items_llsd;
- for(item_ref_t::const_iterator it = ids.begin(); it < ids.end(); ++it)
- {
- LLViewerInventoryItem* item = gInventory.getItem(*it);
- if(item)
- {
- if(item->isComplete())
- {
- // It's complete, so put it on the complete container.
- mComplete.push_back(*it);
- continue;
- }
- else
- {
- owner_id = item->getPermissions().getOwner();
- }
- }
- else
- {
- // assume it's agent inventory.
- owner_id = gAgent.getID();
- }
-
- // It's incomplete, so put it on the incomplete container, and
- // pack this on the message.
- mIncomplete.push_back(*it);
-
- // Prepare the data to fetch
- LLSD item_entry;
- item_entry["owner_id"] = owner_id;
- item_entry["item_id"] = (*it);
- items_llsd.append(item_entry);
- }
- fetch_items_from_llsd(items_llsd);
-}
-
-// virtual
-void LLInventoryFetchDescendentsObserver::changed(U32 mask)
-{
- for(folder_ref_t::iterator it = mIncompleteFolders.begin(); it < mIncompleteFolders.end();)
- {
- LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
- if(!cat)
- {
- it = mIncompleteFolders.erase(it);
- continue;
- }
- if(isComplete(cat))
- {
- mCompleteFolders.push_back(*it);
- it = mIncompleteFolders.erase(it);
- continue;
- }
- ++it;
- }
- if(mIncompleteFolders.empty())
- {
- done();
- }
-}
-
-void LLInventoryFetchDescendentsObserver::fetchDescendents(
- const folder_ref_t& ids)
-{
- for(folder_ref_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
- {
- LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
- if(!cat) continue;
- if(!isComplete(cat))
- {
- cat->fetchDescendents(); //blindly fetch it without seeing if anything else is fetching it.
- mIncompleteFolders.push_back(*it); //Add to list of things being downloaded for this observer.
- }
- else
- {
- mCompleteFolders.push_back(*it);
- }
- }
-}
-
-bool LLInventoryFetchDescendentsObserver::isEverythingComplete() const
-{
- return mIncompleteFolders.empty();
-}
-
-bool LLInventoryFetchDescendentsObserver::isComplete(LLViewerInventoryCategory* cat)
-{
- S32 version = cat->getVersion();
- S32 descendents = cat->getDescendentCount();
- if((LLViewerInventoryCategory::VERSION_UNKNOWN == version)
- || (LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN == descendents))
- {
- return false;
- }
- // it might be complete - check known descendents against
- // currently available.
- LLInventoryModel::cat_array_t* cats;
- LLInventoryModel::item_array_t* items;
- gInventory.getDirectDescendentsOf(cat->getUUID(), cats, items);
- if(!cats || !items)
- {
- // bit of a hack - pretend we're done if they are gone or
- // incomplete. should never know, but it would suck if this
- // kept tight looping because of a corrupt memory state.
- return true;
- }
- S32 known = cats->count() + items->count();
- if(descendents == known)
- {
- // hey - we're done.
- return true;
- }
- return false;
-}
-
-void LLInventoryFetchComboObserver::changed(U32 mask)
-{
- if(!mIncompleteItems.empty())
- {
- for(item_ref_t::iterator it = mIncompleteItems.begin(); it < mIncompleteItems.end(); )
- {
- LLViewerInventoryItem* item = gInventory.getItem(*it);
- if(!item)
- {
- it = mIncompleteItems.erase(it);
- continue;
- }
- if(item->isComplete())
- {
- mCompleteItems.push_back(*it);
- it = mIncompleteItems.erase(it);
- continue;
- }
- ++it;
- }
- }
- if(!mIncompleteFolders.empty())
- {
- for(folder_ref_t::iterator it = mIncompleteFolders.begin(); it < mIncompleteFolders.end();)
- {
- LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
- if(!cat)
- {
- it = mIncompleteFolders.erase(it);
- continue;
- }
- if(gInventory.isCategoryComplete(*it))
- {
- mCompleteFolders.push_back(*it);
- it = mIncompleteFolders.erase(it);
- continue;
- }
- ++it;
- }
- }
- if(!mDone && mIncompleteItems.empty() && mIncompleteFolders.empty())
- {
- mDone = true;
- done();
- }
-}
-
-void LLInventoryFetchComboObserver::fetch(
- const folder_ref_t& folder_ids,
- const item_ref_t& item_ids)
-{
- lldebugs << "LLInventoryFetchComboObserver::fetch()" << llendl;
- for(folder_ref_t::const_iterator fit = folder_ids.begin(); fit != folder_ids.end(); ++fit)
- {
- LLViewerInventoryCategory* cat = gInventory.getCategory(*fit);
- if(!cat) continue;
- if(!gInventory.isCategoryComplete(*fit))
- {
- cat->fetchDescendents();
- lldebugs << "fetching folder " << *fit <<llendl;
- mIncompleteFolders.push_back(*fit);
- }
- else
- {
- mCompleteFolders.push_back(*fit);
- lldebugs << "completing folder " << *fit <<llendl;
- }
- }
-
- // Now for the items - we fetch everything which is not a direct
- // descendent of an incomplete folder because the item will show
- // up in an inventory descendents message soon enough so we do not
- // have to fetch it individually.
- LLSD items_llsd;
- LLUUID owner_id;
- for(item_ref_t::const_iterator iit = item_ids.begin(); iit != item_ids.end(); ++iit)
- {
- LLViewerInventoryItem* item = gInventory.getItem(*iit);
- if(!item)
- {
- lldebugs << "uanble to find item " << *iit << llendl;
- continue;
- }
- if(item->isComplete())
- {
- // It's complete, so put it on the complete container.
- mCompleteItems.push_back(*iit);
- lldebugs << "completing item " << *iit << llendl;
- continue;
- }
- else
- {
- mIncompleteItems.push_back(*iit);
- owner_id = item->getPermissions().getOwner();
- }
- if(std::find(mIncompleteFolders.begin(), mIncompleteFolders.end(), item->getParentUUID()) == mIncompleteFolders.end())
- {
- LLSD item_entry;
- item_entry["owner_id"] = owner_id;
- item_entry["item_id"] = (*iit);
- items_llsd.append(item_entry);
- }
- else
- {
- lldebugs << "not worrying about " << *iit << llendl;
- }
- }
- fetch_items_from_llsd(items_llsd);
-}
-
-void LLInventoryExistenceObserver::watchItem(const LLUUID& id)
-{
- if(id.notNull())
- {
- mMIA.push_back(id);
- }
-}
-
-void LLInventoryExistenceObserver::changed(U32 mask)
-{
- // scan through the incomplete items and move or erase them as
- // appropriate.
- if(!mMIA.empty())
- {
- for(item_ref_t::iterator it = mMIA.begin(); it < mMIA.end(); )
- {
- LLViewerInventoryItem* item = gInventory.getItem(*it);
- if(!item)
- {
- ++it;
- continue;
- }
- mExist.push_back(*it);
- it = mMIA.erase(it);
- }
- if(mMIA.empty())
- {
- done();
- }
- }
-}
-
-void LLInventoryAddedObserver::changed(U32 mask)
-{
- if(!(mask & LLInventoryObserver::ADD))
- {
- return;
- }
-
- // *HACK: If this was in response to a packet off
- // the network, figure out which item was updated.
- LLMessageSystem* msg = gMessageSystem;
-
- std::string msg_name;
- if (mMessageName.empty())
- {
- msg_name = msg->getMessageName();
- }
- else
- {
- msg_name = mMessageName;
- }
-
- if (msg_name.empty())
- {
- return;
- }
-
- // We only want newly created inventory items. JC
- if ( msg_name != "UpdateCreateInventoryItem")
- {
- return;
- }
-
- LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
- S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_InventoryData);
- for(S32 i = 0; i < num_blocks; ++i)
- {
- titem->unpackMessage(msg, _PREHASH_InventoryData, i);
- if (!(titem->getUUID().isNull()))
- {
- //we don't do anything with null keys
- mAdded.push_back(titem->getUUID());
- }
- }
- if (!mAdded.empty())
- {
- done();
- }
-}
-
-LLInventoryTransactionObserver::LLInventoryTransactionObserver(
- const LLTransactionID& transaction_id) :
- mTransactionID(transaction_id)
-{
-}
-
-void LLInventoryTransactionObserver::changed(U32 mask)
-{
- if(mask & LLInventoryObserver::ADD)
- {
- // This could be it - see if we are processing a bulk update
- LLMessageSystem* msg = gMessageSystem;
- if(msg->getMessageName()
- && (0 == strcmp(msg->getMessageName(), "BulkUpdateInventory")))
- {
- // we have a match for the message - now check the
- // transaction id.
- LLUUID id;
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_TransactionID, id);
- if(id == mTransactionID)
- {
- // woo hoo, we found it
- folder_ref_t folders;
- item_ref_t items;
- S32 count;
- count = msg->getNumberOfBlocksFast(_PREHASH_FolderData);
- S32 i;
- for(i = 0; i < count; ++i)
- {
- msg->getUUIDFast(_PREHASH_FolderData, _PREHASH_FolderID, id, i);
- if(id.notNull())
- {
- folders.push_back(id);
- }
- }
- count = msg->getNumberOfBlocksFast(_PREHASH_ItemData);
- for(i = 0; i < count; ++i)
- {
- msg->getUUIDFast(_PREHASH_ItemData, _PREHASH_ItemID, id, i);
- if(id.notNull())
- {
- items.push_back(id);
- }
- }
-
- // call the derived class the implements this method.
- done(folders, items);
- }
- }
- }
-}
-
-
///----------------------------------------------------------------------------
/// LLAssetIDMatches
///----------------------------------------------------------------------------
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index faf026887a..bd64591194 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -41,40 +41,27 @@
#include "lluuid.h"
#include "llpermissionsflags.h"
#include "llstring.h"
-
#include <map>
#include <set>
#include <string>
#include <vector>
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryObserver
-//
-// This class is designed to be a simple abstract base class which can
-// relay messages when the inventory changes.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// ! REFACTOR ! Remove llinventoryobservers.h and have other files that need it explicitly
+// include llinventoryobservers.h instead of llinventorymodel.h . This will reduce dependency on
+// llinventorymodel.h.
+#include "llinventoryobserver.h"
+
+class LLInventoryObserver;
+class LLInventoryObject;
+class LLInventoryItem;
+class LLInventoryCategory;
+class LLViewerInventoryItem;
+class LLViewerInventoryCategory;
+class LLViewerInventoryItem;
+class LLViewerInventoryCategory;
+class LLMessageSystem;
+class LLInventoryCollectFunctor;
-class LLInventoryObserver
-{
-public:
- // This enumeration is a way to refer to what changed in a more
- // human readable format. You can mask the value provided by
- // chaged() to see if the observer is interested in the change.
- enum
- {
- NONE = 0,
- LABEL = 1, // name changed
- INTERNAL = 2, // internal change, eg, asset uuid different
- ADD = 4, // something added
- REMOVE = 8, // something deleted
- STRUCTURE = 16, // structural change, eg, item or folder moved
- CALLING_CARD = 32, // online, grant status, cancel, etc change
- ALL = 0xffffffff
- };
- virtual ~LLInventoryObserver() {};
- virtual void changed(U32 mask) = 0;
- std::string mMessageName; // used by Agent Inventory Service only. [DEV-20328]
-};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInventoryModel
@@ -87,16 +74,6 @@ public:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLInventoryObject;
-class LLInventoryItem;
-class LLInventoryCategory;
-class LLViewerInventoryItem;
-class LLViewerInventoryCategory;
-class LLViewerInventoryItem;
-class LLViewerInventoryCategory;
-class LLMessageSystem;
-class LLInventoryCollectFunctor;
-
class LLInventoryModel
{
public:
@@ -473,23 +450,12 @@ protected:
cat_array_t* getUnlockedCatArray(const LLUUID& id);
item_array_t* getUnlockedItemArray(const LLUUID& id);
-protected:
+private:
// Variables used to track what has changed since the last notify.
U32 mModifyMask;
typedef std::set<LLUUID> changed_items_t;
changed_items_t mChangedItemIDs;
- // Information for tracking the actual inventory. We index this
- // information in a lot of different ways so we can access
- // the inventory using several different identifiers.
- // mInventory member data is the 'master' list of inventory, and
- // mCategoryMap and mItemMap store uuid->object mappings.
- typedef std::map<LLUUID, LLPointer<LLViewerInventoryCategory> > cat_map_t;
- typedef std::map<LLUUID, LLPointer<LLViewerInventoryItem> > item_map_t;
- //inv_map_t mInventory;
- cat_map_t mCategoryMap;
- item_map_t mItemMap;
-
std::map<LLUUID, bool> mCategoryLock;
std::map<LLUUID, bool> mItemLock;
@@ -525,6 +491,21 @@ protected:
// This flag is used to handle an invalid inventory state.
bool mIsAgentInvUsable;
+private:
+ // Information for tracking the actual inventory. We index this
+ // information in a lot of different ways so we can access
+ // the inventory using several different identifiers.
+ // mInventory member data is the 'master' list of inventory, and
+ // mCategoryMap and mItemMap store uuid->object mappings.
+ typedef std::map<LLUUID, LLPointer<LLViewerInventoryCategory> > cat_map_t;
+ typedef std::map<LLUUID, LLPointer<LLViewerInventoryItem> > item_map_t;
+ //inv_map_t mInventory;
+ cat_map_t mCategoryMap;
+ item_map_t mItemMap;
+
+ // Flag set when notifyObservers is being called, to look for bugs
+ // where it's called recursively.
+ BOOL mIsNotifyObservers;
public:
// *NOTE: DEBUG functionality
void dumpInventory() const;
@@ -767,183 +748,5 @@ public:
LLInventoryItem* item);
};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryCompletionObserver
-//
-// Class which can be used as a base class for doing something when
-// when all observed items are locally complete. This class implements
-// the changed() method of LLInventoryObserver and declares a new
-// method named done() which is called when all watched items have
-// complete information in the inventory model.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLInventoryCompletionObserver : public LLInventoryObserver
-{
-public:
- LLInventoryCompletionObserver() {}
- virtual void changed(U32 mask);
-
- void watchItem(const LLUUID& id);
-
-protected:
- virtual void done() = 0;
-
- typedef std::vector<LLUUID> item_ref_t;
- item_ref_t mComplete;
- item_ref_t mIncomplete;
-};
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryFetchObserver
-//
-// This class is much like the LLInventoryCompletionObserver, except
-// that it handles all the the fetching necessary. Override the done()
-// method to do the thing you want.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLInventoryFetchObserver : public LLInventoryObserver
-{
-public:
- LLInventoryFetchObserver() {}
- virtual void changed(U32 mask);
-
- typedef std::vector<LLUUID> item_ref_t;
-
- bool isEverythingComplete() const;
- void fetchItems(const item_ref_t& ids);
- virtual void done() = 0;
-
-protected:
- item_ref_t mComplete;
- item_ref_t mIncomplete;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryFetchDescendentsObserver
-//
-// This class is much like the LLInventoryCompletionObserver, except
-// that it handles fetching based on category. Override the done()
-// method to do the thing you want.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLInventoryFetchDescendentsObserver : public LLInventoryObserver
-{
-public:
- LLInventoryFetchDescendentsObserver() {}
- virtual void changed(U32 mask);
-
- typedef std::vector<LLUUID> folder_ref_t;
- void fetchDescendents(const folder_ref_t& ids);
- bool isEverythingComplete() const;
- virtual void done() = 0;
-
-protected:
- bool isComplete(LLViewerInventoryCategory* cat);
- folder_ref_t mIncompleteFolders;
- folder_ref_t mCompleteFolders;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryFetchComboObserver
-//
-// This class does an appropriate combination of fetch descendents and
-// item fetches based on completion of categories and items. Much like
-// the fetch and fetch descendents, this will call done() when everything
-// has arrived.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLInventoryFetchComboObserver : public LLInventoryObserver
-{
-public:
- LLInventoryFetchComboObserver() : mDone(false) {}
- virtual void changed(U32 mask);
-
- typedef std::vector<LLUUID> folder_ref_t;
- typedef std::vector<LLUUID> item_ref_t;
- void fetch(const folder_ref_t& folder_ids, const item_ref_t& item_ids);
-
- virtual void done() = 0;
-
-protected:
- bool mDone;
- folder_ref_t mCompleteFolders;
- folder_ref_t mIncompleteFolders;
- item_ref_t mCompleteItems;
- item_ref_t mIncompleteItems;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryExistenceObserver
-//
-// This class is used as a base class for doing somethign when all the
-// observed item ids exist in the inventory somewhere. You can derive
-// a class from this class and implement the done() method to do
-// something useful.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLInventoryExistenceObserver : public LLInventoryObserver
-{
-public:
- LLInventoryExistenceObserver() {}
- virtual void changed(U32 mask);
-
- void watchItem(const LLUUID& id);
-
-protected:
- virtual void done() = 0;
-
- typedef std::vector<LLUUID> item_ref_t;
- item_ref_t mExist;
- item_ref_t mMIA;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryAddedObserver
-//
-// This class is used as a base class for doing something when
-// a new item arrives in inventory.
-// It does not watch for a certain UUID, rather it acts when anything is added
-// Derive a class from this class and implement the done() method to do
-// something useful.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLInventoryAddedObserver : public LLInventoryObserver
-{
-public:
- LLInventoryAddedObserver() : mAdded() {}
- virtual void changed(U32 mask);
-
-protected:
- virtual void done() = 0;
-
- typedef std::vector<LLUUID> item_ref_t;
- item_ref_t mAdded;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryTransactionObserver
-//
-// Class which can be used as a base class for doing something when an
-// inventory transaction completes.
-//
-// *NOTE: This class is not quite complete. Avoid using unless you fix up it's
-// functionality gaps.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLInventoryTransactionObserver : public LLInventoryObserver
-{
-public:
- LLInventoryTransactionObserver(const LLTransactionID& transaction_id);
- virtual void changed(U32 mask);
-
-protected:
- typedef std::vector<LLUUID> folder_ref_t;
- typedef std::vector<LLUUID> item_ref_t;
- virtual void done(const folder_ref_t& folders, const item_ref_t& items) = 0;
-
- LLTransactionID mTransactionID;
-};
-
-
#endif // LL_LLINVENTORYMODEL_H
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
new file mode 100644
index 0000000000..3ccf593d27
--- /dev/null
+++ b/indra/newview/llinventoryobserver.cpp
@@ -0,0 +1,564 @@
+/**
+ * @file llinventoryobserver.cpp
+ * @brief Implementation of the inventory observers used to track agent inventory.
+ *
+ * $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 "llinventoryobserver.h"
+
+#include "llassetstorage.h"
+#include "llcrc.h"
+#include "lldir.h"
+#include "llsys.h"
+#include "llxfermanager.h"
+#include "message.h"
+
+#include "llagent.h"
+#include "llagentwearables.h"
+#include "llfloater.h"
+#include "llfocusmgr.h"
+#include "llinventorybridge.h"
+#include "llinventoryfunctions.h"
+#include "llinventorymodel.h"
+#include "llviewermessage.h"
+#include "llviewerwindow.h"
+#include "llviewerregion.h"
+#include "llappviewer.h"
+#include "lldbstrings.h"
+#include "llviewerstats.h"
+#include "llmutelist.h"
+#include "llnotifications.h"
+#include "llcallbacklist.h"
+#include "llpreview.h"
+#include "llviewercontrol.h"
+#include "llvoavatarself.h"
+#include "llsdutil.h"
+#include <deque>
+
+void LLInventoryCompletionObserver::changed(U32 mask)
+{
+ // scan through the incomplete items and move or erase them as
+ // appropriate.
+ if(!mIncomplete.empty())
+ {
+ for(item_ref_t::iterator it = mIncomplete.begin(); it < mIncomplete.end(); )
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(*it);
+ if(!item)
+ {
+ it = mIncomplete.erase(it);
+ continue;
+ }
+ if(item->isComplete())
+ {
+ mComplete.push_back(*it);
+ it = mIncomplete.erase(it);
+ continue;
+ }
+ ++it;
+ }
+ if(mIncomplete.empty())
+ {
+ done();
+ }
+ }
+}
+
+void LLInventoryCompletionObserver::watchItem(const LLUUID& id)
+{
+ if(id.notNull())
+ {
+ mIncomplete.push_back(id);
+ }
+}
+
+
+void LLInventoryFetchObserver::changed(U32 mask)
+{
+ // scan through the incomplete items and move or erase them as
+ // appropriate.
+ if(!mIncomplete.empty())
+ {
+ for(item_ref_t::iterator it = mIncomplete.begin(); it < mIncomplete.end(); )
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(*it);
+ if(!item)
+ {
+ // BUG: This can cause done() to get called prematurely below.
+ // This happens with the LLGestureInventoryFetchObserver that
+ // loads gestures at startup. JC
+ it = mIncomplete.erase(it);
+ continue;
+ }
+ if(item->isComplete())
+ {
+ mComplete.push_back(*it);
+ it = mIncomplete.erase(it);
+ continue;
+ }
+ ++it;
+ }
+ if(mIncomplete.empty())
+ {
+ done();
+ }
+ }
+ //llinfos << "LLInventoryFetchObserver::changed() mComplete size " << mComplete.size() << llendl;
+ //llinfos << "LLInventoryFetchObserver::changed() mIncomplete size " << mIncomplete.size() << llendl;
+}
+
+bool LLInventoryFetchObserver::isEverythingComplete() const
+{
+ return mIncomplete.empty();
+}
+
+void fetch_items_from_llsd(const LLSD& items_llsd)
+{
+ if (!items_llsd.size()) return;
+ LLSD body;
+ body[0]["cap_name"] = "FetchInventory";
+ body[1]["cap_name"] = "FetchLib";
+ for (S32 i=0; i<items_llsd.size();i++)
+ {
+ if (items_llsd[i]["owner_id"].asString() == gAgent.getID().asString())
+ {
+ body[0]["items"].append(items_llsd[i]);
+ continue;
+ }
+ if (items_llsd[i]["owner_id"].asString() == ALEXANDRIA_LINDEN_ID.asString())
+ {
+ body[1]["items"].append(items_llsd[i]);
+ continue;
+ }
+ }
+
+ for (S32 i=0; i<body.size(); i++)
+ {
+ if (0 >= body[i].size()) continue;
+ std::string url = gAgent.getRegion()->getCapability(body[i]["cap_name"].asString());
+
+ if (!url.empty())
+ {
+ body[i]["agent_id"] = gAgent.getID();
+ LLHTTPClient::post(url, body[i], new LLInventoryModel::fetchInventoryResponder(body[i]));
+ break;
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+ BOOL start_new_message = TRUE;
+ for (S32 j=0; j<body[i]["items"].size(); j++)
+ {
+ LLSD item_entry = body[i]["items"][j];
+ if(start_new_message)
+ {
+ start_new_message = FALSE;
+ msg->newMessageFast(_PREHASH_FetchInventory);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ }
+ msg->nextBlockFast(_PREHASH_InventoryData);
+ msg->addUUIDFast(_PREHASH_OwnerID, item_entry["owner_id"].asUUID());
+ msg->addUUIDFast(_PREHASH_ItemID, item_entry["item_id"].asUUID());
+ if(msg->isSendFull(NULL))
+ {
+ start_new_message = TRUE;
+ gAgent.sendReliableMessage();
+ }
+ }
+ if(!start_new_message)
+ {
+ gAgent.sendReliableMessage();
+ }
+ }
+}
+
+void LLInventoryFetchObserver::fetchItems(
+ const LLInventoryFetchObserver::item_ref_t& ids)
+{
+ LLUUID owner_id;
+ LLSD items_llsd;
+ for(item_ref_t::const_iterator it = ids.begin(); it < ids.end(); ++it)
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(*it);
+ if(item)
+ {
+ if(item->isComplete())
+ {
+ // It's complete, so put it on the complete container.
+ mComplete.push_back(*it);
+ continue;
+ }
+ else
+ {
+ owner_id = item->getPermissions().getOwner();
+ }
+ }
+ else
+ {
+ // assume it's agent inventory.
+ owner_id = gAgent.getID();
+ }
+
+ // It's incomplete, so put it on the incomplete container, and
+ // pack this on the message.
+ mIncomplete.push_back(*it);
+
+ // Prepare the data to fetch
+ LLSD item_entry;
+ item_entry["owner_id"] = owner_id;
+ item_entry["item_id"] = (*it);
+ items_llsd.append(item_entry);
+ }
+ fetch_items_from_llsd(items_llsd);
+}
+
+// virtual
+void LLInventoryFetchDescendentsObserver::changed(U32 mask)
+{
+ for(folder_ref_t::iterator it = mIncompleteFolders.begin(); it < mIncompleteFolders.end();)
+ {
+ LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
+ if(!cat)
+ {
+ it = mIncompleteFolders.erase(it);
+ continue;
+ }
+ if(isComplete(cat))
+ {
+ mCompleteFolders.push_back(*it);
+ it = mIncompleteFolders.erase(it);
+ continue;
+ }
+ ++it;
+ }
+ if(mIncompleteFolders.empty())
+ {
+ done();
+ }
+}
+
+void LLInventoryFetchDescendentsObserver::fetchDescendents(
+ const folder_ref_t& ids)
+{
+ for(folder_ref_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
+ if(!cat) continue;
+ if(!isComplete(cat))
+ {
+ cat->fetchDescendents(); //blindly fetch it without seeing if anything else is fetching it.
+ mIncompleteFolders.push_back(*it); //Add to list of things being downloaded for this observer.
+ }
+ else
+ {
+ mCompleteFolders.push_back(*it);
+ }
+ }
+}
+
+bool LLInventoryFetchDescendentsObserver::isEverythingComplete() const
+{
+ return mIncompleteFolders.empty();
+}
+
+bool LLInventoryFetchDescendentsObserver::isComplete(LLViewerInventoryCategory* cat)
+{
+ S32 version = cat->getVersion();
+ S32 descendents = cat->getDescendentCount();
+ if((LLViewerInventoryCategory::VERSION_UNKNOWN == version)
+ || (LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN == descendents))
+ {
+ return false;
+ }
+ // it might be complete - check known descendents against
+ // currently available.
+ LLInventoryModel::cat_array_t* cats;
+ LLInventoryModel::item_array_t* items;
+ gInventory.getDirectDescendentsOf(cat->getUUID(), cats, items);
+ if(!cats || !items)
+ {
+ // bit of a hack - pretend we're done if they are gone or
+ // incomplete. should never know, but it would suck if this
+ // kept tight looping because of a corrupt memory state.
+ return true;
+ }
+ S32 known = cats->count() + items->count();
+ if(descendents == known)
+ {
+ // hey - we're done.
+ return true;
+ }
+ return false;
+}
+
+void LLInventoryFetchComboObserver::changed(U32 mask)
+{
+ if(!mIncompleteItems.empty())
+ {
+ for(item_ref_t::iterator it = mIncompleteItems.begin(); it < mIncompleteItems.end(); )
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(*it);
+ if(!item)
+ {
+ it = mIncompleteItems.erase(it);
+ continue;
+ }
+ if(item->isComplete())
+ {
+ mCompleteItems.push_back(*it);
+ it = mIncompleteItems.erase(it);
+ continue;
+ }
+ ++it;
+ }
+ }
+ if(!mIncompleteFolders.empty())
+ {
+ for(folder_ref_t::iterator it = mIncompleteFolders.begin(); it < mIncompleteFolders.end();)
+ {
+ LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
+ if(!cat)
+ {
+ it = mIncompleteFolders.erase(it);
+ continue;
+ }
+ if(gInventory.isCategoryComplete(*it))
+ {
+ mCompleteFolders.push_back(*it);
+ it = mIncompleteFolders.erase(it);
+ continue;
+ }
+ ++it;
+ }
+ }
+ if(!mDone && mIncompleteItems.empty() && mIncompleteFolders.empty())
+ {
+ mDone = true;
+ done();
+ }
+}
+
+void LLInventoryFetchComboObserver::fetch(
+ const folder_ref_t& folder_ids,
+ const item_ref_t& item_ids)
+{
+ lldebugs << "LLInventoryFetchComboObserver::fetch()" << llendl;
+ for(folder_ref_t::const_iterator fit = folder_ids.begin(); fit != folder_ids.end(); ++fit)
+ {
+ LLViewerInventoryCategory* cat = gInventory.getCategory(*fit);
+ if(!cat) continue;
+ if(!gInventory.isCategoryComplete(*fit))
+ {
+ cat->fetchDescendents();
+ lldebugs << "fetching folder " << *fit <<llendl;
+ mIncompleteFolders.push_back(*fit);
+ }
+ else
+ {
+ mCompleteFolders.push_back(*fit);
+ lldebugs << "completing folder " << *fit <<llendl;
+ }
+ }
+
+ // Now for the items - we fetch everything which is not a direct
+ // descendent of an incomplete folder because the item will show
+ // up in an inventory descendents message soon enough so we do not
+ // have to fetch it individually.
+ LLSD items_llsd;
+ LLUUID owner_id;
+ for(item_ref_t::const_iterator iit = item_ids.begin(); iit != item_ids.end(); ++iit)
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(*iit);
+ if(!item)
+ {
+ lldebugs << "uanble to find item " << *iit << llendl;
+ continue;
+ }
+ if(item->isComplete())
+ {
+ // It's complete, so put it on the complete container.
+ mCompleteItems.push_back(*iit);
+ lldebugs << "completing item " << *iit << llendl;
+ continue;
+ }
+ else
+ {
+ mIncompleteItems.push_back(*iit);
+ owner_id = item->getPermissions().getOwner();
+ }
+ if(std::find(mIncompleteFolders.begin(), mIncompleteFolders.end(), item->getParentUUID()) == mIncompleteFolders.end())
+ {
+ LLSD item_entry;
+ item_entry["owner_id"] = owner_id;
+ item_entry["item_id"] = (*iit);
+ items_llsd.append(item_entry);
+ }
+ else
+ {
+ lldebugs << "not worrying about " << *iit << llendl;
+ }
+ }
+ fetch_items_from_llsd(items_llsd);
+}
+
+void LLInventoryExistenceObserver::watchItem(const LLUUID& id)
+{
+ if(id.notNull())
+ {
+ mMIA.push_back(id);
+ }
+}
+
+void LLInventoryExistenceObserver::changed(U32 mask)
+{
+ // scan through the incomplete items and move or erase them as
+ // appropriate.
+ if(!mMIA.empty())
+ {
+ for(item_ref_t::iterator it = mMIA.begin(); it < mMIA.end(); )
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(*it);
+ if(!item)
+ {
+ ++it;
+ continue;
+ }
+ mExist.push_back(*it);
+ it = mMIA.erase(it);
+ }
+ if(mMIA.empty())
+ {
+ done();
+ }
+ }
+}
+
+void LLInventoryAddedObserver::changed(U32 mask)
+{
+ if(!(mask & LLInventoryObserver::ADD))
+ {
+ return;
+ }
+
+ // *HACK: If this was in response to a packet off
+ // the network, figure out which item was updated.
+ LLMessageSystem* msg = gMessageSystem;
+
+ std::string msg_name;
+ if (mMessageName.empty())
+ {
+ msg_name = msg->getMessageName();
+ }
+ else
+ {
+ msg_name = mMessageName;
+ }
+
+ if (msg_name.empty())
+ {
+ return;
+ }
+
+ // We only want newly created inventory items. JC
+ if ( msg_name != "UpdateCreateInventoryItem")
+ {
+ return;
+ }
+
+ LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
+ S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_InventoryData);
+ for(S32 i = 0; i < num_blocks; ++i)
+ {
+ titem->unpackMessage(msg, _PREHASH_InventoryData, i);
+ if (!(titem->getUUID().isNull()))
+ {
+ //we don't do anything with null keys
+ mAdded.push_back(titem->getUUID());
+ }
+ }
+ if (!mAdded.empty())
+ {
+ done();
+ }
+}
+
+LLInventoryTransactionObserver::LLInventoryTransactionObserver(
+ const LLTransactionID& transaction_id) :
+ mTransactionID(transaction_id)
+{
+}
+
+void LLInventoryTransactionObserver::changed(U32 mask)
+{
+ if(mask & LLInventoryObserver::ADD)
+ {
+ // This could be it - see if we are processing a bulk update
+ LLMessageSystem* msg = gMessageSystem;
+ if(msg->getMessageName()
+ && (0 == strcmp(msg->getMessageName(), "BulkUpdateInventory")))
+ {
+ // we have a match for the message - now check the
+ // transaction id.
+ LLUUID id;
+ msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_TransactionID, id);
+ if(id == mTransactionID)
+ {
+ // woo hoo, we found it
+ folder_ref_t folders;
+ item_ref_t items;
+ S32 count;
+ count = msg->getNumberOfBlocksFast(_PREHASH_FolderData);
+ S32 i;
+ for(i = 0; i < count; ++i)
+ {
+ msg->getUUIDFast(_PREHASH_FolderData, _PREHASH_FolderID, id, i);
+ if(id.notNull())
+ {
+ folders.push_back(id);
+ }
+ }
+ count = msg->getNumberOfBlocksFast(_PREHASH_ItemData);
+ for(i = 0; i < count; ++i)
+ {
+ msg->getUUIDFast(_PREHASH_ItemData, _PREHASH_ItemID, id, i);
+ if(id.notNull())
+ {
+ items.push_back(id);
+ }
+ }
+
+ // call the derived class the implements this method.
+ done(folders, items);
+ }
+ }
+ }
+}
diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h
new file mode 100644
index 0000000000..384e6292e8
--- /dev/null
+++ b/indra/newview/llinventoryobserver.h
@@ -0,0 +1,249 @@
+/**
+ * @file llinventoryobserver.h
+ * @brief LLInventoryObserver class header file
+ *
+ * $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_LLINVENTORYOBSERVERS_H
+#define LL_LLINVENTORYOBSERVERS_H
+
+#include "lluuid.h"
+#include <string>
+#include <vector>
+
+class LLViewerInventoryCategory;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryObserver
+//
+// This class is designed to be a simple abstract base class which can
+// relay messages when the inventory changes.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLInventoryObserver
+{
+public:
+ // This enumeration is a way to refer to what changed in a more
+ // human readable format. You can mask the value provided by
+ // chaged() to see if the observer is interested in the change.
+ enum
+ {
+ NONE = 0,
+ LABEL = 1, // name changed
+ INTERNAL = 2, // internal change, eg, asset uuid different
+ ADD = 4, // something added
+ REMOVE = 8, // something deleted
+ STRUCTURE = 16, // structural change, eg, item or folder moved
+ CALLING_CARD = 32, // online, grant status, cancel, etc change
+ ALL = 0xffffffff
+ };
+ virtual ~LLInventoryObserver() {};
+ virtual void changed(U32 mask) = 0;
+ std::string mMessageName; // used by Agent Inventory Service only. [DEV-20328]
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryCompletionObserver
+//
+// Class which can be used as a base class for doing something when
+// when all observed items are locally complete. This class implements
+// the changed() method of LLInventoryObserver and declares a new
+// method named done() which is called when all watched items have
+// complete information in the inventory model.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLInventoryCompletionObserver : public LLInventoryObserver
+{
+public:
+ LLInventoryCompletionObserver() {}
+ virtual void changed(U32 mask);
+
+ void watchItem(const LLUUID& id);
+
+protected:
+ virtual void done() = 0;
+
+ typedef std::vector<LLUUID> item_ref_t;
+ item_ref_t mComplete;
+ item_ref_t mIncomplete;
+};
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryFetchObserver
+//
+// This class is much like the LLInventoryCompletionObserver, except
+// that it handles all the the fetching necessary. Override the done()
+// method to do the thing you want.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLInventoryFetchObserver : public LLInventoryObserver
+{
+public:
+ LLInventoryFetchObserver() {}
+ virtual void changed(U32 mask);
+
+ typedef std::vector<LLUUID> item_ref_t;
+
+ bool isEverythingComplete() const;
+ void fetchItems(const item_ref_t& ids);
+ virtual void done() = 0;
+
+protected:
+ item_ref_t mComplete;
+ item_ref_t mIncomplete;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryFetchDescendentsObserver
+//
+// This class is much like the LLInventoryCompletionObserver, except
+// that it handles fetching based on category. Override the done()
+// method to do the thing you want.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLInventoryFetchDescendentsObserver : public LLInventoryObserver
+{
+public:
+ LLInventoryFetchDescendentsObserver() {}
+ virtual void changed(U32 mask);
+
+ typedef std::vector<LLUUID> folder_ref_t;
+ void fetchDescendents(const folder_ref_t& ids);
+ bool isEverythingComplete() const;
+ virtual void done() = 0;
+
+protected:
+ bool isComplete(LLViewerInventoryCategory* cat);
+ folder_ref_t mIncompleteFolders;
+ folder_ref_t mCompleteFolders;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryFetchComboObserver
+//
+// This class does an appropriate combination of fetch descendents and
+// item fetches based on completion of categories and items. Much like
+// the fetch and fetch descendents, this will call done() when everything
+// has arrived.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLInventoryFetchComboObserver : public LLInventoryObserver
+{
+public:
+ LLInventoryFetchComboObserver() : mDone(false) {}
+ virtual void changed(U32 mask);
+
+ typedef std::vector<LLUUID> folder_ref_t;
+ typedef std::vector<LLUUID> item_ref_t;
+ void fetch(const folder_ref_t& folder_ids, const item_ref_t& item_ids);
+
+ virtual void done() = 0;
+
+protected:
+ bool mDone;
+ folder_ref_t mCompleteFolders;
+ folder_ref_t mIncompleteFolders;
+ item_ref_t mCompleteItems;
+ item_ref_t mIncompleteItems;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryExistenceObserver
+//
+// This class is used as a base class for doing somethign when all the
+// observed item ids exist in the inventory somewhere. You can derive
+// a class from this class and implement the done() method to do
+// something useful.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLInventoryExistenceObserver : public LLInventoryObserver
+{
+public:
+ LLInventoryExistenceObserver() {}
+ virtual void changed(U32 mask);
+
+ void watchItem(const LLUUID& id);
+
+protected:
+ virtual void done() = 0;
+
+ typedef std::vector<LLUUID> item_ref_t;
+ item_ref_t mExist;
+ item_ref_t mMIA;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryAddedObserver
+//
+// This class is used as a base class for doing something when
+// a new item arrives in inventory.
+// It does not watch for a certain UUID, rather it acts when anything is added
+// Derive a class from this class and implement the done() method to do
+// something useful.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLInventoryAddedObserver : public LLInventoryObserver
+{
+public:
+ LLInventoryAddedObserver() : mAdded() {}
+ virtual void changed(U32 mask);
+
+protected:
+ virtual void done() = 0;
+
+ typedef std::vector<LLUUID> item_ref_t;
+ item_ref_t mAdded;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryTransactionObserver
+//
+// Class which can be used as a base class for doing something when an
+// inventory transaction completes.
+//
+// *NOTE: This class is not quite complete. Avoid using unless you fix up it's
+// functionality gaps.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLInventoryTransactionObserver : public LLInventoryObserver
+{
+public:
+ LLInventoryTransactionObserver(const LLTransactionID& transaction_id);
+ virtual void changed(U32 mask);
+
+protected:
+ typedef std::vector<LLUUID> folder_ref_t;
+ typedef std::vector<LLUUID> item_ref_t;
+ virtual void done(const folder_ref_t& folders, const item_ref_t& items) = 0;
+
+ LLTransactionID mTransactionID;
+};
+
+
+#endif // LL_LLINVENTORYOBSERVERS_H
+
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 9a71e53441..dfd4af5c28 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -191,11 +191,9 @@ BOOL LLInventoryPanel::postBuild()
{
rebuildViewsFor(mStartFolderID);
mHasInventoryConnection = true;
+ defaultOpenInventory();
}
- // bit of a hack to make sure the inventory is open.
- mFolders->openFolder(preferred_type != LLFolderType::FT_NONE ? LLViewerFolderType::lookupNewCategoryName(preferred_type) : "My Inventory");
-
if (mSortOrderSetting != INHERIT_SORT_ORDER)
{
setSortOrder(gSavedSettings.getU32(mSortOrderSetting));
@@ -300,6 +298,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
{
rebuildViewsFor(mStartFolderID);
mHasInventoryConnection = true;
+ defaultOpenInventory();
return;
}
@@ -561,6 +560,25 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
}
}
+// bit of a hack to make sure the inventory is open.
+void LLInventoryPanel::defaultOpenInventory()
+{
+ const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString);
+ if (preferred_type != LLFolderType::FT_NONE)
+ {
+ const std::string& top_level_folder_name = LLViewerFolderType::lookupNewCategoryName(preferred_type);
+ mFolders->openFolder(top_level_folder_name);
+ }
+ else
+ {
+ // Get the first child (it should be "My Inventory") and
+ // open it up by name (just to make sure the first child is actually a folder).
+ LLView* first_child = mFolders->getFirstChild();
+ const std::string& first_child_name = first_child->getName();
+ mFolders->openFolder(first_child_name);
+ }
+}
+
struct LLConfirmPurgeData
{
LLUUID mID;
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 9f74fad5c1..e398c44105 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -165,7 +165,7 @@ protected:
// Given the id and the parent, build all of the folder views.
void rebuildViewsFor(const LLUUID& id);
virtual void buildNewViews(const LLUUID& id); // made virtual to support derived classes. EXT-719
-
+ void defaultOpenInventory(); // open the first level of inventory
protected:
LLInventoryModel* mInventory;
LLInventoryObserver* mInventoryObserver;
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index e5f347ddc4..a01426ea87 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -73,9 +73,9 @@ LLLoginInstance::LLLoginInstance() :
{
mLoginModule->getEventPump().listen("lllogininstance",
boost::bind(&LLLoginInstance::handleLoginEvent, this, _1));
- mDispatcher.add("fail.login", boost::bind(&LLLoginInstance::handleLoginFailure, this, _1));
- mDispatcher.add("connect", boost::bind(&LLLoginInstance::handleLoginSuccess, this, _1));
- mDispatcher.add("disconnect", boost::bind(&LLLoginInstance::handleDisconnect, this, _1));
+ mDispatcher.add("fail.login", "", boost::bind(&LLLoginInstance::handleLoginFailure, this, _1));
+ mDispatcher.add("connect", "", boost::bind(&LLLoginInstance::handleLoginSuccess, this, _1));
+ mDispatcher.add("disconnect", "", boost::bind(&LLLoginInstance::handleDisconnect, this, _1));
}
LLLoginInstance::~LLLoginInstance()
@@ -182,6 +182,9 @@ void LLLoginInstance::constructAuthParams(const LLSD& credentials)
mRequestData["method"] = "login_to_simulator";
mRequestData["params"] = request_params;
mRequestData["options"] = requested_options;
+
+ mRequestData["cfg_srv_timeout"] = gSavedSettings.getF32("LoginSRVTimeout");
+ mRequestData["cfg_srv_pump"] = gSavedSettings.getString("LoginSRVPump");
}
bool LLLoginInstance::handleLoginEvent(const LLSD& event)
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 541db0ca6e..9439717fb8 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -323,8 +323,8 @@ void LLNameListCtrl::refreshAll(const LLUUID& id, const std::string& first,
LLInstanceTracker<LLNameListCtrl>::instance_iter it;
for (it = beginInstances(); it != endInstances(); ++it)
{
- LLNameListCtrl* ctrl = *it;
- ctrl->refresh(id, first, last, is_group);
+ LLNameListCtrl& ctrl = *it;
+ ctrl.refresh(id, first, last, is_group);
}
}
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index 17b712bc5e..794d73a5ad 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -480,7 +480,7 @@ void LLNavigationBar::rebuildTeleportHistoryMenu()
type = LLTeleportHistoryMenuItem::TYPE_CURRENT;
LLTeleportHistoryMenuItem::Params item_params;
- item_params.label = item_params.name = hist_items[i].getTitle();
+ item_params.label = item_params.name = hist_items[i].mTitle;
item_params.item_type = type;
item_params.on_click.function(boost::bind(&LLNavigationBar::onTeleportHistoryMenuItemClicked, this, i));
LLTeleportHistoryMenuItem* new_itemp = LLUICtrlFactory::create<LLTeleportHistoryMenuItem>(item_params);
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index d54545971b..94b8791147 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -36,7 +36,6 @@
#include "lltrans.h"
#include "llnearbychatbar.h"
-#include "llspeakbutton.h"
#include "llbottomtray.h"
#include "llagent.h"
#include "llgesturemgr.h"
@@ -234,14 +233,6 @@ BOOL LLNearbyChatBar::postBuild()
mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
mOutputMonitor->setVisible(FALSE);
- mSpeakBtn = getParent()->getChild<LLSpeakButton>("talk");
-
- // Speak button should be initially disabled because
- // it takes some time between logging in to world and connecting to voice channel.
- mSpeakBtn->setEnabled(FALSE);
-
- // Registering Chat Bar to receive Voice client status change notifications.
- gVoiceClient->addObserver(this);
return TRUE;
}
@@ -260,6 +251,8 @@ bool LLNearbyChatBar::instanceExists()
void LLNearbyChatBar::draw()
{
+// TODO: mantipov: remove
+/*
LLRect rect = getRect();
S32 max_width = getMaxWidth();
@@ -269,6 +262,7 @@ void LLNearbyChatBar::draw()
reshape(rect.getWidth(), rect.getHeight(), FALSE);
setRect(rect);
}
+*/
displaySpeakingIndicator();
LLPanel::draw();
@@ -730,27 +724,6 @@ public:
}
};
-void LLNearbyChatBar::onChange(EStatusType status, const std::string &channelURI, bool proximal)
-{
- // Time it takes to connect to voice channel might be pretty long,
- // so don't expect user login or STATUS_VOICE_ENABLED to be followed by STATUS_JOINED.
- BOOL enable = FALSE;
-
- switch (status)
- {
- // Do not add STATUS_VOICE_ENABLED because voice chat is
- // inactive until STATUS_JOINED
- case STATUS_JOINED:
- enable = TRUE;
- break;
- default:
- enable = FALSE;
- break;
- }
-
- mSpeakBtn->setEnabled(enable);
-}
-
// Creating the object registers with the dispatcher.
LLChatHandler gChatHandler;
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index 56ee706a97..224118e088 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -42,9 +42,6 @@
#include "llspeakers.h"
-class LLSpeakButton;
-
-
class LLGestureComboBox
: public LLComboBox
, public LLGestureManagerObserver
@@ -76,7 +73,6 @@ protected:
class LLNearbyChatBar
: public LLPanel
-, public LLVoiceClientStatusObserver
{
public:
// constructor for inline chat-bars (e.g. hosted in chat history window)
@@ -105,11 +101,6 @@ public:
S32 getMinWidth() const;
S32 getMaxWidth() const;
- /**
- * Implements LLVoiceClientStatusObserver::onChange()
- */
- /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
-
protected:
static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata);
@@ -127,7 +118,6 @@ protected:
static S32 sLastSpecialChatChannel;
LLLineEditor* mChatBox;
- LLSpeakButton* mSpeakBtn;
LLOutputMonitorCtrl* mOutputMonitor;
LLLocalSpeakerMgr* mSpeakerMgr;
};
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 4286582cdc..6145588df2 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -155,11 +155,9 @@ void LLNetMap::draw()
F32 rotation = 0;
{
- LLGLEnable scissor(GL_SCISSOR_TEST);
-
+ LLLocalClipRect clip(getLocalRect());
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLLocalClipRect clip(getLocalRect());
glMatrixMode(GL_MODELVIEW);
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 1bf7be1c4e..471dd28426 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -95,14 +95,9 @@ bool LLOfferHandler::processNotification(const LLSD& notify)
LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, notification->getPayload()["from_id"]);
if (!LLIMMgr::instance().hasSession(session_id))
{
- // create session with faked type to avoid creating chicklets
session_id = LLIMMgr::instance().addSession(
notification->getSubstitutions()["NAME"], IM_NOTHING_SPECIAL,
notification->getPayload()["from_id"]);
- if (session_id != LLUUID::null)
- {
- LLIMFloater::show(session_id);
- }
}
LLIMMgr::instance().addMessage(session_id, LLUUID(),
notification->getSubstitutions()["NAME"],
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index a29c9752e6..67a2704501 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -1142,3 +1142,552 @@ void LLPanelClassified::setDefaultAccessCombo()
break;
}
}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLPanelClassifiedInfo::LLPanelClassifiedInfo()
+ : LLPanel()
+ , mInfoLoaded(false)
+{
+}
+
+LLPanelClassifiedInfo::~LLPanelClassifiedInfo()
+{
+}
+
+// static
+LLPanelClassifiedInfo* LLPanelClassifiedInfo::create()
+{
+ LLPanelClassifiedInfo* panel = new LLPanelClassifiedInfo();
+ LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_classified_info.xml");
+ return panel;
+}
+
+BOOL LLPanelClassifiedInfo::postBuild()
+{
+ childSetAction("back_btn", boost::bind(&LLPanelClassifiedInfo::onExit, this));
+ childSetAction("show_on_map_btn", boost::bind(&LLPanelClassifiedInfo::onMapClick, this));
+ childSetAction("teleport_btn", boost::bind(&LLPanelClassifiedInfo::onTeleportClick, this));
+
+ return TRUE;
+}
+
+void LLPanelClassifiedInfo::setExitCallback(const commit_callback_t& cb)
+{
+ getChild<LLButton>("back_btn")->setClickedCallback(cb);
+}
+
+void LLPanelClassifiedInfo::setEditClassifiedCallback(const commit_callback_t& cb)
+{
+ getChild<LLButton>("edit_btn")->setClickedCallback(cb);
+}
+
+void LLPanelClassifiedInfo::onOpen(const LLSD& key)
+{
+ LLUUID avatar_id = key["avatar_id"];
+ if(avatar_id.isNull())
+ {
+ return;
+ }
+
+ if(getAvatarId().notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+ }
+
+ setAvatarId(avatar_id);
+
+ resetData();
+ resetControls();
+
+ setClassifiedId(key["classified_id"]);
+ setClassifiedName(key["name"]);
+ setDescription(key["desc"]);
+ setSnapshotId(key["snapshot_id"]);
+
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
+ setInfoLoaded(false);
+}
+
+void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType type)
+{
+ if(APT_CLASSIFIED_INFO == type)
+ {
+ LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
+ if(c_info && getClassifiedId() == c_info->classified_id)
+ {
+ setClassifiedName(c_info->name);
+ setDescription(c_info->description);
+ setSnapshotId(c_info->snapshot_id);
+ setParcelId(c_info->parcel_id);
+ setPosGlobal(c_info->pos_global);
+ setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global));
+ childSetValue("category", LLClassifiedInfo::sCategories[c_info->category]);
+
+ static std::string mature_str = getString("type_mature");
+ static std::string pg_str = getString("type_pg");
+
+ bool mature = is_cf_mature(c_info->flags);
+ childSetValue("content_type", mature ? mature_str : pg_str);
+ childSetValue("auto_renew", is_cf_auto_renew(c_info->flags));
+
+ childSetTextArg("price_for_listing", "[PRICE]", llformat("%d", c_info->price_for_listing));
+
+ setInfoLoaded(true);
+ }
+ }
+}
+
+void LLPanelClassifiedInfo::resetData()
+{
+ setClassifiedName(LLStringUtil::null);
+ setDescription(LLStringUtil::null);
+ setClassifiedLocation(LLStringUtil::null);
+ setClassifiedId(LLUUID::null);
+ setSnapshotId(LLUUID::null);
+ mPosGlobal.clearVec();
+ childSetValue("category", LLStringUtil::null);
+ childSetValue("content_type", LLStringUtil::null);
+}
+
+void LLPanelClassifiedInfo::resetControls()
+{
+ if(getAvatarId() == gAgent.getID())
+ {
+ childSetEnabled("edit_btn", TRUE);
+ childSetVisible("edit_btn", TRUE);
+ }
+ else
+ {
+ childSetEnabled("edit_btn", FALSE);
+ childSetVisible("edit_btn", FALSE);
+ }
+}
+
+void LLPanelClassifiedInfo::setClassifiedName(const std::string& name)
+{
+ childSetValue("classified_name", name);
+}
+
+std::string LLPanelClassifiedInfo::getClassifiedName()
+{
+ return childGetValue("classified_name").asString();
+}
+
+void LLPanelClassifiedInfo::setDescription(const std::string& desc)
+{
+ childSetValue("classified_desc", desc);
+}
+
+std::string LLPanelClassifiedInfo::getDescription()
+{
+ return childGetValue("classified_desc").asString();
+}
+
+void LLPanelClassifiedInfo::setClassifiedLocation(const std::string& location)
+{
+ childSetValue("classified_location", location);
+}
+
+void LLPanelClassifiedInfo::setSnapshotId(const LLUUID& id)
+{
+ childSetValue("classified_snapshot", id);
+}
+
+LLUUID LLPanelClassifiedInfo::getSnapshotId()
+{
+ return childGetValue("classified_snapshot").asUUID();
+}
+
+// static
+std::string LLPanelClassifiedInfo::createLocationText(
+ const std::string& original_name,
+ const std::string& sim_name,
+ const LLVector3d& pos_global)
+{
+ std::string location_text;
+
+ location_text.append(original_name);
+
+ if (!sim_name.empty())
+ {
+ if (!location_text.empty())
+ location_text.append(", ");
+ location_text.append(sim_name);
+ }
+
+ if (!location_text.empty())
+ location_text.append(" ");
+
+ if (!pos_global.isNull())
+ {
+ S32 region_x = llround((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
+ S32 region_y = llround((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
+ S32 region_z = llround((F32)pos_global.mdV[VZ]);
+ location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
+ }
+
+ return location_text;
+}
+
+void LLPanelClassifiedInfo::onMapClick()
+{
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ LLFloaterReg::showInstance("world_map", "center");
+}
+
+void LLPanelClassifiedInfo::onTeleportClick()
+{
+ if (!getPosGlobal().isExactlyZero())
+ {
+ gAgent.teleportViaLocation(getPosGlobal());
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ }
+}
+
+void LLPanelClassifiedInfo::onExit()
+{
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+static const S32 CB_ITEM_MATURE = 0;
+static const S32 CB_ITEM_PG = 1;
+
+LLPanelClassifiedEdit::LLPanelClassifiedEdit()
+ : LLPanelClassifiedInfo()
+ , mIsNew(false)
+{
+}
+
+LLPanelClassifiedEdit::~LLPanelClassifiedEdit()
+{
+}
+
+//static
+LLPanelClassifiedEdit* LLPanelClassifiedEdit::create()
+{
+ LLPanelClassifiedEdit* panel = new LLPanelClassifiedEdit();
+ LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_edit_classified.xml");
+ return panel;
+}
+
+BOOL LLPanelClassifiedEdit::postBuild()
+{
+ LLPanelClassifiedInfo::postBuild();
+
+ LLTextureCtrl* snapshot = getChild<LLTextureCtrl>("classified_snapshot");
+ snapshot->setOnSelectCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
+
+ LLUICtrl* edit_icon = getChild<LLUICtrl>("edit_icon");
+ snapshot->setMouseEnterCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseEnter, this, edit_icon));
+ snapshot->setMouseLeaveCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseLeave, this, edit_icon));
+ edit_icon->setVisible(false);
+
+ LLLineEditor* line_edit = getChild<LLLineEditor>("classified_name");
+ line_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
+
+ LLTextEditor* text_edit = getChild<LLTextEditor>("classified_desc");
+ text_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
+
+ LLComboBox* combobox = getChild<LLComboBox>( "category");
+ LLClassifiedInfo::cat_map::iterator iter;
+ for (iter = LLClassifiedInfo::sCategories.begin();
+ iter != LLClassifiedInfo::sCategories.end();
+ iter++)
+ {
+ combobox->add(LLTrans::getString(iter->second));
+ }
+
+ combobox->setCommitCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
+
+ childSetCommitCallback("content_type", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
+ childSetCommitCallback("price_for_listing", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
+ childSetCommitCallback("auto_renew", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
+
+ childSetAction("save_changes_btn", boost::bind(&LLPanelClassifiedEdit::onSaveClick, this));
+ childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelClassifiedEdit::onSetLocationClick, this));
+
+ return TRUE;
+}
+
+void LLPanelClassifiedEdit::onOpen(const LLSD& key)
+{
+ LLUUID classified_id = key["classified_id"];
+
+ mIsNew = classified_id.isNull();
+
+ if(mIsNew)
+ {
+ setAvatarId(gAgent.getID());
+
+ resetData();
+ resetControls();
+
+ setPosGlobal(gAgent.getPositionGlobal());
+
+ LLUUID snapshot_id = LLUUID::null;
+ std::string desc;
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+
+ if(parcel)
+ {
+ desc = parcel->getDesc();
+ snapshot_id = parcel->getSnapshotID();
+ }
+
+ std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ childSetValue("classified_name", makeClassifiedName());
+ childSetValue("classified_desc", desc);
+ setSnapshotId(snapshot_id);
+
+ setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
+
+ // server will set valid parcel id
+ setParcelId(LLUUID::null);
+
+ enableVerbs(true);
+ enableEditing(true);
+ }
+ else
+ {
+ LLPanelClassifiedInfo::onOpen(key);
+ enableVerbs(false);
+ enableEditing(false);
+ }
+
+ resetDirty();
+ setInfoLoaded(false);
+}
+
+void LLPanelClassifiedEdit::processProperties(void* data, EAvatarProcessorType type)
+{
+ if(APT_CLASSIFIED_INFO == type)
+ {
+ LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
+ if(c_info && getClassifiedId() == c_info->classified_id)
+ {
+ enableEditing(true);
+
+ setClassifiedName(c_info->name);
+ setDescription(c_info->description);
+ setSnapshotId(c_info->snapshot_id);
+ setPosGlobal(c_info->pos_global);
+
+ setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global));
+ getChild<LLComboBox>("category")->setCurrentByIndex(c_info->category + 1);
+ getChild<LLComboBox>("category")->resetDirty();
+
+ bool mature = is_cf_mature(c_info->flags);
+ bool auto_renew = is_cf_auto_renew(c_info->flags);
+
+ getChild<LLComboBox>("content_type")->setCurrentByIndex(mature ? CB_ITEM_MATURE : CB_ITEM_PG);
+ childSetValue("auto_renew", auto_renew);
+ childSetValue("price_for_listing", c_info->price_for_listing);
+
+ resetDirty();
+ setInfoLoaded(true);
+ }
+ }
+}
+
+BOOL LLPanelClassifiedEdit::isDirty() const
+{
+ if(mIsNew)
+ {
+ return TRUE;
+ }
+
+ BOOL dirty = false;
+
+ dirty |= LLPanelClassifiedInfo::isDirty();
+ dirty |= getChild<LLUICtrl>("classified_snapshot")->isDirty();
+ dirty |= getChild<LLUICtrl>("classified_name")->isDirty();
+ dirty |= getChild<LLUICtrl>("classified_desc")->isDirty();
+ dirty |= getChild<LLUICtrl>("category")->isDirty();
+ dirty |= getChild<LLUICtrl>("content_type")->isDirty();
+ dirty |= getChild<LLUICtrl>("auto_renew")->isDirty();
+ dirty |= getChild<LLUICtrl>("price_for_listing")->isDirty();
+
+ return dirty;
+}
+
+void LLPanelClassifiedEdit::resetDirty()
+{
+ LLPanelClassifiedInfo::resetDirty();
+ getChild<LLUICtrl>("classified_snapshot")->resetDirty();
+ getChild<LLUICtrl>("classified_name")->resetDirty();
+ getChild<LLUICtrl>("classified_desc")->resetDirty();
+ getChild<LLUICtrl>("category")->resetDirty();
+ getChild<LLUICtrl>("content_type")->resetDirty();
+ getChild<LLUICtrl>("auto_renew")->resetDirty();
+ getChild<LLUICtrl>("price_for_listing")->resetDirty();
+}
+
+void LLPanelClassifiedEdit::setSaveCallback(const commit_callback_t& cb)
+{
+ getChild<LLButton>("save_changes_btn")->setClickedCallback(cb);
+}
+
+void LLPanelClassifiedEdit::setCancelCallback(const commit_callback_t& cb)
+{
+ getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
+}
+
+void LLPanelClassifiedEdit::resetControls()
+{
+ LLPanelClassifiedInfo::resetControls();
+
+ getChild<LLComboBox>("category")->setCurrentByIndex(0);
+ getChild<LLComboBox>("content_type")->setCurrentByIndex(0);
+ childSetValue("auto_renew", false);
+ childSetValue("price_for_listing", MINIMUM_PRICE_FOR_LISTING);
+}
+
+void LLPanelClassifiedEdit::sendUpdate()
+{
+ LLAvatarClassifiedInfo c_data;
+
+ if(getClassifiedId().isNull())
+ {
+ LLUUID id;
+ id.generate();
+ setClassifiedId(id);
+ }
+
+ c_data.agent_id = gAgent.getID();
+ c_data.classified_id = getClassifiedId();
+ c_data.category = getCategory();
+ c_data.name = getClassifiedName();
+ c_data.description = getDescription();
+ c_data.parcel_id = getParcelId();
+ c_data.snapshot_id = getSnapshotId();
+ c_data.pos_global = getPosGlobal();
+ c_data.flags = getFlags();
+ c_data.price_for_listing = getPriceForListing();
+
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoUpdate(&c_data);
+}
+
+U32 LLPanelClassifiedEdit::getCategory()
+{
+ LLComboBox* cat_cb = getChild<LLComboBox>("category");
+ return cat_cb->getCurrentIndex() + 1;
+}
+
+U8 LLPanelClassifiedEdit::getFlags()
+{
+ bool auto_renew = childGetValue("auto_renew").asBoolean();
+
+ LLComboBox* content_cb = getChild<LLComboBox>("content_type");
+ bool mature = content_cb->getCurrentIndex() == CB_ITEM_MATURE;
+
+ return pack_classified_flags_request(auto_renew, false, mature, false);
+}
+
+void LLPanelClassifiedEdit::enableVerbs(bool enable)
+{
+ childSetEnabled("save_changes_btn", enable);
+}
+
+void LLPanelClassifiedEdit::enableEditing(bool enable)
+{
+ childSetEnabled("classified_snapshot", enable);
+ childSetEnabled("classified_name", enable);
+ childSetEnabled("classified_desc", enable);
+ childSetEnabled("set_to_curr_location_btn", enable);
+ childSetEnabled("category", enable);
+ childSetEnabled("content_type", enable);
+ childSetEnabled("price_for_listing", enable);
+ childSetEnabled("auto_renew", enable);
+}
+
+std::string LLPanelClassifiedEdit::makeClassifiedName()
+{
+ std::string name;
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if(parcel)
+ {
+ name = parcel->getName();
+ }
+
+ if(!name.empty())
+ {
+ return name;
+ }
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if(region)
+ {
+ name = region->getName();
+ }
+
+ return name;
+}
+
+S32 LLPanelClassifiedEdit::getPriceForListing()
+{
+ return childGetValue("price_for_listing").asInteger();
+}
+
+void LLPanelClassifiedEdit::onSetLocationClick()
+{
+ setPosGlobal(gAgent.getPositionGlobal());
+ setParcelId(LLUUID::null);
+
+ std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
+
+ // mark classified as dirty
+ setValue(LLSD());
+
+ onChange();
+}
+
+void LLPanelClassifiedEdit::onChange()
+{
+ enableVerbs(isDirty());
+}
+
+void LLPanelClassifiedEdit::onSaveClick()
+{
+ sendUpdate();
+ resetDirty();
+}
+
+std::string LLPanelClassifiedEdit::getLocationNotice()
+{
+ static std::string location_notice = getString("location_notice");
+ return location_notice;
+}
+
+void LLPanelClassifiedEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl)
+{
+ ctrl->setVisible(TRUE);
+}
+
+void LLPanelClassifiedEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
+{
+ ctrl->setVisible(FALSE);
+}
+
+//EOF
diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h
index 417eddf460..8b32495854 100644
--- a/indra/newview/llpanelclassified.h
+++ b/indra/newview/llpanelclassified.h
@@ -37,6 +37,7 @@
#ifndef LL_LLPANELCLASSIFIED_H
#define LL_LLPANELCLASSIFIED_H
+#include "llavatarpropertiesprocessor.h"
#include "llpanel.h"
#include "llclassifiedinfo.h"
#include "v3dmath.h"
@@ -55,6 +56,8 @@ class LLTextureCtrl;
class LLUICtrl;
class LLMessageSystem;
+// *TODO deprecated, should be removed.
+// New class implemented in ticket EXT-2095
class LLPanelClassified : public LLPanel
{
public:
@@ -198,5 +201,139 @@ private:
void* mUserData;
};
+class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver
+{
+public:
+
+ static LLPanelClassifiedInfo* create();
+
+ virtual ~LLPanelClassifiedInfo();
+
+ /*virtual*/ void onOpen(const LLSD& key);
+
+ /*virtual*/ BOOL postBuild();
+
+ /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
+
+ void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; }
+
+ LLUUID& getAvatarId() { return mAvatarId; }
+
+ void setSnapshotId(const LLUUID& id);
+
+ LLUUID getSnapshotId();
+
+ void setClassifiedId(const LLUUID& id) { mClassifiedId = id; }
+
+ LLUUID& getClassifiedId() { return mClassifiedId; }
+
+ void setClassifiedName(const std::string& name);
+
+ std::string getClassifiedName();
+
+ void setDescription(const std::string& desc);
+
+ std::string getDescription();
+
+ void setClassifiedLocation(const std::string& location);
+
+ void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
+
+ LLVector3d& getPosGlobal() { return mPosGlobal; }
+
+ void setParcelId(const LLUUID& id) { mParcelId = id; }
+
+ LLUUID getParcelId() { return mParcelId; }
+
+ bool getInfoLoaded() { return mInfoLoaded; }
+
+ void setInfoLoaded(bool loaded) { mInfoLoaded = loaded; }
+
+ void setExitCallback(const commit_callback_t& cb);
+
+ void setEditClassifiedCallback(const commit_callback_t& cb);
+
+protected:
+
+ LLPanelClassifiedInfo();
+
+ virtual void resetData();
+
+ virtual void resetControls();
+
+ static std::string createLocationText(
+ const std::string& original_name,
+ const std::string& sim_name,
+ const LLVector3d& pos_global);
+
+ void onMapClick();
+ void onTeleportClick();
+ void onExit();
+
+private:
+
+ LLUUID mAvatarId;
+ LLUUID mClassifiedId;
+ LLVector3d mPosGlobal;
+ LLUUID mParcelId;
+ bool mInfoLoaded;
+};
+
+class LLPanelClassifiedEdit : public LLPanelClassifiedInfo
+{
+public:
+
+ static LLPanelClassifiedEdit* create();
+
+ virtual ~LLPanelClassifiedEdit();
+
+ /*virtual*/ BOOL postBuild();
+
+ /*virtual*/ void onOpen(const LLSD& key);
+
+ /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
+
+ /*virtual*/ BOOL isDirty() const;
+
+ /*virtual*/ void resetDirty();
+
+ void setSaveCallback(const commit_callback_t& cb);
+
+ void setCancelCallback(const commit_callback_t& cb);
+
+ /*virtual*/ void resetControls();
+
+ bool isNew() { return mIsNew; }
+
+protected:
+
+ LLPanelClassifiedEdit();
+
+ void sendUpdate();
+
+ U32 getCategory();
+
+ void enableVerbs(bool enable);
+
+ void enableEditing(bool enable);
+
+ std::string makeClassifiedName();
+
+ S32 getPriceForListing();
+
+ U8 getFlags();
+
+ std::string getLocationNotice();
+
+ void onSetLocationClick();
+ void onChange();
+ void onSaveClick();
+
+ void onTexturePickerMouseEnter(LLUICtrl* ctrl);
+ void onTexturePickerMouseLeave(LLUICtrl* ctrl);
+
+private:
+ bool mIsNew;
+};
#endif // LL_LLPANELCLASSIFIED_H
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 88aad4923d..7b5b232ad2 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -2383,12 +2383,8 @@ BOOL LLPanelGroupActionsSubTab::postBuildSubTab(LLView* root)
void LLPanelGroupActionsSubTab::activate()
{
LLPanelGroupSubTab::activate();
- lldebugs << "LLPanelGroupActionsSubTab::activate()" << llendl;
- mActionList->deselectAllItems();
- mActionMembers->deleteAllItems();
- mActionRoles->deleteAllItems();
- mActionDescription->clear();
+ update(GC_ALL);
}
void LLPanelGroupActionsSubTab::deactivate()
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index c9168670d5..9cd949c9cc 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -86,14 +86,20 @@ void LLPanelChatControlPanel::draw()
bool session_initialized = session->mSessionInitialized;
bool callback_enabled = session->mCallBackEnabled;
- LLViewerRegion* region = gAgent.getRegion();
- BOOL enable_connect = (region && region->getCapability("ChatSessionRequest") != "")
- && session_initialized
+ BOOL enable_connect = session_initialized
&& voice_enabled
&& callback_enabled;
childSetEnabled("call_btn", enable_connect);
+ // send a signal when the floater is fully initialized
+ // this lets LLAvatarActions::startAdhocCall() start the call
+ if (enable_connect && !mInitialized)
+ {
+ LLIMModel::sendSessionInitialized(mSessionId);
+ mInitialized = true;
+ }
+
LLPanel::draw();
}
@@ -168,14 +174,26 @@ void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id)
getChild<LLAvatarIconCtrl>("avatar_icon")->setValue(mAvatarID);
- // Fetch the currect name
- gCacheName->get(mAvatarID, FALSE, boost::bind(&LLPanelIMControlPanel::nameUpdatedCallback, this, _1, _2, _3, _4));
-
- // Disable profile button if participant is not realy SL avatar
+ // Disable most profile buttons if the participant is
+ // not really an SL avatar (e.g., an Avaline caller).
LLIMModel::LLIMSession* im_session =
im_model.findIMSession(session_id);
if( im_session && !im_session->mOtherParticipantIsAvatar )
+ {
childSetEnabled("view_profile_btn", FALSE);
+ childSetEnabled("add_friend_btn", FALSE);
+
+ childSetEnabled("share_btn", FALSE);
+ childSetEnabled("teleport_btn", FALSE);
+ childSetEnabled("pay_btn", FALSE);
+
+ getChild<LLTextBox>("avatar_name")->setValue(im_session->mName);
+ }
+ else
+ {
+ // If the participant is an avatar, fetch the currect name
+ gCacheName->get(mAvatarID, FALSE, boost::bind(&LLPanelIMControlPanel::nameUpdatedCallback, this, _1, _2, _3, _4));
+ }
}
void LLPanelIMControlPanel::nameUpdatedCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group)
@@ -190,7 +208,8 @@ void LLPanelIMControlPanel::nameUpdatedCallback(const LLUUID& id, const std::str
}
}
-LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id)
+LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id):
+mParticipantList(NULL)
{
mSpeakerManager = LLIMModel::getInstance()->getSpeakerManager(session_id);
}
@@ -199,9 +218,6 @@ BOOL LLPanelGroupControlPanel::postBuild()
{
childSetAction("group_info_btn", boost::bind(&LLPanelGroupControlPanel::onGroupInfoButtonClicked, this));
- mAvatarList = getChild<LLAvatarList>("speakers_list");
- mParticipantList = new LLParticipantList(mSpeakerManager, mAvatarList);
-
return LLPanelChatControlPanel::postBuild();
}
@@ -214,6 +230,8 @@ LLPanelGroupControlPanel::~LLPanelGroupControlPanel()
// virtual
void LLPanelGroupControlPanel::draw()
{
+ //Remove event does not raised until speakerp->mActivityTimer.hasExpired() is false, see LLSpeakerManager::update()
+ //so we need update it to raise needed event
mSpeakerManager->update(true);
LLPanelChatControlPanel::draw();
}
@@ -241,7 +259,7 @@ void LLPanelGroupControlPanel::onSortMenuItemClicked(const LLSD& userdata)
void LLPanelGroupControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
{
LLPanelChatControlPanel::onVoiceChannelStateChanged(old_state, new_state);
- mAvatarList->setSpeakingIndicatorsVisible(new_state >= LLVoiceChannel::STATE_CALL_STARTED);
+ mParticipantList->setSpeakingIndicatorsVisible(new_state >= LLVoiceChannel::STATE_CALL_STARTED);
}
void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id)
@@ -249,6 +267,9 @@ void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id)
LLPanelChatControlPanel::setSessionId(session_id);
mGroupID = LLIMModel::getInstance()->getOtherParticipantID(session_id);
+
+ if(!mParticipantList)
+ mParticipantList = new LLParticipantList(mSpeakerManager, getChild<LLAvatarList>("speakers_list"));
}
@@ -258,9 +279,7 @@ LLPanelAdHocControlPanel::LLPanelAdHocControlPanel(const LLUUID& session_id):LLP
BOOL LLPanelAdHocControlPanel::postBuild()
{
- mAvatarList = getChild<LLAvatarList>("speakers_list");
- mParticipantList = new LLParticipantList(mSpeakerManager, mAvatarList);
-
+ //We don't need LLPanelGroupControlPanel::postBuild() to be executed as there is no group_info_btn at AdHoc chat
return LLPanelChatControlPanel::postBuild();
}
diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h
index ac5d86345e..923c5acbd2 100644
--- a/indra/newview/llpanelimcontrolpanel.h
+++ b/indra/newview/llpanelimcontrolpanel.h
@@ -43,7 +43,9 @@ class LLParticipantList;
class LLPanelChatControlPanel : public LLPanel
{
public:
- LLPanelChatControlPanel() {};
+ LLPanelChatControlPanel() :
+ mSessionId(LLUUID()),
+ mInitialized(false) {};
~LLPanelChatControlPanel() {};
virtual BOOL postBuild();
@@ -59,6 +61,7 @@ public:
private:
LLUUID mSessionId;
+ bool mInitialized;
};
@@ -100,7 +103,7 @@ public:
protected:
LLUUID mGroupID;
LLSpeakerMgr* mSpeakerManager;
- LLAvatarList* mAvatarList;
+
LLParticipantList* mParticipantList;
private:
diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp
index 4985663833..f94a59ecef 100644
--- a/indra/newview/llpanellandmarkinfo.cpp
+++ b/indra/newview/llpanellandmarkinfo.cpp
@@ -35,6 +35,7 @@
#include "llpanellandmarkinfo.h"
#include "llcombobox.h"
+#include "lliconctrl.h"
#include "lllineeditor.h"
#include "lltextbox.h"
#include "lltexteditor.h"
@@ -58,6 +59,11 @@ static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
static LLRegisterPanelClassWrapper<LLPanelLandmarkInfo> t_landmark_info("panel_landmark_info");
+// Statics for textures filenames
+static std::string icon_pg;
+static std::string icon_m;
+static std::string icon_r;
+
LLPanelLandmarkInfo::LLPanelLandmarkInfo()
: LLPanelPlaceInfo()
{}
@@ -79,6 +85,10 @@ BOOL LLPanelLandmarkInfo::postBuild()
mNotesEditor = getChild<LLTextEditor>("notes_editor");
mFolderCombo = getChild<LLComboBox>("folder_combo");
+ icon_pg = getString("icon_PG");
+ icon_m = getString("icon_M");
+ icon_r = getString("icon_R");
+
return TRUE;
}
@@ -101,9 +111,8 @@ void LLPanelLandmarkInfo::setInfoType(INFO_TYPE type)
LLPanel* landmark_info_panel = getChild<LLPanel>("landmark_info_panel");
bool is_info_type_create_landmark = type == CREATE_LANDMARK;
- bool is_info_type_landmark = type == LANDMARK;
- landmark_info_panel->setVisible(is_info_type_landmark);
+ landmark_info_panel->setVisible(type == LANDMARK);
getChild<LLTextBox>("folder_label")->setVisible(is_info_type_create_landmark);
mFolderCombo->setVisible(is_info_type_create_landmark);
@@ -136,6 +145,24 @@ void LLPanelLandmarkInfo::processParcelInfo(const LLParcelData& parcel_data)
{
LLPanelPlaceInfo::processParcelInfo(parcel_data);
+ // HACK: Flag 0x2 == adult region,
+ // Flag 0x1 == mature region, otherwise assume PG
+ if (parcel_data.flags & 0x2)
+ {
+ mMaturityRatingIcon->setValue(icon_r);
+ mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_ADULT));
+ }
+ else if (parcel_data.flags & 0x1)
+ {
+ mMaturityRatingIcon->setValue(icon_m);
+ mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_MATURE));
+ }
+ else
+ {
+ mMaturityRatingIcon->setValue(icon_pg);
+ mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_PG));
+ }
+
S32 region_x;
S32 region_y;
S32 region_z;
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 15a75cb930..e3b2ab77aa 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -204,11 +204,6 @@ void LLPanelMainInventory::initListCommandsHandlers()
mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelMainInventory::onGearButtonClick, this));
mListCommands->childSetAction("trash_btn", boost::bind(&LLPanelMainInventory::onTrashButtonClick, this));
mListCommands->childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this));
- /*
- mListCommands->getChild<LLButton>("add_btn")->setHeldDownCallback(boost::bind(&LLPanelMainInventory::onAddButtonHeldDown, this));
- static const LLSD add_landmark_command("add_landmark");
- mListCommands->childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddAction, this, add_landmark_command));
- */
LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>("trash_btn");
trash_btn->setDragAndDropHandler(boost::bind(&LLPanelMainInventory::handleDragAndDropToTrash, this
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index a6083a5755..2bbb2b7153 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -60,6 +60,7 @@
#include "llviewermenu.h" // for gMenuHolder
#include "llvoiceclient.h"
#include "llworld.h"
+#include "llspeakers.h"
#define FRIEND_LIST_UPDATE_TIMEOUT 0.5
#define NEARBY_LIST_UPDATE_INTERVAL 1
@@ -119,8 +120,84 @@ protected:
}
};
+/** Compares avatar items by distance between you and them */
+class LLAvatarItemDistanceComparator : public LLAvatarItemComparator
+{
+public:
+ typedef std::map < LLUUID, LLVector3d > id_to_pos_map_t;
+ LLAvatarItemDistanceComparator() {};
+
+ void updateAvatarsPositions(std::vector<LLVector3d>& positions, std::vector<LLUUID>& uuids)
+ {
+ std::vector<LLVector3d>::const_iterator
+ pos_it = positions.begin(),
+ pos_end = positions.end();
+
+ std::vector<LLUUID>::const_iterator
+ id_it = uuids.begin(),
+ id_end = uuids.end();
+
+ LLAvatarItemDistanceComparator::id_to_pos_map_t pos_map;
+
+ mAvatarsPositions.clear();
+
+ for (;pos_it != pos_end && id_it != id_end; ++pos_it, ++id_it )
+ {
+ mAvatarsPositions[*id_it] = *pos_it;
+ }
+ };
+
+protected:
+ virtual bool doCompare(const LLAvatarListItem* item1, const LLAvatarListItem* item2) const
+ {
+ const LLVector3d& me_pos = gAgent.getPositionGlobal();
+ const LLVector3d& item1_pos = mAvatarsPositions.find(item1->getAvatarId())->second;
+ const LLVector3d& item2_pos = mAvatarsPositions.find(item2->getAvatarId())->second;
+ F32 dist1 = dist_vec(item1_pos, me_pos);
+ F32 dist2 = dist_vec(item2_pos, me_pos);
+ return dist1 < dist2;
+ }
+private:
+ id_to_pos_map_t mAvatarsPositions;
+};
+
+/** Comparator for comparing nearby avatar items by last spoken time */
+class LLAvatarItemRecentSpeakerComparator : public LLAvatarItemNameComparator
+{
+public:
+ LLAvatarItemRecentSpeakerComparator() {};
+ virtual ~LLAvatarItemRecentSpeakerComparator() {};
+
+protected:
+ virtual bool doCompare(const LLAvatarListItem* item1, const LLAvatarListItem* item2) const
+ {
+ LLPointer<LLSpeaker> lhs = LLLocalSpeakerMgr::instance().findSpeaker(item1->getAvatarId());
+ LLPointer<LLSpeaker> rhs = LLLocalSpeakerMgr::instance().findSpeaker(item2->getAvatarId());
+ if ( lhs.notNull() && rhs.notNull() )
+ {
+ // Compare by last speaking time
+ if( lhs->mLastSpokeTime != rhs->mLastSpokeTime )
+ return ( lhs->mLastSpokeTime > rhs->mLastSpokeTime );
+ }
+ else if ( lhs.notNull() )
+ {
+ // True if only item1 speaker info available
+ return true;
+ }
+ else if ( rhs.notNull() )
+ {
+ // False if only item2 speaker info available
+ return false;
+ }
+ // By default compare by name.
+ return LLAvatarItemNameComparator::doCompare(item1, item2);
+ }
+};
+
static const LLAvatarItemRecentComparator RECENT_COMPARATOR;
static const LLAvatarItemStatusComparator STATUS_COMPARATOR;
+static LLAvatarItemDistanceComparator DISTANCE_COMPARATOR;
+static const LLAvatarItemRecentSpeakerComparator RECENT_SPEAKER_COMPARATOR;
static LLRegisterPanelClassWrapper<LLPanelPeople> t_people("panel_people");
@@ -432,9 +509,12 @@ BOOL LLPanelPeople::postBuild()
mNearbyList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
mRecentList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
+ mAllFriendList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
+ mOnlineFriendList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
setSortOrder(mRecentList, (ESortOrder)gSavedSettings.getU32("RecentPeopleSortOrder"), false);
setSortOrder(mAllFriendList, (ESortOrder)gSavedSettings.getU32("FriendsSortOrder"), false);
+ setSortOrder(mNearbyList, (ESortOrder)gSavedSettings.getU32("NearbyPeopleSortOrder"), false);
LLPanel* groups_panel = getChild<LLPanel>(GROUP_TAB_NAME);
groups_panel->childSetAction("activate_btn", boost::bind(&LLPanelPeople::onActivateButtonClicked, this));
@@ -495,7 +575,8 @@ BOOL LLPanelPeople::postBuild()
enable_registrar.add("People.Friends.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemCheck, this, _2));
enable_registrar.add("People.Recent.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemCheck, this, _2));
-
+ enable_registrar.add("People.Nearby.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemCheck, this, _2));
+
LLMenuGL* plus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mGroupPlusMenuHandle = plus_menu->getHandle();
@@ -574,8 +655,13 @@ void LLPanelPeople::updateNearbyList()
if (!mNearbyList)
return;
- LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
+ std::vector<LLVector3d> positions;
+
+ LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
mNearbyList->setDirty();
+
+ DISTANCE_COMPARATOR.updateAvatarsPositions(positions, mNearbyList->getIDs());
+ LLLocalSpeakerMgr::instance().update(TRUE);
}
void LLPanelPeople::updateRecentList()
@@ -608,6 +694,12 @@ void LLPanelPeople::buttonSetAction(const std::string& btn_name, const commit_si
button->setClickedCallback(cb);
}
+bool LLPanelPeople::isFriendOnline(const LLUUID& id)
+{
+ LLAvatarList::uuid_vector_t ids = mOnlineFriendList->getIDs();
+ return std::find(ids.begin(), ids.end(), id) != ids.end();
+}
+
void LLPanelPeople::updateButtons()
{
std::string cur_tab = getActiveTabName();
@@ -660,10 +752,10 @@ void LLPanelPeople::updateButtons()
childSetEnabled("add_friend_btn", !is_friend);
}
- buttonSetEnabled("teleport_btn", friends_tab_active && item_selected);
+ buttonSetEnabled("teleport_btn", friends_tab_active && item_selected && isFriendOnline(selected_uuids.front()));
buttonSetEnabled("view_profile_btn", item_selected);
buttonSetEnabled("im_btn", multiple_selected); // allow starting the friends conference for multiple selection
- buttonSetEnabled("call_btn", item_selected);
+ buttonSetEnabled("call_btn", multiple_selected);
buttonSetEnabled("share_btn", item_selected && false); // not implemented yet
bool none_group_selected = item_selected && selected_id.isNull();
@@ -758,6 +850,14 @@ void LLPanelPeople::setSortOrder(LLAvatarList* list, ESortOrder order, bool save
list->setComparator(&RECENT_COMPARATOR);
list->sort();
break;
+ case E_SORT_BY_RECENT_SPEAKERS:
+ list->setComparator(&RECENT_SPEAKER_COMPARATOR);
+ list->sort();
+ break;
+ case E_SORT_BY_DISTANCE:
+ list->setComparator(&DISTANCE_COMPARATOR);
+ list->sort();
+ break;
default:
llwarns << "Unrecognized people sort order for " << list->getName() << llendl;
return;
@@ -772,7 +872,7 @@ void LLPanelPeople::setSortOrder(LLAvatarList* list, ESortOrder order, bool save
else if (list == mRecentList)
setting = "RecentPeopleSortOrder";
else if (list == mNearbyList)
- setting = "NearbyPeopleSortOrder"; // *TODO: unused by current implementation
+ setting = "NearbyPeopleSortOrder";
if (!setting.empty())
gSavedSettings.setU32(setting, order);
@@ -1008,12 +1108,13 @@ void LLPanelPeople::onNearbyViewSortMenuItemClicked(const LLSD& userdata)
{
std::string chosen_item = userdata.asString();
- if (chosen_item == "sort_recent")
+ if (chosen_item == "sort_by_recent_speakers")
{
+ setSortOrder(mNearbyList, E_SORT_BY_RECENT_SPEAKERS);
}
else if (chosen_item == "sort_name")
{
- mNearbyList->sortByName();
+ setSortOrder(mNearbyList, E_SORT_BY_NAME);
}
else if (chosen_item == "view_icons")
{
@@ -1021,8 +1122,25 @@ void LLPanelPeople::onNearbyViewSortMenuItemClicked(const LLSD& userdata)
}
else if (chosen_item == "sort_distance")
{
+ setSortOrder(mNearbyList, E_SORT_BY_DISTANCE);
}
}
+
+bool LLPanelPeople::onNearbyViewSortMenuItemCheck(const LLSD& userdata)
+{
+ std::string item = userdata.asString();
+ U32 sort_order = gSavedSettings.getU32("NearbyPeopleSortOrder");
+
+ if (item == "sort_by_recent_speakers")
+ return sort_order == E_SORT_BY_RECENT_SPEAKERS;
+ if (item == "sort_name")
+ return sort_order == E_SORT_BY_NAME;
+ if (item == "sort_distance")
+ return sort_order == E_SORT_BY_DISTANCE;
+
+ return false;
+}
+
void LLPanelPeople::onRecentViewSortMenuItemClicked(const LLSD& userdata)
{
std::string chosen_item = userdata.asString();
@@ -1079,7 +1197,8 @@ void LLPanelPeople::onCallButtonClicked()
}
else if (selected_uuids.size() > 1)
{
- // *NOTE: ad-hoc voice chat not implemented yet
+ // initiate an ad-hoc voice chat with multiple users
+ LLAvatarActions::startAdhocCall(selected_uuids);
}
}
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 9bf9befe90..a369bcd3e2 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -62,6 +62,8 @@ private:
E_SORT_BY_NAME = 0,
E_SORT_BY_STATUS = 1,
E_SORT_BY_MOST_RECENT = 2,
+ E_SORT_BY_DISTANCE = 3,
+ E_SORT_BY_RECENT_SPEAKERS = 4,
} ESortOrder;
// methods indirectly called by the updaters
@@ -69,6 +71,8 @@ private:
void updateNearbyList();
void updateRecentList();
+ bool isFriendOnline(const LLUUID& id);
+
void updateButtons();
std::string getActiveTabName() const;
LLUUID getCurrentItemID() const;
@@ -115,6 +119,7 @@ private:
bool onFriendsViewSortMenuItemCheck(const LLSD& userdata);
bool onRecentViewSortMenuItemCheck(const LLSD& userdata);
+ bool onNearbyViewSortMenuItemCheck(const LLSD& userdata);
// misc callbacks
static void onAvatarPicked(
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index f5c4f89702..da0c8d5020 100644
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
@@ -440,7 +440,8 @@ void LLPanelPickEdit::resetDirty()
BOOL LLPanelPickEdit::isDirty() const
{
- if( LLPanelPickInfo::isDirty()
+ if( mNewPick
+ || LLPanelPickInfo::isDirty()
|| mLocationChanged
|| mSnapshotCtrl->isDirty()
|| getChild<LLLineEditor>("pick_name")->isDirty()
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index 2bf04f9681..6905c7e546 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -45,11 +45,14 @@
#include "llviewermenu.h"
#include "llregistry.h"
+#include "llaccordionctrl.h"
+#include "llaccordionctrltab.h"
#include "llpanelpicks.h"
#include "llavatarpropertiesprocessor.h"
#include "llpanelavatar.h"
#include "llpanelprofile.h"
#include "llpanelpick.h"
+#include "llpanelclassified.h"
static const std::string XML_BTN_NEW = "new_btn";
static const std::string XML_BTN_DELETE = "trash_btn";
@@ -62,9 +65,40 @@ static const std::string PICK_ID("pick_id");
static const std::string PICK_CREATOR_ID("pick_creator_id");
static const std::string PICK_NAME("pick_name");
+static const std::string CLASSIFIED_ID("classified_id");
+static const std::string CLASSIFIED_NAME("classified_name");
+
static LLRegisterPanelClassWrapper<LLPanelPicks> t_panel_picks("panel_picks");
+//////////////////////////////////////////////////////////////////////////
+
+/**
+ * Copy&Pasted from old LLPanelClassified. This class does nothing at the moment.
+ * Subscribing to "classifiedclickthrough" removes a few warnings.
+ */
+class LLClassifiedClickThrough : public LLDispatchHandler
+{
+public:
+
+ // "classifiedclickthrough"
+ // strings[0] = classified_id
+ // strings[1] = teleport_clicks
+ // strings[2] = map_clicks
+ // strings[3] = profile_clicks
+ virtual bool operator()(
+ const LLDispatcher* dispatcher,
+ const std::string& key,
+ const LLUUID& invoice,
+ const sparam_t& strings)
+ {
+ if (strings.size() != 4)
+ return false;
+
+ return true;
+ }
+};
+
//-----------------------------------------------------------------------------
// LLPanelPicks
//-----------------------------------------------------------------------------
@@ -74,10 +108,19 @@ LLPanelPicks::LLPanelPicks()
mProfilePanel(NULL),
mPickPanel(NULL),
mPicksList(NULL),
+ mClassifiedsList(NULL),
mPanelPickInfo(NULL),
mPanelPickEdit(NULL),
- mOverflowMenu(NULL)
+ mOverflowMenu(NULL),
+ mPlusMenu(NULL),
+ mPicksAccTab(NULL),
+ mClassifiedsAccTab(NULL),
+ mPanelClassifiedInfo(NULL),
+ mPanelClassifiedEdit(NULL),
+ mClickThroughDisp(NULL)
{
+ mClickThroughDisp = new LLClassifiedClickThrough();
+ gGenericDispatcher.addHandler("classifiedclickthrough", mClickThroughDisp);
}
LLPanelPicks::~LLPanelPicks()
@@ -86,6 +129,8 @@ LLPanelPicks::~LLPanelPicks()
{
LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
}
+
+ delete mClickThroughDisp;
}
void* LLPanelPicks::create(void* data /* = NULL */)
@@ -100,6 +145,9 @@ void LLPanelPicks::updateData()
{
mPicksList->clear();
LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(getAvatarId());
+
+ mClassifiedsList->clear();
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(getAvatarId());
}
}
@@ -138,13 +186,47 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
mPicksList->addItem(picture, pick_value);
- picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickItem, this, _1));
+ picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickPickItem, this, _1));
picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
}
+ showAccordion("tab_picks", mPicksList->size());
+
+ resetDirty();
+ updateButtons();
+ }
+ }
+ else if(APT_CLASSIFIEDS == type)
+ {
+ LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data);
+ if(c_info && getAvatarId() == c_info->target_id)
+ {
+ mClassifiedsList->clear();
+
+ LLAvatarClassifieds::classifieds_list_t::const_iterator it = c_info->classifieds_list.begin();
+ for(; c_info->classifieds_list.end() != it; ++it)
+ {
+ LLAvatarClassifieds::classified_data c_data = *it;
+
+ LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), c_data.classified_id);
+ c_item->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
+ c_item->setClassifiedName(c_data.name);
+
+ LLSD pick_value = LLSD();
+ pick_value.insert(CLASSIFIED_ID, c_data.classified_id);
+ pick_value.insert(CLASSIFIED_NAME, c_data.name);
+
+ mClassifiedsList->addItem(c_item, pick_value);
+
+ c_item->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickClassifiedItem, this, _1));
+ c_item->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
+ c_item->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
+ }
+
+ showAccordion("tab_classifieds", mClassifiedsList->size());
+
resetDirty();
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
updateButtons();
}
}
@@ -158,16 +240,44 @@ LLPickItem* LLPanelPicks::getSelectedPickItem()
return dynamic_cast<LLPickItem*>(selected_item);
}
+LLClassifiedItem* LLPanelPicks::getSelectedClassifiedItem()
+{
+ LLPanel* selected_item = mClassifiedsList->getSelectedItem();
+ if (!selected_item)
+ {
+ return NULL;
+ }
+ return dynamic_cast<LLClassifiedItem*>(selected_item);
+}
+
BOOL LLPanelPicks::postBuild()
{
mPicksList = getChild<LLFlatListView>("picks_list");
+ mClassifiedsList = getChild<LLFlatListView>("classifieds_list");
+
+ mPicksList->setCommitOnSelectionChange(true);
+ mClassifiedsList->setCommitOnSelectionChange(true);
+
+ mPicksList->setCommitCallback(boost::bind(&LLPanelPicks::onListCommit, this, mPicksList));
+ mClassifiedsList->setCommitCallback(boost::bind(&LLPanelPicks::onListCommit, this, mClassifiedsList));
+
+ mPicksList->setNoItemsCommentText(getString("no_picks"));
+ mClassifiedsList->setNoItemsCommentText(getString("no_classifieds"));
- childSetAction(XML_BTN_NEW, boost::bind(&LLPanelPicks::onClickNew, this));
+ childSetAction(XML_BTN_NEW, boost::bind(&LLPanelPicks::onClickPlusBtn, this));
childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this));
childSetAction(XML_BTN_TELEPORT, boost::bind(&LLPanelPicks::onClickTeleport, this));
childSetAction(XML_BTN_SHOW_ON_MAP, boost::bind(&LLPanelPicks::onClickMap, this));
childSetAction(XML_BTN_INFO, boost::bind(&LLPanelPicks::onClickInfo, this));
childSetAction(XML_BTN_OVERFLOW, boost::bind(&LLPanelPicks::onOverflowButtonClicked, this));
+
+ mPicksAccTab = getChild<LLAccordionCtrlTab>("tab_picks");
+ mPicksAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelPicks::onAccordionStateChanged, this, mPicksAccTab));
+ mPicksAccTab->setDisplayChildren(true);
+
+ mClassifiedsAccTab = getChild<LLAccordionCtrlTab>("tab_classifieds");
+ mClassifiedsAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelPicks::onAccordionStateChanged, this, mClassifiedsAccTab));
+ mClassifiedsAccTab->setDisplayChildren(false);
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar;
registar.add("Pick.Info", boost::bind(&LLPanelPicks::onClickInfo, this));
@@ -180,6 +290,10 @@ BOOL LLPanelPicks::postBuild()
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar overflow_registar;
overflow_registar.add("PicksList.Overflow", boost::bind(&LLPanelPicks::onOverflowMenuItemClicked, this, _2));
mOverflowMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_picks_overflow.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar plus_registar;
+ plus_registar.add("Picks.Plus.Action", boost::bind(&LLPanelPicks::onPlusMenuItemClicked, this, _2));
+ mPlusMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_picks_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
return TRUE;
}
@@ -202,6 +316,34 @@ void LLPanelPicks::onOverflowMenuItemClicked(const LLSD& param)
}
}
+void LLPanelPicks::onPlusMenuItemClicked(const LLSD& param)
+{
+ std::string value = param.asString();
+
+ if("new_pick" == value)
+ {
+ createNewPick();
+ }
+ else if("new_classified" == value)
+ {
+ createNewClassified();
+ }
+}
+
+void LLPanelPicks::onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab)
+{
+ if(!mPicksAccTab->getDisplayChildren())
+ {
+ mPicksList->resetSelection(true);
+ }
+ if(!mClassifiedsAccTab->getDisplayChildren())
+ {
+ mClassifiedsList->resetSelection(true);
+ }
+
+ updateButtons();
+}
+
void LLPanelPicks::onOverflowButtonClicked()
{
LLRect rect;
@@ -242,6 +384,9 @@ void LLPanelPicks::onOpen(const LLSD& key)
if(getAvatarId() != id)
{
+ showAccordion("tab_picks", false);
+ showAccordion("tab_classifieds", false);
+
mPicksList->goToTop();
// Set dummy value to make panel dirty and make it reload picks
setValue(LLSD());
@@ -250,21 +395,50 @@ void LLPanelPicks::onOpen(const LLSD& key)
LLPanelProfileTab::onOpen(key);
}
+void LLPanelPicks::onListCommit(const LLFlatListView* f_list)
+{
+ // Make sure only one of the lists has selection.
+ if(f_list == mPicksList)
+ {
+ mClassifiedsList->resetSelection(true);
+ }
+ else if(f_list == mClassifiedsList)
+ {
+ mPicksList->resetSelection(true);
+ }
+ else
+ {
+ llwarns << "Unknown list" << llendl;
+ }
+
+ updateButtons();
+}
+
//static
void LLPanelPicks::onClickDelete()
{
- LLSD pick_value = mPicksList->getSelectedValue();
- if (pick_value.isUndefined()) return;
+ LLSD value = mPicksList->getSelectedValue();
+ if (value.isDefined())
+ {
+ LLSD args;
+ args["PICK"] = value[PICK_NAME];
+ LLNotifications::instance().add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackDeletePick, this, _1, _2));
+ return;
+ }
- LLSD args;
- args["PICK"] = pick_value[PICK_NAME];
- LLNotifications::instance().add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackDelete, this, _1, _2));
+ value = mClassifiedsList->getSelectedValue();
+ if(value.isDefined())
+ {
+ LLSD args;
+ args["NAME"] = value[CLASSIFIED_NAME];
+ LLNotifications::instance().add("DeleteClassified", args, LLSD(), boost::bind(&LLPanelPicks::callbackDeleteClassified, this, _1, _2));
+ return;
+ }
}
-bool LLPanelPicks::callbackDelete(const LLSD& notification, const LLSD& response)
+bool LLPanelPicks::callbackDeletePick(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
-
LLSD pick_value = mPicksList->getSelectedValue();
if (0 == option)
@@ -276,6 +450,20 @@ bool LLPanelPicks::callbackDelete(const LLSD& notification, const LLSD& response
return false;
}
+bool LLPanelPicks::callbackDeleteClassified(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ LLSD value = mClassifiedsList->getSelectedValue();
+
+ if (0 == option)
+ {
+ LLAvatarPropertiesProcessor::instance().sendClassifiedDelete(value[CLASSIFIED_ID]);
+ mClassifiedsList->removeItemByValue(value);
+ }
+ updateButtons();
+ return false;
+}
+
bool LLPanelPicks::callbackTeleport( const LLSD& notification, const LLSD& response )
{
S32 option = LLNotification::getSelectedOption(notification, response);
@@ -291,9 +479,14 @@ bool LLPanelPicks::callbackTeleport( const LLSD& notification, const LLSD& respo
void LLPanelPicks::onClickTeleport()
{
LLPickItem* pick_item = getSelectedPickItem();
- if (!pick_item) return;
+ LLClassifiedItem* c_item = getSelectedClassifiedItem();
+
+ LLVector3d pos;
+ if(pick_item)
+ pos = pick_item->getPosGlobal();
+ else if(c_item)
+ pos = c_item->getPosGlobal();
- LLVector3d pos = pick_item->getPosGlobal();
if (!pos.isExactlyZero())
{
gAgent.teleportViaLocation(pos);
@@ -305,9 +498,15 @@ void LLPanelPicks::onClickTeleport()
void LLPanelPicks::onClickMap()
{
LLPickItem* pick_item = getSelectedPickItem();
- if (!pick_item) return;
+ LLClassifiedItem* c_item = getSelectedClassifiedItem();
+
+ LLVector3d pos;
+ if (pick_item)
+ pos = pick_item->getPosGlobal();
+ else if(c_item)
+ pos = c_item->getPosGlobal();
- LLFloaterWorldMap::getInstance()->trackLocation(pick_item->getPosGlobal());
+ LLFloaterWorldMap::getInstance()->trackLocation(pos);
LLFloaterReg::showInstance("world_map", "center");
}
@@ -325,7 +524,7 @@ void LLPanelPicks::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
}
}
-void LLPanelPicks::onDoubleClickItem(LLUICtrl* item)
+void LLPanelPicks::onDoubleClickPickItem(LLUICtrl* item)
{
LLSD pick_value = mPicksList->getSelectedValue();
if (pick_value.isUndefined()) return;
@@ -335,9 +534,19 @@ void LLPanelPicks::onDoubleClickItem(LLUICtrl* item)
LLNotifications::instance().add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));
}
+void LLPanelPicks::onDoubleClickClassifiedItem(LLUICtrl* item)
+{
+ LLSD value = mClassifiedsList->getSelectedValue();
+ if (value.isUndefined()) return;
+
+ LLSD args;
+ args["CLASSIFIED"] = value[CLASSIFIED_NAME];
+ LLNotifications::instance().add("TeleportToClassified", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));
+}
+
void LLPanelPicks::updateButtons()
{
- bool has_selected = mPicksList->numSelected();
+ bool has_selected = mPicksList->numSelected() > 0 || mClassifiedsList->numSelected() > 0;
if (getAvatarId() == gAgentID)
{
@@ -366,15 +575,44 @@ void LLPanelPicks::buildPickPanel()
// }
}
-void LLPanelPicks::onClickNew()
+void LLPanelPicks::onClickPlusBtn()
+{
+ LLRect rect;
+ childGetRect(XML_BTN_NEW, rect);
+
+ mPlusMenu->updateParent(LLMenuGL::sMenuContainer);
+ mPlusMenu->setButtonRect(rect, this);
+ LLMenuGL::showPopup(this, mPlusMenu, rect.mLeft, rect.mTop);
+}
+
+void LLPanelPicks::createNewPick()
{
createPickEditPanel();
getProfilePanel()->openPanel(mPanelPickEdit, LLSD());
}
+void LLPanelPicks::createNewClassified()
+{
+ createClassifiedEditPanel();
+
+ getProfilePanel()->openPanel(mPanelClassifiedEdit, LLSD());
+}
+
void LLPanelPicks::onClickInfo()
{
+ if(mPicksList->numSelected() > 0)
+ {
+ openPickInfo();
+ }
+ else if(mClassifiedsList->numSelected() > 0)
+ {
+ openClassifiedInfo();
+ }
+}
+
+void LLPanelPicks::openPickInfo()
+{
LLSD selected_value = mPicksList->getSelectedValue();
if (selected_value.isUndefined()) return;
@@ -392,6 +630,33 @@ void LLPanelPicks::onClickInfo()
getProfilePanel()->openPanel(mPanelPickInfo, params);
}
+void LLPanelPicks::openClassifiedInfo()
+{
+ LLSD selected_value = mClassifiedsList->getSelectedValue();
+ if (selected_value.isUndefined()) return;
+
+ LLClassifiedItem* c_item = getSelectedClassifiedItem();
+
+ createClassifiedInfoPanel();
+
+ LLSD params;
+ params["classified_id"] = c_item->getClassifiedId();
+ params["avatar_id"] = c_item->getAvatarId();
+ params["snapshot_id"] = c_item->getSnapshotId();
+ params["name"] = c_item->getClassifiedName();
+ params["desc"] = c_item->getDescription();
+
+ getProfilePanel()->openPanel(mPanelClassifiedInfo, params);
+}
+
+void LLPanelPicks::showAccordion(const std::string& name, bool show)
+{
+ LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(name);
+ tab->setVisible(show);
+ LLAccordionCtrl* acc = getChild<LLAccordionCtrl>("accordion");
+ acc->arrange();
+}
+
void LLPanelPicks::onPanelPickClose(LLPanel* panel)
{
panel->setVisible(FALSE);
@@ -403,6 +668,65 @@ void LLPanelPicks::onPanelPickSave(LLPanel* panel)
updateButtons();
}
+void LLPanelPicks::onPanelClassifiedSave(LLPanelClassifiedEdit* panel)
+{
+ if(panel->isNew())
+ {
+ LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), panel->getClassifiedId());
+
+ c_item->setClassifiedName(panel->getClassifiedName());
+ c_item->setDescription(panel->getDescription());
+ c_item->setSnapshotId(panel->getSnapshotId());
+
+ LLSD c_value;
+ c_value.insert(CLASSIFIED_ID, c_item->getClassifiedId());
+ c_value.insert(CLASSIFIED_NAME, c_item->getClassifiedName());
+ mClassifiedsList->addItem(c_item, c_value, ADD_TOP);
+
+ c_item->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickClassifiedItem, this, _1));
+ c_item->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
+ c_item->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
+ c_item->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
+
+ // order does matter, showAccordion will invoke arrange for accordions.
+ mClassifiedsAccTab->changeOpenClose(false);
+ showAccordion("tab_classifieds", true);
+ }
+ else
+ {
+ onPanelClassifiedClose(panel);
+ return;
+ }
+
+ onPanelPickClose(panel);
+ updateButtons();
+}
+
+void LLPanelPicks::onPanelClassifiedClose(LLPanelClassifiedInfo* panel)
+{
+ if(panel->getInfoLoaded() && !panel->isDirty())
+ {
+ std::vector<LLSD> values;
+ mClassifiedsList->getValues(values);
+ for(size_t n = 0; n < values.size(); ++n)
+ {
+ LLUUID c_id = values[n][CLASSIFIED_ID].asUUID();
+ if(panel->getClassifiedId() == c_id)
+ {
+ LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(
+ mClassifiedsList->getItemByValue(values[n]));
+
+ c_item->setClassifiedName(panel->getClassifiedName());
+ c_item->setDescription(panel->getDescription());
+ c_item->setSnapshotId(panel->getSnapshotId());
+ }
+ }
+ }
+
+ onPanelPickClose(panel);
+ updateButtons();
+}
+
void LLPanelPicks::createPickInfoPanel()
{
if(!mPanelPickInfo)
@@ -414,6 +738,29 @@ void LLPanelPicks::createPickInfoPanel()
}
}
+void LLPanelPicks::createClassifiedInfoPanel()
+{
+ if(!mPanelClassifiedInfo)
+ {
+ mPanelClassifiedInfo = LLPanelClassifiedInfo::create();
+ mPanelClassifiedInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, mPanelClassifiedInfo));
+ mPanelClassifiedInfo->setEditClassifiedCallback(boost::bind(&LLPanelPicks::onPanelClassifiedEdit, this));
+ mPanelClassifiedInfo->setVisible(FALSE);
+ }
+}
+
+void LLPanelPicks::createClassifiedEditPanel()
+{
+ if(!mPanelClassifiedEdit)
+ {
+ mPanelClassifiedEdit = LLPanelClassifiedEdit::create();
+ mPanelClassifiedEdit->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, mPanelClassifiedEdit));
+ mPanelClassifiedEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelClassifiedSave, this, mPanelClassifiedEdit));
+ mPanelClassifiedEdit->setCancelCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, mPanelClassifiedEdit));
+ mPanelClassifiedEdit->setVisible(FALSE);
+ }
+}
+
void LLPanelPicks::createPickEditPanel()
{
if(!mPanelPickEdit)
@@ -473,9 +820,38 @@ void LLPanelPicks::onPanelPickEdit()
getProfilePanel()->openPanel(mPanelPickEdit, params);
}
+void LLPanelPicks::onPanelClassifiedEdit()
+{
+ LLSD selected_value = mClassifiedsList->getSelectedValue();
+ if (selected_value.isUndefined())
+ {
+ return;
+ }
+
+ LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
+
+ createClassifiedEditPanel();
+
+ LLSD params;
+ params["classified_id"] = c_item->getClassifiedId();
+ params["avatar_id"] = c_item->getAvatarId();
+ params["snapshot_id"] = c_item->getSnapshotId();
+ params["name"] = c_item->getClassifiedName();
+ params["desc"] = c_item->getDescription();
+
+ getProfilePanel()->openPanel(mPanelClassifiedEdit, params);
+}
+
void LLPanelPicks::onClickMenuEdit()
{
- onPanelPickEdit();
+ if(getSelectedPickItem())
+ {
+ onPanelPickEdit();
+ }
+ else if(getSelectedClassifiedItem())
+ {
+ onPanelClassifiedEdit();
+ }
}
inline LLPanelProfile* LLPanelPicks::getProfilePanel()
@@ -610,3 +986,80 @@ void LLPickItem::setValue(const LLSD& value)
if (!value.has("selected")) return;
childSetVisible("selected_icon", value["selected"]);
}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLClassifiedItem::LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id)
+ : LLPanel()
+ , mAvatarId(avatar_id)
+ , mClassifiedId(classified_id)
+{
+ LLUICtrlFactory::getInstance()->buildPanel(this,"panel_classifieds_list_item.xml");
+
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
+}
+
+LLClassifiedItem::~LLClassifiedItem()
+{
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+}
+
+void LLClassifiedItem::processProperties(void* data, EAvatarProcessorType type)
+{
+ if(APT_CLASSIFIED_INFO != type)
+ {
+ return;
+ }
+
+ LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
+ if( !c_info || c_info->classified_id != getClassifiedId() )
+ {
+ return;
+ }
+
+ setClassifiedName(c_info->name);
+ setDescription(c_info->description);
+ setSnapshotId(c_info->snapshot_id);
+ setPosGlobal(c_info->pos_global);
+
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+}
+
+BOOL LLClassifiedItem::postBuild()
+{
+ setMouseEnterCallback(boost::bind(&LLPanelPickInfo::childSetVisible, this, "hovered_icon", true));
+ setMouseLeaveCallback(boost::bind(&LLPanelPickInfo::childSetVisible, this, "hovered_icon", false));
+ return TRUE;
+}
+
+void LLClassifiedItem::setValue(const LLSD& value)
+{
+ if (!value.isMap()) return;;
+ if (!value.has("selected")) return;
+ childSetVisible("selected_icon", value["selected"]);
+}
+
+void LLClassifiedItem::setClassifiedName(const std::string& name)
+{
+ childSetValue("name", name);
+}
+
+void LLClassifiedItem::setDescription(const std::string& desc)
+{
+ childSetValue("description", desc);
+}
+
+void LLClassifiedItem::setSnapshotId(const LLUUID& snapshot_id)
+{
+ childSetValue("picture", snapshot_id);
+}
+
+LLUUID LLClassifiedItem::getSnapshotId()
+{
+ return childGetValue("picture");
+}
+
+//EOF
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
index 5a2754ad10..4b90ea5048 100644
--- a/indra/newview/llpanelpicks.h
+++ b/indra/newview/llpanelpicks.h
@@ -40,6 +40,7 @@
#include "llpanelavatar.h"
#include "llregistry.h"
+class LLAccordionCtrlTab;
class LLPanelProfile;
class LLMessageSystem;
class LLVector3d;
@@ -47,10 +48,18 @@ class LLPanelProfileTab;
class LLAgent;
class LLMenuGL;
class LLPickItem;
+class LLClassifiedItem;
class LLFlatListView;
class LLPanelPickInfo;
class LLPanelPickEdit;
class LLToggleableMenu;
+class LLPanelClassifiedInfo;
+class LLPanelClassifiedEdit;
+class LLClassifiedClickThrough;
+
+// *TODO
+// Panel Picks has been consolidated with Classifieds (EXT-2095), give LLPanelPicks
+// and corresponding files (cpp, h, xml) a new name. (new name is TBD at the moment)
class LLPanelPicks
: public LLPanelProfileTab
@@ -71,6 +80,7 @@ public:
// returns the selected pick item
LLPickItem* getSelectedPickItem();
+ LLClassifiedItem* getSelectedClassifiedItem();
//*NOTE top down approch when panel toggling is done only by
// parent panels failed to work (picks related code was in me profile panel)
@@ -83,41 +93,67 @@ private:
void onOverflowMenuItemClicked(const LLSD& param);
void onOverflowButtonClicked();
+ void onPlusMenuItemClicked(const LLSD& param);
+
+ void onListCommit(const LLFlatListView* f_list);
+ void onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab);
//------------------------------------------------
// Callbacks which require panel toggling
//------------------------------------------------
- void onClickNew();
+ void onClickPlusBtn();
void onClickInfo();
void onPanelPickClose(LLPanel* panel);
void onPanelPickSave(LLPanel* panel);
+ void onPanelClassifiedSave(LLPanelClassifiedEdit* panel);
+ void onPanelClassifiedClose(LLPanelClassifiedInfo* panel);
void onPanelPickEdit();
+ void onPanelClassifiedEdit();
void onClickMenuEdit();
+ void createNewPick();
+ void createNewClassified();
+
+ void openPickInfo();
+ void openClassifiedInfo();
+
+ void showAccordion(const std::string& name, bool show);
+
void buildPickPanel();
- bool callbackDelete(const LLSD& notification, const LLSD& response);
+ bool callbackDeletePick(const LLSD& notification, const LLSD& response);
+ bool callbackDeleteClassified(const LLSD& notification, const LLSD& response);
bool callbackTeleport(const LLSD& notification, const LLSD& response);
void updateButtons();
- virtual void onDoubleClickItem(LLUICtrl* item);
+ virtual void onDoubleClickPickItem(LLUICtrl* item);
+ virtual void onDoubleClickClassifiedItem(LLUICtrl* item);
virtual void onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
LLPanelProfile* getProfilePanel();
void createPickInfoPanel();
void createPickEditPanel();
-// void openPickEditPanel(LLPickItem* pick);
-// void openPickInfoPanel(LLPickItem* pick);
+ void createClassifiedInfoPanel();
+ void createClassifiedEditPanel();
LLMenuGL* mPopupMenu;
LLPanelProfile* mProfilePanel;
LLPanelPickInfo* mPickPanel;
LLFlatListView* mPicksList;
+ LLFlatListView* mClassifiedsList;
LLPanelPickInfo* mPanelPickInfo;
+ LLPanelClassifiedInfo* mPanelClassifiedInfo;
+ LLPanelClassifiedEdit* mPanelClassifiedEdit;
LLPanelPickEdit* mPanelPickEdit;
LLToggleableMenu* mOverflowMenu;
+ LLToggleableMenu* mPlusMenu;
+
+ LLAccordionCtrlTab* mPicksAccTab;
+ LLAccordionCtrlTab* mClassifiedsAccTab;
+
+ LLClassifiedClickThrough* mClickThroughDisp;
};
class LLPickItem : public LLPanel, public LLAvatarPropertiesObserver
@@ -189,4 +225,48 @@ protected:
std::string mSimName;
};
+class LLClassifiedItem : public LLPanel, public LLAvatarPropertiesObserver
+{
+public:
+
+ LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id);
+
+ virtual ~LLClassifiedItem();
+
+ /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
+
+ /*virtual*/ BOOL postBuild();
+
+ /*virtual*/ void setValue(const LLSD& value);
+
+ LLUUID getAvatarId() {return mAvatarId;}
+
+ void setAvatarId(const LLUUID& avatar_id) {mAvatarId = avatar_id;}
+
+ LLUUID getClassifiedId() {return mClassifiedId;}
+
+ void setClassifiedId(const LLUUID& classified_id) {mClassifiedId = classified_id;}
+
+ void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
+
+ const LLVector3d& getPosGlobal() { return mPosGlobal; }
+
+ void setClassifiedName (const std::string& name);
+
+ std::string getClassifiedName() { return childGetValue("name").asString(); }
+
+ void setDescription(const std::string& desc);
+
+ std::string getDescription() { return childGetValue("description").asString(); }
+
+ void setSnapshotId(const LLUUID& snapshot_id);
+
+ LLUUID getSnapshotId();
+
+private:
+ LLUUID mAvatarId;
+ LLUUID mClassifiedId;
+ LLVector3d mPosGlobal;
+};
+
#endif // LL_LLPANELPICKS_H
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index c600651015..963d39de8a 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -40,7 +40,7 @@
#include "llsdutil_math.h"
-#include "llscrollcontainer.h"
+#include "lliconctrl.h"
#include "lltextbox.h"
#include "llagent.h"
@@ -57,8 +57,7 @@ LLPanelPlaceInfo::LLPanelPlaceInfo()
: LLPanel(),
mParcelID(),
mRequestedID(),
- mPosRegion(),
- mMinHeight(0)
+ mPosRegion()
{}
//virtual
@@ -81,12 +80,9 @@ BOOL LLPanelPlaceInfo::postBuild()
mParcelName = getChild<LLTextBox>("parcel_title");
mDescEditor = getChild<LLExpandableTextBox>("description");
+ mMaturityRatingIcon = getChild<LLIconCtrl>("maturity_icon");
mMaturityRatingText = getChild<LLTextBox>("maturity_value");
- LLScrollContainer* scroll_container = getChild<LLScrollContainer>("place_scroll");
- scroll_container->setBorderVisible(FALSE);
- mMinHeight = scroll_container->getScrolledViewRect().getHeight();
-
return TRUE;
}
@@ -98,6 +94,7 @@ void LLPanelPlaceInfo::resetLocation()
mPosRegion.clearVec();
std::string not_available = getString("not_available");
+ mMaturityRatingIcon->setValue(not_available);
mMaturityRatingText->setValue(not_available);
mRegionName->setText(not_available);
mParcelName->setText(not_available);
@@ -204,20 +201,6 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
mDescEditor->setText(parcel_data.desc);
}
- // HACK: Flag 0x2 == adult region,
- // Flag 0x1 == mature region, otherwise assume PG
- std::string rating = LLViewerRegion::accessToString(SIM_ACCESS_PG);
- if (parcel_data.flags & 0x2)
- {
- rating = LLViewerRegion::accessToString(SIM_ACCESS_ADULT);
- }
- else if (parcel_data.flags & 0x1)
- {
- rating = LLViewerRegion::accessToString(SIM_ACCESS_MATURE);
- }
-
- mMaturityRatingText->setValue(rating);
-
S32 region_x;
S32 region_y;
S32 region_z;
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index ec30397cff..133933a880 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -41,6 +41,7 @@
#include "llremoteparcelrequest.h"
class LLExpandableTextBox;
+class LLIconCtrl;
class LLInventoryItem;
class LLPanelPickEdit;
class LLParcel;
@@ -109,7 +110,6 @@ protected:
LLUUID mRequestedID;
LLVector3 mPosRegion;
std::string mCurrentTitle;
- S32 mMinHeight;
INFO_TYPE mInfoType;
LLTextBox* mTitle;
@@ -117,6 +117,7 @@ protected:
LLTextBox* mRegionName;
LLTextBox* mParcelName;
LLExpandableTextBox* mDescEditor;
+ LLIconCtrl* mMaturityRatingIcon;
LLTextBox* mMaturityRatingText;
};
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index 2a9ba4697d..61501cc1b1 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -97,7 +97,6 @@ BOOL LLPanelPlaceProfile::postBuild()
setMouseDownCallback(boost::bind(&LLPanelPlaceProfile::onForSaleBannerClick, this));
mParcelOwner = getChild<LLTextBox>("owner_value");
- mLastVisited = getChild<LLTextBox>("last_visited_value");
mParcelRatingIcon = getChild<LLIconCtrl>("rating_icon");
mParcelRatingText = getChild<LLTextBox>("rating_value");
@@ -165,7 +164,6 @@ void LLPanelPlaceProfile::resetLocation()
std::string not_available = getString("not_available");
mParcelOwner->setValue(not_available);
- mLastVisited->setValue(not_available);
mParcelRatingIcon->setValue(not_available);
mParcelRatingText->setText(not_available);
@@ -209,17 +207,13 @@ void LLPanelPlaceProfile::resetLocation()
void LLPanelPlaceProfile::setInfoType(INFO_TYPE type)
{
bool is_info_type_agent = type == AGENT;
- bool is_info_type_teleport_history = type == TELEPORT_HISTORY;
- getChild<LLTextBox>("maturity_label")->setVisible(!is_info_type_agent);
+ mMaturityRatingIcon->setVisible(!is_info_type_agent);
mMaturityRatingText->setVisible(!is_info_type_agent);
getChild<LLTextBox>("owner_label")->setVisible(is_info_type_agent);
mParcelOwner->setVisible(is_info_type_agent);
- getChild<LLTextBox>("last_visited_label")->setVisible(is_info_type_teleport_history);
- mLastVisited->setVisible(is_info_type_teleport_history);
-
getChild<LLAccordionCtrl>("advanced_info_accordion")->setVisible(is_info_type_agent);
switch(type)
@@ -238,6 +232,30 @@ void LLPanelPlaceProfile::setInfoType(INFO_TYPE type)
LLPanelPlaceInfo::setInfoType(type);
}
+// virtual
+void LLPanelPlaceProfile::processParcelInfo(const LLParcelData& parcel_data)
+{
+ LLPanelPlaceInfo::processParcelInfo(parcel_data);
+
+ // HACK: Flag 0x2 == adult region,
+ // Flag 0x1 == mature region, otherwise assume PG
+ if (parcel_data.flags & 0x2)
+ {
+ mMaturityRatingIcon->setValue(icon_r);
+ mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_ADULT));
+ }
+ else if (parcel_data.flags & 0x1)
+ {
+ mMaturityRatingIcon->setValue(icon_m);
+ mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_MATURE));
+ }
+ else
+ {
+ mMaturityRatingIcon->setValue(icon_pg);
+ mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_PG));
+ }
+}
+
void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
LLViewerRegion* region,
const LLVector3d& pos_global,
@@ -521,22 +539,6 @@ void LLPanelPlaceProfile::updateCovenantText(const std::string &text)
mCovenantText->setText(text);
}
-void LLPanelPlaceProfile::updateLastVisitedText(const LLDate &date)
-{
- if (date.isNull())
- {
- mLastVisited->setText(getString("unknown"));
- }
- else
- {
- std::string timeStr = getString("acquired_date");
- LLSD substitution;
- substitution["datetime"] = (S32) date.secondsSinceEpoch();
- LLStringUtil::format (timeStr, substitution);
- mLastVisited->setText(timeStr);
- }
-}
-
void LLPanelPlaceProfile::onForSaleBannerClick()
{
LLViewerParcelMgr* mgr = LLViewerParcelMgr::getInstance();
diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h
index b3ef4acf51..8c30ca92fb 100644
--- a/indra/newview/llpanelplaceprofile.h
+++ b/indra/newview/llpanelplaceprofile.h
@@ -50,6 +50,8 @@ public:
/*virtual*/ void setInfoType(INFO_TYPE type);
+ /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
+
// Displays information about the currently selected parcel
// without sending a request to the server.
// If is_current_parcel true shows "You Are Here" banner.
@@ -61,7 +63,6 @@ public:
void updateEstateName(const std::string& name);
void updateEstateOwnerName(const std::string& name);
void updateCovenantText(const std::string &text);
- void updateLastVisitedText(const LLDate &date);
private:
void onForSaleBannerClick();
@@ -78,7 +79,6 @@ private:
LLPanel* mYouAreHerePanel;
LLTextBox* mParcelOwner;
- LLTextBox* mLastVisited;
LLIconCtrl* mParcelRatingIcon;
LLTextBox* mParcelRatingText;
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 8d117afcfe..3d0fba9426 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -293,7 +293,6 @@ void LLPanelPlaces::onOpen(const LLSD& key)
mPosGlobal = hist_items[index].mGlobalPos;
mPlaceProfile->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
- mPlaceProfile->updateLastVisitedText(hist_items[index].mDate);
mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
}
diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp
index 5c3c260549..24de2dcdfc 100644
--- a/indra/newview/llpanelprimmediacontrols.cpp
+++ b/indra/newview/llpanelprimmediacontrols.cpp
@@ -118,21 +118,33 @@ LLPanelPrimMediaControls::~LLPanelPrimMediaControls()
BOOL LLPanelPrimMediaControls::postBuild()
{
LLButton* scroll_up_ctrl = getChild<LLButton>("scrollup");
- scroll_up_ctrl->setClickedCallback(onScrollUp, this);
- scroll_up_ctrl->setHeldDownCallback(onScrollUpHeld, this);
- scroll_up_ctrl->setMouseUpCallback(onScrollStop, this);
+ if (scroll_up_ctrl)
+ {
+ scroll_up_ctrl->setClickedCallback(onScrollUp, this);
+ scroll_up_ctrl->setHeldDownCallback(onScrollUpHeld, this);
+ scroll_up_ctrl->setMouseUpCallback(onScrollStop, this);
+ }
LLButton* scroll_left_ctrl = getChild<LLButton>("scrollleft");
- scroll_left_ctrl->setClickedCallback(onScrollLeft, this);
- scroll_left_ctrl->setHeldDownCallback(onScrollLeftHeld, this);
- scroll_left_ctrl->setMouseUpCallback(onScrollStop, this);
+ if (scroll_left_ctrl)
+ {
+ scroll_left_ctrl->setClickedCallback(onScrollLeft, this);
+ scroll_left_ctrl->setHeldDownCallback(onScrollLeftHeld, this);
+ scroll_left_ctrl->setMouseUpCallback(onScrollStop, this);
+ }
LLButton* scroll_right_ctrl = getChild<LLButton>("scrollright");
- scroll_right_ctrl->setClickedCallback(onScrollRight, this);
- scroll_right_ctrl->setHeldDownCallback(onScrollRightHeld, this);
- scroll_right_ctrl->setMouseUpCallback(onScrollStop, this);
+ if (scroll_right_ctrl)
+ {
+ scroll_right_ctrl->setClickedCallback(onScrollRight, this);
+ scroll_right_ctrl->setHeldDownCallback(onScrollRightHeld, this);
+ scroll_right_ctrl->setMouseUpCallback(onScrollStop, this);
+ }
LLButton* scroll_down_ctrl = getChild<LLButton>("scrolldown");
- scroll_down_ctrl->setClickedCallback(onScrollDown, this);
- scroll_down_ctrl->setHeldDownCallback(onScrollDownHeld, this);
- scroll_down_ctrl->setMouseUpCallback(onScrollStop, this);
+ if (scroll_down_ctrl)
+ {
+ scroll_down_ctrl->setClickedCallback(onScrollDown, this);
+ scroll_down_ctrl->setHeldDownCallback(onScrollDownHeld, this);
+ scroll_down_ctrl->setMouseUpCallback(onScrollStop, this);
+ }
LLUICtrl* media_address = getChild<LLUICtrl>("media_address");
media_address->setFocusReceivedCallback(boost::bind(&LLPanelPrimMediaControls::onInputURL, _1, this ));
@@ -326,11 +338,14 @@ void LLPanelPrimMediaControls::updateShape()
whitelist_icon->setVisible(false);
secure_lock_icon->setVisible(false);
- scroll_up_ctrl->setVisible(false);
- scroll_left_ctrl->setVisible(false);
- scroll_right_ctrl->setVisible(false);
- scroll_down_ctrl->setVisible(false);
- media_panel_scroll->setVisible(false);
+ if (media_panel_scroll)
+ {
+ media_panel_scroll->setVisible(false);
+ scroll_up_ctrl->setVisible(false);
+ scroll_left_ctrl->setVisible(false);
+ scroll_right_ctrl->setVisible(false);
+ scroll_down_ctrl->setVisible(false);
+ }
F32 volume = media_impl->getVolume();
// movie's url changed
@@ -422,12 +437,15 @@ void LLPanelPrimMediaControls::updateShape()
volume_ctrl->setEnabled(FALSE);
volume_up_ctrl->setEnabled(FALSE);
volume_down_ctrl->setEnabled(FALSE);
-
- scroll_up_ctrl->setVisible(has_focus);
- scroll_left_ctrl->setVisible(has_focus);
- scroll_right_ctrl->setVisible(has_focus);
- scroll_down_ctrl->setVisible(has_focus);
- media_panel_scroll->setVisible(has_focus);
+
+ if (media_panel_scroll)
+ {
+ media_panel_scroll->setVisible(has_focus);
+ scroll_up_ctrl->setVisible(has_focus);
+ scroll_left_ctrl->setVisible(has_focus);
+ scroll_right_ctrl->setVisible(has_focus);
+ scroll_down_ctrl->setVisible(has_focus);
+ }
// TODO: get the secure lock bool from media plug in
std::string prefix = std::string("https://");
std::string test_prefix = mCurrentURL.substr(0, prefix.length());
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 8147ff17f0..02f45c1b48 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -243,5 +243,6 @@ void LLPanelProfile::notifyParent(const LLSD& info)
onOpen(info);
return;
}
+
LLPanel::notifyParent(info);
}
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 2be0781487..f5367c0477 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -36,10 +36,12 @@
#include "lltrans.h"
#include "llavataractions.h"
#include "llagent.h"
+#include "llimview.h"
#include "llparticipantlist.h"
#include "llavatarlist.h"
#include "llspeakers.h"
+#include "llviewermenu.h"
//LLParticipantList retrieves add, clear and remove events and updates view accordingly
#if LL_MSVC
@@ -64,6 +66,9 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* av
mAvatarList->setDoubleClickCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, mAvatarList));
mAvatarList->setRefreshCompleteCallback(boost::bind(&LLParticipantList::onAvatarListRefreshed, this, _1, _2));
+ mParticipantListMenu = new LLParticipantListMenu(*this);
+ mAvatarList->setContextMenu(mParticipantListMenu);
+
//Lets fill avatarList with existing speakers
LLAvatarList::uuid_vector_t& group_members = mAvatarList->getIDs();
@@ -83,8 +88,15 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* av
LLParticipantList::~LLParticipantList()
{
+ delete mParticipantListMenu;
+ mParticipantListMenu = NULL;
}
+void LLParticipantList::setSpeakingIndicatorsVisible(BOOL visible)
+{
+ mAvatarList->setSpeakingIndicatorsVisible(visible);
+};
+
void LLParticipantList::onAvatarListDoubleClicked(LLAvatarList* list)
{
LLUUID clicked_id = list->getSelectedUUID();
@@ -265,3 +277,139 @@ bool LLParticipantList::SpeakerModeratorUpdateListener::handleEvent(LLPointer<LL
{
return mParent.onModeratorUpdateEvent(event, userdata);
}
+
+LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu()
+{
+ // set up the callbacks for all of the avatar menu items
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+
+ registrar.add("ParticipantList.ToggleAllowTextChat", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleAllowTextChat, this, _2));
+ registrar.add("ParticipantList.ToggleMuteText", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleMuteText, this, _2));
+
+ enable_registrar.add("ParticipantList.EnableItem", boost::bind(&LLParticipantList::LLParticipantListMenu::enableContextMenuItem, this, _2));
+ enable_registrar.add("ParticipantList.CheckItem", boost::bind(&LLParticipantList::LLParticipantListMenu::checkContextMenuItem, this, _2));
+
+ // create the context menu from the XUI
+ return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
+ "menu_participant_list.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
+}
+
+void LLParticipantList::LLParticipantListMenu::toggleAllowTextChat(const LLSD& userdata)
+{
+ const LLUUID speaker_id = mUUIDs.front();
+
+ std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest");
+ LLSD data;
+ data["method"] = "mute update";
+ data["session-id"] = mParent.mSpeakerMgr->getSessionID();
+ data["params"] = LLSD::emptyMap();
+ data["params"]["agent_id"] = speaker_id;
+ data["params"]["mute_info"] = LLSD::emptyMap();
+ //current value represents ability to type, so invert
+ data["params"]["mute_info"]["text"] = !mParent.mSpeakerMgr->findSpeaker(speaker_id)->mModeratorMutedText;
+
+ class MuteTextResponder : public LLHTTPClient::Responder
+ {
+ public:
+ MuteTextResponder(const LLUUID& session_id)
+ {
+ mSessionID = session_id;
+ }
+
+ virtual void error(U32 status, const std::string& reason)
+ {
+ llwarns << status << ": " << reason << llendl;
+
+ if ( gIMMgr )
+ {
+ //403 == you're not a mod
+ //should be disabled if you're not a moderator
+ if ( 403 == status )
+ {
+ gIMMgr->showSessionEventError(
+ "mute",
+ "not_a_moderator",
+ mSessionID);
+ }
+ else
+ {
+ gIMMgr->showSessionEventError(
+ "mute",
+ "generic",
+ mSessionID);
+ }
+ }
+ }
+
+ private:
+ LLUUID mSessionID;
+ };
+
+ LLHTTPClient::post(
+ url,
+ data,
+ new MuteTextResponder(mParent.mSpeakerMgr->getSessionID()));
+}
+
+void LLParticipantList::LLParticipantListMenu::toggleMuteText(const LLSD& userdata)
+{
+ const LLUUID speaker_id = mUUIDs.front();
+ BOOL is_muted = LLMuteList::getInstance()->isMuted(speaker_id, LLMute::flagTextChat);
+ std::string name;
+
+ //fill in name using voice client's copy of name cache
+ LLPointer<LLSpeaker> speakerp = mParent.mSpeakerMgr->findSpeaker(speaker_id);
+ if (speakerp.isNull())
+ {
+ return;
+ }
+
+ name = speakerp->mDisplayName;
+
+ LLMute mute(speaker_id, name, speakerp->mType == LLSpeaker::SPEAKER_AGENT ? LLMute::AGENT : LLMute::OBJECT);
+
+ if (!is_muted)
+ {
+ LLMuteList::getInstance()->add(mute, LLMute::flagTextChat);
+ }
+ else
+ {
+ LLMuteList::getInstance()->remove(mute, LLMute::flagTextChat);
+ }
+}
+
+bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD& userdata)
+{
+ std::string item = userdata.asString();
+ if (item == "can_mute_text")
+ {
+ return mUUIDs.front() != gAgentID;
+ }
+ else
+ if (item == "can_allow_text_chat")
+ {
+ LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(mParent.mSpeakerMgr->getSessionID());
+ return im_session->mType == IM_SESSION_GROUP_START && mParent.mSpeakerMgr->findSpeaker(gAgentID)->mIsModerator;
+ }
+ return true;
+}
+
+bool LLParticipantList::LLParticipantListMenu::checkContextMenuItem(const LLSD& userdata)
+{
+ std::string item = userdata.asString();
+ const LLUUID& id = mUUIDs.front();
+ if (item == "is_muted")
+ return LLMuteList::getInstance()->isMuted(id, LLMute::flagTextChat);
+ else
+ if (item == "is_allowed_text_chat")
+ {
+ LLPointer<LLSpeaker> selected_speakerp = mParent.mSpeakerMgr->findSpeaker(id);
+
+ if (selected_speakerp.notNull())
+ {
+ return !selected_speakerp->mModeratorMutedText;
+ }
+ }
+ return false;
+}
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index fc34dd308b..5e26c39fc8 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -32,6 +32,8 @@
#include "llviewerprecompiledheaders.h"
#include "llevent.h"
+#include "llpanelpeoplemenus.h"
+#include "llimview.h"
class LLSpeakerMgr;
class LLAvatarList;
@@ -43,6 +45,7 @@ class LLParticipantList
public:
LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list);
~LLParticipantList();
+ void setSpeakingIndicatorsVisible(BOOL visible);
typedef enum e_participant_sort_oder {
E_SORT_BY_NAME = 0,
@@ -105,6 +108,25 @@ class LLParticipantList
SpeakerModeratorUpdateListener(LLParticipantList& parent) : BaseSpeakerListner(parent) {}
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
};
+
+ /**
+ * Menu used in the participant list.
+ */
+ class LLParticipantListMenu : public LLPanelPeopleMenus::ContextMenu
+ {
+ public:
+ LLParticipantListMenu(LLParticipantList& parent):mParent(parent){};
+ /*virtual*/ LLContextMenu* createMenu();
+ protected:
+ LLParticipantList& mParent;
+ private:
+ bool enableContextMenuItem(const LLSD& userdata);
+ bool checkContextMenuItem(const LLSD& userdata);
+
+ void toggleAllowTextChat(const LLSD& userdata);
+ void toggleMuteText(const LLSD& userdata);
+
+ };
private:
void onAvatarListDoubleClicked(LLAvatarList* list);
@@ -121,5 +143,7 @@ class LLParticipantList
LLPointer<SpeakerClearListener> mSpeakerClearListener;
LLPointer<SpeakerModeratorUpdateListener> mSpeakerModeratorListener;
+ LLParticipantListMenu* mParticipantListMenu;
+
EParticipantSortOrder mSortOrder;
};
diff --git a/indra/newview/llrecentpeople.cpp b/indra/newview/llrecentpeople.cpp
index b491c7e109..bd46b5b56a 100644
--- a/indra/newview/llrecentpeople.cpp
+++ b/indra/newview/llrecentpeople.cpp
@@ -33,6 +33,7 @@
#include "llviewerprecompiledheaders.h"
#include "llrecentpeople.h"
+#include "llgroupmgr.h"
#include "llagent.h"
@@ -43,12 +44,18 @@ bool LLRecentPeople::add(const LLUUID& id)
if (id == gAgent.getID())
return false;
- LLDate date_added = LLDate::now();
+ bool is_not_group_id = LLGroupMgr::getInstance()->getGroupData(id) == NULL;
- //[] instead of insert to replace existing id->date with new date value
- mPeople[id] = date_added;
- mChangedSignal();
- return true;
+ if (is_not_group_id)
+ {
+ LLDate date_added = LLDate::now();
+
+ //[] instead of insert to replace existing id->date with new date value
+ mPeople[id] = date_added;
+ mChangedSignal();
+ }
+
+ return is_not_group_id;
}
bool LLRecentPeople::contains(const LLUUID& id) const
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 061587f11b..70dc04f575 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -101,6 +101,7 @@ LLSideTray* LLSideTray::getInstance()
if (!sInstance)
{
sInstance = LLUICtrlFactory::createFromFile<LLSideTray>("panel_side_tray.xml",NULL, LLRootView::child_registry_t::instance());
+ sInstance->setXMLFilename("panel_side_tray.xml");
}
return sInstance;
@@ -353,7 +354,8 @@ bool LLSideTray::selectTabByName (const std::string& name)
return true;
}
-LLButton* LLSideTray::createButton (const std::string& name,const std::string& image,LLUICtrl::commit_callback_t callback)
+LLButton* LLSideTray::createButton (const std::string& name,const std::string& image,const std::string& tooltip,
+ LLUICtrl::commit_callback_t callback)
{
static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>());
@@ -374,6 +376,9 @@ LLButton* LLSideTray::createButton (const std::string& name,const std::string& i
LLButton* button = LLUICtrlFactory::create<LLButton> (bparams);
button->setLabel(name);
button->setClickedCallback(callback);
+
+ if(tooltip!="Home")
+ button->setToolTip(tooltip);
if(image.length())
{
@@ -412,28 +417,63 @@ void LLSideTray::createButtons ()
// change if the home screen becomes its own tab.
if (name == "sidebar_home")
{
- mCollapseButton = createButton("",sidebar_tab->mImage,
+ mCollapseButton = createButton("",sidebar_tab->mImage,sidebar_tab->getTabTitle(),
boost::bind(&LLSideTray::onToggleCollapse, this));
}
else
{
- LLButton* button = createButton("",sidebar_tab->mImage,
+ LLButton* button = createButton("",sidebar_tab->mImage,sidebar_tab->getTabTitle(),
boost::bind(&LLSideTray::onTabButtonClick, this, name));
mTabButtons[name] = button;
}
}
}
+void LLSideTray::processTriState ()
+{
+ if(mCollapsed)
+ expandSideBar();
+ else
+ {
+ //!!!!!!!!!!!!!!!!!
+ //** HARDCODED!!!!!
+ //!!!!!!!!!!!!!!!!!
+
+ //there is no common way to determine "default" panel for tab
+ //so default panels for now will be hardcoded
+
+ //hardcoded for people tab and profile tab
+
+ /*if(mActiveTab == getTab("sidebar_people"))
+ {
+ LLSideTrayPanelContainer* container = findChild<LLSideTrayPanelContainer>("panel_container");
+ if(container && container->getCurrentPanelIndex()>0)
+ {
+ container->onOpen(LLSD().insert("sub_panel_name","panel_people"));
+ }
+ else
+ collapseSideBar();
+ }
+ else if(mActiveTab == getTab("sidebar_me"))
+ {
+ LLTabContainer* tab_container = findChild<LLTabContainer>("tabs");
+ if(tab_container && tab_container->getCurrentPanelIndex()>0)
+ tab_container->selectFirstTab();
+ else
+ collapseSideBar();
+ }
+ else*/
+ collapseSideBar();
+ }
+}
+
void LLSideTray::onTabButtonClick(string name)
{
LLSideTrayTab* side_bar = getTab(name);
if(side_bar == mActiveTab)
{
- if(mCollapsed)
- expandSideBar();
- else
- collapseSideBar();
+ processTriState ();
return;
}
selectTabByName (name);
diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h
index 4d6081e230..8b30199c45 100644
--- a/indra/newview/llsidetray.h
+++ b/indra/newview/llsidetray.h
@@ -134,11 +134,15 @@ public:
void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE);
+ void processTriState ();
+
+
protected:
LLSideTrayTab* getTab (const std::string& name);
void createButtons ();
- LLButton* createButton (const std::string& name,const std::string& image,LLUICtrl::commit_callback_t callback);
+ LLButton* createButton (const std::string& name,const std::string& image,const std::string& tooltip,
+ LLUICtrl::commit_callback_t callback);
void arrange ();
void reflectCollapseChange();
diff --git a/indra/newview/llspeakbutton.cpp b/indra/newview/llspeakbutton.cpp
index 57ea018f25..51d53b2674 100644
--- a/indra/newview/llspeakbutton.cpp
+++ b/indra/newview/llspeakbutton.cpp
@@ -133,6 +133,16 @@ LLSpeakButton::~LLSpeakButton()
LLTransientFloaterMgr::getInstance()->removeControlView(mShowBtn);
}
+void LLSpeakButton::setSpeakToolTip(const std::string& msg)
+{
+ mSpeakBtn->setToolTip(msg);
+}
+
+void LLSpeakButton::setShowToolTip(const std::string& msg)
+{
+ mShowBtn->setToolTip(msg);
+}
+
void LLSpeakButton::onMouseDown_SpeakBtn()
{
bool down = true;
diff --git a/indra/newview/llspeakbutton.h b/indra/newview/llspeakbutton.h
index e213c562dd..02c8ab3890 100644
--- a/indra/newview/llspeakbutton.h
+++ b/indra/newview/llspeakbutton.h
@@ -62,6 +62,11 @@ public:
/*virtual*/ ~LLSpeakButton();
/*virtual*/ void draw();
+ // *HACK: Need to put tooltips in a translatable location,
+ // the panel that contains this button.
+ void setSpeakToolTip(const std::string& msg);
+ void setShowToolTip(const std::string& msg);
+
protected:
friend class LLUICtrlFactory;
LLSpeakButton(const Params& p);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 25729c91e6..2c59d62b4b 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -873,6 +873,9 @@ bool idle_startup()
gViewerWindow->getWindow()->show();
display_startup();
+ //DEV-10530. do cleanup. remove at some later date. jan-2009
+ LLFloaterPreference::cleanupBadSetting();
+
// DEV-16927. The following code removes errant keystrokes that happen while the window is being
// first made visible.
#ifdef _WIN32
@@ -1900,9 +1903,6 @@ bool idle_startup()
//DEV-17797. get null folder. Any items found here moved to Lost and Found
LLInventoryModel::findLostItems();
- //DEV-10530. do cleanup. remove at some later date. jan-2009
- LLFloaterPreference::cleanupBadSetting();
-
LLStartUp::setStartupState( STATE_PRECACHE );
timeout.reset();
return FALSE;
@@ -2478,7 +2478,7 @@ void register_viewer_callbacks(LLMessageSystem* msg)
msg->setHandlerFunc("AvatarPicksReply",
&LLAvatarPropertiesProcessor::processAvatarPicksReply);
msg->setHandlerFunc("AvatarClassifiedReply",
- &LLAvatarPropertiesProcessor::processAvatarClassifiedReply);
+ &LLAvatarPropertiesProcessor::processAvatarClassifiedsReply);
msg->setHandlerFuncFast(_PREHASH_CreateGroupReply,
LLGroupMgr::processCreateGroupReply);
@@ -2543,7 +2543,8 @@ void register_viewer_callbacks(LLMessageSystem* msg)
msg->setHandlerFunc("EventInfoReply", LLPanelEvent::processEventInfoReply);
msg->setHandlerFunc("PickInfoReply", &LLAvatarPropertiesProcessor::processPickInfoReply);
- msg->setHandlerFunc("ClassifiedInfoReply", LLPanelClassified::processClassifiedInfoReply);
+// msg->setHandlerFunc("ClassifiedInfoReply", LLPanelClassified::processClassifiedInfoReply);
+ msg->setHandlerFunc("ClassifiedInfoReply", LLAvatarPropertiesProcessor::processClassifiedInfoReply);
msg->setHandlerFunc("ParcelInfoReply", LLRemoteParcelInfoProcessor::processParcelInfoReply);
msg->setHandlerFunc("ScriptDialog", process_script_dialog);
msg->setHandlerFunc("LoadURL", process_load_url);
diff --git a/indra/newview/lltexglobalcolor.cpp b/indra/newview/lltexglobalcolor.cpp
index 595b24ad47..d7840fb435 100644
--- a/indra/newview/lltexglobalcolor.cpp
+++ b/indra/newview/lltexglobalcolor.cpp
@@ -108,9 +108,9 @@ LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color)
return new_param;
}
-void LLTexParamGlobalColor::onGlobalColorChanged(bool set_by_user)
+void LLTexParamGlobalColor::onGlobalColorChanged(bool upload_bake)
{
- mAvatar->onGlobalColorChanged(mTexGlobalColor, set_by_user);
+ mAvatar->onGlobalColorChanged(mTexGlobalColor, upload_bake);
}
//-----------------------------------------------------------------------------
diff --git a/indra/newview/lltexglobalcolor.h b/indra/newview/lltexglobalcolor.h
index 1e6754133f..829a7d645b 100644
--- a/indra/newview/lltexglobalcolor.h
+++ b/indra/newview/lltexglobalcolor.h
@@ -80,7 +80,7 @@ public:
LLTexParamGlobalColor(LLTexGlobalColor *tex_color);
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
protected:
- /*virtual*/ void onGlobalColorChanged(bool set_by_user);
+ /*virtual*/ void onGlobalColorChanged(bool upload_bake);
private:
LLTexGlobalColor* mTexGlobalColor;
};
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index 5d682cad3c..25e0ca46e4 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -1834,7 +1834,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i)
}
if (layer)
{
- wearable->writeToAvatar(FALSE, FALSE);
+ wearable->writeToAvatar();
layer->setLTO(lto);
success &= layer->render(x,y,width,height);
}
diff --git a/indra/newview/lltexlayerparams.cpp b/indra/newview/lltexlayerparams.cpp
index b744722f4c..0c7e61d00e 100644
--- a/indra/newview/lltexlayerparams.cpp
+++ b/indra/newview/lltexlayerparams.cpp
@@ -160,7 +160,7 @@ BOOL LLTexLayerParamAlpha::getMultiplyBlend() const
return ((LLTexLayerParamAlphaInfo *)getInfo())->mMultiplyBlend;
}
-void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL set_by_user)
+void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL upload_bake)
{
if (mIsAnimating || mTexLayer == NULL)
{
@@ -179,37 +179,37 @@ void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL set_by_user)
{
if (gAgent.cameraCustomizeAvatar())
{
- set_by_user = FALSE;
+ upload_bake = FALSE;
}
- mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), set_by_user);
+ mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
mTexLayer->invalidateMorphMasks();
}
}
}
-void LLTexLayerParamAlpha::setAnimationTarget(F32 target_value, BOOL set_by_user)
+void LLTexLayerParamAlpha::setAnimationTarget(F32 target_value, BOOL upload_bake)
{
// do not animate dummy parameters
if (mIsDummy)
{
- setWeight(target_value, set_by_user);
+ setWeight(target_value, upload_bake);
return;
}
mTargetWeight = target_value;
- setWeight(target_value, set_by_user);
+ setWeight(target_value, upload_bake);
mIsAnimating = TRUE;
if (mNext)
{
- mNext->setAnimationTarget(target_value, set_by_user);
+ mNext->setAnimationTarget(target_value, upload_bake);
}
}
-void LLTexLayerParamAlpha::animate(F32 delta, BOOL set_by_user)
+void LLTexLayerParamAlpha::animate(F32 delta, BOOL upload_bake)
{
if (mNext)
{
- mNext->animate(delta, set_by_user);
+ mNext->animate(delta, upload_bake);
}
}
@@ -449,7 +449,7 @@ LLColor4 LLTexLayerParamColor::getNetColor() const
}
}
-void LLTexLayerParamColor::setWeight(F32 weight, BOOL set_by_user)
+void LLTexLayerParamColor::setWeight(F32 weight, BOOL upload_bake)
{
if (mIsAnimating)
{
@@ -474,10 +474,10 @@ void LLTexLayerParamColor::setWeight(F32 weight, BOOL set_by_user)
if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
{
- onGlobalColorChanged(set_by_user);
+ onGlobalColorChanged(upload_bake);
if (mTexLayer)
{
- mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), set_by_user);
+ mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
}
}
@@ -485,23 +485,23 @@ void LLTexLayerParamColor::setWeight(F32 weight, BOOL set_by_user)
}
}
-void LLTexLayerParamColor::setAnimationTarget(F32 target_value, BOOL set_by_user)
+void LLTexLayerParamColor::setAnimationTarget(F32 target_value, BOOL upload_bake)
{
// set value first then set interpolating flag to ignore further updates
mTargetWeight = target_value;
- setWeight(target_value, set_by_user);
+ setWeight(target_value, upload_bake);
mIsAnimating = TRUE;
if (mNext)
{
- mNext->setAnimationTarget(target_value, set_by_user);
+ mNext->setAnimationTarget(target_value, upload_bake);
}
}
-void LLTexLayerParamColor::animate(F32 delta, BOOL set_by_user)
+void LLTexLayerParamColor::animate(F32 delta, BOOL upload_bake)
{
if (mNext)
{
- mNext->animate(delta, set_by_user);
+ mNext->animate(delta, upload_bake);
}
}
diff --git a/indra/newview/lltexlayerparams.h b/indra/newview/lltexlayerparams.h
index 98365864f9..2b80dbdba4 100644
--- a/indra/newview/lltexlayerparams.h
+++ b/indra/newview/lltexlayerparams.h
@@ -66,9 +66,9 @@ public:
// LLVisualParam Virtual functions
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
/*virtual*/ void apply( ESex avatar_sex ) {}
- /*virtual*/ void setWeight(F32 weight, BOOL set_by_user);
- /*virtual*/ void setAnimationTarget(F32 target_value, BOOL set_by_user);
- /*virtual*/ void animate(F32 delta, BOOL set_by_user);
+ /*virtual*/ void setWeight(F32 weight, BOOL upload_bake);
+ /*virtual*/ void setAnimationTarget(F32 target_value, BOOL upload_bake);
+ /*virtual*/ void animate(F32 delta, BOOL upload_bake);
// LLViewerVisualParam Virtual functions
/*virtual*/ F32 getTotalDistortion() { return 1.f; }
@@ -143,9 +143,9 @@ public:
// LLVisualParam Virtual functions
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
/*virtual*/ void apply( ESex avatar_sex ) {}
- /*virtual*/ void setWeight(F32 weight, BOOL set_by_user);
- /*virtual*/ void setAnimationTarget(F32 target_value, BOOL set_by_user);
- /*virtual*/ void animate(F32 delta, BOOL set_by_user);
+ /*virtual*/ void setWeight(F32 weight, BOOL upload_bake);
+ /*virtual*/ void setAnimationTarget(F32 target_value, BOOL upload_bake);
+ /*virtual*/ void animate(F32 delta, BOOL upload_bake);
// LLViewerVisualParam Virtual functions
@@ -159,7 +159,7 @@ public:
// New functions
LLColor4 getNetColor() const;
protected:
- virtual void onGlobalColorChanged(bool set_by_user) {}
+ virtual void onGlobalColorChanged(bool upload_bake) {}
private:
LLVector3 mAvgDistortionVec;
};
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 69a2d1d7a6..9be342c424 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -1541,21 +1541,24 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort)
{
lockWorkers();
handle_map_t::iterator iter = mReaders.find(handle);
- llassert_always(iter != mReaders.end() || abort);
- LLTextureCacheWorker* worker = iter->second;
- bool res = worker->complete();
- if (res || abort)
+ LLTextureCacheWorker* worker = NULL;
+ bool complete = false;
+ if (iter != mReaders.end())
+ {
+ worker = iter->second;
+ complete = worker->complete();
+ }
+ if (worker && (complete || abort))
{
- mReaders.erase(handle);
+ mReaders.erase(iter);
unlockWorkers();
worker->scheduleDelete();
- return true;
}
else
{
unlockWorkers();
- return false;
}
+ return (complete || abort);
}
LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 priority,
diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp
index c02fd7a5ef..9370e318cf 100644
--- a/indra/newview/lltoastimpanel.cpp
+++ b/indra/newview/lltoastimpanel.cpp
@@ -50,7 +50,19 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif
mMessage = getChild<LLTextBox>("message");
mReplyBtn = getChild<LLButton>("reply");
- mMessage->setValue(p.message);
+ LLStyle::Params style_params;
+ //Handle IRC styled /me messages.
+ std::string prefix = p.message.substr(0, 4);
+ if (prefix == "/me " || prefix == "/me'")
+ {
+ mMessage->clear();
+ style_params.font.style= "ITALIC";
+ mMessage->appendText(p.from + " ", FALSE, style_params);
+ style_params.font.style= "UNDERLINE";
+ mMessage->appendText(p.message.substr(3), FALSE, style_params);
+ }
+ else
+ mMessage->setValue(p.message);
mUserName->setValue(p.from);
mTime->setValue(p.time);
mSessionID = p.session_id;
diff --git a/indra/newview/lluilistener.cpp b/indra/newview/lluilistener.cpp
index 9c643e78de..8b4cfa7248 100644
--- a/indra/newview/lluilistener.cpp
+++ b/indra/newview/lluilistener.cpp
@@ -20,10 +20,16 @@
#include "lluictrl.h"
#include "llerror.h"
-LLUIListener::LLUIListener(const std::string& name):
- LLDispatchListener(name, "op")
+LLUIListener::LLUIListener():
+ LLEventAPI("UI",
+ "LLUICtrl::CommitCallbackRegistry listener.\n"
+ "Capable of invoking any function (with parameter) you can specify in XUI.")
{
- add("call", &LLUIListener::call, LLSD().insert("function", LLSD()));
+ add("call",
+ "Invoke the operation named by [\"function\"], passing [\"parameter\"],\n"
+ "as if from a user gesture on a menu -- or a button click.",
+ &LLUIListener::call,
+ LLSD().insert("function", LLSD()));
}
void LLUIListener::call(const LLSD& event) const
diff --git a/indra/newview/lluilistener.h b/indra/newview/lluilistener.h
index ea904a99ff..8605d60bd3 100644
--- a/indra/newview/lluilistener.h
+++ b/indra/newview/lluilistener.h
@@ -12,15 +12,15 @@
#if ! defined(LL_LLUILISTENER_H)
#define LL_LLUILISTENER_H
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
#include <string>
class LLSD;
-class LLUIListener: public LLDispatchListener
+class LLUIListener: public LLEventAPI
{
public:
- LLUIListener(const std::string& name);
+ LLUIListener();
private:
void call(const LLSD& event) const;
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index a3daca6fa4..9e064d8135 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -364,9 +364,9 @@ bool LLURLDispatcher::dispatchRightClick(const std::string& url)
bool LLURLDispatcher::dispatchFromTextEditor(const std::string& url)
{
// *NOTE: Text editors are considered sources of trusted URLs
- // in order to make objectim and avatar profile links in chat
- // history work. While a malicious resident could chat an app
- // SLURL, the receiving resident will see it and must affirmatively
+ // in order to make avatar profile links in chat history work.
+ // While a malicious resident could chat an app SLURL, the
+ // receiving resident will see it and must affirmatively
// click on it.
// *TODO: Make this trust model more refined. JC
const bool trusted_browser = true;
diff --git a/indra/newview/llviewercontrollistener.cpp b/indra/newview/llviewercontrollistener.cpp
index ecba1b8eb0..0b9db1b906 100644
--- a/indra/newview/llviewercontrollistener.cpp
+++ b/indra/newview/llviewercontrollistener.cpp
@@ -18,12 +18,22 @@
LLViewerControlListener gSavedSettingsListener;
LLViewerControlListener::LLViewerControlListener()
- : LLDispatchListener("LLViewerControl", "group")
+ : LLEventAPI("LLViewerControl",
+ "LLViewerControl listener: set, toggle or set default for various controls",
+ "group")
{
- add("Global", boost::bind(&LLViewerControlListener::set, &gSavedSettings, _1));
- add("PerAccount", boost::bind(&LLViewerControlListener::set, &gSavedPerAccountSettings, _1));
- add("Warning", boost::bind(&LLViewerControlListener::set, &gWarningSettings, _1));
- add("Crash", boost::bind(&LLViewerControlListener::set, &gCrashSettings, _1));
+ add("Global",
+ "Set gSavedSettings control [\"key\"] to value [\"value\"]",
+ boost::bind(&LLViewerControlListener::set, &gSavedSettings, _1));
+ add("PerAccount",
+ "Set gSavedPerAccountSettings control [\"key\"] to value [\"value\"]",
+ boost::bind(&LLViewerControlListener::set, &gSavedPerAccountSettings, _1));
+ add("Warning",
+ "Set gWarningSettings control [\"key\"] to value [\"value\"]",
+ boost::bind(&LLViewerControlListener::set, &gWarningSettings, _1));
+ add("Crash",
+ "Set gCrashSettings control [\"key\"] to value [\"value\"]",
+ boost::bind(&LLViewerControlListener::set, &gCrashSettings, _1));
#if 0
add(/*"toggleControl",*/ "Global", boost::bind(&LLViewerControlListener::toggleControl, &gSavedSettings, _1));
diff --git a/indra/newview/llviewercontrollistener.h b/indra/newview/llviewercontrollistener.h
index cacf97e908..88afbb871d 100644
--- a/indra/newview/llviewercontrollistener.h
+++ b/indra/newview/llviewercontrollistener.h
@@ -12,12 +12,12 @@
#ifndef LL_LLVIEWERCONTROLLISTENER_H
#define LL_LLVIEWERCONTROLLISTENER_H
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
class LLControlGroup;
class LLSD;
-class LLViewerControlListener : public LLDispatchListener
+class LLViewerControlListener : public LLEventAPI
{
public:
LLViewerControlListener();
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index edbac69e1b..7772f613f0 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -112,6 +112,7 @@
#include "llinspectavatar.h"
#include "llinspectgroup.h"
#include "llinspectobject.h"
+#include "llinspectremoteobject.h"
#include "llmediaremotectrl.h"
#include "llmoveview.h"
#include "llnearbychat.h"
@@ -176,6 +177,7 @@ void LLViewerFloaterReg::registerFloaters()
LLInspectAvatarUtil::registerFloater();
LLInspectGroupUtil::registerFloater();
LLInspectObjectUtil::registerFloater();
+ LLInspectRemoteObjectUtil::registerFloater();
LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>);
LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);
@@ -195,7 +197,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationConsole>);
LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>);
-
+ LLFloaterReg::add("outgoing_call", "floater_outgoing_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLOutgoingCallDialog>);
LLFloaterReg::add("parcel_info", "floater_preview_url.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterParcelInfo>);
LLFloaterPayUtil::registerFloater();
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 605861f1cb..493457704b 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -295,11 +295,21 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s
}
}
- if(media_impl && needs_navigate)
+ if(media_impl)
{
std::string url = media_entry->getCurrentURL();
-
- media_impl->navigateTo(url, "", true, true);
+ if(needs_navigate)
+ {
+ media_impl->navigateTo(url, "", true, true);
+ }
+ else if(!media_impl->mMediaURL.empty() && (media_impl->mMediaURL != url))
+ {
+ // If we already have a non-empty media URL set and we aren't doing a navigate, update the media URL to match the media entry.
+ media_impl->mMediaURL = url;
+
+ // If this causes a navigate at some point (such as after a reload), it should be considered server-driven so it isn't broadcast.
+ media_impl->mNavigateServerRequest = true;
+ }
}
return media_impl;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 820f709ba5..728fb7c616 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -415,7 +415,7 @@ public:
static LLMenuParcelObserver* gMenuParcelObserver = NULL;
-static LLUIListener sUIListener("UI");
+static LLUIListener sUIListener;
LLMenuParcelObserver::LLMenuParcelObserver()
{
@@ -1879,7 +1879,9 @@ class LLAdvancedDebugAvatarTextures : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
+#ifndef LL_RELEASE_FOR_DOWNLOAD
handle_debug_avatar_textures(NULL);
+#endif
return true;
}
};
@@ -1893,7 +1895,9 @@ class LLAdvancedDumpAvatarLocalTextures : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
+#ifndef LL_RELEASE_FOR_DOWNLOAD
handle_dump_avatar_local_textures(NULL);
+#endif
return true;
}
};
@@ -7860,10 +7864,8 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedCheckDebugCharacterVis(), "Advanced.CheckDebugCharacterVis");
view_listener_t::addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments");
view_listener_t::addMenu(new LLAdvancedRebakeTextures(), "Advanced.RebakeTextures");
- #ifndef LL_RELEASE_FOR_DOWNLOAD
view_listener_t::addMenu(new LLAdvancedDebugAvatarTextures(), "Advanced.DebugAvatarTextures");
view_listener_t::addMenu(new LLAdvancedDumpAvatarLocalTextures(), "Advanced.DumpAvatarLocalTextures");
- #endif
// Advanced > Network
view_listener_t::addMenu(new LLAdvancedEnableMessageLog(), "Advanced.EnableMessageLog");
view_listener_t::addMenu(new LLAdvancedDisableMessageLog(), "Advanced.DisableMessageLog");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index a90790c59a..4088eafe16 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1431,6 +1431,17 @@ bool goto_url_callback(const LLSD& notification, const LLSD& response)
}
static LLNotificationFunctorRegistration goto_url_callback_reg("GotoURL", goto_url_callback);
+bool inspect_remote_object_callback(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ LLFloaterReg::showInstance("inspect_remote_object", notification["payload"]);
+ }
+ return false;
+}
+static LLNotificationFunctorRegistration inspect_remote_object_callback_reg("ServerObjectMessage", inspect_remote_object_callback);
+
void process_improved_im(LLMessageSystem *msg, void **user_data)
{
if (gNoRender)
@@ -1498,15 +1509,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
}
std::string separator_string(": ");
- int message_offset = 0;
-
- //Handle IRC styled /me messages.
- std::string prefix = message.substr(0, 4);
- if (prefix == "/me " || prefix == "/me'")
- {
- separator_string = "";
- message_offset = 3;
- }
LLSD args;
switch(dialog)
@@ -1558,7 +1560,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
// now store incoming IM in chat history
- buffer = message.substr(message_offset);
+ buffer = message;
LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
@@ -1576,7 +1578,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
true);
// pretend this is chat generated by self, so it does not show up on screen
- chat.mText = std::string("IM: ") + name + separator_string + message.substr(message_offset);
+ chat.mText = std::string("IM: ") + name + separator_string + message;
LLFloaterChat::addChat( chat, TRUE, TRUE );
}
else if (from_id.isNull())
@@ -1596,7 +1598,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
// Treat like a system message and put in chat history.
// Claim to be from a local agent so it doesn't go into
// console.
- chat.mText = name + separator_string + message.substr(message_offset);
+ chat.mText = name + separator_string + message;
LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
if(nearby_chat)
@@ -1612,7 +1614,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
{
saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
}
- buffer = saved + message.substr(message_offset);
+ buffer = saved + message;
LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
@@ -1634,7 +1636,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
region_id,
position,
true);
- chat.mText = std::string("IM: ") + name + separator_string + saved + message.substr(message_offset);
+ chat.mText = std::string("IM: ") + name + separator_string + saved + message;
BOOL local_agent = FALSE;
LLFloaterChat::addChat( chat, TRUE, local_agent );
@@ -1922,7 +1924,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
{
saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
}
- buffer = saved + message.substr(message_offset);
+ buffer = saved + message;
BOOL is_this_agent = FALSE;
if(from_id == gAgentID)
{
@@ -1940,7 +1942,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
position,
true);
- chat.mText = std::string("IM: ") + name + separator_string + saved + message.substr(message_offset);
+ chat.mText = std::string("IM: ") + name + separator_string + saved + message;
LLFloaterChat::addChat(chat, TRUE, is_this_agent);
}
break;
@@ -1952,9 +1954,23 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
return;
}
+ // Build a link to open the object IM info window.
+ std::string location = ll_safe_string((char*)binary_bucket, binary_bucket_size-1);
+
LLSD substitutions;
- substitutions["MSG"] = message.substr(message_offset);
- LLNotifications::instance().add("ServerObjectMessage", substitutions);
+ substitutions["NAME"] = name;
+ substitutions["MSG"] = message;
+
+ LLSD payload;
+ payload["object_id"] = session_id;
+ payload["owner_id"] = from_id;
+ payload["slurl"] = location;
+ payload["name"] = name;
+ if (from_group)
+ {
+ payload["groupowned"] = "true";
+ }
+ LLNotifications::instance().add("ServerObjectMessage", substitutions, payload);
}
break;
case IM_FROM_TASK_AS_ALERT:
@@ -1978,7 +1994,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
else
{
// TODO: after LLTrans hits release, get "busy response" into translatable file
- buffer = llformat("%s (%s): %s", name.c_str(), "busy response", message.substr(message_offset).c_str());
+ buffer = llformat("%s (%s): %s", name.c_str(), "busy response", message.c_str());
gIMMgr->addMessage(session_id, from_id, name, buffer);
}
break;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 6b0f8814b9..1054223dcf 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1212,7 +1212,7 @@ LLViewerWindow::LLViewerWindow(
mStatesDirty(false),
mIsFullscreenChecked(false),
mCurrResolutionIndex(0),
- mViewerWindowListener(new LLViewerWindowListener("LLViewerWindow", this))
+ mViewerWindowListener(new LLViewerWindowListener(this))
{
LLNotificationChannel::buildChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
LLNotificationChannel::buildChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
@@ -2302,13 +2302,13 @@ void LLViewerWindow::moveCursorToCenter()
// Hover handlers
//
-void append_xui_tooltip(LLView* viewp, std::string& tool_tip_msg)
+void append_xui_tooltip(LLView* viewp, LLToolTip::Params& params)
{
if (viewp)
{
- if (!tool_tip_msg.empty())
+ if (!params.styled_message().empty())
{
- tool_tip_msg.append("\n---------\n");
+ params.styled_message.add().text("\n---------\n");
}
LLView::root_to_view_iterator_t end_tooltip_it = viewp->endRootToView();
// NOTE: we skip "root" since it is assumed
@@ -2318,15 +2318,16 @@ void append_xui_tooltip(LLView* viewp, std::string& tool_tip_msg)
{
LLView* viewp = *tooltip_it;
- tool_tip_msg.append(viewp->getName());
+ params.styled_message.add().text(viewp->getName());
+
LLPanel* panelp = dynamic_cast<LLPanel*>(viewp);
if (panelp && !panelp->getXMLFilename().empty())
{
- tool_tip_msg.append("(");
- tool_tip_msg.append(panelp->getXMLFilename());
- tool_tip_msg.append(")");
+ params.styled_message.add()
+ .text("(" + panelp->getXMLFilename() + ")")
+ .style.color(LLColor4(0.7f, 0.7f, 1.f, 1.f));
}
- tool_tip_msg.append("/");
+ params.styled_message.add().text("/");
}
}
}
@@ -2567,6 +2568,8 @@ void LLViewerWindow::updateUI()
if (gSavedSettings.getBOOL("DebugShowXUINames"))
{
+ LLToolTip::Params params;
+
LLView* tooltip_view = mRootView;
LLView::tree_iterator_t end_it = mRootView->endTreeDFS();
for (LLView::tree_iterator_t it = mRootView->beginTreeDFS(); it != end_it; ++it)
@@ -2599,20 +2602,20 @@ void LLViewerWindow::updateUI()
// NOTE: this emulates visiting only the leaf nodes that meet our criteria
if (!viewp->hasAncestor(tooltip_view))
{
- append_xui_tooltip(tooltip_view, tool_tip_msg);
+ append_xui_tooltip(tooltip_view, params);
screen_sticky_rect.intersectWith(tooltip_view->calcScreenRect());
}
tooltip_view = viewp;
}
}
- append_xui_tooltip(tooltip_view, tool_tip_msg);
+ append_xui_tooltip(tooltip_view, params);
screen_sticky_rect.intersectWith(tooltip_view->calcScreenRect());
- LLToolTipMgr::instance().show(LLToolTip::Params()
- .message(tool_tip_msg)
- .sticky_rect(screen_sticky_rect)
- .max_width(400));
+ params.sticky_rect = screen_sticky_rect;
+ params.max_width = 400;
+
+ LLToolTipMgr::instance().show(params);
}
// if there is a mouse captor, nothing else gets a tooltip
else if (mouse_captor)
diff --git a/indra/newview/llviewerwindowlistener.cpp b/indra/newview/llviewerwindowlistener.cpp
index a890b042ae..de57788271 100644
--- a/indra/newview/llviewerwindowlistener.cpp
+++ b/indra/newview/llviewerwindowlistener.cpp
@@ -20,8 +20,9 @@
// other Linden headers
#include "llviewerwindow.h"
-LLViewerWindowListener::LLViewerWindowListener(const std::string& pumpname, LLViewerWindow* llviewerwindow):
- LLDispatchListener(pumpname, "op"),
+LLViewerWindowListener::LLViewerWindowListener(LLViewerWindow* llviewerwindow):
+ LLEventAPI("LLViewerWindow",
+ "LLViewerWindow listener to (e.g.) save a screenshot"),
mViewerWindow(llviewerwindow)
{
// add() every method we want to be able to invoke via this event API.
@@ -34,8 +35,15 @@ LLViewerWindowListener::LLViewerWindowListener(const std::string& pumpname, LLVi
// saveSnapshotArgs["showui"] = LLSD::Boolean();
// saveSnapshotArgs["rebuild"] = LLSD::Boolean();
// saveSnapshotArgs["type"] = LLSD::String();
- add("saveSnapshot", &LLViewerWindowListener::saveSnapshot, saveSnapshotArgs);
- add("requestReshape", &LLViewerWindowListener::requestReshape);
+ add("saveSnapshot",
+ "Save screenshot: [\"filename\"], [\"width\"], [\"height\"], [\"showui\"], [\"rebuild\"], [\"type\"]\n"
+ "type: \"COLOR\", \"DEPTH\", \"OBJECT_ID\"\n"
+ "Post on [\"reply\"] an event containing [\"ok\"]",
+ &LLViewerWindowListener::saveSnapshot,
+ saveSnapshotArgs);
+ add("requestReshape",
+ "Resize the window: [\"w\"], [\"h\"]",
+ &LLViewerWindowListener::requestReshape);
}
void LLViewerWindowListener::saveSnapshot(const LLSD& event) const
diff --git a/indra/newview/llviewerwindowlistener.h b/indra/newview/llviewerwindowlistener.h
index 59c636ecec..699f7907af 100644
--- a/indra/newview/llviewerwindowlistener.h
+++ b/indra/newview/llviewerwindowlistener.h
@@ -12,18 +12,17 @@
#if ! defined(LL_LLVIEWERWINDOWLISTENER_H)
#define LL_LLVIEWERWINDOWLISTENER_H
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
class LLViewerWindow;
class LLSD;
/// Listen on an LLEventPump with specified name for LLViewerWindow request events.
-class LLViewerWindowListener: public LLDispatchListener
+class LLViewerWindowListener: public LLEventAPI
{
public:
- /// Specify the pump name on which to listen, and bind the LLViewerWindow
- /// instance to use (e.g. gViewerWindow).
- LLViewerWindowListener(const std::string& pumpname, LLViewerWindow* llviewerwindow);
+ /// Bind the LLViewerWindow instance to use (e.g. gViewerWindow).
+ LLViewerWindowListener(LLViewerWindow* llviewerwindow);
private:
void saveSnapshot(const LLSD& event) const;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 16bd74f798..62ac8adad0 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -647,7 +647,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mWindFreq(0.f),
mRipplePhase( 0.f ),
mBelowWater(FALSE),
- mAppearanceAnimSetByUser(FALSE),
mLastAppearanceBlendTime(0.f),
mAppearanceAnimating(FALSE),
mNameString(),
@@ -2436,7 +2435,7 @@ void LLVOAvatar::idleUpdateAppearanceAnimation()
{
if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
{
- param->stopAnimating(mAppearanceAnimSetByUser);
+ param->stopAnimating(FALSE);
}
}
updateVisualParams();
@@ -2459,7 +2458,7 @@ void LLVOAvatar::idleUpdateAppearanceAnimation()
{
if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
{
- param->animate(morph_amt, mAppearanceAnimSetByUser);
+ param->animate(morph_amt, FALSE);
}
}
}
@@ -5372,11 +5371,11 @@ void LLVOAvatar::updateShadowFaces()
//-----------------------------------------------------------------------------
// updateSexDependentLayerSets()
//-----------------------------------------------------------------------------
-void LLVOAvatar::updateSexDependentLayerSets( BOOL set_by_user )
+void LLVOAvatar::updateSexDependentLayerSets( BOOL upload_bake )
{
- invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet, set_by_user );
- invalidateComposite( mBakedTextureDatas[BAKED_UPPER].mTexLayerSet, set_by_user );
- invalidateComposite( mBakedTextureDatas[BAKED_LOWER].mTexLayerSet, set_by_user );
+ invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet, upload_bake );
+ invalidateComposite( mBakedTextureDatas[BAKED_UPPER].mTexLayerSet, upload_bake );
+ invalidateComposite( mBakedTextureDatas[BAKED_LOWER].mTexLayerSet, upload_bake );
}
//-----------------------------------------------------------------------------
@@ -5741,7 +5740,7 @@ LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name ) const
}
// virtual
-void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL set_by_user )
+void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result )
{
}
@@ -5754,18 +5753,18 @@ void LLVOAvatar::setCompositeUpdatesEnabled( BOOL b )
{
}
-void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL set_by_user )
+void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake )
{
if (global_color == mTexSkinColor)
{
- invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet, set_by_user );
- invalidateComposite( mBakedTextureDatas[BAKED_UPPER].mTexLayerSet, set_by_user );
- invalidateComposite( mBakedTextureDatas[BAKED_LOWER].mTexLayerSet, set_by_user );
+ invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet, upload_bake );
+ invalidateComposite( mBakedTextureDatas[BAKED_UPPER].mTexLayerSet, upload_bake );
+ invalidateComposite( mBakedTextureDatas[BAKED_LOWER].mTexLayerSet, upload_bake );
}
else if (global_color == mTexHairColor)
{
- invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet, set_by_user );
- invalidateComposite( mBakedTextureDatas[BAKED_HAIR].mTexLayerSet, set_by_user );
+ invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet, upload_bake );
+ invalidateComposite( mBakedTextureDatas[BAKED_HAIR].mTexLayerSet, upload_bake );
// ! BACKWARDS COMPATIBILITY !
// Fix for dealing with avatars from viewers that don't bake hair.
@@ -5781,7 +5780,7 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL
else if (global_color == mTexEyeColor)
{
// llinfos << "invalidateComposite cause: onGlobalColorChanged( eyecolor )" << llendl;
- invalidateComposite( mBakedTextureDatas[BAKED_EYES].mTexLayerSet, set_by_user );
+ invalidateComposite( mBakedTextureDatas[BAKED_EYES].mTexLayerSet, upload_bake );
}
updateMeshTextures();
}
@@ -6239,14 +6238,14 @@ BOOL LLVOAvatar::teToColorParams( ETextureIndex te, U32 *param_name )
return TRUE;
}
-void LLVOAvatar::setClothesColor( ETextureIndex te, const LLColor4& new_color, BOOL set_by_user )
+void LLVOAvatar::setClothesColor( ETextureIndex te, const LLColor4& new_color, BOOL upload_bake )
{
U32 param_name[3];
if( teToColorParams( te, param_name ) )
{
- setVisualParamWeight( param_name[0], new_color.mV[VX], set_by_user );
- setVisualParamWeight( param_name[1], new_color.mV[VY], set_by_user );
- setVisualParamWeight( param_name[2], new_color.mV[VZ], set_by_user );
+ setVisualParamWeight( param_name[0], new_color.mV[VX], upload_bake );
+ setVisualParamWeight( param_name[1], new_color.mV[VY], upload_bake );
+ setVisualParamWeight( param_name[2], new_color.mV[VZ], upload_bake );
}
}
@@ -6592,7 +6591,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
{
if (interp_params)
{
- startAppearanceAnimation(FALSE, FALSE);
+ startAppearanceAnimation();
}
updateVisualParams();
@@ -6977,11 +6976,10 @@ void LLVOAvatar::cullAvatarsByPixelArea()
}
}
-void LLVOAvatar::startAppearanceAnimation(BOOL set_by_user, BOOL play_sound)
+void LLVOAvatar::startAppearanceAnimation()
{
if(!mAppearanceAnimating)
{
- mAppearanceAnimSetByUser = set_by_user;
mAppearanceAnimating = TRUE;
mAppearanceMorphTimer.reset();
mLastAppearanceBlendTime = 0.f;
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 173ad02808..2fd1a506a9 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -522,7 +522,7 @@ protected:
// Composites
//--------------------------------------------------------------------
public:
- virtual void invalidateComposite(LLTexLayerSet* layerset, BOOL set_by_user);
+ virtual void invalidateComposite(LLTexLayerSet* layerset, BOOL upload_result);
virtual void invalidateAll();
virtual void setCompositeUpdatesEnabled(BOOL b);
@@ -558,7 +558,7 @@ private:
public:
void updateMeshTextures();
- void updateSexDependentLayerSets(BOOL set_by_user);
+ void updateSexDependentLayerSets(BOOL upload_bake);
void dirtyMesh(); // Dirty the avatar mesh
void updateMeshData();
protected:
@@ -591,7 +591,7 @@ protected:
public:
void processAvatarAppearance(LLMessageSystem* mesgsys);
void hideSkirt();
- void startAppearanceAnimation(BOOL set_by_user, BOOL play_sound);
+ void startAppearanceAnimation();
//--------------------------------------------------------------------
// Appearance morphing
@@ -600,14 +600,13 @@ public:
BOOL mAppearanceAnimating;
private:
LLFrameTimer mAppearanceMorphTimer;
- BOOL mAppearanceAnimSetByUser;
F32 mLastAppearanceBlendTime;
//--------------------------------------------------------------------
// Clothing colors (convenience functions to access visual parameters)
//--------------------------------------------------------------------
public:
- void setClothesColor(LLVOAvatarDefines::ETextureIndex te, const LLColor4& new_color, BOOL set_by_user);
+ void setClothesColor(LLVOAvatarDefines::ETextureIndex te, const LLColor4& new_color, BOOL upload_bake);
LLColor4 getClothesColor(LLVOAvatarDefines::ETextureIndex te);
static BOOL teToColorParams(LLVOAvatarDefines::ETextureIndex te, U32 *param_name);
@@ -616,7 +615,7 @@ public:
//--------------------------------------------------------------------
public:
LLColor4 getGlobalColor(const std::string& color_name ) const;
- void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL set_by_user);
+ void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake);
private:
LLTexGlobalColor* mTexSkinColor;
LLTexGlobalColor* mTexHairColor;
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index a2203ba2ea..185274d40d 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -633,33 +633,33 @@ LLJoint *LLVOAvatarSelf::getJoint(const std::string &name)
return LLVOAvatar::getJoint(name);
}
-/*virtual*/ BOOL LLVOAvatarSelf::setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL set_by_user )
+/*virtual*/ BOOL LLVOAvatarSelf::setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake )
{
if (!which_param)
{
return FALSE;
}
LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(which_param->getID());
- return setParamWeight(param,weight,set_by_user);
+ return setParamWeight(param,weight,upload_bake);
}
-/*virtual*/ BOOL LLVOAvatarSelf::setVisualParamWeight(const char* param_name, F32 weight, BOOL set_by_user )
+/*virtual*/ BOOL LLVOAvatarSelf::setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake )
{
if (!param_name)
{
return FALSE;
}
LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(param_name);
- return setParamWeight(param,weight,set_by_user);
+ return setParamWeight(param,weight,upload_bake);
}
-/*virtual*/ BOOL LLVOAvatarSelf::setVisualParamWeight(S32 index, F32 weight, BOOL set_by_user )
+/*virtual*/ BOOL LLVOAvatarSelf::setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake )
{
LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(index);
- return setParamWeight(param,weight,set_by_user);
+ return setParamWeight(param,weight,upload_bake);
}
-BOOL LLVOAvatarSelf::setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL set_by_user )
+BOOL LLVOAvatarSelf::setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake )
{
if (!param)
{
@@ -675,12 +675,12 @@ BOOL LLVOAvatarSelf::setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL
LLWearable *wearable = gAgentWearables.getWearable(type,count);
if (wearable)
{
- wearable->setVisualParamWeight(param->getID(), weight, set_by_user);
+ wearable->setVisualParamWeight(param->getID(), weight, upload_bake);
}
}
}
- return LLCharacter::setVisualParamWeight(param,weight,set_by_user);
+ return LLCharacter::setVisualParamWeight(param,weight,upload_bake);
}
/*virtual*/
@@ -691,7 +691,7 @@ void LLVOAvatarSelf::updateVisualParams()
LLWearable *wearable = gAgentWearables.getTopWearable((EWearableType)type);
if (wearable)
{
- wearable->writeToAvatar(FALSE, FALSE);
+ wearable->writeToAvatar();
}
}
@@ -702,7 +702,7 @@ void LLVOAvatarSelf::updateVisualParams()
void LLVOAvatarSelf::idleUpdateAppearanceAnimation()
{
// Animate all top-level wearable visual parameters
- gAgentWearables.animateAllWearableParams(calcMorphAmount(), mAppearanceAnimSetByUser);
+ gAgentWearables.animateAllWearableParams(calcMorphAmount(), FALSE);
// apply wearable visual params to avatar
updateVisualParams();
@@ -737,8 +737,7 @@ void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id)
}
}
-// virtual
-void LLVOAvatarSelf::setLocalTextureTE(U8 te, LLViewerTexture* image, BOOL set_by_user, U32 index)
+void LLVOAvatarSelf::setLocalTextureTE(U8 te, LLViewerTexture* image, U32 index)
{
if (te >= TEX_NUM_INDICES)
{
@@ -1347,7 +1346,7 @@ bool LLVOAvatarSelf::hasPendingBakedUploads() const
return false;
}
-void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset, BOOL set_by_user )
+void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result )
{
if( !layerset || !layerset->getUpdatesEnabled() )
{
@@ -1358,7 +1357,7 @@ void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset, BOOL set_by_u
layerset->requestUpdate();
layerset->invalidateMorphMasks();
- if( set_by_user )
+ if( upload_result )
{
llassert(isSelf());
@@ -1945,9 +1944,7 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**)
if (layer_set)
{
llinfos << "TAT: rebake - matched entry " << (S32)index << llendl;
- // Apparently set_by_user == force upload
- BOOL set_by_user = TRUE;
- self->invalidateComposite(layer_set, set_by_user);
+ self->invalidateComposite(layer_set, TRUE);
found = TRUE;
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES);
}
@@ -1983,8 +1980,7 @@ void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug)
layer_set->cancelUpload();
}
- BOOL set_by_user = TRUE;
- invalidateComposite(layer_set, set_by_user);
+ invalidateComposite(layer_set, TRUE);
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES);
}
else
@@ -2047,7 +2043,6 @@ void LLVOAvatarSelf::onCustomizeEnd()
if (avatarp)
{
avatarp->invalidateAll();
- avatarp->requestLayerSetUploads();
}
}
@@ -2084,7 +2079,6 @@ void LLVOAvatarSelf::setInvisible(BOOL newvalue)
{
setCompositeUpdatesEnabled(TRUE);
invalidateAll();
- requestLayerSetUploads();
gAgent.sendAgentSetAppearance();
}
}
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 8a66422c44..6702f030fe 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -86,15 +86,15 @@ public:
/*virtual*/ void requestStopMotion(LLMotion* motion);
/*virtual*/ LLJoint* getJoint(const std::string &name);
- /*virtual*/ BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL set_by_user = FALSE );
- /*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL set_by_user = FALSE );
- /*virtual*/ BOOL setVisualParamWeight(S32 index, F32 weight, BOOL set_by_user = FALSE );
+ /*virtual*/ BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
+ /*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE );
+ /*virtual*/ BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE );
/*virtual*/ void updateVisualParams();
/*virtual*/ void idleUpdateAppearanceAnimation();
private:
// helper function. Passed in param is assumed to be in avatar's parameter list.
- BOOL setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL set_by_user = FALSE );
+ BOOL setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE );
/** Initialization
@@ -186,7 +186,7 @@ public:
BOOL getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture** image_gl_pp, U32 index) const;
LLViewerFetchedTexture* getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
const LLUUID& getLocalTextureID(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
- void setLocalTextureTE(U8 te, LLViewerTexture* image, BOOL set_by_user, U32 index);
+ void setLocalTextureTE(U8 te, LLViewerTexture* image, U32 index);
const LLUUID& grabLocalTexture(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
BOOL canGrabLocalTexture(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
/*virtual*/ void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index);
@@ -228,7 +228,7 @@ public:
// Composites
//--------------------------------------------------------------------
public:
- /* virtual */ void invalidateComposite(LLTexLayerSet* layerset, BOOL set_by_user);
+ /* virtual */ void invalidateComposite(LLTexLayerSet* layerset, BOOL upload_result);
/* virtual */ void invalidateAll();
/* virtual */ void setCompositeUpdatesEnabled(BOOL b); // only works for self
void setupComposites();
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index cefc88ebee..d93913b944 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -46,6 +46,7 @@ LLVoiceChannel::voice_channel_map_t LLVoiceChannel::sVoiceChannelMap;
LLVoiceChannel::voice_channel_map_uri_t LLVoiceChannel::sVoiceChannelURIMap;
LLVoiceChannel* LLVoiceChannel::sCurrentVoiceChannel = NULL;
LLVoiceChannel* LLVoiceChannel::sSuspendedVoiceChannel = NULL;
+LLVoiceChannel::channel_changed_signal_t LLVoiceChannel::sCurrentVoiceChannelChangedSignal;
BOOL LLVoiceChannel::sSuspended = FALSE;
@@ -305,8 +306,10 @@ void LLVoiceChannel::activate()
// activating the proximal channel between IM calls
LLVoiceChannel* old_channel = sCurrentVoiceChannel;
sCurrentVoiceChannel = this;
+ mCallDialogPayload["old_channel_name"] = "";
if (old_channel)
{
+ mCallDialogPayload["old_channel_name"] = old_channel->getSessionName();
old_channel->deactivate();
}
}
@@ -320,6 +323,8 @@ void LLVoiceChannel::activate()
{
setState(STATE_CALL_STARTED);
}
+
+ sCurrentVoiceChannelChangedSignal(this->mSessionID);
}
void LLVoiceChannel::getChannelInfo()
@@ -867,6 +872,19 @@ void LLVoiceChannelP2P::setState(EState state)
{
// HACK: Open/close the call window if needed.
toggleCallWindowIfNeeded(state);
+
+ // *HACK: open outgoing call floater if needed, might be better done elsewhere.
+ mCallDialogPayload["session_id"] = mSessionID;
+ mCallDialogPayload["session_name"] = mSessionName;
+ mCallDialogPayload["other_user_id"] = mOtherUserID;
+ if (!mReceivedCall && state == STATE_RINGING)
+ {
+ llinfos << "RINGINGGGGGGGG " << mSessionName << llendl;
+ if (!mSessionName.empty())
+ {
+ LLFloaterReg::showInstance("outgoing_call", mCallDialogPayload, TRUE);
+ }
+ }
// you only "answer" voice invites in p2p mode
// so provide a special purpose message here
diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h
index 8f1e9ff02d..639585de55 100644
--- a/indra/newview/llvoicechannel.h
+++ b/indra/newview/llvoicechannel.h
@@ -54,6 +54,13 @@ public:
typedef boost::function<void(const EState& old_state, const EState& new_state)> state_changed_callback_t;
+ // on current channel changed signal
+ typedef boost::function<void(const LLUUID& session_id)> channel_changed_callback_t;
+ typedef boost::signals2::signal<void(const LLUUID& session_id)> channel_changed_signal_t;
+ static channel_changed_signal_t sCurrentVoiceChannelChangedSignal;
+ static boost::signals2::connection setCurrentVoiceChannelChangedCallback(channel_changed_callback_t cb) { return sCurrentVoiceChannelChangedSignal.connect(cb); }
+
+
LLVoiceChannel(const LLUUID& session_id, const std::string& session_name);
virtual ~LLVoiceChannel();
@@ -102,6 +109,7 @@ protected:
EState mState;
std::string mSessionName;
LLSD mNotifyArgs;
+ LLSD mCallDialogPayload;
BOOL mIgnoreNextSessionLeave;
LLHandle<LLPanel> mLoginNotificationHandle;
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 39d4bb0c02..5fedfc943b 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -1598,7 +1598,7 @@ void LLVoiceClient::stateMachine()
}
else
{
- LL_WARNS("Voice") << "region doesn't have ParcelVoiceInfoRequest capability. This is normal for a short time after teleporting, but bad if it persists for very long." << LL_ENDL;
+ LL_WARNS_ONCE("Voice") << "region doesn't have ParcelVoiceInfoRequest capability. This is normal for a short time after teleporting, but bad if it persists for very long." << LL_ENDL;
}
}
}
@@ -4273,7 +4273,7 @@ void LLVoiceClient::mediaStreamUpdatedEvent(
if(incoming)
{
// Send the voice chat invite to the GUI layer
- // TODO: Question: Should we correlate with the mute list here?
+ // *TODO: Question: Should we correlate with the mute list here?
session->mIMSessionID = LLIMMgr::computeSessionID(IM_SESSION_P2P_INVITE, session->mCallerID);
session->mVoiceInvitePending = true;
if(session->mName.empty())
diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp
index 3185ee45bf..c5c97e7649 100644
--- a/indra/newview/llwearable.cpp
+++ b/indra/newview/llwearable.cpp
@@ -602,7 +602,7 @@ void LLWearable::setTexturesToDefaults()
}
// Updates the user's avatar's appearance
-void LLWearable::writeToAvatar( BOOL set_by_user, BOOL update_customize_floater )
+void LLWearable::writeToAvatar()
{
LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
llassert( avatar );
@@ -622,24 +622,10 @@ void LLWearable::writeToAvatar( BOOL set_by_user, BOOL update_customize_floater
S32 param_id = param->getID();
F32 weight = getVisualParamWeight(param_id);
- // only animate with user-originated changes
- if (set_by_user)
- {
- param->setAnimationTarget(weight, set_by_user);
- }
- else
- {
- avatar->setVisualParamWeight( param_id, weight, set_by_user );
- }
+ avatar->setVisualParamWeight( param_id, weight, FALSE );
}
}
- // only interpolate with user-originated changes
- if (set_by_user)
- {
- avatar->startAppearanceAnimation(TRUE, TRUE);
- }
-
// Pull texture entries
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
@@ -657,24 +643,17 @@ void LLWearable::writeToAvatar( BOOL set_by_user, BOOL update_customize_floater
}
LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE );
// MULTI-WEARABLE: replace hard-coded 0
- avatar->setLocalTextureTE(te, image, set_by_user, 0);
+ avatar->setLocalTextureTE(te, image, 0);
}
}
-
- if( gFloaterCustomize && update_customize_floater )
- {
- gFloaterCustomize->setWearable(mType, 0);
- gFloaterCustomize->setCurrentWearableType( mType );
- }
-
ESex new_sex = avatar->getSex();
if( old_sex != new_sex )
{
- avatar->updateSexDependentLayerSets( set_by_user );
+ avatar->updateSexDependentLayerSets( FALSE );
}
-// if( set_by_user )
+// if( upload_bake )
// {
// gAgent.sendAgentSetAppearance();
// }
@@ -683,7 +662,7 @@ void LLWearable::writeToAvatar( BOOL set_by_user, BOOL update_customize_floater
// Updates the user's avatar's appearance, replacing this wearables' parameters and textures with default values.
// static
-void LLWearable::removeFromAvatar( EWearableType type, BOOL set_by_user )
+void LLWearable::removeFromAvatar( EWearableType type, BOOL upload_bake )
{
LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
llassert( avatar );
@@ -707,7 +686,7 @@ void LLWearable::removeFromAvatar( EWearableType type, BOOL set_by_user )
if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) )
{
S32 param_id = param->getID();
- avatar->setVisualParamWeight( param_id, param->getDefaultWeight(), set_by_user );
+ avatar->setVisualParamWeight( param_id, param->getDefaultWeight(), upload_bake );
}
}
@@ -719,7 +698,7 @@ void LLWearable::removeFromAvatar( EWearableType type, BOOL set_by_user )
avatar->updateVisualParams();
avatar->wearableUpdated(type);
-// if( set_by_user )
+// if( upload_bake )
// {
// gAgent.sendAgentSetAppearance();
// }
@@ -868,12 +847,12 @@ void LLWearable::setVisualParams()
}
-void LLWearable::setVisualParamWeight(S32 param_index, F32 value, BOOL set_by_user)
+void LLWearable::setVisualParamWeight(S32 param_index, F32 value, BOOL upload_bake)
{
if( is_in_map(mVisualParamIndexMap, param_index ) )
{
LLVisualParam *wearable_param = mVisualParamIndexMap[param_index];
- wearable_param->setWeight(value, set_by_user);
+ wearable_param->setWeight(value, upload_bake);
}
else
{
@@ -914,14 +893,14 @@ void LLWearable::getVisualParams(visual_param_vec_t &list)
}
}
-void LLWearable::animateParams(F32 delta, BOOL set_by_user)
+void LLWearable::animateParams(F32 delta, BOOL upload_bake)
{
for(visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
iter != mVisualParamIndexMap.end();
++iter)
{
LLVisualParam *param = (LLVisualParam*) iter->second;
- param->animate(delta, set_by_user);
+ param->animate(delta, upload_bake);
}
}
@@ -939,14 +918,14 @@ LLColor4 LLWearable::getClothesColor(S32 te) const
return color;
}
-void LLWearable::setClothesColor( S32 te, const LLColor4& new_color, BOOL set_by_user )
+void LLWearable::setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake )
{
U32 param_name[3];
if( LLVOAvatar::teToColorParams( (LLVOAvatarDefines::ETextureIndex)te, param_name ) )
{
for( U8 index = 0; index < 3; index++ )
{
- setVisualParamWeight(param_name[index], new_color.mV[index], set_by_user);
+ setVisualParamWeight(param_name[index], new_color.mV[index], upload_bake);
}
}
}
diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h
index 96631811c5..fd19a86406 100644
--- a/indra/newview/llwearable.h
+++ b/indra/newview/llwearable.h
@@ -89,9 +89,9 @@ public:
BOOL isDirty() const;
BOOL isOldVersion() const;
- void writeToAvatar( BOOL set_by_user, BOOL update_customize_floater = TRUE );
- void removeFromAvatar( BOOL set_by_user ) { LLWearable::removeFromAvatar( mType, set_by_user ); }
- static void removeFromAvatar( EWearableType type, BOOL set_by_user );
+ void writeToAvatar();
+ void removeFromAvatar( BOOL upload_bake ) { LLWearable::removeFromAvatar( mType, upload_bake ); }
+ static void removeFromAvatar( EWearableType type, BOOL upload_bake );
BOOL exportFile(LLFILE* file) const;
BOOL importFile(LLFILE* file);
@@ -115,14 +115,14 @@ public:
void setLocalTextureObject(S32 index, LLLocalTextureObject *lto);
void addVisualParam(LLVisualParam *param);
void setVisualParams();
- void setVisualParamWeight(S32 index, F32 value, BOOL set_by_user);
+ void setVisualParamWeight(S32 index, F32 value, BOOL upload_bake);
F32 getVisualParamWeight(S32 index) const;
LLVisualParam* getVisualParam(S32 index) const;
void getVisualParams(visual_param_vec_t &list);
- void animateParams(F32 delta, BOOL set_by_user);
+ void animateParams(F32 delta, BOOL upload_bake);
LLColor4 getClothesColor(S32 te) const;
- void setClothesColor( S32 te, const LLColor4& new_color, BOOL set_by_user );
+ void setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake );
void revertValues();
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 1129e9ffd1..507c726e02 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -512,16 +512,18 @@ void LLPipeline::resizeScreenTexture()
LLFastTimer ft(FTM_RESIZE_SCREEN_TEXTURE);
if (gPipeline.canUseVertexShaders() && assertInitialized())
{
- GLuint resX = gViewerWindow->getWorldViewWidthRaw();
- GLuint resY = gViewerWindow->getWorldViewHeightRaw();
+ GLuint resX = gViewerWindow->getWindowWidthRaw();
+ GLuint resY = gViewerWindow->getWindowHeightRaw();
+ GLuint view_width = gViewerWindow->getWorldViewWidthRaw();
+ GLuint view_height = gViewerWindow->getWorldViewHeightRaw();
- allocateScreenBuffer(resX,resY);
+ allocateScreenBuffer(resX, resY, view_width, view_height);
llinfos << "RESIZED SCREEN TEXTURE: " << resX << "x" << resY << llendl;
}
}
-void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
+void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 viewport_width, U32 viewport_height)
{
U32 samples = gSavedSettings.getU32("RenderFSAASamples");
@@ -542,18 +544,24 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
//allocate deferred rendering color buffers
mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
+ mDeferredScreen.setViewport(viewport_width, viewport_height);
+ mDeferredDepth.setViewport(viewport_width, viewport_height);
addDeferredAttachments(mDeferredScreen);
mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
mEdgeMap.allocate(resX, resY, GL_ALPHA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
+ mScreen.setViewport(viewport_width, viewport_height);
+ mEdgeMap.setViewport(viewport_width, viewport_height);
for (U32 i = 0; i < 3; i++)
{
mDeferredLight[i].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
+ mDeferredLight[i].setViewport(viewport_width, viewport_height);
}
for (U32 i = 0; i < 2; i++)
{
mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
+ mGIMapPost[i].setViewport(viewport_width, viewport_height);
}
F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale");
@@ -561,6 +569,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
for (U32 i = 0; i < 4; i++)
{
mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
+ mShadow[i].setViewport(viewport_width, viewport_height);
}
@@ -570,6 +579,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
for (U32 i = 4; i < 6; i++)
{
mShadow[i].allocate(width, height, 0, TRUE, FALSE);
+ mShadow[i].setViewport(viewport_width, viewport_height);
}
@@ -577,16 +587,19 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
width = nhpo2(resX)/2;
height = nhpo2(resY)/2;
mLuminanceMap.allocate(width,height, GL_RGBA, FALSE, FALSE);
+ mLuminanceMap.setViewport(viewport_width, viewport_height);
}
else
{
mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
+ mScreen.setViewport(viewport_width, viewport_height);
}
if (gGLManager.mHasFramebufferMultisample && samples > 1)
{
mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples);
+ mSampleBuffer.setViewport(viewport_width, viewport_height);
mScreen.setSampleBuffer(&mSampleBuffer);
if (LLPipeline::sRenderDeferred)
@@ -698,8 +711,10 @@ void LLPipeline::createGLBuffers()
stop_glerror();
- GLuint resX = gViewerWindow->getWorldViewWidthRaw();
- GLuint resY = gViewerWindow->getWorldViewHeightRaw();
+ GLuint resX = gViewerWindow->getWindowWidthRaw();
+ GLuint resY = gViewerWindow->getWindowHeightRaw();
+ GLuint viewport_width = gViewerWindow->getWorldViewWidthRaw();
+ GLuint viewport_height = gViewerWindow->getWorldViewHeightRaw();
if (LLPipeline::sRenderGlow)
{ //screen space glow buffers
@@ -711,7 +726,7 @@ void LLPipeline::createGLBuffers()
mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE);
}
- allocateScreenBuffer(resX,resY);
+ allocateScreenBuffer(resX,resY, viewport_width, viewport_height);
}
if (sRenderDeferred)
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index ce50a37405..9193e19bb1 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -111,7 +111,7 @@ public:
void resizeScreenTexture();
void releaseGLBuffers();
void createGLBuffers();
- void allocateScreenBuffer(U32 resX, U32 resY);
+ void allocateScreenBuffer(U32 resX, U32 resY, U32 viewport_width, U32 viewport_height);
void resetVertexBuffers(LLDrawable* drawable);
void setUseVBO(BOOL use_vbo);
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 7e19a80c10..028a5844c6 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -513,7 +513,7 @@
reference="White" />
<color
name="ObjectChatColor"
- reference="LtGray" />
+ reference="0.7 0.8 0.9 1" />
<color
name="OverdrivenColor"
value="1 0 0 1" />
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 48c7236796..4c4b6a3899 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -38,6 +38,8 @@
<texture name="Blank" file_name="Blank.png" preload="false" />
<texture name="BottomTray_BG" file_name="bottomtray/BottomTray_BG.png" preload="false" />
+ <texture name="BottomTray_Scroll_Right" file_name="navbar/Arrow_Right_Off.png" preload="false" />
+ <texture name="BottomTray_Scroll_Left" file_name="navbar/Arrow_Left_Off.png" preload="false" />
<texture name="BuyArrow_Off" file_name="navbar/BuyArrow_Off.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" />
<texture name="BuyArrow_Over" file_name="navbar/BuyArrow_Over.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" />
@@ -529,6 +531,8 @@
<texture name="Toolbar_Right_Off" file_name="containers/Toolbar_Right_Off.png" preload="false" />
<texture name="Toolbar_Right_Press" file_name="containers/Toolbar_Right_Press.png" preload="false" />
<texture name="Toolbar_Right_Selected" file_name="containers/Toolbar_Right_Selected.png" preload="false" />
+
+ <texture name="Tooltip" file_name="widgets/Tooltip.png" preload="true" scale.left="2" scale.top="1" scale.right="99" scale.bottom="14" />
<texture name="TrashItem_Disabled" file_name="icons/TrashItem_Disabled.png" preload="false" />
<texture name="TrashItem_Off" file_name="icons/TrashItem_Off.png" preload="false" />
diff --git a/indra/newview/skins/default/textures/widgets/Tooltip.png b/indra/newview/skins/default/textures/widgets/Tooltip.png
new file mode 100644
index 0000000000..f989ac9083
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Tooltip.png
Binary files differ
diff --git a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml
index a0f9bb59fd..3a1499eaaa 100644
--- a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml
+++ b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml
@@ -16,7 +16,7 @@
</floater.string>
<floater.string
name="no_one_near">
- No-one near
+ No one near
</floater.string>
<floater.string
name="no_results">
diff --git a/indra/newview/skins/default/xui/en/floater_incoming_call.xml b/indra/newview/skins/default/xui/en/floater_incoming_call.xml
index 16873df310..9c2898945b 100644
--- a/indra/newview/skins/default/xui/en/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/en/floater_incoming_call.xml
@@ -4,13 +4,17 @@
can_close="false"
can_minimize="false"
can_tear_off="false"
- height="200"
+ height="125"
layout="topleft"
name="incoming call"
help_topic="incoming_call"
title="UNKNOWN PERSON IS CALLING"
- width="240">
- <floater.string
+ width="410">
+ <floater.string
+ name="localchat">
+ Local Voice Chat
+ </floater.string>
+ <floater.string
name="anonymous">
anonymous
</floater.string>
@@ -31,18 +35,26 @@
left_delta="19"
top="35"
width="36" />
- <text_editor
- font="SansSerif"
- height="64"
- border_visible="false"
+ <text
+ font="SansSerifLarge"
+ height="20"
layout="topleft"
left="77"
- max_length="2147483647"
name="caller name"
- read_only="true"
- top="21"
- width="163"
+ top="27"
+ width="315"
word_wrap="true" />
+ <text
+ font="SansSerif"
+ height="50"
+ layout="topleft"
+ left="77"
+ name="question"
+ top="52"
+ width="315"
+ word_wrap="true">
+ Do you want to leave [CURRENT_CHAT] and join this voice chat?
+ </text>
<button
height="24"
label="Accept"
@@ -57,16 +69,14 @@
label="Reject"
label_selected="Reject"
layout="topleft"
- left_delta="0"
name="Reject"
- top_pad="12"
+ left_pad="10"
width="100" />
<button
height="24"
label="Start IM"
layout="topleft"
- left_delta="0"
name="Start IM"
- top_pad="12"
+ left_pad="10"
width="100" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inventory.xml b/indra/newview/skins/default/xui/en/floater_inventory.xml
index 30639f955f..b48c962413 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory.xml
@@ -36,10 +36,10 @@
filename="panel_main_inventory.xml"
follows="all"
layout="topleft"
+ hide_top_panel="true"
left="0"
label="Inventory Panel"
name="Inventory Panel"
top="15"
- width="467">
-</panel>
+ width="467" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_media_settings.xml b/indra/newview/skins/default/xui/en/floater_media_settings.xml
index 68dd2001af..8122386fae 100644
--- a/indra/newview/skins/default/xui/en/floater_media_settings.xml
+++ b/indra/newview/skins/default/xui/en/floater_media_settings.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
- bottom="-666"
+ bottom="666"
can_close="true"
can_drag_on_left="false"
can_minimize="true"
@@ -12,14 +12,14 @@
width="365"
height="535"
left="330"
- min_height="430"
- min_width="620"
+ min_height="535"
+ min_width="365"
mouse_opaque="true"
- name="Media Settings"
+ name="media_settings"
help_topic = "media_settings"
title="MEDIA SETTINGS">
<button
- bottom="-525"
+ bottom="525"
enabled="true"
follows="right|bottom"
font="SansSerif"
@@ -61,7 +61,7 @@
scale_image="true"
width="90" />
<tab_container
- bottom="-500"
+ bottom="500"
enabled="true"
follows="left|top|right|bottom"
height="485"
diff --git a/indra/newview/skins/default/xui/en/floater_outgoing_call.xml b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml
new file mode 100644
index 0000000000..44956f7e52
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_close="false"
+ can_minimize="false"
+ can_tear_off="false"
+ height="125"
+ layout="topleft"
+ name="outgoing call"
+ help_topic="outgoing_call"
+ title="CALLING"
+ width="410">
+ <floater.string
+ name="localchat">
+ Local Voice Chat
+ </floater.string>
+ <floater.string
+ name="anonymous">
+ anonymous
+ </floater.string>
+ <floater.string
+ name="VoiceInviteP2P">
+ is calling.
+ </floater.string>
+ <floater.string
+ name="VoiceInviteAdHoc">
+ has joined a Voice Chat call with a conference chat.
+ </floater.string>
+ <avatar_icon
+ enabled="false"
+ follows="left|top"
+ height="36"
+ image_name="icon_avatar_online.tga"
+ layout="topleft"
+ left_delta="19"
+ top="35"
+ width="36" />
+ <text
+ font="SansSerifLarge"
+ height="20"
+ layout="topleft"
+ left="77"
+ name="calling"
+ top="27"
+ width="315"
+ word_wrap="true">
+Calling [CALLEE_NAME]
+ </text>
+ <text
+ font="SansSerif"
+ height="50"
+ layout="topleft"
+ left="77"
+ name="leaving"
+ top="52"
+ width="315"
+ word_wrap="true">
+Leaving [CURRENT_CHAT].
+ </text>
+ <button
+ height="24"
+ label="Cancel"
+ label_selected="Cancel"
+ left="70"
+ layout="topleft"
+ name="Cancel"
+ left_pad="10"
+ width="100" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_search.xml b/indra/newview/skins/default/xui/en/floater_search.xml
index b9cf456842..d9498586af 100644
--- a/indra/newview/skins/default/xui/en/floater_search.xml
+++ b/indra/newview/skins/default/xui/en/floater_search.xml
@@ -25,7 +25,7 @@
Done
</floater.string>
<layout_stack
- bottom="400"
+ bottom="512"
follows="left|right|top|bottom"
layout="topleft"
left="10"
@@ -54,7 +54,7 @@
layout="topleft"
left_delta="0"
name="status_text"
- top_pad="4"
+ top_pad="5"
width="150" />
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/en/floater_test_widgets.xml b/indra/newview/skins/default/xui/en/floater_test_widgets.xml
index 44dcb07526..a2055d8c52 100644
--- a/indra/newview/skins/default/xui/en/floater_test_widgets.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_widgets.xml
@@ -385,6 +385,16 @@ line to actually fit
left="10"
width="250"
follows="top|left"
+ font.name="Monospace"
+ name="test_text10"
+ tool_tip="text">
+ Monospace Button Flyout Checkbox
+ </text>
+ <text
+ top_pad="10"
+ left="10"
+ width="250"
+ follows="top|left"
font.name="SansSerifSmall"
name="test_text10"
tool_tip="text">
diff --git a/indra/newview/skins/default/xui/en/inspect_remote_object.xml b/indra/newview/skins/default/xui/en/inspect_remote_object.xml
new file mode 100644
index 0000000000..07c684d904
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/inspect_remote_object.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!--
+ Not can_close / no title to avoid window chrome
+ Single instance - only have one at a time, recycle it each spawn
+-->
+<floater
+ legacy_header_height="18"
+ bevel_style="in"
+ bg_opaque_image="Inspector_Background"
+ can_close="false"
+ can_minimize="false"
+ height="145"
+ layout="topleft"
+ name="inspect_remote_object"
+ single_instance="true"
+ sound_flags="0"
+ visible="true"
+ width="300">
+ <text
+ follows="all"
+ font="SansSerifLargeBold"
+ height="16"
+ left="8"
+ name="object_name"
+ text_color="White"
+ top="5"
+ use_ellipses="true"
+ width="290">
+ Test Object Name That Is Really Long
+ </text>
+ <text
+ follows="all"
+ font="SansSerif"
+ height="20"
+ left="8"
+ name="object_owner_label"
+ width="55"
+ top_pad="20">
+ Owner:
+ </text>
+ <text
+ follows="top|left"
+ font="SansSerif"
+ height="20"
+ left_pad="10"
+ name="object_owner"
+ use_ellipses="true"
+ width="200"
+ word_wrap="false">
+ Longavatarname Johnsonlongstonnammer
+ </text>
+ <text
+ follows="top|left"
+ font="SansSerif"
+ height="20"
+ left="8"
+ name="object_slurl_label"
+ top_pad="10"
+ width="55">
+ Location:
+ </text>
+ <text
+ follows="top|left"
+ height="20"
+ left_pad="10"
+ name="object_slurl"
+ width="240"
+ use_ellipses="true"
+ word_wrap="false">
+ http://slurl.com/Ahern/50/50/50
+ </text>
+ <button
+ follows="top|left"
+ font="SansSerif"
+ height="20"
+ label="Map"
+ left="10"
+ name="map_btn"
+ top="114"
+ width="75" />
+ <button
+ follows="top|left"
+ font="SansSerif"
+ height="20"
+ label="Block"
+ left_pad="5"
+ name="block_btn"
+ top_delta="0"
+ width="75" />
+ <button
+ follows="top|left"
+ font="SansSerif"
+ height="20"
+ label="Close"
+ right="-10"
+ name="close_btn"
+ top_delta="0"
+ width="75" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index 5eb0560962..bd60574a95 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -185,6 +185,14 @@
<menu_item_call.on_click
function="Advanced.ShowSideTray" />
</menu_item_call>
+ <menu_item_call
+ label="Widget Test"
+ name="Widget Test"
+ shortcut="control|shift|T">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="test_widgets" />
+ </menu_item_call>
<menu_item_check
label="Reg In Client Test (restart)"
name="Reg In Client Test (restart)">
diff --git a/indra/newview/skins/default/xui/en/menu_participant_list.xml b/indra/newview/skins/default/xui/en/menu_participant_list.xml
new file mode 100644
index 0000000000..c3283c6014
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_participant_list.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Participant List Context Menu">
+ <menu_item_check
+ label="Mute Text"
+ layout="topleft"
+ name="MuteText">
+ <on_check
+ function="ParticipantList.CheckItem"
+ parameter="is_muted" />
+ <on_click
+ function="ParticipantList.ToggleMuteText" />
+ <on_enable
+ function="ParticipantList.EnableItem"
+ parameter="can_mute_text" />
+ </menu_item_check>
+ <menu_item_check
+ label="Allow text chat"
+ layout="topleft"
+ name="AllowTextChat">
+ <on_check
+ function="ParticipantList.CheckItem"
+ parameter="is_allowed_text_chat" />
+ <on_click
+ function="ParticipantList.ToggleAllowTextChat" />
+ <on_enable
+ function="ParticipantList.EnableItem"
+ parameter="can_allow_text_chat" />
+ </menu_item_check>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
index c002cd078f..39f9e48609 100644
--- a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
@@ -2,15 +2,36 @@
<menu name="menu_group_plus"
left="0" bottom="0" visible="false"
mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="false">
- <menu_item_call name="sort_recent" label="Sort by Recent Speakers">
- <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="sort_recent" />
- </menu_item_call>
- <menu_item_call name="sort_name" label="Sort by Name">
- <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="sort_name" />
- </menu_item_call>
- <menu_item_call name="sort_distance" label="Sort by Distance">
- <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="sort_distance" />
- </menu_item_call>
+ <menu_item_check
+ label="Sort by Recent Speakers"
+ name="sort_by_recent_speakers">
+ <menu_item_check.on_click
+ function="People.Nearby.ViewSort.Action"
+ parameter="sort_by_recent_speakers"/>
+ <menu_item_check.on_check
+ function="People.Nearby.ViewSort.CheckItem"
+ parameter="sort_by_recent_speakers"/>
+ </menu_item_check>
+ <menu_item_check
+ label="Sort by Name"
+ name="sort_name">
+ <menu_item_check.on_click
+ function="People.Nearby.ViewSort.Action"
+ parameter="sort_name"/>
+ <menu_item_check.on_check
+ function="People.Nearby.ViewSort.CheckItem"
+ parameter="sort_name"/>
+ </menu_item_check>
+ <menu_item_check
+ label="Sort by Distance"
+ name="sort_distance">
+ <menu_item_check.on_click
+ function="People.Nearby.ViewSort.Action"
+ parameter="sort_distance"/>
+ <menu_item_check.on_check
+ function="People.Nearby.ViewSort.CheckItem"
+ parameter="sort_distance"/>
+ </menu_item_check>
<menu_item_separator layout="topleft" />
<menu_item_check name="view_icons" label="View People Icons">
<menu_item_check.on_click
diff --git a/indra/newview/skins/default/xui/en/menu_picks_plus.xml b/indra/newview/skins/default/xui/en/menu_picks_plus.xml
new file mode 100644
index 0000000000..3065239615
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_picks_plus.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ height="201"
+ layout="topleft"
+ mouse_opaque="false"
+ name="picks_plus_menu"
+ width="120">
+ <menu_item_call
+ name="create_pick"
+ label="New Pick">
+ <menu_item_call.on_click
+ function="Picks.Plus.Action"
+ userdata="new_pick" />
+ </menu_item_call>
+ <menu_item_call
+ name="create_classified"
+ label="New Classified">
+ <menu_item_call.on_click
+ function="Picks.Plus.Action"
+ userdata="new_classified" />
+ </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 1499095bcc..e98a6d57bb 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -843,18 +843,18 @@
<menu_item_call.on_click
function="Floater.Toggle"
parameter="perm_prefs" />
- <menu_item_check
- label="Show Advanced Permissions"
- layout="topleft"
- name="DebugPermissions">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="DebugPermissions" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="DebugPermissions" />
- </menu_item_check>
</menu_item_call>
+ <menu_item_check
+ label="Show Advanced Permissions"
+ layout="topleft"
+ name="DebugPermissions">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DebugPermissions" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DebugPermissions" />
+ </menu_item_check>
<!--menu_item_call
label="Show Script Warning/Error Window"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 989dc88851..ff0cd7ffeb 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3051,6 +3051,18 @@ Teleport to [PICK]?
</notification>
<notification
+ icon="alertmodal.tga"
+ name="TeleportToClassified"
+ type="alertmodal">
+ Teleport to [CLASSIFIED]?
+ <usetemplate
+ ignoretext="Confirm that I want to teleport to a location in Classifieds"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="Teleport"/>
+ </notification>
+
+ <notification
icon="alert.tga"
label="Message everyone in your Estate"
name="MessageEstate"
@@ -4684,7 +4696,12 @@ The objects on the selected parcel that are NOT owned by you have been returned
icon="notify.tga"
name="ServerObjectMessage"
type="notify">
+Message from [NAME]:
[MSG]
+ <usetemplate
+ name="okcancelbuttons"
+ notext="OK"
+ yestext="Inspect"/>
</notification>
<notification
@@ -5001,6 +5018,7 @@ An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you a
name="GodMessage"
type="notify">
[NAME]
+
[MESSAGE]
</notification>
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 0c42686531..2eaa3a94ee 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
@@ -30,7 +30,7 @@
<avatar_icon
follows="top|left"
height="20"
- image_name="smile.png"
+ default_icon_name="Generic_Person"
layout="topleft"
left="5"
mouse_opaque="true"
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index 3fbc8e1afd..3c16a439d9 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -13,6 +13,8 @@
chrome="true"
border_visible="false"
width="1000">
+ <string name="SpeakBtnToolTip">Turns microphone on/off</string>
+ <string name="VoiceControlBtnToolTip">Shows/hides voice control panel</string>
<layout_stack
mouse_opaque="false"
border_size="0"
@@ -45,7 +47,7 @@
min_height="23"
width="310"
top="0"
- min_width="310"
+ min_width="192"
name="chat_bar"
user_resize="false"
filename="panel_nearby_chat_bar.xml" />
@@ -70,9 +72,7 @@
left="0"
name="talk"
top="3"
- width="100"
- speak_button.tool_tip="Turns microphone on/off"
- show_button.tool_tip="Shows/hides voice control panel" />
+ width="100" />
</layout_panel>
<icon
auto_resize="false"
@@ -92,13 +92,13 @@
height="28"
layout="topleft"
min_height="28"
- width="80"
+ width="82"
top_delta="0"
- min_width="76"
+ min_width="82"
name="gesture_panel"
user_resize="false">
- <button
- follows="right"
+ <gesture_combo_box
+ follows="left|right"
height="23"
label="Gesture"
layout="topleft"
@@ -106,7 +106,7 @@
left="0"
top="3"
use_ellipses="true"
- width="80"
+ width="82"
tool_tip="Shows/hides gestures"/>
</layout_panel>
<icon
@@ -129,8 +129,9 @@
layout="topleft"
min_height="28"
name="movement_panel"
+ user_resize="false"
width="80"
- min_width="76">
+ min_width="80">
<button
follows="left|right"
height="23"
@@ -166,10 +167,10 @@
height="28"
layout="topleft"
min_height="28"
- min_width="76"
+ min_width="80"
name="cam_panel"
- top_delta="-10"
- width="100">
+ user_resize="false"
+ width="80">
<button
follows="left|right"
height="23"
@@ -205,10 +206,11 @@
follows="left|right"
height="28"
layout="topleft"
+ min_width="40"
name="snapshot_panel"
width="40">
<button
- follows="left|right"
+ follows="left|right"
height="23"
left="0"
label=""
@@ -217,9 +219,12 @@
width="36"
top="3"
image_overlay="Snapshot_Off"
- tool_tip="Take snapshot"
- />
- </layout_panel>
+ tool_tip="Take snapshot">
+ <button.commit_callback
+ function="Floater.Toggle"
+ parameter="snapshot" />
+ </button>
+ </layout_panel>
<layout_panel
mouse_opaque="false"
follows="left|right"
@@ -228,20 +233,48 @@
top="0"
name="chiclet_list_panel"
width="189"
- min_width="189"
+ min_width="180"
user_resize="false"
auto_resize="true">
+<!--*NOTE: min_width of the chiclet_panel (chiclet_list) must be the same
+as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly. EXT-991-->
<chiclet_panel
mouse_opaque="false"
follows="left|right"
height="28"
layout="topleft"
left="0"
+ min_width="180"
name="chiclet_list"
top="0"
chiclet_padding="3"
scrolling_offset="40"
- width="189" />
+ width="189">
+ <button
+ auto_resize="true"
+ follows="right"
+ height="23"
+ image_selected="BottomTray_Scroll_Left"
+ image_unselected="BottomTray_Scroll_Left"
+ layout="topleft"
+ name="chicklet_left_scroll_button"
+ tab_stop="false"
+ top="3"
+ visible="false"
+ width="20" />
+ <button
+ auto_resize="true"
+ follows="right"
+ height="23"
+ image_selected="BottomTray_Scroll_Right"
+ image_unselected="BottomTray_Scroll_Right"
+ layout="topleft"
+ name="chicklet_right_scroll_button"
+ tab_stop="false"
+ top="3"
+ visible="false"
+ width="20" />
+ </chiclet_panel>
</layout_panel>
<icon
auto_resize="false"
@@ -285,9 +318,9 @@
/>
<unread_notifications
width="34"
- height="23"
- left="22"
- top="23" />
+ height="20"
+ left="0"
+ top="19" />
</chiclet_notification>
</layout_panel>
<icon
diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml
new file mode 100644
index 0000000000..bdca8531dc
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ follows="all"
+ height="570"
+ layout="topleft"
+ left="0"
+ min_height="350"
+ name="panel_classified_info"
+ top="0"
+ width="333">
+ <panel.string
+ name="type_mature">
+ Mature
+ </panel.string>
+ <panel.string
+ name="type_pg">
+ PG Content
+ </panel.string>
+ <button
+ follows="top|right"
+ height="23"
+ image_overlay="BackArrow_Off"
+ layout="topleft"
+ name="back_btn"
+ picture_style="true"
+ left="10"
+ tab_stop="false"
+ top="2"
+ width="23" />
+ <text
+ follows="top|left|right"
+ font="SansSerifHugeBold"
+ height="26"
+ layout="topleft"
+ left_pad="10"
+ name="title"
+ text_color="white"
+ top="0"
+ value="Classified Info"
+ use_ellipses="true"
+ width="275" />
+ <scroll_container
+ color="DkGray2"
+ opaque="true"
+ follows="all"
+ height="500"
+ layout="topleft"
+ left="10"
+ top_pad="10"
+ name="profile_scroll"
+ reserve_scroll_corner="false"
+ width="313">
+ <panel
+ name="scroll_content_panel"
+ follows="left|top"
+ min_height="300"
+ layout="topleft"
+ top="0"
+ background_visible="false"
+ height="500"
+ left="0"
+ width="295">
+ <texture_picker
+ enabled="false"
+ follows="left|top"
+ height="197"
+ layout="topleft"
+ left="10"
+ name="classified_snapshot"
+ top="20"
+ width="290" />
+ <text
+ follows="left|top|right"
+ height="35"
+ width="290"
+ layout="topleft"
+ font="SansSerifBig"
+ font.style="BOLD"
+ left="10"
+ top_pad="10"
+ name="classified_name"
+ text_color="white"
+ value="[name]"
+ use_ellipses="true" />
+ <text
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left="10"
+ name="classified_location"
+ width="290"
+ word_wrap="true"
+ value="[loading...]" />
+ <text
+ follows="left|top|right"
+ height="18"
+ layout="topleft"
+ left="10"
+ name="content_type"
+ width="290"
+ top_pad="5"
+ value="[content type]" />
+ <text
+ follows="left|top|right"
+ height="18"
+ layout="topleft"
+ left="10"
+ name="category"
+ width="290"
+ top_pad="5"
+ value="[category]" />
+ <check_box
+ enabled="false"
+ height="16"
+ label="Auto renew each week"
+ layout="topleft"
+ left="10"
+ name="auto_renew"
+ top_pad="5"
+ width="290" />
+ <text
+ follows="left|top"
+ halign="left"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="price_for_listing"
+ top_pad="5"
+ tool_tip="Price for listing."
+ width="105">
+ L$[PRICE]
+ </text>
+ <text
+ follows="left|top|right"
+ height="200"
+ layout="topleft"
+ left="10"
+ name="classified_desc"
+ width="290"
+ value="[description]"
+ word_wrap="true" />
+ </panel>
+ </scroll_container>
+ <panel
+ follows="left|right|bottom"
+ height="20"
+ layout="topleft"
+ top_pad="8"
+ left="10"
+ name="buttons">
+ <button
+ follows="bottom|left"
+ font="SansSerifSmall"
+ height="19"
+ label="Teleport"
+ layout="topleft"
+ left="0"
+ name="teleport_btn"
+ top="0"
+ width="90" />
+ <button
+ follows="bottom|left"
+ font="SansSerifSmall"
+ height="19"
+ label="Map"
+ layout="topleft"
+ left_pad="10"
+ name="show_on_map_btn"
+ top="0"
+ width="90" />
+ <button
+ follows="bottom|left"
+ font="SansSerifSmall"
+ height="19"
+ label="Edit"
+ layout="topleft"
+ right="-1"
+ name="edit_btn"
+ top="0"
+ width="90" />
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml b/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml
new file mode 100644
index 0000000000..ee333be0cb
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bevel_style="none"
+ follows="top|left|right"
+ height="85"
+ layout="topleft"
+ left="0"
+ name="classified_item"
+ top="0"
+ width="313">
+ <icon
+ follows="all"
+ height="85"
+ image_name="ListItem_Over"
+ right="-3"
+ mouse_opaque="false"
+ name="hovered_icon"
+ top="1"
+ scale_image="true"
+ visible="false"
+ width="307"/>
+ <icon
+ follows="all"
+ height="85"
+ image_name="ListItem_Select"
+ right="-3"
+ mouse_opaque="false"
+ name="selected_icon"
+ top="1"
+ scale_image="true"
+ visible="false"
+ width="307"/>
+ <texture_picker
+ allow_no_texture="true"
+ border_enabled="true"
+ default_image_name="TabIcon_Places_Large"
+ enabled="false"
+ follows="left|top"
+ height="80"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="picture"
+ tab_stop="false"
+ top="10"
+ top_pad="10"
+ width="90" />
+ <text
+ follows="top|left|right"
+ font="SansSerifSmallBold"
+ height="16"
+ layout="topleft"
+ left="110"
+ name="name"
+ text_color="white"
+ top="9"
+ use_ellipses="false"
+ width="197"
+ word_wrap="false" />
+ <expandable_text
+ follows="top|left|right"
+ font="SansSerifSmall"
+ height="40"
+ layout="topleft"
+ left="110"
+ name="description"
+ top_pad="3"
+ width="178"
+ word_wrap="true" />
+ <button
+ follows="top|right"
+ height="16"
+ image_selected="BuyArrow_Press"
+ image_pressed="BuyArrow_Press"
+ image_unselected="BuyArrow_Press"
+ layout="topleft"
+ name="info_chevron"
+ picture_style="true"
+ right="-7"
+ tab_stop="false"
+ top="27"
+ width="16" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
new file mode 100644
index 0000000000..2f3277804f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ bevel_style="in"
+ follows="left|top|right|bottom"
+ height="570"
+ label="Edit Classified"
+ layout="topleft"
+ left="0"
+ min_height="350"
+ name="panel_edit_classified"
+ top="0"
+ width="333">
+ <panel.string
+ name="location_notice">
+ (will update after save)
+ </panel.string>
+ <button
+ follows="top|right"
+ height="23"
+ image_overlay="BackArrow_Off"
+ layout="topleft"
+ name="back_btn"
+ picture_style="true"
+ left="10"
+ tab_stop="false"
+ top="2"
+ width="23" />
+ <text
+ type="string"
+ length="1"
+ follows="top"
+ font="SansSerifHuge"
+ height="15"
+ layout="topleft"
+ left_pad="10"
+ name="title"
+ text_color="white"
+ top="5"
+ width="250">
+ Edit Classified
+ </text>
+ <scroll_container
+ color="DkGray2"
+ follows="all"
+ height="510"
+ layout="topleft"
+ left="10"
+ top_pad="10"
+ name="profile_scroll"
+ reserve_scroll_corner="false"
+ opaque="true"
+ width="313">
+ <panel
+ name="scroll_content_panel"
+ follows="left|top"
+ min_height="300"
+ layout="topleft"
+ top="0"
+ background_visible="false"
+ height="600"
+ left="0"
+ width="295">
+ <texture_picker
+ follows="left|top|right"
+ height="197"
+ width="290"
+ layout="topleft"
+ top="20"
+ left="10"
+ name="classified_snapshot" />
+ <icon
+ height="18"
+ image_name="AddItem_Off"
+ layout="topleft"
+ right="-5"
+ name="edit_icon"
+ label=""
+ tool_tip="Click to select an image"
+ top="27"
+ width="18" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="15"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ layout="topleft"
+ left="10"
+ top="215"
+ name="Name:"
+ text_color="white"
+ width="290">
+ Title:
+ </text>
+ <line_editor
+ follows="left|top|right"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="10"
+ top_pad="2"
+ max_length="63"
+ name="classified_name"
+ text_color="black"
+ width="290" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="15"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ layout="topleft"
+ left="10"
+ top_pad="20"
+ name="description_label"
+ text_color="white"
+ width="290">
+ Description:
+ </text>
+ <text_editor
+ follows="left|top|right"
+ height="100"
+ width="290"
+ hide_scrollbar="false"
+ layout="topleft"
+ left="10"
+ top_pad="2"
+ max_length="1023"
+ name="classified_desc"
+ text_color="black"
+ word_wrap="true" />
+ <text
+ type="string"
+ length="1"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="location_label"
+ text_color="white"
+ top_pad="20"
+ width="290">
+ Location:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="50"
+ layout="topleft"
+ left="10"
+ name="classified_location"
+ right="-10"
+ top_pad="2"
+ width="290"
+ word_wrap="true">
+ loading...
+ </text>
+ <button
+ follows="left|top"
+ height="20"
+ label="Set to Current Location"
+ layout="topleft"
+ left="8"
+ top_pad="5"
+ name="set_to_curr_location_btn"
+ width="200" />
+ <combo_box
+ follows="left|top"
+ height="18"
+ label=""
+ left="10"
+ name="category"
+ top_pad="5"
+ width="200" />
+ <combo_box
+ allow_text_entry="false"
+ follows="left|top"
+ height="18"
+ left="10"
+ name="content_type"
+ top_pad="5"
+ width="200">
+ <combo_item
+ name="mature_ci"
+ value="Mature">
+ Mature Content
+ </combo_item>
+ <combo_item
+ name="pg_ci"
+ value="PG">
+ PG Content
+ </combo_item>
+ </combo_box>
+ <spinner
+ decimal_digits="0"
+ follows="left|top"
+ halign="left"
+ height="16"
+ increment="1"
+ label_width="20"
+ label="L$"
+ layout="topleft"
+ left="10"
+ value="50"
+ min_val="50"
+ max_val="99999"
+ name="price_for_listing"
+ top_pad="5"
+ tool_tip="Price for listing."
+ width="105" />
+ <check_box
+ height="16"
+ label="Auto renew each week"
+ layout="topleft"
+ left="10"
+ name="auto_renew"
+ top_pad="5"
+ width="250" />
+ </panel>
+ </scroll_container>
+ <panel
+ follows="left|right|bottom"
+ height="20"
+ label="bottom_panel"
+ layout="topleft"
+ left="10"
+ name="bottom_panel"
+ top_pad="5"
+ width="303">
+ <button
+ follows="bottom|left"
+ height="19"
+ label="Save"
+ layout="topleft"
+ name="save_changes_btn"
+ left="0"
+ top="0"
+ width="130" />
+ <button
+ follows="bottom|left"
+ height="19"
+ label="Cancel"
+ layout="topleft"
+ name="cancel_btn"
+ left_pad="5"
+ right="-1"
+ width="130" />
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
index f4a212ba0a..d6de5af32d 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -53,7 +53,7 @@
layout="topleft"
top="0"
background_visible="false"
- height="470"
+ height="510"
left="0"
width="295">
<texture_picker
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 4f24c7a745..58a78a0ab8 100644
--- a/indra/newview/skins/default/xui/en/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_general.xml
@@ -8,7 +8,7 @@
left="0"
top="0"
name="general_tab"
- width="303">
+ width="310">
<panel.string
name="help_text">
The General tab contains general information about this group, a list of members, general Group Preferences and member options.
@@ -32,7 +32,7 @@ Hover your mouse over the options for more help.
max_length="511"
name="charter"
top="5"
- width="303"
+ width="305"
word_wrap="true">
Group Charter
</text_editor>
@@ -43,10 +43,10 @@ Hover your mouse over the options for more help.
heading_height="16"
height="130"
layout="topleft"
- left_delta="0"
+ left="5"
name="visible_members"
- top_pad="0"
- width="303">
+ top_pad="2"
+ width="305">
<name_list.columns
label="Member"
name="name"
@@ -64,7 +64,7 @@ Hover your mouse over the options for more help.
left_delta="0"
name="active_title_label"
top_pad="5"
- width="303">
+ width="300">
My Title
</text>
<combo_box
@@ -75,7 +75,7 @@ Hover your mouse over the options for more help.
name="active_title"
tool_tip="Sets the title that appears in your avatar&apos;s name tag when this group is active."
top_pad="2"
- width="303" />
+ width="305" />
<check_box
height="16"
font="SansSerifSmall"
@@ -85,7 +85,7 @@ Hover your mouse over the options for more help.
name="receive_notices"
tool_tip="Sets whether you want to receive Notices from this group. Uncheck this box if this group is spamming you."
top_pad="5"
- width="303" />
+ width="300" />
<check_box
height="16"
label="Show in my profile"
@@ -94,7 +94,7 @@ Hover your mouse over the options for more help.
name="list_groups_in_profile"
tool_tip="Sets whether you want to show this group in your profile"
top_pad="5"
- width="303" />
+ width="295" />
<panel
background_visible="true"
bevel_style="in"
@@ -106,7 +106,7 @@ Hover your mouse over the options for more help.
left="5"
name="preferences_container"
top_pad="5"
- width="303">
+ width="305">
<check_box
follows="right|top"
height="16"
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 de1323d9cb..0082128ca4 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
@@ -9,7 +9,7 @@ background_visible="true"
left="0"
top="20"
name="GroupInfo"
- width="333">
+ width="323">
<panel.string
name="default_needs_apply_text">
There are unsaved changes to the current tab
@@ -117,28 +117,17 @@ background_visible="true"
width="120" />
<accordion
follows="all"
- height="425"
+ height="405"
layout="topleft"
left="0"
name="groups_accordion"
top_pad="15"
- width="336">
+ width="323">
<accordion_tab
expanded="true"
layout="topleft"
name="group_general_tab"
title="General">
- <scroll_container
- color="DkGray2"
- opaque="true"
- height="323"
- follows="all"
- layout="topleft"
- left="0"
- top="0"
- name="general_scroll"
- reserve_scroll_corner="false"
- width="333">
<panel
border="false"
class="panel_group_general"
@@ -146,27 +135,15 @@ background_visible="true"
layout="topleft"
left="0"
help_topic="group_general_tab"
- name="group_general_tab_panel"
+ name="group_general_tab_panel"
top="0"
- width="303" />
- </scroll_container>
+ width="300" />
</accordion_tab>
<accordion_tab
expanded="false"
layout="topleft"
name="group_roles_tab"
title="Roles">
- <scroll_container
- color="DkGray2"
- opaque="true"
- height="323"
- follows="all"
- layout="topleft"
- left="0"
- top="0"
- name="roles_scroll"
- reserve_scroll_corner="false"
- width="333">
<panel
border="false"
class="panel_group_roles"
@@ -177,24 +154,12 @@ background_visible="true"
name="group_roles_tab_panel"
top="0"
width="303" />
- </scroll_container>
</accordion_tab>
<accordion_tab
expanded="false"
layout="topleft"
name="group_notices_tab"
title="Notices">
- <scroll_container
- color="DkGray2"
- opaque="true"
- height="323"
- follows="all"
- layout="topleft"
- left="0"
- top="0"
- name="notices_scroll"
- reserve_scroll_corner="false"
- width="333">
<panel
border="false"
class="panel_group_notices"
@@ -205,24 +170,12 @@ background_visible="true"
name="group_notices_tab_panel"
top="0"
width="303" />
- </scroll_container>
</accordion_tab>
<accordion_tab
expanded="false"
layout="topleft"
name="group_land_tab"
title="Land/Assets">
- <scroll_container
- color="DkGray2"
- opaque="true"
- height="323"
- follows="all"
- layout="topleft"
- left="0"
- top="0"
- name="land_scroll"
- reserve_scroll_corner="false"
- width="333">
<panel
border="false"
class="panel_group_land_money"
@@ -232,8 +185,7 @@ background_visible="true"
help_topic="group_land_money_tab"
name="group_land_tab_panel"
top="0"
- width="313" />
- </scroll_container>
+ width="300" />
</accordion_tab>
</accordion>
<button
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 0c6f81f8fd..2c649642c3 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
@@ -5,10 +5,10 @@
height="510"
label="Land &amp; L$"
layout="topleft"
- left="1"
+ left="0"
name="land_money_tab"
top="0"
- width="313">
+ width="310">
<panel.string
name="help_text">
Parcels owned by a group are listed along with contribution details. A warning appears until the Total Land in Use is less than or = to the Total Contribution.
@@ -47,10 +47,10 @@
heading_height="20"
height="150"
layout="topleft"
- left="0"
+ left="2"
name="group_parcel_list"
top_pad="0"
- width="313">
+ width="305">
<scroll_list.columns
label="Parcel"
name="name"
@@ -79,7 +79,7 @@
label_selected="Map"
layout="topleft"
name="map_button"
- right="-10"
+ right="-5"
top_pad="5"
width="95"
enabled="false" />
@@ -185,7 +185,9 @@
layout="topleft"
left_pad="3"
name="your_contribution_units"
- top_delta="2">
+ top_delta="2"
+ width="40"
+ >
m²
</text>
<text
@@ -210,17 +212,17 @@
visible="false"
width="16" />
<text
- follows="left|top"
+ follows="left|top"
type="string"
word_wrap="true"
font="SansSerifSmall"
height="35"
layout="topleft"
- left_pad="0"
+ left_pad="5"
name="group_over_limit_text"
text_color="EmphasisColor"
top_delta="0"
- width="290">
+ width="260">
Group members must contribute more land credits to support land in use
</text>
<text
@@ -241,7 +243,7 @@
height="200"
halign="center"
layout="topleft"
- left="10"
+ left="5"
name="group_money_tab_container"
tab_position="top"
tab_height="20"
@@ -268,7 +270,7 @@
left="0"
max_length="4096"
name="group_money_planning_text"
- top="0"
+ top="2"
width="300"
word_wrap="true">
Loading...
@@ -293,7 +295,7 @@
left="0"
max_length="4096"
name="group_money_details_text"
- top="0"
+ top="2"
width="300"
word_wrap="true">
Loading...
@@ -305,8 +307,8 @@
layout="topleft"
name="earlier_details_button"
tool_tip="Back"
- top_pad="3"
- right="-35"
+ top_pad="5"
+ right="-45"
width="31" />
<button
follows="left|top"
@@ -327,7 +329,7 @@
left_delta="0"
help_topic="group_money_sales_tab"
name="group_money_sales_tab"
- top_delta="-1"
+ top="5"
width="300">
<text_editor
type="string"
@@ -337,7 +339,7 @@
left="0"
max_length="4096"
name="group_money_sales_text"
- top="0"
+ top="2"
width="300"
word_wrap="true">
Loading...
@@ -349,8 +351,8 @@
layout="topleft"
name="earlier_sales_button"
tool_tip="Back"
- top_pad="3"
- right="-35"
+ top_pad="5"
+ right="-45"
width="31" />
<button
follows="left|top"
@@ -358,7 +360,7 @@
image_overlay="Arrow_Right_Off"
layout="topleft"
left_pad="10"
- name="later_sales_button"
+ name="later_sales_button"
tool_tip="Next"
width="31" />
</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 24a4005a45..e56db6414f 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -7,7 +7,7 @@
left="0"
name="notices_tab"
top="0"
- width="313">
+ width="310">
<panel.string
name="help_text">
Notices are a quick way to communicate across a
@@ -27,7 +27,7 @@ the General tab.
word_wrap="true"
height="30"
layout="topleft"
- left="10"
+ left="5"
name="lbl2"
top="5"
width="300">
@@ -41,10 +41,10 @@ Groups are limited to 200 notices/group daily
heading_height="16"
height="125"
layout="topleft"
- left="0"
+ left="2"
name="notice_list"
top_pad="0"
- width="303">
+ width="305">
<scroll_list.columns
label=""
name="icon"
@@ -81,10 +81,10 @@ Groups are limited to 200 notices/group daily
image_disabled="AddItem_Disabled"
layout="topleft"
label="Create a new notice"
- left="15"
+ left="5"
name="create_new_notice"
tool_tip="Create a new notice"
- top_delta="-5"
+ top_delta="0"
width="18" />
<button
follows="top|left"
@@ -93,7 +93,7 @@ Groups are limited to 200 notices/group daily
layout="topleft"
name="refresh_notices"
right="-5"
- top_delta="5"
+ top_delta="0"
width="23" />
<panel
follows="left|top"
@@ -219,7 +219,7 @@ Groups are limited to 200 notices/group daily
label_selected="Send Notice"
layout="topleft"
right="-10"
- top_pad="20"
+ top_pad="10"
name="send_notice"
width="100" />
<group_drop_target
diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml
index 4129d7b448..604fb81c8e 100644
--- a/indra/newview/skins/default/xui/en/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -7,7 +7,7 @@
left="0"
top="0"
name="roles_tab"
- width="313">
+ width="310">
<panel.string
name="default_needs_apply_text">
There are unsaved changes to the current tab
@@ -28,9 +28,9 @@
name="roles_tab_container"
tab_position="top"
tab_height="20"
- tab_min_width="96"
+ tab_min_width="75"
top="3"
- width="303">
+ width="300">
<panel
border="false"
height="220"
@@ -51,23 +51,13 @@ clicking on their names.
<filter_editor
layout="topleft"
top="10"
- left="4"
+ left="5"
width="280"
height="20"
follows="left|top|right"
max_length="250"
label="Filter Members"
name="filter_input" />
- <!-- <button
- enabled="false"
- font="SansSerifSmall"
- height="20"
- label="Show All"
- layout="topleft"
- left_pad="-90"
- name="show_all_button"
- top_delta="-6"
- width="80" />-->
<name_list
column_padding="0"
draw_heading="true"
@@ -111,14 +101,6 @@ clicking on their names.
right="-5"
name="member_eject"
width="100" />
- <!--What is this?-->
- <icon
- height="16"
- image_name="Inv_FolderClosed"
- layout="topleft"
- name="power_folder_icon"
- visible="false"
- width="16" />
</panel>
<panel
border="false"
@@ -156,7 +138,7 @@ including the Everyone and Owner Roles.
<filter_editor
layout="topleft"
top="10"
- left="4"
+ left="5"
width="280"
height="20"
follows="left|top|right"
@@ -179,12 +161,12 @@ including the Everyone and Owner Roles.
draw_stripes="false"
follows="left|top"
heading_height="20"
- height="150"
+ height="160"
layout="topleft"
search_column="1"
left="0"
name="role_list"
- top_pad="4"
+ top_pad="2"
width="300">
<scroll_list.columns
label="Role"
@@ -238,24 +220,13 @@ things in this group. There&apos;s a broad variety of Abilities.
<filter_editor
layout="topleft"
top="10"
- left="4"
+ left="5"
width="280"
height="20"
follows="left|top|right"
max_length="250"
label="Filter Abilities"
name="filter_input" />
- <!--
- <button
- enabled="false"
- font="SansSerifSmall"
- height="20"
- label="Show All"
- layout="topleft"
- left_pad="0"
- name="show_all_button"
- top_delta="0"
- width="80" /> -->
<scroll_list
column_padding="0"
draw_stripes="false"
@@ -267,14 +238,14 @@ things in this group. There&apos;s a broad variety of Abilities.
name="action_list"
search_column="1"
tool_tip="Select an Ability to view more details"
- top_pad="6"
+ top_pad="2"
width="300">
<scroll_list.columns
label=""
name="icon"
width="16" />
<scroll_list.columns
- label=""
+ label="Action"
name="action"
width="247" />
</scroll_list>
@@ -293,9 +264,9 @@ things in this group. There&apos;s a broad variety of Abilities.
follows="left|top"
left="10"
name="members_footer"
- top_pad="10"
+ top="245"
top_delta="0"
- width="300">
+ width="290">
<text
type="string"
height="16"
@@ -304,7 +275,7 @@ things in this group. There&apos;s a broad variety of Abilities.
left="0"
name="static"
top_pad="5"
- width="295">
+ width="285">
Assigned Roles
</text>
<scroll_list
@@ -315,7 +286,7 @@ things in this group. There&apos;s a broad variety of Abilities.
left="0"
name="member_assigned_roles"
top_pad="0"
- width="295">
+ width="285">
<scroll_list.columns
label=""
name="checkbox"
@@ -323,7 +294,7 @@ things in this group. There&apos;s a broad variety of Abilities.
<scroll_list.columns
label=""
name="role"
- width="265" />
+ width="255" />
</scroll_list>
<text
type="string"
@@ -333,7 +304,7 @@ things in this group. There&apos;s a broad variety of Abilities.
left="0"
name="static2"
top_pad="5"
- width="295">
+ width="285">
Allowed Abilities
</text>
<scroll_list
@@ -345,7 +316,7 @@ things in this group. There&apos;s a broad variety of Abilities.
search_column="2"
tool_tip="For details of each allowed ability see the abilities tab"
top_pad="0"
- width="295">
+ width="285">
<scroll_list.columns
label=""
name="icon"
@@ -353,7 +324,7 @@ things in this group. There&apos;s a broad variety of Abilities.
<scroll_list.columns
label=""
name="action"
- width="275" />
+ width="265" />
</scroll_list>
</panel>
<panel
@@ -364,7 +335,7 @@ things in this group. There&apos;s a broad variety of Abilities.
top_delta="0"
top="245"
visible="false"
- width="300">
+ width="290">
<text
type="string"
height="16"
@@ -386,7 +357,7 @@ things in this group. There&apos;s a broad variety of Abilities.
max_length="295"
name="role_name"
top_pad="0"
- width="295">
+ width="290">
Employees
</line_editor>
<text
@@ -395,7 +366,7 @@ things in this group. There&apos;s a broad variety of Abilities.
layout="topleft"
name="static3"
top_pad="5"
- width="295">
+ width="290">
Title
</text>
<line_editor
@@ -408,7 +379,7 @@ things in this group. There&apos;s a broad variety of Abilities.
max_length="295"
name="role_title"
top_pad="0"
- width="295">
+ width="290">
(waiting)
</line_editor>
<text
@@ -442,7 +413,7 @@ things in this group. There&apos;s a broad variety of Abilities.
left="0"
name="static4"
top_pad="5"
- width="295">
+ width="290">
Assigned Roles
</text>
<name_list
@@ -452,7 +423,7 @@ things in this group. There&apos;s a broad variety of Abilities.
left="0"
name="role_assigned_members"
top_pad="0"
- width="295" />
+ width="290" />
<check_box
height="15"
label="Reveal members"
@@ -469,7 +440,7 @@ things in this group. There&apos;s a broad variety of Abilities.
left="0"
name="static5"
top_pad="5"
- width="295">
+ width="290">
Allowed Abilities
</text>
<scroll_list
@@ -504,7 +475,7 @@ things in this group. There&apos;s a broad variety of Abilities.
top_delta="0"
top="245"
visible="false"
- width="300">
+ width="290">
<text
type="string"
height="16"
@@ -550,7 +521,7 @@ things in this group. There&apos;s a broad variety of Abilities.
layout="topleft"
name="static3"
top_pad="5"
- width="295">
+ width="290">
Members with this ability
</text>
<name_list
@@ -558,6 +529,6 @@ things in this group. There&apos;s a broad variety of Abilities.
layout="topleft"
name="action_members"
top_pad="0"
- width="295" />
+ width="290" />
</panel>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_instant_message.xml b/indra/newview/skins/default/xui/en/panel_instant_message.xml
index 26d8304551..be56866119 100644
--- a/indra/newview/skins/default/xui/en/panel_instant_message.xml
+++ b/indra/newview/skins/default/xui/en/panel_instant_message.xml
@@ -79,7 +79,7 @@
text_color="white"
top="33"
use_ellipses="true"
- value="MESSAGE"
+ value=""
width="285"
word_wrap="true"
max_length="350" />
diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
index 0c24adfad5..b01ddbf75a 100644
--- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
@@ -43,6 +43,16 @@
name="acquired_date">
[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
</string>
+ <!-- Texture names for rating icons -->
+ <string
+ name="icon_PG"
+ value="parcel_drk_PG" />
+ <string
+ name="icon_M"
+ value="parcel_drk_M" />
+ <string
+ name="icon_R"
+ value="parcel_drk_R" />
<button
follows="top|right"
height="23"
@@ -125,6 +135,24 @@
top_pad="10"
value="Du waltz die spritz"
width="300" />
+ <icon
+ follows="top|left"
+ height="16"
+ image_name="unknown"
+ layout="topleft"
+ left="10"
+ name="maturity_icon"
+ top_pad="10"
+ width="18" />
+ <text
+ follows="right|top"
+ height="16"
+ layout="topleft"
+ left_pad="8"
+ name="maturity_value"
+ top_delta="0"
+ value="unknown"
+ width="268" />
<panel
follows="left|top|right"
height="55"
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
index a12797d96b..1ef845b769 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
@@ -9,7 +9,7 @@
top="21"
width="310">
<string name="min_width">
- 310
+ 192
</string>
<string name="max_width">
320
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 15fdd73bdc..9fac7d34f7 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -16,7 +16,7 @@ background_visible="true"
value="No people" />
<string
name="no_one_near"
- value="No-one near" />
+ value="No one near" />
<string
name="no_friends_online"
value="No friends online" />
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
index ae61852f68..9cfbed432a 100644
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ b/indra/newview/skins/default/xui/en/panel_picks.xml
@@ -8,16 +8,58 @@
name="panel_picks"
top="0"
width="313">
+ <string
+ name="no_picks"
+ value="No Picks" />
+ <string
+ name="no_classifieds"
+ value="No Classifieds" />
+
+ <accordion
+ follows="all"
+ height="465"
+ layout="topleft"
+ left="0"
+ name="accordion"
+ top="0"
+ single_expansion="true"
+ width="313">
+ <accordion_tab
+ can_resize="false"
+ layout="topleft"
+ height="235"
+ min_height="150"
+ name="tab_picks"
+ title="Picks"
+ visible="false">
<flat_list_view
color="DkGray2"
follows="all"
- height="465"
layout="topleft"
left="0"
name="picks_list"
opaque="true"
top="0"
width="313" />
+ </accordion_tab>
+ <accordion_tab
+ can_resize="false"
+ layout="topleft"
+ height="235"
+ name="tab_classifieds"
+ title="Classifieds"
+ visible="false">
+ <flat_list_view
+ color="DkGray2"
+ follows="all"
+ layout="topleft"
+ left="0"
+ name="classifieds_list"
+ opaque="true"
+ top="0"
+ width="313" />
+ </accordion_tab>
+ </accordion>
<panel
background_visible="true"
bevel_style="none"
diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml
index 65f150b33c..e6084202d7 100644
--- a/indra/newview/skins/default/xui/en/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml
@@ -179,7 +179,6 @@
min_height="300"
name="scrolling_panel"
top="0"
- value="&gt;"
width="313">
<texture_picker
enabled="false"
@@ -296,6 +295,24 @@
top_delta="0"
value="Alex Superduperlongenamenton"
width="205" />
+ <icon
+ follows="top|left"
+ height="16"
+ image_name="unknown"
+ layout="topleft"
+ left="10"
+ name="maturity_icon"
+ top_delta="0"
+ width="18" />
+ <text
+ follows="right|top"
+ height="16"
+ layout="topleft"
+ left_pad="8"
+ name="maturity_value"
+ top_delta="0"
+ value="unknown"
+ width="268" />
<accordion
follows="all"
height="230"
@@ -308,222 +325,211 @@
layout="topleft"
name="parcel_characteristics_tab"
title="Parcel">
- <scroll_container
- color="DkGray2"
+ <panel
follows="all"
- height="132"
+ height="160"
layout="topleft"
left="0"
- name="parcel_scroll"
- opaque="true"
top="0"
- width="290">
- <panel
- follows="all"
- height="165"
+ width="275">
+ <icon
+ follows="top|left"
+ height="16"
+ image_name="parcel_drk_PG"
layout="topleft"
- left="0"
+ left="10"
+ name="rating_icon"
top="0"
- width="275">
- <icon
- follows="top|left"
- height="16"
- image_name="parcel_drk_PG"
- layout="topleft"
- left="20"
- name="rating_icon"
- top="0"
- width="18" />
- <text
- follows="left|top"
- height="16"
- layout="topleft"
- left_pad="8"
- name="rating_label"
- value="Rating:"
- width="80" />
- <text
- follows="right|top"
- height="16"
- layout="topleft"
- left_pad="0"
- name="rating_value"
- top_delta="0"
- value="unknown"
- width="120" />
- <icon
- follows="top|left"
- height="18"
- image_name="parcel_drk_Voice"
- layout="topleft"
- left="20"
- name="voice_icon"
- top_pad="5"
- width="22" />
- <text
- follows="left|top"
- height="18"
- layout="topleft"
- left_pad="8"
- name="voice_label"
- top_delta="0"
- value="Voice:"
- width="76" />
- <text
- follows="right|top"
- height="18"
- layout="topleft"
- left_pad="0"
- name="voice_value"
- top_delta="0"
- value="On"
- width="60" />
- <icon
- follows="top|left"
- height="18"
- image_name="parcel_drk_Fly"
- layout="topleft"
- left="20"
- name="fly_icon"
- top_pad="3"
- width="22" />
- <text
- follows="left|top"
- height="16"
- layout="topleft"
- left_pad="8"
- name="fly_label"
- value="Fly:"
- width="76" />
- <text
- follows="right|top"
- height="16"
- layout="topleft"
- left_pad="0"
- name="fly_value"
- top_delta="0"
- value="On"
- width="60" />
- <icon
- follows="top|left"
- height="18"
- image_name="parcel_drk_Push"
- layout="topleft"
- left="20"
- name="push_icon"
- top_pad="3"
- width="22" />
- <text
- follows="left|top"
- height="14"
- layout="topleft"
- left_pad="8"
- name="push_label"
- value="Push:"
- width="76" />
- <text
- follows="right|top"
- height="14"
- layout="topleft"
- left_pad="0"
- name="push_value"
- top_delta="0"
- value="Off"
- width="60" />
- <icon
- follows="top|left"
- height="18"
- image_name="parcel_drk_Build"
- layout="topleft"
- left="20"
- name="build_icon"
- top_pad="3"
- width="22" />
- <text
- follows="left|top"
- height="14"
- layout="topleft"
- left_pad="8"
- name="build_label"
- value="Build:"
- width="76" />
- <text
- follows="right|top"
- height="15"
- layout="topleft"
- left_pad="0"
- name="build_value"
- top_delta="0"
- value="On"
- width="60" />
- <icon
- follows="top|left"
- height="18"
- image_name="parcel_drk_Scripts"
- layout="topleft"
- left="20"
- name="scripts_icon"
- top_pad="3"
- width="22" />
- <text
- follows="left|top"
- height="14"
- layout="topleft"
- left_pad="8"
- name="scripts_label"
- value="Scripts:"
- width="76" />
- <text
- follows="right|top"
- height="14"
- layout="topleft"
- left_pad="0"
- name="scripts_value"
- top_delta="0"
- value="On"
- width="60" />
- <icon
- follows="top|left"
- height="18"
- image_name="parcel_drk_Damage"
- layout="topleft"
- left="20"
- name="damage_icon"
- top_pad="7"
- width="22" />
- <text
- follows="left|top"
- height="14"
- layout="topleft"
- left_pad="8"
- name="damage_label"
- value="Damage:"
- width="76" />
- <text
- follows="right|top"
- height="14"
- layout="topleft"
- left_pad="0"
- name="damage_value"
- top_delta="0"
- value="Off"
- width="60" />
- <button
- follows="bottom|right"
- height="19"
- label="About Land"
- layout="topleft"
- name="about_land_btn"
- right="-5"
- tab_stop="false"
- top="138"
- width="90">
- <click_callback
- function="ShowFloater"
- parameter="about_land" />
- </button>
- </panel>
- </scroll_container>
+ width="18" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="12"
+ name="rating_label"
+ value="Rating:"
+ width="60" />
+ <text
+ follows="left|right|top"
+ height="16"
+ layout="topleft"
+ left_pad="0"
+ name="rating_value"
+ top_delta="0"
+ value="unknown"
+ width="60" />
+ <icon
+ follows="top|left"
+ height="18"
+ image_name="parcel_drk_Voice"
+ layout="topleft"
+ left="10"
+ name="voice_icon"
+ top_pad="5"
+ width="22" />
+ <text
+ follows="left|top"
+ height="18"
+ layout="topleft"
+ left_pad="8"
+ name="voice_label"
+ top_delta="0"
+ value="Voice:"
+ width="60" />
+ <text
+ follows="left|right|top"
+ height="18"
+ layout="topleft"
+ left_pad="0"
+ name="voice_value"
+ top_delta="0"
+ value="On"
+ width="60" />
+ <icon
+ follows="top|left"
+ height="18"
+ image_name="parcel_drk_Fly"
+ layout="topleft"
+ left="10"
+ name="fly_icon"
+ top_pad="3"
+ width="22" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="8"
+ name="fly_label"
+ value="Fly:"
+ width="60" />
+ <text
+ follows="left|right|top"
+ height="16"
+ layout="topleft"
+ left_pad="0"
+ name="fly_value"
+ top_delta="0"
+ value="On"
+ width="60" />
+ <icon
+ follows="top|left"
+ height="18"
+ image_name="parcel_drk_Push"
+ layout="topleft"
+ left="10"
+ name="push_icon"
+ top_pad="3"
+ width="22" />
+ <text
+ follows="left|top"
+ height="14"
+ layout="topleft"
+ left_pad="8"
+ name="push_label"
+ value="Push:"
+ width="60" />
+ <text
+ follows="left|right|top"
+ height="14"
+ layout="topleft"
+ left_pad="0"
+ name="push_value"
+ top_delta="0"
+ value="Off"
+ width="60" />
+ <icon
+ follows="top|left"
+ height="18"
+ image_name="parcel_drk_Build"
+ layout="topleft"
+ left="10"
+ name="build_icon"
+ top_pad="3"
+ width="22" />
+ <text
+ follows="left|top"
+ height="14"
+ layout="topleft"
+ left_pad="8"
+ name="build_label"
+ value="Build:"
+ width="60" />
+ <text
+ follows="left|right|top"
+ height="15"
+ layout="topleft"
+ left_pad="0"
+ name="build_value"
+ top_delta="0"
+ value="On"
+ width="60" />
+ <icon
+ follows="top|left"
+ height="18"
+ image_name="parcel_drk_Scripts"
+ layout="topleft"
+ left="10"
+ name="scripts_icon"
+ top_pad="3"
+ width="22" />
+ <text
+ follows="left|top"
+ height="14"
+ layout="topleft"
+ left_pad="8"
+ name="scripts_label"
+ value="Scripts:"
+ width="60" />
+ <text
+ follows="left|right|top"
+ height="14"
+ layout="topleft"
+ left_pad="0"
+ name="scripts_value"
+ top_delta="0"
+ value="On"
+ width="60" />
+ <icon
+ follows="top|left"
+ height="18"
+ image_name="parcel_drk_Damage"
+ layout="topleft"
+ left="10"
+ name="damage_icon"
+ top_pad="7"
+ width="22" />
+ <text
+ follows="left|top"
+ height="14"
+ layout="topleft"
+ left_pad="8"
+ name="damage_label"
+ value="Damage:"
+ width="60" />
+ <text
+ follows="left|right|top"
+ height="14"
+ layout="topleft"
+ left_pad="0"
+ name="damage_value"
+ top_delta="0"
+ value="Off"
+ width="60" />
+ <button
+ follows="bottom|right"
+ height="19"
+ label="About Land"
+ layout="topleft"
+ name="about_land_btn"
+ right="-5"
+ tab_stop="false"
+ top="138"
+ width="90">
+ <click_callback
+ function="ShowFloater"
+ parameter="about_land" />
+ </button>
+ </panel>
</accordion_tab>
<accordion_tab
expanded="false"
@@ -545,7 +551,7 @@
name="region_name_label"
top_pad="5"
value="Region:"
- width="80" />
+ width="90" />
<text
follows="left|top|right"
height="15"
@@ -554,7 +560,7 @@
name="region_name"
top_delta="0"
value="Mooseland"
- width="195" />
+ width="187" />
<text
follows="left|top"
height="15"
@@ -563,7 +569,7 @@
name="region_type_label"
top_pad="5"
value="Type:"
- width="80" />
+ width="90" />
<text
follows="left|top|right"
height="15"
@@ -572,7 +578,7 @@
name="region_type"
top_delta="0"
value="Moose"
- width="195" />
+ width="187" />
<text
follows="left|top"
height="15"
@@ -581,7 +587,7 @@
name="region_rating_label"
top_pad="7"
value="Rating:"
- width="80" />
+ width="90" />
<icon
follows="top|left"
height="16"
@@ -597,7 +603,7 @@
left_pad="10"
name="region_rating"
value="Explicit"
- width="100" />
+ width="159" />
<text
follows="left|top"
height="15"
@@ -606,7 +612,7 @@
name="region_owner_label"
top_pad="5"
value="Owner:"
- width="80" />
+ width="90" />
<text
follows="left|top|right"
height="15"
@@ -615,7 +621,7 @@
name="region_owner"
top_delta="0"
value="moose Van Moose"
- width="195" />
+ width="187" />
<text
follows="left|top"
height="15"
@@ -624,7 +630,7 @@
name="region_group_label"
top_pad="5"
value="Group:"
- width="80" />
+ width="90" />
<text
follows="left|top|right"
height="15"
@@ -633,7 +639,7 @@
name="region_group"
top_delta="0"
use_ellipses="true"
- width="195">
+ width="187">
The Mighty Moose of mooseville soundvillemoose
</text>
<button
@@ -671,15 +677,15 @@
name="estate_name_label"
top_pad="5"
value="Estate:"
- width="80" />
+ width="90" />
<text
follows="left|top|right"
height="15"
layout="topleft"
- left="90"
+ left_pad="0"
name="estate_name"
top_delta="0"
- width="160" />
+ width="187" />
<text
follows="left|top"
height="15"
@@ -688,15 +694,15 @@
name="estate_rating_label"
top_pad="5"
value="Rating:"
- width="80" />
+ width="90" />
<text
follows="left|top|right"
height="15"
layout="topleft"
- left="90"
+ left_pad="0"
name="estate_rating"
top_delta="0"
- width="160" />
+ width="187" />
<text
follows="left|top"
height="15"
@@ -705,15 +711,15 @@
name="estate_owner_label"
top_pad="5"
value="Owner:"
- width="80" />
+ width="90" />
<text
follows="left|top|right"
height="15"
layout="topleft"
- left="90"
+ left_pad="0"
name="estate_owner"
top_delta="0"
- width="160" />
+ width="187" />
<text
follows="left|top"
height="15"
@@ -722,7 +728,7 @@
name="covenant_label"
top_pad="5"
value="Covenant:"
- width="220" />
+ width="277" />
<text_editor
bg_focus_color="DkGray2"
bg_readonly_color="DkGray2"
@@ -735,7 +741,8 @@
name="covenant"
read_only="true"
top_pad="0"
- width="280" />
+ width="277"
+ word_wrap="true" />
</panel>
</accordion_tab>
<accordion_tab
@@ -758,15 +765,15 @@
name="sales_price_label"
top_pad="5"
value="Price:"
- width="100" />
+ width="90" />
<text
follows="left|top|right"
height="15"
layout="topleft"
- left="110"
+ left_pad="0"
name="sales_price"
top_delta="0"
- width="140" />
+ width="187" />
<text
follows="left|top"
height="15"
@@ -775,15 +782,15 @@
name="area_label"
top_pad="5"
value="Area:"
- width="100" />
+ width="90" />
<text
follows="left|top|right"
height="15"
layout="topleft"
- left="110"
+ left_pad="0"
name="area"
top_delta="0"
- width="140" />
+ width="187" />
<text
follows="left|top"
height="15"
@@ -792,15 +799,15 @@
name="traffic_label"
top_pad="5"
value="Traffic:"
- width="100" />
+ width="90" />
<text
follows="left|top|right"
height="15"
layout="topleft"
- left="110"
+ left_pad="0"
name="traffic"
top_delta="0"
- width="140" />
+ width="187" />
<text
follows="left|top"
height="15"
@@ -809,15 +816,15 @@
name="primitives_label"
top_pad="5"
value="Primitives:"
- width="100" />
+ width="90" />
<text
follows="left|top|right"
height="15"
layout="topleft"
- left="110"
+ left_pad="0"
name="primitives"
top_delta="0"
- width="140" />
+ width="187" />
<text
follows="left|top"
height="15"
@@ -826,15 +833,15 @@
name="parcel_scripts_label"
top_pad="5"
value="Scripts:"
- width="100" />
+ width="90" />
<text
follows="left|top|right"
height="15"
layout="topleft"
- left="110"
+ left_pad="0"
name="parcel_scripts"
top_delta="0"
- width="140" />
+ width="187" />
<text
follows="left|top"
height="15"
@@ -843,15 +850,15 @@
name="terraform_limits_label"
top_pad="5"
value="Terraform limits:"
- width="100" />
+ width="90" />
<text
follows="left|top|right"
height="15"
layout="topleft"
- left="110"
+ left_pad="0"
name="terraform_limits"
top_delta="0"
- width="140" />
+ width="187" />
<text
follows="left|top"
height="15"
@@ -860,7 +867,7 @@
name="subdivide_label"
top_pad="5"
value="Subdivide/Join ability:"
- width="220" />
+ width="277" />
<text_editor
bg_focus_color="DkGray2"
bg_readonly_color="DkGray2"
@@ -872,7 +879,8 @@
name="subdivide"
read_only="true"
top_pad="5"
- width="245" />
+ width="277"
+ word_wrap="true" />
<text
follows="left|top"
height="15"
@@ -881,7 +889,7 @@
name="resale_label"
top_pad="5"
value="ReSale ability:"
- width="80" />
+ width="277" />
<text_editor
bg_focus_color="DkGray2"
bg_readonly_color="DkGray2"
@@ -893,7 +901,8 @@
name="resale"
read_only="true"
top_pad="5"
- width="245" />
+ width="277"
+ word_wrap="true" />
<text
follows="left|top"
height="15"
@@ -902,15 +911,15 @@
name="sale_to_label"
top_pad="5"
value="For sale to:"
- width="80" />
+ width="90" />
<text
follows="left|top|right"
height="15"
layout="topleft"
- left="90"
+ left_pad="0"
name="sale_to"
top_delta="0"
- width="160" />
+ width="187" />
</panel>
</accordion_tab>
</accordion>
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
index cbbcfe5068..5efacb68be 100644
--- a/indra/newview/skins/default/xui/en/panel_places.xml
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
@@ -104,7 +104,7 @@ background_visible="true"
follows="bottom|right"
font="SansSerifSmall"
height="19"
- image_disabled="ForwardArrow_Disabled"
+ image_disabled="ForwardArrow_Off"
image_selected="ForwardArrow_Press"
image_unselected="ForwardArrow_Off"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 645863e7a4..5a4b0a3892 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -45,14 +45,20 @@
<color_swatch
border_color="0.45098 0.517647 0.607843 1"
can_apply_immediately="true"
- control_name="UserChatColor"
follows="left|top"
height="47"
layout="topleft"
left="30"
name="user"
top_pad="10"
- width="44" />
+ width="44" >
+ <color_swatch.init_callback
+ function="Pref.getUIColor"
+ parameter="UserChatColor" />
+ <color_swatch.commit_callback
+ function="Pref.applyUIColor"
+ parameter="UserChatColor" />
+ </color_swatch>
<text
type="string"
length="1"
@@ -69,14 +75,20 @@
<color_swatch
border_color="0.45098 0.517647 0.607843 1"
can_apply_immediately="true"
- control_name="AgentChatColor"
follows="left|top"
height="47"
layout="topleft"
left="180"
name="agent"
top_pad="-17"
- width="44" />
+ width="44" >
+ <color_swatch.init_callback
+ function="Pref.getUIColor"
+ parameter="AgentChatColor" />
+ <color_swatch.commit_callback
+ function="Pref.applyUIColor"
+ parameter="AgentChatColor" />
+ </color_swatch>
<text
type="string"
length="1"
@@ -94,7 +106,6 @@
border_color="0.45098 0.517647 0.607843 1"
can_apply_immediately="true"
color="0.6 0.6 1 1"
- control_name="IMChatColor"
follows="left|top"
height="47"
label_width="60"
@@ -102,8 +113,15 @@
left="350"
name="im"
top_pad="-17"
- width="44" />
- <text
+ width="44">
+ <color_swatch.init_callback
+ function="Pref.getUIColor"
+ parameter="IMChatColor" />
+ <color_swatch.commit_callback
+ function="Pref.applyUIColor"
+ parameter="IMChatColor" />
+ </color_swatch>
+ <text
type="string"
length="1"
follows="left|top"
@@ -120,7 +138,6 @@
border_color="0.45098 0.517647 0.607843 1"
can_apply_immediately="true"
color="0.8 1 1 1"
- control_name="SystemChatColor"
follows="left|top"
height="47"
label_width="44"
@@ -128,7 +145,14 @@
left="30"
name="system"
top_pad="40"
- width="44" />
+ width="44" >
+ <color_swatch.init_callback
+ function="Pref.getUIColor"
+ parameter="SystemChatColor" />
+ <color_swatch.commit_callback
+ function="Pref.applyUIColor"
+ parameter="SystemChatColor" />
+ </color_swatch>
<text
type="string"
length="1"
@@ -146,14 +170,20 @@
border_color="0.45098 0.517647 0.607843 1"
can_apply_immediately="true"
color="0.82 0.82 0.99 1"
- control_name="ScriptErrorColor"
follows="left|top"
height="47"
layout="topleft"
left="180"
name="script_error"
top_pad="-17"
- width="44" />
+ width="44">
+ <color_swatch.init_callback
+ function="Pref.getUIColor"
+ parameter="ScriptErrorColor" />
+ <color_swatch.commit_callback
+ function="Pref.applyUIColor"
+ parameter="ScriptErrorColor" />
+ </color_swatch>
<text
type="string"
length="1"
@@ -171,14 +201,20 @@
border_color="0.45098 0.517647 0.607843 1"
can_apply_immediately="true"
color="0.7 0.9 0.7 1"
- control_name="ObjectChatColor"
follows="left|top"
height="47"
layout="topleft"
left="350"
name="objects"
top_pad="-17"
- width="44" />
+ width="44" >
+ <color_swatch.init_callback
+ function="Pref.getUIColor"
+ parameter="ObjectChatColor" />
+ <color_swatch.commit_callback
+ function="Pref.applyUIColor"
+ parameter="ObjectChatColor" />
+ </color_swatch>
<text
type="string"
length="1"
@@ -196,14 +232,20 @@
border_color="0.45098 0.517647 0.607843 1"
can_apply_immediately="true"
color="0.7 0.9 0.7 1"
- control_name="llOwnerSayChatColor"
follows="left|top"
height="47"
layout="topleft"
left="30"
name="owner"
top_pad="40"
- width="44" />
+ width="44" >
+ <color_swatch.init_callback
+ function="Pref.getUIColor"
+ parameter="llOwnerSayChatColor" />
+ <color_swatch.commit_callback
+ function="Pref.applyUIColor"
+ parameter="llOwnerSayChatColor" />
+ </color_swatch>
<text
type="string"
length="1"
@@ -221,14 +263,20 @@
border_color="0.45098 0.517647 0.607843 1"
can_apply_immediately="true"
color="0.6 0.6 1 1"
- control_name="HTMLLinkColor"
follows="left|top"
height="47"
layout="topleft"
left="180"
name="links"
top_pad="-17"
- width="44" />
+ width="44" >
+ <color_swatch.init_callback
+ function="Pref.getUIColor"
+ parameter="HTMLLinkColor" />
+ <color_swatch.commit_callback
+ function="Pref.applyUIColor"
+ parameter="HTMLLinkColor" />
+ </color_swatch>
<text
type="string"
length="1"
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 b1308a1942..9b10edde33 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -109,19 +109,7 @@
name="ui_scale_slider"
top_pad="2"
width="180" />
- <spinner
- control_name="UIScaleFactor"
- height="16"
- increment="0.025"
- initial_value="1"
- layout="topleft"
- left_pad="10"
- max_val="1.4"
- min_val="0.75"
- name="ui_scale_slider"
- top_delta="0"
- width="58" />
- <text
+ <text
type="string"
length="1"
follows="left|top"
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 a9874f4553..a419a02d75 100644
--- a/indra/newview/skins/default/xui/en/panel_side_tray.xml
+++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml
@@ -94,7 +94,7 @@
<sidetray_tab
name="sidebar_me"
help_topic="sidebar_me"
- tab_title="Me"
+ tab_title="My Profile"
description="Edit your public profile and Picks."
image="TabIcon_Me_Off"
image_selected="TabIcon_Me_Selected"
@@ -112,7 +112,7 @@
<sidetray_tab
name="sidebar_appearance"
help_topic="sidebar_appearance"
- tab_title="Appearance"
+ tab_title="My Appearance"
description="Change your appearance and current look."
image="TabIcon_Appearance_Off"
image_selected="TabIcon_Appearance_Selected"
@@ -131,7 +131,7 @@
<sidetray_tab
name="sidebar_inventory"
help_topic="sidebar_inventory"
- tab_title="Inventory"
+ tab_title="My Inventory"
description="Browse your inventory."
image="TabIcon_Things_Off"
image_selected="TabIcon_Things_Selected"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index c850dce141..761c17cfd2 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2850,7 +2850,6 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="IM_to_label">To</string>
<string name="IM_moderator_label">(Moderator)</string>
-
<string name="ringing-im">
Joining Voice Chat...
</string>
@@ -2863,6 +2862,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="answering-im">
Connecting...
</string>
+ <string name="conference-title">
+ Ad-hoc Conference
+ </string>
<string name="inventory_item_offered-im">
Inventory item offered
</string>
diff --git a/indra/newview/skins/default/xui/en/widgets/avatar_icon.xml b/indra/newview/skins/default/xui/en/widgets/avatar_icon.xml
new file mode 100644
index 0000000000..a35e2c3663
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/avatar_icon.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+
+<avatar_icon default_icon_name="Generic_Person_Large">
+</avatar_icon>
diff --git a/indra/newview/skins/default/xui/en/widgets/ui_ctrl.xml b/indra/newview/skins/default/xui/en/widgets/ui_ctrl.xml
new file mode 100644
index 0000000000..2f72ad65a1
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/ui_ctrl.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- Global settings for all widgets ("UI Controls") -->
+<ui_ctrl
+ font="SansSerif"
+ />
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index d31a81e128..7b28a3b72c 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -76,6 +76,7 @@ LLControlGroup::LLControlGroup(const std::string& name) :
LLControlGroup::~LLControlGroup() {}
void LLControlGroup::setBOOL(const std::string& name, BOOL val) {}
BOOL LLControlGroup::getBOOL(const std::string& name) { return FALSE; }
+F32 LLControlGroup::getF32(const std::string& name) { return 0.0f; }
U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only) { return 1; }
void LLControlGroup::setString(const std::string& name, const std::string& val) {}
std::string LLControlGroup::getString(const std::string& name) { return "test_string"; }
diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp
index 7a30315b9a..b14c59ab9a 100644
--- a/indra/viewer_components/login/lllogin.cpp
+++ b/indra/viewer_components/login/lllogin.cpp
@@ -70,7 +70,7 @@ public:
LLEventPump& getEventPump() { return mPump; }
private:
- void sendProgressEvent(const std::string& state, const std::string& change,
+ LLSD getProgressEventLLSD(const std::string& state, const std::string& change,
const LLSD& data = LLSD())
{
LLSD status_data;
@@ -87,7 +87,13 @@ private:
{
status_data["data"] = data;
}
+ return status_data;
+ }
+ void sendProgressEvent(const std::string& state, const std::string& change,
+ const LLSD& data = LLSD())
+ {
+ LLSD status_data = getProgressEventLLSD(state, change, data);
mPump.post(status_data);
}
@@ -140,15 +146,28 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD credential
// Request SRV record.
LL_INFOS("LLLogin") << "Requesting SRV record from " << uri << LL_ENDL;
- // *NOTE:Mani - Completely arbitrary timeout value for SRV request.
- filter.errorAfter(5, "SRV Request timed out!");
+ // *NOTE:Mani - Completely arbitrary default timeout value for SRV request.
+ F32 seconds_to_timeout = 5.0f;
+ if(credentials.has("cfg_srv_timeout"))
+ {
+ seconds_to_timeout = credentials["cfg_srv_timeout"].asReal();
+ }
+
+ filter.eventAfter(seconds_to_timeout,
+ getProgressEventLLSD("offline", "fail.login"));
+
+ std::string srv_pump_name = "LLAres";
+ if(credentials.has("cfg_srv_pump"))
+ {
+ srv_pump_name = credentials["cfg_srv_pump"].asString();
+ }
- // Make request
+ // Make request
LLSD request;
request["op"] = "rewriteURI";
request["uri"] = uri;
request["reply"] = replyPump.getName();
- rewrittenURIs = postAndWait(self, request, "LLAres", filter);
+ rewrittenURIs = postAndWait(self, request, srv_pump_name, filter);
} // we no longer need the filter
LLEventPump& xmlrpcPump(LLEventPumps::instance().obtain("LLXMLRPCTransaction"));
diff --git a/indra/viewer_components/login/tests/lllogin_test.cpp b/indra/viewer_components/login/tests/lllogin_test.cpp
index a8ae2883d5..56c21016bd 100644
--- a/indra/viewer_components/login/tests/lllogin_test.cpp
+++ b/indra/viewer_components/login/tests/lllogin_test.cpp
@@ -47,6 +47,7 @@ public:
bool call(const LLSD& event)
{
mDebug(STRINGIZE("LoginListener called!: " << event));
+
mLastEvent = event;
return false;
}
@@ -414,4 +415,40 @@ namespace tut
ensure_equals("Failed to offline", listener.lastEvent()["state"].asString(), "offline");
}
+
+ template<> template<>
+ void llviewerlogin_object::test<5>()
+ {
+ DEBUG;
+ // Test SRV request timeout.
+ set_test_name("LLLogin SRV timeout testing");
+
+ // Testing normal login procedure.
+ LLEventStream llaresPump("LLAres"); // Dummy LLAres pump.
+
+ // LLAresListener dummyLLAres("dummy_llares");
+ // dummyLLAres.listenTo(llaresPump);
+
+ LLLogin login;
+ LoginListener listener("test_ear");
+ listener.listenTo(login.getEventPump());
+
+ LLSD credentials;
+ credentials["first"] = "these";
+ credentials["last"] = "don't";
+ credentials["passwd"] = "matter";
+ credentials["cfg_srv_timeout"] = 0.0f;
+
+ login.connect("login.bar.com", credentials);
+
+ ensure_equals("SRV State", listener.lastEvent()["change"].asString(), "srvrequest");
+
+ // Get the mainloop eventpump, which needs a pinging in order to drive the
+ // SRV timeout.
+ LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
+ LLSD frame_event;
+ mainloop.post(frame_event);
+
+ ensure_equals("SRV Failure", listener.lastEvent()["change"].asString(), "fail.login");
+ }
}