summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llappearancemgr.cpp43
-rw-r--r--indra/newview/llappearancemgr.h3
-rw-r--r--indra/newview/llfloaterinventory.cpp11
-rw-r--r--indra/newview/llfolderviewitem.cpp4
-rwxr-xr-xindra/newview/llmediadataclient.cpp116
-rwxr-xr-xindra/newview/llmediadataclient.h2
-rw-r--r--indra/newview/llsidepanelappearance.cpp76
-rw-r--r--indra/newview/llsidepanelappearance.h7
-rw-r--r--indra/newview/llvovolume.cpp25
-rw-r--r--indra/newview/llvovolume.h1
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml1
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml2
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_appearance.xml35
-rw-r--r--indra/newview/tests/llmediadataclient_test.cpp66
14 files changed, 284 insertions, 108 deletions
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index d6265a85f6..1050deaa27 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -363,6 +363,35 @@ LLUUID LLAppearanceManager::getCOF()
return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
}
+
+const LLViewerInventoryItem* LLAppearanceManager::getCurrentOutfitLink()
+{
+ const LLUUID& current_outfit_cat = getCOF();
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+ // Can't search on FT_OUTFIT since links to categories return FT_CATEGORY for type since they don't
+ // return preferred type.
+ LLIsType is_category( LLAssetType::AT_CATEGORY );
+ gInventory.collectDescendentsIf(current_outfit_cat,
+ cat_array,
+ item_array,
+ false,
+ is_category,
+ false);
+ for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
+ iter != item_array.end();
+ iter++)
+ {
+ const LLViewerInventoryItem *item = (*iter);
+ const LLViewerInventoryCategory *cat = item->getLinkedCategory();
+ if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT)
+ {
+ return item;
+ }
+ }
+ return NULL;
+}
+
// Update appearance from outfit folder.
void LLAppearanceManager::changeOutfit(bool proceed, const LLUUID& category, bool append)
{
@@ -531,20 +560,28 @@ void LLAppearanceManager::updateCOF(const LLUUID& category, bool append)
linkAll(cof, gest_items, link_waiter);
// Add link to outfit if category is an outfit.
- LLViewerInventoryCategory* catp = gInventory.getCategory(category);
+ const LLViewerInventoryCategory* catp = gInventory.getCategory(category);
+ LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance *>(LLSideTray::getInstance()->getPanel("sidepanel_appearance"));
+
if (!append && catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
{
link_inventory_item(gAgent.getID(), category, cof, catp->getName(),
LLAssetType::AT_LINK_FOLDER, link_waiter);
// Update the current outfit name of the appearance sidepanel.
- LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance *>(LLSideTray::getInstance()->getPanel("sidepanel_appearance"));
if (panel_appearance)
{
panel_appearance->refreshCurrentOutfitName(catp->getName());
}
}
-
+ else
+ {
+ // Update the current outfit name of the appearance sidepanel.
+ if (panel_appearance)
+ {
+ panel_appearance->refreshCurrentOutfitName();
+ }
+ }
}
void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder, bool append)
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 5daa6d067b..7038d1a35b 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -61,6 +61,9 @@ public:
// Find the Current Outfit folder.
LLUUID getCOF();
+ // Finds the folder link to the currently worn outfit
+ const LLViewerInventoryItem *getCurrentOutfitLink();
+
void updateAgentWearables(LLWearableHoldingPattern* holder, bool append);
// For debugging - could be moved elsewhere.
diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp
index 92778510e7..db38fc0fb3 100644
--- a/indra/newview/llfloaterinventory.cpp
+++ b/indra/newview/llfloaterinventory.cpp
@@ -64,10 +64,7 @@ BOOL LLFloaterInventory::postBuild()
void LLFloaterInventory::draw()
{
- if (LLInventoryModel::isEverythingFetched())
- {
- updateTitle();
- }
+ updateTitle();
LLFloater::draw();
}
@@ -85,10 +82,14 @@ void LLFloaterInventory::updateTitle()
{
setTitle(getString("TitleFetching", string_args));
}
- else
+ else if (LLInventoryModel::isEverythingFetched())
{
setTitle(getString("TitleCompleted", string_args));
}
+ else
+ {
+ setTitle(getString("Title"));
+ }
}
void LLFloaterInventory::changed(U32 mask)
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 7323c421da..a1260d1156 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -2498,11 +2498,13 @@ bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolde
{
static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ static const LLUUID& landmarks_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
LLUUID a_uuid = a->getParentFolder()->getListener()->getUUID();
LLUUID b_uuid = b->getParentFolder()->getListener()->getUUID();
- if (a_uuid == favorites_folder_id && b_uuid == favorites_folder_id)
+ if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id) ||
+ (a_uuid == landmarks_folder_id && b_uuid == landmarks_folder_id))
{
// *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem
// or to LLInvFVBridge
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index 986c14acff..6666a03ee4 100755
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -371,67 +371,87 @@ BOOL LLMediaDataClient::QueueTimer::tick()
}
LLMediaDataClient::PriorityQueue &queue = *(mMDC->pRequestQueue);
-
- if (queue.empty())
+
+ if(!queue.empty())
{
- LL_DEBUGS("LLMediaDataClient") << "queue empty: " << queue << LL_ENDL;
- return TRUE;
+ LL_INFOS("LLMediaDataClient") << "QueueTimer::tick() started, queue is: " << queue << LL_ENDL;
}
- LL_INFOS("LLMediaDataClient") << "QueueTimer::tick() started, queue is: " << queue << LL_ENDL;
-
- // Peel one off of the items from the queue, and execute request
- request_ptr_t request = queue.top();
- llassert(!request.isNull());
- const LLMediaDataClientObject *object = (request.isNull()) ? NULL : request->getObject();
- bool performed_request = false;
- bool error = false;
- llassert(NULL != object);
- if (NULL != object && object->hasMedia())
+ // quick retry loop for cases where we shouldn't wait for the next timer tick
+ while(true)
{
- std::string url = request->getCapability();
- if (!url.empty())
+ if (queue.empty())
{
- const LLSD &sd_payload = request->getPayload();
- LL_INFOS("LLMediaDataClient") << "Sending request for " << *request << LL_ENDL;
-
- // Call the subclass for creating the responder
- LLHTTPClient::post(url, sd_payload, mMDC->createResponder(request));
- performed_request = true;
+ LL_DEBUGS("LLMediaDataClient") << "queue empty: " << queue << LL_ENDL;
+ return TRUE;
}
- else {
- LL_INFOS("LLMediaDataClient") << "NOT Sending request for " << *request << ": empty cap url!" << LL_ENDL;
- }
- }
- else {
- if (request.isNull())
+
+ // Peel one off of the items from the queue, and execute request
+ request_ptr_t request = queue.top();
+ llassert(!request.isNull());
+ const LLMediaDataClientObject *object = (request.isNull()) ? NULL : request->getObject();
+ bool performed_request = false;
+ bool error = false;
+ llassert(NULL != object);
+
+ if(object->isDead())
{
- LL_WARNS("LLMediaDataClient") << "Not Sending request: NULL request!" << LL_ENDL;
+ // This object has been marked dead. Pop it and move on to the next item in the queue immediately.
+ LL_INFOS("LLMediaDataClient") << "Skipping " << *request << ": object is dead!" << LL_ENDL;
+ queue.pop();
+ continue; // jump back to the start of the quick retry loop
}
- else if (NULL == object)
+
+ if (NULL != object && object->hasMedia())
{
- LL_WARNS("LLMediaDataClient") << "Not Sending request for " << *request << " NULL object!" << LL_ENDL;
+ std::string url = request->getCapability();
+ if (!url.empty())
+ {
+ const LLSD &sd_payload = request->getPayload();
+ LL_INFOS("LLMediaDataClient") << "Sending request for " << *request << LL_ENDL;
+
+ // Call the subclass for creating the responder
+ LLHTTPClient::post(url, sd_payload, mMDC->createResponder(request));
+ performed_request = true;
+ }
+ else {
+ LL_INFOS("LLMediaDataClient") << "NOT Sending request for " << *request << ": empty cap url!" << LL_ENDL;
+ }
}
- else if (!object->hasMedia())
- {
- LL_WARNS("LLMediaDataClient") << "Not Sending request for " << *request << " hasMedia() is false!" << LL_ENDL;
+ else {
+ if (request.isNull())
+ {
+ LL_WARNS("LLMediaDataClient") << "Not Sending request: NULL request!" << LL_ENDL;
+ }
+ else if (NULL == object)
+ {
+ LL_WARNS("LLMediaDataClient") << "Not Sending request for " << *request << " NULL object!" << LL_ENDL;
+ }
+ else if (!object->hasMedia())
+ {
+ LL_WARNS("LLMediaDataClient") << "Not Sending request for " << *request << " hasMedia() is false!" << LL_ENDL;
+ }
+ error = true;
}
- error = true;
- }
- bool exceeded_retries = request->getRetryCount() > mMDC->mMaxNumRetries;
- if (performed_request || exceeded_retries || error) // Try N times before giving up
- {
- if (exceeded_retries)
+ bool exceeded_retries = request->getRetryCount() > mMDC->mMaxNumRetries;
+ if (performed_request || exceeded_retries || error) // Try N times before giving up
{
- LL_WARNS("LLMediaDataClient") << "Could not send request " << *request << " for "
- << mMDC->mMaxNumRetries << " tries...popping object id " << object->getID() << LL_ENDL;
- // XXX Should we bring up a warning dialog??
+ if (exceeded_retries)
+ {
+ LL_WARNS("LLMediaDataClient") << "Could not send request " << *request << " for "
+ << mMDC->mMaxNumRetries << " tries...popping object id " << object->getID() << LL_ENDL;
+ // XXX Should we bring up a warning dialog??
+ }
+ queue.pop();
}
- queue.pop();
- }
- else {
- request->incRetryCount();
- }
+ else {
+ request->incRetryCount();
+ }
+
+ // end of quick retry loop -- any cases where we want to loop will use 'continue' to jump back to the start.
+ break;
+ }
+
LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() finished, queue is now: " << (*(mMDC->pRequestQueue)) << LL_ENDL;
return queue.empty();
diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h
index 0d1450ffbe..d5dd050111 100755
--- a/indra/newview/llmediadataclient.h
+++ b/indra/newview/llmediadataclient.h
@@ -62,6 +62,8 @@ public:
virtual F64 getTotalMediaInterest() const = 0;
// Return the given cap url
virtual std::string getCapabilityUrl(const std::string &name) const = 0;
+ // Return whether the object has been marked dead
+ virtual bool isDead() const = 0;
// smart pointer
typedef LLPointer<LLMediaDataClientObject> ptr_t;
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index aeab3e2876..0f8e86cb3c 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -34,9 +34,12 @@
#include "llagent.h"
#include "llagentwearables.h"
+#include "llappearancemgr.h"
+#include "llinventorypanel.h"
#include "llfiltereditor.h"
#include "llfloaterreg.h"
#include "llfloaterworldmap.h"
+#include "llfoldervieweventlistener.h"
#include "llpaneleditwearable.h"
#include "llpaneloutfitsinventory.h"
#include "lltextbox.h"
@@ -68,7 +71,7 @@ LLSidepanelAppearance::LLSidepanelAppearance() :
mFilterSubString(LLStringUtil::null),
mFilterEditor(NULL),
mLookInfo(NULL),
- mCurrLookPanel(NULL)
+ mCurrOutfitPanel(NULL)
{
//LLUICtrlFactory::getInstance()->buildPanel(this, "panel_appearance.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder()
mFetchWorn = new LLCurrentlyWornFetchObserver(this);
@@ -81,6 +84,9 @@ LLSidepanelAppearance::~LLSidepanelAppearance()
// virtual
BOOL LLSidepanelAppearance::postBuild()
{
+ mOpenOutfitBtn = getChild<LLButton>("openoutfit_btn");
+ mOpenOutfitBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onOpenOutfitButtonClicked, this));
+
mEditAppearanceBtn = getChild<LLButton>("editappearance_btn");
mEditAppearanceBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditAppearanceButtonClicked, this));
@@ -90,11 +96,9 @@ BOOL LLSidepanelAppearance::postBuild()
mEditBtn = getChild<LLButton>("edit_btn");
mEditBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditButtonClicked, this));
- mNewLookBtn = getChild<LLButton>("newlook_btn");
- mNewLookBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onNewOutfitButtonClicked, this));
- mNewLookBtn->setEnabled(false);
-
- mOverflowBtn = getChild<LLButton>("overflow_btn");
+ mNewOutfitBtn = getChild<LLButton>("newlook_btn");
+ mNewOutfitBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onNewOutfitButtonClicked, this));
+ mNewOutfitBtn->setEnabled(false);
mFilterEditor = getChild<LLFilterEditor>("Filter");
if (mFilterEditor)
@@ -114,8 +118,6 @@ BOOL LLSidepanelAppearance::postBuild()
back_btn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onBackButtonClicked, this));
}
- // *TODO: Assign the action to an appropriate event.
- // mOverflowBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::toggleMediaPanel, this));
}
mEditWearable = dynamic_cast<LLPanelEditWearable*>(getChild<LLPanel>("panel_edit_wearable"));
@@ -130,7 +132,7 @@ BOOL LLSidepanelAppearance::postBuild()
mCurrentLookName = getChild<LLTextBox>("currentlook_name");
- mCurrLookPanel = getChild<LLPanel>("panel_currentlook");
+ mCurrOutfitPanel = getChild<LLPanel>("panel_currentlook");
return TRUE;
}
@@ -179,6 +181,27 @@ void LLSidepanelAppearance::onWearButtonClicked()
}
}
+void LLSidepanelAppearance::onOpenOutfitButtonClicked()
+{
+ const LLViewerInventoryItem *outfit_link = LLAppearanceManager::getInstance()->getCurrentOutfitLink();
+ if (!outfit_link)
+ return;
+ if (!outfit_link->getIsLinkType())
+ return;
+ LLInventoryPanel *inventory_panel = mPanelOutfitsInventory->getActivePanel();
+ if (inventory_panel)
+ {
+ LLFolderView *folder = inventory_panel->getRootFolder();
+ LLFolderViewItem *outfit_folder = folder->getItemByID(outfit_link->getLinkedUUID());
+ if (outfit_folder)
+ {
+ outfit_folder->setOpen(!outfit_folder->isOpen());
+ folder->setSelectionFromRoot(outfit_folder,TRUE);
+ folder->scrollToShowSelection();
+ }
+ }
+}
+
void LLSidepanelAppearance::onEditAppearanceButtonClicked()
{
if (gAgentWearables.areWearablesLoaded())
@@ -231,9 +254,8 @@ void LLSidepanelAppearance::toggleLookInfoPanel(BOOL visible)
mFilterEditor->setVisible(!visible);
mWearBtn->setVisible(!visible);
mEditBtn->setVisible(!visible);
- mNewLookBtn->setVisible(!visible);
- mOverflowBtn->setVisible(!visible);
- mCurrLookPanel->setVisible(!visible);
+ mNewOutfitBtn->setVisible(!visible);
+ mCurrOutfitPanel->setVisible(!visible);
}
void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable)
@@ -255,7 +277,6 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we
void LLSidepanelAppearance::updateVerbs()
{
bool is_look_info_visible = mLookInfo->getVisible();
- mOverflowBtn->setEnabled(false);
if (!is_look_info_visible)
{
@@ -274,35 +295,24 @@ void LLSidepanelAppearance::refreshCurrentOutfitName(const std::string name)
{
if (name == "")
{
- const LLUUID current_outfit_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
- LLInventoryModel::cat_array_t cat_array;
- LLInventoryModel::item_array_t item_array;
- // Can't search on AT_OUTFIT since links to categories return AT_CATEGORY for type since they don't
- // return preferred type.
- LLIsType is_category( LLAssetType::AT_CATEGORY );
- gInventory.collectDescendentsIf(current_outfit_cat,
- cat_array,
- item_array,
- false,
- is_category,
- false);
- for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
- iter != item_array.end();
- iter++)
+ const LLViewerInventoryItem *outfit_link = LLAppearanceManager::getInstance()->getCurrentOutfitLink();
+ if (outfit_link)
{
- const LLViewerInventoryItem *item = (*iter);
- const LLViewerInventoryCategory *cat = item->getLinkedCategory();
+ const LLViewerInventoryCategory *cat = outfit_link->getLinkedCategory();
if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT)
{
mCurrentLookName->setText(cat->getName());
return;
}
}
- mCurrentLookName->setText(std::string(""));
+ mCurrentLookName->setText(getString("No Outfit"));
+ mOpenOutfitBtn->setEnabled(FALSE);
}
else
{
mCurrentLookName->setText(name);
+ // Can't just call update verbs since the folder link may not have been created yet.
+ mOpenOutfitBtn->setEnabled(TRUE);
}
}
@@ -319,7 +329,7 @@ void LLSidepanelAppearance::editWearable(LLWearable *wearable, void *data)
void LLSidepanelAppearance::fetchInventory()
{
- mNewLookBtn->setEnabled(false);
+ mNewOutfitBtn->setEnabled(false);
LLInventoryFetchObserver::item_ref_t ids;
LLUUID item_id;
for(S32 type = (S32)WT_SHAPE; type < (S32)WT_COUNT; ++type)
@@ -368,5 +378,5 @@ void LLSidepanelAppearance::fetchInventory()
void LLSidepanelAppearance::inventoryFetched()
{
- mNewLookBtn->setEnabled(true);
+ mNewOutfitBtn->setEnabled(true);
}
diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h
index 496a1fef72..b335fd910d 100644
--- a/indra/newview/llsidepanelappearance.h
+++ b/indra/newview/llsidepanelappearance.h
@@ -64,6 +64,7 @@ public:
private:
void onFilterEdit(const std::string& search_string);
+ void onOpenOutfitButtonClicked();
void onEditAppearanceButtonClicked();
void onWearButtonClicked();
void onEditButtonClicked();
@@ -78,12 +79,12 @@ private:
LLPanelLookInfo* mLookInfo;
LLPanelEditWearable* mEditWearable;
+ LLButton* mOpenOutfitBtn;
LLButton* mEditAppearanceBtn;
LLButton* mWearBtn;
LLButton* mEditBtn;
- LLButton* mNewLookBtn;
- LLButton* mOverflowBtn;
- LLPanel* mCurrLookPanel;
+ LLButton* mNewOutfitBtn;
+ LLPanel* mCurrOutfitPanel;
LLTextBox* mCurrentLookName;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index e5531a1497..5a67e64bbd 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -140,6 +140,9 @@ public:
virtual std::string getCapabilityUrl(const std::string &name) const
{ return mObject->getRegion()->getCapability(name); }
+ virtual bool isDead() const
+ { return mObject->isDead(); }
+
private:
LLPointer<LLVOVolume> mObject;
};
@@ -183,6 +186,22 @@ LLVOVolume::~LLVOVolume()
}
}
+void LLVOVolume::markDead()
+{
+ if (!mDead)
+ {
+ // TODO: tell LLMediaDataClient to remove this object from its queue
+
+ // Detach all media impls from this object
+ for(U32 i = 0 ; i < mMediaImplList.size() ; i++)
+ {
+ removeMediaImpl(i);
+ }
+ }
+
+ LLViewerObject::markDead();
+}
+
// static
void LLVOVolume::initClass()
@@ -1708,6 +1727,12 @@ void LLVOVolume::updateObjectMediaData(const LLSD &media_data_array)
void LLVOVolume::syncMediaData(S32 texture_index, const LLSD &media_data, bool merge, bool ignore_agent)
{
+ if(mDead)
+ {
+ // If the object has been marked dead, don't process media updates.
+ return;
+ }
+
LLTextureEntry *te = getTE(texture_index);
//llinfos << "BEFORE: texture_index = " << texture_index
// << " hasMedia = " << te->hasMedia() << " : "
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index fb543efc04..70d203daf2 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -100,6 +100,7 @@ public:
public:
LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
+ /*virtual*/ void markDead(); // Override (and call through to parent) to clean up media references
/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index c20aaea2aa..01713cc003 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -35,6 +35,7 @@
<layout_panel
left="0"
top="0"
+ width="180"
user_resize="false">
<button
height="20"
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 077667a3fc..8ab5fb1659 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -2464,7 +2464,7 @@
function="Advanced.EnableRenderDeferred" />
</menu_item_check>
<menu_item_check
- label="Global Illumintation"
+ label="Global Illumination"
name="Global Illumination">
<menu_item_check.on_check
function="CheckControl"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
index 041297a542..b9a89a2ebc 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
@@ -9,9 +9,9 @@
min_width="240"
name="appearance panel"
width="333">
- <string
- name="looks_tab_title"
- value="Outfits" />
+ <string
+ name="No Outfit"
+ value="No Outfit" />
<panel
left="5" width="320" height="55"
background_visible="true"
@@ -19,25 +19,34 @@
bg_alpha_color="0.2 0.2 0.2 1.0"
name="panel_currentlook"
follows="left|top|right">
+ <button
+ follows="left|right|top"
+ font="SansSerif"
+ top="28" right="-10" width="60" height="20"
+ layout="topleft"
+ label="Edit"
+ name="editappearance_btn"/>
+ <button
+ follows="left|right|top"
+ top="28" left="5" width="25" height="22"
+ image_overlay="Inv_LookFolderOpen"
+ layout="topleft"
+ name="openoutfit_btn"
+ picture_style="true" />
<text
- top="-5" width="200" left="5" height="10" follows="left|right|top"
+ top="10" width="150" left="5" height="15" follows="left|right|top"
+ layout="topleft"
font="SansSerif" text_color="LtGray" word_wrap="true"
mouse_opaque="false" name="currentlook_title">
- Current Outfit
+ Current Outfit:
</text>
<text
- top="-30" left="8" height="10" follows="left|right|top"
+ top="32" width="150" left="32" height="15" follows="left|right|top"
+ layout="topleft"
font="SansSerifBold" text_color="white" word_wrap="true"
mouse_opaque="false" name="currentlook_name" >
MyOutfit
</text>
- <button
- follows="left|right|top"
- font="SansSerif"
- top="28" right="-105" width="60" height="20"
- layout="topleft"
- label="Edit"
- name="editappearance_btn"/>
</panel>
<filter_editor
diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp
index 3ac631d96e..217889c390 100644
--- a/indra/newview/tests/llmediadataclient_test.cpp
+++ b/indra/newview/tests/llmediadataclient_test.cpp
@@ -152,12 +152,13 @@ public:
std::istringstream d(data);
LLSDSerialize::fromXML(mRep, d);
mNumBounceBacks = 0;
+ mDead = false;
// std::cout << ll_pretty_print_sd(mRep) << std::endl;
// std::cout << "ID: " << getID() << std::endl;
}
LLMediaDataClientObjectTest(const LLSD &rep)
- : mRep(rep), mNumBounceBacks(0) {}
+ : mRep(rep), mNumBounceBacks(0), mDead(false) {}
~LLMediaDataClientObjectTest()
{ LL_DEBUGS("LLMediaDataClient") << "~LLMediaDataClientObjectTest" << LL_ENDL; }
@@ -187,12 +188,18 @@ public:
virtual std::string getCapabilityUrl(const std::string &name) const
{ return mRep["cap_urls"][name]; }
+ virtual bool isDead() const
+ { return mDead; }
+
int getNumBounceBacks() const
{ return mNumBounceBacks; }
+ void markDead()
+ { mDead = true; }
private:
LLSD mRep;
int mNumBounceBacks;
+ bool mDead;
};
// This special timer delay should ensure that the timer will fire on the very
@@ -531,4 +538,61 @@ namespace tut
ensure("REF COUNT", o1->getNumRefs(), num_refs_start);
}
+
+ template<> template<>
+ void mediadataclient_object_t::test<8>()
+ {
+ // Test queue handling of objects that are marked dead.
+ LOG_TEST(8);
+
+ LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"1.0","1.0"));
+ LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"2.0","1.0"));
+ LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"3.0","1.0"));
+ LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"4.0","1.0"));
+ {
+ LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
+
+ // queue up all 4 objects
+ mdc->fetchMedia(o1);
+ mdc->fetchMedia(o2);
+ mdc->fetchMedia(o3);
+ mdc->fetchMedia(o4);
+
+ // and mark the second and fourth ones dead.
+ dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o2))->markDead();
+ dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o4))->markDead();
+
+ ensure("is in queue 1", mdc->isInQueue(o1));
+ ensure("is in queue 2", mdc->isInQueue(o2));
+ ensure("is in queue 3", mdc->isInQueue(o3));
+ ensure("is in queue 4", mdc->isInQueue(o4));
+ ensure("post records", gPostRecords->size(), 0);
+
+ ::pump_timers();
+
+ // The first tick should remove the first one
+ ensure("is not in queue 1", !mdc->isInQueue(o1));
+ ensure("is in queue 2", mdc->isInQueue(o2));
+ ensure("is in queue 3", mdc->isInQueue(o3));
+ ensure("is in queue 4", mdc->isInQueue(o4));
+ ensure("post records", gPostRecords->size(), 1);
+
+ ::pump_timers();
+
+ // The second tick should skip the second and remove the third
+ ensure("is not in queue 2", !mdc->isInQueue(o2));
+ ensure("is not in queue 3", !mdc->isInQueue(o3));
+ ensure("is in queue 4", mdc->isInQueue(o4));
+ ensure("post records", gPostRecords->size(), 2);
+
+ ::pump_timers();
+
+ // The third tick should skip the fourth one and empty the queue.
+ ensure("is not in queue 4", !mdc->isInQueue(o4));
+ ensure("post records", gPostRecords->size(), 2);
+
+ ensure("queue empty", mdc->isEmpty());
+ }
+
+ }
}