diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index d78f27bfa7..a88471c3ea 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -194,7 +194,8 @@ LLFolderView::LLFolderView(const Params& p) mShowItemLinkOverlays(p.show_item_link_overlays), mViewModel(p.view_model), mGroupedItemModel(p.grouped_item_model), - mForceArrange(false) + mForceArrange(false), + mSingleFolderMode(false) { LLPanel* panel = p.parent_panel; mParentPanel = panel->getHandle(); @@ -716,11 +717,18 @@ void LLFolderView::draw() } } - if (mRenameItem && mRenamer && mRenamer->getVisible() && !getVisibleRect().overlaps(mRenamer->getRect())) + if (mRenameItem + && mRenamer + && mRenamer->getVisible()) { - // renamer is not connected to the item we are renaming in any form so manage it manually - // TODO: consider stopping on any scroll action instead of when out of visible area - finishRenamingItem(); + LLRect renamer_rect; + localRectToOtherView(mRenamer->getRect(), &renamer_rect, mScrollContainer); + if (!mScrollContainer->getRect().overlaps(renamer_rect)) + { + // renamer is not connected to the item we are renaming in any form so manage it manually + // TODO: consider stopping on any scroll action instead of when out of visible area + finishRenamingItem(); + } } // skip over LLFolderViewFolder::draw since we don't want the folder icon, label, @@ -855,9 +863,12 @@ void LLFolderView::autoOpenItem( LLFolderViewFolder* item ) mAutoOpenItems.push(item); item->setOpen(TRUE); + if(!item->isSingleFolderMode()) + { LLRect content_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect()); LLRect constraint_rect(0,content_rect.getHeight(), content_rect.getWidth(), 0); scrollToShowItem(item, constraint_rect); + } } void LLFolderView::closeAutoOpenedFolders() @@ -1561,8 +1572,8 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask ) } } bool hide_folder_menu = mSuppressFolderMenu && isFolderSelected(); - if (menu && (handled - && ( count > 0 && (hasVisibleChildren()) )) && // show menu only if selected items are visible + if (menu && (mSingleFolderMode || (handled + && ( count > 0 && (hasVisibleChildren()) ))) && // show menu only if selected items are visible !hide_folder_menu) { if (mCallbackRegistrar) @@ -2004,6 +2015,11 @@ void LLFolderView::updateMenuOptions(LLMenuGL* menu) flags = multi_select_flag; } + if(mSingleFolderMode && (mSelectedItems.size() == 0)) + { + buildContextMenu(*menu, flags); + } + // This adds a check for restrictions based on the entire // selection set - for example, any one wearable may not push you // over the limit, but all wearables together still might. @@ -2160,7 +2176,7 @@ LLFolderViewItem* LLFolderView::getNextUnselectedItem() return new_selection; } -S32 LLFolderView::getItemHeight() +S32 LLFolderView::getItemHeight() const { if(!hasVisibleChildren()) { diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index f2b1eb18ec..658dfd4dc4 100644 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -127,6 +127,9 @@ public: bool getAllowMultiSelect() { return mAllowMultiSelect; } bool getAllowDrag() { return mAllowDrag; } + void setSingleFolderMode(bool is_single_mode) { mSingleFolderMode = is_single_mode; } + bool isSingleFolderMode() { return mSingleFolderMode; } + // Close all folders in the view void closeAllFolders(); void openTopLevelFolders(); @@ -136,7 +139,7 @@ public: // Find width and height of this object and its children. Also // makes sure that this view and its children are the right size. virtual S32 arrange( S32* width, S32* height ); - virtual S32 getItemHeight(); + virtual S32 getItemHeight() const; void arrangeAll() { mArrangeGeneration++; } S32 getArrangeGeneration() { return mArrangeGeneration; } @@ -305,7 +308,8 @@ protected: mShowItemLinkOverlays, mShowSelectionContext, mShowSingleSelection, - mSuppressFolderMenu; + mSuppressFolderMenu, + mSingleFolderMode; // Renaming variables and methods LLFolderViewItem* mRenameItem; // The item currently being renamed diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index b06a3c6979..7456846aa4 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -453,7 +453,7 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height ) return *height; } -S32 LLFolderViewItem::getItemHeight() +S32 LLFolderViewItem::getItemHeight() const { return mItemHeight; } @@ -1459,7 +1459,7 @@ BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem child_selected = TRUE; } } - if(openitem && child_selected) + if(openitem && child_selected && !mSingleFolderMode) { setOpenArrangeRecursively(TRUE); } diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index 4aa3f130a9..20009c531f 100644 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -188,7 +188,7 @@ public: // Finds width and height of this object and it's children. Also // makes sure that this view and it's children are the right size. virtual S32 arrange( S32* width, S32* height ); - virtual S32 getItemHeight(); + virtual S32 getItemHeight() const; virtual S32 getLabelXPos(); S32 getIconPad(); S32 getTextPad(); @@ -227,9 +227,9 @@ public: void setIsCurSelection(BOOL select) { mIsCurSelection = select; } - BOOL getIsCurSelection() { return mIsCurSelection; } + BOOL getIsCurSelection() const { return mIsCurSelection; } - BOOL hasVisibleChildren() { return mHasVisibleChildren; } + BOOL hasVisibleChildren() const { return mHasVisibleChildren; } // true if object can't have children virtual bool isFolderComplete() { return true; } @@ -278,7 +278,7 @@ public: virtual LLFolderView* getRoot(); virtual const LLFolderView* getRoot() const; BOOL isDescendantOf( const LLFolderViewFolder* potential_ancestor ); - S32 getIndentation() { return mIndentation; } + S32 getIndentation() const { return mIndentation; } virtual BOOL passedFilter(S32 filter_generation = -1); virtual BOOL isPotentiallyVisible(S32 filter_generation = -1); diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 6828498f52..de5de31c60 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -32,11 +32,12 @@ #include "llappviewer.h" #include "llcallbacklist.h" #include "llinventorymodel.h" +#include "llinventoryobserver.h" +#include "llnotificationsutil.h" #include "llsdutil.h" #include "llviewerregion.h" #include "llvoavatar.h" #include "llvoavatarself.h" -#include "llinventoryobserver.h" #include "llviewercontrol.h" #include "llviewernetwork.h" @@ -898,11 +899,21 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht } } } - else if (status.getType() == 403) + else if (status == LLCore::HttpStatus(HTTP_FORBIDDEN) /*403*/) { if (type == FETCHCATEGORYCHILDREN) { - LL_DEBUGS("Inventory") << "Fetch failed, content is over imit" << LL_ENDL; + if (body.has("depth") && body["depth"].asInteger() == 0) + { + // Can't fetch a single folder with depth 0, folder is too big. + LLNotificationsUtil::add("InventoryLimitReachedAIS"); + LL_WARNS("Inventory") << "Fetch failed, content is over limit, url: " << url << LL_ENDL; + } + else + { + // Result was too big, but situation is recoverable by requesting with lower depth + LL_DEBUGS("Inventory") << "Fetch failed, content is over limit, url: " << url << LL_ENDL; + } } } LL_WARNS("Inventory") << "Inventory error: " << status.toString() << LL_ENDL; diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 2c3c7780ff..b005939827 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -337,9 +337,6 @@ void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj) if (item) { setTitle(getString("title_item_thumbnail")); - // This floater probably shouldn't be possible to open - // for imcomplete items - llassert(item->isFinished()); icon_img = LLInventoryIcon::getIcon(item->getType(), item->getInventoryType(), item->getFlags(), FALSE); mRemoveImageBtn->setEnabled(thumbnail_id.notNull() && ((item->getActualType() != LLAssetType::AT_TEXTURE) || (item->getAssetUUID() != thumbnail_id))); @@ -472,6 +469,7 @@ void LLFloaterChangeItemThumbnail::onCopyToClipboard(void *userdata) LLInventoryObject* obj = self->getInventoryObject(); if (obj) { + LLClipboard::instance().reset(); LLClipboard::instance().addToClipboard(obj->getThumbnailUUID(), LLAssetType::AT_NONE); self->mPasteFromClipboardBtn->setEnabled(true); } @@ -544,6 +542,13 @@ void LLFloaterChangeItemThumbnail::onRemovalConfirmation(const LLSD& notificatio } } +struct ImageLoadedData +{ + LLUUID mThumbnailId; + LLUUID mObjectId; + LLHandle mFloaterHandle; +}; + void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id, bool silent) { LLPointer texturep = LLViewerTextureManager::getFetchedTexture(asset_id); @@ -558,11 +563,16 @@ void LLFloaterChangeItemThumbnail::assignAndValidateAsset(const LLUUID &asset_id // don't warn user multiple times if some textures took their time mExpectingAssetId = asset_id; } + ImageLoadedData *data = new ImageLoadedData(); + data->mObjectId = mItemId; + data->mThumbnailId = asset_id; + data->mFloaterHandle = getHandle(); + texturep->setLoadedCallback(onImageLoaded, MAX_DISCARD_LEVEL, // don't actually need max one, 3 or 4 should be enough FALSE, FALSE, - new LLHandle(getHandle()), + (void*)data, NULL, FALSE); } @@ -630,19 +640,21 @@ void LLFloaterChangeItemThumbnail::onImageLoaded( if (!final && success) return; //not done yet - LLHandle* handle = (LLHandle*)userdata; + ImageLoadedData* data = (ImageLoadedData*)userdata; - if (success && !handle->isDead()) + if (success) { - LLFloaterChangeItemThumbnail* self = static_cast(handle->get()); - if (self) + // Update the item, set it even if floater is dead + if (validateAsset(data->mThumbnailId)) { - LLUUID asset_id = src_vi->getID(); - if (validateAsset(asset_id)) - { - self->setThumbnailId(asset_id); - } - else if (self->mExpectingAssetId == asset_id) + setThumbnailId(data->mThumbnailId, data->mObjectId); + } + + // Update floater + if (!data->mFloaterHandle.isDead()) + { + LLFloaterChangeItemThumbnail* self = static_cast(data->mFloaterHandle.get()); + if (self && self->mExpectingAssetId == data->mThumbnailId) { LLNotificationsUtil::add("ThumbnailDimentionsLimit"); self->mExpectingAssetId = LLUUID::null; @@ -650,7 +662,7 @@ void LLFloaterChangeItemThumbnail::onImageLoaded( } } - delete handle; + delete data; } void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) @@ -739,8 +751,25 @@ void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID &new_thumbnail_id if (mTaskId.notNull()) { LL_ERRS() << "Not implemented yet" << LL_ENDL; + return; } - else if (obj->getThumbnailUUID() != new_thumbnail_id) + + setThumbnailId(new_thumbnail_id, mItemId, obj); +} + +void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID& new_thumbnail_id, const LLUUID& object_id) +{ + LLInventoryObject* obj = gInventory.getObject(object_id); + if (!obj) + { + return; + } + + setThumbnailId(new_thumbnail_id, object_id, obj); +} +void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID& new_thumbnail_id, const LLUUID& object_id, LLInventoryObject* obj) +{ + if (obj->getThumbnailUUID() != new_thumbnail_id) { LLSD updates; // At the moment server expects id as a string @@ -748,12 +777,12 @@ void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID &new_thumbnail_id LLViewerInventoryCategory* view_folder = dynamic_cast(obj); if (view_folder) { - update_inventory_category(mItemId, updates, NULL); + update_inventory_category(object_id, updates, NULL); } LLViewerInventoryItem* view_item = dynamic_cast(obj); if (view_item) { - update_inventory_item(mItemId, updates, NULL); + update_inventory_item(object_id, updates, NULL); } } } diff --git a/indra/newview/llfloaterchangeitemthumbnail.h b/indra/newview/llfloaterchangeitemthumbnail.h index 33bf2ecab5..de2a20bf2a 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.h +++ b/indra/newview/llfloaterchangeitemthumbnail.h @@ -95,6 +95,8 @@ private: void onTexturePickerCommit(LLUUID id); void setThumbnailId(const LLUUID &new_thumbnail_id); + static void setThumbnailId(const LLUUID& new_thumbnail_id, const LLUUID& object_id); + static void setThumbnailId(const LLUUID& new_thumbnail_id, const LLUUID& object_id, LLInventoryObject* obj); enum EToolTipState { diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index b3d649506d..ef2098852d 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -835,33 +835,22 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, menuentry_vec_t &disabled_items, U32 flags) { const LLInventoryObject *obj = getInventoryObject(); + bool single_folder_root = (mRoot == NULL); if (obj) { -// [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.0) items.push_back(std::string("Copy Separator")); - - items.push_back(std::string("Cut")); - if (!isItemMovable() || !isItemRemovable() || isLibraryItem()) - { - disabled_items.push_back(std::string("Cut")); - } - items.push_back(std::string("Copy")); +// [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.0) if (!isItemCopyable() && !isItemLinkable()) +// [/SL:KB] + //if (!isItemCopyable()) { disabled_items.push_back(std::string("Copy")); } -// [/SL:KB] - //items.push_back(std::string("Copy Separator")); - //items.push_back(std::string("Copy")); - //if (!isItemCopyable()) - //{ - // disabled_items.push_back(std::string("Copy")); - //} - if (isAgentInventory()) + if (isAgentInventory() && !single_folder_root) { items.push_back(std::string("New folder from selected")); items.push_back(std::string("Subfolder Separator")); @@ -895,7 +884,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, items.push_back(std::string("Find Links")); } - if (!isInboxFolder()) + if (!isInboxFolder() && !single_folder_root) { items.push_back(std::string("Rename")); // Locked folder @@ -931,13 +920,14 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, disabled_items.push_back(std::string("Copy Asset UUID")); } } -// [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.0) - //items.push_back(std::string("Cut")); - //if (!isItemMovable() || !isItemRemovable()) - //{ - // disabled_items.push_back(std::string("Cut")); - //} -// [/SL:KB] + + if(!single_folder_root) + { + items.push_back(std::string("Cut")); + if (!isItemMovable() || !isItemRemovable()) + { + disabled_items.push_back(std::string("Cut")); + } if (canListOnMarketplace() && !isMarketplaceListingsFolder() && !isInboxFolder()) { @@ -954,6 +944,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, } } } + } } } @@ -990,7 +981,10 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, items.push_back(std::string("Paste Separator")); - addDeleteContextMenuOptions(items, disabled_items); + if(!single_folder_root) + { + addDeleteContextMenuOptions(items, disabled_items); + } // Don't offer "Show in Main View" for folders opened in separate inventory views // as there are no tabs to switch to @@ -4881,7 +4875,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& // [/SL:KB] // Only enable calling-card related options for non-system folders. - if (!is_system_folder && is_agent_inventory) + if (!is_system_folder && is_agent_inventory && (mRoot != NULL)) { LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD); if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard)) @@ -4901,6 +4895,11 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& disabled_items.push_back(std::string("New folder from selected")); } + //skip the rest options in single-folder mode + if (mRoot == NULL) + { + return; + } if ((flags & ITEM_IN_MULTI_SELECTION) == 0) { diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 35e30c685c..19c1d0b823 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -124,7 +124,7 @@ public: virtual void move(LLFolderViewModelItem* new_parent_bridge) {} virtual bool isItemCopyable(bool can_copy_as_link = true) const { return false; } // [SL:KB] - Patch: Inventory-Links | Checked: 2013-09-19 (Catznip-3.6) - virtual bool isItemLinkable() const { return FALSE; } + virtual bool isItemLinkable() const { return false; } // [/SL:KB] virtual BOOL copyToClipboard() const; virtual BOOL cutToClipboard(); diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 4910eff01a..72a0eaba57 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -3518,6 +3518,14 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root if(!bridge) continue; bridge->performAction(model, action); } + if(root->isSingleFolderMode() && selected_items.empty()) + { + LLInvFVBridge* bridge = (LLInvFVBridge*)root->getViewModelItem(); + if(bridge) + { + bridge->performAction(model, action); + } + } } // Update the marketplace listings that have been affected by the operation diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp index f97cb9dbf4..2f9f594790 100644 --- a/indra/newview/llinventorygallery.cpp +++ b/indra/newview/llinventorygallery.cpp @@ -126,12 +126,15 @@ BOOL LLInventoryGallery::postBuild() mGalleryPanel = LLUICtrlFactory::create(params); mMessageTextBox = getChild("empty_txt"); mInventoryGalleryMenu = new LLInventoryGalleryContextMenu(this); + mRootGalleryMenu = new LLInventoryGalleryContextMenu(this); + mRootGalleryMenu->setRootFolder(true); return TRUE; } LLInventoryGallery::~LLInventoryGallery() { delete mInventoryGalleryMenu; + delete mRootGalleryMenu; delete mFilter; while (!mUnusedRowPanels.empty()) @@ -180,7 +183,8 @@ void LLInventoryGallery::setRootFolder(const LLUUID cat_id) void LLInventoryGallery::updateRootFolder() { - if (mIsInitialized) + llassert(mFolderID.notNull()); + if (mIsInitialized && mFolderID.notNull()) { S32 count = mItemsAddedCount; for (S32 i = count - 1; i >= 0; i--) @@ -200,6 +204,14 @@ void LLInventoryGallery::updateRootFolder() delete mCategoriesObserver; mCategoriesObserver = new LLInventoryCategoriesObserver(); + + if (gInventory.containsObserver(mThumbnailsObserver)) + { + gInventory.removeObserver(mThumbnailsObserver); + } + delete mThumbnailsObserver; + mThumbnailsObserver = new LLThumbnailsObserver(); + gInventory.addObserver(mThumbnailsObserver); } { mRootChangedSignal(); @@ -699,7 +711,11 @@ void LLInventoryGallery::updateAddedItem(LLUUID item_id) LL_WARNS("InventoryGallery") << "Failed to find item: " << item_id << LL_ENDL; return; } - + if(!mFilter->checkAgainstFilterThumbnails(item_id)) + { + mThumbnailsObserver->addSkippedItem(item_id, boost::bind(&LLInventoryGallery::onThumbnailAdded, this, item_id)); + return; + } std::string name = obj->getName(); LLUUID thumbnail_id = obj->getThumbnailUUID();; LLInventoryType::EType inventory_type(LLInventoryType::IT_CATEGORY); @@ -816,6 +832,36 @@ void LLInventoryGallery::updateItemThumbnail(LLUUID item_id) } } +void LLInventoryGallery::onThumbnailAdded(LLUUID item_id) +{ + if((mItemMap.count(item_id) == 0) && mFilter->checkAgainstFilterThumbnails(item_id)) + { + updateAddedItem(item_id); + reArrangeRows(); + } +} + +BOOL LLInventoryGallery::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + if(mItemMap[mSelectedItemID]) + { + mItemMap[mSelectedItemID]->setFocus(false); + } + clearSelection(); + BOOL res = LLPanel::handleRightMouseDown(x, y, mask); + if (mSelectedItemID.isNull()) + { + if (mInventoryGalleryMenu && mFolderID.notNull()) + { + uuid_vec_t selected_uuids; + selected_uuids.push_back(mFolderID); + mRootGalleryMenu->show(this, selected_uuids, x, y); + return TRUE; + } + } + return res; +} + void LLInventoryGallery::showContextMenu(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& item_id) { if (mInventoryGalleryMenu && item_id.notNull()) @@ -1525,9 +1571,33 @@ void LLInventoryGalleryItem::updateNameText() void LLThumbnailsObserver::changed(U32 mask) { - if (!mItemMap.size()) - return; std::vector deleted_ids; + for (item_map_t::iterator iter = mSkippedItems.begin(); + iter != mSkippedItems.end(); + ++iter) + { + const LLUUID& obj_id = (*iter).first; + LLItemData& data = (*iter).second; + + LLInventoryObject* obj = gInventory.getObject(obj_id); + if (!obj) + { + deleted_ids.push_back(obj_id); + continue; + } + + const LLUUID thumbnail_id = obj->getThumbnailUUID(); + if (data.mThumbnailID != thumbnail_id) + { + data.mThumbnailID = thumbnail_id; + data.mCallback(); + } + } + for (std::vector::iterator deleted_id = deleted_ids.begin(); deleted_id != deleted_ids.end(); ++deleted_id) + { + removeSkippedItem(*deleted_id); + } + deleted_ids.clear(); for (item_map_t::iterator iter = mItemMap.begin(); iter != mItemMap.end(); @@ -1569,11 +1639,25 @@ bool LLThumbnailsObserver::addItem(const LLUUID& obj_id, callback_t cb) return false; } +void LLThumbnailsObserver::addSkippedItem(const LLUUID& obj_id, callback_t cb) +{ + LLInventoryObject* obj = gInventory.getObject(obj_id); + if (obj) + { + mSkippedItems.insert(item_map_value_t(obj_id, LLItemData(obj_id, obj->getThumbnailUUID(), cb))); + } +} + void LLThumbnailsObserver::removeItem(const LLUUID& obj_id) { mItemMap.erase(obj_id); } +void LLThumbnailsObserver::removeSkippedItem(const LLUUID& obj_id) +{ + mSkippedItems.erase(obj_id); +} + //----------------------------- // Helper drag&drop functions //----------------------------- diff --git a/indra/newview/llinventorygallery.h b/indra/newview/llinventorygallery.h index f7065afdae..7e4ed9725b 100644 --- a/indra/newview/llinventorygallery.h +++ b/indra/newview/llinventorygallery.h @@ -78,6 +78,7 @@ public: void draw(); BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg); + BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); void setFilterSubString(const std::string& string); std::string getFilterSubString() { return mFilterSubString; } @@ -89,6 +90,7 @@ public: void updateRemovedItem(LLUUID item_id); void updateChangedItemName(LLUUID item_id, std::string name); void updateItemThumbnail(LLUUID item_id); + void onThumbnailAdded(LLUUID item_id); void updateWornItem(LLUUID item_id, bool is_worn); void updateMessageVisibility(); @@ -203,6 +205,7 @@ private: int mGalleryWidthFactor; LLInventoryGalleryContextMenu* mInventoryGalleryMenu; + LLInventoryGalleryContextMenu* mRootGalleryMenu; std::string mFilterSubString; LLInventoryFilter* mFilter; @@ -308,7 +311,9 @@ public: virtual void changed(U32 mask); bool addItem(const LLUUID& obj_id, callback_t cb); + void addSkippedItem(const LLUUID& obj_id, callback_t cb); void removeItem(const LLUUID& obj_id); + void removeSkippedItem(const LLUUID& obj_id); protected: @@ -328,6 +333,7 @@ protected: typedef std::map item_map_t; typedef item_map_t::value_type item_map_value_t; item_map_t mItemMap; + item_map_t mSkippedItems; }; class LLGalleryGestureObserver : public LLGestureManagerObserver diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp index 43ddf4da63..6dc749fab6 100644 --- a/indra/newview/llinventorygallerymenu.cpp +++ b/indra/newview/llinventorygallerymenu.cpp @@ -159,6 +159,8 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata, const LLU bool is_cut_mode = (LLClipboard::instance().isCutMode()); { + LLUUID dest = is_folder ? selected_id : obj->getParentUUID(); + std::vector objects; LLClipboard::instance().pasteFromClipboard(objects); for (std::vector::const_iterator iter = objects.begin(); iter != objects.end(); ++iter) @@ -174,11 +176,11 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata, const LLU { if(is_cut_mode) { - gInventory.changeCategoryParent(cat, selected_id, false); + gInventory.changeCategoryParent(cat, dest, false); } else { - copy_inventory_category(&gInventory, cat, selected_id); + copy_inventory_category(&gInventory, cat, dest); } } else @@ -188,13 +190,13 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata, const LLU { if(is_cut_mode) { - gInventory.changeItemParent(item, selected_id, false); + gInventory.changeItemParent(item, dest, false); } else { if (item->getIsLinkType()) { - link_inventory_object(selected_id, item_id, + link_inventory_object(dest, item_id, LLPointer(NULL)); } else @@ -203,7 +205,7 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata, const LLU gAgent.getID(), item->getPermissions().getOwner(), item->getUUID(), - selected_id, + dest, std::string(), LLPointer(NULL)); } @@ -264,7 +266,7 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata, const LLU { return; } - + LLUUID dest = is_folder ? selected_id : obj->getParentUUID(); std::vector objects; LLClipboard::instance().pasteFromClipboard(objects); for (std::vector::const_iterator iter = objects.begin(); @@ -274,7 +276,7 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata, const LLU const LLUUID &object_id = (*iter); if (LLConstPointer link_obj = gInventory.getObject(object_id)) { - link_inventory_object(selected_id, link_obj, LLPointer(NULL)); + link_inventory_object(dest, link_obj, LLPointer(NULL)); } } @@ -463,11 +465,14 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men if (is_folder) { - items.push_back(std::string("Copy Separator")); + if(!isRootFolder()) + { + items.push_back(std::string("Copy Separator")); - items.push_back(std::string("open_in_current_window")); - items.push_back(std::string("open_in_new_window")); - items.push_back(std::string("Open Folder Separator")); + items.push_back(std::string("open_in_current_window")); + items.push_back(std::string("open_in_new_window")); + items.push_back(std::string("Open Folder Separator")); + } } else { @@ -512,24 +517,34 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men { items.push_back(std::string("Share")); } + if (LLClipboard::instance().hasContents() && is_agent_inventory && !is_cof && !is_inbox_folder(selected_id)) + { + items.push_back(std::string("Paste")); + + static LLCachedControl inventory_linking(gSavedSettings, "InventoryLinking", true); + if (inventory_linking) + { + items.push_back(std::string("Paste As Link")); + } + } if (is_folder && is_agent_inventory) { if (!is_cof && (folder_type != LLFolderType::FT_OUTFIT) && !is_outfits && !is_inbox_folder(selected_id)) { - if (!gInventory.isObjectDescendentOf(selected_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD))) + if (!gInventory.isObjectDescendentOf(selected_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD)) && !isRootFolder()) { items.push_back(std::string("New Folder")); } items.push_back(std::string("upload_def")); } - if(is_outfits) + if(is_outfits && !isRootFolder()) { items.push_back(std::string("New Outfit")); } items.push_back(std::string("Subfolder Separator")); - if (!is_system_folder) + if (!is_system_folder && !isRootFolder()) { if(has_children && (folder_type != LLFolderType::FT_OUTFIT)) { @@ -542,21 +557,12 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men disabled_items.push_back(std::string("Delete")); disabled_items.push_back(std::string("Cut")); } + if(!is_inbox) { items.push_back(std::string("Rename")); } } - if (LLClipboard::instance().hasContents() && is_agent_inventory && !is_cof && !is_inbox_folder(selected_id)) - { - items.push_back(std::string("Paste")); - - static LLCachedControl inventory_linking(gSavedSettings, "InventoryLinking", true); - if (inventory_linking) - { - items.push_back(std::string("Paste As Link")); - } - } if(!is_system_folder) { items.push_back(std::string("Copy")); diff --git a/indra/newview/llinventorygallerymenu.h b/indra/newview/llinventorygallerymenu.h index 1768c07e6e..fd542e7d79 100644 --- a/indra/newview/llinventorygallerymenu.h +++ b/indra/newview/llinventorygallerymenu.h @@ -33,9 +33,13 @@ class LLInventoryGalleryContextMenu : public LLListContextMenu public: LLInventoryGalleryContextMenu(LLInventoryGallery* gallery) : LLListContextMenu(), - mGallery(gallery){} + mGallery(gallery), + mRootFolder(false){} /*virtual*/ LLContextMenu* createMenu(); + bool isRootFolder() { return mRootFolder; } + void setRootFolder(bool is_root) { mRootFolder = is_root; } + protected: //virtual void buildContextMenu(class LLMenuGL& menu, U32 flags); void updateMenuItemsVisibility(LLContextMenu* menu); @@ -50,6 +54,7 @@ private: bool checkContextMenuItem(const LLSD& userdata); LLInventoryGallery* mGallery; + bool mRootFolder; }; #endif diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index cd5a02d943..d36ad02b3c 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -34,6 +34,7 @@ #include "llinventorymodel.h" #include "llinventoryobserver.h" #include "llinventorypanel.h" +#include "llnotificationsutil.h" #include "llstartup.h" #include "llviewercontrol.h" #include "llviewerinventory.h" @@ -1116,6 +1117,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch() // *TODO: Think I'd like to get a shared pointer to this and share it // among all the folder requests. uuid_vec_t recursive_cats; + uuid_vec_t all_cats; // dupplicate avoidance LLSD folder_request_body; LLSD folder_request_body_lib; @@ -1147,25 +1149,28 @@ void LLInventoryModelBackgroundFetch::bulkFetch() { if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) { - LLSD folder_sd; - folder_sd["folder_id"] = cat->getUUID(); - folder_sd["owner_id"] = cat->getOwnerID(); - folder_sd["sort_order"] = LLSD::Integer(sort_order); - folder_sd["fetch_folders"] = LLSD::Boolean(true); //(LLSD::Boolean)sFullFetchStarted; - folder_sd["fetch_items"] = LLSD::Boolean(true); + if (std::find(all_cats.begin(), all_cats.end(), cat_id) == all_cats.end()) + { + LLSD folder_sd; + folder_sd["folder_id"] = cat->getUUID(); + folder_sd["owner_id"] = cat->getOwnerID(); + folder_sd["sort_order"] = LLSD::Integer(sort_order); + folder_sd["fetch_folders"] = LLSD::Boolean(TRUE); //(LLSD::Boolean)sFullFetchStarted; + folder_sd["fetch_items"] = LLSD::Boolean(TRUE); - // correct library owner for OpenSim (Rye) - // if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) - if (gInventory.getLibraryOwnerID() == cat->getOwnerID()) - // - { - folder_request_body_lib["folders"].append(folder_sd); + // correct library owner for OpenSim (Rye) + //if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) + if (gInventory.getLibraryOwnerID() == cat->getOwnerID()) + // + { + folder_request_body_lib["folders"].append(folder_sd); + } + else + { + folder_request_body["folders"].append(folder_sd); + } + folder_count++; } - else - { - folder_request_body["folders"].append(folder_sd); - } - folder_count++; } else { @@ -1189,6 +1194,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch() { recursive_cats.push_back(cat_id); } + all_cats.push_back(cat_id); } mFetchFolderQueue.pop_front(); @@ -1536,6 +1542,63 @@ void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::Http << LLCoreHttpUtil::responseToString(response) << "]" << LL_ENDL; // Could use a 404 test here to try to detect revoked caps... + + if(status == LLCore::HttpStatus(HTTP_FORBIDDEN)) + { + // Too large, split into two if possible + if (gDisconnected || LLApp::isExiting()) + { + return; + } + + const std::string url(gAgent.getRegionCapability("FetchInventoryDescendents2")); + if (url.empty()) + { + LL_WARNS(LOG_INV) << "Failed to get AIS2 cap" << LL_ENDL; + return; + } + + S32 size = mRequestSD["folders"].size(); + + if (size > 1) + { + // Can split, assume that this isn't the library + LLSD folders; + uuid_vec_t recursive_cats; + LLSD::array_iterator iter = mRequestSD["folders"].beginArray(); + LLSD::array_iterator end = mRequestSD["folders"].endArray(); + while (iter != end) + { + folders.append(*iter); + LLUUID fodler_id = iter->get("folder_id").asUUID(); + if (std::find(mRecursiveCatUUIDs.begin(), mRecursiveCatUUIDs.end(), fodler_id) != mRecursiveCatUUIDs.end()) + { + recursive_cats.push_back(fodler_id); + } + if (folders.size() == (S32)(size / 2)) + { + LLSD request_body; + request_body["folders"] = folders; + LLCore::HttpHandler::ptr_t handler(new BGFolderHttpHandler(request_body, recursive_cats)); + gInventory.requestPost(false, url, request_body, handler, "Inventory Folder"); + recursive_cats.clear(); + folders.clear(); + } + iter++; + } + + LLSD request_body; + request_body["folders"] = folders; + LLCore::HttpHandler::ptr_t handler(new BGFolderHttpHandler(request_body, recursive_cats)); + gInventory.requestPost(false, url, request_body, handler, "Inventory Folder"); + return; + } + else + { + // Can't split + LLNotificationsUtil::add("InventoryLimitReachedAIS"); + } + } // This was originally the request retry logic for the inventory // request which tested on HTTP_INTERNAL_ERROR status. This diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index eaf8f2bdf0..b703f15f2a 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -1405,10 +1405,18 @@ BOOL LLInventoryPanel::handleToolTip(S32 x, S32 y, MASK mask) params["inv_type"] = vm_item_p->getInventoryType(); params["thumbnail_id"] = vm_item_p->getThumbnailUUID(); params["item_id"] = vm_item_p->getUUID(); - + + // tooltip should only show over folder, but screen + // rect includes items under folder as well + LLRect actionable_rect = hover_item_p->calcScreenRect(); + if (hover_item_p->isOpen() && hover_item_p->hasVisibleChildren()) + { + actionable_rect.mBottom = actionable_rect.mTop - hover_item_p->getItemHeight(); + } + LLToolTipMgr::instance().show(LLToolTip::Params() .message(hover_item_p->getToolTip()) - .sticky_rect(hover_item_p->calcScreenRect()) + .sticky_rect(actionable_rect) .delay_time(LLView::getTooltipTimeout()) .create_callback(boost::bind(&LLInspectTextureUtil::createInventoryToolTip, _1)) .create_params(params)); @@ -2054,7 +2062,13 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L //if (main_inventory && main_inventory->isSingleFolderMode() // && use_main_panel) //{ - // main_inventory->toggleViewMode(); + // const LLInventoryObject *obj = gInventory.getObject(obj_id); + // if (obj) + // { + // main_inventory->setSingleFolderViewRoot(obj->getParentUUID(), false); + // main_inventory->setGallerySelection(obj_id); + // return; + // } //} if (!inventory_floater) { @@ -2066,7 +2080,13 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L LLPanelMainInventory* main_inventory = inventory_panel->getMainInventoryPanel(); if (main_inventory && main_inventory->isSingleFolderMode()) { - main_inventory->toggleViewMode(); + const LLInventoryObject *obj = gInventory.getObject(obj_id); + if (obj) + { + main_inventory->setSingleFolderViewRoot(obj->getParentUUID(), false); + main_inventory->setGallerySelection(obj_id); + return; + } } } // @@ -2360,6 +2380,7 @@ static LLDefaultChildRegistry::Register t_single_f LLInventorySingleFolderPanel::LLInventorySingleFolderPanel(const Params& params) : LLInventoryPanel(params) + , mExternalScroller(NULL) { mBuildChildrenViews = false; getFilter().setSingleFolderMode(true); @@ -2368,6 +2389,7 @@ LLInventorySingleFolderPanel::LLInventorySingleFolderPanel(const Params& params) mCommitCallbackRegistrar.add("Inventory.OpenSelectedFolder", boost::bind(&LLInventorySingleFolderPanel::openInCurrentWindow, this, _2)); mCommitCallbackRegistrar.replace("Inventory.DoCreate", boost::bind(&LLInventorySingleFolderPanel::doCreate, this, _2)); + mCommitCallbackRegistrar.replace("Inventory.Share", boost::bind(&LLInventorySingleFolderPanel::doShare, this)); } LLInventorySingleFolderPanel::~LLInventorySingleFolderPanel() @@ -2383,6 +2405,15 @@ void LLInventorySingleFolderPanel::setSelectCallback(const boost::functionsetScrollContainer(mExternalScroller); + } +} + void LLInventorySingleFolderPanel::initFromParams(const Params& p) { mFolderID = gInventory.getRootFolderID(); @@ -2390,6 +2421,7 @@ void LLInventorySingleFolderPanel::initFromParams(const Params& p) pane_params.open_first_folder = false; pane_params.start_folder.id = mFolderID; LLInventoryPanel::initFromParams(pane_params); + mFolderRoot.get()->setSingleFolderMode(true); } void LLInventorySingleFolderPanel::openInCurrentWindow(const LLSD& userdata) @@ -2471,7 +2503,7 @@ void LLInventorySingleFolderPanel::updateSingleFolderRoot() LLFolderView* folder_view = createFolderRoot(root_id); folder_view->setChildrenInited(false); mFolderRoot = folder_view->getHandle(); - + mFolderRoot.get()->setSingleFolderMode(true); addItemID(root_id, mFolderRoot.get()); LLRect scroller_view_rect = getRect(); @@ -2488,7 +2520,18 @@ void LLInventorySingleFolderPanel::updateSingleFolderRoot() mScroller = LLUICtrlFactory::create(scroller_params); addChild(mScroller); mScroller->addChild(mFolderRoot.get()); - mFolderRoot.get()->setScrollContainer(mScroller); + if (!mExternalScroller) + { + mFolderRoot.get()->setScrollContainer(mScroller); + } + else + { + // Hack to use exteranl scroll in combination view + // Todo: find a way to avoid this + // ideally combination view should be own inventory panel + // instead of piggy backing on two different ones + mFolderRoot.get()->setScrollContainer(mExternalScroller); + } mFolderRoot.get()->setFollowsAll(); mFolderRoot.get()->addChild(mFolderRoot.get()->mStatusTextBox); @@ -2526,6 +2569,19 @@ void LLInventorySingleFolderPanel::doCreate(const LLSD& userdata) reset_inventory_filter(); menu_create_inventory_item(this, dest_id, userdata); } + +void LLInventorySingleFolderPanel::doShare() +{ + if(mFolderRoot.get()->getCurSelectedItem() == NULL) + { + std::set uuids{mFolderID}; + LLAvatarActions::shareWithAvatars(uuids, gFloaterView->getParentFloater(this)); + } + else + { + LLAvatarActions::shareWithAvatars(this); + } +} /************************************************************************/ /* Asset Pre-Filtered Inventory Panel related class */ /************************************************************************/ diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index c79fd24a0e..cfe8b8f825 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -426,6 +426,7 @@ public: LLUUID getSingleFolderRoot() { return mFolderID; } void doCreate(const LLSD& userdata); + void doShare(); bool isBackwardAvailable(); bool isForwardAvailable(); @@ -438,6 +439,7 @@ public: std::list getNavForwardList() { return mForwardFolders; } void setSelectCallback(const boost::function& items, BOOL user_action)>& cb); + void setScroller(LLScrollContainer* scroller); typedef boost::function root_changed_callback_t; boost::signals2::connection setRootChangedCallback(root_changed_callback_t cb); @@ -453,6 +455,7 @@ protected: LLUUID mFolderID; std::list mBackwardFolders; std::list mForwardFolders; + LLScrollContainer* mExternalScroller; boost::signals2::signal mRootChangedSignal; }; diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 559525ad98..106f1553d0 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -377,7 +377,7 @@ BOOL LLPanelMainInventory::postBuild() mInventoryGalleryPanel = getChild("gallery_view_inv"); mGalleryRootUpdatedConnection = mInventoryGalleryPanel->setRootChangedCallback(boost::bind(&LLPanelMainInventory::updateTitle, this)); - mCombinationScrollPanel = getChild("combination_view_inventory"); + mCombinationScrollPanel = getChild("combination_view_inventory"); mCombinationInventoryPanel = getChild("comb_single_folder_inv"); LLInventoryFilter& comb_inv_filter = mCombinationInventoryPanel->getFilter(); @@ -385,6 +385,7 @@ BOOL LLPanelMainInventory::postBuild() comb_inv_filter.markDefault(); mCombinationInventoryPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onCombinationInventorySelectionChanged, this, _1, _2)); mCombinationInventoryPanel->setRootChangedCallback(boost::bind(&LLPanelMainInventory::onCombinationRootChanged, this, false)); + mCombinationInventoryPanel->setScroller(mCombinationScrollPanel); mCombinationGalleryPanel = getChild("comb_gallery_view_inv"); LLInventoryFilter& comb_gallery_filter = mCombinationGalleryPanel->getFilter(); @@ -1394,9 +1395,12 @@ void LLPanelMainInventory::updateItemcountText() gInventory.getDirectDescendentsOf(getCurrentSFVRoot(), cats, items); - string_args["[ITEM_COUNT]"] = llformat("%d", items->size()); - string_args["[CATEGORY_COUNT]"] = llformat("%d", cats->size()); - text = getString("ItemcountCompleted", string_args); + if (items && cats) + { + string_args["[ITEM_COUNT]"] = llformat("%d", items->size()); + string_args["[CATEGORY_COUNT]"] = llformat("%d", cats->size()); + text = getString("ItemcountCompleted", string_args); + } } mCounterCtrl->setValue(text); @@ -2010,6 +2014,13 @@ void LLPanelMainInventory::toggleViewMode() } mSingleFolderMode = !mSingleFolderMode; + mCombinationShapeDirty = true; + + if (mCombinationGalleryPanel->getRootFolder().isNull()) + { + mCombinationGalleryPanel->setRootFolder(mCombinationInventoryPanel->getSingleFolderRoot()); + mCombinationGalleryPanel->updateRootFolder(); + } getChild("default_inventory_panel")->setVisible(!mSingleFolderMode); getChild("single_folder_inventory")->setVisible(mSingleFolderMode && isListViewMode()); @@ -3029,6 +3040,11 @@ void LLPanelMainInventory::updateCombinationVisibility() { mCombinationShapeDirty = false; mCombinationInventoryPanel->reshape(1,1); // HACK: force reduce visible area + LLFolderView* root_folder = mCombinationInventoryPanel->getRootFolder(); + if (root_folder) + { + root_folder->arrangeAll(); + } } if (!mCombinationGalleryPanel->hasVisibleItems()) { @@ -3038,20 +3054,17 @@ void LLPanelMainInventory::updateCombinationVisibility() LLRect inv_inner_rect = mCombinationInventoryPanel->getScrollableContainer()->getScrolledViewRect(); LLRect galery_rect = mCombinationGalleryPanel->getRect(); LLRect inner_galery_rect = mCombinationGalleryPanel->getScrollableContainer()->getScrolledViewRect(); - LLScrollContainer* scroll = static_cast(mCombinationScrollPanel); - LLRect scroller_window_rect = scroll->getContentWindowRect(); - const S32 BORDER_PAD = 2; // two sides - S32 desired_width = llmax(inv_inner_rect.getWidth(), scroller_window_rect.getWidth() - BORDER_PAD); + LLRect scroller_window_rect = mCombinationScrollPanel->getContentWindowRect(); inv_rect.mBottom = 0; - inv_rect.mRight = inv_rect.mLeft + desired_width; + inv_rect.mRight = inv_rect.mLeft + inv_inner_rect.getWidth() + mCombinationInventoryPanel->getScrollableContainer()->getBorderWidth(); if (!mCombinationGalleryPanel->hasVisibleItems() || mCombinationInventoryPanel->hasVisibleItems()) { - inv_rect.mTop = inv_rect.mBottom + inv_inner_rect.getHeight() + BORDER_PAD; + inv_rect.mTop = inv_rect.mBottom + inv_inner_rect.getHeight() + mCombinationInventoryPanel->getScrollableContainer()->getBorderWidth(); } else { - inv_rect.mTop = inv_rect.mBottom; + inv_rect.mTop = inv_rect.mBottom + mCombinationInventoryPanel->getScrollableContainer()->getBorderWidth(); } galery_rect.mBottom = inv_rect.mTop; @@ -3059,15 +3072,15 @@ void LLPanelMainInventory::updateCombinationVisibility() if (mCombinationGalleryPanel->hasVisibleItems()) { mCombinationGalleryPanel->setVisible(true); - galery_rect.mTop = galery_rect.mBottom + inner_galery_rect.getHeight() + BORDER_PAD; + galery_rect.mTop = galery_rect.mBottom + inner_galery_rect.getHeight() + mCombinationGalleryPanel->getScrollableContainer()->getBorderWidth(); } else { mCombinationGalleryPanel->setVisible(false); - galery_rect.mTop = galery_rect.mBottom; + galery_rect.mTop = galery_rect.mBottom + mCombinationGalleryPanel->getScrollableContainer()->getBorderWidth(); } - mCombinationScroller->reshape(desired_width, inv_rect.getHeight() + galery_rect.getHeight(), true); + mCombinationScroller->reshape(scroller_window_rect.getWidth(), inv_rect.getHeight() + galery_rect.getHeight(), true); mCombinationGalleryPanel->setShape(galery_rect, false); mCombinationInventoryPanel->setShape(inv_rect, false); @@ -3079,12 +3092,6 @@ void LLPanelMainInventory::updateCombinationVisibility() { scrollToInvPanelSelection(); } - - LLFolderView* root_folder = mCombinationInventoryPanel->getRootFolder(); - if (root_folder) - { - root_folder->updateRenamerPosition(); - } } } diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index f37f9522c4..068572b22e 100644 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -37,19 +37,20 @@ #include "llfolderview.h" class LLComboBox; -class LLFolderViewItem; class LLInventoryPanel; class LLInventoryGallery; -class LLSaveFolderState; class LLFilterEditor; -class LLTabContainer; +class LLFloater; class LLFloaterInventoryFinder; +class LLFloaterSidePanelContainer; +class LLFolderViewItem; class LLMenuButton; class LLMenuGL; +class LLSaveFolderState; +class LLScrollContainer; class LLSidepanelInventory; +class LLTabContainer; class LLToggleableMenu; -class LLFloater; -class LLFloaterSidePanelContainer; class LLComboBox; // Filter dropdown //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -222,7 +223,7 @@ private: LLInventorySingleFolderPanel* mSingleFolderPanelInventory; LLInventoryGallery* mInventoryGalleryPanel; - LLUICtrl* mCombinationScrollPanel; + LLScrollContainer* mCombinationScrollPanel; LLInventorySingleFolderPanel* mCombinationInventoryPanel; LLInventoryGallery* mCombinationGalleryPanel; LLView* mCombinationScroller; diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 57f85af559..6ec2431756 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6747,6 +6747,14 @@ Your trash is overflowing. This may cause problems logging in. yestext="Check trash folder"/> + +Your inventory is experiencing issues. Please contact support of your grid. + fail + +