summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/app_settings/settings.xml16
-rw-r--r--indra/newview/llagent.cpp4
-rw-r--r--indra/newview/llagentcamera.cpp2
-rw-r--r--indra/newview/llagentlanguage.cpp26
-rw-r--r--indra/newview/llagentlanguage.h10
-rw-r--r--indra/newview/llagentwearables.cpp17
-rw-r--r--indra/newview/llagentwearables.h3
-rw-r--r--indra/newview/llappearancemgr.cpp215
-rw-r--r--indra/newview/llappearancemgr.h186
-rw-r--r--indra/newview/llappviewer.cpp7
-rw-r--r--indra/newview/llavataractions.cpp5
-rw-r--r--indra/newview/llchathistory.cpp18
-rw-r--r--indra/newview/llcofwearables.cpp34
-rw-r--r--indra/newview/llcofwearables.h4
-rw-r--r--indra/newview/llcurrencyuimanager.cpp9
-rw-r--r--indra/newview/lldrawpoolbump.cpp4
-rw-r--r--indra/newview/lldynamictexture.cpp4
-rw-r--r--indra/newview/llface.cpp2
-rw-r--r--indra/newview/llfloatergroups.cpp2
-rw-r--r--indra/newview/llfloaterland.cpp3
-rw-r--r--indra/newview/llfloatervoicedevicesettings.cpp36
-rw-r--r--indra/newview/llfloaterworldmap.cpp68
-rw-r--r--indra/newview/llfloaterworldmap.h7
-rw-r--r--indra/newview/llfolderview.cpp46
-rw-r--r--indra/newview/llfolderview.h3
-rw-r--r--indra/newview/llgroupmgr.cpp10
-rw-r--r--indra/newview/llinventorybridge.cpp48
-rw-r--r--indra/newview/llinventorybridge.h18
-rw-r--r--indra/newview/llinventoryfunctions.cpp12
-rw-r--r--indra/newview/llinventoryicon.cpp1
-rw-r--r--indra/newview/llinventorymodel.cpp27
-rw-r--r--indra/newview/llinventorymodel.h4
-rw-r--r--indra/newview/llinventoryobserver.cpp25
-rw-r--r--indra/newview/llinventoryobserver.h6
-rw-r--r--indra/newview/llinventorypanel.cpp2
-rw-r--r--indra/newview/lllogininstance.cpp21
-rw-r--r--indra/newview/llmoveview.cpp10
-rw-r--r--indra/newview/llmoveview.h2
-rw-r--r--indra/newview/llnearbychatbar.cpp46
-rw-r--r--indra/newview/llnearbychatbar.h2
-rw-r--r--indra/newview/lloutfitobserver.cpp20
-rw-r--r--indra/newview/lloutfitobserver.h3
-rw-r--r--indra/newview/lloutfitslist.cpp34
-rw-r--r--indra/newview/lloutfitslist.h5
-rw-r--r--indra/newview/llpaneleditwearable.cpp60
-rw-r--r--indra/newview/llpaneleditwearable.h7
-rw-r--r--indra/newview/llpanelgroup.cpp12
-rw-r--r--indra/newview/llpanelgroup.h3
-rw-r--r--indra/newview/llpanelgrouplandmoney.cpp8
-rw-r--r--indra/newview/llpanelgrouproles.cpp10
-rw-r--r--indra/newview/llpanelmaininventory.cpp3
-rw-r--r--indra/newview/llpanelobjectinventory.cpp2
-rw-r--r--indra/newview/llpaneloutfitedit.cpp12
-rw-r--r--indra/newview/llpaneloutfitedit.h2
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp2
-rw-r--r--indra/newview/llpanelplaceinfo.cpp13
-rw-r--r--indra/newview/llpanelplaceprofile.cpp9
-rw-r--r--indra/newview/llpanelplaceprofile.h2
-rw-r--r--indra/newview/llpanelplaces.cpp6
-rw-r--r--indra/newview/llplacesinventorybridge.cpp2
-rw-r--r--indra/newview/llpreviewgesture.cpp12
-rw-r--r--indra/newview/llpreviewtexture.cpp4
-rw-r--r--indra/newview/llsidepanelappearance.cpp21
-rw-r--r--indra/newview/llsidepanelinventory.cpp7
-rw-r--r--indra/newview/llsidepaneltaskinfo.h2
-rw-r--r--indra/newview/llsurface.cpp2
-rw-r--r--indra/newview/lltexlayer.cpp144
-rw-r--r--indra/newview/lltexlayer.h78
-rw-r--r--indra/newview/lltexlayerparams.cpp2
-rw-r--r--indra/newview/lltexturecache.cpp1
-rw-r--r--indra/newview/lltexturectrl.cpp30
-rw-r--r--indra/newview/lltexturefetch.cpp23
-rw-r--r--indra/newview/lltextureview.cpp4
-rw-r--r--indra/newview/lltoolmorph.cpp2
-rw-r--r--indra/newview/llviewerattachmenu.cpp2
-rw-r--r--indra/newview/llviewerinventory.cpp72
-rw-r--r--indra/newview/llviewerinventory.h5
-rw-r--r--indra/newview/llviewermenu.cpp120
-rw-r--r--indra/newview/llviewermessage.cpp39
-rw-r--r--indra/newview/llviewertexteditor.cpp50
-rw-r--r--indra/newview/llviewertexteditor.h7
-rw-r--r--indra/newview/llviewertexture.cpp55
-rw-r--r--indra/newview/llviewertexture.h16
-rw-r--r--indra/newview/llviewertexturelist.cpp15
-rw-r--r--indra/newview/llviewerwindow.cpp2
-rw-r--r--indra/newview/llvoavatar.cpp48
-rw-r--r--indra/newview/llvoavatar.h4
-rw-r--r--indra/newview/llvoavatarself.cpp23
-rw-r--r--indra/newview/llvograss.cpp56
-rw-r--r--indra/newview/llvotree.cpp8
-rw-r--r--indra/newview/llvotree.h1
-rw-r--r--indra/newview/llwearable.cpp5
-rw-r--r--indra/newview/llwearableitemslist.cpp88
-rw-r--r--indra/newview/llwearableitemslist.h73
-rw-r--r--indra/newview/llworldmap.cpp9
-rw-r--r--indra/newview/llworldmap.h2
-rw-r--r--indra/newview/skins/default/xui/da/menu_object.xml4
-rw-r--r--indra/newview/skins/default/xui/da/panel_nearby_media.xml2
-rw-r--r--indra/newview/skins/default/xui/da/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/de/menu_object.xml4
-rw-r--r--indra/newview/skins/default/xui/de/panel_nearby_media.xml2
-rw-r--r--indra/newview/skins/default/xui/de/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_buy_land.xml24
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_gesture.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_world_map.xml123
-rw-r--r--indra/newview/skins/default/xui/en/menu_attachment_self.xml3
-rw-r--r--indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_object.xml10
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml7
-rw-r--r--indra/newview/skins/default/xui/en/panel_classified.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_classified_info.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_classified.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_pick.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_wearable.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_notices.xml13
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_roles.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_my_profile.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_nearby_media.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_info.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_list_item.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_sound.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_teleport_history.xml8
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml33
-rw-r--r--indra/newview/skins/default/xui/en/widgets/accordion.xml6
-rw-r--r--indra/newview/skins/default/xui/es/menu_object.xml4
-rw-r--r--indra/newview/skins/default/xui/es/panel_nearby_media.xml2
-rw-r--r--indra/newview/skins/default/xui/es/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/floater_buy_currency.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/floater_water.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_windlight_options.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/menu_object.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/strings.xml5
-rw-r--r--indra/newview/skins/default/xui/it/menu_object.xml4
-rw-r--r--indra/newview/skins/default/xui/it/panel_nearby_media.xml2
-rw-r--r--indra/newview/skins/default/xui/it/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/ja/menu_object.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_nearby_media.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/pl/menu_object.xml4
-rw-r--r--indra/newview/skins/default/xui/pl/panel_nearby_media.xml2
-rw-r--r--indra/newview/skins/default/xui/pl/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/menu_object.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/panel_nearby_media.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/sidepanel_item_info.xml3
-rw-r--r--indra/newview/tests/lllogininstance_test.cpp10
149 files changed, 1828 insertions, 741 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index d51498f6d1..c2236233dc 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -585,7 +585,7 @@
<key>Value</key>
<integer>2</integer>
</map>
- <key>AvatarBakedTextureTimeout</key>
+ <key>AvatarBakedTextureUploadTimeout</key>
<map>
<key>Comment</key>
<string>Specifes the maximum time in seconds to wait before sending your baked textures for avatar appearance. Set to 0 to disable and wait until all baked textures are at highest resolution.</string>
@@ -594,8 +594,20 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <integer>120</integer>
+ <integer>60</integer>
</map>
+ <key>AvatarBakedLocalTextureUpdateTimeout</key>
+ <map>
+ <key>Comment</key>
+ <string>Specifes the maximum time in seconds to wait before updating your appearance during appearance mode.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>10</integer>
+ </map>
+
<key>AvatarSex</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 4e5fdb1219..7c92a5a756 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -3075,7 +3075,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
return;
}
- if (gAgentCamera.cameraCustomizeAvatar())
+ if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
{
// ignore baked textures when in customize mode
return;
@@ -3541,7 +3541,7 @@ void LLAgent::sendAgentSetAppearance()
{
if (!isAgentAvatarValid()) return;
- if (gAgentQueryManager.mNumPendingQueries > 0 && !gAgentCamera.cameraCustomizeAvatar())
+ if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && gAgentAvatarp->isUsingBakedTextures()))
{
return;
}
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 1ef9e34f87..4dc78e9a1d 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -941,7 +941,7 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction)
*/
}
- if( cameraCustomizeAvatar() )
+ if(cameraCustomizeAvatar())
{
new_distance = llclamp( new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM );
}
diff --git a/indra/newview/llagentlanguage.cpp b/indra/newview/llagentlanguage.cpp
index e97f136489..3d4e34a549 100644
--- a/indra/newview/llagentlanguage.cpp
+++ b/indra/newview/llagentlanguage.cpp
@@ -39,21 +39,35 @@
// library includes
#include "llui.h" // getLanguage()
-LLAgentLanguage::LLAgentLanguage()
+// static
+void LLAgentLanguage::init()
{
- gSavedSettings.getControl("Language")->getSignal()->connect(boost::bind(&update));
- gSavedSettings.getControl("InstallLanguage")->getSignal()->connect(boost::bind(&update));
- gSavedSettings.getControl("SystemLanguage")->getSignal()->connect(boost::bind(&update));
- gSavedSettings.getControl("LanguageIsPublic")->getSignal()->connect(boost::bind(&update));
+ gSavedSettings.getControl("Language")->getSignal()->connect(boost::bind(&onChange));
+ gSavedSettings.getControl("InstallLanguage")->getSignal()->connect(boost::bind(&onChange));
+ gSavedSettings.getControl("SystemLanguage")->getSignal()->connect(boost::bind(&onChange));
+ gSavedSettings.getControl("LanguageIsPublic")->getSignal()->connect(boost::bind(&onChange));
}
+// static
+void LLAgentLanguage::onChange()
+{
+ // Clear inventory cache so that default names of inventory items
+ // appear retranslated (EXT-8308).
+ gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE);
+}
// send language settings to the sim
// static
bool LLAgentLanguage::update()
{
LLSD body;
- std::string url = gAgent.getRegion()->getCapability("UpdateAgentLanguage");
+ std::string url;
+
+ if (gAgent.getRegion())
+ {
+ url = gAgent.getRegion()->getCapability("UpdateAgentLanguage");
+ }
+
if (!url.empty())
{
std::string language = LLUI::getLanguage();
diff --git a/indra/newview/llagentlanguage.h b/indra/newview/llagentlanguage.h
index 45348a1e50..d7e6f3c6c7 100644
--- a/indra/newview/llagentlanguage.h
+++ b/indra/newview/llagentlanguage.h
@@ -33,14 +33,14 @@
#ifndef LL_LLAGENTLANGUAGE_H
#define LL_LLAGENTLANGUAGE_H
-#include "llsingleton.h" // LLSingleton<>
-#include "llevent.h"
-
-class LLAgentLanguage: public LLSingleton<LLAgentLanguage>, public LLOldEvents::LLSimpleListener
+class LLAgentLanguage
{
public:
- LLAgentLanguage();
+ static void init();
static bool update();
+
+ private:
+ static void onChange();
};
#endif // LL_LLAGENTLANGUAGE_H
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index efa5eca217..6ee5a8b279 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -384,7 +384,8 @@ void LLAgentWearables::sendAgentWearablesUpdate()
gAgent.sendReliableMessage();
}
-void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update)
+void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update,
+ const std::string new_name)
{
LLWearable* old_wearable = getWearable(type, index);
if (old_wearable && (old_wearable->isDirty() || old_wearable->isOldVersion()))
@@ -402,6 +403,14 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
LLInventoryItem* item = gInventory.getItem(old_item_id);
if (item)
{
+ std::string item_name = item->getName();
+ bool name_changed = false;
+ if (!new_name.empty() && (new_name != item->getName()))
+ {
+ llinfos << "saveWearable changing name from " << item->getName() << " to " << new_name << llendl;
+ item_name = new_name;
+ name_changed = true;
+ }
// Update existing inventory item
LLPointer<LLViewerInventoryItem> template_item =
new LLViewerInventoryItem(item->getUUID(),
@@ -410,7 +419,7 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
new_wearable->getAssetID(),
new_wearable->getAssetType(),
item->getInventoryType(),
- item->getName(),
+ item_name,
item->getDescription(),
item->getSaleInfo(),
item->getFlags(),
@@ -418,6 +427,10 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
template_item->setTransactionID(new_wearable->getTransactionID());
template_item->updateServer(FALSE);
gInventory.updateItem(template_item);
+ if (name_changed)
+ {
+ gInventory.notifyObservers();
+ }
}
else
{
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index 8122971db6..f3457363a0 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -206,7 +206,8 @@ private:
//--------------------------------------------------------------------
public:
void saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found);
- void saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update = TRUE);
+ void saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update = TRUE,
+ const std::string new_name = "");
void saveAllWearables();
void revertWearable(const LLWearableType::EType type, const U32 index);
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 43f6be42b6..e1635461db 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -983,6 +983,10 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up
LLNotificationsUtil::add("CannotWearTrash");
return false;
}
+ else if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), LLAppearanceMgr::instance().getCOF())) // EXT-84911
+ {
+ return false;
+ }
switch (item_to_wear->getType())
{
@@ -1801,9 +1805,9 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool
llinfos << "wearInventoryCategory( " << category->getName()
<< " )" << llendl;
- callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal,
- &LLAppearanceMgr::instance(),
- category->getUUID(), copy, append));
+ callAfterCategoryFetch(category->getUUID(), boost::bind(&LLAppearanceMgr::wearCategoryFinal,
+ &LLAppearanceMgr::instance(),
+ category->getUUID(), copy, append));
}
void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append)
@@ -2217,6 +2221,7 @@ void LLAppearanceMgr::updateIsDirty()
LLViewerInventoryItem *item2 = outfit_items.get(i);
if (item1->getLinkedUUID() != item2->getLinkedUUID() ||
+ item1->getName() != item2->getName() ||
item1->LLInventoryItem::getDescription() != item2->LLInventoryItem::getDescription())
{
mOutfitIsDirty = true;
@@ -2706,6 +2711,21 @@ BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const
return gInventory.isObjectDescendentOf(obj_id, getCOF());
}
+// static
+bool LLAppearanceMgr::isLinkInCOF(const LLUUID& obj_id)
+{
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ LLLinkedItemIDMatches find_links(gInventory.getLinkedItemID(obj_id));
+ gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(),
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ find_links);
+
+ return !items.empty();
+}
+
BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const
{
if (!getIsInCOF(obj_id)) return FALSE;
@@ -2733,3 +2753,192 @@ BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const
return FALSE;
*/
}
+
+// Shim class to allow arbitrary boost::bind
+// expressions to be run as one-time idle callbacks.
+//
+// TODO: rework idle function spec to take a boost::function in the first place.
+class OnIdleCallbackOneTime
+{
+public:
+ OnIdleCallbackOneTime(nullary_func_t callable):
+ mCallable(callable)
+ {
+ }
+ static void onIdle(void *data)
+ {
+ gIdleCallbacks.deleteFunction(onIdle, data);
+ OnIdleCallbackOneTime* self = reinterpret_cast<OnIdleCallbackOneTime*>(data);
+ self->call();
+ delete self;
+ }
+ void call()
+ {
+ mCallable();
+ }
+private:
+ nullary_func_t mCallable;
+};
+
+void doOnIdleOneTime(nullary_func_t callable)
+{
+ OnIdleCallbackOneTime* cb_functor = new OnIdleCallbackOneTime(callable);
+ gIdleCallbacks.addFunction(&OnIdleCallbackOneTime::onIdle,cb_functor);
+}
+
+// Shim class to allow generic boost functions to be run as
+// recurring idle callbacks. Callable should return true when done,
+// false to continue getting called.
+//
+// TODO: rework idle function spec to take a boost::function in the first place.
+class OnIdleCallbackRepeating
+{
+public:
+ OnIdleCallbackRepeating(bool_func_t callable):
+ mCallable(callable)
+ {
+ }
+ // Will keep getting called until the callable returns true.
+ static void onIdle(void *data)
+ {
+ OnIdleCallbackRepeating* self = reinterpret_cast<OnIdleCallbackRepeating*>(data);
+ bool done = self->call();
+ if (done)
+ {
+ gIdleCallbacks.deleteFunction(onIdle, data);
+ delete self;
+ }
+ }
+ bool call()
+ {
+ return mCallable();
+ }
+private:
+ bool_func_t mCallable;
+};
+
+void doOnIdleRepeating(bool_func_t callable)
+{
+ OnIdleCallbackRepeating* cb_functor = new OnIdleCallbackRepeating(callable);
+ gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor);
+}
+
+class CallAfterCategoryFetchStage2: public LLInventoryFetchItemsObserver
+{
+public:
+ CallAfterCategoryFetchStage2(const uuid_vec_t& ids,
+ nullary_func_t callable) :
+ LLInventoryFetchItemsObserver(ids),
+ mCallable(callable)
+ {
+ }
+ ~CallAfterCategoryFetchStage2()
+ {
+ }
+ virtual void done()
+ {
+ llinfos << this << " done with incomplete " << mIncomplete.size()
+ << " complete " << mComplete.size() << " calling callable" << llendl;
+
+ gInventory.removeObserver(this);
+ doOnIdleOneTime(mCallable);
+ delete this;
+ }
+protected:
+ nullary_func_t mCallable;
+};
+
+class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver
+{
+public:
+ CallAfterCategoryFetchStage1(const LLUUID& cat_id, nullary_func_t callable) :
+ LLInventoryFetchDescendentsObserver(cat_id),
+ mCallable(callable)
+ {
+ }
+ ~CallAfterCategoryFetchStage1()
+ {
+ }
+ virtual void done()
+ {
+ // What we do here is get the complete information on the items in
+ // the library, and set up an observer that will wait for that to
+ // happen.
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+ gInventory.collectDescendents(mComplete.front(),
+ cat_array,
+ item_array,
+ LLInventoryModel::EXCLUDE_TRASH);
+ S32 count = item_array.count();
+ if(!count)
+ {
+ llwarns << "Nothing fetched in category " << mComplete.front()
+ << llendl;
+ //dec_busy_count();
+ gInventory.removeObserver(this);
+
+ // lets notify observers that loading is finished.
+ gAgentWearables.notifyLoadingFinished();
+ delete this;
+ return;
+ }
+
+ llinfos << "stage1 got " << item_array.count() << " items, passing to stage2 " << llendl;
+ uuid_vec_t ids;
+ for(S32 i = 0; i < count; ++i)
+ {
+ ids.push_back(item_array.get(i)->getUUID());
+ }
+
+ gInventory.removeObserver(this);
+
+ // do the fetch
+ CallAfterCategoryFetchStage2 *stage2 = new CallAfterCategoryFetchStage2(ids, mCallable);
+ stage2->startFetch();
+ if(stage2->isFinished())
+ {
+ // everything is already here - call done.
+ stage2->done();
+ }
+ else
+ {
+ // it's all on it's way - add an observer, and the inventory
+ // will call done for us when everything is here.
+ gInventory.addObserver(stage2);
+ }
+ delete this;
+ }
+protected:
+ nullary_func_t mCallable;
+};
+
+void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb)
+{
+ CallAfterCategoryFetchStage1 *stage1 = new CallAfterCategoryFetchStage1(cat_id, cb);
+ stage1->startFetch();
+ if (stage1->isFinished())
+ {
+ stage1->done();
+ }
+ else
+ {
+ gInventory.addObserver(stage1);
+ }
+}
+
+void wear_multiple(const uuid_vec_t& ids, bool replace)
+{
+ LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
+
+ bool first = true;
+ uuid_vec_t::const_iterator it;
+ for (it = ids.begin(); it != ids.end(); ++it)
+ {
+ // if replace is requested, the first item worn will replace the current top
+ // item, and others will be added.
+ LLAppearanceMgr::instance().wearItemOnAvatar(*it,false,first && replace,cb);
+ first = false;
+ }
+}
+
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 84c911c038..9f554dbdef 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -223,6 +223,11 @@ public:
BOOL getIsInCOF(const LLUUID& obj_id) const;
// Is this in the COF and can the user delete it from the COF?
BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const;
+
+ /**
+ * Checks if COF contains link to specified object.
+ */
+ static bool isLinkInCOF(const LLUUID& obj_id);
};
class LLUpdateAppearanceOnDestroy: public LLInventoryCallback
@@ -242,180 +247,19 @@ private:
LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name);
-// Shim class and template function to allow arbitrary boost::bind
-// expressions to be run as one-time idle callbacks.
-template <typename T>
-class OnIdleCallbackOneTime
-{
-public:
- OnIdleCallbackOneTime(T callable):
- mCallable(callable)
- {
- }
- static void onIdle(void *data)
- {
- gIdleCallbacks.deleteFunction(onIdle, data);
- OnIdleCallbackOneTime<T>* self = reinterpret_cast<OnIdleCallbackOneTime<T>*>(data);
- self->call();
- delete self;
- }
- void call()
- {
- mCallable();
- }
-private:
- T mCallable;
-};
+typedef boost::function<void ()> nullary_func_t;
+typedef boost::function<bool ()> bool_func_t;
-template <typename T>
-void doOnIdleOneTime(T callable)
-{
- OnIdleCallbackOneTime<T>* cb_functor = new OnIdleCallbackOneTime<T>(callable);
- gIdleCallbacks.addFunction(&OnIdleCallbackOneTime<T>::onIdle,cb_functor);
-}
-
-// Shim class and template function to allow arbitrary boost::bind
-// expressions to be run as recurring idle callbacks.
-// Callable should return true when done, false to continue getting called.
-template <typename T>
-class OnIdleCallbackRepeating
-{
-public:
- OnIdleCallbackRepeating(T callable):
- mCallable(callable)
- {
- }
- // Will keep getting called until the callable returns true.
- static void onIdle(void *data)
- {
- OnIdleCallbackRepeating<T>* self = reinterpret_cast<OnIdleCallbackRepeating<T>*>(data);
- bool done = self->call();
- if (done)
- {
- gIdleCallbacks.deleteFunction(onIdle, data);
- delete self;
- }
- }
- bool call()
- {
- return mCallable();
- }
-private:
- T mCallable;
-};
+// Call a given callable once in idle loop.
+void doOnIdleOneTime(nullary_func_t callable);
-template <typename T>
-void doOnIdleRepeating(T callable)
-{
- OnIdleCallbackRepeating<T>* cb_functor = new OnIdleCallbackRepeating<T>(callable);
- gIdleCallbacks.addFunction(&OnIdleCallbackRepeating<T>::onIdle,cb_functor);
-}
+// Repeatedly call a callable in idle loop until it returns true.
+void doOnIdleRepeating(bool_func_t callable);
-template <class T>
-class CallAfterCategoryFetchStage2: public LLInventoryFetchItemsObserver
-{
-public:
- CallAfterCategoryFetchStage2(const uuid_vec_t& ids,
- T callable) :
- LLInventoryFetchItemsObserver(ids),
- mCallable(callable)
- {
- }
- ~CallAfterCategoryFetchStage2()
- {
- }
- virtual void done()
- {
- llinfos << this << " done with incomplete " << mIncomplete.size()
- << " complete " << mComplete.size() << " calling callable" << llendl;
-
- gInventory.removeObserver(this);
- doOnIdleOneTime(mCallable);
- delete this;
- }
-protected:
- T mCallable;
-};
+// Invoke a given callable after category contents are fully fetched.
+void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb);
-template <class T>
-class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver
-{
-public:
- CallAfterCategoryFetchStage1(const LLUUID& cat_id, T callable) :
- LLInventoryFetchDescendentsObserver(cat_id),
- mCallable(callable)
- {
- }
- ~CallAfterCategoryFetchStage1()
- {
- }
- virtual void done()
- {
- // What we do here is get the complete information on the items in
- // the library, and set up an observer that will wait for that to
- // happen.
- LLInventoryModel::cat_array_t cat_array;
- LLInventoryModel::item_array_t item_array;
- gInventory.collectDescendents(mComplete.front(),
- cat_array,
- item_array,
- LLInventoryModel::EXCLUDE_TRASH);
- S32 count = item_array.count();
- if(!count)
- {
- llwarns << "Nothing fetched in category " << mComplete.front()
- << llendl;
- //dec_busy_count();
- gInventory.removeObserver(this);
-
- // lets notify observers that loading is finished.
- gAgentWearables.notifyLoadingFinished();
- delete this;
- return;
- }
-
- llinfos << "stage1 got " << item_array.count() << " items, passing to stage2 " << llendl;
- uuid_vec_t ids;
- for(S32 i = 0; i < count; ++i)
- {
- ids.push_back(item_array.get(i)->getUUID());
- }
-
- gInventory.removeObserver(this);
-
- // do the fetch
- CallAfterCategoryFetchStage2<T> *stage2 = new CallAfterCategoryFetchStage2<T>(ids, mCallable);
- stage2->startFetch();
- if(stage2->isFinished())
- {
- // everything is already here - call done.
- stage2->done();
- }
- else
- {
- // it's all on it's way - add an observer, and the inventory
- // will call done for us when everything is here.
- gInventory.addObserver(stage2);
- }
- delete this;
- }
-protected:
- T mCallable;
-};
-
-template <class T>
-void callAfterCategoryFetch(const LLUUID& cat_id, T callable)
-{
- CallAfterCategoryFetchStage1<T> *stage1 = new CallAfterCategoryFetchStage1<T>(cat_id, callable);
- stage1->startFetch();
- if (stage1->isFinished())
- {
- stage1->done();
- }
- else
- {
- gInventory.addObserver(stage1);
- }
-}
+// Wear all items in a uuid vector.
+void wear_multiple(const uuid_vec_t& ids, bool replace);
#endif
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 682e3eb874..58b651ec39 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -45,6 +45,7 @@
#include "llgroupmgr.h"
#include "llagent.h"
#include "llagentcamera.h"
+#include "llagentlanguage.h"
#include "llagentwearables.h"
#include "llwindow.h"
#include "llviewerstats.h"
@@ -356,7 +357,7 @@ static void ui_audio_callback(const LLUUID& uuid)
bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
{
- if(!match || !base)
+ if(!match || !base || base->getPlainText())
return false;
LLUUID match_id = match->getID();
@@ -385,7 +386,7 @@ bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
params.view = icon;
params.left_pad = 4;
params.right_pad = 4;
- params.top_pad = 2;
+ params.top_pad = -2;
params.bottom_pad = 2;
base->appendWidget(params," ",false);
@@ -946,6 +947,8 @@ bool LLAppViewer::init()
LLStringOps::sPM = LLTrans::getString("dateTimePM");
}
+ LLAgentLanguage::init();
+
return true;
}
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 752a2e7504..1e59e5b805 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -550,9 +550,10 @@ namespace action_give_inventory
}
LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
- if (NULL == active_panel)
+ if (!active_panel)
{
- return;
+ active_panel = get_outfit_editor_inventory_panel();
+ if (!active_panel) return;
}
const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList();
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index c0fa910f86..7c33923f04 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -111,6 +111,12 @@ public:
return pInstance;
}
+ ~LLChatHistoryHeader()
+ {
+ // Detach the info button so that it doesn't get destroyed (EXT-8463).
+ hideInfoCtrl();
+ }
+
BOOL handleMouseUp(S32 x, S32 y, MASK mask)
{
return LLPanel::handleMouseUp(x,y,mask);
@@ -382,8 +388,18 @@ protected:
if (!sInfoCtrl)
{
+ // *TODO: Delete the button at exit.
sInfoCtrl = LLUICtrlFactory::createFromFile<LLUICtrl>("inspector_info_ctrl.xml", NULL, LLPanel::child_registry_t::instance());
- sInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, sInfoCtrl));
+ if (sInfoCtrl)
+ {
+ sInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, sInfoCtrl));
+ }
+ }
+
+ if (!sInfoCtrl)
+ {
+ llassert(sInfoCtrl != NULL);
+ return;
}
LLTextBase* name = getChild<LLTextBase>("user_name");
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index 4c0f51056d..629a92db11 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -283,7 +283,8 @@ LLCOFWearables::LLCOFWearables() : LLPanel(),
mClothingTab(NULL),
mAttachmentsTab(NULL),
mBodyPartsTab(NULL),
- mLastSelectedTab(NULL)
+ mLastSelectedTab(NULL),
+ mAccordionCtrl(NULL)
{
mClothingMenu = new CofClothingContextMenu(this);
mAttachmentMenu = new CofAttachmentContextMenu(this);
@@ -335,6 +336,8 @@ BOOL LLCOFWearables::postBuild()
mTab2AssetType[mAttachmentsTab] = LLAssetType::AT_OBJECT;
mTab2AssetType[mBodyPartsTab] = LLAssetType::AT_BODYPART;
+ mAccordionCtrl = getChild<LLAccordionCtrl>("cof_wearables_accordion");
+
return LLPanel::postBuild();
}
@@ -633,18 +636,35 @@ LLAssetType::EType LLCOFWearables::getExpandedAccordionAssetType()
typedef std::map<std::string, LLAssetType::EType> type_map_t;
static type_map_t type_map;
- static LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("cof_wearables_accordion");
- const LLAccordionCtrlTab* expanded_tab = accordion_ctrl->getExpandedTab();
- return get_if_there(mTab2AssetType, expanded_tab, LLAssetType::AT_NONE);
+ if (mAccordionCtrl != NULL)
+ {
+ const LLAccordionCtrlTab* expanded_tab = mAccordionCtrl->getExpandedTab();
+
+ return get_if_there(mTab2AssetType, expanded_tab, LLAssetType::AT_NONE);
+ }
+
+ return LLAssetType::AT_NONE;
}
LLAssetType::EType LLCOFWearables::getSelectedAccordionAssetType()
{
- static LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("cof_wearables_accordion");
- const LLAccordionCtrlTab* selected_tab = accordion_ctrl->getSelectedTab();
+ if (mAccordionCtrl != NULL)
+ {
+ const LLAccordionCtrlTab* selected_tab = mAccordionCtrl->getSelectedTab();
- return get_if_there(mTab2AssetType, selected_tab, LLAssetType::AT_NONE);
+ return get_if_there(mTab2AssetType, selected_tab, LLAssetType::AT_NONE);
+ }
+
+ return LLAssetType::AT_NONE;
+}
+
+void LLCOFWearables::expandDefaultAccordionTab()
+{
+ if (mAccordionCtrl != NULL)
+ {
+ mAccordionCtrl->expandDefaultTab();
+ }
}
void LLCOFWearables::onListRightClick(LLUICtrl* ctrl, S32 x, S32 y, LLListContextMenu* menu)
diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h
index 0518d59df3..9a259600a9 100644
--- a/indra/newview/llcofwearables.h
+++ b/indra/newview/llcofwearables.h
@@ -40,6 +40,7 @@
#include "llappearancemgr.h"
#include "llinventorymodel.h"
+class LLAccordionCtrl;
class LLAccordionCtrlTab;
class LLListContextMenu;
class LLPanelClothingListItem;
@@ -86,6 +87,7 @@ public:
LLAssetType::EType getExpandedAccordionAssetType();
LLAssetType::EType getSelectedAccordionAssetType();
+ void expandDefaultAccordionTab();
LLCOFCallbacks& getCOFCallbacks() { return mCOFCallbacks; }
@@ -123,6 +125,8 @@ protected:
LLListContextMenu* mClothingMenu;
LLListContextMenu* mAttachmentMenu;
LLListContextMenu* mBodyPartMenu;
+
+ LLAccordionCtrl* mAccordionCtrl;
};
diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp
index fd3df359bd..7ebcef943e 100644
--- a/indra/newview/llcurrencyuimanager.cpp
+++ b/indra/newview/llcurrencyuimanager.cpp
@@ -35,6 +35,8 @@
#include "lluictrlfactory.h"
#include "lltextbox.h"
#include "lllineeditor.h"
+#include "llresmgr.h" // for LLLocale
+#include "lltrans.h"
#include "llviewercontrol.h"
#include "llversioninfo.h"
@@ -323,7 +325,12 @@ std::string LLCurrencyUIManager::Impl::getLocalEstimate() const
if (mUSDCurrencyEstimated)
{
// we have the old-style USD-specific value
- return "US$ " + llformat("%#.2f", mUSDCurrencyEstimatedCost / 100.0);
+ LLStringUtil::format_map_t args;
+ {
+ LLLocale locale_override(LLStringUtil::getLocale());
+ args["[AMOUNT]"] = llformat("%#.2f", mUSDCurrencyEstimatedCost / 100.0);
+ }
+ return LLTrans::getString("LocalEstimateUSD", args);
}
return "";
}
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 68809b0926..c206daf89b 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -149,7 +149,7 @@ void LLStandardBumpmap::restoreGL()
0,
0);
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLViewerTexture::BOOST_BUMP) ;
- gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL, NULL );
+ gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL );
LLStandardBumpmap::sStandardBumpmapCount++;
}
@@ -923,7 +923,7 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText
// Note: this may create an LLImageGL immediately
src_image->setBoostLevel(LLViewerTexture::BOOST_BUMP) ;
- src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL, NULL );
+ src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL );
bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image
// bump_total++;
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index c423473740..bb4e6c7a3e 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -167,6 +167,10 @@ void LLViewerDynamicTexture::postRender(BOOL success)
{
generateGLTexture() ;
}
+ if(!mGLTexturep->getHasGLTexture())
+ {
+ generateGLTexture() ;
+ }
llcallstacks << "class type: " << (S32)getType() << llcallstacksendl ;
success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index dbbcb6e7c4..f299518474 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -1364,7 +1364,7 @@ F32 LLFace::getTextureVirtualSize()
F32 cos_angle_to_view_dir;
BOOL in_frustum = calcPixelArea(cos_angle_to_view_dir, radius);
- if (mPixelArea < 0.0001f || !in_frustum)
+ if (mPixelArea < F_ALMOST_ZERO || !in_frustum)
{
setVirtualSize(0.f) ;
return 0.f;
diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp
index c71764c2e5..3952c54670 100644
--- a/indra/newview/llfloatergroups.cpp
+++ b/indra/newview/llfloatergroups.cpp
@@ -47,6 +47,7 @@
#include "llbutton.h"
#include "llgroupactions.h"
#include "llscrolllistctrl.h"
+#include "llselectmgr.h"
#include "lltextbox.h"
#include "lluictrlfactory.h"
#include "lltrans.h"
@@ -89,6 +90,7 @@ BOOL LLFloaterGroupPicker::postBuild()
list_ctrl->setContextMenu(LLScrollListCtrl::MENU_GROUP);
}
+ LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterGroupPicker::onBtnCancel, this));
childSetAction("OK", onBtnOK, this);
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 913bb676b0..f0ed659f5a 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -2088,7 +2088,8 @@ void LLPanelLandOptions::refresh()
LLStyle::Params style;
style.image(LLUI::getUIImage(gFloaterView->getParentFloater(this)->getString("maturity_icon_moderate")));
LLCheckBoxWithTBAcess* fullaccess_mature_ctrl = (LLCheckBoxWithTBAcess*)mMatureCtrl;
- fullaccess_mature_ctrl->getTextBox()->setText(std::string("icon"),style);
+ fullaccess_mature_ctrl->getTextBox()->setText(LLStringExplicit(""));
+ fullaccess_mature_ctrl->getTextBox()->appendImageSegment(style);
fullaccess_mature_ctrl->getTextBox()->appendText(getString("mature_check_mature"), false);
fullaccess_mature_ctrl->setToolTip(getString("mature_check_mature_tooltip"));
fullaccess_mature_ctrl->reshape(fullaccess_mature_ctrl->getRect().getWidth(), fullaccess_mature_ctrl->getRect().getHeight(), FALSE);
diff --git a/indra/newview/llfloatervoicedevicesettings.cpp b/indra/newview/llfloatervoicedevicesettings.cpp
index 63365e3461..48095ff200 100644
--- a/indra/newview/llfloatervoicedevicesettings.cpp
+++ b/indra/newview/llfloatervoicedevicesettings.cpp
@@ -227,7 +227,23 @@ void LLPanelVoiceDeviceSettings::refresh()
iter != LLVoiceClient::getInstance()->getCaptureDevices().end();
iter++)
{
- mCtrlInputDevices->add( *iter, ADD_BOTTOM );
+ // Lets try to localize some system device names. EXT-8375
+ std::string device_name = *iter;
+ LLStringUtil::toLower(device_name); //compare in low case
+ if ("default system device" == device_name)
+ {
+ device_name = getString(device_name);
+ }
+ else if ("no device" == device_name)
+ {
+ device_name = getString(device_name);
+ }
+ else
+ {
+ // restore original value
+ device_name = *iter;
+ }
+ mCtrlInputDevices->add(device_name, ADD_BOTTOM );
}
if(!mCtrlInputDevices->setSimple(mInputDevice))
@@ -244,7 +260,23 @@ void LLPanelVoiceDeviceSettings::refresh()
for(iter= LLVoiceClient::getInstance()->getRenderDevices().begin();
iter != LLVoiceClient::getInstance()->getRenderDevices().end(); iter++)
{
- mCtrlOutputDevices->add( *iter, ADD_BOTTOM );
+ // Lets try to localize some system device names. EXT-8375
+ std::string device_name = *iter;
+ LLStringUtil::toLower(device_name); //compare in low case
+ if ("default system device" == device_name)
+ {
+ device_name = getString(device_name);
+ }
+ else if ("no device" == device_name)
+ {
+ device_name = getString(device_name);
+ }
+ else
+ {
+ // restore original value
+ device_name = *iter;
+ }
+ mCtrlOutputDevices->add(device_name, ADD_BOTTOM );
}
if(!mCtrlOutputDevices->setSimple(mOutputDevice))
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 983fd97b0b..88f8545877 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -206,6 +206,7 @@ LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key)
mFactoryMap["objects_mapview"] = LLCallbackMap(createWorldMapView, NULL);
//Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_world_map.xml", FALSE);
+ mCommitCallbackRegistrar.add("WMap.Coordinates", boost::bind(&LLFloaterWorldMap::onCoordinatesCommit, this));
mCommitCallbackRegistrar.add("WMap.Location", boost::bind(&LLFloaterWorldMap::onLocationCommit, this));
mCommitCallbackRegistrar.add("WMap.AvatarCombo", boost::bind(&LLFloaterWorldMap::onAvatarComboCommit, this));
mCommitCallbackRegistrar.add("WMap.Landmark", boost::bind(&LLFloaterWorldMap::onLandmarkComboCommit, this));
@@ -336,8 +337,6 @@ void LLFloaterWorldMap::onOpen(const LLSD& key)
}
}
-
-
// static
void LLFloaterWorldMap::reloadIcons(void*)
{
@@ -582,6 +581,10 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
S32 world_y = S32(pos_global.mdV[1] / 256);
LLWorldMapMessage::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true);
setDefaultBtn("");
+
+ // clicked on a non-region - turn off coord display
+ enableTeleportCoordsDisplay( false );
+
return;
}
if (sim_info->isDown())
@@ -592,6 +595,10 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
LLWorldMap::getInstance()->setTrackingInvalid();
LLTracker::stopTracking(NULL);
setDefaultBtn("");
+
+ // clicked on a down region - turn off coord display
+ enableTeleportCoordsDisplay( false );
+
return;
}
@@ -609,9 +616,40 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
LLTracker::trackLocation(pos_global, full_name, tooltip);
LLWorldMap::getInstance()->cancelTracking(); // The floater is taking over the tracking
+ LLVector3d coord_pos = LLTracker::getTrackedPositionGlobal();
+ updateTeleportCoordsDisplay( coord_pos );
+
+ // we have a valid region - turn on coord display
+ enableTeleportCoordsDisplay( true );
+
setDefaultBtn("Teleport");
}
+// enable/disable teleport destination coordinates
+void LLFloaterWorldMap::enableTeleportCoordsDisplay( bool enabled )
+{
+ childSetEnabled("teleport_coordinate_x", enabled );
+ childSetEnabled("teleport_coordinate_y", enabled );
+ childSetEnabled("teleport_coordinate_z", enabled );
+}
+
+// update display of teleport destination coordinates - pos is in global coordinates
+void LLFloaterWorldMap::updateTeleportCoordsDisplay( const LLVector3d& pos )
+{
+ // if we're going to update their value, we should also enable them
+ enableTeleportCoordsDisplay( true );
+
+ // convert global specified position to a local one
+ F32 region_local_x = (F32)fmod( pos.mdV[VX], (F64)REGION_WIDTH_METERS );
+ F32 region_local_y = (F32)fmod( pos.mdV[VY], (F64)REGION_WIDTH_METERS );
+ F32 region_local_z = (F32)fmod( pos.mdV[VZ], (F64)REGION_WIDTH_METERS );
+
+ // write in the values
+ childSetValue("teleport_coordinate_x", region_local_x );
+ childSetValue("teleport_coordinate_y", region_local_y );
+ childSetValue("teleport_coordinate_z", region_local_z );
+}
+
void LLFloaterWorldMap::updateLocation()
{
bool gotSimName;
@@ -638,6 +676,9 @@ void LLFloaterWorldMap::updateLocation()
// Fill out the location field
childSetValue("location", agent_sim_name);
+ // update the coordinate display with location of avatar in region
+ updateTeleportCoordsDisplay( agentPos );
+
// Figure out where user is
// Set the current SLURL
mSLURL = LLSLURL(agent_sim_name, gAgent.getPositionGlobal());
@@ -668,6 +709,10 @@ void LLFloaterWorldMap::updateLocation()
childSetValue("location", sim_name);
+ // refresh coordinate display to reflect where user clicked.
+ LLVector3d coord_pos = LLTracker::getTrackedPositionGlobal();
+ updateTeleportCoordsDisplay( coord_pos );
+
// simNameFromPosGlobal can fail, so don't give the user an invalid SLURL
if ( gotSimName )
{
@@ -1139,6 +1184,22 @@ void LLFloaterWorldMap::onLocationCommit()
}
}
+void LLFloaterWorldMap::onCoordinatesCommit()
+{
+ if( mIsClosing )
+ {
+ return;
+ }
+
+ S32 x_coord = (S32)childGetValue("teleport_coordinate_x").asReal();
+ S32 y_coord = (S32)childGetValue("teleport_coordinate_y").asReal();
+ S32 z_coord = (S32)childGetValue("teleport_coordinate_z").asReal();
+
+ const std::string region_name = childGetValue("location").asString();
+
+ trackURL( region_name, x_coord, y_coord, z_coord );
+}
+
void LLFloaterWorldMap::onClearBtn()
{
mTrackedStatus = LLTracker::TRACKING_NOTHING;
@@ -1199,6 +1260,9 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate)
else if(LLWorldMap::getInstance()->isTracking())
{
pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal() - gAgentCamera.getCameraPositionGlobal();;
+
+
+
}
else
{
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index 550b4ef689..e31bafaf9b 100644
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
@@ -149,6 +149,7 @@ protected:
void updateSearchEnabled();
void onLocationFocusChanged( LLFocusableElement* ctrl );
void onLocationCommit();
+ void onCoordinatesCommit();
void onCommitSearchResult();
void cacheLandmarkPosition();
@@ -160,6 +161,12 @@ private:
F32 mCurZoomVal;
LLFrameTimer mZoomTimer;
+ // update display of teleport destination coordinates - pos is in global coordinates
+ void updateTeleportCoordsDisplay( const LLVector3d& pos );
+
+ // enable/disable teleport destination coordinates
+ void enableTeleportCoordsDisplay( bool enabled );
+
LLDynamicArray<LLUUID> mLandmarkAssetIDList;
LLDynamicArray<LLUUID> mLandmarkItemIDList;
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 87c5a830e9..5aa504eb35 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -1195,7 +1195,7 @@ void LLFolderView::propertiesSelectedItems( void )
void LLFolderView::changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type)
{
- LLFolderBridge *folder_bridge = LLFolderBridge::sSelf;
+ LLFolderBridge *folder_bridge = LLFolderBridge::sSelf.get();
if (!folder_bridge) return;
LLViewerInventoryCategory *cat = folder_bridge->getCategory();
@@ -1874,13 +1874,18 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
}
// Successively filter out invalid options
- selected_items_t::iterator item_itor;
+
U32 flags = FIRST_SELECTED_ITEM;
- for (item_itor = mSelectedItems.begin(); item_itor != mSelectedItems.end(); ++item_itor)
+ for (selected_items_t::iterator item_itor = mSelectedItems.begin();
+ item_itor != mSelectedItems.end();
+ ++item_itor)
{
- (*item_itor)->buildContextMenu(*menu, flags);
+ LLFolderViewItem* selected_item = (*item_itor);
+ selected_item->buildContextMenu(*menu, flags);
flags = 0x0;
}
+
+ addNoOptions(menu);
menu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, menu, x, y);
@@ -1889,7 +1894,7 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
}
else
{
- if(menu && menu->getVisible())
+ if (menu && menu->getVisible())
{
menu->setVisible(FALSE);
}
@@ -1898,6 +1903,37 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
return handled;
}
+// Add "--no options--" if the menu is completely blank.
+BOOL LLFolderView::addNoOptions(LLMenuGL* menu) const
+{
+ const std::string nooptions_str = "--no options--";
+ LLView *nooptions_item = NULL;
+
+ const LLView::child_list_t *list = menu->getChildList();
+ for (LLView::child_list_t::const_iterator itor = list->begin();
+ itor != list->end();
+ ++itor)
+ {
+ LLView *menu_item = (*itor);
+ if (menu_item->getVisible())
+ {
+ return FALSE;
+ }
+ std::string name = menu_item->getName();
+ if (menu_item->getName() == nooptions_str)
+ {
+ nooptions_item = menu_item;
+ }
+ }
+ if (nooptions_item)
+ {
+ nooptions_item->setVisible(TRUE);
+ nooptions_item->setEnabled(FALSE);
+ return TRUE;
+ }
+ return FALSE;
+}
+
BOOL LLFolderView::handleHover( S32 x, S32 y, MASK mask )
{
return LLView::handleHover( x, y, mask );
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 55eb543f5f..24cd7b8018 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -262,6 +262,7 @@ public:
BOOL needsAutoSelect() { return mNeedsAutoSelect && !mAutoSelectOverride; }
BOOL needsAutoRename() { return mNeedsAutoRename; }
void setNeedsAutoRename(BOOL val) { mNeedsAutoRename = val; }
+ void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; }
void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
@@ -290,6 +291,8 @@ protected:
bool selectFirstItem();
bool selectLastItem();
+ BOOL addNoOptions(LLMenuGL* menu) const;
+
protected:
LLHandle<LLView> mPopupMenuHandle;
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 996553ccf7..d464b67105 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -903,7 +903,15 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
if (member_id.notNull())
{
- formatDateString(online_status); // reformat for sorting, e.g. 12/25/2008 -> 2008/12/25
+ if (online_status == "Online")
+ {
+ static std::string localized_online(LLTrans::getString("group_member_status_online"));
+ online_status = localized_online;
+ }
+ else
+ {
+ formatDateString(online_status); // reformat for sorting, e.g. 12/25/2008 -> 2008/12/25
+ }
//llinfos << "Member " << member_id << " has powers " << std::hex << agent_powers << std::dec << llendl;
LLGroupMemberData* newdata = new LLGroupMemberData(member_id,
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 7ec6440dc3..38f3521b2d 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -952,6 +952,8 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid)
BOOL LLInvFVBridge::canShare() const
{
+ if (!isAgentInventory()) return FALSE;
+
const LLInventoryModel* model = getInventoryModel();
if (!model) return FALSE;
@@ -963,9 +965,10 @@ BOOL LLInvFVBridge::canShare() const
return (BOOL)LLGiveInventory::isInventoryGiveAcceptable(item);
}
- // All categories can be given.
- const LLViewerInventoryCategory* cat = model->getCategory(mUUID);
- return (cat != NULL);
+ // Categories can be given.
+ if (model->getCategory(mUUID)) return TRUE;
+
+ return FALSE;
}
// +=================================================+
@@ -1444,7 +1447,7 @@ bool LLItemBridge::isRemoveAction(std::string action) const
// | LLFolderBridge |
// +=================================================+
-LLFolderBridge* LLFolderBridge::sSelf=NULL;
+LLHandle<LLFolderBridge> LLFolderBridge::sSelf;
// Can be moved to another folder
BOOL LLFolderBridge::isItemMovable() const
@@ -2388,8 +2391,11 @@ void LLFolderBridge::pasteLinkFromClipboard()
void LLFolderBridge::staticFolderOptionsMenu()
{
- if (!sSelf) return;
- sSelf->folderOptionsMenu();
+ LLFolderBridge* selfp = sSelf.get();
+ if (selfp)
+ {
+ selfp->folderOptionsMenu();
+ }
}
void LLFolderBridge::folderOptionsMenu()
@@ -2466,11 +2472,15 @@ void LLFolderBridge::folderOptionsMenu()
}
mItems.push_back(std::string("Outfit Separator"));
}
- hide_context_entries(*mMenu, mItems, disabled_items, TRUE);
+ LLMenuGL* menup = dynamic_cast<LLMenuGL*>(mMenu.get());
+ if (menup)
+ {
+ hide_context_entries(*menup, mItems, disabled_items, TRUE);
- // Reposition the menu, in case we're adding items to an existing menu.
- mMenu->needsArrange();
- mMenu->arrangeAndClear();
+ // Reposition the menu, in case we're adding items to an existing menu.
+ menup->needsArrange();
+ menup->arrangeAndClear();
+ }
}
BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& is_type)
@@ -2512,6 +2522,10 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
mDisabledItems.push_back(std::string("New Body Parts"));
}
+ // clear out old menu and folder pointers
+ mMenu.markDead();
+ sSelf.markDead();
+
if(trash_id == mUUID)
{
// This is the trash.
@@ -2587,9 +2601,6 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
mWearables=TRUE;
}
-
- mMenu = &menu;
- sSelf = this;
}
// Preemptively disable system folder removal if more than one item selected.
@@ -2604,12 +2615,6 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
mDisabledItems.push_back(std::string("Share"));
}
- if (mItems.empty())
- {
- mItems.push_back(std::string("--no options--"));
- mDisabledItems.push_back(std::string("--no options--"));
- }
-
hide_context_entries(menu, mItems, mDisabledItems);
// Add menu items that are dependent on the contents of the folder.
@@ -2619,6 +2624,9 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
folders.push_back(category->getUUID());
}
+
+ mMenu = menu.getHandle();
+ sSelf = getHandle();
LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders, FALSE);
fetch->startFetch();
inc_busy_count();
@@ -4134,7 +4142,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
LLSD cbparams;
cbparams["index"] = curiter->first;
- cbparams["label"] = attachment->getName();
+ cbparams["label"] = p.name;
p.on_click.function_name = "Inventory.AttachObject";
p.on_click.parameter = LLSD(attachment->getName());
p.on_enable.function_name = "Attachment.Label";
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 9dc50b542d..91055eb906 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -230,8 +230,8 @@ public:
const LLUUID& uuid) :
LLInvFVBridge(inventory, root, uuid),
mCallingCards(FALSE),
- mWearables(FALSE),
- mMenu(NULL) {}
+ mWearables(FALSE)
+ {}
BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop);
BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop);
@@ -272,6 +272,7 @@ public:
static void createWearable(LLFolderBridge* bridge, LLWearableType::EType type);
LLViewerInventoryCategory* getCategory() const;
+ LLHandle<LLFolderBridge> getHandle() { mHandle.bind(this); return mHandle; }
protected:
//--------------------------------------------------------------------
@@ -305,16 +306,17 @@ protected:
// Messy hacks for handling folder options
//--------------------------------------------------------------------
public:
- static LLFolderBridge* sSelf;
+ static LLHandle<LLFolderBridge> sSelf;
static void staticFolderOptionsMenu();
void folderOptionsMenu();
private:
- BOOL mCallingCards;
- BOOL mWearables;
- LLMenuGL* mMenu;
- menuentry_vec_t mItems;
- menuentry_vec_t mDisabledItems;
+ BOOL mCallingCards;
+ BOOL mWearables;
+ LLHandle<LLView> mMenu;
+ menuentry_vec_t mItems;
+ menuentry_vec_t mDisabledItems;
+ LLRootHandle<LLFolderBridge> mHandle;
};
class LLTextureBridge : public LLItemBridge
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 2d11337955..ba357b2361 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -250,6 +250,18 @@ BOOL get_can_item_be_worn(const LLUUID& id)
const LLViewerInventoryItem* item = gInventory.getItem(id);
if (!item)
return FALSE;
+
+ if (LLAppearanceMgr::isLinkInCOF(item->getLinkedUUID()))
+ {
+ // an item having links in COF (i.e. a worn item)
+ return FALSE;
+ }
+
+ if (gInventory.isObjectDescendentOf(id, LLAppearanceMgr::instance().getCOF()))
+ {
+ // a non-link object in COF (should not normally happen)
+ return FALSE;
+ }
switch(item->getType())
{
diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp
index 3090371a73..2201481df3 100644
--- a/indra/newview/llinventoryicon.cpp
+++ b/indra/newview/llinventoryicon.cpp
@@ -117,6 +117,7 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
if (item_is_multi)
{
idx = ICONNAME_OBJECT_MULTI;
+ return getIconName(idx);
}
switch(asset_type)
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 236ed9bbd1..5a952bb6a8 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -294,6 +294,30 @@ void LLInventoryModel::getDirectDescendentsOf(const LLUUID& cat_id,
items = get_ptr_in_map(mParentChildItemTree, cat_id);
}
+LLMD5 LLInventoryModel::hashDirectDescendentNames(const LLUUID& cat_id) const
+{
+ LLInventoryModel::cat_array_t* cat_array;
+ LLInventoryModel::item_array_t* item_array;
+ getDirectDescendentsOf(cat_id,cat_array,item_array);
+ LLMD5 item_name_hash;
+ if (!item_array)
+ {
+ item_name_hash.finalize();
+ return item_name_hash;
+ }
+ for (LLInventoryModel::item_array_t::const_iterator iter = item_array->begin();
+ iter != item_array->end();
+ iter++)
+ {
+ const LLViewerInventoryItem *item = (*iter);
+ if (!item)
+ continue;
+ item_name_hash.update(item->getName());
+ }
+ item_name_hash.finalize();
+ return item_name_hash;
+}
+
// SJB: Added version to lock the arrays to catch potential logic bugs
void LLInventoryModel::lockDirectDescendentArrays(const LLUUID& cat_id,
cat_array_t*& categories,
@@ -1254,6 +1278,9 @@ void LLInventoryModel::addCategory(LLViewerInventoryCategory* category)
//llinfos << "LLInventoryModel::addCategory()" << llendl;
if(category)
{
+ // try to localize default names first. See EXT-8319, EXT-7051.
+ category->localizeName();
+
// Insert category uniquely into the map
mCategoryMap[category->getUUID()] = category; // LLPointer will deref and delete the old one
//mInventory[category->getUUID()] = category;
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 7b56d0bdd1..ff8a5bae9b 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -41,6 +41,7 @@
#include "lluuid.h"
#include "llpermissionsflags.h"
#include "llstring.h"
+#include "llmd5.h"
#include <map>
#include <set>
#include <string>
@@ -194,6 +195,9 @@ public:
void getDirectDescendentsOf(const LLUUID& cat_id,
cat_array_t*& categories,
item_array_t*& items) const;
+
+ // Compute a hash of direct descendent names (for detecting child name changes)
+ LLMD5 hashDirectDescendentNames(const LLUUID& cat_id) const;
// Starting with the object specified, add its descendents to the
// array provided, but do not add the inventory object specified
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index bd6877d9d3..5416f01033 100644
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -676,7 +676,9 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
iter != mCategoryMap.end();
++iter)
{
- LLViewerInventoryCategory* category = gInventory.getCategory((*iter).first);
+ const LLUUID& cat_id = (*iter).first;
+
+ LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);
if (!category)
continue;
@@ -691,7 +693,7 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
// Check number of known descendents to find out whether it has changed.
LLInventoryModel::cat_array_t* cats;
LLInventoryModel::item_array_t* items;
- gInventory.getDirectDescendentsOf((*iter).first, cats, items);
+ gInventory.getDirectDescendentsOf(cat_id, cats, items);
if (!cats || !items)
{
llwarns << "Category '" << category->getName() << "' descendents corrupted, fetch failed." << llendl;
@@ -703,20 +705,33 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
continue;
}
-
+
const S32 current_num_known_descendents = cats->count() + items->count();
LLCategoryData cat_data = (*iter).second;
+ bool cat_changed = false;
+
// If category version or descendents count has changed
- // update category data in mCategoryMap and fire a callback.
+ // update category data in mCategoryMap
if (version != cat_data.mVersion || current_num_known_descendents != cat_data.mDescendentsCount)
{
cat_data.mVersion = version;
cat_data.mDescendentsCount = current_num_known_descendents;
+ cat_changed = true;
+ }
- cat_data.mCallback();
+ // If any item names have changed, update the name hash
+ LLMD5 item_name_hash = gInventory.hashDirectDescendentNames(cat_id);
+ if (cat_data.mItemNameHash != item_name_hash)
+ {
+ cat_data.mItemNameHash = item_name_hash;
+ cat_changed = true;
}
+
+ // If anything has changed above, fire the callback.
+ if (cat_changed)
+ cat_data.mCallback();
}
}
diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h
index 4a88a65bf8..ccd5fa5f4e 100644
--- a/indra/newview/llinventoryobserver.h
+++ b/indra/newview/llinventoryobserver.h
@@ -34,6 +34,7 @@
#define LL_LLINVENTORYOBSERVERS_H
#include "lluuid.h"
+#include "llmd5.h"
#include <string>
#include <vector>
@@ -298,11 +299,14 @@ protected:
: mCallback(cb)
, mVersion(version)
, mDescendentsCount(num_descendents)
- {}
+ {
+ mItemNameHash.finalize();
+ }
callback_t mCallback;
S32 mVersion;
S32 mDescendentsCount;
+ LLMD5 mItemNameHash;
};
typedef std::map<LLUUID, LLCategoryData> category_map_t;
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 5af99f3c8f..ac92f41624 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -790,7 +790,7 @@ void LLInventoryPanel::doToSelected(const LLSD& userdata)
void LLInventoryPanel::doCreate(const LLSD& userdata)
{
- menu_create_inventory_item(mFolderRoot, LLFolderBridge::sSelf, userdata);
+ menu_create_inventory_item(mFolderRoot, LLFolderBridge::sSelf.get(), userdata);
}
bool LLInventoryPanel::beginIMSession()
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 06f490e8e3..ae8efc01a3 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -58,6 +58,7 @@
#endif
#include "llsecapi.h"
#include "llstartup.h"
+#include "llmachineid.h"
static const char * const TOS_REPLY_PUMP = "lllogininstance_tos_callback";
static const char * const TOS_LISTENER_NAME = "lllogininstance_tos";
@@ -165,22 +166,24 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
// (re)initialize the request params with creds.
LLSD request_params = user_credential->getLoginParams();
- char hashed_mac_string[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */
- LLMD5 hashed_mac;
- unsigned char MACAddress[MAC_ADDRESS_BYTES];
- if(LLUUID::getNodeID(MACAddress) == 0) {
- llerrs << "Failed to get node id; cannot uniquely identify this machine." << llendl;
+ char hashed_unique_id_string[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */
+ LLMD5 hashed_unique_id;
+ unsigned char unique_id[MAC_ADDRESS_BYTES];
+ if(LLUUID::getNodeID(unique_id) == 0) {
+ if(LLMachineID::getUniqueID(unique_id, sizeof(unique_id)) == 0) {
+ llerrs << "Failed to get an id; cannot uniquely identify this machine." << llendl;
+ }
}
- hashed_mac.update( MACAddress, MAC_ADDRESS_BYTES );
- hashed_mac.finalize();
- hashed_mac.hex_digest(hashed_mac_string);
+ hashed_unique_id.update(unique_id, MAC_ADDRESS_BYTES);
+ hashed_unique_id.finalize();
+ hashed_unique_id.hex_digest(hashed_unique_id_string);
request_params["start"] = construct_start_string();
request_params["skipoptional"] = mSkipOptionalUpdate;
request_params["agree_to_tos"] = false; // Always false here. Set true in
request_params["read_critical"] = false; // handleTOSResponse
request_params["last_exec_event"] = mLastExecEvent;
- request_params["mac"] = hashed_mac_string;
+ request_params["mac"] = hashed_unique_id_string;
request_params["version"] = gCurrentVersion; // Includes channel name
request_params["channel"] = gSavedSettings.getString("VersionChannelName");
request_params["id0"] = mSerialNumber;
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 6ae4a5e5e4..fc41137686 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -83,6 +83,16 @@ LLFloaterMove::LLFloaterMove(const LLSD& key)
{
}
+LLFloaterMove::~LLFloaterMove()
+{
+ // Ensure LLPanelStandStopFlying panel is not among floater's children. See EXT-8458.
+ setVisible(FALSE);
+
+ // Otherwise it can be destroyed and static pointer in LLPanelStandStopFlying::getInstance() will become invalid.
+ // Such situation was possible when LLFloaterReg returns "dead" instance of floater.
+ // Should not happen after LLFloater::destroy was modified to remove "dead" instances from LLFloaterReg.
+}
+
// virtual
BOOL LLFloaterMove::postBuild()
{
diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h
index d463861188..43b0342744 100644
--- a/indra/newview/llmoveview.h
+++ b/indra/newview/llmoveview.h
@@ -51,7 +51,7 @@ class LLFloaterMove
private:
LLFloaterMove(const LLSD& key);
- ~LLFloaterMove() {}
+ ~LLFloaterMove();
public:
/*virtual*/ BOOL postBuild();
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index a300e15edd..8a52cf715f 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -317,9 +317,19 @@ void LLGestureComboList::refreshGestures()
if (gestures)
{
- S32 index = gestures->getSelectedValue().asInteger();
- if(index > 0)
- gesture = mGestures.at(index);
+ S32 sel_index = gestures->getFirstSelectedIndex();
+ if (sel_index != 0)
+ {
+ S32 index = gestures->getSelectedValue().asInteger();
+ if (index<0 || index >= (S32)mGestures.size())
+ {
+ llwarns << "out of range gesture access" << llendl;
+ }
+ else
+ {
+ gesture = mGestures.at(index);
+ }
+ }
}
if(gesture && LLGestureMgr::instance().isGesturePlaying(gesture))
@@ -335,13 +345,13 @@ void LLGestureComboList::onCommitGesture()
LLCtrlListInterface* gestures = getListInterface();
if (gestures)
{
- S32 index = gestures->getFirstSelectedIndex();
- if (index == 0)
+ S32 sel_index = gestures->getFirstSelectedIndex();
+ if (sel_index == 0)
{
return;
}
- index = gestures->getSelectedValue().asInteger();
+ S32 index = gestures->getSelectedValue().asInteger();
if (mViewAllItemIndex == index)
{
@@ -357,13 +367,20 @@ void LLGestureComboList::onCommitGesture()
return;
}
- LLMultiGesture* gesture = mGestures.at(index);
- if(gesture)
+ if (index<0 || index >= (S32)mGestures.size())
+ {
+ llwarns << "out of range gesture index" << llendl;
+ }
+ else
{
- LLGestureMgr::instance().playGesture(gesture);
- if(!gesture->mReplaceText.empty())
+ LLMultiGesture* gesture = mGestures.at(index);
+ if(gesture)
{
- LLNearbyChatBar::sendChatFromViewer(gesture->mReplaceText, CHAT_TYPE_NORMAL, FALSE);
+ LLGestureMgr::instance().playGesture(gesture);
+ if(!gesture->mReplaceText.empty())
+ {
+ LLNearbyChatBar::sendChatFromViewer(gesture->mReplaceText, CHAT_TYPE_NORMAL, FALSE);
+ }
}
}
}
@@ -374,6 +391,13 @@ LLGestureComboList::~LLGestureComboList()
LLGestureMgr::instance().removeObserver(this);
}
+LLCtrlListInterface* LLGestureComboList::getListInterface()
+{
+ LLCtrlListInterface *result = mList;
+ llassert((LLCtrlListInterface*)mList==result);
+ return mList;
+};
+
LLNearbyChatBar::LLNearbyChatBar()
: LLPanel()
, mChatBox(NULL)
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index 83c174fd10..0eaa60ce81 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -68,7 +68,7 @@ public:
~LLGestureComboList();
- LLCtrlListInterface* getListInterface() { return (LLCtrlListInterface*)mList; };
+ LLCtrlListInterface* getListInterface();
virtual void showList();
virtual void hideList();
virtual BOOL handleKeyHere(KEY key, MASK mask);
diff --git a/indra/newview/lloutfitobserver.cpp b/indra/newview/lloutfitobserver.cpp
index 03414b9964..60c941b456 100644
--- a/indra/newview/lloutfitobserver.cpp
+++ b/indra/newview/lloutfitobserver.cpp
@@ -40,6 +40,7 @@
LLOutfitObserver::LLOutfitObserver() :
mCOFLastVersion(LLViewerInventoryCategory::VERSION_UNKNOWN)
{
+ mItemNameHash.finalize();
gInventory.addObserver(this);
}
@@ -87,13 +88,24 @@ bool LLOutfitObserver::checkCOF()
if (cof.isNull())
return false;
+ bool cof_changed = false;
+ LLMD5 item_name_hash = gInventory.hashDirectDescendentNames(cof);
+ if (item_name_hash != mItemNameHash)
+ {
+ cof_changed = true;
+ mItemNameHash = item_name_hash;
+ }
+
S32 cof_version = getCategoryVersion(cof);
+ if (cof_version != mCOFLastVersion)
+ {
+ cof_changed = true;
+ mCOFLastVersion = cof_version;
+ }
- if (cof_version == mCOFLastVersion)
+ if (!cof_changed)
return false;
-
- mCOFLastVersion = cof_version;
-
+
// dirtiness state should be updated before sending signal
LLAppearanceMgr::getInstance()->updateIsDirty();
mCOFChanged();
diff --git a/indra/newview/lloutfitobserver.h b/indra/newview/lloutfitobserver.h
index 3a66b5ea9f..4bb2b9b5ec 100644
--- a/indra/newview/lloutfitobserver.h
+++ b/indra/newview/lloutfitobserver.h
@@ -34,6 +34,7 @@
#define LL_OUTFITOBSERVER_H
#include "llsingleton.h"
+#include "llmd5.h"
/**
* Outfit observer facade that provides simple possibility to subscribe on
@@ -84,6 +85,8 @@ protected:
bool mLastOutfitDirtiness;
+ LLMD5 mItemNameHash;
+
private:
signal_t mBOFReplaced;
signal_t mBOFChanged;
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 63ffb80ff2..8147a97317 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -665,7 +665,18 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata)
}
if (command_name == "wear")
{
- return !gAgentWearables.isCOFChangeInProgress();
+ if (gAgentWearables.isCOFChangeInProgress())
+ {
+ return false;
+ }
+
+ if (hasItemSelected())
+ {
+ return canWearSelected();
+ }
+
+ // outfit selected
+ return LLAppearanceMgr::getCanAddToCOF(mSelectedOutfitUUID);
}
if (command_name == "take_off")
{
@@ -677,6 +688,7 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata)
if (command_name == "wear_add")
{
+ // *TODO: do we ever get here?
if (gAgentWearables.isCOFChangeInProgress())
{
return false;
@@ -984,6 +996,26 @@ bool LLOutfitsList::canTakeOffSelected()
return false;
}
+bool LLOutfitsList::canWearSelected()
+{
+ uuid_vec_t selected_items;
+ getSelectedItemsUUIDs(selected_items);
+
+ for (uuid_vec_t::const_iterator it = selected_items.begin(); it != selected_items.end(); ++it)
+ {
+ const LLUUID& id = *it;
+
+ // Check whether the item is worn.
+ if (!get_can_item_be_worn(id))
+ {
+ return false;
+ }
+ }
+
+ // All selected items can be worn.
+ return true;
+}
+
void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id)
{
LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl);
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index d7cf8a8c08..206854b232 100644
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -183,6 +183,11 @@ private:
*/
bool canTakeOffSelected();
+ /**
+ * Returns true if all selected items can be worn.
+ */
+ bool canWearSelected();
+
void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
void onCOFChanged();
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index 14f05bdb17..62e6cdc79d 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -47,6 +47,7 @@
#include "llvoavatarself.h"
#include "lltexteditor.h"
#include "lltextbox.h"
+#include "llaccordionctrl.h"
#include "llaccordionctrltab.h"
#include "llagentwearables.h"
#include "llscrollingpanelparam.h"
@@ -666,6 +667,35 @@ void LLPanelEditWearable::updateAvatarHeightLabel()
mTxtAvatarHeight->appendText(this->mReplacementMetricUrl, false, param);
}
+void LLPanelEditWearable::onWearablePanelVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl)
+{
+ if (in_visible_chain.asBoolean() && accordion_ctrl != NULL)
+ {
+ accordion_ctrl->expandDefaultTab();
+ }
+}
+
+void LLPanelEditWearable::setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel)
+{
+ if (bodypart_panel != NULL)
+ {
+ LLAccordionCtrl* accordion_ctrl = bodypart_panel->getChild<LLAccordionCtrl>("wearable_accordion");
+
+ if (accordion_ctrl != NULL)
+ {
+ bodypart_panel->setVisibleCallback(
+ boost::bind(&LLPanelEditWearable::onWearablePanelVisibilityChange, this, _2, accordion_ctrl));
+ }
+ else
+ {
+ llwarns << "accordion_ctrl is NULL" << llendl;
+ }
+ }
+ else
+ {
+ llwarns << "bodypart_panel is NULL" << llendl;
+ }
+}
// virtual
BOOL LLPanelEditWearable::postBuild()
@@ -695,6 +725,14 @@ BOOL LLPanelEditWearable::postBuild()
mPanelEyes = getChild<LLPanel>("edit_eyes_panel");
mPanelHair = getChild<LLPanel>("edit_hair_panel");
+ // Setting the visibility callback is applied only to the bodyparts panel
+ // because currently they are the only ones whose 'wearable_accordion' has
+ // multiple accordion tabs (see EXT-8164 for details).
+ setWearablePanelVisibilityChangeCallback(mPanelShape);
+ setWearablePanelVisibilityChangeCallback(mPanelSkin);
+ setWearablePanelVisibilityChangeCallback(mPanelEyes);
+ setWearablePanelVisibilityChangeCallback(mPanelHair);
+
//clothes
mPanelShirt = getChild<LLPanel>("edit_shirt_panel");
mPanelPants = getChild<LLPanel>("edit_pants_panel");
@@ -786,7 +824,7 @@ BOOL LLPanelEditWearable::isDirty() const
if (mWearablePtr)
{
if (mWearablePtr->isDirty() ||
- mWearablePtr->getName().compare(mNameEditor->getText()) != 0)
+ mWearableItem->getName().compare(mNameEditor->getText()) != 0)
{
isDirty = TRUE;
}
@@ -839,7 +877,7 @@ void LLPanelEditWearable::saveAsCallback(const LLSD& notification, const LLSD& r
if( !wearable_name.empty() )
{
mNameEditor->setText(wearable_name);
- saveChanges();
+ saveChanges(true);
}
}
}
@@ -896,7 +934,7 @@ void LLPanelEditWearable::onTexturePickerCommit(const LLUICtrl* ctrl)
{
// Set the new version
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_ctrl->getImageAssetID());
- if( image->getID().isNull() )
+ if( image->getID() == IMG_DEFAULT )
{
image = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);
}
@@ -971,7 +1009,7 @@ void LLPanelEditWearable::updatePanelPickerControls(LLWearableType::EType type)
}
}
-void LLPanelEditWearable::saveChanges()
+void LLPanelEditWearable::saveChanges(bool force_save_as)
{
if (!mWearablePtr || !isDirty())
{
@@ -980,16 +1018,18 @@ void LLPanelEditWearable::saveChanges()
}
U32 index = gAgentWearables.getWearableIndex(mWearablePtr);
-
- if (mWearablePtr->getName().compare(mNameEditor->getText()) != 0)
+
+ std::string new_name = mNameEditor->getText();
+ if (force_save_as)
{
// the name of the wearable has changed, re-save wearable with new name
LLAppearanceMgr::instance().removeCOFItemLinks(mWearablePtr->getItemID(),false);
- gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, mNameEditor->getText(), FALSE);
+ gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, new_name, FALSE);
+ mNameEditor->setText(mWearableItem->getName());
}
else
{
- gAgentWearables.saveWearable(mWearablePtr->getType(), index);
+ gAgentWearables.saveWearable(mWearablePtr->getType(), index, TRUE, new_name);
}
}
@@ -1002,7 +1042,7 @@ void LLPanelEditWearable::revertChanges()
}
mWearablePtr->revertValues();
- mNameEditor->setText(mWearablePtr->getName());
+ mNameEditor->setText(mWearableItem->getName());
updatePanelPickerControls(mWearablePtr->getType());
updateTypeSpecificControls(mWearablePtr->getType());
gAgentAvatarp->wearableUpdated(mWearablePtr->getType(), FALSE);
@@ -1048,7 +1088,7 @@ void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show)
mDescTitle->setText(description_title);
// set name
- mNameEditor->setText(wearable->getName());
+ mNameEditor->setText(mWearableItem->getName());
updatePanelPickerControls(type);
updateTypeSpecificControls(type);
diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h
index bfce2ae56e..c0823dd3fa 100644
--- a/indra/newview/llpaneleditwearable.h
+++ b/indra/newview/llpaneleditwearable.h
@@ -39,6 +39,7 @@
#include "llvoavatardefines.h"
#include "llwearabletype.h"
+class LLAccordionCtrl;
class LLCheckBoxCtrl;
class LLWearable;
class LLTextBox;
@@ -63,7 +64,7 @@ public:
LLWearable* getWearable() { return mWearablePtr; }
void setWearable(LLWearable *wearable);
- void saveChanges();
+ void saveChanges(bool force_save_as = false);
void revertChanges();
void showDefaultSubpart();
@@ -113,6 +114,10 @@ private:
// updates avatar height label
void updateAvatarHeightLabel();
+ void onWearablePanelVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl);
+
+ void setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel);
+
// the pointer to the wearable we're editing. NULL means we're not editing a wearable.
LLWearable *mWearablePtr;
LLViewerInventoryItem* mWearableItem;
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index d997b83cbb..38e776b195 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -182,6 +182,11 @@ BOOL LLPanelGroup::postBuild()
LLPanelGroupTab* panel_notices = findChild<LLPanelGroupTab>("group_notices_tab_panel");
LLPanelGroupTab* panel_land = findChild<LLPanelGroupTab>("group_land_tab_panel");
+ if (LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("groups_accordion"))
+ {
+ setVisibleCallback(boost::bind(&LLPanelGroup::onVisibilityChange, this, _2, accordion_ctrl));
+ }
+
if(panel_general) mTabs.push_back(panel_general);
if(panel_roles) mTabs.push_back(panel_roles);
if(panel_notices) mTabs.push_back(panel_notices);
@@ -305,6 +310,13 @@ void LLPanelGroup::onBtnCancel()
onBackBtnClick();
}
+void LLPanelGroup::onVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl)
+{
+ if (in_visible_chain.asBoolean() && accordion_ctrl != NULL)
+ {
+ accordion_ctrl->expandDefaultTab();
+ }
+}
void LLPanelGroup::changed(LLGroupChange gc)
{
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index 13a03b0713..2b21e9895a 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -42,6 +42,7 @@ class LLOfferInfo;
const S32 UPDATE_MEMBERS_PER_FRAME = 500;
// Forward declares
+class LLAccordionCtrl;
class LLPanelGroupTab;
class LLTabContainer;
class LLAgent;
@@ -102,6 +103,7 @@ protected:
void onBackBtnClick();
void onBtnJoin();
void onBtnCancel();
+ void onVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl);
static void onBtnApply(void*);
static void onBtnRefresh(void*);
@@ -126,7 +128,6 @@ protected:
LLButton* mButtonJoin;
LLUICtrl* mJoinText;
-
};
class LLPanelGroupTab : public LLPanel
diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp
index 65fe7165c2..b7d6b65ce5 100644
--- a/indra/newview/llpanelgrouplandmoney.cpp
+++ b/indra/newview/llpanelgrouplandmoney.cpp
@@ -1432,10 +1432,10 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg,
// text.append(llformat( "%-24s %6d %6d \n", LLTrans::getString("GroupMoneyDebits").c_str(), total_debits, (S32)floor((F32)total_debits/(F32)non_exempt_members)));
// text.append(llformat( "%-24s %6d %6d \n", LLTrans::getString("GroupMoneyTotal").c_str(), total_credits + total_debits, (S32)floor((F32)(total_credits + total_debits)/(F32)non_exempt_members)));
- text.append( " Group\n");
- text.append(llformat( "%-24s %6d\n", "Credits", total_credits));
- text.append(llformat( "%-24s %6d\n", "Debits", total_debits));
- text.append(llformat( "%-24s %6d\n", "Total", total_credits + total_debits));
+ text.append(llformat( "%s\n", LLTrans::getString("GroupColumn").c_str()));
+ text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyCredits").c_str(), total_credits));
+ text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyDebits").c_str(), total_debits));
+ text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyTotal").c_str(), total_credits + total_debits));
if ( mImplementationp->mTextEditorp )
{
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 26e8a932aa..7a28d10baf 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -51,6 +51,7 @@
#include "lltabcontainer.h"
#include "lltextbox.h"
#include "lltexteditor.h"
+#include "lltrans.h"
#include "llviewertexturelist.h"
#include "llviewerwindow.h"
#include "llfocusmgr.h"
@@ -587,7 +588,7 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl,
row["columns"][1]["column"] = "action";
row["columns"][1]["type"] = "text";
- row["columns"][1]["value"] = action_set->mActionSetData->mName;
+ row["columns"][1]["value"] = LLTrans::getString(action_set->mActionSetData->mName);
row["columns"][1]["font"]["name"] = "SANSSERIF_SMALL";
@@ -1593,6 +1594,7 @@ void LLPanelGroupMembersSubTab::updateMembers()
LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end();
+ LLUIString donated = getString("donation_area");
S32 i = 0;
for( ; mMemberProgress != end && i<UPDATE_MEMBERS_PER_FRAME;
@@ -1614,9 +1616,7 @@ void LLPanelGroupMembersSubTab::updateMembers()
if (add_member)
{
- // Build the donated tier string.
- std::ostringstream donated;
- donated << mMemberProgress->second->getContribution() << " sq. m.";
+ donated.setArg("[AREA]", llformat("%d", mMemberProgress->second->getContribution()));
LLSD row;
row["id"] = (*mMemberProgress).first;
@@ -1625,7 +1625,7 @@ void LLPanelGroupMembersSubTab::updateMembers()
// value is filled in by name list control
row["columns"][1]["column"] = "donated";
- row["columns"][1]["value"] = donated.str();
+ row["columns"][1]["value"] = donated.getString();
row["columns"][2]["column"] = "online";
row["columns"][2]["value"] = mMemberProgress->second->getOnlineStatus();
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 29ce3449d1..17ec0d3a56 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -566,7 +566,8 @@ void LLPanelMainInventory::draw()
void LLPanelMainInventory::updateItemcountText()
{
- LLLocale locale(LLLocale::USER_LOCALE);
+ // *TODO: Calling setlocale() on each frame may be inefficient.
+ LLLocale locale(LLStringUtil::getLocale());
std::string item_count_string;
LLResMgr::getInstance()->getIntegerString(item_count_string, gInventory.getItemCount());
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index ca1361c84b..116e5ba4cb 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -750,8 +750,6 @@ void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
std::vector<std::string> items;
std::vector<std::string> disabled_items;
- items.push_back(std::string("--no options--"));
- disabled_items.push_back(std::string("--no options--"));
hide_context_entries(menu, items, disabled_items);
}
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index f8350a56ef..5195b719d4 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -923,6 +923,18 @@ bool LLPanelOutfitEdit::switchPanels(LLPanel* switch_from_panel, LLPanel* switch
return false;
}
+void LLPanelOutfitEdit::resetAccordionState()
+{
+ if (mCOFWearables != NULL)
+ {
+ mCOFWearables->expandDefaultAccordionTab();
+ }
+ else
+ {
+ llwarns << "mCOFWearables is NULL" << llendl;
+ }
+}
+
void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button)
{
if(!mGearMenu)
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index fb9a35411c..5009de0fef 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -182,6 +182,8 @@ public:
*/
bool switchPanels(LLPanel* switch_from_panel, LLPanel* switch_to_panel);
+ void resetAccordionState();
+
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index ca5679d5b0..16ef7998b3 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -337,7 +337,7 @@ bool LLPanelOutfitsInventory::isCOFPanelActive() const
void LLPanelOutfitsInventory::setWearablesLoading(bool val)
{
- mListCommands->childSetEnabled("wear_btn", !val);
+ updateVerbs();
}
void LLPanelOutfitsInventory::onWearablesLoaded()
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 8c1f5d0915..99e48cca6d 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -60,7 +60,8 @@ LLPanelPlaceInfo::LLPanelPlaceInfo()
mScrollingPanelWidth(0),
mInfoType(UNKNOWN),
mScrollingPanel(NULL),
- mScrollContainer(NULL)
+ mScrollContainer(NULL),
+ mDescEditor(NULL)
{}
//virtual
@@ -248,6 +249,16 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
// virtual
void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
{
+
+ // This if was added to force collapsing description textbox on Windows at the beginning of reshape
+ // (the only case when reshape is skipped here is when it's caused by this textbox, so called_from_parent is FALSE)
+ // This way it is consistent with Linux where topLost collapses textbox at the beginning of reshape.
+ // On windows it collapsed only after reshape which caused EXT-8342.
+ if(called_from_parent)
+ {
+ if(mDescEditor) mDescEditor->onTopLost();
+ }
+
LLPanel::reshape(width, height, called_from_parent);
if (!mScrollContainer || !mScrollingPanel)
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index 1f979b0ef1..08835dc2b8 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -79,7 +79,8 @@ LLPanelPlaceProfile::LLPanelPlaceProfile()
: LLPanelPlaceInfo(),
mForSalePanel(NULL),
mYouAreHerePanel(NULL),
- mSelectedParcelID(-1)
+ mSelectedParcelID(-1),
+ mAccordionCtrl(NULL)
{}
// virtual
@@ -139,6 +140,7 @@ BOOL LLPanelPlaceProfile::postBuild()
mSubdivideText = getChild<LLTextEditor>("subdivide");
mResaleText = getChild<LLTextEditor>("resale");
mSaleToText = getChild<LLTextBox>("sale_to");
+ mAccordionCtrl = getChild<LLAccordionCtrl>("advanced_info_accordion");
icon_pg = getString("icon_PG");
icon_m = getString("icon_M");
@@ -278,6 +280,11 @@ void LLPanelPlaceProfile::handleVisibilityChange(BOOL new_visibility)
parcel_mgr->deselectUnused();
}
}
+
+ if (mAccordionCtrl != NULL)
+ {
+ mAccordionCtrl->expandDefaultTab();
+ }
}
void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h
index e77b441567..49c13ff5e3 100644
--- a/indra/newview/llpanelplaceprofile.h
+++ b/indra/newview/llpanelplaceprofile.h
@@ -35,6 +35,7 @@
#include "llpanelplaceinfo.h"
+class LLAccordionCtrl;
class LLIconCtrl;
class LLTextEditor;
@@ -118,6 +119,7 @@ private:
LLTextEditor* mSubdivideText;
LLTextEditor* mResaleText;
LLTextBox* mSaleToText;
+ LLAccordionCtrl* mAccordionCtrl;
};
#endif // LL_LLPANELPLACEPROFILE_H
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 705b196ef1..c713bc3965 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -718,8 +718,8 @@ void LLPanelPlaces::onOverflowButtonClicked()
bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE;
if ((is_agent_place_info_visible ||
- mPlaceInfoType == "remote_place" ||
- mPlaceInfoType == "teleport_history") && mPlaceMenu != NULL)
+ mPlaceInfoType == REMOTE_PLACE_INFO_TYPE ||
+ mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) && mPlaceMenu != NULL)
{
menu = mPlaceMenu;
@@ -1089,6 +1089,8 @@ void LLPanelPlaces::updateVerbs()
if (is_place_info_visible)
{
+ mShowOnMapBtn->setEnabled(have_3d_pos);
+
if (is_agent_place_info_visible)
{
// We don't need to teleport to the current location
diff --git a/indra/newview/llplacesinventorybridge.cpp b/indra/newview/llplacesinventorybridge.cpp
index f59a55cb8b..18a91b0eb0 100644
--- a/indra/newview/llplacesinventorybridge.cpp
+++ b/indra/newview/llplacesinventorybridge.cpp
@@ -115,7 +115,7 @@ void LLPlacesFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
// they should be synchronized with Places/My Landmarks/Gear menu. See EXT-1601
// repeat parent functionality
- sSelf = this; // necessary for "New Folder" functionality
+ sSelf = getHandle(); // necessary for "New Folder" functionality
hide_context_entries(menu, items, disabled_items);
}
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index a7b4873fed..6f9d8a7623 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -1625,7 +1625,17 @@ std::string LLPreviewGesture::getLabel(std::vector<std::string> labels)
result=LLTrans::getString("AnimFlagStart");
}
- result.append(v_labels[1]);
+ // lets localize action value
+ std::string action = v_labels[1];
+ if ("None" == action)
+ {
+ action = LLTrans::getString("GestureActionNone");
+ }
+ else if ("until animations are done" == action)
+ {
+ action = LLFloaterReg::getInstance("preview_gesture")->getChild<LLCheckBoxCtrl>("wait_anim_check")->getLabel();
+ }
+ result.append(action);
return result;
}
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index bf18c9e5e7..ef6ceb5f2e 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -87,7 +87,7 @@ LLPreviewTexture::LLPreviewTexture(const LLSD& key)
LLPreviewTexture::~LLPreviewTexture()
{
- LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList, this) ;
+ LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;
if( mLoadingFullImage )
{
@@ -280,7 +280,7 @@ void LLPreviewTexture::saveAs()
mLoadingFullImage = TRUE;
getWindow()->incBusyCount();
mImage->setLoadedCallback( LLPreviewTexture::onFileLoadedForSave,
- 0, TRUE, FALSE, new LLUUID( mItemUUID ), this, &mCallbackTextureList );
+ 0, TRUE, FALSE, new LLUUID( mItemUUID ), &mCallbackTextureList );
}
// virtual
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 7a7ffb9983..98cd0b88eb 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -190,13 +190,16 @@ void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility)
{
if (new_visibility.asBoolean())
{
- if ((mOutfitEdit && mOutfitEdit->getVisible()) || (mEditWearable && mEditWearable->getVisible()))
+ bool is_outfit_edit_visible = mOutfitEdit && mOutfitEdit->getVisible();
+ bool is_wearable_edit_visible = mEditWearable && mEditWearable->getVisible();
+
+ if (is_outfit_edit_visible || is_wearable_edit_visible)
{
if (!gAgentCamera.cameraCustomizeAvatar() && gSavedSettings.getBOOL("AppearanceCameraMovement"))
{
gAgentCamera.changeCameraToCustomizeAvatar();
}
- if (mEditWearable && mEditWearable->getVisible())
+ if (is_wearable_edit_visible)
{
LLWearable *wearable_ptr = mEditWearable->getWearable();
if (gAgentWearables.getWearableIndex(wearable_ptr) == LLAgentWearables::MAX_CLOTHING_PER_TYPE)
@@ -205,6 +208,11 @@ void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility)
showOutfitEditPanel();
}
}
+
+ if (is_outfit_edit_visible)
+ {
+ mOutfitEdit->resetAccordionState();
+ }
}
}
else
@@ -283,6 +291,15 @@ void LLSidepanelAppearance::showOutfitsInventoryPanel()
void LLSidepanelAppearance::showOutfitEditPanel()
{
+ // Accordion's state must be reset in all cases except the one when user
+ // is returning back to the mOutfitEdit panel from the mEditWearable panel.
+ // The simplest way to control this is to check the visibility state of the mEditWearable
+ // BEFORE it is changed by the call to the toggleWearableEditPanel(FALSE, NULL, TRUE).
+ if (mEditWearable != NULL && !mEditWearable->getVisible() && mOutfitEdit != NULL)
+ {
+ mOutfitEdit->resetAccordionState();
+ }
+
togglMyOutfitsPanel(FALSE);
toggleWearableEditPanel(FALSE, NULL, TRUE); // don't switch out of edit appearance mode
toggleOutfitEditPanel(TRUE);
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index de59af49da..0951586dd5 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -33,10 +33,13 @@
#include "llsidepanelinventory.h"
#include "llagent.h"
+#include "llappearancemgr.h"
#include "llavataractions.h"
#include "llbutton.h"
#include "llinventorybridge.h"
+#include "llinventoryfunctions.h"
#include "llinventorypanel.h"
+#include "lloutfitobserver.h"
#include "llpanelmaininventory.h"
#include "llsidepaneliteminfo.h"
#include "llsidepaneltaskinfo.h"
@@ -98,6 +101,8 @@ BOOL LLSidepanelInventory::postBuild()
my_inventory_panel->addHideFolderType(LLFolderType::FT_LANDMARK);
my_inventory_panel->addHideFolderType(LLFolderType::FT_FAVORITE);
*/
+
+ LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this));
}
// UI elements from item panel
@@ -283,7 +288,7 @@ void LLSidepanelInventory::updateVerbs()
case LLInventoryType::IT_OBJECT:
case LLInventoryType::IT_ATTACHMENT:
mWearBtn->setVisible(TRUE);
- mWearBtn->setEnabled(TRUE);
+ mWearBtn->setEnabled(get_can_item_be_worn(item->getLinkedUUID()));
mShopBtn->setVisible(FALSE);
break;
case LLInventoryType::IT_SOUND:
diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h
index 010173e84e..99d0603ec5 100644
--- a/indra/newview/llsidepaneltaskinfo.h
+++ b/indra/newview/llsidepaneltaskinfo.h
@@ -121,7 +121,7 @@ private:
protected:
LLViewerObject* getObject();
private:
- LLViewerObject* mObject;
+ LLPointer<LLViewerObject> mObject;
LLObjectSelectionHandle mObjectSelection;
static LLSidepanelTaskInfo* sActivePanel;
};
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index ddb5d08e07..cecc135951 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -158,6 +158,7 @@ void LLSurface::initClasses()
void LLSurface::setRegion(LLViewerRegion *regionp)
{
mRegionp = regionp;
+ mWaterObjp = NULL; // depends on regionp, needs recreating
}
// Assumes that arguments are powers of 2, and that
@@ -958,6 +959,7 @@ LLSurfacePatch *LLSurface::resolvePatchRegion(const LLVector3 &pos_region) const
LLSurfacePatch *LLSurface::resolvePatchGlobal(const LLVector3d &pos_global) const
{
+ llassert(mRegionp);
LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(pos_global);
return resolvePatchRegion(pos_region);
}
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index 46bd55de43..f4f8241b99 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -119,14 +119,16 @@ LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner,
S32 width, S32 height) :
// ORDER_LAST => must render these after the hints are created.
LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ),
- mNeedsUpdate(TRUE),
- mNeedsUpload(FALSE),
mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates
+ mNeedsUpload(FALSE),
mNumLowresUploads(0),
+ mNeedsUpdate(TRUE),
+ mNumLowresUpdates(0),
mTexLayerSet(owner)
{
LLTexLayerSetBuffer::sGLByteCount += getSize();
mNeedsUploadTimer.start();
+ mNeedsUpdateTimer.start();
}
LLTexLayerSetBuffer::~LLTexLayerSetBuffer()
@@ -165,8 +167,9 @@ void LLTexLayerSetBuffer::dumpTotalByteCount()
void LLTexLayerSetBuffer::requestUpdate()
{
- conditionalRestartUploadTimer();
+ restartUpdateTimer();
mNeedsUpdate = TRUE;
+ mNumLowresUpdates = 0;
// If we're in the middle of uploading a baked texture, we don't care about it any more.
// When it's downloaded, ignore it.
mUploadID.setNull();
@@ -196,6 +199,12 @@ void LLTexLayerSetBuffer::conditionalRestartUploadTimer()
}
}
+void LLTexLayerSetBuffer::restartUpdateTimer()
+{
+ mNeedsUpdateTimer.reset();
+ mNeedsUpdateTimer.start();
+}
+
void LLTexLayerSetBuffer::cancelUpload()
{
mNeedsUpload = FALSE;
@@ -229,25 +238,31 @@ BOOL LLTexLayerSetBuffer::needsRender()
llassert(mTexLayerSet->getAvatar() == gAgentAvatarp);
if (!isAgentAvatarValid()) return FALSE;
- const BOOL upload_now = isReadyToUpload();
- BOOL needs_update = (mNeedsUpdate || upload_now) && !gAgentAvatarp->mAppearanceAnimating;
- if (needs_update)
+ const BOOL upload_now = mNeedsUpload && isReadyToUpload();
+ const BOOL update_now = mNeedsUpdate && isReadyToUpdate();
+
+ // Don't render if we don't want to (or aren't ready to) upload or update.
+ if (!(update_now || upload_now))
{
- BOOL invalid_skirt = gAgentAvatarp->getBakedTE(mTexLayerSet) == LLVOAvatarDefines::TEX_SKIRT_BAKED && !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT);
- if (invalid_skirt)
- {
- // we were trying to create a skirt texture
- // but we're no longer wearing a skirt...
- needs_update = FALSE;
- cancelUpload();
- }
- else
- {
- needs_update &= mTexLayerSet->isLocalTextureDataAvailable();
- }
+ return FALSE;
+ }
+
+ // Don't render if we're animating our appearance.
+ if (gAgentAvatarp->getIsAppearanceAnimating())
+ {
+ return FALSE;
}
- return needs_update;
+ // Don't render if we are trying to create a shirt texture but aren't wearing a skirt.
+ if (gAgentAvatarp->getBakedTE(mTexLayerSet) == LLVOAvatarDefines::TEX_SKIRT_BAKED &&
+ !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT))
+ {
+ cancelUpload();
+ return FALSE;
+ }
+
+ // Render if we have at least minimal level of detail for each local texture.
+ return mTexLayerSet->isLocalTextureDataAvailable();
}
void LLTexLayerSetBuffer::preRender(BOOL clear_depth)
@@ -272,11 +287,12 @@ BOOL LLTexLayerSetBuffer::render()
gGL.setColorMask(true, true);
// do we need to upload, and do we have sufficient data to create an uploadable composite?
- // When do we upload the texture if gAgent.mNumPendingQueries is non-zero?
- const BOOL upload_now = isReadyToUpload();
+ // TODO: When do we upload the texture if gAgent.mNumPendingQueries is non-zero?
+ const BOOL upload_now = mNeedsUpload && isReadyToUpload();
+ const BOOL update_now = mNeedsUpdate && isReadyToUpdate();
+
BOOL success = TRUE;
-
// Composite the color data
LLGLSUIDefault gls_ui;
success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight );
@@ -294,7 +310,7 @@ BOOL LLTexLayerSetBuffer::render()
if (mTexLayerSet->isVisible())
{
mTexLayerSet->getAvatar()->debugBakedTextureUpload(mTexLayerSet->getBakedTexIndex(), FALSE); // FALSE for start of upload, TRUE for finish.
- readBackAndUpload();
+ doUpload();
}
else
{
@@ -305,6 +321,11 @@ BOOL LLTexLayerSetBuffer::render()
}
}
}
+
+ if (update_now)
+ {
+ doUpdate();
+ }
// reset GL state
gGL.setColorMask(true, true);
@@ -312,7 +333,6 @@ BOOL LLTexLayerSetBuffer::render()
// we have valid texture data now
mGLTexturep->setGLTextureCreated(true);
- mNeedsUpdate = FALSE;
return success;
}
@@ -339,16 +359,16 @@ BOOL LLTexLayerSetBuffer::uploadInProgress() const
BOOL LLTexLayerSetBuffer::isReadyToUpload() const
{
- if (!mNeedsUpload) return FALSE; // Don't need to upload if we haven't requested one.
if (!gAgentQueryManager.hasNoPendingQueries()) return FALSE; // Can't upload if there are pending queries.
if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures()) return FALSE; // Don't upload if avatar is using composites.
// If we requested an upload and have the final LOD ready, then upload.
- const BOOL can_highest_lod = mTexLayerSet->isLocalTextureDataFinal();
- if (can_highest_lod) return TRUE;
+ if (mTexLayerSet->isLocalTextureDataFinal()) return TRUE;
- const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureTimeout");
- if (texture_timeout)
+ // Upload if we've hit a timeout. Upload is a pretty expensive process so we need to make sure
+ // we aren't doing uploads too frequently.
+ const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureUploadTimeout");
+ if (texture_timeout != 0)
{
// The timeout period increases exponentially between every lowres upload in order to prevent
// spamming the server with frequent uploads.
@@ -359,10 +379,33 @@ BOOL LLTexLayerSetBuffer::isReadyToUpload() const
const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable();
if (has_lower_lod && is_upload_textures_timeout) return TRUE;
}
+
return FALSE;
}
-BOOL LLTexLayerSetBuffer::updateImmediate()
+BOOL LLTexLayerSetBuffer::isReadyToUpdate() const
+{
+ // If we requested an update and have the final LOD ready, then update.
+ if (mTexLayerSet->isLocalTextureDataFinal()) return TRUE;
+
+ // If we haven't done an update yet, then just do one now regardless of state of textures.
+ if (mNumLowresUpdates == 0) return TRUE;
+
+ // Update if we've hit a timeout. Unlike for uploads, we can make this timeout fairly small
+ // since render unnecessarily doesn't cost much.
+ const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedLocalTextureUpdateTimeout");
+ if (texture_timeout != 0)
+ {
+ // If we hit our timeout and have textures available at even lower resolution, then update.
+ const BOOL is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= texture_timeout;
+ const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable();
+ if (has_lower_lod && is_update_textures_timeout) return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOL LLTexLayerSetBuffer::requestUpdateImmediate()
{
mNeedsUpdate = TRUE;
BOOL result = FALSE;
@@ -377,7 +420,9 @@ BOOL LLTexLayerSetBuffer::updateImmediate()
return result;
}
-void LLTexLayerSetBuffer::readBackAndUpload()
+// Create the baked texture, send it out to the server, then wait for it to come
+// back so we can switch to using it.
+void LLTexLayerSetBuffer::doUpload()
{
llinfos << "Uploading baked " << mTexLayerSet->getBodyRegionName() << llendl;
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES);
@@ -447,6 +492,7 @@ void LLTexLayerSetBuffer::readBackAndUpload()
LLBakedUploadData* baked_upload_data = new LLBakedUploadData(gAgentAvatarp,
this->mTexLayerSet,
asset_id);
+ // upload ID is used to avoid overlaps, e.g. when the user rapidly makes two changes outside of Face Edit.
mUploadID = asset_id;
// Upload the image
@@ -490,12 +536,13 @@ void LLTexLayerSetBuffer::readBackAndUpload()
// Print out notification that we uploaded this texture.
if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
{
- std::string lod_str = highest_lod ? "HighRes" : "LowRes";
+ const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
LLSD args;
args["EXISTENCE"] = llformat("%d",(U32)mTexLayerSet->getAvatar()->debugGetExistenceTimeElapsedF32());
args["TIME"] = llformat("%d",(U32)mNeedsUploadTimer.getElapsedTimeF32());
args["BODYREGION"] = mTexLayerSet->getBodyRegionName();
args["RESOLUTION"] = lod_str;
+ args["ACTION"] = "uploaded";
LLNotificationsUtil::add("AvatarRezSelfBakeNotification",args);
llinfos << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << llendl;
}
@@ -520,6 +567,37 @@ void LLTexLayerSetBuffer::readBackAndUpload()
delete [] baked_color_data;
}
+// Mostly bookkeeping; don't need to actually "do" anything since
+// render() will actually do the update.
+void LLTexLayerSetBuffer::doUpdate()
+{
+ const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal();
+ if (highest_lod)
+ {
+ mNeedsUpdate = FALSE;
+ }
+ else
+ {
+ mNumLowresUpdates++;
+ }
+
+ restartUpdateTimer();
+
+ // Print out notification that we uploaded this texture.
+ if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
+ {
+ const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal();
+ const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
+ LLSD args;
+ args["EXISTENCE"] = llformat("%d",(U32)mTexLayerSet->getAvatar()->debugGetExistenceTimeElapsedF32());
+ args["TIME"] = llformat("%d",(U32)mNeedsUpdateTimer.getElapsedTimeF32());
+ args["BODYREGION"] = mTexLayerSet->getBodyRegionName();
+ args["RESOLUTION"] = lod_str;
+ args["ACTION"] = "locally updated";
+ LLNotificationsUtil::add("AvatarRezSelfBakeNotification",args);
+ llinfos << "Locally updating [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << llendl;
+ }
+}
// static
void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid,
@@ -931,7 +1009,7 @@ void LLTexLayerSet::setUpdatesEnabled( BOOL b )
void LLTexLayerSet::updateComposite()
{
createComposite();
- mComposite->updateImmediate();
+ mComposite->requestUpdateImmediate();
}
LLTexLayerSetBuffer* LLTexLayerSet::getComposite()
diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h
index cb2e1faaa6..745cd88c47 100644
--- a/indra/newview/lltexlayer.h
+++ b/indra/newview/lltexlayer.h
@@ -270,47 +270,69 @@ class LLTexLayerSetBuffer : public LLViewerDynamicTexture
public:
LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height);
virtual ~LLTexLayerSetBuffer();
- /*virtual*/ S8 getType() const;
- virtual void preRender(BOOL clear_depth);
- virtual void postRender(BOOL success);
- virtual BOOL render();
- BOOL updateImmediate();
+public:
+ /*virtual*/ S8 getType() const;
BOOL isInitialized(void) const;
- BOOL uploadPending() const; // We are expecting a new texture to be uploaded at some point
- BOOL uploadNeeded() const; // We need to upload a new texture
- BOOL uploadInProgress() const; // We have started uploading a new texture and are awaiting the result
+ static void dumpTotalByteCount();
+ const std::string dumpTextureInfo() const;
+ virtual void restoreGLTexture();
+ virtual void destroyGLTexture();
+protected:
+ void pushProjection() const;
+ void popProjection() const;
+private:
+ LLTexLayerSet* const mTexLayerSet;
+ static S32 sGLByteCount;
+ //--------------------------------------------------------------------
+ // Render
+ //--------------------------------------------------------------------
+public:
/*virtual*/ BOOL needsRender();
- void requestUpdate();
+protected:
+ BOOL render(S32 x, S32 y, S32 width, S32 height);
+ virtual void preRender(BOOL clear_depth);
+ virtual void postRender(BOOL success);
+ virtual BOOL render();
+
+ //--------------------------------------------------------------------
+ // Uploads
+ //--------------------------------------------------------------------
+public:
void requestUpload();
void cancelUpload();
- BOOL render(S32 x, S32 y, S32 width, S32 height);
- void readBackAndUpload();
+ BOOL uploadNeeded() const; // We need to upload a new texture
+ BOOL uploadInProgress() const; // We have started uploading a new texture and are awaiting the result
+ BOOL uploadPending() const; // We are expecting a new texture to be uploaded at some point
static void onTextureUploadComplete(const LLUUID& uuid,
void* userdata,
S32 result, LLExtStat ext_status);
- static void dumpTotalByteCount();
- const std::string dumpTextureInfo() const;
- virtual void restoreGLTexture();
- virtual void destroyGLTexture();
-
-
protected:
- void pushProjection() const;
- void popProjection() const;
BOOL isReadyToUpload() const;
+ void doUpload(); // Does a read back and upload.
void conditionalRestartUploadTimer();
-
private:
- LLTexLayerSet* const mTexLayerSet;
- BOOL mNeedsUpdate; // whether we need to update our baked textures
- BOOL mNeedsUpload; // whether we need to send our baked textures to the server
- U32 mNumLowresUploads; // number of times we've sent a lowres version of our baked textures to the server
- BOOL mUploadPending; // whether we have received back the new baked textures
- LLUUID mUploadID; // the current upload process (null if none). Used to avoid overlaps, e.g. when the user rapidly makes two changes outside of Face Edit.
- static S32 sGLByteCount;
- LLFrameTimer mNeedsUploadTimer; // Tracks time since upload was requested
+ BOOL mNeedsUpload; // Whether we need to send our baked textures to the server
+ U32 mNumLowresUploads; // Number of times we've sent a lowres version of our baked textures to the server
+ BOOL mUploadPending; // Whether we have received back the new baked textures
+ LLUUID mUploadID; // The current upload process (null if none).
+ LLFrameTimer mNeedsUploadTimer; // Tracks time since upload was requested and performed.
+
+ //--------------------------------------------------------------------
+ // Updates
+ //--------------------------------------------------------------------
+public:
+ void requestUpdate();
+ BOOL requestUpdateImmediate();
+protected:
+ BOOL isReadyToUpdate() const;
+ void doUpdate();
+ void restartUpdateTimer();
+private:
+ BOOL mNeedsUpdate; // Whether we need to locally update our baked textures
+ U32 mNumLowresUpdates; // Number of times we've locally updated with lowres version of our baked textures
+ LLFrameTimer mNeedsUpdateTimer; // Tracks time since update was requested and performed.
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/newview/lltexlayerparams.cpp b/indra/newview/lltexlayerparams.cpp
index f2d1b5d032..dc97c4b673 100644
--- a/indra/newview/lltexlayerparams.cpp
+++ b/indra/newview/lltexlayerparams.cpp
@@ -180,7 +180,7 @@ void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL upload_bake)
if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
{
- if (gAgentCamera.cameraCustomizeAvatar())
+ if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
{
upload_bake = FALSE;
}
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 9ad2322765..403692951f 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -391,6 +391,7 @@ bool LLTextureCacheRemoteWorker::doRead()
}
else
{
+ //llinfos << "texture " << mID.asString() << " found in local_assets" << llendl;
mImageSize = local_size;
mImageLocal = TRUE;
}
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index fcb9deb20b..d324cb1565 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -175,6 +175,8 @@ protected:
BOOL mNoCopyTextureSelected;
F32 mContextConeOpacity;
LLSaveFolderState mSavedFolderState;
+
+ BOOL mSelectedItemPinned;
};
LLFloaterTexturePicker::LLFloaterTexturePicker(
@@ -197,7 +199,8 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
mFilterEdit(NULL),
mImmediateFilterPermMask(immediate_filter_perm_mask),
mNonImmediateFilterPermMask(non_immediate_filter_perm_mask),
- mContextConeOpacity(0.f)
+ mContextConeOpacity(0.f),
+ mSelectedItemPinned( FALSE )
{
mCanApplyImmediately = can_apply_immediately;
LLUICtrlFactory::getInstance()->buildFloater(this,"floater_texture_ctrl.xml",NULL);
@@ -593,6 +596,31 @@ void LLFloaterTexturePicker::draw()
mTentativeLabel->setVisible( TRUE );
drawChild(mTentativeLabel);
}
+
+ if (mSelectedItemPinned) return;
+
+ LLFolderView* folder_view = mInventoryPanel->getRootFolder();
+ if (!folder_view) return;
+
+ LLInventoryFilter* filter = folder_view->getFilter();
+ if (!filter) return;
+
+ bool is_filter_active = folder_view->getCompletedFilterGeneration() < filter->getCurrentGeneration() &&
+ filter->isNotDefault();
+
+ // After inventory panel filter is applied we have to update
+ // constraint rect for the selected item because of folder view
+ // AutoSelectOverride set to TRUE. We force PinningSelectedItem
+ // flag to FALSE state and setting filter "dirty" to update
+ // scroll container to show selected item (see LLFolderView::doIdle()).
+ if (!is_filter_active && !mSelectedItemPinned)
+ {
+ folder_view->setPinningSelectedItem(mSelectedItemPinned);
+ folder_view->dirtyFilter();
+ folder_view->arrangeFromRoot();
+
+ mSelectedItemPinned = TRUE;
+ }
}
}
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index ceed90e210..dddfed097d 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -290,8 +290,8 @@ class HTTPGetResponder : public LLCurl::Responder
{
LOG_CLASS(HTTPGetResponder);
public:
- HTTPGetResponder(LLTextureFetch* fetcher, const LLUUID& id, U64 startTime, S32 requestedSize, U32 offset)
- : mFetcher(fetcher), mID(id), mStartTime(startTime), mRequestedSize(requestedSize), mOffset(offset)
+ HTTPGetResponder(LLTextureFetch* fetcher, const LLUUID& id, U64 startTime, S32 requestedSize, U32 offset, bool redir)
+ : mFetcher(fetcher), mID(id), mStartTime(startTime), mRequestedSize(requestedSize), mOffset(offset), mFollowRedir(redir)
{
}
~HTTPGetResponder()
@@ -344,6 +344,11 @@ public:
llwarns << "Worker not found: " << mID << llendl;
}
}
+
+ virtual bool followRedir()
+ {
+ return mFollowRedir;
+ }
private:
LLTextureFetch* mFetcher;
@@ -351,6 +356,7 @@ private:
U64 mStartTime;
S32 mRequestedSize;
U32 mOffset;
+ bool mFollowRedir;
};
//////////////////////////////////////////////////////////////////////////////
@@ -897,7 +903,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
std::vector<std::string> headers;
headers.push_back("Accept: image/x-j2c");
res = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize,
- new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset));
+ new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset, true));
}
if (!res)
{
@@ -945,17 +951,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
max_attempts = mHTTPFailCount+1; // Keep retrying
LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL;
}
- else if(mGetStatus >= HTTP_MULTIPLE_CHOICES && mGetStatus < HTTP_BAD_REQUEST) //http re-direct
- {
- ++mHTTPFailCount;
- max_attempts = 5 ; //try at most 5 times to avoid infinite redirection loop.
-
- llwarns << "HTTP GET failed because of redirection: " << mUrl
- << " Status: " << mGetStatus << " Reason: '" << mGetReason << llendl ;
-
- //assign to the new url
- mUrl = mGetReason ;
- }
else
{
const S32 HTTP_MAX_RETRY_COUNT = 3;
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 8ea4dbeb04..b588ff91d1 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -450,14 +450,14 @@ void LLAvatarTexBar::draw()
text_color, LLFontGL::LEFT, LLFontGL::TOP); //, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT);
line_num++;
}
- const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureTimeout");
+ const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureUploadTimeout");
const U32 override_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
LLColor4 header_color(1.f, 1.f, 1.f, 0.9f);
const std::string texture_timeout_str = texture_timeout ? llformat("%d",texture_timeout) : "Disabled";
const std::string override_tex_discard_level_str = override_tex_discard_level ? llformat("%d",override_tex_discard_level) : "Disabled";
- std::string header_text = llformat("[ Timeout('AvatarBakedTextureTimeout'):%s ] [ LOD_Override('TextureDiscardLevel'):%s ]", texture_timeout_str.c_str(), override_tex_discard_level_str.c_str());
+ std::string header_text = llformat("[ Timeout('AvatarBakedTextureUploadTimeout'):%s ] [ LOD_Override('TextureDiscardLevel'):%s ]", texture_timeout_str.c_str(), override_tex_discard_level_str.c_str());
LLFontGL::getFontMonospace()->renderUTF8(header_text, 0, l_offset, v_offset + line_height*line_num,
header_color, LLFontGL::LEFT, LLFontGL::TOP); //, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT);
line_num++;
diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp
index fa21b1a866..81559429b0 100644
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -147,7 +147,7 @@ void LLVisualParamHint::requestHintUpdates( LLVisualParamHint* exception1, LLVis
BOOL LLVisualParamHint::needsRender()
{
- return mNeedsUpdate && mDelayFrames-- <= 0 && !gAgentAvatarp->mAppearanceAnimating && mAllowsUpdates;
+ return mNeedsUpdate && mDelayFrames-- <= 0 && !gAgentAvatarp->getIsAppearanceAnimating() && mAllowsUpdates;
}
void LLVisualParamHint::preRender(BOOL clear_depth)
diff --git a/indra/newview/llviewerattachmenu.cpp b/indra/newview/llviewerattachmenu.cpp
index f7f5ec72fd..f683bd8674 100644
--- a/indra/newview/llviewerattachmenu.cpp
+++ b/indra/newview/llviewerattachmenu.cpp
@@ -84,7 +84,7 @@ void LLViewerAttachMenu::populateMenus(const std::string& attach_to_menu_name, c
LLSD cbparams;
cbparams["index"] = curiter->first;
- cbparams["label"] = attachment->getName();
+ cbparams["label"] = p.name;
p.on_click.function_name = "Object.Attach";
p.on_click.parameter = LLSD(attachment->getName());
p.on_enable.function_name = "Attachment.Label";
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 1ff4d6db9e..7e8f11c41a 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -67,7 +67,7 @@
#include "llsidepanelappearance.h"
///----------------------------------------------------------------------------
-/// Helper class to store special inventory item names
+/// Helper class to store special inventory item names and their localized values.
///----------------------------------------------------------------------------
class LLLocalizedInventoryItemsDictionary : public LLSingleton<LLLocalizedInventoryItemsDictionary>
{
@@ -93,8 +93,10 @@ public:
mInventoryItemsDict["New Tattoo"] = LLTrans::getString("New Tattoo");
mInventoryItemsDict["Invalid Wearable"] = LLTrans::getString("Invalid Wearable");
+ mInventoryItemsDict["New Gesture"] = LLTrans::getString("New Gesture");
mInventoryItemsDict["New Script"] = LLTrans::getString("New Script");
mInventoryItemsDict["New Folder"] = LLTrans::getString("New Folder");
+ mInventoryItemsDict["New Note"] = LLTrans::getString("New Note");
mInventoryItemsDict["Contents"] = LLTrans::getString("Contents");
mInventoryItemsDict["Gesture"] = LLTrans::getString("Gesture");
@@ -108,7 +110,7 @@ public:
//male
mInventoryItemsDict["Male - Excuse me"] = LLTrans::getString("Male - Excuse me");
- mInventoryItemsDict["Male - Get lost"] = LLTrans::getString("Male - Get lost");
+ mInventoryItemsDict["Male - Get lost"] = LLTrans::getString("Male - Get lost"); // double space after Male. EXT-8319
mInventoryItemsDict["Male - Blow kiss"] = LLTrans::getString("Male - Blow kiss");
mInventoryItemsDict["Male - Boo"] = LLTrans::getString("Male - Boo");
mInventoryItemsDict["Male - Bored"] = LLTrans::getString("Male - Bored");
@@ -120,19 +122,47 @@ public:
mInventoryItemsDict["Male - Wow"] = LLTrans::getString("Male - Wow");
//female
+ mInventoryItemsDict["Female - Chuckle"] = LLTrans::getString("Female - Chuckle");
+ mInventoryItemsDict["Female - Cry"] = LLTrans::getString("Female - Cry");
+ mInventoryItemsDict["Female - Embarrassed"] = LLTrans::getString("Female - Embarrassed");
mInventoryItemsDict["Female - Excuse me"] = LLTrans::getString("Female - Excuse me");
- mInventoryItemsDict["Female - Get lost"] = LLTrans::getString("Female - Get lost");
+ mInventoryItemsDict["Female - Get lost"] = LLTrans::getString("Female - Get lost"); // double space after Female. EXT-8319
mInventoryItemsDict["Female - Blow kiss"] = LLTrans::getString("Female - Blow kiss");
mInventoryItemsDict["Female - Boo"] = LLTrans::getString("Female - Boo");
mInventoryItemsDict["Female - Bored"] = LLTrans::getString("Female - Bored");
mInventoryItemsDict["Female - Hey"] = LLTrans::getString("Female - Hey");
+ mInventoryItemsDict["Female - Hey baby"] = LLTrans::getString("Female - Hey baby");
mInventoryItemsDict["Female - Laugh"] = LLTrans::getString("Female - Laugh");
+ mInventoryItemsDict["Female - Looking good"] = LLTrans::getString("Female - Looking good");
+ mInventoryItemsDict["Female - Over here"] = LLTrans::getString("Female - Over here");
+ mInventoryItemsDict["Female - Please"] = LLTrans::getString("Female - Please");
mInventoryItemsDict["Female - Repulsed"] = LLTrans::getString("Female - Repulsed");
mInventoryItemsDict["Female - Shrug"] = LLTrans::getString("Female - Shrug");
mInventoryItemsDict["Female - Stick tougue out"]= LLTrans::getString("Female - Stick tougue out");
mInventoryItemsDict["Female - Wow"] = LLTrans::getString("Female - Wow");
}
+
+ /**
+ * Finds passed name in dictionary and replaces it with found localized value.
+ *
+ * @param object_name - string to be localized.
+ * @return true if passed name was found and localized, false otherwise.
+ */
+ bool localizeInventoryObjectName(std::string& object_name)
+ {
+ LL_DEBUGS("InventoryLocalize") << "Searching for localization: " << object_name << LL_ENDL;
+
+ std::map<std::string, std::string>::const_iterator dictionary_iter = mInventoryItemsDict.find(object_name);
+
+ bool found = dictionary_iter != mInventoryItemsDict.end();
+ if(found)
+ {
+ object_name = dictionary_iter->second;
+ LL_DEBUGS("InventoryLocalize") << "Found, new name is: " << object_name << LL_ENDL;
+ }
+ return found;
+ }
};
@@ -391,16 +421,7 @@ BOOL LLViewerInventoryItem::unpackMessage(LLMessageSystem* msg, const char* bloc
{
BOOL rv = LLInventoryItem::unpackMessage(msg, block, block_num);
- std::string localized_str;
-
- std::map<std::string, std::string>::const_iterator dictionary_iter;
-
- dictionary_iter = LLLocalizedInventoryItemsDictionary::getInstance()->mInventoryItemsDict.find(mName);
-
- if(dictionary_iter != LLLocalizedInventoryItemsDictionary::getInstance()->mInventoryItemsDict.end())
- {
- mName = dictionary_iter->second;
- }
+ LLLocalizedInventoryItemsDictionary::getInstance()->localizeInventoryObjectName(mName);
mIsComplete = TRUE;
return rv;
@@ -820,6 +841,11 @@ void LLViewerInventoryCategory::changeType(LLFolderType::EType new_folder_type)
gInventory.addChangedMask(LLInventoryObserver::LABEL, folder_id);
}
+void LLViewerInventoryCategory::localizeName()
+{
+ LLLocalizedInventoryItemsDictionary::getInstance()->localizeInventoryObjectName(mName);
+}
+
///----------------------------------------------------------------------------
/// Local function definitions
///----------------------------------------------------------------------------
@@ -895,7 +921,7 @@ void ModifiedCOFCallback::fire(const LLUUID& inv_item)
gAgentWearables.editWearableIfRequested(inv_item);
// TODO: camera mode may not be changed if a debug setting is tweaked
- if( gAgentCamera.cameraCustomizeAvatar() )
+ if(gAgentCamera.cameraCustomizeAvatar())
{
// If we're in appearance editing mode, the current tab may need to be refreshed
LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLSideTray::getInstance()->getPanel("sidepanel_appearance"));
@@ -1132,6 +1158,14 @@ void move_inventory_item(
void copy_inventory_from_notecard(const LLUUID& object_id, const LLUUID& notecard_inv_id, const LLInventoryItem *src, U32 callback_id)
{
+ if (NULL == src)
+ {
+ LL_WARNS("copy_inventory_from_notecard") << "Null pointer to item was passed for object_id "
+ << object_id << " and notecard_inv_id "
+ << notecard_inv_id << LL_ENDL;
+ return;
+ }
+
LLViewerRegion* viewer_region = NULL;
LLViewerObject* vo = NULL;
if (object_id.notNull() && (vo = gObjectList.findObject(object_id)) != NULL)
@@ -1154,6 +1188,16 @@ void copy_inventory_from_notecard(const LLUUID& object_id, const LLUUID& notecar
return;
}
+ // check capability to prevent a crash while LL_ERRS in LLCapabilityListener::capListener. See EXT-8459.
+ std::string url = viewer_region->getCapability("CopyInventoryFromNotecard");
+ if (url.empty())
+ {
+ LL_WARNS("copy_inventory_from_notecard") << "There is no 'CopyInventoryFromNotecard' capability"
+ << " for region: " << viewer_region->getName()
+ << LL_ENDL;
+ return;
+ }
+
LLSD request, body;
body["notecard-id"] = notecard_inv_id;
body["object-id"] = object_id;
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index d0d3ad693e..690c23e6a5 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -228,6 +228,11 @@ public:
bool importFileLocal(LLFILE* fp);
void determineFolderType();
void changeType(LLFolderType::EType new_folder_type);
+
+private:
+ friend class LLInventoryModel;
+ void localizeName(); // intended to be called from the LLInventoryModel
+
protected:
LLUUID mOwnerID;
S32 mVersion;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 635cc361f3..df8e127b1f 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -108,9 +108,12 @@
#include "llappearancemgr.h"
#include "lltrans.h"
#include "lleconomy.h"
+#include "boost/unordered_map.hpp"
using namespace LLVOAvatarDefines;
+static boost::unordered_map<std::string, LLStringExplicit> sDefaultItemLabels;
+
BOOL enable_land_build(void*);
BOOL enable_object_build(void*);
@@ -2403,31 +2406,53 @@ void handle_object_touch()
msg->sendMessage(object->getRegion()->getHost());
}
-// One object must have touch sensor
-class LLObjectEnableTouch : public view_listener_t
+static void init_default_item_label(const std::string& item_name)
{
- bool handleEvent(const LLSD& userdata)
+ boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
+ if (it == sDefaultItemLabels.end())
{
- LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
-
- bool new_value = obj && obj->flagHandleTouch();
-
- // Update label based on the node touch name if available.
- std::string touch_text;
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
- if (node && node->mValid && !node->mTouchName.empty())
- {
- touch_text = node->mTouchName;
- }
- else
+ LLStringExplicit default_label = gMenuHolder->childGetValue(item_name).asString();
+ if (!default_label.empty())
{
- touch_text = userdata.asString();
+ sDefaultItemLabels.insert(std::pair<std::string, LLStringExplicit>(item_name, default_label));
}
- gMenuHolder->childSetText("Object Touch", touch_text);
- gMenuHolder->childSetText("Attachment Object Touch", touch_text);
+ }
+}
- return new_value;
+static LLStringExplicit get_default_item_label(const std::string& item_name)
+{
+ LLStringExplicit res("");
+ boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
+ if (it != sDefaultItemLabels.end())
+ {
+ res = it->second;
+ }
+
+ return res;
+}
+
+
+bool enable_object_touch(LLUICtrl* ctrl)
+{
+ LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+
+ bool new_value = obj && obj->flagHandleTouch();
+
+ std::string item_name = ctrl->getName();
+ init_default_item_label(item_name);
+
+ // Update label based on the node touch name if available.
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
+ if (node && node->mValid && !node->mTouchName.empty())
+ {
+ gMenuHolder->childSetText(item_name, node->mTouchName);
+ }
+ else
+ {
+ gMenuHolder->childSetText(item_name, get_default_item_label(item_name));
}
+
+ return new_value;
};
//void label_touch(std::string& label, void*)
@@ -3627,7 +3652,7 @@ class LLEnableEditShape : public view_listener_t
}
};
-bool enable_sit_object()
+bool is_object_sittable()
{
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
@@ -5513,56 +5538,37 @@ bool enable_pay_object()
return false;
}
-bool visible_object_stand_up()
+bool enable_object_stand_up()
{
- // 'Object Stand Up' menu item is visible when agent is sitting on selection
+ // 'Object Stand Up' menu item is enabled when agent is sitting on selection
return sitting_on_selection();
}
-bool visible_object_sit()
+bool enable_object_sit(LLUICtrl* ctrl)
{
- // 'Object Sit' menu item is visible when agent is not sitting on selection
- bool is_sit_visible = !sitting_on_selection();
- if (is_sit_visible)
+ // 'Object Sit' menu item is enabled when agent is not sitting on selection
+ bool sitting_on_sel = sitting_on_selection();
+ if (!sitting_on_sel)
{
- LLMenuItemGL* sit_menu_item = gMenuHolder->getChild<LLMenuItemGL>("Object Sit");
- // Init default 'Object Sit' menu item label
- static const LLStringExplicit sit_text(sit_menu_item->getLabel());
+ std::string item_name = ctrl->getName();
+
+ // init default labels
+ init_default_item_label(item_name);
+
// Update label
- std::string label;
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
if (node && node->mValid && !node->mSitName.empty())
{
- label.assign(node->mSitName);
+ gMenuHolder->childSetText(item_name, node->mSitName);
}
else
{
- label = sit_text;
+ gMenuHolder->childSetText(item_name, get_default_item_label(item_name));
}
- sit_menu_item->setLabel(label);
}
- return is_sit_visible;
+ return !sitting_on_sel && is_object_sittable();
}
-class LLObjectEnableSitOrStand : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = false;
- LLViewerObject* dest_object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
-
- if(dest_object)
- {
- if(dest_object->getPCode() == LL_PCODE_VOLUME)
- {
- new_value = true;
- }
- }
-
- return new_value;
- }
-};
-
void dump_select_mgr(void*)
{
LLSelectMgr::getInstance()->dump();
@@ -8067,7 +8073,6 @@ void initialize_menus()
view_listener_t::addMenu(new LLObjectBuild(), "Object.Build");
commit.add("Object.Touch", boost::bind(&handle_object_touch));
commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand));
- enable.add("Object.EnableSit", boost::bind(&enable_sit_object));
commit.add("Object.Delete", boost::bind(&handle_object_delete));
view_listener_t::addMenu(new LLObjectAttachToAvatar(), "Object.AttachToAvatar");
view_listener_t::addMenu(new LLObjectReturn(), "Object.Return");
@@ -8083,13 +8088,12 @@ void initialize_menus()
commit.add("Object.Open", boost::bind(&handle_object_open));
commit.add("Object.Take", boost::bind(&handle_take));
enable.add("Object.EnableOpen", boost::bind(&enable_object_open));
- view_listener_t::addMenu(new LLObjectEnableTouch(), "Object.EnableTouch");
- view_listener_t::addMenu(new LLObjectEnableSitOrStand(), "Object.EnableSitOrStand");
+ enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1));
enable.add("Object.EnableDelete", boost::bind(&enable_object_delete));
enable.add("Object.EnableWear", boost::bind(&object_selected_and_point_valid));
- enable.add("Object.StandUpVisible", boost::bind(&visible_object_stand_up));
- enable.add("Object.SitVisible", boost::bind(&visible_object_sit));
+ enable.add("Object.EnableStandUp", boost::bind(&enable_object_stand_up));
+ enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1));
view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn");
view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 07b6431c92..04545d2549 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1138,10 +1138,26 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam
}
else if(from_name.empty())
{
+ std::string folder_name;
+ if (parent_folder)
+ {
+ // Localize folder name.
+ // *TODO: share this code?
+ folder_name = parent_folder->getName();
+ if (LLFolderType::lookupIsProtectedType(parent_folder->getPreferredType()))
+ {
+ LLTrans::findString(folder_name, "InvFolder " + folder_name);
+ }
+ }
+ else
+ {
+ folder_name = LLTrans::getString("Unknown");
+ }
+
// we receive a message from LLOpenTaskOffer, it mean that new landmark has been added.
LLSD args;
args["LANDMARK_NAME"] = item->getName();
- args["FOLDER_NAME"] = std::string(parent_folder ? parent_folder->getName() : "unknown");
+ args["FOLDER_NAME"] = folder_name;
LLNotificationsUtil::add("LandmarkCreated", args);
}
}
@@ -1215,8 +1231,9 @@ bool highlight_offered_object(const LLUUID& obj_id)
void inventory_offer_mute_callback(const LLUUID& blocked_id,
const std::string& first_name,
const std::string& last_name,
- BOOL is_group, LLOfferInfo* offer = NULL)
+ BOOL is_group, boost::shared_ptr<LLNotificationResponderInterface> offer_ptr)
{
+ LLOfferInfo* offer = dynamic_cast<LLOfferInfo*>(offer_ptr.get());
std::string from_name;
LLMute::EType type;
if (is_group)
@@ -1406,7 +1423,13 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
// * we can't build two messages at once.
if (2 == button) // Block
{
- gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4,this));
+ LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
+
+ llassert(notification_ptr != NULL);
+ if (notification_ptr != NULL)
+ {
+ gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4, notification_ptr->getResponderPtr()));
+ }
}
std::string from_string; // Used in the pop-up.
@@ -1540,7 +1563,13 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
// * we can't build two messages at once.
if (2 == button)
{
- gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4,this));
+ LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
+
+ llassert(notification_ptr != NULL);
+ if (notification_ptr != NULL)
+ {
+ gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4, notification_ptr->getResponderPtr()));
+ }
}
LLMessageSystem* msg = gMessageSystem;
@@ -5093,7 +5122,7 @@ void process_alert_message(LLMessageSystem *msgsystem, void **user_data)
void process_alert_core(const std::string& message, BOOL modal)
{
- // HACK -- handle callbacks for specific alerts
+ // HACK -- handle callbacks for specific alerts. It also is localized in notifications.xml
if ( message == "You died and have been teleported to your home location")
{
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT);
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 59efae4cb2..8bd43bb30c 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -90,7 +90,7 @@ public:
}
static void processForeignLandmark(LLLandmark* landmark,
const LLUUID& object_id, const LLUUID& notecard_inventory_id,
- LLInventoryItem* item)
+ LLPointer<LLInventoryItem> item_ptr)
{
LLVector3d global_pos;
landmark->getGlobalPos(global_pos);
@@ -103,8 +103,16 @@ public:
}
else
{
- LLPointer<LLEmbeddedLandmarkCopied> cb = new LLEmbeddedLandmarkCopied();
- copy_inventory_from_notecard(object_id, notecard_inventory_id, item, gInventoryCallbacks.registerCB(cb));
+ if (item_ptr.isNull())
+ {
+ // check to prevent a crash. See EXT-8459.
+ llwarns << "Passed handle contains a dead inventory item. Most likely notecard has been closed and embedded item was destroyed." << llendl;
+ }
+ else
+ {
+ LLPointer<LLEmbeddedLandmarkCopied> cb = new LLEmbeddedLandmarkCopied();
+ copy_inventory_from_notecard(object_id, notecard_inventory_id, item_ptr.get(), gInventoryCallbacks.registerCB(cb));
+ }
}
}
};
@@ -300,14 +308,14 @@ public:
void markSaved();
- static LLInventoryItem* getEmbeddedItem(llwchar ext_char); // returns item from static list
+ static LLPointer<LLInventoryItem> getEmbeddedItemPtr(llwchar ext_char); // returns pointer to item from static list
static BOOL getEmbeddedItemSaved(llwchar ext_char); // returns whether item from static list is saved
private:
struct embedded_info_t
{
- LLPointer<LLInventoryItem> mItem;
+ LLPointer<LLInventoryItem> mItemPtr;
BOOL mSaved;
};
typedef std::map<llwchar, embedded_info_t > item_map_t;
@@ -378,7 +386,7 @@ BOOL LLEmbeddedItems::insertEmbeddedItem( LLInventoryItem* item, llwchar* ext_ch
++wc_emb;
}
- sEntries[wc_emb].mItem = item;
+ sEntries[wc_emb].mItemPtr = item;
sEntries[wc_emb].mSaved = is_new ? FALSE : TRUE;
*ext_char = wc_emb;
mEmbeddedUsedChars.insert(wc_emb);
@@ -400,14 +408,14 @@ BOOL LLEmbeddedItems::removeEmbeddedItem( llwchar ext_char )
}
// static
-LLInventoryItem* LLEmbeddedItems::getEmbeddedItem(llwchar ext_char)
+LLPointer<LLInventoryItem> LLEmbeddedItems::getEmbeddedItemPtr(llwchar ext_char)
{
if( ext_char >= LLTextEditor::FIRST_EMBEDDED_CHAR && ext_char <= LLTextEditor::LAST_EMBEDDED_CHAR )
{
item_map_t::iterator iter = sEntries.find(ext_char);
if (iter != sEntries.end())
{
- return iter->second.mItem;
+ return iter->second.mItemPtr;
}
}
return NULL;
@@ -505,7 +513,7 @@ BOOL LLEmbeddedItems::hasEmbeddedItem(llwchar ext_char)
LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const
{
- LLInventoryItem* item = getEmbeddedItem(ext_char);
+ LLInventoryItem* item = getEmbeddedItemPtr(ext_char);
if (item)
{
const char* img_name = "";
@@ -567,7 +575,7 @@ void LLEmbeddedItems::getEmbeddedItemList( std::vector<LLPointer<LLInventoryItem
for (std::set<llwchar>::iterator iter = mEmbeddedUsedChars.begin(); iter != mEmbeddedUsedChars.end(); ++iter)
{
llwchar wc = *iter;
- LLPointer<LLInventoryItem> item = getEmbeddedItem(wc);
+ LLPointer<LLInventoryItem> item = getEmbeddedItemPtr(wc);
if (item)
{
items.push_back(item);
@@ -698,7 +706,7 @@ BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
{
wc = getWText()[mCursorPos];
}
- LLInventoryItem* item_at_pos = LLEmbeddedItems::getEmbeddedItem(wc);
+ LLPointer<LLInventoryItem> item_at_pos = LLEmbeddedItems::getEmbeddedItemPtr(wc);
if (item_at_pos)
{
mDragItem = item_at_pos;
@@ -1019,7 +1027,7 @@ llwchar LLViewerTextEditor::pasteEmbeddedItem(llwchar ext_char)
{
return ext_char; // already exists in my list
}
- LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItem(ext_char);
+ LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItemPtr(ext_char);
if (item)
{
// Add item to my list and return new llwchar associated with it
@@ -1053,7 +1061,7 @@ void LLViewerTextEditor::findEmbeddedItemSegments(S32 start, S32 end)
&& embedded_char <= LAST_EMBEDDED_CHAR
&& mEmbeddedItemList->hasEmbeddedItem(embedded_char) )
{
- LLInventoryItem* itemp = mEmbeddedItemList->getEmbeddedItem(embedded_char);
+ LLInventoryItem* itemp = mEmbeddedItemList->getEmbeddedItemPtr(embedded_char);
LLUIImagePtr image = mEmbeddedItemList->getItemImage(embedded_char);
insertSegment(new LLEmbeddedItemSegment(idx, image, itemp, *this));
}
@@ -1065,7 +1073,7 @@ BOOL LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos)
if( pos < getLength())
{
llwchar wc = getWText()[pos];
- LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItem( wc );
+ LLPointer<LLInventoryItem> item = LLEmbeddedItems::getEmbeddedItemPtr( wc );
if( item )
{
BOOL saved = LLEmbeddedItems::getEmbeddedItemSaved( wc );
@@ -1083,7 +1091,7 @@ BOOL LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos)
}
-BOOL LLViewerTextEditor::openEmbeddedItem(LLInventoryItem* item, llwchar wc)
+BOOL LLViewerTextEditor::openEmbeddedItem(LLPointer<LLInventoryItem> item, llwchar wc)
{
switch( item->getType() )
@@ -1151,17 +1159,17 @@ void LLViewerTextEditor::openEmbeddedSound( LLInventoryItem* item, llwchar wc )
}
-void LLViewerTextEditor::openEmbeddedLandmark( LLInventoryItem* item, llwchar wc )
+void LLViewerTextEditor::openEmbeddedLandmark( LLPointer<LLInventoryItem> item_ptr, llwchar wc )
{
- if (!item)
+ if (item_ptr.isNull())
return;
- LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID(),
- boost::bind(&LLEmbeddedLandmarkCopied::processForeignLandmark, _1, mObjectID, mNotecardInventoryID, item));
+ LLLandmark* landmark = gLandmarkList.getAsset(item_ptr->getAssetUUID(),
+ boost::bind(&LLEmbeddedLandmarkCopied::processForeignLandmark, _1, mObjectID, mNotecardInventoryID, item_ptr));
if (landmark)
{
LLEmbeddedLandmarkCopied::processForeignLandmark(landmark, mObjectID,
- mNotecardInventoryID, item);
+ mNotecardInventoryID, item_ptr);
}
}
@@ -1220,7 +1228,7 @@ bool LLViewerTextEditor::onCopyToInvDialog(const LLSD& notification, const LLSD&
{
LLUUID item_id = notification["payload"]["item_id"].asUUID();
llwchar wc = llwchar(notification["payload"]["item_wc"].asInteger());
- LLInventoryItem* itemp = LLEmbeddedItems::getEmbeddedItem(wc);
+ LLInventoryItem* itemp = LLEmbeddedItems::getEmbeddedItemPtr(wc);
if (itemp)
copyInventory(itemp);
}
diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h
index ba0c40cb2e..74b6d70640 100644
--- a/indra/newview/llviewertexteditor.h
+++ b/indra/newview/llviewertexteditor.h
@@ -104,13 +104,16 @@ private:
virtual llwchar pasteEmbeddedItem(llwchar ext_char);
BOOL openEmbeddedItemAtPos( S32 pos );
- BOOL openEmbeddedItem(LLInventoryItem* item, llwchar wc);
+ BOOL openEmbeddedItem(LLPointer<LLInventoryItem> item, llwchar wc);
S32 insertEmbeddedItem(S32 pos, LLInventoryItem* item);
+ // *NOTE: most of openEmbeddedXXX methods except openEmbeddedLandmark take pointer to LLInventoryItem.
+ // Be sure they don't bind it to callback function to avoid situation when it gets invalid when
+ // callback is trigged after text editor is closed. See EXT-8459.
void openEmbeddedTexture( LLInventoryItem* item, llwchar wc );
void openEmbeddedSound( LLInventoryItem* item, llwchar wc );
- void openEmbeddedLandmark( LLInventoryItem* item, llwchar wc );
+ void openEmbeddedLandmark( LLPointer<LLInventoryItem> item_ptr, llwchar wc );
void openEmbeddedNotecard( LLInventoryItem* item, llwchar wc);
void openEmbeddedCallingcard( LLInventoryItem* item, llwchar wc);
void showCopyToInvDialog( LLInventoryItem* item, llwchar wc );
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 0afbce7d51..2929dce898 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -114,7 +114,6 @@ LLLoadedCallbackEntry::LLLoadedCallbackEntry(loaded_callback_func cb,
BOOL need_imageraw, // Needs image raw for the callback
void* userdata,
LLLoadedCallbackEntry::source_callback_list_t* src_callback_list,
- void* source,
LLViewerFetchedTexture* target,
BOOL pause)
: mCallback(cb),
@@ -123,7 +122,6 @@ LLLoadedCallbackEntry::LLLoadedCallbackEntry(loaded_callback_func cb,
mNeedsImageRaw(need_imageraw),
mUserData(userdata),
mSourceCallbackList(src_callback_list),
- mSource(source),
mPaused(pause)
{
if(mSourceCallbackList)
@@ -145,10 +143,10 @@ void LLLoadedCallbackEntry::removeTexture(LLViewerFetchedTexture* tex)
}
//static
-void LLLoadedCallbackEntry::cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list, void* src)
+void LLLoadedCallbackEntry::cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list)
{
//clear texture callbacks.
- if(!callback_list->empty())
+ if(callback_list && !callback_list->empty())
{
for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = callback_list->begin();
iter != callback_list->end(); ++iter)
@@ -156,7 +154,7 @@ void LLLoadedCallbackEntry::cleanUpCallbackList(LLLoadedCallbackEntry::source_ca
LLViewerFetchedTexture* tex = gTextureList.findImage(*iter) ;
if(tex)
{
- tex->deleteCallbackEntry(src) ;
+ tex->deleteCallbackEntry(callback_list) ;
}
}
callback_list->clear() ;
@@ -513,6 +511,7 @@ LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps)
LLViewerTexture::~LLViewerTexture()
{
+ cleanup();
sImageCount--;
}
@@ -545,7 +544,6 @@ S8 LLViewerTexture::getType() const
return LLViewerTexture::LOCAL_TEXTURE ;
}
-//virtual
void LLViewerTexture::cleanup()
{
mFaceList.clear() ;
@@ -1176,7 +1174,6 @@ S8 LLViewerFetchedTexture::getType() const
return LLViewerTexture::FETCHED_TEXTURE ;
}
-//virtual
void LLViewerFetchedTexture::cleanup()
{
for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
@@ -1198,8 +1195,6 @@ void LLViewerFetchedTexture::cleanup()
mCachedRawDiscardLevel = -1 ;
mCachedRawImageReady = FALSE ;
mSavedRawImage = NULL ;
-
- LLViewerTexture::cleanup();
}
void LLViewerFetchedTexture::setForSculpt()
@@ -1609,6 +1604,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired;
ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);
priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;
+ setAdditionalDecodePriority(1.0f) ;//boost the textures without any data so far.
}
else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel))
{
@@ -2003,7 +1999,7 @@ void LLViewerFetchedTexture::setIsMissingAsset()
}
void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_callback,
- S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* userdata, void* src,
+ S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* userdata,
LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause)
{
//
@@ -2022,9 +2018,9 @@ void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_call
if(mPauseLoadedCallBacks && !pause)
{
- unpauseLoadedCallbacks(src) ;
+ unpauseLoadedCallbacks(src_callback_list) ;
}
- LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata, src_callback_list, src, this, pause);
+ LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata, src_callback_list, this, pause);
mLoadedCallbackList.push_back(entryp);
mNeedsAux |= needs_aux;
@@ -2039,9 +2035,9 @@ void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_call
}
}
-void LLViewerFetchedTexture::deleteCallbackEntry(void* src)
+void LLViewerFetchedTexture::deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)
{
- if(mLoadedCallbackList.empty())
+ if(mLoadedCallbackList.empty() || !callback_list)
{
return ;
}
@@ -2052,13 +2048,13 @@ void LLViewerFetchedTexture::deleteCallbackEntry(void* src)
iter != mLoadedCallbackList.end(); )
{
LLLoadedCallbackEntry *entryp = *iter;
- if(entryp->mSource == src)
+ if(entryp->mSourceCallbackList == callback_list)
{
// We never finished loading the image. Indicate failure.
// Note: this allows mLoadedCallbackUserData to be cleaned up.
entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData);
- delete entryp;
iter = mLoadedCallbackList.erase(iter) ;
+ delete entryp;
}
else
{
@@ -2097,14 +2093,20 @@ void LLViewerFetchedTexture::deleteCallbackEntry(void* src)
}
}
-void LLViewerFetchedTexture::unpauseLoadedCallbacks(void* src)
+void LLViewerFetchedTexture::unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)
{
+ if(!callback_list)
+ {
+ mPauseLoadedCallBacks = FALSE ;
+ return ;
+ }
+
BOOL need_raw = FALSE ;
for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
iter != mLoadedCallbackList.end(); )
{
LLLoadedCallbackEntry *entryp = *iter++;
- if(entryp->mSource == src)
+ if(entryp->mSourceCallbackList == callback_list)
{
entryp->mPaused = FALSE ;
if(entryp->mNeedsImageRaw)
@@ -2120,15 +2122,20 @@ void LLViewerFetchedTexture::unpauseLoadedCallbacks(void* src)
}
}
-void LLViewerFetchedTexture::pauseLoadedCallbacks(void* src)
+void LLViewerFetchedTexture::pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)
{
+ if(!callback_list)
+ {
+ return ;
+ }
+
bool paused = true ;
for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
iter != mLoadedCallbackList.end(); )
{
LLLoadedCallbackEntry *entryp = *iter++;
- if(entryp->mSource == src)
+ if(entryp->mSourceCallbackList == callback_list)
{
entryp->mPaused = TRUE ;
}
@@ -2305,10 +2312,6 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()
BOOL final = mRawDiscardLevel <= entryp->mDesiredDiscard ? TRUE : FALSE;
//llinfos << "Running callback for " << getID() << llendl;
//llinfos << mRawImage->getWidth() << "x" << mRawImage->getHeight() << llendl;
- if (final)
- {
- //llinfos << "Final!" << llendl;
- }
entryp->mLastUsedDiscard = mRawDiscardLevel;
entryp->mCallback(TRUE, this, mRawImage, mAuxRawImage, mRawDiscardLevel, final, entryp->mUserData);
if (final)
@@ -3665,7 +3668,7 @@ void LLTexturePipelineTester::updateStablizingTime()
{
F32 t = mEndStablizingTime - mStartStablizingTime ;
- if(t > 0.0001f && (t - mTotalStablizingTime) < 0.0001f)
+ if(t > F_ALMOST_ZERO && (t - mTotalStablizingTime) < F_ALMOST_ZERO)
{
//already stablized
mTotalStablizingTime = LLImageGL::sLastFrameTime - mStartStablizingTime ;
@@ -3790,7 +3793,7 @@ LLMetricPerformanceTester::LLTestSession* LLTexturePipelineTester::loadTestSessi
//time
F32 start_time = (*log)[label]["StartFetchingTime"].asReal() ;
F32 cur_time = (*log)[label]["Time"].asReal() ;
- if(start_time - start_fetching_time > 0.0001f) //fetching has paused for a while
+ if(start_time - start_fetching_time > F_ALMOST_ZERO) //fetching has paused for a while
{
sessionp->mTotalFetchingTime += total_fetching_time ;
sessionp->mTotalGrayTime += total_gray_time ;
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 8b69408e4b..f071c6e392 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -75,7 +75,6 @@ public:
BOOL need_imageraw, // Needs image raw for the callback
void* userdata,
source_callback_list_t* src_callback_list,
- void* source,
LLViewerFetchedTexture* target,
BOOL pause);
~LLLoadedCallbackEntry();
@@ -88,10 +87,9 @@ public:
BOOL mPaused;
void* mUserData;
source_callback_list_t* mSourceCallbackList;
- void* mSource;
public:
- static void cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list, void* src) ;
+ static void cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list) ;
};
class LLTextureBar;
@@ -264,7 +262,7 @@ public:
/*virtual*/ void updateBindStatsForTester() ;
protected:
- virtual void cleanup() ;
+ void cleanup() ;
void init(bool firstinit) ;
void reorganizeFaceList() ;
void reorganizeVolumeList() ;
@@ -384,13 +382,13 @@ public:
// Set callbacks to get called when the image gets updated with higher
// resolution versions.
void setLoadedCallback(loaded_callback_func cb,
- S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* src,
+ S32 discard_level, BOOL keep_imageraw, BOOL needs_aux,
void* userdata, LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause = FALSE);
bool hasCallbacks() { return mLoadedCallbackList.empty() ? false : true; }
- void pauseLoadedCallbacks(void* src);
- void unpauseLoadedCallbacks(void* src);
+ void pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);
+ void unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);
bool doLoadedCallbacks();
- void deleteCallbackEntry(void* src);
+ void deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);
void addToCreateTexture();
@@ -485,7 +483,7 @@ protected:
private:
void init(bool firstinit) ;
- /*virtual*/ void cleanup() ;
+ void cleanup() ;
void saveRawImage() ;
void setCachedRawImage() ;
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index b3aff30324..31f0998fab 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -1402,12 +1402,17 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st
mUIImages.insert(std::make_pair(name, new_imagep));
mUITextureList.push_back(imagep);
- LLUIImageLoadData* datap = new LLUIImageLoadData;
- datap->mImageName = name;
- datap->mImageScaleRegion = scale_rect;
-
- imagep->setLoadedCallback(onUIImageLoaded, 0, FALSE, FALSE, datap, NULL, NULL);
+ //Note:
+ //Some other textures such as ICON also through this flow to be fetched.
+ //But only UI textures need to set this callback.
+ if(imagep->getBoostLevel() == LLViewerTexture::BOOST_UI)
+ {
+ LLUIImageLoadData* datap = new LLUIImageLoadData;
+ datap->mImageName = name;
+ datap->mImageScaleRegion = scale_rect;
+ imagep->setLoadedCallback(onUIImageLoaded, 0, FALSE, FALSE, datap, NULL);
+ }
return new_imagep;
}
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 6346ac320b..5f0fcb72f0 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -4524,7 +4524,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)
gResizeScreenTexture = TRUE;
- if (gAgentCamera.cameraCustomizeAvatar())
+ if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
{
LLVisualParamHint::requestHintUpdates();
}
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 47e35ca0c4..32723dfe3d 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -835,6 +835,7 @@ LLVOAvatar::~LLVOAvatar()
mDead = TRUE;
mAnimationSources.clear();
+ LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;
lldebugs << "LLVOAvatar Destructor end" << llendl;
}
@@ -848,7 +849,7 @@ void LLVOAvatar::markDead()
sNumVisibleChatBubbles--;
}
mVoiceVisualizer->markDead();
- LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList, this) ;
+ LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;
LLViewerObject::markDead();
}
@@ -4142,9 +4143,13 @@ void LLVOAvatar::updateTextures()
}
else
{
- render_avatar = isVisible() && !mCulled;
+ if(!isVisible())
+ {
+ return ;//do not update for invisible avatar.
+ }
+
+ render_avatar = !mCulled; //visible and not culled.
}
- checkTextureLoading() ;
std::vector<BOOL> layer_baked;
// GL NOT ACTIVE HERE - *TODO
@@ -4224,10 +4229,11 @@ void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerFetchedTexture
return;
}
-
+const S32 MAX_TEXTURE_UPDATE_INTERVAL = 64 ; //need to call updateTextures() at least every 32 frames.
+const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = S32_MAX ; //frames
void LLVOAvatar::checkTextureLoading()
{
- static const F32 MAX_INVISIBLE_WAITING_TIME = 30.f ; //seconds
+ static const F32 MAX_INVISIBLE_WAITING_TIME = 15.f ; //seconds
BOOL pause = !isVisible() ;
if(!pause)
@@ -4247,7 +4253,7 @@ void LLVOAvatar::checkTextureLoading()
if(pause && mInvisibleTimer.getElapsedTimeF32() < MAX_INVISIBLE_WAITING_TIME)
{
- return ;
+ return ; //have not been invisible for enough time.
}
for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = mCallbackTextureList.begin();
@@ -4258,30 +4264,40 @@ void LLVOAvatar::checkTextureLoading()
{
if(pause)//pause texture fetching.
{
- tex->pauseLoadedCallbacks(this) ;
+ tex->pauseLoadedCallbacks(&mCallbackTextureList) ;
+
+ //set to terminate texture fetching after MAX_TEXTURE_UPDATE_INTERVAL frames.
+ tex->setMaxVirtualSizeResetInterval(MAX_TEXTURE_UPDATE_INTERVAL);
+ tex->resetMaxVirtualSizeResetCounter() ;
}
else//unpause
{
static const F32 START_AREA = 100.f ;
- tex->unpauseLoadedCallbacks(this) ;
+ tex->unpauseLoadedCallbacks(&mCallbackTextureList) ;
tex->addTextureStats(START_AREA); //jump start the fetching again
}
}
}
+ if(!pause)
+ {
+ updateTextures() ; //refresh texture stats.
+ }
mLoadedCallbacksPaused = pause ;
return ;
}
void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level)
{
- //if this function is not called for the last 512 frames, the texture pipeline will stop fetching this texture.
- static const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = 512 ; //frames
+ //Note:
+ //if this function is not called for the last MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL frames,
+ //the texture pipeline will stop fetching this texture.
imagep->resetTextureStats();
imagep->setCanUseHTTP(false) ; //turn off http fetching for baked textures.
imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
+ imagep->resetMaxVirtualSizeResetCounter() ;
mMaxPixelArea = llmax(pixel_area, mMaxPixelArea);
mMinPixelArea = llmin(pixel_area, mMinPixelArea);
@@ -6206,11 +6222,9 @@ void LLVOAvatar::updateMeshTextures()
const BOOL self_customizing = isSelf() && gAgentCamera.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures
const BOOL other_culled = !isSelf() && mCulled;
LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ;
- void* callback_src = NULL ;
BOOL paused = FALSE;
if(!isSelf())
{
- callback_src = this ;
src_callback_list = &mCallbackTextureList ;
paused = mLoadedCallbacksPaused ;
}
@@ -6286,10 +6300,10 @@ void LLVOAvatar::updateMeshTextures()
if ( (baked_img->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
{
baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ),
- callback_src, src_callback_list, paused);
+ src_callback_list, paused);
}
baked_img->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ),
- callback_src, src_callback_list, paused );
+ src_callback_list, paused );
}
}
else if (mBakedTextureDatas[i].mTexLayerSet
@@ -6750,11 +6764,9 @@ void LLVOAvatar::onFirstTEMessageReceived()
mFirstTEMessageReceived = TRUE;
LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ;
- void* callback_src = NULL ;
BOOL paused = FALSE ;
if(!isSelf())
{
- callback_src = this ;
src_callback_list = &mCallbackTextureList ;
paused = mLoadedCallbacksPaused ;
}
@@ -6773,10 +6785,10 @@ void LLVOAvatar::onFirstTEMessageReceived()
if ( (image->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
{
image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ),
- callback_src, src_callback_list, paused);
+ src_callback_list, paused);
}
image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ),
- callback_src, src_callback_list, paused );
+ src_callback_list, paused );
}
}
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 3dad919875..bb04511a8d 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -611,8 +611,9 @@ public:
// Appearance morphing
//--------------------------------------------------------------------
public:
- BOOL mAppearanceAnimating;
+ BOOL getIsAppearanceAnimating() const { return mAppearanceAnimating; }
private:
+ BOOL mAppearanceAnimating;
LLFrameTimer mAppearanceMorphTimer;
F32 mLastAppearanceBlendTime;
@@ -1048,5 +1049,6 @@ protected: // Shared with LLVOAvatarSelf
*******************************************************************************/
}; // LLVOAvatar
+extern const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL;
#endif // LL_VO_AVATAR_H
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 4edbbb7402..46d987353f 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1148,11 +1148,11 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr
discard_level < local_tex_obj->getDiscard())
{
local_tex_obj->setDiscard(discard_level);
- if (!gAgentCamera.cameraCustomizeAvatar())
+ if (isUsingBakedTextures())
{
requestLayerSetUpdate(index);
}
- else if (gAgentCamera.cameraCustomizeAvatar())
+ else
{
LLVisualParamHint::requestHintUpdates();
}
@@ -1622,18 +1622,21 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
if (tex_discard >= 0 && tex_discard <= desired_discard)
{
local_tex_obj->setDiscard(tex_discard);
- if (isSelf() && !gAgentCamera.cameraCustomizeAvatar())
- {
- requestLayerSetUpdate(type);
- }
- else if (isSelf() && gAgentCamera.cameraCustomizeAvatar())
+ if (isSelf())
{
- LLVisualParamHint::requestHintUpdates();
+ if (gAgentAvatarp->isUsingBakedTextures())
+ {
+ requestLayerSetUpdate(type);
+ }
+ else
+ {
+ LLVisualParamHint::requestHintUpdates();
+ }
}
}
else
{
- tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL, NULL);
+ tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL);
}
}
tex->setMinDiscardLevel(desired_discard);
@@ -2032,7 +2035,7 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe
imagep->setBoostLevel(getAvatarBoostLevel());
imagep->resetTextureStats();
- imagep->setMaxVirtualSizeResetInterval(16);
+ imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
imagep->addTextureStats( desired_pixels / texel_area_ratio );
imagep->setAdditionalDecodePriority(1.0f) ;
imagep->forceUpdateBindStats() ;
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index a82afbeb76..8a58a9c65b 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -53,6 +53,7 @@
#include "llworld.h"
#include "lldir.h"
#include "llxmltree.h"
+#include "llvotree.h"
const S32 GRASS_MAX_BLADES = 32;
const F32 GRASS_BLADE_BASE = 0.25f; // Width of grass at base
@@ -294,6 +295,23 @@ BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
return TRUE;
}
+ if(LLVOTree::isTreeRenderingStopped()) //stop rendering grass
+ {
+ if(mNumBlades)
+ {
+ mNumBlades = 0 ;
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ }
+ return TRUE ;
+ }
+ else if(!mNumBlades)//restart grass rendering
+ {
+ mNumBlades = GRASS_MAX_BLADES ;
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+
+ return TRUE ;
+ }
+
if (mPatch && (mLastPatchUpdateTime != mPatch->getLastUpdateTime()))
{
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
@@ -340,7 +358,20 @@ BOOL LLVOGrass::updateLOD()
{
return FALSE;
}
-
+ if(LLVOTree::isTreeRenderingStopped())
+ {
+ if(mNumBlades)
+ {
+ mNumBlades = 0 ;
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ }
+ return TRUE ;
+ }
+ if(!mNumBlades)
+ {
+ mNumBlades = GRASS_MAX_BLADES;
+ }
+
LLFace* face = mDrawable->getFace(0);
F32 tan_angle = 0.f;
@@ -387,8 +418,24 @@ static LLFastTimer::DeclareTimer FTM_UPDATE_GRASS("Update Grass");
BOOL LLVOGrass::updateGeometry(LLDrawable *drawable)
{
LLFastTimer ftm(FTM_UPDATE_GRASS);
+
dirtySpatialGroup();
- plantBlades();
+
+ if(!mNumBlades)//stop rendering grass
+ {
+ if (mDrawable->getNumFaces() > 0)
+ {
+ LLFace* facep = mDrawable->getFace(0);
+ if(facep)
+ {
+ facep->setSize(0, 0);
+ }
+ }
+ }
+ else
+ {
+ plantBlades();
+ }
return TRUE;
}
@@ -429,6 +476,11 @@ void LLVOGrass::getGeometry(S32 idx,
LLStrider<LLColor4U>& colorsp,
LLStrider<U16>& indicesp)
{
+ if(!mNumBlades)//stop rendering grass
+ {
+ return ;
+ }
+
mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion());
if (mPatch)
mLastPatchUpdateTime = mPatch->getLastUpdateTime();
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 5431aec07c..0efe6682be 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -73,7 +73,7 @@ S32 LLVOTree::sLODVertexCount[sMAX_NUM_TREE_LOD_LEVELS];
S32 LLVOTree::sLODIndexOffset[sMAX_NUM_TREE_LOD_LEVELS];
S32 LLVOTree::sLODIndexCount[sMAX_NUM_TREE_LOD_LEVELS];
S32 LLVOTree::sLODSlices[sMAX_NUM_TREE_LOD_LEVELS] = {10, 5, 4, 3};
-F32 LLVOTree::sLODAngles[sMAX_NUM_TREE_LOD_LEVELS] = {30.f, 20.f, 15.f, 0.00001f};
+F32 LLVOTree::sLODAngles[sMAX_NUM_TREE_LOD_LEVELS] = {30.f, 20.f, 15.f, F_ALMOST_ZERO};
F32 LLVOTree::sTreeFactor = 1.f;
@@ -101,6 +101,12 @@ LLVOTree::~LLVOTree()
}
}
+//static
+bool LLVOTree::isTreeRenderingStopped()
+{
+ return LLVOTree::sTreeFactor < LLVOTree::sLODAngles[sMAX_NUM_TREE_LOD_LEVELS - 1] ;
+}
+
// static
void LLVOTree::initClass()
{
diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h
index 036ad692b1..a6850e4790 100644
--- a/indra/newview/llvotree.h
+++ b/indra/newview/llvotree.h
@@ -59,6 +59,7 @@ public:
// Initialize data that's only inited once per class.
static void initClass();
static void cleanupClass();
+ static bool isTreeRenderingStopped();
/*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp
index ec9c78ee53..c5042ca016 100644
--- a/indra/newview/llwearable.cpp
+++ b/indra/newview/llwearable.cpp
@@ -444,8 +444,7 @@ BOOL LLWearable::importFile( LLFILE* file )
delete mSavedTEMap[te];
}
- image->setBoostLevel(LLViewerTexture::BOOST_AVATAR_SELF) ;
- image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(id, (LLVOAvatarDefines::ETextureIndex)te), NULL, NULL);
+ image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(id, (LLVOAvatarDefines::ETextureIndex)te), NULL);
LLUUID textureid(text_buffer);
mTEMap[te] = new LLLocalTextureObject(image, textureid);
@@ -699,7 +698,7 @@ void LLWearable::removeFromAvatar( LLWearableType::EType type, BOOL upload_bake
}
}
- if( gAgentCamera.cameraCustomizeAvatar() )
+ if(gAgentCamera.cameraCustomizeAvatar())
{
LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "edit_outfit"));
}
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index 3887f64618..c01d7fa62f 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -365,6 +365,29 @@ std::string LLPanelDummyClothingListItem::wearableTypeToString(LLWearableType::E
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
+LLWearableItemTypeNameComparator::LLWearableTypeOrder::LLWearableTypeOrder(LLWearableItemTypeNameComparator::ETypeListOrder order_priority, bool sort_asset_by_name, bool sort_wearable_by_name):
+ mOrderPriority(order_priority),
+ mSortAssetTypeByName(sort_asset_by_name),
+ mSortWearableTypeByName(sort_wearable_by_name)
+{
+}
+
+LLWearableItemTypeNameComparator::LLWearableItemTypeNameComparator()
+{
+ // By default the sort order conforms the order by spec of MY OUTFITS items list:
+ // 1. CLOTHING - sorted by name
+ // 2. OBJECT - sorted by type
+ // 3. BODYPART - sorted by name
+ mWearableOrder[LLAssetType::AT_CLOTHING] = LLWearableTypeOrder(ORDER_RANK_1, false, false);
+ mWearableOrder[LLAssetType::AT_OBJECT] = LLWearableTypeOrder(ORDER_RANK_2, true, true);
+ mWearableOrder[LLAssetType::AT_BODYPART] = LLWearableTypeOrder(ORDER_RANK_3, false, true);
+}
+
+void LLWearableItemTypeNameComparator::setOrder(LLAssetType::EType items_of_type, LLWearableItemTypeNameComparator::ETypeListOrder order_priority, bool sort_asset_items_by_name, bool sort_wearable_items_by_name)
+{
+ mWearableOrder[items_of_type] = LLWearableTypeOrder(order_priority, sort_asset_items_by_name, sort_wearable_items_by_name);
+}
+
/*virtual*/
bool LLWearableItemNameComparator::doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const
{
@@ -393,7 +416,7 @@ bool LLWearableItemTypeNameComparator::doCompare(const LLPanelInventoryListItemB
return item_type_order1 < item_type_order2;
}
- if (item_type_order1 & TLO_SORTABLE_BY_NAME)
+ if (sortAssetTypeByName(item_type1))
{
// If both items are of the same asset type except AT_CLOTHING and AT_BODYPART
// we can compare them by name.
@@ -405,38 +428,61 @@ bool LLWearableItemTypeNameComparator::doCompare(const LLPanelInventoryListItemB
if (item_wearable_type1 != item_wearable_type2)
{
- // If items are of different clothing types they are compared
- // by clothing types order determined in LLWearableType::EType.
+ // If items are of different LLWearableType::EType types they are compared
+ // by LLWearableType::EType. types order determined in LLWearableType::EType.
return item_wearable_type1 < item_wearable_type2;
}
else
{
// If both items are of the same clothing type they are compared
- // by description and place in reverse order i.e. outer layer item
- // on top.
+ // by description and place in reverse order (i.e. outer layer item
+ // on top) OR by name
+ if(sortWearableTypeByName(item_type1))
+ {
+ return LLWearableItemNameComparator::doCompare(wearable_item1, wearable_item2);
+ }
return wearable_item1->getDescription() > wearable_item2->getDescription();
}
}
-// static
-LLWearableItemTypeNameComparator::ETypeListOrder LLWearableItemTypeNameComparator::getTypeListOrder(LLAssetType::EType item_type)
+LLWearableItemTypeNameComparator::ETypeListOrder LLWearableItemTypeNameComparator::getTypeListOrder(LLAssetType::EType item_type) const
{
- switch (item_type)
+ wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
+
+ if(const_it == mWearableOrder.end())
{
- case LLAssetType::AT_OBJECT:
- return TLO_ATTACHMENT;
+ llwarns<<"Absent information about order rang of items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
+ return ORDER_RANK_UNKNOWN;
+ }
- case LLAssetType::AT_CLOTHING:
- return TLO_CLOTHING;
+ return const_it->second.mOrderPriority;
+}
- case LLAssetType::AT_BODYPART:
- return TLO_BODYPART;
+bool LLWearableItemTypeNameComparator::sortAssetTypeByName(LLAssetType::EType item_type) const
+{
+ wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
- default:
- return TLO_UNKNOWN;
+ if(const_it == mWearableOrder.end())
+ {
+ llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
+ return true;
}
+
+ return const_it->second.mSortAssetTypeByName;
}
+bool LLWearableItemTypeNameComparator::sortWearableTypeByName(LLAssetType::EType item_type) const
+{
+ wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
+
+ if(const_it == mWearableOrder.end())
+ {
+ llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
+ return true;
+ }
+
+ return const_it->second.mSortWearableTypeByName;
+}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
@@ -576,13 +622,11 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()
const uuid_vec_t& ids = mUUIDs; // selected items IDs
LLUUID selected_id = ids.front(); // ID of the first selected item
- functor_t wear = boost::bind(&LLAppearanceMgr::wearItemOnAvatar, LLAppearanceMgr::getInstance(), _1, true, true, LLPointer<LLInventoryCallback>(NULL));
- functor_t add = boost::bind(&LLAppearanceMgr::wearItemOnAvatar, LLAppearanceMgr::getInstance(), _1, true, false, LLPointer<LLInventoryCallback>(NULL));
functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
// Register handlers common for all wearable types.
- registrar.add("Wearable.Wear", boost::bind(handleMultiple, wear, ids));
- registrar.add("Wearable.Add", boost::bind(handleMultiple, add, ids));
+ registrar.add("Wearable.Wear", boost::bind(wear_multiple, ids, true));
+ registrar.add("Wearable.Add", boost::bind(wear_multiple, ids, false));
registrar.add("Wearable.Edit", boost::bind(handleMultiple, LLAgentWearables::editWearable, ids));
registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id));
registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id));
@@ -665,8 +709,8 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu
bool standalone = mParent ? mParent->isStandalone() : false;
// *TODO: eliminate multiple traversals over the menu items
- setMenuItemVisible(menu, "wear_wear", n_already_worn == 0);
- setMenuItemEnabled(menu, "wear_wear", n_already_worn == 0);
+ setMenuItemVisible(menu, "wear_wear", n_already_worn == 0 && n_worn == 0);
+ setMenuItemEnabled(menu, "wear_wear", n_already_worn == 0 && n_worn == 0);
setMenuItemVisible(menu, "wear_add", mask == MASK_CLOTHING && n_worn == 0 && n_already_worn != 0);
setMenuItemEnabled(menu, "wear_add", n_items == 1 && canAddWearable(ids.front()) && n_already_worn != 0);
setMenuItemVisible(menu, "wear_replace", n_worn == 0 && n_already_worn != 0);
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index d16a2a89c8..0e5403f30c 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -281,33 +281,76 @@ class LLWearableItemTypeNameComparator : public LLWearableItemNameComparator
LOG_CLASS(LLWearableItemTypeNameComparator);
public:
- LLWearableItemTypeNameComparator() {};
+
+ LLWearableItemTypeNameComparator();
virtual ~LLWearableItemTypeNameComparator() {};
+ enum ETypeListOrder
+ {
+ ORDER_RANK_1 = 1,
+ ORDER_RANK_2,
+ ORDER_RANK_3,
+ ORDER_RANK_UNKNOWN
+ };
+
+ void setOrder(LLAssetType::EType items_of_type, ETypeListOrder order_priority, bool sort_items_by_name, bool sort_wearable_items_by_name);
+
protected:
/**
- * Returns "true" if wearable_item1 is placed before wearable_item2 sorted by the following:
- * - Attachments (abc order)
- * - Clothing
- * - by type (types order determined in LLWearableType::EType)
- * - outer layer on top
- * - Body Parts (abc order),
- * "false" otherwise.
+ * All information about sort order is stored in mWearableOrder map
+ *
+ * mWearableOrder : KYES VALUES
+ * [LLAssetType] [struct LLWearableTypeOrder]
+ *
+ *---------------------------------------------------------------------------------------------
+ * I. Determines order (ORDER_RANK) in which items of LLAssetType should be displayed in list.
+ * For example by spec in MY OUTFITS the order is:
+ * 1. AT_CLOTHING (ORDER_RANK_1)
+ * 2. AT_OBJECT (ORDER_RANK_2)
+ * 3. AT_BODYPART (ORDER_RANK_3)
+ *
+ * II.Items of each type(LLAssetType) are sorted by name or type(LLWearableType)
+ * For example by spec in MY OUTFITS the order within each items type(LLAssetType) is:
+ * 1. AT_OBJECTS (abc order)
+ * 2. AT_CLOTHINGS
+ * - by type (types order determined in LLWearableType::EType)
+ * - outer layer on top
+ * 3. AT_BODYPARTS (abc order)
+ *---------------------------------------------------------------------------------------------
+ *
+ * For each LLAssetType (KEYS in mWearableOrder) the information about:
+ *
+ * I. ORDER_RANK (the flag is LLWearableTypeOrder::mOrderPriority)
+ *
+ * II. whether items of this LLAssetType type should be ordered
+ * by name or by LLWearableType::EType (the flag is LLWearableTypeOrder::mSortAssetTypeByName)
+ *
+ * III.whether items of LLWearableType type within this LLAssetType
+ * should be ordered by name (the flag is LLWearableTypeOrder::mSortWearableTypeByName)
+ *
+ * holds in mWearableOrder map as VALUES (struct LLWearableTypeOrder).
*/
/*virtual*/ bool doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const;
private:
- enum ETypeListOrder
+
+ struct LLWearableTypeOrder
{
- TLO_CLOTHING = 0x01,
- TLO_ATTACHMENT = 0x02,
- TLO_BODYPART = 0x04,
- TLO_UNKNOWN = 0x08,
+ ETypeListOrder mOrderPriority;
+ bool mSortAssetTypeByName;
+ bool mSortWearableTypeByName;
- TLO_SORTABLE_BY_NAME = TLO_ATTACHMENT | TLO_UNKNOWN
+ LLWearableTypeOrder(ETypeListOrder order_priority, bool sort_asset_by_name, bool sort_wearable_by_name);
+ LLWearableTypeOrder(){};
};
- static LLWearableItemTypeNameComparator::ETypeListOrder getTypeListOrder(LLAssetType::EType item_type);
+ ETypeListOrder getTypeListOrder(LLAssetType::EType item_type) const;
+
+ bool sortAssetTypeByName(LLAssetType::EType item_type) const;
+ bool sortWearableTypeByName(LLAssetType::EType item_type) const;
+
+ typedef std::map<LLAssetType::EType,LLWearableTypeOrder> wearable_type_order_map_t;
+ wearable_type_order_map_t mWearableOrder;
};
/**
diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp
index 66cb02ce99..9bbe005de8 100644
--- a/indra/newview/llworldmap.cpp
+++ b/indra/newview/llworldmap.cpp
@@ -37,6 +37,7 @@
#include "llworldmapmessage.h"
#include "message.h"
#include "lltracker.h"
+#include "lluistring.h"
#include "llviewertexturelist.h"
#include "lltrans.h"
@@ -522,8 +523,12 @@ bool LLWorldMap::insertItem(U32 x_world, U32 y_world, std::string& name, LLUUID&
case MAP_ITEM_LAND_FOR_SALE: // land for sale
case MAP_ITEM_LAND_FOR_SALE_ADULT: // adult land for sale
{
- std::string tooltip = llformat("%d sq. m. L$%d", extra, extra2);
- new_item.setTooltip(tooltip);
+ static LLUIString tooltip_fmt = LLTrans::getString("worldmap_item_tooltip_format");
+
+ tooltip_fmt.setArg("[AREA]", llformat("%d", extra));
+ tooltip_fmt.setArg("[PRICE]", llformat("%d", extra2));
+ new_item.setTooltip(tooltip_fmt.getString());
+
if (type == MAP_ITEM_LAND_FOR_SALE)
{
siminfo->insertLandForSale(new_item);
diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h
index e4e677eb64..b97e5249e1 100644
--- a/indra/newview/llworldmap.h
+++ b/indra/newview/llworldmap.h
@@ -52,7 +52,7 @@ public:
LLItemInfo(F32 global_x, F32 global_y, const std::string& name, LLUUID id);
// Setters
- void setTooltip(std::string& tooltip) { mToolTip = tooltip; }
+ void setTooltip(const std::string& tooltip) { mToolTip = tooltip; }
void setElevation(F64 z) { mPosGlobal.mdV[VZ] = z; }
void setCount(S32 count) { mCount = count; }
// void setSelected(bool selected) { mSelected = selected; }
diff --git a/indra/newview/skins/default/xui/da/menu_object.xml b/indra/newview/skins/default/xui/da/menu_object.xml
index c98a07e140..f4f7eb0af8 100644
--- a/indra/newview/skins/default/xui/da/menu_object.xml
+++ b/indra/newview/skins/default/xui/da/menu_object.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Object Pie">
- <menu_item_call label="Berør" name="Object Touch"/>
+ <menu_item_call label="Berør" name="Object Touch">
+ <on_enable parameter="Berør" name="EnableTouch"/>
+ </menu_item_call>
<menu_item_call label="Redigér" name="Edit..."/>
<menu_item_call label="Byg" name="Build"/>
<menu_item_call label="Åben" name="Open"/>
diff --git a/indra/newview/skins/default/xui/da/panel_nearby_media.xml b/indra/newview/skins/default/xui/da/panel_nearby_media.xml
index 7d25b2af99..a269e35f4b 100644
--- a/indra/newview/skins/default/xui/da/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/da/panel_nearby_media.xml
@@ -42,7 +42,7 @@
<scroll_list.columns label="Navn" name="media_name"/>
<scroll_list.columns label="Debug" name="media_debug"/>
</scroll_list>
- <panel>
+ <panel name="media_controls_panel">
<layout_stack name="media_controls">
<layout_panel name="stop">
<button name="stop_btn" tool_tip="Stop valgte medie"/>
diff --git a/indra/newview/skins/default/xui/da/sidepanel_item_info.xml b/indra/newview/skins/default/xui/da/sidepanel_item_info.xml
index 070b4218a8..b1ec2c44df 100644
--- a/indra/newview/skins/default/xui/da/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/da/sidepanel_item_info.xml
@@ -23,7 +23,8 @@
</panel.string>
<text name="title" value="Profil for genstand"/>
<text name="origin" value="(Beholdning)"/>
- <panel label="">
+ <panel label=""
+ name="item_profile">
<text name="LabelItemNameTitle">
Navn:
</text>
diff --git a/indra/newview/skins/default/xui/de/menu_object.xml b/indra/newview/skins/default/xui/de/menu_object.xml
index 8bb7b66482..756b606d65 100644
--- a/indra/newview/skins/default/xui/de/menu_object.xml
+++ b/indra/newview/skins/default/xui/de/menu_object.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Object Pie">
- <menu_item_call label="Berühren" name="Object Touch"/>
+ <menu_item_call label="Berühren" name="Object Touch">
+ <on_enable parameter="Berühren" name="EnableTouch"/>
+ </menu_item_call>
<menu_item_call label="Bearbeiten" name="Edit..."/>
<menu_item_call label="Bauen" name="Build"/>
<menu_item_call label="Öffnen" name="Open"/>
diff --git a/indra/newview/skins/default/xui/de/panel_nearby_media.xml b/indra/newview/skins/default/xui/de/panel_nearby_media.xml
index e7886fa149..ef66148902 100644
--- a/indra/newview/skins/default/xui/de/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/de/panel_nearby_media.xml
@@ -42,7 +42,7 @@
<scroll_list.columns label="Name" name="media_name"/>
<scroll_list.columns label="Fehler beseitigen" name="media_debug"/>
</scroll_list>
- <panel>
+ <panel name="media_controls_panel">
<layout_stack name="media_controls">
<layout_panel name="stop">
<button name="stop_btn" tool_tip="Ausgewählte Medien stoppen"/>
diff --git a/indra/newview/skins/default/xui/de/sidepanel_item_info.xml b/indra/newview/skins/default/xui/de/sidepanel_item_info.xml
index 63e7bce8ae..b9ca969ac5 100644
--- a/indra/newview/skins/default/xui/de/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/de/sidepanel_item_info.xml
@@ -23,7 +23,8 @@
</panel.string>
<text name="title" value="Objektprofil"/>
<text name="origin" value="(Inventar)"/>
- <panel label="">
+ <panel label=""
+ name="item_profile">
<text name="LabelItemNameTitle">
Name:
</text>
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index 68e36ff0b3..99bf3e6bc1 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -1472,8 +1472,10 @@ Only large parcels can be listed in search.
left="14"
name="MatureCheck"
top="177"
+ label_text.valign="center"
+ label_text.v_pad="-5"
tool_tip=" "
- width="107" />
+ width="200" />
<text
type="string"
length="1"
diff --git a/indra/newview/skins/default/xui/en/floater_buy_land.xml b/indra/newview/skins/default/xui/en/floater_buy_land.xml
index 0ad4fbc967..c88de878f4 100644
--- a/indra/newview/skins/default/xui/en/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_land.xml
@@ -529,13 +529,14 @@ sold with objects
length="1"
follows="top|left"
font="SansSerifBig"
- height="16"
+ height="32"
layout="topleft"
left="72"
name="account_action"
right="438"
top="200"
- width="218">
+ width="218"
+ wrap="true">
Upgrade you to premium membership.
</text>
<text
@@ -577,19 +578,21 @@ sold with objects
layout="topleft"
left="0"
name="step_2"
+ top_pad="-10"
width="64" />
<text
type="string"
length="1"
follows="top|left"
font="SansSerifBig"
- height="16"
+ height="32"
layout="topleft"
left="72"
name="land_use_action"
right="438"
top="284"
- width="218">
+ width="218"
+ wrap="true">
Increase your monthly land use fees to US$ 40/month.
</text>
<text
@@ -620,14 +623,15 @@ This parcel is 512 m² of land.
<text
type="string"
length="1"
- bottom_delta="-38"
+ bottom_delta="-22"
follows="top|left"
font="SansSerifBig"
- height="16"
+ height="32"
layout="topleft"
left="72"
name="purchase_action"
- right="438">
+ right="438"
+ wrap="true">
Pay Joe Resident L$ 4000 for the land
</text>
<text
@@ -665,7 +669,7 @@ This parcel is 512 m² of land.
layout="topleft"
left="170"
name="currency_amt"
- top="408"
+ top="424"
width="80">
1000
</line_editor>
@@ -681,7 +685,7 @@ This parcel is 512 m² of land.
layout="topleft"
left="260"
name="currency_est"
- top="409"
+ top="425"
width="178">
for approx. [LOCAL_AMOUNT]
</text>
@@ -713,7 +717,7 @@ This parcel is 512 m² of land.
layout="topleft"
left="70"
name="buy_btn"
- top="448"
+ top="460"
width="100" />
<button
follows="bottom|right"
diff --git a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
index 6281bc5272..7be9cfbb71 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
@@ -162,12 +162,16 @@
top_delta="15"
width="180">
<scroll_list.rows
+ name="action_animation"
value="Animation" />
<scroll_list.rows
+ name="action_sound"
value="Sound" />
<scroll_list.rows
+ name="action_chat"
value="Chat" />
<scroll_list.rows
+ name="action_wait"
value="Wait" />
</scroll_list>
<button
diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml
index a59db1420f..20629018e2 100644
--- a/indra/newview/skins/default/xui/en/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_world_map.xml
@@ -395,7 +395,7 @@
<panel
follows="right|top|bottom"
- height="310"
+ height="330"
top_pad="0"
width="238"
name="layout_panel_4">
@@ -534,7 +534,66 @@
<scroll_list.commit_callback
function="WMap.SearchResult" />
</scroll_list>
- <button
+ <text
+ type="string"
+ length="1"
+ follows="right|bottom"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="25"
+ name="events_label"
+ top_pad="16"
+ width="70">
+ Location:
+ </text>
+ <spinner
+ control_name="Teleport_Coordinate_X"
+ decimal_digits="0"
+ follows="right|bottom"
+ height="23"
+ increment="1"
+ initial_value="128"
+ layout="topleft"
+ left_delta="74"
+ max_val="255"
+ min_val="0"
+ name="teleport_coordinate_x"
+ width="44" >
+ <spinner.commit_callback
+ function="WMap.Coordinates" />
+ </spinner>
+ <spinner
+ control_name="Teleport_Coordinate_Y"
+ decimal_digits="0"
+ follows="right|bottom"
+ height="23"
+ increment="1"
+ initial_value="128"
+ layout="topleft"
+ left_delta="47"
+ max_val="255"
+ min_val="0"
+ name="teleport_coordinate_y" >
+ <spinner.commit_callback
+ function="WMap.Coordinates" />
+ </spinner>
+ <spinner
+ control_name="Teleport_Coordinate_Z"
+ decimal_digits="0"
+ follows="right|bottom"
+ height="23"
+ increment="1"
+ initial_value="128"
+ layout="topleft"
+ left_delta="47"
+ max_val="255"
+ min_val="0"
+ name="teleport_coordinate_z">
+ <spinner.commit_callback
+ function="WMap.Coordinates" />
+ </spinner>
+ <button
follows="right|bottom"
height="23"
image_unselected="PushButton_On"
@@ -574,66 +633,6 @@
<button.commit_callback
function="WMap.ShowTarget" />
</button>
-
-<!-- <text
- type="string"
- length="1"
- follows="bottom|right"
- halign="left"
- height="16"
- top_pad="4"
- left="25"
- layout="topleft"
- name="land_sale_label"
- width="250">
- Location:
- </text>
- <spinner
- decimal_digits="0"
- follows="bottom|right"
- increment="1"
- initial_value="128"
- layout="topleft"
- top_pad="0"
- left="25"
- max_val="255"
- name="spin x"
- tool_tip="X coordinate of location to show on map"
- width="48">
- <spinner.commit_callback
- function="WMap.CommitLocation" />
- </spinner>
- <spinner
- decimal_digits="0"
- follows="bottom|right"
- height="16"
- increment="1"
- initial_value="128"
- layout="topleft"
- left_pad="2"
- max_val="255"
- name="spin y"
- tool_tip="Y coordinate of location to show on map"
- top_delta="0"
- width="48" >
- <spinner.commit_callback
- function="WMap.CommitLocation" />
- </spinner>
- <spinner
- decimal_digits="0"
- follows="bottom|right"
- increment="1"
- initial_value="0"
- layout="topleft"
- left_pad="2"
- max_val="4096"
- name="spin z"
- tool_tip="Z coordinate of location to show on map"
- top_delta="0"
- width="48">
- <spinner.commit_callback
- function="WMap.CommitLocation" />
- </spinner>-->
</panel>
<panel
follows="right|bottom"
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
index 7239b13466..e2348375d5 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -11,8 +11,7 @@
function="Object.Touch" />
<menu_item_call.on_enable
function="Object.EnableTouch"
- name="EnableTouch"
- parameter="Touch" />
+ name="EnableTouch"/>
</menu_item_call>
<!--menu_item_call
label="Stand Up"
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml
index 22df02cd7e..8ec7689819 100644
--- a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml
@@ -22,7 +22,7 @@
<menu_item_call.on_click
function="InspectObject.Sit"/>
<menu_item_call.on_visible
- function="Object.EnableSit" />
+ function="Object.EnableSit"/>
</menu_item_call>
<menu_item_call
label="Pay"
diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml
index 397e61c97a..b6cc222e96 100644
--- a/indra/newview/skins/default/xui/en/menu_object.xml
+++ b/indra/newview/skins/default/xui/en/menu_object.xml
@@ -45,10 +45,7 @@
<menu_item_call.on_click
function="Object.SitOrStand" />
<menu_item_call.on_enable
- function="Object.SitVisible" />
- <menu_item_call.on_enable
- function="Object.EnableSitOrStand"
- name="EnableSitOrStand" />
+ function="Object.EnableSit" />
</menu_item_call>
<menu_item_call
enabled="false"
@@ -57,10 +54,7 @@
<menu_item_call.on_click
function="Object.SitOrStand" />
<menu_item_call.on_enable
- function="Object.StandUpVisible" />
- <menu_item_call.on_enable
- function="Object.EnableSitOrStand"
- name="EnableSitOrStand" />
+ function="Object.EnableStandUp" />
</menu_item_call>
<menu_item_call
label="Object Profile"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 04a8a02ecd..1bb282dff9 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6346,7 +6346,7 @@ Avatar '[NAME]' left as fully loaded.
name="AvatarRezSelfBakeNotification"
type="notifytip">
( [EXISTENCE] seconds alive )
-You uploaded a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] seconds.
+You [ACTION] a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] seconds.
</notification>
<notification
@@ -6405,11 +6405,14 @@ If you continue to have problems, please visit the [SUPPORT_SITE].
- Your system memory does not meet the minimum requirements.
</global>
-<!-- this is alert string from server. the name needs to match entire the server string, and needs to be changed
+<!-- these are alert strings from server. the name needs to match entire the server string, and needs to be changed
whenever the server string changes -->
<global name="You can only set your 'Home Location' on your land or at a mainland Infohub.">
If you own a piece of land, you can make it your home location.
Otherwise, you can look at the Map and find places marked &quot;Infohub&quot;.
</global>
+ <global name="You died and have been teleported to your home location">
+You died and have been teleported to your home location.
+ </global>
</notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_classified.xml b/indra/newview/skins/default/xui/en/panel_classified.xml
index c8293d3663..e96dbd527c 100644
--- a/indra/newview/skins/default/xui/en/panel_classified.xml
+++ b/indra/newview/skins/default/xui/en/panel_classified.xml
@@ -25,6 +25,7 @@
[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
</panel.string>
<texture_picker
+ fallback_image="default_land_picture.j2c"
follows="left|top"
height="300"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml
index b7fd9773f2..e66cf400b4 100644
--- a/indra/newview/skins/default/xui/en/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml
@@ -93,6 +93,7 @@
width="275"
>
<texture_picker
+ fallback_image="default_land_picture.j2c"
enabled="false"
follows="left|top|right"
height="197"
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
index af3315ebfe..e390b9e836 100644
--- a/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml
@@ -33,7 +33,7 @@
<texture_picker
allow_no_texture="true"
border_enabled="true"
- default_image_name="TabIcon_Places_Large"
+ fallback_image="default_land_picture.j2c"
enabled="false"
follows="left|top"
height="80"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
index 9408f193fd..a5c74b08e7 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
@@ -78,6 +78,7 @@
top="10"
width="272">
<texture_picker
+ fallback_image="default_land_picture.j2c"
follows="left|top|right"
height="197"
width="272"
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 dc83b334b5..f50e182313 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -63,6 +63,7 @@
left="0"
width="285">
<texture_picker
+ fallback_image="default_land_picture.j2c"
follows="left|top|right"
height="197"
width="272"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
index 484617df34..9fb777e0e7 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
@@ -242,6 +242,7 @@
max_length="63"
name="description"
prevalidate_callback="ascii"
+ select_on_focus="true"
text_color="black"
top_pad="3"
width="290" />
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 6523b0d491..41f2b28004 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -76,19 +76,22 @@ Maximum 200 per group daily
follows="top|left"
height="23"
image_overlay="AddItem_Off"
+ image_overlay_alignment="left"
+ imgoverlay_label_space="-10"
+ label="New Notice"
layout="topleft"
left="5"
name="create_new_notice"
tool_tip="Create a new notice"
- top_delta="-3"
- width="23" />
+ top_delta="0"
+ width="93" />
<button
follows="top|left"
height="23"
image_overlay="Refresh_Off"
layout="topleft"
name="refresh_notices"
- left_pad="230"
+ left="260"
tool_tip="Refresh list of notices"
top_delta="0"
width="23" />
@@ -113,7 +116,7 @@ Maximum 200 per group daily
mouse_opaque="false"
name="lbl"
text_color="EmphasisColor"
- top="0"
+ top="5"
width="200">
Create a Notice
</text>
@@ -270,7 +273,7 @@ Maximum 200 per group daily
mouse_opaque="false"
name="lbl"
text_color="EmphasisColor"
- top_pad="0"
+ top_pad="5"
width="265">
Archived Notice
</text>
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 0eb5c47f85..18a2f37ba2 100644
--- a/indra/newview/skins/default/xui/en/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -50,6 +50,10 @@ Select multiple Members by holding the Ctrl key and
clicking on their names.
</panel.string>
<panel.string
+ name="donation_area">
+ [AREA] m²
+ </panel.string>
+ <panel.string
name="power_folder_icon" translate="false">
Inv_FolderClosed
</panel.string>
diff --git a/indra/newview/skins/default/xui/en/panel_my_profile.xml b/indra/newview/skins/default/xui/en/panel_my_profile.xml
index 1083f4d467..2e49fc8d6f 100644
--- a/indra/newview/skins/default/xui/en/panel_my_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_my_profile.xml
@@ -141,6 +141,7 @@
allow_no_texture="true"
default_image_name="None"
enabled="false"
+ fallback_image="Generic_Person_Large"
follows="top|left"
height="124"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_media.xml b/indra/newview/skins/default/xui/en/panel_nearby_media.xml
index d8675b3512..a4cac97af6 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_media.xml
@@ -185,6 +185,7 @@
bevel_style="in"
background_visible="false"
follows="left|right|bottom"
+ name="media_controls_panel"
top_pad="5"
height="30"
left="10"
diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml
index 1d01bcb8a5..f6f1c33fe3 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml
@@ -55,6 +55,7 @@
left="0"
width="285">
<texture_picker
+ fallback_image="default_land_picture.j2c"
enabled="false"
follows="left|top|right"
height="197"
diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
index 41651edaa0..292bd47207 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
@@ -33,7 +33,7 @@
<texture_picker
allow_no_texture="true"
border_enabled="true"
- default_image_name="TabIcon_Places_Large"
+ fallback_image="default_land_picture.j2c"
enabled="false"
follows="left|top"
height="80"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
index 65c78ad333..aa760edad3 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
@@ -408,6 +408,14 @@
name="default_text">
Default
</panel.string>
+ <panel.string
+ name="default system device">
+ Default system device
+ </panel.string>
+ <panel.string
+ name="no device">
+ No device
+ </panel.string>
<icon
height="18"
image_name="Microphone_On"
diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
index daa4356c83..b48c5d1f8a 100644
--- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
@@ -5,8 +5,6 @@
background_visible="true"
bg_alpha_color="DkGray">
<accordion
- no_matched_tabs_text.value="Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search]."
- no_visible_tabs_text.value="Teleport history is empty. Try [secondlife:///app/search/places/ Search]."
follows="left|top|right|bottom"
height="373"
layout="topleft"
@@ -16,6 +14,12 @@
background_visible="true"
bg_alpha_color="DkGray2"
width="307">
+ <no_matched_tabs_text
+ name="no_matched_teleports_msg"
+ value="Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search]." />
+ <no_visible_tabs_text
+ name="no_teleports_msg"
+ value="Teleport history is empty. Try [secondlife:///app/search/places/ Search]." />
<accordion_tab
layout="topleft"
name="today"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
index 50df227fbf..49b252174c 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
@@ -80,10 +80,11 @@
<panel
follows="all"
height="493"
+ help_topic=""
label=""
layout="topleft"
left="9"
- help_topic=""
+ name="item_profile"
top="45"
width="313"
background_visible="true"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 0c31fda68b..20d49fac04 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -278,6 +278,7 @@
<!-- world map -->
<string name="texture_loading">Loading...</string>
<string name="worldmap_offline">Offline</string>
+ <string name="worldmap_item_tooltip_format">[AREA] m² L$[PRICE]</string>
<string name="worldmap_results_none_found">None found.</string>
<!-- animations uploading status codes -->
@@ -1913,6 +1914,7 @@ Clears (deletes) the media and all params from the given face.
<string name="AnimFlagStop" value=" Stop Animation : " />
<string name="AnimFlagStart" value=" Start Animation : " />
<string name="Wave" value=" Wave " />
+ <string name="GestureActionNone" value="None" />
<string name="HelloAvatar" value=" Hello, avatar! " />
<string name="ViewAllGestures" value=" View All &gt;&gt;" />
<string name="GetMoreGestures" value=" Get More &gt;&gt;" />
@@ -1957,6 +1959,7 @@ Clears (deletes) the media and all params from the given face.
<string name="InvFolder Gestures">Gestures</string>
<string name="InvFolder Favorite">Favorites</string>
<string name="InvFolder Current Outfit">Current Outfit</string>
+ <string name="InvFolder Initial Outfits">Initial Outfits</string>
<string name="InvFolder My Outfits">My Outfits</string>
<string name="InvFolder Accessories">Accessories</string>
@@ -2097,6 +2100,7 @@ Clears (deletes) the media and all params from the given face.
<string name="SummaryForTheWeek" value="Summary for this week, beginning on " />
<string name="NextStipendDay" value="The next stipend day is " />
<string name="GroupIndividualShare" value=" Group Individual Share" />
+ <string name="GroupColumn" value=" Group" />
<string name="Balance">Balance</string>
<string name="Credits">Credits</string>
<string name="Debits">Debits</string>
@@ -3140,6 +3144,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="group_role_everyone">Everyone</string>
<string name="group_role_officers">Officers</string>
<string name="group_role_owners">Owners</string>
+ <string name="group_member_status_online">Online</string>
<string name="uploading_abuse_report">Uploading...
@@ -3162,7 +3167,9 @@ Abuse Report</string>
<string name="New Alpha">New Alpha</string>
<string name="New Tattoo">New Tattoo</string>
<string name="Invalid Wearable">Invalid Wearable</string>
+ <string name="New Gesture">New Gesture</string>
<string name="New Script">New Script</string>
+ <string name="New Note">New Note</string>
<string name="New Folder">New Folder</string>
<string name="Contents">Contents</string>
<string name="Gesture">Gesture</string>
@@ -3184,13 +3191,20 @@ Abuse Report</string>
<string name="Male - Stick tougue out">Male - Stick tougue out</string>
<string name="Male - Wow">Male - Wow</string>
+ <string name="Female - Chuckle">Female - Chuckle</string>
+ <string name="Female - Cry">Female - Cry</string>
+ <string name="Female - Embarrassed">Female - Embarrassed</string>
<string name="Female - Excuse me">Female - Excuse me</string>
<string name="Female - Get lost">Female - Get lost</string>
<string name="Female - Blow kiss">Female - Blow kiss</string>
<string name="Female - Boo">Female - Boo</string>
<string name="Female - Bored">Female - Bored</string>
<string name="Female - Hey">Female - Hey</string>
+ <string name="Female - Hey baby">Female - Hey baby</string>
<string name="Female - Laugh">Female - Laugh</string>
+ <string name="Female - Looking good">Female - Looking good</string>
+ <string name="Female - Over here">Female - Over here</string>
+ <string name="Female - Please">Female - Please</string>
<string name="Female - Repulsed">Female - Repulsed</string>
<string name="Female - Shrug">Female - Shrug</string>
<string name="Female - Stick tougue out">Female - Stick tougue out</string>
@@ -3223,4 +3237,23 @@ Abuse Report</string>
<string name="dateTimeDayFormat">[MDAY]</string>
<string name="dateTimeAM">AM</string>
<string name="dateTimePM">PM</string>
+
+ <!-- currency formatting -->
+ <string name="LocalEstimateUSD">US$ [AMOUNT]</string>
+
+ <!-- Group Profile roles and powers -->
+ <string name="Membership">Membership</string>
+ <string name="Roles">Roles</string>
+ <string name="Group Identity">Group Identity</string>
+ <string name="Parcel Management">Parcel Management</string>
+ <string name="Parcel Identity">Parcel Identity</string>
+ <string name="Parcel Settings">Parcel Settings</string>
+ <string name="Parcel Powers">Parcel Powers</string>
+ <string name="Parcel Access">Parcel Access</string>
+ <string name="Parcel Content">Parcel Content</string>
+ <string name="Object Management">Object Management</string>
+ <string name="Accounting">Accounting</string>
+ <string name="Notices">Notices</string>
+ <string name="Chat">Chat</string>
+
</strings>
diff --git a/indra/newview/skins/default/xui/en/widgets/accordion.xml b/indra/newview/skins/default/xui/en/widgets/accordion.xml
index 19f8234389..1a66f0f5c5 100644
--- a/indra/newview/skins/default/xui/en/widgets/accordion.xml
+++ b/indra/newview/skins/default/xui/en/widgets/accordion.xml
@@ -3,6 +3,12 @@
height="100"
name="accordion"
width="200">
+ <!-- It is possible to override attributes of "no_matched_tabs_text" and "no_visible_tabs_text" with a short form:
+ no_matched_tabs_text.value="Overridden text" (placed among <accordion> attributes)
+ But unfortunatly such form is not supported by VLT Tool. It requires to have the overridden "value"
+ attribute declared in tags below ("no_matched_tabs_text" & "no_visible_tabs_text").
+ It looks less clean but we have to use "long" form for these messages to enable automated translation with VLT.
+ -->
<no_matched_tabs_text
follows="all"
height="100"
diff --git a/indra/newview/skins/default/xui/es/menu_object.xml b/indra/newview/skins/default/xui/es/menu_object.xml
index d2743cd4fc..060d806c55 100644
--- a/indra/newview/skins/default/xui/es/menu_object.xml
+++ b/indra/newview/skins/default/xui/es/menu_object.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Object Pie">
- <menu_item_call label="Tocar" name="Object Touch"/>
+ <menu_item_call label="Tocar" name="Object Touch">
+ <on_enable parameter="Tocar" name="EnableTouch"/>
+ </menu_item_call>
<menu_item_call label="Editar" name="Edit..."/>
<menu_item_call label="Construir" name="Build"/>
<menu_item_call label="Abrir" name="Open"/>
diff --git a/indra/newview/skins/default/xui/es/panel_nearby_media.xml b/indra/newview/skins/default/xui/es/panel_nearby_media.xml
index b78ecd0cd0..f03338e4c7 100644
--- a/indra/newview/skins/default/xui/es/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/es/panel_nearby_media.xml
@@ -42,7 +42,7 @@
<scroll_list.columns label="Nombre" name="media_name"/>
<scroll_list.columns label="Depurar" name="media_debug"/>
</scroll_list>
- <panel>
+ <panel name="media_controls_panel">
<layout_stack name="media_controls">
<layout_panel name="stop">
<button name="stop_btn" tool_tip="Parar los media seleccionados"/>
diff --git a/indra/newview/skins/default/xui/es/sidepanel_item_info.xml b/indra/newview/skins/default/xui/es/sidepanel_item_info.xml
index 38f43c3cbc..d3b91e7a71 100644
--- a/indra/newview/skins/default/xui/es/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/es/sidepanel_item_info.xml
@@ -23,7 +23,8 @@
</panel.string>
<text name="title" value="Perfil del elemento"/>
<text name="origin" value="(Inventario)"/>
- <panel label="">
+ <panel label=""
+ name="item_profile">
<text name="LabelItemNameTitle">
Nombre:
</text>
diff --git a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
index 4eaff8535e..b3acc83078 100644
--- a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
@@ -22,10 +22,10 @@ le Lindex...
<text name="currency_action">
Je veux acheter
</text>
- <text name="currency_label">
+ <text name="currency_label" left="308">
L$
</text>
- <line_editor label="L$" name="currency_amt" width="65">
+ <line_editor label="L$" name="currency_amt" width="65" left_pad="-85">
1234
</line_editor>
<text name="buying_label">
diff --git a/indra/newview/skins/default/xui/fr/floater_water.xml b/indra/newview/skins/default/xui/fr/floater_water.xml
index 96723b0fe6..7d1e3cd65c 100644
--- a/indra/newview/skins/default/xui/fr/floater_water.xml
+++ b/indra/newview/skins/default/xui/fr/floater_water.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="Water Floater" title="ÉDITEUR D&apos;EAU AVANCÉ">
<floater.string name="WLDefaultWaterNames">
- Default:Glassy:Pond:Murky:Second Plague:SNAKE!!!:Valdez
+ Valeur par défaut:Transparente:Bassin:Trouble:Première plaie:SERPENT !!!:Valdez
</floater.string>
<text name="KeyFramePresetsText" width="120">
Préréglages :
diff --git a/indra/newview/skins/default/xui/fr/floater_windlight_options.xml b/indra/newview/skins/default/xui/fr/floater_windlight_options.xml
index 74f1697449..657e5f5051 100644
--- a/indra/newview/skins/default/xui/fr/floater_windlight_options.xml
+++ b/indra/newview/skins/default/xui/fr/floater_windlight_options.xml
@@ -184,6 +184,6 @@
</panel>
</tab_container>
<string name="WLDefaultSkyNames">
- A-12AM:A-12PM:A-3AM:A-3PM:A-4.30PM:A-6AM:A-6PM:A-9AM:A-9PM:Barcelona:Blizzard:Blue Midday:Coastal Afternoon:Coastal Sunset:Default:Desert Sunset:Fine Day:Fluffy Big Clouds:Foggy:Funky Funky:Funky Funky Funky:Gelatto:Ghost:Incongruent Truths:Midday 1:Midday 2:Midday 3:Midday 4:Night:Pirate:Purple:Sailor&apos;s Delight:Sheer Sensuality
+ A-Minuit:A-Midi:A-3h:A-15h:A-16h30:A-6h:A-18h:A-9h:A-21h:Barcelone:Blizzard:Bleu mi-journée:Après-midi sur la côte:Coucher de soleil (côte):Valeur par défaut:Coucher de soleil (désert):Belle journée:Gros nuages floconneux:Brumeux:Funky Funky:Funky Funky Funky:Gelatto:Fantôme:Vérités incohérentes:Mi-journée 1:Mi-journée 2:Mi-journée 3:Mi-journée 4:Nuit:Pirate:Mauve:Rêve de navigateur:Sensualité pure
</string>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/menu_object.xml b/indra/newview/skins/default/xui/fr/menu_object.xml
index 576fc66d46..257c44795f 100644
--- a/indra/newview/skins/default/xui/fr/menu_object.xml
+++ b/indra/newview/skins/default/xui/fr/menu_object.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Object Pie">
- <menu_item_call label="Toucher" name="Object Touch"/>
+ <menu_item_call label="Toucher" name="Object Touch">
+ <on_enable parameter="Toucher" name="EnableTouch"/>
+ </menu_item_call>
<menu_item_call label="Modifier" name="Edit..."/>
<menu_item_call label="Construire" name="Build"/>
<menu_item_call label="Ouvrir" name="Open"/>
diff --git a/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml b/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml
index 0a5680fe06..0350ea5116 100644
--- a/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml
@@ -23,7 +23,8 @@
</panel.string>
<text name="title" value="Profil de l&apos;article"/>
<text name="origin" value="(inventaire)"/>
- <panel label="">
+ <panel label=""
+ name="item_profile">
<text name="LabelItemNameTitle">
Nom :
</text>
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index 0a269016f5..7aadaed209 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -1472,7 +1472,7 @@
Solde
</string>
<string name="Credits">
- Remerciements
+ Crédits
</string>
<string name="Debits">
Débits
@@ -1787,7 +1787,7 @@
Solde
</string>
<string name="GroupMoneyCredits">
- Remerciements
+ Crédits
</string>
<string name="GroupMoneyDebits">
Débits
@@ -3859,4 +3859,5 @@ de l&apos;infraction signalée
<string name="dateTimePM">
PM
</string>
+ <string name="LocalEstimateUSD">[AMOUNT] US$</string>
</strings>
diff --git a/indra/newview/skins/default/xui/it/menu_object.xml b/indra/newview/skins/default/xui/it/menu_object.xml
index 237b6b3a0e..81f27ab8fa 100644
--- a/indra/newview/skins/default/xui/it/menu_object.xml
+++ b/indra/newview/skins/default/xui/it/menu_object.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Object Pie">
- <menu_item_call label="Tocca" name="Object Touch"/>
+ <menu_item_call label="Tocca" name="Object Touch">
+ <on_enable parameter="Tocca" name="EnableTouch"/>
+ </menu_item_call>
<menu_item_call label="Modifica" name="Edit..."/>
<menu_item_call label="Costruisci" name="Build"/>
<menu_item_call label="Apri" name="Open"/>
diff --git a/indra/newview/skins/default/xui/it/panel_nearby_media.xml b/indra/newview/skins/default/xui/it/panel_nearby_media.xml
index bec36fd427..40312f76b4 100644
--- a/indra/newview/skins/default/xui/it/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/it/panel_nearby_media.xml
@@ -42,7 +42,7 @@
<scroll_list.columns label="Nome" name="media_name"/>
<scroll_list.columns label="Debug" name="media_debug"/>
</scroll_list>
- <panel>
+ <panel name="media_controls_panel">
<layout_stack name="media_controls">
<layout_panel name="stop">
<button name="stop_btn" tool_tip="Interrompi supporto selezionato"/>
diff --git a/indra/newview/skins/default/xui/it/sidepanel_item_info.xml b/indra/newview/skins/default/xui/it/sidepanel_item_info.xml
index d0ec943e67..627aeb5cb5 100644
--- a/indra/newview/skins/default/xui/it/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/it/sidepanel_item_info.xml
@@ -23,7 +23,8 @@
</panel.string>
<text name="title" value="Profilo articolo"/>
<text name="origin" value="(Inventario)"/>
- <panel label="">
+ <panel label=""
+ name="item_profile">
<text name="LabelItemNameTitle">
Nome:
</text>
diff --git a/indra/newview/skins/default/xui/ja/menu_object.xml b/indra/newview/skins/default/xui/ja/menu_object.xml
index e59a500534..be25a2932e 100644
--- a/indra/newview/skins/default/xui/ja/menu_object.xml
+++ b/indra/newview/skins/default/xui/ja/menu_object.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Object Pie">
- <menu_item_call label="触る" name="Object Touch"/>
+ <menu_item_call label="触る" name="Object Touch">
+ <on_enable parameter="触る" name="EnableTouch"/>
+ </menu_item_call>
<menu_item_call label="編集" name="Edit..."/>
<menu_item_call label="制作" name="Build"/>
<menu_item_call label="開く" name="Open"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_nearby_media.xml b/indra/newview/skins/default/xui/ja/panel_nearby_media.xml
index b3df3503bb..07293e6c79 100644
--- a/indra/newview/skins/default/xui/ja/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/ja/panel_nearby_media.xml
@@ -42,7 +42,7 @@
<scroll_list.columns label="名前" name="media_name"/>
<scroll_list.columns label="デバッグ" name="media_debug"/>
</scroll_list>
- <panel>
+ <panel name="media_controls_panel">
<layout_stack name="media_controls">
<layout_panel name="stop">
<button name="stop_btn" tool_tip="選択したメディアを停止"/>
diff --git a/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml b/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml
index fdabe88362..414eba0509 100644
--- a/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml
@@ -23,7 +23,8 @@
</panel.string>
<text name="title" value="アイテムのプロフィール"/>
<text name="origin" value="(持ち物)"/>
- <panel label="">
+ <panel label=""
+ name="item_profile">
<text name="LabelItemNameTitle">
名前:
</text>
diff --git a/indra/newview/skins/default/xui/pl/menu_object.xml b/indra/newview/skins/default/xui/pl/menu_object.xml
index 763b120f89..f25495e8e6 100644
--- a/indra/newview/skins/default/xui/pl/menu_object.xml
+++ b/indra/newview/skins/default/xui/pl/menu_object.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Object Pie">
- <menu_item_call label="Dotknij" name="Object Touch"/>
+ <menu_item_call label="Dotknij" name="Object Touch">
+ <on_enable parameter="Dotknij" name="EnableTouch"/>
+ </menu_item_call>
<menu_item_call label="Edytuj" name="Edit..."/>
<menu_item_call label="Buduj" name="Build"/>
<menu_item_call label="Otwórz" name="Open"/>
diff --git a/indra/newview/skins/default/xui/pl/panel_nearby_media.xml b/indra/newview/skins/default/xui/pl/panel_nearby_media.xml
index 86c7275e79..926ca806ac 100644
--- a/indra/newview/skins/default/xui/pl/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/pl/panel_nearby_media.xml
@@ -42,7 +42,7 @@
<scroll_list.columns label="Nazwa" name="media_name"/>
<scroll_list.columns label="Debugowanie" name="media_debug"/>
</scroll_list>
- <panel>
+ <panel name="media_controls_panel">
<layout_stack name="media_controls">
<layout_panel name="stop">
<button name="stop_btn" tool_tip="Wyłącz wybrane media"/>
diff --git a/indra/newview/skins/default/xui/pl/sidepanel_item_info.xml b/indra/newview/skins/default/xui/pl/sidepanel_item_info.xml
index 2f43e0c215..0c6169c9c0 100644
--- a/indra/newview/skins/default/xui/pl/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/pl/sidepanel_item_info.xml
@@ -23,7 +23,8 @@
</panel.string>
<text name="title" value="Profil obiektu"/>
<text name="origin" value="(Szafa)"/>
- <panel label="">
+ <panel label=""
+ name="item_profile">
<text name="LabelItemNameTitle">
Nazwa:
</text>
diff --git a/indra/newview/skins/default/xui/pt/menu_object.xml b/indra/newview/skins/default/xui/pt/menu_object.xml
index a5969cacc3..cd1a72b896 100644
--- a/indra/newview/skins/default/xui/pt/menu_object.xml
+++ b/indra/newview/skins/default/xui/pt/menu_object.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Object Pie">
- <menu_item_call label="Tocar" name="Object Touch"/>
+ <menu_item_call label="Tocar" name="Object Touch">
+ <on_enable parameter="Tocar" name="EnableTouch"/>
+ </menu_item_call>
<menu_item_call label="Editar" name="Edit..."/>
<menu_item_call label="Construir" name="Build"/>
<menu_item_call label="Abrir" name="Open"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_nearby_media.xml b/indra/newview/skins/default/xui/pt/panel_nearby_media.xml
index 672b8e6735..7d1b48ad76 100644
--- a/indra/newview/skins/default/xui/pt/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/pt/panel_nearby_media.xml
@@ -42,7 +42,7 @@
<scroll_list.columns label="Nome" name="media_name"/>
<scroll_list.columns label="Depurar" name="media_debug"/>
</scroll_list>
- <panel>
+ <panel name="media_controls_panel">
<layout_stack name="media_controls">
<layout_panel name="stop">
<button name="stop_btn" tool_tip="Parar mídia selecionada"/>
diff --git a/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml b/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml
index 8e880588e9..d2050f4660 100644
--- a/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml
@@ -23,7 +23,8 @@
</panel.string>
<text name="title" value="Perfil do item"/>
<text name="origin" value="(Inventário)"/>
- <panel label="">
+ <panel label=""
+ name="item_profile">
<text name="LabelItemNameTitle">
Nome:
</text>
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index 1c29feec5f..347a5e8ab8 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -226,6 +226,16 @@ S32 LLNotification::getSelectedOption(const LLSD& notification, const LLSD& resp
return response.asInteger();
}
+//-----------------------------------------------------------------------------
+#include "../llmachineid.h"
+unsigned char gMACAddress[MAC_ADDRESS_BYTES] = {77,21,46,31,89,2};
+
+S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
+{
+ memcpy(unique_id, gMACAddress, len);
+ return 1;
+}
+//-----------------------------------------------------------------------------
// misc
std::string xml_escape_string(const std::string& in)
{