summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorTofu Linden <tofu.linden@lindenlab.com>2010-05-05 19:16:05 +0100
committerTofu Linden <tofu.linden@lindenlab.com>2010-05-05 19:16:05 +0100
commit8d9c7855ddbe3f4666a293f29f4d6c89730d10c5 (patch)
tree6d84364e513f68908f2fddcbd1a4a68ca1958062 /indra
parent447bffcb532694fcc3bc3b046051f02ac4550fd3 (diff)
parentf290e9e851e1af694cd8df86e171b79ed4186e90 (diff)
merge from viewer-public
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/llworkerthread.cpp2
-rw-r--r--indra/llmessage/llhttpclient.cpp4
-rw-r--r--indra/llui/llfiltereditor.cpp1
-rw-r--r--indra/llui/llflatlistview.cpp44
-rw-r--r--indra/llui/llflatlistview.h2
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/llagentwearables.cpp11
-rw-r--r--indra/newview/llagentwearables.h11
-rw-r--r--indra/newview/llfloaterurlentry.cpp5
-rw-r--r--indra/newview/llfolderview.h1
-rw-r--r--indra/newview/llinventorybridge.cpp64
-rw-r--r--indra/newview/llinventorybridge.h57
-rw-r--r--indra/newview/llinventorymodelbackgroundfetch.cpp178
-rw-r--r--indra/newview/llinventorymodelbackgroundfetch.h21
-rw-r--r--indra/newview/llinventorypanel.cpp27
-rw-r--r--indra/newview/llpanelmaininventory.cpp6
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp18
-rw-r--r--indra/newview/llpaneloutfitsinventory.h2
-rw-r--r--indra/newview/llparticipantlist.cpp4
-rw-r--r--indra/newview/llsidepanelappearance.cpp6
-rw-r--r--indra/newview/llsidepanelappearance.h1
-rw-r--r--indra/newview/lltexturefetch.cpp42
-rw-r--r--indra/newview/lltexturefetch.h4
-rw-r--r--indra/newview/llviewerinventory.cpp2
-rw-r--r--indra/newview/llviewertexture.cpp26
-rw-r--r--indra/newview/llviewertexture.h4
-rw-r--r--indra/newview/llvoavatar.cpp28
-rw-r--r--indra/newview/pipeline.cpp2
-rw-r--r--indra/newview/skins/default/xui/en/menu_participant_list.xml198
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_notices.xml18
-rw-r--r--indra/newview/skins/default/xui/en/panel_main_inventory.xml140
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_appearance.xml8
32 files changed, 667 insertions, 281 deletions
diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp
index 2629237f7e..a29e9a348e 100644
--- a/indra/llcommon/llworkerthread.cpp
+++ b/indra/llcommon/llworkerthread.cpp
@@ -404,7 +404,7 @@ void LLWorkerClass::scheduleDelete()
void LLWorkerClass::setPriority(U32 priority)
{
mMutex.lock();
- if (mRequestHandle != LLWorkerThread::nullHandle())
+ if (mRequestHandle != LLWorkerThread::nullHandle() && mRequestPriority != priority)
{
mRequestPriority = priority;
mWorkerThread->setPriority(mRequestHandle, priority);
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
index dd56e18caf..964cbd1026 100644
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -79,8 +79,10 @@ namespace
{
if (mResponder.get())
{
- mResponder->completedRaw(mStatus, mReason, channels, buffer);
+ // Allow clients to parse headers before we attempt to parse
+ // the body and provide completed/result/error calls.
mResponder->completedHeader(mStatus, mReason, mHeaderOutput);
+ mResponder->completedRaw(mStatus, mReason, channels, buffer);
}
}
virtual void header(const std::string& header, const std::string& value)
diff --git a/indra/llui/llfiltereditor.cpp b/indra/llui/llfiltereditor.cpp
index 390504234d..6c80275713 100644
--- a/indra/llui/llfiltereditor.cpp
+++ b/indra/llui/llfiltereditor.cpp
@@ -39,6 +39,7 @@
LLFilterEditor::LLFilterEditor(const LLFilterEditor::Params& p)
: LLSearchEditor(p)
{
+ setCommitOnFocusLost(FALSE); // we'll commit on every keystroke, don't re-commit when we take focus away (i.e. we go to interact with the actual results!)
}
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index bea2572ff8..6bd16c9ee6 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -379,6 +379,7 @@ LLFlatListView::LLFlatListView(const LLFlatListView::Params& p)
, mCommitOnSelectionChange(false)
, mPrevNotifyParentRect(LLRect())
, mNoItemsCommentTextbox(NULL)
+ , mIsConsecutiveSelection(false)
{
mBorderThickness = getBorderWidth();
@@ -536,6 +537,7 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
return;
bool grab_items = false;
+ bool reverse = false;
pairs_list_t pairs_to_select;
// Pick out items from list between last selected and current clicked item_pair.
@@ -547,6 +549,8 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
item_pair_t* cur = *iter;
if (cur == last_selected_pair || cur == item_pair)
{
+ // We've got reverse selection if last grabed item isn't a new selection.
+ reverse = grab_items && (cur != item_pair);
grab_items = !grab_items;
// Skip last selected and current clicked item pairs.
continue;
@@ -562,26 +566,35 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
}
}
- if (select_item)
+ if (reverse)
{
- pairs_to_select.push_back(item_pair);
+ pairs_to_select.reverse();
}
+ pairs_to_select.push_back(item_pair);
+
for (pairs_iterator_t
iter = pairs_to_select.begin(),
iter_end = pairs_to_select.end();
iter != iter_end; ++iter)
{
item_pair_t* pair_to_select = *iter;
- selectItemPair(pair_to_select, true);
+ if (isSelected(pair_to_select))
+ {
+ // Item was already selected but there is a need to keep order from last selected pair to new selection.
+ // Do it here to prevent extra mCommitOnSelectionChange in selectItemPair().
+ mSelectedItemPairs.remove(pair_to_select);
+ mSelectedItemPairs.push_back(pair_to_select);
+ }
+ else
+ {
+ selectItemPair(pair_to_select, true);
+ }
}
if (!select_item)
{
- // Item was already selected but there is a need to update last selected item and its border.
- // Do it here to prevent extra mCommitOnSelectionChange in selectItemPair().
- mSelectedItemPairs.remove(item_pair);
- mSelectedItemPairs.push_back(item_pair);
+ // Update last selected item border.
mSelectedItemsBorder->setRect(getLastSelectedItemRect().stretch(-1));
}
return;
@@ -749,6 +762,8 @@ bool LLFlatListView::selectItemPair(item_pair_t* item_pair, bool select)
// Stretch selected item rect to ensure it won't be clipped
mSelectedItemsBorder->setRect(getLastSelectedItemRect().stretch(-1));
+ // By default mark it as not consecutive selection
+ mIsConsecutiveSelection = false;
return true;
}
@@ -823,6 +838,17 @@ bool LLFlatListView::selectNextItemPair(bool is_up_direction, bool reset_selecti
if ( 0 == size() )
return false;
+ if (!mIsConsecutiveSelection)
+ {
+ // Leave only one item selected if list has not consecutive selection
+ if (mSelectedItemPairs.size() && !reset_selection)
+ {
+ item_pair_t* cur_sel_pair = mSelectedItemPairs.back();
+ resetSelection();
+ selectItemPair (cur_sel_pair, true);
+ }
+ }
+
if ( mSelectedItemPairs.size() )
{
item_pair_t* to_sel_pair = NULL;
@@ -877,6 +903,8 @@ bool LLFlatListView::selectNextItemPair(bool is_up_direction, bool reset_selecti
}
// Select/Deselect next item
selectItemPair(select ? to_sel_pair : cur_sel_pair, select);
+ // Mark it as consecutive selection
+ mIsConsecutiveSelection = true;
return true;
}
}
@@ -888,6 +916,8 @@ bool LLFlatListView::selectNextItemPair(bool is_up_direction, bool reset_selecti
selectLastItem();
else
selectFirstItem();
+ // Mark it as consecutive selection
+ mIsConsecutiveSelection = true;
return true;
}
diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h
index 6395805aab..f4e0426f15 100644
--- a/indra/llui/llflatlistview.h
+++ b/indra/llui/llflatlistview.h
@@ -410,6 +410,8 @@ private:
bool mKeepOneItemSelected;
+ bool mIsConsecutiveSelection;
+
/** All pairs of the list */
pairs_list_t mItemPairs;
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index be32d92ea1..0106e9a78f 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1652,6 +1652,17 @@
<key>Value</key>
<string />
</map>
+ <key>DebugAvatarRezTime</key>
+ <map>
+ <key>Comment</key>
+ <string>Display times for avatars to resolve.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>DebugBeaconLineWidth</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index b5fde0baca..47735e7179 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1164,6 +1164,7 @@ void LLAgentWearables::createStandardWearablesAllDone()
mWearablesLoaded = TRUE;
checkWearablesLoaded();
+ mLoadedSignal();
updateServer();
@@ -1567,6 +1568,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
// Start rendering & update the server
mWearablesLoaded = TRUE;
checkWearablesLoaded();
+ mLoadedSignal();
queryWearableCache();
updateServer();
@@ -2012,6 +2014,10 @@ BOOL LLAgentWearables::areWearablesLoaded() const
void LLAgentWearables::updateWearablesLoaded()
{
mWearablesLoaded = (itemUpdatePendingCount()==0);
+ if (mWearablesLoaded)
+ {
+ mLoadedSignal();
+ }
}
bool LLAgentWearables::canWearableBeRemoved(const LLWearable* wearable) const
@@ -2091,3 +2097,8 @@ void LLAgentWearables::populateMyOutfitsFolder(void)
outfits->done();
}
}
+
+boost::signals2::connection LLAgentWearables::addLoadedCallback(loaded_callback_t cb)
+{
+ return mLoadedSignal.connect(cb);
+}
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index d3b18f68f1..a28cba0343 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -209,6 +209,17 @@ public:
U32 itemUpdatePendingCount() const;
//--------------------------------------------------------------------
+ // Signals
+ //--------------------------------------------------------------------
+public:
+ typedef boost::function<void()> loaded_callback_t;
+ typedef boost::signals2::signal<void()> loaded_signal_t;
+ boost::signals2::connection addLoadedCallback(loaded_callback_t cb);
+
+private:
+ loaded_signal_t mLoadedSignal; // emitted when all agent wearables get loaded
+
+ //--------------------------------------------------------------------
// Member variables
//--------------------------------------------------------------------
private:
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index 002d417e4c..0e802e9736 100644
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -70,11 +70,6 @@ public:
completeAny(status, mime_type);
}
- virtual void error( U32 status, const std::string& reason )
- {
- completeAny(status, LLMIMETypes::getDefaultMimeType());
- }
-
void completeAny(U32 status, const std::string& mime_type)
{
// Set empty type to none/none. Empty string is reserved for legacy parcels
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 874723bb1a..38d7a47eba 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -230,6 +230,7 @@ public:
EAcceptance* accept,
std::string& tooltip_msg);
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+ /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask) { setShowSelectionContext(FALSE); }
virtual void draw();
virtual void deleteAllChildren();
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 2d08c0a01a..228ab7ebd6 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -5525,3 +5525,67 @@ LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_
/** Bridge Actions
**
********************************************************************************/
+
+/************************************************************************/
+/* Recent Inventory Panel related classes */
+/************************************************************************/
+void LLRecentItemsFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+ LLFolderBridge::buildContextMenu(menu, flags);
+
+ menuentry_vec_t disabled_items, items = getMenuItems();
+
+ items.erase(std::find(items.begin(), items.end(), std::string("New Folder")));
+ items.erase(std::find(items.begin(), items.end(), std::string("New Script")));
+ items.erase(std::find(items.begin(), items.end(), std::string("New Note")));
+ items.erase(std::find(items.begin(), items.end(), std::string("New Gesture")));
+ items.erase(std::find(items.begin(), items.end(), std::string("New Clothes")));
+ items.erase(std::find(items.begin(), items.end(), std::string("New Body Parts")));
+
+ hide_context_entries(menu, items, disabled_items);
+}
+
+LLInvFVBridge* LLRecentInventoryBridgeBuilder::createBridge(
+ LLAssetType::EType asset_type,
+ LLAssetType::EType actual_asset_type,
+ LLInventoryType::EType inv_type,
+ LLInventoryPanel* inventory,
+ LLFolderView* root,
+ const LLUUID& uuid,
+ U32 flags /*= 0x00*/ ) const
+{
+ LLInvFVBridge* new_listener = NULL;
+ switch(asset_type)
+ {
+ case LLAssetType::AT_CATEGORY:
+ if (actual_asset_type == LLAssetType::AT_LINK_FOLDER)
+ {
+ // *TODO: Create a link folder handler instead if it is necessary
+ new_listener = LLInventoryFVBridgeBuilder::createBridge(
+ asset_type,
+ actual_asset_type,
+ inv_type,
+ inventory,
+ root,
+ uuid,
+ flags);
+ break;
+ }
+ new_listener = new LLRecentItemsFolderBridge(inv_type, inventory, root, uuid);
+ break;
+ default:
+ new_listener = LLInventoryFVBridgeBuilder::createBridge(
+ asset_type,
+ actual_asset_type,
+ inv_type,
+ inventory,
+ root,
+ uuid,
+ flags);
+ }
+ return new_listener;
+
+}
+
+
+// EOF
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index de63bdd76b..c45e376cab 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -349,6 +349,11 @@ protected:
void modifyOutfit(BOOL append);
void determineFolderType();
+ /**
+ * Returns a copy of current menu items.
+ */
+ menuentry_vec_t getMenuItems() { return mItems; }
+
public:
static LLFolderBridge* sSelf;
static void staticFolderOptionsMenu();
@@ -659,6 +664,58 @@ protected:
};
+/************************************************************************/
+/* Recent Inventory Panel related classes */
+/************************************************************************/
+class LLRecentInventoryBridgeBuilder;
+/**
+ * Overridden version of the Inventory-Folder-View-Bridge for Folders
+ */
+class LLRecentItemsFolderBridge : public LLFolderBridge
+{
+ friend class LLRecentInventoryBridgeBuilder;
+
+public:
+ /**
+ * Creates context menu for Folders related to Recent Inventory Panel.
+ *
+ * It uses base logic and than removes from visible items "New..." menu items.
+ */
+ /*virtual*/ void buildContextMenu(LLMenuGL& menu, U32 flags);
+
+protected:
+ LLRecentItemsFolderBridge(LLInventoryType::EType type,
+ LLInventoryPanel* inventory,
+ LLFolderView* root,
+ const LLUUID& uuid) :
+ LLFolderBridge(inventory, root, uuid)
+ {
+ mInvType = type;
+ }
+};
+
+/**
+ * Bridge builder to create Inventory-Folder-View-Bridge for Recent Inventory Panel
+ */
+class LLRecentInventoryBridgeBuilder : public LLInventoryFVBridgeBuilder
+{
+ /**
+ * Overrides FolderBridge for Recent Inventory Panel.
+ *
+ * It use base functionality for bridges other than FolderBridge.
+ */
+ virtual LLInvFVBridge* createBridge(LLAssetType::EType asset_type,
+ LLAssetType::EType actual_asset_type,
+ LLInventoryType::EType inv_type,
+ LLInventoryPanel* inventory,
+ LLFolderView* root,
+ const LLUUID& uuid,
+ U32 flags = 0x00) const;
+
+};
+
+
+
void wear_inventory_item_on_avatar(LLInventoryItem* item);
void rez_attachment(LLViewerInventoryItem* item,
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index cfbc2c3e05..0ff6ab2644 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -46,26 +46,11 @@
const F32 MAX_TIME_FOR_SINGLE_FETCH = 10.f;
const S32 MAX_FETCH_RETRIES = 10;
-// RN: for some reason, using std::queue in the header file confuses the compiler which thinks it's an xmlrpc_queue
-static std::deque<LLUUID> sFetchQueue;
-bool fetchQueueContainsNoDescendentsOf(const LLUUID& cat_id)
-{
- for (std::deque<LLUUID>::iterator it = sFetchQueue.begin();
- it != sFetchQueue.end(); ++it)
- {
- const LLUUID& fetch_id = *it;
- if (gInventory.isObjectDescendentOf(fetch_id, cat_id))
- return false;
- }
- return true;
-}
-
-
LLInventoryModelBackgroundFetch::LLInventoryModelBackgroundFetch() :
mBackgroundFetchActive(FALSE),
mAllFoldersFetched(FALSE),
- mInventoryFetchStarted(FALSE),
- mLibraryFetchStarted(FALSE),
+ mRecursiveInventoryFetchStarted(FALSE),
+ mRecursiveLibraryFetchStarted(FALSE),
mNumFetchRetries(0),
mMinTimeBetweenFetches(0.3f),
mMaxTimeBetweenFetches(10.f),
@@ -80,12 +65,12 @@ LLInventoryModelBackgroundFetch::~LLInventoryModelBackgroundFetch()
bool LLInventoryModelBackgroundFetch::isBulkFetchProcessingComplete()
{
- return sFetchQueue.empty() && mBulkFetchCount<=0;
+ return mFetchQueue.empty() && mBulkFetchCount<=0;
}
bool LLInventoryModelBackgroundFetch::libraryFetchStarted()
{
- return mLibraryFetchStarted;
+ return mRecursiveLibraryFetchStarted;
}
bool LLInventoryModelBackgroundFetch::libraryFetchCompleted()
@@ -100,7 +85,7 @@ bool LLInventoryModelBackgroundFetch::libraryFetchInProgress()
bool LLInventoryModelBackgroundFetch::inventoryFetchStarted()
{
- return mInventoryFetchStarted;
+ return mRecursiveInventoryFetchStarted;
}
bool LLInventoryModelBackgroundFetch::inventoryFetchCompleted()
@@ -123,41 +108,41 @@ BOOL LLInventoryModelBackgroundFetch::backgroundFetchActive()
return mBackgroundFetchActive;
}
-void LLInventoryModelBackgroundFetch::start(const LLUUID& cat_id)
+void LLInventoryModelBackgroundFetch::start(const LLUUID& cat_id, BOOL recursive)
{
if (!mAllFoldersFetched)
{
mBackgroundFetchActive = TRUE;
if (cat_id.isNull())
{
- if (!mInventoryFetchStarted)
+ if (!mRecursiveInventoryFetchStarted)
{
- mInventoryFetchStarted = TRUE;
- sFetchQueue.push_back(gInventory.getRootFolderID());
+ mRecursiveInventoryFetchStarted |= recursive;
+ mFetchQueue.push_back(FetchQueueInfo(gInventory.getRootFolderID(), recursive));
gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL);
}
- if (!mLibraryFetchStarted)
+ if (!mRecursiveLibraryFetchStarted)
{
- mLibraryFetchStarted = TRUE;
- sFetchQueue.push_back(gInventory.getLibraryRootFolderID());
+ mRecursiveLibraryFetchStarted |= recursive;
+ mFetchQueue.push_back(FetchQueueInfo(gInventory.getLibraryRootFolderID(), recursive));
gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL);
}
}
else
{
// specific folder requests go to front of queue
- if (sFetchQueue.empty() || sFetchQueue.front() != cat_id)
+ if (mFetchQueue.empty() || mFetchQueue.front().mCatUUID != cat_id)
{
- sFetchQueue.push_front(cat_id);
+ mFetchQueue.push_front(FetchQueueInfo(cat_id, recursive));
gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL);
}
if (cat_id == gInventory.getLibraryRootFolderID())
{
- mLibraryFetchStarted = TRUE;
+ mRecursiveLibraryFetchStarted |= recursive;
}
if (cat_id == gInventory.getRootFolderID())
{
- mInventoryFetchStarted = TRUE;
+ mRecursiveInventoryFetchStarted |= recursive;
}
}
}
@@ -166,7 +151,7 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& cat_id)
void LLInventoryModelBackgroundFetch::findLostItems()
{
mBackgroundFetchActive = TRUE;
- sFetchQueue.push_back(LLUUID::null);
+ mFetchQueue.push_back(FetchQueueInfo(LLUUID::null, TRUE));
gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL);
}
@@ -183,8 +168,8 @@ void LLInventoryModelBackgroundFetch::stopBackgroundFetch()
void LLInventoryModelBackgroundFetch::setAllFoldersFetched()
{
- if (mInventoryFetchStarted &&
- mLibraryFetchStarted)
+ if (mRecursiveInventoryFetchStarted &&
+ mRecursiveLibraryFetchStarted)
{
mAllFoldersFetched = TRUE;
}
@@ -210,7 +195,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()
//DEPRECATED OLD CODE FOLLOWS.
// no more categories to fetch, stop fetch process
- if (sFetchQueue.empty())
+ if (mFetchQueue.empty())
{
llinfos << "Inventory fetch completed" << llendl;
@@ -232,7 +217,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()
while(1)
{
- if (sFetchQueue.empty())
+ if (mFetchQueue.empty())
{
break;
}
@@ -243,12 +228,13 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()
break;
}
- LLViewerInventoryCategory* cat = gInventory.getCategory(sFetchQueue.front());
+ const FetchQueueInfo info = mFetchQueue.front();
+ LLViewerInventoryCategory* cat = gInventory.getCategory(info.mCatUUID);
// category has been deleted, remove from queue.
if (!cat)
{
- sFetchQueue.pop_front();
+ mFetchQueue.pop_front();
continue;
}
@@ -271,10 +257,10 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()
}
}
// do I have all my children?
- else if (gInventory.isCategoryComplete(sFetchQueue.front()))
+ else if (gInventory.isCategoryComplete(info.mCatUUID))
{
// finished with this category, remove from queue
- sFetchQueue.pop_front();
+ mFetchQueue.pop_front();
// add all children to queue
LLInventoryModel::cat_array_t* categories;
@@ -284,7 +270,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()
it != categories->end();
++it)
{
- sFetchQueue.push_back((*it)->getUUID());
+ mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(),info.mRecursive));
}
// we received a response in less than the fast time
@@ -303,13 +289,12 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()
{
// received first packet, but our num descendants does not match db's num descendants
// so try again later
- LLUUID fetch_id = sFetchQueue.front();
- sFetchQueue.pop_front();
+ mFetchQueue.pop_front();
if (mNumFetchRetries++ < MAX_FETCH_RETRIES)
{
// push on back of queue
- sFetchQueue.push_back(fetch_id);
+ mFetchQueue.push_back(info);
}
mTimelyFetchPending = FALSE;
mFetchTimer.reset();
@@ -334,20 +319,25 @@ void LLInventoryModelBackgroundFetch::incrBulkFetch(S16 fetching)
class LLInventoryModelFetchDescendentsResponder: public LLHTTPClient::Responder
{
- public:
- LLInventoryModelFetchDescendentsResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
- //LLInventoryModelFetchDescendentsResponder() {};
- void result(const LLSD& content);
- void error(U32 status, const std::string& reason);
- public:
- typedef std::vector<LLViewerInventoryCategory*> folder_ref_t;
- protected:
- LLSD mRequestSD;
+public:
+ LLInventoryModelFetchDescendentsResponder(const LLSD& request_sd, uuid_vec_t recursive_cats) :
+ mRequestSD(request_sd),
+ mRecursiveCatUUIDs(recursive_cats)
+ {};
+ //LLInventoryModelFetchDescendentsResponder() {};
+ void result(const LLSD& content);
+ void error(U32 status, const std::string& reason);
+protected:
+ BOOL getIsRecursive(const LLUUID& cat_id) const;
+private:
+ LLSD mRequestSD;
+ uuid_vec_t mRecursiveCatUUIDs; // Hack for storing away which cat fetches are recursive.
};
//If we get back a normal response, handle it here
-void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)
+void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)
{
+ LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
if (content.has("folders"))
{
@@ -412,11 +402,12 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)
{
LLSD category = *category_it;
tcategory->fromLLSD(category);
-
- if (LLInventoryModelBackgroundFetch::instance().inventoryFetchStarted() ||
- LLInventoryModelBackgroundFetch::instance().libraryFetchStarted())
+
+ const BOOL recursive = getIsRecursive(tcategory->getUUID());
+
+ if (recursive)
{
- sFetchQueue.push_back(tcategory->getUUID());
+ fetcher->mFetchQueue.push_back(LLInventoryModelBackgroundFetch::FetchQueueInfo(tcategory->getUUID(), recursive));
}
else if ( !gInventory.isCategoryComplete(tcategory->getUUID()) )
{
@@ -461,12 +452,12 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)
}
}
- LLInventoryModelBackgroundFetch::instance().incrBulkFetch(-1);
+ fetcher->incrBulkFetch(-1);
- if (LLInventoryModelBackgroundFetch::instance().isBulkFetchProcessingComplete())
+ if (fetcher->isBulkFetchProcessingComplete())
{
llinfos << "Inventory fetch completed" << llendl;
- LLInventoryModelBackgroundFetch::instance().setAllFoldersFetched();
+ fetcher->setAllFoldersFetched();
}
gInventory.notifyObservers("fetchDescendents");
@@ -475,12 +466,14 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)
//If we get back an error (not found, etc...), handle it here
void LLInventoryModelFetchDescendentsResponder::error(U32 status, const std::string& reason)
{
+ LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
+
llinfos << "LLInventoryModelFetchDescendentsResponder::error "
<< status << ": " << reason << llendl;
- LLInventoryModelBackgroundFetch::instance().incrBulkFetch(-1);
+ fetcher->incrBulkFetch(-1);
- if (status==499) //timed out. Let's be awesome!
+ if (status==499) // Timed out.
{
for(LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray();
folder_it != mRequestSD["folders"].endArray();
@@ -488,24 +481,30 @@ void LLInventoryModelFetchDescendentsResponder::error(U32 status, const std::str
{
LLSD folder_sd = *folder_it;
LLUUID folder_id = folder_sd["folder_id"];
- sFetchQueue.push_front(folder_id);
+ const BOOL recursive = getIsRecursive(folder_id);
+ fetcher->mFetchQueue.push_front(LLInventoryModelBackgroundFetch::FetchQueueInfo(folder_id, recursive));
}
}
else
{
- if (LLInventoryModelBackgroundFetch::instance().isBulkFetchProcessingComplete())
+ if (fetcher->isBulkFetchProcessingComplete())
{
- LLInventoryModelBackgroundFetch::instance().setAllFoldersFetched();
+ fetcher->setAllFoldersFetched();
}
}
gInventory.notifyObservers("fetchDescendents");
}
+BOOL LLInventoryModelFetchDescendentsResponder::getIsRecursive(const LLUUID& cat_id) const
+{
+ return (std::find(mRecursiveCatUUIDs.begin(),mRecursiveCatUUIDs.end(), cat_id) != mRecursiveCatUUIDs.end());
+}
+
//static Bundle up a bunch of requests to send all at once.
void LLInventoryModelBackgroundFetch::bulkFetch(std::string url)
{
//Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped.
- //If there are items in sFetchQueue, we want to check the time since the last bulkFetch was
+ //If there are items in mFetchQueue, we want to check the time since the last bulkFetch was
//sent. If it exceeds our retry time, go ahead and fire off another batch.
//Stopbackgroundfetch will be run from the Responder instead of here.
@@ -528,11 +527,16 @@ void LLInventoryModelBackgroundFetch::bulkFetch(std::string url)
U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER) & 0x1;
+ uuid_vec_t recursive_cats;
+
LLSD body;
LLSD body_lib;
- while (!(sFetchQueue.empty()) && (folder_count < max_batch_size))
+
+ while (!(mFetchQueue.empty()) && (folder_count < max_batch_size))
{
- if (sFetchQueue.front().isNull()) //DEV-17797
+ const FetchQueueInfo& fetch_info = mFetchQueue.front();
+ const LLUUID &cat_id = fetch_info.mCatUUID;
+ if (cat_id.isNull()) //DEV-17797
{
LLSD folder_sd;
folder_sd["folder_id"] = LLUUID::null.asString();
@@ -545,7 +549,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch(std::string url)
}
else
{
- LLViewerInventoryCategory* cat = gInventory.getCategory(sFetchQueue.front());
+ const LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
if (cat)
{
@@ -564,9 +568,9 @@ void LLInventoryModelBackgroundFetch::bulkFetch(std::string url)
body["folders"].append(folder_sd);
folder_count++;
}
- if (mInventoryFetchStarted || mLibraryFetchStarted)
- { //Already have this folder but append child folders to list.
- // add all children to queue
+ // May already have this folder, but append child folders to list.
+ if (fetch_info.mRecursive)
+ {
LLInventoryModel::cat_array_t* categories;
LLInventoryModel::item_array_t* items;
gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items);
@@ -574,12 +578,15 @@ void LLInventoryModelBackgroundFetch::bulkFetch(std::string url)
it != categories->end();
++it)
{
- sFetchQueue.push_back((*it)->getUUID());
+ mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive));
}
}
}
}
- sFetchQueue.pop_front();
+ if (fetch_info.mRecursive)
+ recursive_cats.push_back(cat_id);
+
+ mFetchQueue.pop_front();
}
if (folder_count > 0)
@@ -587,12 +594,15 @@ void LLInventoryModelBackgroundFetch::bulkFetch(std::string url)
mBulkFetchCount++;
if (body["folders"].size())
{
- LLHTTPClient::post(url, body, new LLInventoryModelFetchDescendentsResponder(body),300.0);
+ LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(body, recursive_cats);
+ LLHTTPClient::post(url, body, fetcher, 300.0);
}
if (body_lib["folders"].size())
{
std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents");
- LLHTTPClient::post(url_lib, body_lib, new LLInventoryModelFetchDescendentsResponder(body_lib),300.0);
+
+ LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(body_lib, recursive_cats);
+ LLHTTPClient::post(url_lib, body_lib, fetcher, 300.0);
}
mFetchTimer.reset();
}
@@ -601,3 +611,17 @@ void LLInventoryModelBackgroundFetch::bulkFetch(std::string url)
setAllFoldersFetched();
}
}
+
+bool LLInventoryModelBackgroundFetch::fetchQueueContainsNoDescendentsOf(const LLUUID& cat_id) const
+{
+ for (fetch_queue_t::const_iterator it = mFetchQueue.begin();
+ it != mFetchQueue.end(); ++it)
+ {
+ const LLUUID& fetch_id = (*it).mCatUUID;
+ if (gInventory.isObjectDescendentOf(fetch_id, cat_id))
+ return false;
+ }
+ return true;
+}
+
+
diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h
index 94606fae23..c1e37eda8f 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.h
+++ b/indra/newview/llinventorymodelbackgroundfetch.h
@@ -68,13 +68,15 @@ class LLInventoryCollectFunctor;
class LLInventoryModelBackgroundFetch : public LLSingleton<LLInventoryModelBackgroundFetch>
{
+ friend class LLInventoryModelFetchDescendentsResponder;
+
public:
LLInventoryModelBackgroundFetch();
~LLInventoryModelBackgroundFetch();
// Start and stop background breadth-first fetching of inventory contents.
// This gets triggered when performing a filter-search
- void start(const LLUUID& cat_id = LLUUID::null);
+ void start(const LLUUID& cat_id = LLUUID::null, BOOL recursive = TRUE);
BOOL backgroundFetchActive();
bool isEverythingFetched();
void incrBulkFetch(S16 fetching);
@@ -98,9 +100,20 @@ public:
static void backgroundFetchCB(void*); // background fetch idle function
void backgroundFetch();
+ struct FetchQueueInfo
+ {
+ FetchQueueInfo(const LLUUID& id, BOOL recursive) :
+ mCatUUID(id), mRecursive(recursive)
+ {
+ }
+ LLUUID mCatUUID;
+ BOOL mRecursive;
+ };
+protected:
+ bool fetchQueueContainsNoDescendentsOf(const LLUUID& cat_id) const;
private:
- BOOL mInventoryFetchStarted;
- BOOL mLibraryFetchStarted;
+ BOOL mRecursiveInventoryFetchStarted;
+ BOOL mRecursiveLibraryFetchStarted;
BOOL mAllFoldersFetched;
// completing the fetch once per session should be sufficient
@@ -113,6 +126,8 @@ private:
F32 mMinTimeBetweenFetches;
F32 mMaxTimeBetweenFetches;
+ typedef std::deque<FetchQueueInfo> fetch_queue_t;
+ fetch_queue_t mFetchQueue;
};
#endif // LL_LLINVENTORYMODELBACKGROUNDFETCH_H
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 15c872a7c4..dd1e039cb1 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1001,3 +1001,30 @@ BOOL LLInventoryPanel::getIsHiddenFolderType(LLFolderType::EType folder_type) co
{
return (std::find(mHiddenFolderTypes.begin(), mHiddenFolderTypes.end(), folder_type) != mHiddenFolderTypes.end());
}
+
+
+/************************************************************************/
+/* Recent Inventory Panel related class */
+/************************************************************************/
+class LLInventoryRecentItemsPanel;
+static LLDefaultChildRegistry::Register<LLInventoryRecentItemsPanel> t_recent_inventory_panel("recent_inventory_panel");
+
+static const LLRecentInventoryBridgeBuilder RECENT_ITEMS_BUILDER;
+class LLInventoryRecentItemsPanel : public LLInventoryPanel
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params>
+ {};
+
+protected:
+ LLInventoryRecentItemsPanel (const Params&);
+ friend class LLUICtrlFactory;
+};
+
+LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params)
+: LLInventoryPanel(params)
+{
+ // replace bridge builder to have necessary View bridges.
+ mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER;
+}
+
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 0ba373c51b..a84280c213 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -167,7 +167,7 @@ BOOL LLPanelMainInventory::postBuild()
// Now load the stored settings from disk, if available.
std::ostringstream filterSaveName;
filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME);
- llinfos << "LLPanelMainInventory::init: reading from " << filterSaveName << llendl;
+ llinfos << "LLPanelMainInventory::init: reading from " << filterSaveName.str() << llendl;
llifstream file(filterSaveName.str());
LLSD savedFilterState;
if (file.is_open())
@@ -492,6 +492,10 @@ void LLPanelMainInventory::onFilterSelected()
{
return;
}
+
+ BOOL recent_active = ("Recent Items" == mActivePanel->getName());
+ childSetVisible("add_btn_panel", !recent_active);
+
setFilterSubString(mFilterSubString);
LLInventoryFilter* filter = mActivePanel->getFilter();
LLFloaterInventoryFinder *finder = getFinder();
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index 59c1fb4f3c..e36e63521e 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -77,6 +77,7 @@ LLPanelOutfitsInventory::LLPanelOutfitsInventory() :
{
mSavedFolderState = new LLSaveFolderState();
mSavedFolderState->setApply(FALSE);
+ gAgentWearables.addLoadedCallback(boost::bind(&LLPanelOutfitsInventory::onWearablesLoaded, this));
}
LLPanelOutfitsInventory::~LLPanelOutfitsInventory()
@@ -190,6 +191,7 @@ void LLPanelOutfitsInventory::onWearButtonClick()
if (!isCOFPanelActive())
{
mMyOutfitsPanel->performAction("replaceoutfit");
+ setWearablesLoading(true);
}
else
{
@@ -642,3 +644,19 @@ BOOL LLPanelOutfitsInventory::isCOFPanelActive() const
{
return (childGetVisibleTab("appearance_tabs")->getName() == COF_TAB_NAME);
}
+
+void LLPanelOutfitsInventory::setWearablesLoading(bool val)
+{
+ mListCommands->childSetEnabled("wear_btn", !val);
+
+ llassert(mParent);
+ if (mParent)
+ {
+ mParent->setWearablesLoading(val);
+ }
+}
+
+void LLPanelOutfitsInventory::onWearablesLoaded()
+{
+ setWearablesLoading(false);
+}
diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h
index 975d99f834..6b4d1dbd84 100644
--- a/indra/newview/llpaneloutfitsinventory.h
+++ b/indra/newview/llpaneloutfitsinventory.h
@@ -123,6 +123,8 @@ protected:
void onCustomAction(const LLSD& command_name);
bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept);
bool hasItemsSelected();
+ void setWearablesLoading(bool val);
+ void onWearablesLoaded();
private:
LLPanel* mListCommands;
LLMenuGL* mMenuGearDefault;
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index a058548459..8c908449a0 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -719,8 +719,10 @@ void LLParticipantList::LLParticipantListMenu::toggleMute(const LLSD& userdata,
{
return;
}
+ LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(mParent.mAvatarList->getItemByValue(speaker_id));
+ if (NULL == item) return;
- name = speakerp->mDisplayName;
+ name = item->getAvatarName();
LLMute::EType mute_type;
switch (speakerp->mType)
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 08098e2adb..18f12955ce 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -439,3 +439,9 @@ void LLSidepanelAppearance::inventoryFetched()
{
mNewOutfitBtn->setEnabled(true);
}
+
+void LLSidepanelAppearance::setWearablesLoading(bool val)
+{
+ childSetVisible("wearables_loading_indicator", val);
+ childSetVisible("edit_outfit_btn", !val);
+}
diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h
index 0a2d882a0b..2900831099 100644
--- a/indra/newview/llsidepanelappearance.h
+++ b/indra/newview/llsidepanelappearance.h
@@ -65,6 +65,7 @@ public:
void showOutfitsInventoryPanel();
void showOutfitEditPanel();
+ void setWearablesLoading(bool val);
private:
void onFilterEdit(const std::string& search_string);
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 3d447dd411..7fa04ce574 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -166,6 +166,9 @@ public:
mGetReason = reason;
}
+ void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;}
+ bool getCanUseHTTP()const {return mCanUseHTTP ;}
+
protected:
LLTextureFetchWorker(LLTextureFetch* fetcher, const std::string& url, const LLUUID& id, const LLHost& host,
F32 priority, S32 discard, S32 size);
@@ -247,15 +250,16 @@ private:
S32 mRequestedSize;
S32 mDesiredSize;
S32 mFileSize;
- S32 mCachedSize;
- BOOL mLoaded;
+ S32 mCachedSize;
e_request_state mSentRequest;
handle_t mDecodeHandle;
+ BOOL mLoaded;
BOOL mDecoded;
BOOL mWritten;
BOOL mNeedsAux;
BOOL mHaveAllData;
BOOL mInLocalCache;
+ bool mCanUseHTTP ;
S32 mHTTPFailCount;
S32 mRetryAttempt;
S32 mActiveCount;
@@ -411,6 +415,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mNeedsAux(FALSE),
mHaveAllData(FALSE),
mInLocalCache(FALSE),
+ mCanUseHTTP(true),
mHTTPFailCount(0),
mRetryAttempt(0),
mActiveCount(0),
@@ -640,11 +645,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
return false;
}
mFileSize = 0;
- mLoaded = FALSE;
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
+ mLoaded = FALSE;
if (mUrl.compare(0, 7, "file://") == 0)
{
+ setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
+
// read file from local disk
std::string filename = mUrl.substr(7, std::string::npos);
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
@@ -653,11 +659,13 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
else if (mUrl.empty())
{
+ setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
+
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority,
offset, size, responder);
}
- else
+ else if(mCanUseHTTP)
{
if (!(mUrl.compare(0, 7, "http://") == 0))
{
@@ -667,6 +675,11 @@ bool LLTextureFetchWorker::doWork(S32 param)
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
mState = SEND_HTTP_REQ;
}
+ else
+ {
+ setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
+ mState = LOAD_FROM_NETWORK;
+ }
}
if (mLoaded)
@@ -727,7 +740,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
static LLCachedControl<bool> use_http(gSavedSettings,"ImagePipelineUseHTTP");
// if (mHost != LLHost::invalid) get_url = false;
- if ( use_http && mUrl.empty())//get http url.
+ if ( use_http && mCanUseHTTP && mUrl.empty())//get http url.
{
LLViewerRegion* region = NULL;
if (mHost == LLHost::invalid)
@@ -750,7 +763,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
//llwarns << "Region not found for host: " << mHost << llendl;
}
}
- if (!mUrl.empty())
+ if (mCanUseHTTP && !mUrl.empty())
{
mState = LLTextureFetchWorker::SEND_HTTP_REQ;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
@@ -891,7 +904,13 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mGetStatus == HTTP_NOT_FOUND)
{
mHTTPFailCount = max_attempts = 1; // Don't retry
- llinfos << "Texture missing from server (404): " << mUrl << llendl;
+ //llinfos << "Texture missing from server (404): " << mUrl << llendl;
+
+ //roll back to try UDP
+ mState = INIT ;
+ mCanUseHTTP = false ;
+ setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
+ return false ;
}
else if (mGetStatus == HTTP_SERVICE_UNAVAILABLE)
{
@@ -1471,7 +1490,7 @@ LLTextureFetch::~LLTextureFetch()
}
bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
- S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux)
+ S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http)
{
if (mDebugPause)
{
@@ -1533,6 +1552,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
worker->mNeedsAux = needs_aux;
worker->setImagePriority(priority);
worker->setDesiredDiscard(desired_discard, desired_size);
+ worker->setCanUseHTTP(can_use_http) ;
if (!worker->haveWork())
{
worker->mState = LLTextureFetchWorker::INIT;
@@ -1555,6 +1575,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
worker->lockWorkMutex();
worker->mActiveCount++;
worker->mNeedsAux = needs_aux;
+ worker->setCanUseHTTP(can_use_http) ;
worker->unlockWorkMutex();
}
@@ -2215,7 +2236,7 @@ BOOL LLTextureFetch::isFromLocalCache(const LLUUID& id)
}
S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& requested_priority_p,
- U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p)
+ U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http)
{
S32 state = LLTextureFetchWorker::INVALID;
F32 data_progress = 0.0f;
@@ -2253,6 +2274,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r
requested_priority = worker->mImagePriority;
}
fetch_priority = worker->getPriority();
+ can_use_http = worker->getCanUseHTTP() ;
worker->unlockWorkMutex();
}
data_progress_p = data_progress;
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index ef2ec520bf..634e590fe0 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -62,7 +62,7 @@ public:
void shutDownImageDecodeThread() ; //called in the main thread after the ImageDecodeThread shuts down.
bool createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
- S32 w, S32 h, S32 c, S32 discard, bool needs_aux);
+ S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http);
void deleteRequest(const LLUUID& id, bool cancel);
bool getRequestFinished(const LLUUID& id, S32& discard_level,
LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux);
@@ -77,7 +77,7 @@ public:
// Debug
BOOL isFromLocalCache(const LLUUID& id);
S32 getFetchState(const LLUUID& id, F32& decode_progress_p, F32& requested_priority_p,
- U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p);
+ U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http);
void dump();
S32 getNumRequests() ;
S32 getNumHTTPRequests() ;
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index b39ee8b2e0..ed3d6a0464 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -587,7 +587,7 @@ bool LLViewerInventoryCategory::fetch()
std::string url = gAgent.getRegion()->getCapability("WebFetchInventoryDescendents");
if (!url.empty()) //Capability found. Build up LLSD and use it.
{
- LLInventoryModelBackgroundFetch::instance().start(mUUID);
+ LLInventoryModelBackgroundFetch::instance().start(mUUID, false);
}
else
{ //Deprecated, but if we don't have a capability, use the old system.
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index c883087cf2..d925ab0d90 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -492,6 +492,7 @@ void LLViewerTexture::init(bool firstinit)
mTextureState = NO_DELETE ;
mDontDiscard = FALSE;
+ mCanResetMaxVirtualSize = true ;
mMaxVirtualSize = 0.f;
mNeedsGLTexture = FALSE ;
mNeedsResetMaxVirtualSize = FALSE ;
@@ -540,6 +541,11 @@ void LLViewerTexture::setBoostLevel(S32 level)
if(mBoostLevel != LLViewerTexture::BOOST_NONE)
{
setNoDelete() ;
+
+ if(LLViewerTexture::BOOST_AVATAR_BAKED_SELF == mBoostLevel || LLViewerTexture::BOOST_AVATAR_BAKED == mBoostLevel)
+ {
+ mCanResetMaxVirtualSize = false ;
+ }
}
if(gAuditTexture)
{
@@ -613,7 +619,7 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co
void LLViewerTexture::resetTextureStats()
{
- mMaxVirtualSize = 0.0f;
+ mMaxVirtualSize = 0.0f ;
mAdditionalDecodePriority = 0.f ;
mNeedsResetMaxVirtualSize = FALSE ;
}
@@ -1071,6 +1077,7 @@ void LLViewerFetchedTexture::init(bool firstinit)
mRequestedDiscardLevel = -1;
mRequestedDownloadPriority = 0.f;
mFullyLoaded = FALSE;
+ mCanUseHTTP = true ;
mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
mMinDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
@@ -1665,7 +1672,11 @@ void LLViewerFetchedTexture::updateVirtualSize()
setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
}
}
- mNeedsResetMaxVirtualSize = TRUE ;
+
+ if(mCanResetMaxVirtualSize)
+ {
+ mNeedsResetMaxVirtualSize = TRUE ;
+ }
reorganizeFaceList() ;
reorganizeVolumeList();
}
@@ -1746,7 +1757,7 @@ bool LLViewerFetchedTexture::updateFetch()
else
{
mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
- mFetchPriority, mFetchDeltaTime, mRequestDeltaTime);
+ mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
}
// We may have data ready regardless of whether or not we are finished (e.g. waiting on write)
@@ -1886,7 +1897,7 @@ bool LLViewerFetchedTexture::updateFetch()
// bypass texturefetch directly by pulling from LLTextureCache
bool fetch_request_created = false;
fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mUrl, getID(),getTargetHost(), decode_priority,
- w, h, c, desired_discard, needsAux());
+ w, h, c, desired_discard, needsAux(), mCanUseHTTP);
if (fetch_request_created)
{
@@ -1894,7 +1905,7 @@ bool LLViewerFetchedTexture::updateFetch()
mIsFetching = TRUE;
mRequestedDiscardLevel = desired_discard;
mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
- mFetchPriority, mFetchDeltaTime, mRequestDeltaTime);
+ mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
}
// if createRequest() failed, we're finishing up a request for this UUID,
@@ -3291,7 +3302,10 @@ F32 LLViewerMediaTexture::getMaxVirtualSize()
}
}
- mNeedsResetMaxVirtualSize = TRUE ;
+ if(mCanResetMaxVirtualSize)
+ {
+ mNeedsResetMaxVirtualSize = TRUE ;
+ }
reorganizeFaceList() ;
reorganizeVolumeList();
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index a09a711cc7..74c46f3070 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -263,6 +263,7 @@ protected:
S32 mFullHeight;
BOOL mUseMipMaps ;
S8 mComponents;
+ bool mCanResetMaxVirtualSize;
mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need?
mutable S8 mNeedsGLTexture;
mutable BOOL mNeedsResetMaxVirtualSize ;
@@ -456,6 +457,8 @@ public:
BOOL isFullyLoaded() const;
BOOL hasFetcher() const { return mHasFetcher;}
+ void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;}
+
protected:
/*virtual*/ void switchToCachedImage();
S32 getCurrentDiscardLevelForFetching() ;
@@ -505,6 +508,7 @@ protected:
S8 mIsRawImageValid;
S8 mHasFetcher; // We've made a fecth request
S8 mIsFetching; // Fetch request is active
+ bool mCanUseHTTP ; //This texture can be fetched through http if true.
mutable S8 mIsMissingAsset; // True if we know that there is no image asset with this image id in the database.
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index bef1d63fcf..9ff871370d 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -102,8 +102,6 @@
#include <boost/lexical_cast.hpp>
-#define DISPLAY_AVATAR_LOAD_TIMES
-
using namespace LLVOAvatarDefines;
//-----------------------------------------------------------------------------
@@ -4045,6 +4043,7 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel
{
mMaxPixelArea = llmax(pixel_area, mMaxPixelArea);
mMinPixelArea = llmin(pixel_area, mMinPixelArea);
+ imagep->resetTextureStats();
imagep->addTextureStats(pixel_area / texel_area_ratio);
imagep->setBoostLevel(boost_level);
}
@@ -5316,6 +5315,14 @@ LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* vi
{
S32 attachmentID = ATTACHMENT_ID_FROM_STATE(viewer_object->getState());
+ // This should never happen unless the server didn't process the attachment point
+ // correctly, but putting this check in here to be safe.
+ if (attachmentID & ATTACHMENT_ADD)
+ {
+ llwarns << "Got an attachment with ATTACHMENT_ADD mask, removing ( attach pt:" << attachmentID << " )" << llendl;
+ attachmentID &= ~ATTACHMENT_ADD;
+ }
+
LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL);
if (!attachment)
@@ -5727,16 +5734,17 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > PAUSE);
-#ifdef DISPLAY_AVATAR_LOAD_TIMES
- if (!mPreviousFullyLoaded && !loading && mFullyLoaded)
+ if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
{
- llinfos << "Avatar '" << getFullname() << "' resolved in " << mRuthDebugTimer.getElapsedTimeF32() << " seconds." << llendl;
- LLSD args;
- args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32());
- args["NAME"] = getFullname();
- LLNotificationsUtil::add("AvatarRezNotification",args);
+ if (!mPreviousFullyLoaded && !loading && mFullyLoaded)
+ {
+ llinfos << "Avatar '" << getFullname() << "' resolved in " << mRuthDebugTimer.getElapsedTimeF32() << " seconds." << llendl;
+ LLSD args;
+ args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32());
+ args["NAME"] = getFullname();
+ LLNotificationsUtil::add("AvatarRezNotification",args);
+ }
}
-#endif
// did our loading state "change" from last call?
const S32 UPDATE_RATE = 30;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 4fbc6bb5da..086c2f702c 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -266,7 +266,7 @@ BOOL LLPipeline::sRenderParticleBeacons = FALSE;
BOOL LLPipeline::sRenderSoundBeacons = FALSE;
BOOL LLPipeline::sRenderBeacons = FALSE;
BOOL LLPipeline::sRenderHighlight = TRUE;
-BOOL LLPipeline::sForceOldBakedUpload = FALSE;
+BOOL LLPipeline::sForceOldBakedUpload = TRUE;
S32 LLPipeline::sUseOcclusion = 0;
BOOL LLPipeline::sDelayVBUpdate = TRUE;
BOOL LLPipeline::sAutoMaskAlphaDeferred = TRUE;
diff --git a/indra/newview/skins/default/xui/en/menu_participant_list.xml b/indra/newview/skins/default/xui/en/menu_participant_list.xml
index 2515b60868..6a90e92eca 100644
--- a/indra/newview/skins/default/xui/en/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/en/menu_participant_list.xml
@@ -6,31 +6,31 @@
label="Sort by Name"
layout="topleft"
name="SortByName">
- <menu_item_check.on_click
- function="ParticipantList.Sort"
- parameter="sort_by_name" />
- <menu_item_check.on_check
+ <on_check
function="ParticipantList.CheckItem"
parameter="is_sorted_by_name" />
+ <on_click
+ function="ParticipantList.Sort"
+ parameter="sort_by_name" />
</menu_item_check>
<menu_item_check
label="Sort by Recent Speakers"
layout="topleft"
name="SortByRecentSpeakers">
- <menu_item_check.on_click
- function="ParticipantList.Sort"
- parameter="sort_by_recent_speakers" />
- <menu_item_check.on_check
+ <on_check
function="ParticipantList.CheckItem"
parameter="is_sorted_by_recent_speakers" />
+ <on_click
+ function="ParticipantList.Sort"
+ parameter="sort_by_recent_speakers" />
</menu_item_check>
<menu_item_call
label="View Profile"
layout="topleft"
name="View Profile">
- <menu_item_call.on_click
+ <on_click
function="Avatar.Profile" />
- <menu_item_call.on_enable
+ <on_enable
function="ParticipantList.EnableItem"
parameter="can_view_profile" />
</menu_item_call>
@@ -38,9 +38,9 @@
label="Add Friend"
layout="topleft"
name="Add Friend">
- <menu_item_call.on_click
+ <on_click
function="Avatar.AddFriend" />
- <menu_item_call.on_enable
+ <on_enable
function="ParticipantList.EnableItem"
parameter="can_add" />
</menu_item_call>
@@ -48,9 +48,9 @@
label="IM"
layout="topleft"
name="IM">
- <menu_item_call.on_click
+ <on_click
function="Avatar.IM" />
- <menu_item_call.on_enable
+ <on_enable
function="ParticipantList.EnableItem"
parameter="can_im" />
</menu_item_call>
@@ -58,20 +58,19 @@
label="Call"
layout="topleft"
name="Call">
- <menu_item_call.on_click
+ <on_click
function="Avatar.Call" />
- <menu_item_call.on_enable
+ <on_enable
function="ParticipantList.EnableItem"
parameter="can_call" />
</menu_item_call>
<menu_item_call
- enabled="true"
label="Share"
layout="topleft"
name="Share">
- <menu_item_call.on_click
+ <on_click
function="Avatar.Share" />
- <menu_item_call.on_enable
+ <on_enable
function="ParticipantList.EnableItem"
parameter="can_share" />
</menu_item_call>
@@ -79,37 +78,38 @@
label="Pay"
layout="topleft"
name="Pay">
- <menu_item_call.on_click
+ <on_click
function="Avatar.Pay" />
- <menu_item_call.on_enable
+ <on_enable
function="ParticipantList.EnableItem"
parameter="can_pay" />
</menu_item_call>
<menu_item_separator
- layout="topleft"
- name="View Icons Separator" />
+ layout="topleft"
+ name="View Icons Separator" />
<menu_item_check
- label="View People Icons"
- name="View Icons">
- <on_click
- function="ToggleControl"
- parameter="ParticipantListShowIcons"/>
- <on_check
- function="CheckControl"
- parameter="ParticipantListShowIcons" />
+ label="View People Icons"
+ layout="topleft"
+ name="View Icons">
+ <on_check
+ function="CheckControl"
+ parameter="ParticipantListShowIcons" />
+ <on_click
+ function="ToggleControl"
+ parameter="ParticipantListShowIcons" />
</menu_item_check>
<menu_item_separator
- layout="topleft" />
+ layout="topleft" />
<menu_item_check
label="Block Voice"
layout="topleft"
name="Block/Unblock">
- <menu_item_check.on_click
- function="Avatar.BlockUnblock" />
- <menu_item_check.on_check
+ <on_check
function="ParticipantList.CheckItem"
parameter="is_blocked" />
- <menu_item_check.on_enable
+ <on_click
+ function="Avatar.BlockUnblock" />
+ <on_enable
function="ParticipantList.EnableItem"
parameter="can_block" />
</menu_item_check>
@@ -126,71 +126,71 @@
function="ParticipantList.EnableItem"
parameter="can_mute_text" />
</menu_item_check>
- <menu_item_separator
- layout="topleft" />
+ <menu_item_separator
+ layout="topleft" />
<context_menu
label="Moderator Options &gt;"
layout="topleft"
- name="Moderator Options" >
- <menu_item_check
- label="Allow text chat"
- layout="topleft"
- name="AllowTextChat">
- <on_check
- function="ParticipantList.CheckItem"
- parameter="is_allowed_text_chat" />
- <on_click
- function="ParticipantList.ToggleAllowTextChat" />
- <on_enable
- function="ParticipantList.EnableItem"
- parameter="can_allow_text_chat" />
- </menu_item_check>
- <menu_item_separator
- layout="topleft"
- name="moderate_voice_separator" />
- <menu_item_call
- label="Mute this participant"
- layout="topleft"
- name="ModerateVoiceMuteSelected">
- <on_click
- function="ParticipantList.ModerateVoice"
- parameter="selected" />
- <on_enable
- function="ParticipantList.EnableItem.Moderate"
- parameter="can_moderate_voice" />
- </menu_item_call>
- <menu_item_call
- label="Mute everyone else"
- layout="topleft"
- name="ModerateVoiceMuteOthers">
- <on_click
- function="ParticipantList.ModerateVoice"
- parameter="others" />
- <on_enable
- function="ParticipantList.EnableItem.Moderate"
- parameter="can_moderate_voice" />
- </menu_item_call>
- <menu_item_call
- label="Unmute this participant"
- layout="topleft"
- name="ModerateVoiceUnMuteSelected">
- <on_click
- function="ParticipantList.ModerateVoice"
- parameter="selected" />
- <on_enable
- function="ParticipantList.EnableItem.Moderate"
- parameter="can_moderate_voice" />
- </menu_item_call>
- <menu_item_call
- label="Unmute everyone else"
- layout="topleft"
- name="ModerateVoiceUnMuteOthers">
- <on_click
- function="ParticipantList.ModerateVoice"
- parameter="others" />
- <on_enable
- function="ParticipantList.EnableItem.Moderate"
- parameter="can_moderate_voice" />
- </menu_item_call>
+ name="Moderator Options">
+ <menu_item_check
+ label="Allow text chat"
+ layout="topleft"
+ name="AllowTextChat">
+ <on_check
+ function="ParticipantList.CheckItem"
+ parameter="is_allowed_text_chat" />
+ <on_click
+ function="ParticipantList.ToggleAllowTextChat" />
+ <on_enable
+ function="ParticipantList.EnableItem"
+ parameter="can_allow_text_chat" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft"
+ name="moderate_voice_separator" />
+ <menu_item_call
+ label="Mute this participant"
+ layout="topleft"
+ name="ModerateVoiceMuteSelected">
+ <on_click
+ function="ParticipantList.ModerateVoice"
+ parameter="selected" />
+ <on_enable
+ function="ParticipantList.EnableItem.Moderate"
+ parameter="can_moderate_voice" />
+ </menu_item_call>
+ <menu_item_call
+ label="Mute everyone else"
+ layout="topleft"
+ name="ModerateVoiceMuteOthers">
+ <on_click
+ function="ParticipantList.ModerateVoice"
+ parameter="others" />
+ <on_enable
+ function="ParticipantList.EnableItem.Moderate"
+ parameter="can_moderate_voice" />
+ </menu_item_call>
+ <menu_item_call
+ label="Unmute this participant"
+ layout="topleft"
+ name="ModerateVoiceUnMuteSelected">
+ <on_click
+ function="ParticipantList.ModerateVoice"
+ parameter="selected" />
+ <on_enable
+ function="ParticipantList.EnableItem.Moderate"
+ parameter="can_moderate_voice" />
+ </menu_item_call>
+ <menu_item_call
+ label="Unmute everyone else"
+ layout="topleft"
+ name="ModerateVoiceUnMuteOthers">
+ <on_click
+ function="ParticipantList.ModerateVoice"
+ parameter="others" />
+ <on_enable
+ function="ParticipantList.EnableItem.Moderate"
+ parameter="can_moderate_voice" />
+ </menu_item_call>
</context_menu>
</context_menu>
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 479629f6ea..19fe2ea874 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -210,9 +210,23 @@ Maximum 200 per group daily
<button
follows="left|top"
layout="topleft"
+ left="20"
+ top_delta="50"
+ height="23"
+ width="100"
+ name="open_inventory"
+ label="Inventory"
+ tool_tip="Open Inventory">
+ <button.init_callback
+ function="Button.SetFloaterToggle"
+ parameter="inventory"/>
+ </button>
+ <button
+ follows="left|top"
+ layout="topleft"
left="140"
name="remove_attachment"
- top_delta="50"
+ top_delta="0"
height="18"
image_selected="TrashItem_Press"
image_unselected="TrashItem_Off"
@@ -230,7 +244,7 @@ Maximum 200 per group daily
name="send_notice"
width="100" />
<group_drop_target
- height="95"
+ height="75"
top="160"
left="10"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
index 46625144e1..d65b86f007 100644
--- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
@@ -84,7 +84,7 @@
sort_order_setting="InventorySortOrder"
top="16"
width="288" />
- <inventory_panel
+ <recent_inventory_panel
bg_opaque_color="DkGray2"
bg_alpha_color="DkGray2"
background_visible="true"
@@ -100,62 +100,94 @@
name="Recent Items"
width="290" />
</tab_container>
-
- <panel
- background_visible="true"
+ <layout_stack
+ animate="false"
+ background_visible="true"
bevel_style="none"
+ border_size="0"
follows="left|right|bottom"
- height="27"
+ height="25"
layout="topleft"
- top_pad="-1"
+ orientation="horizontal"
+ top_pad="0"
left="10"
name="bottom_panel"
- width="310">
- <button
- follows="bottom|left"
- tool_tip="Show additional options"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- left="0"
- name="options_gear_btn"
- top="1"
- width="31" />
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="AddItem_Off"
- image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
- layout="topleft"
- left_pad="1"
- name="add_btn"
- tool_tip="Add new item"
- width="31" />
- <icon
- follows="bottom|left"
- height="25"
- image_name="Toolbar_Middle_Off"
- layout="topleft"
- left_pad="1"
- name="dummy_icon"
- width="209"
- />
- <dnd_button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Right_Over"
- image_overlay="TrashItem_Off"
- image_selected="Toolbar_Right_Selected"
- image_unselected="Toolbar_Right_Off"
- left_pad="1"
- layout="topleft"
- name="trash_btn"
- tool_tip="Remove selected item"
- width="31"/>
- </panel>
+ width="307">
+ <layout_panel
+ auto_resize="false"
+ height="25"
+ layout="topleft"
+ name="options_gear_btn_panel"
+ width="32">
+ <button
+ follows="bottom|left"
+ tool_tip="Show additional options"
+ height="25"
+ image_hover_unselected="Toolbar_Left_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Left_Selected"
+ image_unselected="Toolbar_Left_Off"
+ layout="topleft"
+ left="0"
+ name="options_gear_btn"
+ top="0"
+ width="31" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ height="25"
+ layout="topleft"
+ name="add_btn_panel"
+ width="32">
+ <button
+ follows="bottom|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="AddItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left="0"
+ name="add_btn"
+ tool_tip="Add new item"
+ top="0"
+ width="31" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="true"
+ height="25"
+ layout="topleft"
+ name="dummy_panel"
+ width="212">
+ <icon
+ follows="bottom|left|right"
+ height="25"
+ image_name="Toolbar_Middle_Off"
+ layout="topleft"
+ left="0"
+ top="0"
+ name="dummy_icon"
+ width="211" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ height="25"
+ layout="topleft"
+ name="trash_btn_panel"
+ width="31">
+ <dnd_button
+ follows="bottom|left"
+ height="25"
+ image_hover_unselected="Toolbar_Right_Over"
+ image_overlay="TrashItem_Off"
+ image_selected="Toolbar_Right_Selected"
+ image_unselected="Toolbar_Right_Off"
+ left="0"
+ layout="topleft"
+ name="trash_btn"
+ tool_tip="Remove selected item"
+ top="0"
+ width="31"/>
+ </layout_panel>
+ </layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
index e74c70789f..6a3c148456 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
@@ -94,6 +94,14 @@ width="333">
name="edit_outfit_btn"
top="7"
width="30" />
+ <loading_indicator
+ follows="left|top"
+ height="24"
+ layout="topleft"
+ left="268"
+ name="wearables_loading_indicator"
+ top="6"
+ width="24" />
</panel>
<filter_editor
height="23"