From 7c1af50bdaa35be68f851b5db19f89739fc02c05 Mon Sep 17 00:00:00 2001 From: Inusaito Sayori Date: Sat, 1 Aug 2015 16:55:33 -0400 Subject: [PATCH] Double check vmm merge against alchemy. (sync) --- indra/newview/aixmllindengenepool.cpp | 18 +- indra/newview/llfolderview.cpp | 100 +++++------ indra/newview/llfolderview.h | 75 ++++----- indra/newview/llfolderviewitem.cpp | 58 ++----- indra/newview/llfolderviewitem.h | 20 +-- indra/newview/llinventorybridge.cpp | 4 +- indra/newview/llinventoryfilter.cpp | 204 +++++++++++++++++------ indra/newview/llinventoryfilter.h | 82 +++++++-- indra/newview/llinventoryfunctions.cpp | 73 +++----- indra/newview/llinventoryfunctions.h | 4 - indra/newview/llinventorymodel.cpp | 62 ++++--- indra/newview/llinventorypanel.cpp | 33 ++-- indra/newview/llinventorypanel.h | 8 +- indra/newview/llpanelmaininventory.cpp | 2 +- indra/newview/llpanelobjectinventory.cpp | 78 ++++----- indra/newview/llpanelobjectinventory.h | 2 +- indra/newview/lltooldraganddrop.cpp | 7 +- 17 files changed, 472 insertions(+), 358 deletions(-) diff --git a/indra/newview/aixmllindengenepool.cpp b/indra/newview/aixmllindengenepool.cpp index 2e62a7955..913a77c3b 100644 --- a/indra/newview/aixmllindengenepool.cpp +++ b/indra/newview/aixmllindengenepool.cpp @@ -49,12 +49,11 @@ #include "llviewerprecompiledheaders.h" #include "aixmllindengenepool.h" #include "hippogridmanager.h" +#include "llinventorymodel.h" #include "llvisualparam.h" #include "llviewerwearable.h" #include "llquantize.h" -extern void append_path_short(LLUUID const& id, std::string& path); - void AIXMLLindenGenepool::MetaData::toXML(std::ostream& os, int indentation) const { AIXMLElement tag(os, "meta", indentation); @@ -145,7 +144,20 @@ AIArchetype::MetaData::MetaData(AIXMLElementParser const& parser) AIArchetype::MetaData::MetaData(LLViewerWearable const* wearable) : mName(wearable->getName()), mDescription(wearable->getDescription()) { - append_path_short(wearable->getItemID(), mPath); + // Path should already end on '/' if it is not empty. + const LLUUID& root_id = gInventory.getRootFolderID(); + LLUUID id = wearable->getItemID(); + for(const LLInventoryObject* obj = gInventory.getObject(id); obj && id != root_id; obj = gInventory.getCategory(id)) + { + std::string temp(mPath); + mPath = obj->getName(); + if (!temp.empty()) + { + mPath.append(1, '/'); + mPath.append(temp); + } + id = obj->getParentUUID(); + } } AIArchetype::AIArchetype(void) : mType(LLWearableType::WT_NONE) diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 8cae2ce8b..d6e15b422 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -633,6 +633,10 @@ LLFolderViewItem* LLFolderView::getCurSelectedItem( void ) return NULL; } +LLFolderView::selected_items_t& LLFolderView::getSelectedItems( void ) +{ + return mSelectedItems; +} // Record the selected item and pass it down the hierachy. BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem, @@ -875,12 +879,13 @@ std::set LLFolderView::getSelectionList() const return selection; } -BOOL LLFolderView::startDrag(LLToolDragAndDrop::ESource source) +bool LLFolderView::startDrag(LLToolDragAndDrop::ESource source) { std::vector types; uuid_vec_t cargo_ids; selected_items_t::iterator item_it; - BOOL can_drag = TRUE; + bool can_drag = true; + if (!mSelectedItems.empty()) { for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) @@ -922,25 +927,19 @@ void LLFolderView::draw() } // while dragging, update selection rendering to reflect single/multi drag status - if (LLToolDragAndDrop::getInstance()->hasMouseCapture()) + LLToolDragAndDrop& dad_inst(LLToolDragAndDrop::instance()); + if (dad_inst.hasMouseCapture()) { - EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept(); - if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE) - { - setShowSingleSelection(TRUE); - } - else - { - setShowSingleSelection(FALSE); - } + EAcceptance last_accept = dad_inst.getLastAccept(); + setShowSingleSelection(last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE); } else { setShowSingleSelection(FALSE); } - - if (mSearchTimer.getElapsedTimeF32() > gSavedSettings.getF32("TypeAheadTimeout") || !mSearchString.size()) + static LLUICachedControl type_ahead_timeout("TypeAheadTimeout", 0); + if (mSearchTimer.getElapsedTimeF32() > type_ahead_timeout || !mSearchString.size()) { mSearchString.clear(); } @@ -977,7 +976,7 @@ void LLFolderView::draw() // get preferable text height... S32 pixel_height = mStatusTextBox->getTextPixelHeight(); - bool height_changed = local_rect.getHeight() != pixel_height; + bool height_changed = (local_rect.getHeight() != pixel_height); if (height_changed) { // ... if it does not match current height, lets rearrange current view. @@ -988,6 +987,8 @@ void LLFolderView::draw() } } + // skip over LLFolderViewFolder::draw since we don't want the folder icon, label, + // and arrow for the root folder LLView::draw(); mDragAndDropThisFrame = FALSE; @@ -1006,7 +1007,7 @@ void LLFolderView::finishRenamingItem( void ) closeRenamer(); - // List is re-sorted alphabeticly, so scroll to make sure the selected item is visible. + // List is re-sorted alphabetically, so scroll to make sure the selected item is visible. scrollToShowSelection(); } @@ -1064,7 +1065,7 @@ void LLFolderView::removeCutItems() } } -void LLFolderView::removeSelectedItems( void ) +void LLFolderView::removeSelectedItems() { if(getVisible() && getEnabled()) { @@ -1075,8 +1076,7 @@ void LLFolderView::removeSelectedItems( void ) // items, since the removal will futz with internal data // structures. std::vector items; - S32 count = mSelectedItems.size(); - if(count == 0) return; + if(mSelectedItems.empty()) return; LLFolderViewItem* item = NULL; selected_items_t::iterator item_it; for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) @@ -1094,7 +1094,7 @@ void LLFolderView::removeSelectedItems( void ) } // iterate through the new container. - count = items.size(); + size_t count = items.size(); LLUUID new_selection_id; if(count == 1) { @@ -1149,7 +1149,7 @@ void LLFolderView::removeSelectedItems( void ) setSelectionFromRoot(NULL, mParentPanel.get()->hasFocus()); } - for(S32 i = 0; i < count; ++i) + for(size_t i = 0; i < count; ++i) { listener = items[i]->getListener(); if(listener && (std::find(listeners.begin(), listeners.end(), listener) == listeners.end())) @@ -1546,25 +1546,37 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask ) case KEY_PAGE_UP: mSearchString.clear(); - mScrollContainer->pageUp(30); + if (mScrollContainer) + { + mScrollContainer->pageUp(30); + } handled = TRUE; break; case KEY_PAGE_DOWN: mSearchString.clear(); - mScrollContainer->pageDown(30); + if (mScrollContainer) + { + mScrollContainer->pageDown(30); + } handled = TRUE; break; case KEY_HOME: mSearchString.clear(); - mScrollContainer->goToTop(); + if (mScrollContainer) + { + mScrollContainer->goToTop(); + } handled = TRUE; break; case KEY_END: mSearchString.clear(); - mScrollContainer->goToBottom(); + if (mScrollContainer) + { + mScrollContainer->goToBottom(); + } break; case KEY_DOWN: @@ -1587,12 +1599,12 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask ) if (next->isSelected()) { // shrink selection - changeSelectionFromRoot(last_selected, FALSE); + changeSelection(last_selected, FALSE); } else if (last_selected->getParentFolder() == next->getParentFolder()) { // grow selection - changeSelectionFromRoot(next, TRUE); + changeSelection(next, TRUE); } } } @@ -1650,12 +1662,12 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask ) if (prev->isSelected()) { // shrink selection - changeSelectionFromRoot(last_selected, FALSE); + changeSelection(last_selected, FALSE); } else if (last_selected->getParentFolder() == prev->getParentFolder()) { // grow selection - changeSelectionFromRoot(prev, TRUE); + changeSelection(prev, TRUE); } } } @@ -1723,7 +1735,7 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask ) { mSearchString.erase(mSearchString.size() - 1, 1); } - search(getCurSelectedItem(), mSearchString, FALSE); + search(getCurSelectedItem(), wstring_to_utf8str(mSearchString), FALSE); handled = TRUE; } } @@ -1739,12 +1751,6 @@ BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char) return FALSE; } - if (uni_char > 0x7f) - { - LL_WARNS() << "LLFolderView::handleUnicodeCharHere - Don't handle non-ascii yet, aborting" << LL_ENDL; - return FALSE; - } - BOOL handled = FALSE; if (mParentPanel.get()->hasFocus()) { @@ -1757,7 +1763,8 @@ BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char) } //do text search - if (mSearchTimer.getElapsedTimeF32() > gSavedSettings.getF32("TypeAheadTimeout")) + static LLUICachedControl type_ahead_timeout("TypeAheadTimeout", 0.f); + if (mSearchTimer.getElapsedTimeF32() > type_ahead_timeout) { mSearchString.clear(); } @@ -1766,7 +1773,7 @@ BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char) { mSearchString += uni_char; } - search(getCurSelectedItem(), mSearchString, FALSE); + search(getCurSelectedItem(), wstring_to_utf8str(mSearchString), FALSE); handled = TRUE; } @@ -2090,7 +2097,7 @@ BOOL LLFolderView::getShowSelectionContext() return FALSE; } -void LLFolderView::setShowSingleSelection(BOOL show) +void LLFolderView::setShowSingleSelection(bool show) { if (show != mShowSingleSelection) { @@ -2305,8 +2312,8 @@ void LLFolderView::idle(void* user_data) void LLFolderView::dumpSelectionInformation() { - LL_INFOS() << "LLFolderView::dumpSelectionInformation()" << LL_ENDL; - LL_INFOS() << "****************************************" << LL_ENDL; + LL_INFOS() << "LLFolderView::dumpSelectionInformation()" << LL_NEWLINE + << "****************************************" << LL_ENDL; selected_items_t::iterator item_it; for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) { @@ -2352,15 +2359,15 @@ void LLFolderView::updateMenuOptions(LLMenuGL* menu) } // Successively filter out invalid options - - U32 flags = FIRST_SELECTED_ITEM; + U32 multi_select_flag = (/*mSelectedItems.size() > 1 ? ITEM_IN_MULTI_SELECTION :*/ 0x0); + U32 flags = multi_select_flag | FIRST_SELECTED_ITEM; for (selected_items_t::iterator item_itor = mSelectedItems.begin(); item_itor != mSelectedItems.end(); ++item_itor) { LLFolderViewItem* selected_item = (*item_itor); selected_item->buildContextMenu(*menu, flags); - flags = 0x0; + flags = multi_select_flag; } // This adds a check for restrictions based on the entire @@ -2512,11 +2519,6 @@ void LLFolderView::setFilterPermMask( PermissionMask filter_perm_mask ) mFilter->setFilterPermissions(filter_perm_mask); } -bool LLFolderView::getFilterWorn() const -{ - return mFilter->getFilterWorn(); -} - U32 LLFolderView::getFilterObjectTypes() const { return mFilter->getFilterObjectTypes(); diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 121109f79..067c64703 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -87,6 +87,7 @@ public: virtual BOOL canFocusChildren() const; + virtual const LLFolderView* getRoot() const { return this; } virtual LLFolderView* getRoot() { return this; } LLFolderViewGroupedItemModel* getFolderViewGroupedItemModel() { return mGroupedItemModel; } @@ -104,7 +105,6 @@ public: LLInventoryFilter* getFilter(); const std::string getFilterSubString(BOOL trim = FALSE); - bool getFilterWorn() const; U32 getFilterObjectTypes() const; PermissionMask getFilterPermissions() const; // *NOTE: use getFilter()->getShowFolderState(); @@ -132,15 +132,16 @@ public: void arrangeAll() { mArrangeGeneration++; } S32 getArrangeGeneration() { return mArrangeGeneration; } - // Apply filters to control visibility of inventory items + // applies filters to control visibility of items virtual void filter( LLInventoryFilter& filter); // Get the last selected item virtual LLFolderViewItem* getCurSelectedItem( void ); + selected_items_t& getSelectedItems( void ); // Record the selected item and pass it down the hierarchy. virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, - BOOL take_keyboard_focus); + BOOL take_keyboard_focus = TRUE); // Used by menu callbacks void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus); @@ -148,19 +149,19 @@ public: // Called once a frame to update the selection if mSelectThisID has been set void updateSelection(); - // This method is used to toggle the selection of an item. - // Walks children and keeps track of selected objects. + // This method is used to toggle the selection of an item. Walks + // children, and keeps track of selected objects. virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); virtual std::set getSelectionList() const; - // Make sure if ancestor is selected, descendents are not + // Make sure if ancestor is selected, descendants are not void sanitizeSelection(); - void clearSelection(); + virtual void clearSelection(); void addToSelectionList(LLFolderViewItem* item); void removeFromSelectionList(LLFolderViewItem* item); - BOOL startDrag(LLToolDragAndDrop::ESource source); + bool startDrag(LLToolDragAndDrop::ESource source); void setDragAndDropThisFrame() { mDragAndDropThisFrame = TRUE; } void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; } LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; } @@ -181,29 +182,21 @@ public: BOOL autoOpenTest(LLFolderViewFolder* item); // Copy & paste - virtual void copy(); virtual BOOL canCopy() const; + virtual void copy(); - virtual void cut(); virtual BOOL canCut() const; + virtual void cut(); - virtual void paste(); virtual BOOL canPaste() const; + virtual void paste(); - virtual void doDelete(); virtual BOOL canDoDelete() const; + virtual void doDelete(); // Public rename functionality - can only start the process void startRenamingSelectedItem( void ); - // These functions were used when there was only one folderview, - // and relied on that concept. This functionality is now handled - // by the listeners and the lldraganddroptool. - //LLFolderViewItem* getMovingItem() { return mMovingItem; } - //void setMovingItem( LLFolderViewItem* item ) { mMovingItem = item; } - //void dragItemIntoFolder( LLFolderViewItem* moving_item, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept ); - //void dragFolderIntoFolder( LLFolderViewFolder* moving_folder, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept ); - // LLView functionality ///*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent ); /*virtual*/ BOOL handleKeyHere( KEY key, MASK mask ); @@ -218,6 +211,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 BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); virtual void draw(); virtual void deleteAllChildren(); @@ -228,12 +222,13 @@ public: LLRect getVisibleRect(); BOOL search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward); - void setShowSelectionContext(BOOL show) { mShowSelectionContext = show; } + void setShowSelectionContext(bool show) { mShowSelectionContext = show; } BOOL getShowSelectionContext(); - void setShowSingleSelection(BOOL show); + void setShowSingleSelection(bool show); BOOL getShowSingleSelection() { return mShowSingleSelection; } F32 getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); } bool getUseEllipses() { return mUseEllipses; } + S32 getSelectedCount() { return (S32)mSelectedItems.size(); } void addItemID(const LLUUID& id, LLFolderViewItem* itemp); void removeItemID(const LLUUID& id); @@ -259,7 +254,7 @@ public: virtual S32 notify(const LLSD& info) ; bool useLabelSuffix() { return mUseLabelSuffix; } - void updateMenu(); + virtual void updateMenu(); void saveFolderState(); void restoreFolderState(); @@ -290,35 +285,37 @@ protected: LLHandle mPopupMenuHandle; selected_items_t mSelectedItems; - BOOL mKeyboardSelection; - BOOL mAllowMultiSelect; - BOOL mShowEmptyMessage; - BOOL mShowFolderHierarchy; + bool mKeyboardSelection, + mAllowMultiSelect, + mShowEmptyMessage, + mShowFolderHierarchy, + mNeedsScroll, + mPinningSelectedItem, + mNeedsAutoSelect, + mAutoSelectOverride, + mNeedsAutoRename, + mUseLabelSuffix, + mDragAndDropThisFrame, + mShowSelectionContext, + mShowSingleSelection; + LLUUID mSourceID; // Renaming variables and methods LLFolderViewItem* mRenameItem; // The item currently being renamed LLLineEditor* mRenamer; - BOOL mNeedsScroll; - BOOL mPinningSelectedItem; LLRect mScrollConstraintRect; - BOOL mNeedsAutoSelect; - BOOL mAutoSelectOverride; - BOOL mNeedsAutoRename; - bool mUseLabelSuffix; - - BOOL mDebugFilters; + + bool mDebugFilters; U32 mSortOrder; U32 mSearchType; LLDepthStack mAutoOpenItems; LLFolderViewFolder* mAutoOpenCandidate; LLFrameTimer mAutoOpenTimer; LLFrameTimer mSearchTimer; - std::string mSearchString; + LLWString mSearchString; LLInventoryFilter* mFilter; - BOOL mShowSelectionContext; - BOOL mShowSingleSelection; LLFrameTimer mMultiSelectionFadeTimer; S32 mArrangeGeneration; @@ -328,8 +325,6 @@ protected: S32 mMinWidth; S32 mRunningHeight; std::map mItemMap; - BOOL mDragAndDropThisFrame; - LLUUID mSelectThisID; // if non null, select this item LLHandle mParentPanel; diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index 657d5cfdc..ed87b4c3e 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -142,6 +142,10 @@ LLFolderView* LLFolderViewItem::getRoot() return mRoot; } +const LLFolderView* LLFolderViewItem::getRoot() const +{ + return mRoot; +} // Returns true if this object is a child (or grandchild, etc.) of potential_ancestor. BOOL LLFolderViewItem::isDescendantOf( const LLFolderViewFolder* potential_ancestor ) { @@ -374,12 +378,6 @@ void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection, getRoot()->setSelection(selection, openitem, take_keyboard_focus); } -// helper function to change the selection from the root. -void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected) -{ - getRoot()->changeSelection(selection, selected); -} - std::set LLFolderViewItem::getSelectionList() const { std::set selection; @@ -588,7 +586,7 @@ void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags) void LLFolderViewItem::openItem( void ) { if (!mListener) return; - if (mAllowOpen || mListener->isItemWearable()) + if (mAllowWear || mListener->isItemWearable()) { mListener->openItem(); } @@ -679,7 +677,7 @@ BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask ) { if(!mIsSelected) { - setSelectionFromRoot(this, FALSE); + getRoot()->setSelection(this, FALSE); } make_ui_sound("UISndClick"); return TRUE; @@ -700,7 +698,7 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask ) { if(mask & MASK_CONTROL) { - changeSelectionFromRoot(this, !mIsSelected); + getRoot()->changeSelection(this, !mIsSelected); } else if (mask & MASK_SHIFT) { @@ -708,12 +706,14 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask ) } else { - setSelectionFromRoot(this, FALSE); + getRoot()->setSelection(this, FALSE); } make_ui_sound("UISndClick"); } else { + // If selected, we reserve the decision of deselecting/reselecting to the mouse up moment. + // This is necessary so we maintain selection consistent when starting a drag. mSelectPending = TRUE; } @@ -782,6 +782,7 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask ) { gViewerWindow->setCursor(UI_CURSOR_NOLOCKED); } + return TRUE; } else @@ -822,7 +823,7 @@ BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask ) //...then select if(mask & MASK_CONTROL) { - changeSelectionFromRoot(this, !mIsSelected); + getRoot()->changeSelection(this, !mIsSelected); } else if (mask & MASK_SHIFT) { @@ -830,7 +831,7 @@ BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask ) } else { - setSelectionFromRoot(this, FALSE); + getRoot()->setSelection(this, FALSE); } } @@ -838,7 +839,10 @@ BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask ) if( hasMouseCapture() ) { - getRoot()->setShowSelectionContext(FALSE); + if (getRoot()) + { + getRoot()->setShowSelectionContext(FALSE); + } gFocusMgr.setMouseCapture( NULL ); } return TRUE; @@ -2814,34 +2818,6 @@ bool LLInventorySort::updateSort(U32 order) bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b) { - /* TO-DO - // ignore sort order for landmarks in the Favorites folder. - // they should be always sorted as in Favorites bar. See EXT-719 - if (a->getSortGroup() == SG_ITEM - && b->getSortGroup() == SG_ITEM - && a->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK - && b->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK) - { - - static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); - - LLUUID a_uuid = a->getParentFolder()->getListener()->getUUID(); - LLUUID b_uuid = b->getParentFolder()->getListener()->getUUID(); - - if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id)) - { - // *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem - // or to LLInvFVBridge - LLViewerInventoryItem* aitem = (static_cast(a->getListener()))->getItem(); - LLViewerInventoryItem* bitem = (static_cast(b->getListener()))->getItem(); - if (!aitem || !bitem) - return false; - S32 a_sort = aitem->getSortField(); - S32 b_sort = bitem->getSortField(); - return a_sort < b_sort; - } - }*/ - // We sort by name if we aren't sorting by date // OR if these are folders and we are sorting folders by name. bool by_name = ((!mByDate || (mFoldersByName && (a->getSortGroup() != SG_ITEM))) && !mFoldersByWeight); diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index a0246666d..c33eb575b 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -142,13 +142,10 @@ protected: LLTimer mTimeSinceRequestStart; bool mShowLoadStatus; bool mAllowDrop; - bool mAllowOpen; + bool mAllowWear; std::string mSearchable; U32 mSearchType; - - // helper function to change the selection from the root. - void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected); //Sets extra search criteria 'labels' to be compared against by filter. void updateExtraSearchCriteria(); @@ -245,7 +242,7 @@ public: void setShowLoadStatus(bool status) { mShowLoadStatus = status; } void setAllowDrop(bool allow) { mAllowDrop = allow; } - void setAllowOpen(bool allow) { mAllowOpen = allow; } + void setAllowWear(bool allow) { mAllowWear = allow; } // Call through to the viewed object and return true if it can be // removed. Returns true if it's removed. @@ -253,7 +250,7 @@ public: BOOL remove(); // Build an appropriate context menu for the item. Flags unused. - void buildContextMenu(LLMenuGL& menu, U32 flags); + void buildContextMenu(class LLMenuGL& menu, U32 flags); // This method returns the actual name of the thing being // viewed. This method will ask the viewed object itself. @@ -290,12 +287,12 @@ public: virtual void openItem( void ); virtual void preview(void); - // Show children (unfortunate that this is called "open") + // Show children virtual void setOpen(BOOL open = TRUE) {}; - virtual BOOL isOpen() const { return FALSE; } virtual LLFolderView* getRoot(); + virtual const LLFolderView* getRoot() const; BOOL isDescendantOf( const LLFolderViewFolder* potential_ancestor ); S32 getIndentation() { return mIndentation; } @@ -539,12 +536,14 @@ public: virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); - virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, + BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg); - BOOL handleDragAndDropToThisFolder(MASK mask, BOOL drop, + BOOL handleDragAndDropToThisFolder(MASK mask, + BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, @@ -561,6 +560,7 @@ public: items_t::const_iterator getItemsBegin() const { return mItems.begin(); } items_t::const_iterator getItemsEnd() const { return mItems.end(); } items_t::size_type getItemsCount() const { return mItems.size(); } + LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse); void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector& items); }; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index d1e3222c3..23180a1ec 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3877,8 +3877,6 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items const bool is_cof(isCOFFolder()); if (!is_cof && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT)) { - LLInventoryPanel* panel = mInventoryPanel.get(); - if(panel && !panel->getFilterWorn()) if (!isInboxFolder() && !isOutboxFolder()) // don't allow creation in inbox or outbox { { @@ -7404,7 +7402,7 @@ void LLWearableBridgeAction::wearOnAvatar() LLViewerInventoryItem* item = getItem(); if(item) { - if (get_is_item_worn(item)) + if (get_is_item_worn(item->getUUID())) { LLAppearanceMgr::instance().removeItemFromAvatar(item->getUUID()); } diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 8e9c4fdf0..ca1c113f8 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -29,8 +29,10 @@ #include "llinventoryfilter.h" // viewer includes +#include "llappearancemgr.h" #include "llfoldervieweventlistener.h" #include "llfolderviewitem.h" +#include "llinventoryfunctions.h" #include "llinventorymodel.h" #include "llinventorymodelbackgroundfetch.h" #include "llinventoryfunctions.h" @@ -41,24 +43,25 @@ #include "llviewerfoldertype.h" #include "llagentwearables.h" #include "llvoavatarself.h" -#include "llinventoryclipboard.h" // linden library includes +#include "llinventoryclipboard.h" #include "lltrans.h" -LLInventoryFilter::FilterOps::FilterOps() : - mFilterObjectTypes(0xffffffffffffffffULL), - mFilterCategoryTypes(0xffffffffffffffffULL), - mFilterWearableTypes(0xffffffffffffffffULL), - mMinDate(time_min()), - mMaxDate(time_max()), - mHoursAgo(0), - mShowFolderState(SHOW_NON_EMPTY_FOLDERS), - mPermissions(PERM_NONE), - mFilterTypes(FILTERTYPE_OBJECT), - mFilterWorn(false), - mFilterUUID(LLUUID::null), - mFilterLinks(FILTERLINK_INCLUDE_LINKS) +LLInventoryFilter::FilterOps::FilterOps(const Params& p) +: mFilterObjectTypes(p.object_types), + mFilterCategoryTypes(p.category_types), + mFilterWearableTypes(p.wearable_types), + mMinDate(p.date_range.min_date), + mMaxDate(p.date_range.max_date), + mHoursAgo(p.hours_ago), + mDateSearchDirection(p.date_search_direction), + mShowFolderState(p.show_folder_state), + mPermissions(p.permissions), + mFilterTypes(p.types), + mFilterUUID(p.uuid), + mFilterLinks(p.links), + mFilterWornItems(p.worn_items) { } @@ -83,16 +86,12 @@ LLInventoryFilter::LLInventoryFilter(const std::string& name) markDefault(); } -LLInventoryFilter::~LLInventoryFilter() -{ -} - bool LLInventoryFilter::check(LLFolderViewItem* item) { // Clipboard cut items are *always* filtered so we need this value upfront const LLFolderViewEventListener* listener = item->getListener(); const LLUUID item_id = listener ? listener->getUUID() : LLUUID::null; - const bool passed_clipboard = item_id.notNull() ? checkAgainstClipboard(item_id) : true; + const bool passed_clipboard = listener && item_id.notNull() ? checkAgainstClipboard(item_id) : true; // If it's a folder and we're showing all folders, return automatically. const BOOL is_folder = (dynamic_cast(item) != NULL); @@ -103,11 +102,11 @@ bool LLInventoryFilter::check(LLFolderViewItem* item) mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos; - const BOOL passed_filtertype = checkAgainstFilterType(item); - const BOOL passed_permissions = checkAgainstPermissions(item); - const BOOL passed_filterlink = checkAgainstFilterLinks(item); - const BOOL passed_wearable = !mFilterOps.mFilterWorn || (gAgentWearables.isWearingItem(item_id) || (gAgentAvatarp && gAgentAvatarp->isWearingAttachment(item_id))); - const BOOL passed = (passed_filtertype && + const bool passed_filtertype = checkAgainstFilterType(item); + const bool passed_permissions = checkAgainstPermissions(item); + const bool passed_filterlink = checkAgainstFilterLinks(item); + const bool passed_wearable = !mFilterOps.mFilterWornItems || (gAgentWearables.isWearingItem(item_id) || (gAgentAvatarp && gAgentAvatarp->isWearingAttachment(item_id))); + const bool passed = (passed_filtertype && passed_permissions && passed_filterlink && passed_clipboard && @@ -128,8 +127,7 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const const LLFolderViewEventListener* listener = folder->getListener(); if (!listener) { - LL_WARNS() << "Folder view event listener not found." << LL_ENDL; - llassert(false); // crash in development builds + LL_ERRS() << "Folder view event listener not found." << LL_ENDL; return false; } @@ -208,6 +206,13 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const } } + // show folder links + LLViewerInventoryItem* item = gInventory.getItem(folder_id); + if (item && item->getActualType() == LLAssetType::AT_LINK_FOLDER) + { + return passed_clipboard; + } + if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY) { // Can only filter categories for items in your inventory @@ -239,6 +244,7 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con // Pass if this item's type is of the correct filter type if (filterTypes & FILTERTYPE_OBJECT) { + // If it has no type, pass it, unless it's a link. if (object_type == LLInventoryType::IT_NONE) { @@ -285,10 +291,18 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con { earliest = 0; } - if (listener->getCreationDate() < earliest || - listener->getCreationDate() > mFilterOps.mMaxDate) + + if (FILTERDATEDIRECTION_NEWER == mFilterOps.mDateSearchDirection || isSinceLogoff()) { - return FALSE; + if (listener->getCreationDate() < earliest || + listener->getCreationDate() > mFilterOps.mMaxDate) + return FALSE; + } + else + { + if (listener->getCreationDate() > earliest || + listener->getCreationDate() > mFilterOps.mMaxDate) + return FALSE; } } @@ -335,6 +349,20 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con } } + //////////////////////////////////////////////////////////////////////////////// + // FILTERTYPE_WORN + // Pass if this item is worn + if (filterTypes & FILTERTYPE_WORN) + { + if (!object) return FALSE; + LLUUID cat_id = object->getParentUUID(); + const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); + return (get_is_item_worn(object_id) // if it's worn + && !LLAppearanceMgr::instance().getIsInCOF(object_id) // if it's not in CoF + && (!cat || cat->getPreferredType() != LLFolderType::FT_OUTFIT) // if it's not in an outfit + && !object->getIsLinkType()); // and it's not a link + } + return TRUE; } @@ -384,7 +412,7 @@ bool LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) co const LLFolderViewEventListener* listener = item->getListener(); if (!listener) return TRUE; - const LLUUID object_id = listener->getUUID(); + const LLUUID& object_id = listener->getUUID(); const LLInventoryObject *object = gInventory.getObject(object_id); if (!object) return TRUE; @@ -406,6 +434,11 @@ std::string::size_type LLInventoryFilter::getStringMatchOffset() const return mSubStringMatchOffset; } +bool LLInventoryFilter::isDefault() const +{ + return !isNotDefault(); +} + // has user modified default filter params? bool LLInventoryFilter::isNotDefault() const { @@ -417,13 +450,13 @@ bool LLInventoryFilter::isNotDefault() const not_default |= (mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes); not_default |= (mFilterOps.mFilterLinks != mDefaultFilterOps.mFilterLinks); not_default |= (mFilterSubString.size() > 0); - not_default |= (mFilterOps.mFilterWorn != mDefaultFilterOps.mFilterWorn); + not_default |= (mFilterOps.mFilterWornItems != mDefaultFilterOps.mFilterWornItems); not_default |= (mFilterOps.mPermissions != mDefaultFilterOps.mPermissions); not_default |= (mFilterOps.mMinDate != mDefaultFilterOps.mMinDate); not_default |= (mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate); not_default |= (mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo); - return not_default; + return not_default != 0; } bool LLInventoryFilter::isActive() const @@ -434,7 +467,6 @@ bool LLInventoryFilter::isActive() const || mFilterOps.mFilterTypes != FILTERTYPE_OBJECT || mFilterOps.mFilterLinks != FILTERLINK_INCLUDE_LINKS || mFilterSubString.size() - || mFilterOps.mFilterWorn != false || mFilterOps.mPermissions != PERM_NONE || mFilterOps.mMinDate != time_min() || mFilterOps.mMaxDate != time_max() @@ -457,7 +489,7 @@ void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types) current_types = types; if (more_bits_set && fewer_bits_set) { - // neither less or more restrive, both simultaneously + // neither less or more restrictive, both simultaneously // so we need to filter from scratch setModified(FILTER_RESTART); } @@ -498,6 +530,11 @@ void LLInventoryFilter::setFilterEmptySystemFolders() mFilterOps.mFilterTypes |= FILTERTYPE_EMPTYFOLDERS; } +void LLInventoryFilter::setFilterWornItems() +{ + mFilterOps.mFilterTypes |= FILTERTYPE_WORN; +} + void LLInventoryFilter::setFilterMarketplaceActiveFolders() { mFilterOps.mFilterTypes |= FILTERTYPE_MARKETPLACE_ACTIVE; @@ -687,12 +724,37 @@ void LLInventoryFilter::setHoursAgo(U32 hours) { bool are_date_limits_valid = mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max(); - bool is_increasing = hours > mFilterOps.mHoursAgo; - bool is_increasing_from_zero = is_increasing && !mFilterOps.mHoursAgo && !isSinceLogoff(); - // *NOTE: need to cache last filter time, in case filter goes stale - BOOL less_restrictive = ((are_date_limits_valid && ((is_increasing && mFilterOps.mHoursAgo))) || !hours); - BOOL more_restrictive = ((are_date_limits_valid && (!is_increasing && hours)) || is_increasing_from_zero); + bool less_restrictive = false; + bool more_restrictive = false; + + switch (mFilterOps.mDateSearchDirection) + { + case FILTERDATEDIRECTION_NEWER: + less_restrictive = ((are_date_limits_valid && (hours > mFilterOps.mHoursAgo + && mFilterOps.mHoursAgo)) + || !hours); + + more_restrictive = ((are_date_limits_valid && (hours < mFilterOps.mHoursAgo + && hours)) + || (hours > mFilterOps.mHoursAgo + && !mFilterOps.mHoursAgo + && !isSinceLogoff())); + break; + case FILTERDATEDIRECTION_OLDER: + less_restrictive = ((are_date_limits_valid && (hours < mFilterOps.mHoursAgo + && mFilterOps.mHoursAgo)) + || !hours); + + more_restrictive = ((are_date_limits_valid && (hours > mFilterOps.mHoursAgo + && hours)) + || (hours < mFilterOps.mHoursAgo + && !mFilterOps.mHoursAgo + && !isSinceLogoff())); + break; + default: + break; + } mFilterOps.mHoursAgo = hours; mFilterOps.mMinDate = time_min(); @@ -721,18 +783,31 @@ void LLInventoryFilter::setHoursAgo(U32 hours) } } +void LLInventoryFilter::setDateSearchDirection(U32 direction) +{ + if (direction != mFilterOps.mDateSearchDirection) + { + mFilterOps.mDateSearchDirection = direction; + setModified(FILTER_RESTART); + } +} -void LLInventoryFilter::setFilterLinks(U64 filter_links) +U32 LLInventoryFilter::getDateSearchDirection() const +{ + return mFilterOps.mDateSearchDirection; +} + +void LLInventoryFilter::setFilterLinks(EFilterLink filter_links) { if (mFilterOps.mFilterLinks != filter_links) { - if (mFilterOps.mFilterLinks == FILTERLINK_EXCLUDE_LINKS || - mFilterOps.mFilterLinks == FILTERLINK_ONLY_LINKS) + mFilterOps.mFilterLinks = filter_links; + if (filter_links == FILTERLINK_EXCLUDE_LINKS || + filter_links == FILTERLINK_ONLY_LINKS) setModified(FILTER_MORE_RESTRICTIVE); else setModified(FILTER_LESS_RESTRICTIVE); } - mFilterOps.mFilterLinks = filter_links; } void LLInventoryFilter::setShowFolderState(EFolderShow state) @@ -986,12 +1061,12 @@ const std::string& LLInventoryFilter::getFilterText() { mFilterText += LLTrans::getString("Since Logoff"); } - - if (getFilterWorn()) + + if (getFilterWornItems()) { mFilterText += LLTrans::getString("Worn"); } - + return mFilterText; } @@ -1062,6 +1137,11 @@ U64 LLInventoryFilter::getFilterTypes() const return mFilterOps.mFilterTypes; } +U64 LLInventoryFilter::getFilterTypes() const +{ + return mFilterOps.mFilterTypes; +} + U64 LLInventoryFilter::getFilterObjectTypes() const { return mFilterOps.mFilterObjectTypes; @@ -1077,6 +1157,11 @@ U64 LLInventoryFilter::getFilterWearableTypes() const return mFilterOps.mFilterWearableTypes; } +U64 LLInventoryFilter::getFilterWornItems() const +{ + return mFilterOps.mFilterWornItems; +} + bool LLInventoryFilter::hasFilterString() const { return mFilterSubString.size() > 0; @@ -1105,7 +1190,7 @@ U32 LLInventoryFilter::getHoursAgo() const { return mFilterOps.mHoursAgo; } -U64 LLInventoryFilter::getFilterLinks() const +LLInventoryFilter::EFilterLink LLInventoryFilter::getFilterLinks() const { return mFilterOps.mFilterLinks; } @@ -1157,3 +1242,28 @@ bool LLInventoryFilter::showAllResults() const return hasFilterString(); } +bool LLInventoryFilter::areDateLimitsSet() +{ + return mFilterOps.mMinDate != time_min() + || mFilterOps.mMaxDate != time_max() + || mFilterOps.mHoursAgo != 0; +} + + + +bool LLInventoryFilter::FilterOps::DateRange::validateBlock( bool emit_errors /*= true*/ ) const +{ + bool valid = LLInitParam::Block::validateBlock(emit_errors); + if (valid) + { + if (max_date() < min_date()) + { + if (emit_errors) + { + LL_WARNS() << "max_date should be greater or equal to min_date" << LL_ENDL; + } + valid = false; + } + } + return valid; +} diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index 73b564ff1..5fc77844c 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -63,7 +63,15 @@ public: FILTERTYPE_MARKETPLACE_INACTIVE = 0x1 << 7, // pass if folder is a marketplace inactive folder FILTERTYPE_MARKETPLACE_UNASSOCIATED = 0x1 << 8, // pass if folder is a marketplace non associated (no market ID) folder FILTERTYPE_MARKETPLACE_LISTING_FOLDER = 0x1 << 9, // pass iff folder is a listing folder - FILTERTYPE_NO_MARKETPLACE_ITEMS = 0x1 << 10 // pass iff folder is not under the marketplace + FILTERTYPE_NO_MARKETPLACE_ITEMS = 0x1 << 10, // pass iff folder is not under the marketplace + FILTERTYPE_WORN = 0x1 << 11 // search by worn items + + }; + + enum EFilterDateDirection + { + FILTERDATEDIRECTION_NEWER, + FILTERDATEDIRECTION_OLDER }; enum EFilterLink @@ -82,19 +90,66 @@ public: SO_FOLDERS_BY_WEIGHT = 0x1 << 3, // Force folder sort by weight, usually, amount of some elements in their descendents }; -struct FilterOps + struct FilterOps { - FilterOps(); + struct DateRange : public LLInitParam::Block + { + Optional min_date, + max_date; + + DateRange() + : min_date("min_date", time_min()), + max_date("max_date", time_max()) + {} + + bool validateBlock(bool emit_errors = true) const; + }; + + struct Params : public LLInitParam::Block + { + Optional types; + Optional object_types, + wearable_types, + category_types, + worn_items; + Optional links; + Optional uuid; + Optional date_range; + Optional hours_ago; + Optional date_search_direction; + Optional show_folder_state; + Optional permissions; + + Params() + : types("filter_types", FILTERTYPE_OBJECT), + object_types("object_types", 0xffffFFFFffffFFFFULL), + wearable_types("wearable_types", 0xffffFFFFffffFFFFULL), + category_types("category_types", 0xffffFFFFffffFFFFULL), + worn_items("worn_items", 0xffffFFFFffffFFFFULL), + links("links", FILTERLINK_INCLUDE_LINKS), + uuid("uuid"), + date_range("date_range"), + hours_ago("hours_ago", 0), + date_search_direction("date_search_direction", FILTERDATEDIRECTION_NEWER), + show_folder_state("show_folder_state", SHOW_NON_EMPTY_FOLDERS), + permissions("permissions", PERM_NONE) + {} + }; + + FilterOps(const Params& = Params()); + U32 mFilterTypes; - U64 mFilterObjectTypes, // For _OBJECT + U64 mFilterObjectTypes, // For _OBJECT mFilterWearableTypes, - mFilterLinks, - mFilterCategoryTypes; // For _CATEGORY + mFilterCategoryTypes, // For _CATEGORY + mFilterWornItems; + EFilterLink mFilterLinks; LLUUID mFilterUUID; // for UUID time_t mMinDate, mMaxDate; U32 mHoursAgo; + U32 mDateSearchDirection; EFolderShow mShowFolderState; PermissionMask mPermissions; @@ -102,7 +157,7 @@ struct FilterOps }; LLInventoryFilter(const std::string& name); - virtual ~LLInventoryFilter(); + virtual ~LLInventoryFilter() {} // +-------------------------------------------------------------------+ // + Parameters @@ -111,6 +166,7 @@ struct FilterOps U64 getFilterObjectTypes() const; U64 getFilterCategoryTypes() const; U64 getFilterWearableTypes() const; + U64 getFilterWornItems() const; bool isFilterObjectTypesWith(LLInventoryType::EType t) const; void setFilterObjectTypes(U64 types); void setFilterCategoryTypes(U64 types); @@ -123,14 +179,12 @@ struct FilterOps void setFilterMarketplaceListingFolders(bool select_only_listing_folders); void setFilterNoMarketplaceFolder(); void updateFilterTypes(U64 types, U64& current_types); + void setFilterWornItems(); void setFilterSubString(const std::string& string); const std::string& getFilterSubString(BOOL trim = FALSE) const; const std::string& getFilterSubStringOrig() const { return mFilterSubStringOrig; } bool hasFilterString() const; - - void setFilterWorn(bool worn) { mFilterOps.mFilterWorn = worn; } - bool getFilterWorn() const { return mFilterOps.mFilterWorn; } void setFilterPermissions(PermissionMask perms); PermissionMask getFilterPermissions() const; @@ -142,9 +196,11 @@ struct FilterOps void setHoursAgo(U32 hours); U32 getHoursAgo() const; + void setDateSearchDirection(U32 direction); + U32 getDateSearchDirection() const; - void setFilterLinks(U64 filter_link); - U64 getFilterLinks() const; + void setFilterLinks(EFilterLink filter_link); + EFilterLink getFilterLinks() const; // +-------------------------------------------------------------------+ // + Execution And Results @@ -189,6 +245,7 @@ struct FilterOps // +-------------------------------------------------------------------+ // + Default // +-------------------------------------------------------------------+ + bool isDefault() const; bool isNotDefault() const; void markDefault(); void resetDefault(); @@ -234,6 +291,7 @@ private: EFilterModified mFilterModified; std::string mFilterText; + std::string mEmptyLookupMessage; }; #endif diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 4999a7022..33b7e5cf5 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -291,11 +291,6 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc LLNotificationsUtil::add("AlertMerchantVersionFolderEmpty"); LLMarketplaceData::instance().activateListing(listing_uuid, false,1); } - else if (version_folder_uuid.notNull() && (count_descendants_items(version_folder_uuid) == 0)) - { - LL_INFOS("SLM") << "Unlist as the version folder is empty of any item!!" << LL_ENDL; - LLMarketplaceData::instance().activateListing(listing_uuid, false); - } } // Check if the count on hand needs to be updated on SLM @@ -364,37 +359,7 @@ void update_all_marketplace_count() { update_all_marketplace_count(marketplace_listings_uuid); } -} - -// Path should already end on '/' if it is not empty. -void append_path_short(LLUUID const& id, std::string& path) -{ - LLInventoryObject const* obj = gInventory.getObject(id); - if (!obj) return; - - LLUUID const root_id = gInventory.getRootFolderID(); - std::string const forward_slash("/"); - - std::string result; - while(1) - { - LLUUID parent_id = obj->getParentUUID(); - if (parent_id == root_id || - !(obj = gInventory.getCategory(parent_id))) - { - break; - } - std::string temp; - temp.swap(result); - result = obj->getName(); - if (!temp.empty()) - { - result.append(forward_slash); - result.append(temp); - } - } - - path.append(result); + return; } void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name) @@ -533,8 +498,9 @@ BOOL get_is_parent_to_worn_item(const LLUUID& id) return FALSE; } -BOOL get_is_item_worn(const LLInventoryItem *item) +BOOL get_is_item_worn(const LLUUID& id) { + const LLViewerInventoryItem* item = gInventory.getItem(id); if (!item) return FALSE; @@ -568,11 +534,6 @@ BOOL get_is_item_worn(const LLInventoryItem *item) return FALSE; } -BOOL get_is_item_worn(const LLUUID& id) -{ - return get_is_item_worn(gInventory.getItem(id)); -} - BOOL get_can_item_be_worn(const LLUUID& id) { const LLViewerInventoryItem* item = gInventory.getItem(id); @@ -1038,7 +999,7 @@ S32 compute_stock_count(LLUUID cat_uuid, bool force_count /* false */) // "COMPUTE_STOCK_NOT_EVALUATED" denotes that a stock folder has a count that cannot be evaluated at this time (folder not up to date) return COMPUTE_STOCK_NOT_EVALUATED; } - // Note: stock folders are *not* supposed to have nested subfolder so we stop recursion here but we count only items (subfolders will be ignored) + // Note: stock folders are *not* supposed to have nested subfolders so we stop recursion here but we count only items (subfolders will be ignored) // Note: we *always* give a stock count for stock folders, it's useful even if the listing is unassociated LLInventoryModel::cat_array_t* cat_array; LLInventoryModel::item_array_t* item_array; @@ -1144,6 +1105,14 @@ bool can_move_to_marketplace(LLInventoryItem* inv_item, std::string& tooltip_msg return false; } + // Check worn/not worn status: worn items cannot be put on the marketplace + bool worn = get_is_item_worn(inv_item->getUUID()); + if (worn) + { + tooltip_msg = LLTrans::getString("TooltipOutboxWorn"); + return false; + } + // Check library status: library items cannot be put on the marketplace if (!gInventory.isObjectDescendentOf(inv_item->getUUID(), gInventory.getRootFolderID())) { @@ -1185,15 +1154,19 @@ int get_folder_levels(LLInventoryCategory* inv_cat) int get_folder_path_length(const LLUUID& ancestor_id, const LLUUID& descendant_id) { int depth = 0; + if (ancestor_id == descendant_id) return depth; const LLInventoryCategory* category = gInventory.getCategory(descendant_id); + while (category) { LLUUID parent_id = category->getParentUUID(); + if (parent_id.isNull()) break; depth++; + if (parent_id == ancestor_id) return depth; category = gInventory.getCategory(parent_id); @@ -1279,7 +1252,9 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve LLInventoryModel::cat_array_t existing_categories; LLInventoryModel::item_array_t existing_items; + gInventory.collectDescendents(version_folder->getUUID(), existing_categories, existing_items, FALSE); + existing_item_count += count_copyable_items(existing_items) + count_stock_folders(existing_categories); existing_stock_count += count_stock_items(existing_items); existing_folder_count += existing_categories.size(); @@ -1597,7 +1572,7 @@ void dump_trace(std::string& message, S32 depth, LLError::ELevel log_level) // Make all relevant business logic checks on the marketplace listings starting with the folder as argument. // This function does no deletion of listings but a mere audit and raises issues to the user (through the // optional callback cb). It also returns a boolean, true if things validate, false if issues are raised. -// The only inventory changes that are done is to move ad sort folders containing no-copy items to stock folders. +// The only inventory changes that are done is to move and sort folders containing no-copy items to stock folders. bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_t cb, bool fix_hierarchy, S32 depth) { #if 0 @@ -1607,7 +1582,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ cb = boost::bind(&dump_trace, _1, _2, _3); } #endif - // Folder is valid unless an issues is raised + // Folder is valid unless issue is raised bool result = true; // Get the type and the depth of the folder @@ -1615,7 +1590,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ const LLFolderType::EType folder_type = cat->getPreferredType(); if (depth < 0) { - // If the depth argument was not provided, evaluate the depth directlyu + // If the depth argument was not provided, evaluate the depth directly depth = depth_nesting_in_marketplace(cat->getUUID()); } if (depth < 0) @@ -1659,7 +1634,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Warning") + " " + LLTrans::getString("Marketplace Validation Warning Stock"); cb(message, depth, LLError::LEVEL_WARN); } - // Nest the stock folder one level deeper in a normal folder ad restart from there + // Nest the stock folder one level deeper in a normal folder and restart from there LLUUID parent_uuid = cat->getParentUUID(); LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, LLFolderType::FT_NONE, cat->getName()); LLInventoryCategory* new_cat = gInventory.getCategory(folder_uuid); @@ -1762,7 +1737,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ } else { - // Done with that folder : PRint out the folder name unless we alreaady found an error here + // Done with that folder : Print out the folder name unless we already found an error here if (cb && result && (depth >= 1)) { std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Log"); @@ -1773,7 +1748,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ // If we have a single type of items of the right type in the right place, we're done else if ((count == 1) && !has_bad_items && (((unique_key == default_key) && (depth > 1)) || ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2) && (cat_array->size() == 0)))) { - // Done with that folder : Print out the folder name unless we alreaady found an error here + // Done with that folder : Print out the folder name unless we already found an error here if (cb && result && (depth >= 1)) { std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Log"); diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 11382b48c..74aca99bd 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -45,7 +45,6 @@ const S32 COMPUTE_STOCK_NOT_EVALUATED = -2; BOOL get_is_parent_to_worn_item(const LLUUID& id); // Is this item or its baseitem is worn, attached, etc... -BOOL get_is_item_worn(const LLInventoryItem *item); BOOL get_is_item_worn(const LLUUID& id); // Could this item be worn (correct type + not already being worn) @@ -71,9 +70,6 @@ void copy_inventory_category(LLInventoryModel* model, LLViewerInventoryCategory* // Generates a string containing the path to the item specified by item_id. void append_path(const LLUUID& id, std::string& path); -// Same as append_path but omits the root prefix "/My Inventory/". -void append_path_short(const LLUUID& id, std::string& path); - void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LLUUID& top_level_folder, S32 operation_id); void move_item_within_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, S32 operation_id); void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder, S32 operation_id); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index d3e45df42..dd7c32912 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -25,6 +25,9 @@ */ #include "llviewerprecompiledheaders.h" + +#include + #include "llinventorymodel.h" #include "llaisapi.h" @@ -51,7 +54,6 @@ #include "llvoavatarself.h" #include "llgesturemgr.h" #include "llsdutil.h" -#include #include "statemachine/aievent.h" // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) @@ -152,6 +154,7 @@ LLInventoryModel::LLInventoryModel() mItemLock() {} + // Destroys the object LLInventoryModel::~LLInventoryModel() { @@ -562,12 +565,13 @@ public: { } - /*virtual*/ void httpFailure(void) +protected: + virtual void httpFailure() { - LL_WARNS(LOG_INV) << "CreateInventoryCategory failed. status = " << mStatus << ", reason = \"" << mReason << "\"" << LL_ENDL; + LL_WARNS(LOG_INV) << dumpResponse() << LL_ENDL; } - /*virtual*/ void httpSuccess(void) + virtual void httpSuccess() { //Server has created folder. const LLSD& content = getContent(); @@ -596,7 +600,6 @@ public: { mCallback.get()(category_id); } - } /*virtual*/ char const* getName(void) const { return "LLCreateInventoryCategoryResponder"; } @@ -625,7 +628,7 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id, if(LLFolderType::lookup(preferred_type) == LLFolderType::badLookup()) { - LL_DEBUGS(LOG_INV) << "Attempt to create undefined category. (" << preferred_type << ")" << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Attempt to create undefined category." << LL_ENDL; return id; } @@ -1300,7 +1303,8 @@ void LLInventoryModel::changeCategoryParent(LLViewerInventoryCategory* cat, void LLInventoryModel::onAISUpdateReceived(const std::string& context, const LLSD& update) { LLTimer timer; - if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage")) + static LLCachedControl debug_ava_appr_msg(gSavedSettings, "DebugAvatarAppearanceMessage"); + if (debug_ava_appr_msg) { dump_sequential_xml(gAgentAvatarp->getFullname() + "_ais_update", update); } @@ -1553,11 +1557,11 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo // Can't have links to links, so there's no need for this update // if the item removed is a link. Can also skip if source of the // update is getting broken link info separately. - obj = NULL; // delete obj if (fix_broken_links && !is_link_type) { updateLinkedObjectsFromPurge(id); } + obj = NULL; // delete obj if (do_notify_observers) { notifyObservers(); @@ -1854,7 +1858,7 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) // Empty the entire contents void LLInventoryModel::empty() { -// LL_INFOS() << "LLInventoryModel::empty()" << LL_ENDL; +// LL_INFOS(LOG_INV) << "LLInventoryModel::empty()" << LL_ENDL; std::for_each( mParentChildCategoryTree.begin(), mParentChildCategoryTree.end(), @@ -2181,7 +2185,7 @@ bool LLInventoryModel::loadSkeleton( { bad_link_count++; invalid_categories.insert(cit->second); - //LL_INFOS() << "link still broken: " << item->getName() << " in folder " << cat->getName() << LL_ENDL; + //LL_INFOS(LOG_INV) << "link still broken: " << item->getName() << " in folder " << cat->getName() << LL_ENDL; } else { @@ -2363,22 +2367,24 @@ void LLInventoryModel::buildParentChildMap() // plop it into the lost & found. LLFolderType::EType pref = cat->getPreferredType(); if(LLFolderType::FT_NONE == pref) - { - cat->setParent(findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND)); - } - else if(LLFolderType::FT_ROOT_INVENTORY == pref) - { - // it's the root - cat->setParent(LLUUID::null); - } - else - { - // it's a protected folder. - cat->setParent(gInventory.getRootFolderID()); - } - cat->updateServer(TRUE); - catsp = getUnlockedCatArray(cat->getParentUUID()); - if(catsp) + { + cat->setParent(findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND)); + } + else if(LLFolderType::FT_ROOT_INVENTORY == pref) + { + // it's the root + cat->setParent(LLUUID::null); + } + else + { + // it's a protected folder. + cat->setParent(gInventory.getRootFolderID()); + } + // FIXME note that updateServer() fails with protected + // types, so this will not work as intended in that case. + cat->updateServer(TRUE); + catsp = getUnlockedCatArray(cat->getParentUUID()); + if(catsp) { catsp->push_back(cat); } @@ -2510,6 +2516,7 @@ void LLInventoryModel::buildParentChildMap() // root of the agent's inv found. // The inv tree is built. mIsAgentInvUsable = true; + AIEvent::trigger(AIEvent::LLInventoryModel_mIsAgentInvUsable_true); // notifyObservers() has been moved to // llstartup/idle_startup() after this func completes. @@ -4110,7 +4117,8 @@ void LLInventoryModel::FetchItemHttpHandler::httpSuccess() //If we get back an error (not found, etc...), handle it here void LLInventoryModel::FetchItemHttpHandler::httpFailure() { - LL_INFOS() << "FetchItemHttpHandler::error " + LL_WARNS(LOG_INV) << "FetchItemHttpHandler::error " << mStatus << ": " << mReason << LL_ENDL; gInventory.notifyObservers(); } + diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 13e3baba5..cdd7e1c1c 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -143,7 +143,7 @@ LLInventoryPanel::LLInventoryPanel(const std::string& name, mStartFolder(start_folder), mShowRootFolder(false), mAllowDropOnRoot(true), - mAllowOpen(true), + mAllowWear(true), mUseMarketplaceFolders(false), mInventory(inventory), mAllowMultiSelect(allow_multi_select), @@ -361,7 +361,7 @@ LLView* LLInventoryPanel::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac // Singu TODO: Turn these into mParams like upstream. node->getAttribute_bool("show_root_folder", panel->mShowRootFolder); node->getAttribute_bool("allow_drop_on_root", panel->mAllowDropOnRoot); - node->getAttribute_bool("allow_open", panel->mAllowOpen); + node->getAttribute_bool("allow_wear", panel->mAllowWear); node->getAttribute_bool("use_marketplace_folders", panel->mUseMarketplaceFolders); panel->initFromXML(node, parent); @@ -401,12 +401,12 @@ void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType U32 LLInventoryPanel::getFilterObjectTypes() const { - return mFolderRoot.get()->getFilterObjectTypes(); + return getFilter().getFilterObjectTypes(); } U32 LLInventoryPanel::getFilterPermMask() const { - return mFolderRoot.get()->getFilterPermissions(); + return getFilter().getFilterPermissions(); } @@ -420,9 +420,9 @@ void LLInventoryPanel::setFilterWearableTypes(U64 types) getFilter().setFilterWearableTypes(types); } -void LLInventoryPanel::setFilterWorn(bool worn) +void LLInventoryPanel::setFilterWornItems() { - getFilter().setFilterWorn(worn); + getFilter().setFilterWornItems(); } void LLInventoryPanel::setFilterSubString(const std::string& string) @@ -463,7 +463,7 @@ void LLInventoryPanel::setFilterSubString(const std::string& string) const std::string LLInventoryPanel::getFilterSubString() { - return mFolderRoot.get()->getFilterSubString(); + return getFilter().getFilterSubString(); } void LLInventoryPanel::setSortOrder(U32 order) @@ -497,7 +497,12 @@ void LLInventoryPanel::setHoursAgo(U32 hours) getFilter().setHoursAgo(hours); } -void LLInventoryPanel::setFilterLinks(U64 filter_links) +void LLInventoryPanel::setDateSearchDirection(U32 direction) +{ + getFilter().setDateSearchDirection(direction); +} + +void LLInventoryPanel::setFilterLinks(LLInventoryFilter::EFilterLink filter_links) { getFilter().setFilterLinks(filter_links); } @@ -561,7 +566,7 @@ void LLInventoryPanel::modelChanged(U32 mask) ////////////////////////////// // DESCRIPTION Operation (singu only) // Alert listener. - if ((mask & LLInventoryObserver::DESCRIPTION)) + else if (mask & LLInventoryObserver::DESCRIPTION) { if (view_item) { @@ -859,7 +864,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id) { // Singu Note: new_listener disappeared in the last merge, be sure that adding it back here doesn't break anything. ~Liru LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(), - objectp->getType(), + (mUseMarketplaceFolders ? LLAssetType::AT_MARKETPLACE_FOLDER : LLAssetType::AT_CATEGORY), LLInventoryType::IT_CATEGORY, this, mFolderRoot.get(), @@ -870,7 +875,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id) { folderp->setItemSortOrder(mFolderRoot.get()->getSortOrder()); folderp->setAllowDrop(allow_drop); - folderp->setAllowOpen(mAllowOpen); + folderp->setAllowWear(mAllowWear); } folder_view_item = folderp; } @@ -1028,7 +1033,7 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, // If folder view is empty the (x, y) point won't be in its rect // so the handler must be called explicitly. // but only if was not handled before. See EXT-6746. - if (!handled && /*mParams.allow_drop_on_root*/mAllowDropOnRoot && !mFolderRoot.get()->hasVisibleChildren()) + if (!handled && mAllowDropOnRoot && !mFolderRoot.get()->hasVisibleChildren()) { handled = mFolderRoot.get()->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); } @@ -1088,7 +1093,7 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc { return; } - mFolderRoot.get()->setSelectionByID(obj_id, take_keyboard_focus); + setSelectionByID(obj_id, take_keyboard_focus); } void LLInventoryPanel::setSelectCallback(const boost::function& items, BOOL user_action)>& cb) @@ -1120,7 +1125,7 @@ void LLInventoryPanel::onSelectionChange(const std::deque& it } } - LLFolderView* fv = getRootFolder(); + LLFolderView* fv = mFolderRoot.get(); if (fv->needsAutoRename()) // auto-selecting a new user-created asset and preparing to rename { fv->setNeedsAutoRename(FALSE); diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 8f571e075..f00b62f92 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -115,13 +115,13 @@ public: void setFilterWearableTypes(U64 filter); void setFilterSubString(const std::string& string); const std::string getFilterSubString(); - void setFilterWorn(bool worn); - bool getFilterWorn() const { return mFolderRoot.get()->getFilterWorn(); } + void setFilterWornItems(); void setSinceLogoff(BOOL sl); void setHoursAgo(U32 hours); + void setDateSearchDirection(U32 direction); BOOL getSinceLogoff(); - void setFilterLinks(U64 filter_links); + void setFilterLinks(LLInventoryFilter::EFilterLink filter_links); void setShowFolderState(LLInventoryFilter::EFolderShow show); LLInventoryFilter::EFolderShow getShowFolderState(); @@ -213,7 +213,7 @@ private: const std::string mStartFolder; bool mShowRootFolder; bool mAllowDropOnRoot; - bool mAllowOpen; + bool mAllowWear; bool mUseMarketplaceFolders; const std::string mSortOrderSetting; diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index f96730da8..21f226e3c 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -176,7 +176,7 @@ BOOL LLPanelMainInventory::postBuild() worn_items_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::WORNITEMS_SORT_ORDER)); worn_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); worn_items_panel->getFilter().markDefault(); - worn_items_panel->setFilterWorn(true); + worn_items_panel->setFilterWornItems(); worn_items_panel->setFilterLinks(LLInventoryFilter::FILTERLINK_EXCLUDE_LINKS); worn_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, worn_items_panel, _1, _2)); } diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index f9c145b54..942556a43 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -40,6 +40,7 @@ #include "roles_constants.h" #include "llagent.h" +#include "llavataractions.h" #include "llcallbacklist.h" #include "llfloaterbuycontents.h" #include "llfloaterbuycurrency.h" @@ -203,27 +204,11 @@ void LLTaskInvFVBridge::showProperties() } } -struct LLBuyInvItemData -{ - LLUUID mTaskID; - LLUUID mItemID; - LLAssetType::EType mType; - - LLBuyInvItemData(const LLUUID& task, - const LLUUID& item, - LLAssetType::EType type) : - mTaskID(task), mItemID(item), mType(type) - {} -}; - void LLTaskInvFVBridge::buyItem() { LL_INFOS() << "LLTaskInvFVBridge::buyItem()" << LL_ENDL; LLInventoryItem* item = findItem(); if(!item || !item->getSaleInfo().isForSale()) return; - LLBuyInvItemData* inv = new LLBuyInvItemData(mPanel->getTaskUUID(), - mUUID, - item->getType()); const LLSaleInfo& sale_info = item->getSaleInfo(); const LLPermissions& perm = item->getPermissions(); @@ -234,7 +219,6 @@ void LLTaskInvFVBridge::buyItem() { LLNotificationsUtil::add("Cannot_Purchase_an_Attachment"); LL_INFOS() << "Attempt to purchase an attachment" << LL_ENDL; - delete inv; } else { @@ -265,9 +249,9 @@ void LLTaskInvFVBridge::buyItem() } LLSD payload; - payload["task_id"] = inv->mTaskID; - payload["item_id"] = inv->mItemID; - payload["type"] = inv->mType; + payload["task_id"] = mPanel->getTaskUUID(); + payload["item_id"] = mUUID; + payload["type"] = item->getType(); LLNotificationsUtil::add(alertdesc, args, payload, LLTaskInvFVBridge::commitBuyItem); } } @@ -606,7 +590,7 @@ BOOL LLTaskInvFVBridge::isClipboardPasteable() const return FALSE; } -void LLTaskInvFVBridge::pasteFromClipboard(bool only_copies) +void LLTaskInvFVBridge::pasteFromClipboard(bool) { } @@ -667,11 +651,6 @@ BOOL LLTaskInvFVBridge::dragOrDrop(MASK mask, BOOL drop, return FALSE; } -//void LLTaskInvFVBridge::dropped() -//{ -// LL_WARNS() << "LLTaskInvFVBridge::dropped() - not implemented" << LL_ENDL; -//} - void pack_script_message(LLMessageSystem*, const LLInventoryItem*, const LLViewerObject*); void reset_script(const LLInventoryItem* item, const LLViewerObject* obj) @@ -761,7 +740,7 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) return; } - if(gAgent.allowOperation(PERM_OWNER, item->getPermissions(), + if(!gAgent.allowOperation(PERM_OWNER, item->getPermissions(), GP_OBJECT_MANIPULATE) && item->getSaleInfo().isForSale()) { @@ -980,16 +959,6 @@ BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop, case DAD_CALLINGCARD: case DAD_MESH: accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data); - // testzone - //if(LLToolDragAndDrop::isInventoryDropAcceptable( - // object, (LLViewerInventoryItem*)cargo_data) - /*if(object->permModify() - // - && (LLToolDragAndDrop::SOURCE_WORLD != LLToolDragAndDrop::getInstance()->getSource()) - && (LLToolDragAndDrop::SOURCE_NOTECARD != LLToolDragAndDrop::getInstance()->getSource())) - { - accept = TRUE; - }*/ if(accept && drop) { LLToolDragAndDrop::dropInventory(object, @@ -1172,7 +1141,6 @@ void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else if (canOpenItem()) { - //items.push_back(std::string("Task Open")); if (!isItemCopyable()) { disabled_items.push_back(std::string("Task Open")); @@ -1238,6 +1206,7 @@ BOOL LLTaskCallingCardBridge::renameItem(const std::string& new_name) return FALSE; } + ///---------------------------------------------------------------------------- /// Class LLTaskScriptBridge ///---------------------------------------------------------------------------- @@ -1665,7 +1634,7 @@ void LLPanelObjectInventory::clearContents() if( mScroller ) { // removes mFolders - removeChild( mScroller ); + removeChild( mScroller ); //*TODO: Really shouldn't do this during draw()/refresh() mScroller->die(); mScroller = NULL; mFolders = NULL; @@ -1749,27 +1718,27 @@ void LLPanelObjectInventory::updateInventory() inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders); } - reset(); - LLViewerObject* objectp = gObjectList.findObject(mTaskUUID); if (objectp) { LLInventoryObject* inventory_root = objectp->getInventoryRoot(); LLInventoryObject::object_list_t contents; objectp->getInventoryContents(contents); + if (inventory_root) { - createFolderViews(inventory_root, contents); - mHaveInventory = TRUE; + reset(); mIsInventoryEmpty = FALSE; + createFolderViews(inventory_root, contents); mFolders->setEnabled(TRUE); } else { // TODO: create an empty inventory mIsInventoryEmpty = TRUE; - mHaveInventory = TRUE; } + + mHaveInventory = TRUE; } else { @@ -1780,10 +1749,11 @@ void LLPanelObjectInventory::updateInventory() // restore previous selection std::set::iterator selection_it; - BOOL first_item = TRUE; + bool first_item = true; for (selection_it = selected_items.begin(); selection_it != selected_items.end(); ++selection_it) { LLFolderViewItem* selected_item = mFolders->getItemByID(*selection_it); + if (selected_item) { //HACK: "set" first item then "change" each other one to get keyboard focus right @@ -1799,8 +1769,12 @@ void LLPanelObjectInventory::updateInventory() } } - mFolders->requestArrange(); + if (mFolders) + { + mFolders->requestArrange(); + } mInventoryNeedsUpdate = FALSE; + // Edit menu handler is set in onFocusReceived } // *FIX: This is currently a very expensive operation, because we have @@ -1942,13 +1916,18 @@ void LLPanelObjectInventory::refresh() } if(!has_inventory) { - mTaskUUID = LLUUID::null; - removeVOInventoryListener(); - clearContents(); + clearInventoryTask(); } //LL_INFOS() << "LLPanelObjectInventory::refresh() " << mTaskUUID << LL_ENDL; } +void LLPanelObjectInventory::clearInventoryTask() +{ + mTaskUUID = LLUUID::null; + removeVOInventoryListener(); + clearContents(); +} + void LLPanelObjectInventory::removeSelectedItem() { if(mFolders) @@ -2033,7 +2012,6 @@ void LLPanelObjectInventory::idle(void* user_data) { LLPanelObjectInventory* self = (LLPanelObjectInventory*)user_data; - if (self->mInventoryNeedsUpdate) { self->updateInventory(); diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h index 736900c76..e43c1b37f 100644 --- a/indra/newview/llpanelobjectinventory.h +++ b/indra/newview/llpanelobjectinventory.h @@ -52,6 +52,7 @@ public: void refresh(); const LLUUID& getTaskUUID() { return mTaskUUID;} + void clearInventoryTask(); void removeSelectedItem(); void startRenamingSelectedItem(); @@ -77,7 +78,6 @@ protected: void createViewsForCategory(LLInventoryObject::object_list_t* inventory, LLInventoryObject* parent, LLFolderViewFolder* folder); - void clearContents(); private: diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index fd6dc3188..c8f7334b8 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -367,7 +367,7 @@ void LLToolDragAndDrop::setDragStart(S32 x, S32 y) BOOL LLToolDragAndDrop::isOverThreshold(S32 x,S32 y) { - static LLCachedControl drag_and_drop_threshold(gSavedSettings,"DragAndDropDistanceThreshold"); + static LLCachedControl drag_and_drop_threshold(gSavedSettings,"DragAndDropDistanceThreshold", 3); S32 mouse_delta_x = x - mDragStartX; S32 mouse_delta_y = y - mDragStartY; @@ -2743,7 +2743,8 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory( item = NULL; cat = NULL; - if (mCargoIDs.empty()) + if (mCargoIDs.empty() + || (mSource == SOURCE_PEOPLE)) ///< There is no inventory item for people drag and drop. { return NULL; } @@ -2773,7 +2774,7 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory( } else if(mSource == SOURCE_NOTECARD) { - LLPreviewNotecard* preview = dynamic_cast(LLPreview::find(mSourceID)); + LLPreviewNotecard* preview = static_cast(LLPreview::find(mSourceID)); if(preview) { item = (LLViewerInventoryItem*)preview->getDragItem();