EXT-4492 : Deleting gestures from the wearing tab causes the viewer to crash

EXT-4660 : Can delete a bodypart from the COF through inventory view or WEARING tab delete key
EXT-4662 : remove leading separator from COF right-click menu
EXT-4633 : AppearanceSP trash button doesn't update enabled state correctly

Bunch of UI fixes related to the trash/delete functionality in InventoryFloater/SP and AppearanceSP "WEARING" tab.  The main idea is that we don't want to allow deletion of bodyparts and folder links from the COF by the user.
meow-7.2.2
Loren Shih 2010-01-22 14:44:32 -05:00
parent c64638dc21
commit 0283837e56
8 changed files with 83 additions and 44 deletions

View File

@ -358,7 +358,7 @@ static void onWearableAssetFetch(LLWearable* wearable, void* data)
}
}
LLUUID LLAppearanceManager::getCOF()
const LLUUID LLAppearanceManager::getCOF() const
{
return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
}
@ -1263,3 +1263,23 @@ void LLAppearanceManager::linkRegisteredAttachments()
}
mRegisteredAttachments.clear();
}
BOOL LLAppearanceManager::getIsInCOF(const LLUUID& obj_id) const
{
return gInventory.isObjectDescendentOf(obj_id, getCOF());
}
BOOL LLAppearanceManager::getIsProtectedCOFItem(const LLUUID& obj_id) const
{
if (!getIsInCOF(obj_id)) return FALSE;
const LLInventoryObject *obj = gInventory.getObject(obj_id);
if (!obj) return FALSE;
// Can't delete bodyparts, since this would be equivalent to removing the item.
if (obj->getType() == LLAssetType::AT_BODYPART) return TRUE;
// Can't delete the folder link, since this is saved for bookkeeping.
if (obj->getActualType() == LLAssetType::AT_LINK_FOLDER) return TRUE;
return FALSE;
}

View File

@ -59,7 +59,7 @@ public:
LLPointer<LLInventoryCallback> cb);
// Find the Current Outfit folder.
LLUUID getCOF();
const LLUUID getCOF() const;
// Finds the folder link to the currently worn outfit
const LLViewerInventoryItem *getBaseOutfitLink();
@ -132,6 +132,14 @@ private:
std::set<LLUUID> mRegisteredAttachments;
bool mAttachmentInvLinkEnabled;
bool mOutfitIsDirty;
//////////////////////////////////////////////////////////////////////////////////
// Item-specific convenience functions
public:
// Is this in the COF?
BOOL getIsInCOF(const LLUUID& obj_id) const;
// Is this in the COF and can the user delete it from the COF?
BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const;
};
#define SUPPORT_ENSEMBLES 0

View File

@ -185,6 +185,11 @@ BOOL LLInvFVBridge::isItemRemovable()
{
return FALSE;
}
if (LLAppearanceManager::instance().getIsProtectedCOFItem(mUUID))
{
return FALSE;
}
const LLInventoryObject *obj = model->getItem(mUUID);
if (obj && obj->getIsLinkType())
{
@ -712,14 +717,7 @@ BOOL LLInvFVBridge::isAgentInventory() const
BOOL LLInvFVBridge::isCOFFolder() const
{
const LLInventoryModel* model = getInventoryModel();
if(!model) return TRUE;
const LLUUID cof_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
if (mUUID == cof_id || model->isObjectDescendentOf(mUUID, cof_id))
{
return TRUE;
}
return FALSE;
return LLAppearanceManager::instance().getIsInCOF(mUUID);
}
BOOL LLInvFVBridge::isItemPermissive() const
@ -4622,7 +4620,10 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
getClipboardEntries(true, items, disabled_items, flags);
items.push_back(std::string("Wearable Separator"));
if (!is_sidepanel)
{
items.push_back(std::string("Wearable Separator"));
}
items.push_back(std::string("Wearable Edit"));

View File

@ -682,6 +682,14 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc
mFolders->setSelectionByID(obj_id, take_keyboard_focus);
}
void LLInventoryPanel::setSelectCallback(const LLFolderView::signal_t::slot_type& cb)
{
if (mFolders)
{
mFolders->setSelectCallback(cb);
}
}
void LLInventoryPanel::clearSelection()
{
mFolders->clearSelection();

View File

@ -123,7 +123,7 @@ public:
// Call this method to set the selection.
void openAllFolders();
void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus);
void setSelectCallback(const LLFolderView::signal_t::slot_type& cb) { if (mFolders) mFolders->setSelectCallback(cb); }
void setSelectCallback(const LLFolderView::signal_t::slot_type& cb);
void clearSelection();
LLInventoryFilter* getFilter();
void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT);

View File

@ -61,6 +61,9 @@
#include "llviewercontrol.h"
static const std::string OUTFITS_TAB_NAME = "outfitslist_tab";
static const std::string COF_TAB_NAME = "cof_tab";
static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
bool LLPanelOutfitsInventory::sShowDebugEditor = false;
@ -267,7 +270,7 @@ void LLPanelOutfitsInventory::onSaveCommit(const std::string& outfit_name)
if (mAppearanceTabs)
{
mAppearanceTabs->selectTabByName("outfitslist_tab");
mAppearanceTabs->selectTabByName(OUTFITS_TAB_NAME);
}
}
@ -503,8 +506,7 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
if (command_name == "wear")
{
const BOOL is_my_outfits = (mActivePanel->getName() == "outfitslist_tab");
if (!is_my_outfits)
if (isCOFPanelActive())
{
return FALSE;
}
@ -558,17 +560,15 @@ bool LLPanelOutfitsInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropTy
void LLPanelOutfitsInventory::initTabPanels()
{
mTabPanels.resize(2);
LLInventoryPanel *cof_panel = getChild<LLInventoryPanel>("cof_tab");
LLInventoryPanel *cof_panel = getChild<LLInventoryPanel>(COF_TAB_NAME);
cof_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
mTabPanels[0] = cof_panel;
LLInventoryPanel *myoutfits_panel = getChild<LLInventoryPanel>("outfitslist_tab");
mTabPanels.push_back(cof_panel);
LLInventoryPanel *myoutfits_panel = getChild<LLInventoryPanel>(OUTFITS_TAB_NAME);
myoutfits_panel->setFilterTypes(1LL << LLFolderType::FT_OUTFIT, LLInventoryFilter::FILTERTYPE_CATEGORY);
myoutfits_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
mTabPanels[1] = myoutfits_panel;
mTabPanels.push_back(myoutfits_panel);
for (tabpanels_vec_t::iterator iter = mTabPanels.begin();
iter != mTabPanels.end();
++iter)
@ -615,19 +615,19 @@ void LLPanelOutfitsInventory::onTabChange()
updateVerbs();
}
LLInventoryPanel* LLPanelOutfitsInventory::getActivePanel()
BOOL LLPanelOutfitsInventory::isTabPanel(LLInventoryPanel *panel) const
{
return mActivePanel;
}
bool LLPanelOutfitsInventory::isTabPanel(LLInventoryPanel *panel)
{
for(tabpanels_vec_t::iterator it = mTabPanels.begin();
for(tabpanels_vec_t::const_iterator it = mTabPanels.begin();
it != mTabPanels.end();
++it)
{
if (*it == panel)
return true;
return TRUE;
}
return false;
return FALSE;
}
BOOL LLPanelOutfitsInventory::isCOFPanelActive() const
{
return (getActivePanel()->getName() == COF_TAB_NAME);
}

View File

@ -78,24 +78,26 @@ protected:
bool getIsCorrectType(const LLFolderViewEventListener *listenerp) const;
private:
LLSidepanelAppearance* mParent;
LLSaveFolderState* mSavedFolderState;
LLTabContainer* mAppearanceTabs;
std::string mFilterSubString;
LLSidepanelAppearance* mParent;
LLSaveFolderState* mSavedFolderState;
LLTabContainer* mAppearanceTabs;
std::string mFilterSubString;
public:
//////////////////////////////////////////////////////////////////////////////////
// tab panels
LLInventoryPanel* getActivePanel();
bool isTabPanel(LLInventoryPanel *panel);
LLInventoryPanel* getActivePanel() { return mActivePanel; }
const LLInventoryPanel* getActivePanel() const { return mActivePanel; }
BOOL isTabPanel(LLInventoryPanel *panel) const;
protected:
void initTabPanels();
void onTabSelectionChange(LLInventoryPanel* tab_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action);
void onTabChange();
void initTabPanels();
void onTabSelectionChange(LLInventoryPanel* tab_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action);
void onTabChange();
BOOL isCOFPanelActive() const;
private:
LLInventoryPanel* mActivePanel;
LLInventoryPanel* mActivePanel;
typedef std::vector<LLInventoryPanel *> tabpanels_vec_t;
tabpanels_vec_t mTabPanels;

View File

@ -45,7 +45,7 @@
left="0"
top="0"
mouse_opaque="true"
name="cof_accordionpanel"
name="cof_tab"
start_folder="Current Outfit"
width="313" />
</tab_container>