diff options
author | Tofu Linden <tofu.linden@lindenlab.com> | 2010-05-05 19:16:05 +0100 |
---|---|---|
committer | Tofu Linden <tofu.linden@lindenlab.com> | 2010-05-05 19:16:05 +0100 |
commit | 068c404e23ac939879293494ed9d1912c7896e24 (patch) | |
tree | 5ffb18c75b2bd0fbd620ff62c5d66ba54a972ef0 /indra | |
parent | f07b8c194447be4753512716402993888b2ed98c (diff) | |
parent | f290e9e851e1af694cd8df86e171b79ed4186e90 (diff) |
merge from viewer-public
Diffstat (limited to 'indra')
32 files changed, 725 insertions, 338 deletions
diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp index 3ac50832fd..a29e9a348e 100644 --- a/indra/llcommon/llworkerthread.cpp +++ b/indra/llcommon/llworkerthread.cpp @@ -1,25 +1,31 @@ /** * @file llworkerthread.cpp * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ 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 d62874d793..6c80275713 100644 --- a/indra/llui/llfiltereditor.cpp +++ b/indra/llui/llfiltereditor.cpp @@ -2,25 +2,31 @@ * @file llfiltereditor.cpp * @brief LLFilterEditor implementation * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ 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 f148eaa918..634e590fe0 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -2,25 +2,31 @@ * @file lltexturefetch.h * @brief Object for managing texture fetches. * - * $LicenseInfo:firstyear=2000&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ @@ -89,8 +95,7 @@ protected: void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel); void addToHTTPQueue(const LLUUID& id); void removeFromHTTPQueue(const LLUUID& id); - bool isHTTPThrottled(S32 requested_size); - void clearHTTPThrottleFlag(); + S32 getHTTPQueueSize() { return getNumHTTPRequests(); } void removeRequest(LLTextureFetchWorker* worker, bool cancel); // Called from worker thread (during doWork) void processCurlRequests(); @@ -129,16 +134,6 @@ private: F32 mTextureBandwidth; F32 mMaxBandwidth; LLTextureInfo mTextureInfo; - - enum - { - SMALL_TEXTURE = 0 , //size <= 64 * 64 - MEDIUM_TEXTURE, //size <= 256 * 256 - LARGE_TEXTURE, //size > 256 * 256 - DUMMY, - TOTAL_TEXTURE_TYPES - }; - BOOL mHTTPThrottleFlag[TOTAL_TEXTURE_TYPES]; }; #endif // LL_LLTEXTUREFETCH_H 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 361f56e02f..74c46f3070 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -166,7 +166,6 @@ public: void addTextureStats(F32 virtual_size, BOOL needs_gltexture = TRUE) const; void resetTextureStats(); - void setResetMaxVirtualSizeFlag(bool flag) ; virtual F32 getMaxVirtualSize() ; @@ -294,8 +293,8 @@ protected: INACTIVE, //not be used for the last certain period (i.e., 30 seconds). ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds). NO_DELETE = 99 //stay in memory, can not be removed. - } LLGLTextureState; - LLGLTextureState mTextureState ; + } LLGLTexureState; + LLGLTexureState mTextureState ; public: static const U32 sCurrentFileVersion; 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 >" 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" |