diff options
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
-rw-r--r-- | indra/newview/app_settings/foldertypes.xml | 58 | ||||
-rw-r--r-- | indra/newview/llfloaterinventory.cpp | 28 | ||||
-rw-r--r-- | indra/newview/llfloaterproperties.cpp | 1 | ||||
-rw-r--r-- | indra/newview/llfolderview.cpp | 41 | ||||
-rw-r--r-- | indra/newview/llfolderview.h | 3 | ||||
-rw-r--r-- | indra/newview/llfolderviewitem.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llfolderviewitem.h | 14 | ||||
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 257 | ||||
-rw-r--r-- | indra/newview/llinventorybridge.h | 26 | ||||
-rw-r--r-- | indra/newview/llinventorymodel.cpp | 35 | ||||
-rw-r--r-- | indra/newview/llinventorymodel.h | 6 | ||||
-rw-r--r-- | indra/newview/lltooldraganddrop.cpp | 10 | ||||
-rw-r--r-- | indra/newview/llviewerinventory.cpp | 14 | ||||
-rw-r--r-- | indra/newview/llviewerinventory.h | 1 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/menu_inventory.xml | 101 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/strings.xml | 2 |
17 files changed, 523 insertions, 78 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 5dec4a8688..d06571fb7a 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -211,6 +211,7 @@ set(viewer_SOURCE_FILES llfloaterwater.cpp llfloaterwindlight.cpp llfloaterworldmap.cpp + llfoldertype.cpp llfolderview.cpp llfolderviewitem.cpp llfollowcam.cpp @@ -646,6 +647,7 @@ set(viewer_HEADER_FILES llfloaterwater.h llfloaterwindlight.h llfloaterworldmap.h + llfoldertype.h llfolderview.h llfoldervieweventlistener.h llfolderviewitem.h diff --git a/indra/newview/app_settings/foldertypes.xml b/indra/newview/app_settings/foldertypes.xml new file mode 100644 index 0000000000..4d4d479bdd --- /dev/null +++ b/indra/newview/app_settings/foldertypes.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<ensemble_defs> + <ensemble + asset_num="-1" + xui_name="default" + icon_name="inv_plain_closed.tga" + /> + <ensemble + asset_num="27" + xui_name="head" + icon_name="inv_folder_outfit_head.tga" + /> + <ensemble + asset_num="28" + xui_name="gloves" + icon_name="inv_folder_outfit_gloves.tga" + /> + <ensemble + asset_num="29" + xui_name="jacket" + icon_name="inv_folder_outfit_jacket.tga" + /> + <ensemble + asset_num="30" + xui_name="pants" + icon_name="inv_folder_outfit_pants.tga" + /> + <ensemble + asset_num="31" + xui_name="shape" + icon_name="inv_folder_outfit_shape.tga" + /> + <ensemble + asset_num="32" + xui_name="shoes" + icon_name="inv_folder_outfit_shoes.tga" + /> + <ensemble + asset_num="33" + xui_name="shirt" + icon_name="inv_folder_outfit_shirt.tga" + /> + <ensemble + asset_num="34" + xui_name="skirt" + icon_name="inv_folder_outfit_skirt.tga" + /> + <ensemble + asset_num="35" + xui_name="underpants" + icon_name="inv_folder_outfit_underpants.tga" + /> + <ensemble + asset_num="36" + xui_name="undershirt" + icon_name="inv_folder_outfit_undershirt.tga" + /> +</ensemble_defs> diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp index d326e0e970..d05a32dc88 100644 --- a/indra/newview/llfloaterinventory.cpp +++ b/indra/newview/llfloaterinventory.cpp @@ -1533,12 +1533,14 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id) << ((S32) objectp->getType()) << " (shouldn't happen)" << llendl; } - else if (objectp->getType() == LLAssetType::AT_CATEGORY) // build new view for category + else if (objectp->getType() == LLAssetType::AT_CATEGORY && + objectp->getActualType() != LLAssetType::AT_LINK_FOLDER) { LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(objectp->getType(), - LLInventoryType::IT_CATEGORY, - this, - objectp->getUUID()); + objectp->getType(), + LLInventoryType::IT_CATEGORY, + this, + objectp->getUUID()); if (new_listener) { @@ -1553,15 +1555,17 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id) itemp = folderp; } } - else // build new view for item + else { + // Build new view for item LLInventoryItem* item = (LLInventoryItem*)objectp; - LLInvFVBridge* new_listener = LLInvFVBridge::createBridge( - item->getType(), - item->getInventoryType(), - this, - item->getUUID(), - item->getFlags()); + LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(item->getType(), + item->getActualType(), + item->getInventoryType(), + this, + item->getUUID(), + item->getFlags()); + if (new_listener) { LLFolderViewItem::Params params; @@ -1591,7 +1595,7 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id) } } if ((id.isNull() || - (objectp && objectp->getType() == LLAssetType::AT_CATEGORY))) + (objectp && objectp->getType() == LLAssetType::AT_CATEGORY))) { LLViewerInventoryCategory::cat_array_t* categories; LLViewerInventoryItem::item_array_t* items; diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp index efc273c6e5..ca7c929d74 100644 --- a/indra/newview/llfloaterproperties.cpp +++ b/indra/newview/llfloaterproperties.cpp @@ -658,6 +658,7 @@ void LLFloaterProperties::onCommitName(LLUICtrl* ctrl, void* data) { new_item->updateServer(FALSE); gInventory.updateItem(new_item); + gInventory.updateLinkedObjects(new_item->getUUID()); gInventory.notifyObservers(); } else diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 6ef011f1de..c54eafb67a 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -34,10 +34,12 @@ #include "llfolderview.h" +#include "llagent.h" #include "llcallbacklist.h" #include "llinventorybridge.h" #include "llinventoryclipboard.h" // *TODO: remove this once hack below gone. #include "llinventoryfilter.h" +#include "llfoldertype.h" #include "llfloaterinventory.h"// hacked in for the bonus context menu items. #include "llkeyboard.h" #include "lllineeditor.h" @@ -1094,6 +1096,35 @@ void LLFolderView::propertiesSelectedItems( void ) } } +void LLFolderView::changeType(LLInventoryModel *model, LLAssetType::EType new_folder_type) +{ + LLFolderBridge *folder_bridge = LLFolderBridge::sSelf; + + if (!folder_bridge) return; + LLViewerInventoryCategory *cat = folder_bridge->getCategory(); + if (!cat) return; + + const LLUUID &folder_id = cat->getUUID(); + const LLUUID &parent_id = cat->getParentUUID(); + const std::string &name = cat->getName(); + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_UpdateInventoryFolder); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_FolderData); + msg->addUUIDFast(_PREHASH_FolderID, folder_id); + msg->addUUIDFast(_PREHASH_ParentID, parent_id); + msg->addS8Fast(_PREHASH_Type, new_folder_type); + msg->addStringFast(_PREHASH_Name, name); + gAgent.sendReliableMessage(); + + cat->setPreferredType(new_folder_type); + gInventory.addChangedMask(LLInventoryObserver::LABEL, folder_id); + gInventory.updateLinkedObjects(folder_id); +} + void LLFolderView::autoOpenItem( LLFolderViewFolder* item ) { if (mAutoOpenItems.check() == item || mAutoOpenItems.getDepth() >= (U32)AUTO_OPEN_STACK_DEPTH) @@ -1904,6 +1935,16 @@ bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata) LLInventoryClipboard::instance().reset(); } + static const std::string change_folder_string = "change_folder_type_"; + if (action.length() > change_folder_string.length() && + (action.compare(0,change_folder_string.length(),"change_folder_type_") == 0)) + { + LLAssetType::EType new_folder_type = LLFolderType::lookupTypeFromXUIName(action.substr(change_folder_string.length())); + changeType(model, new_folder_type); + return true; + } + + std::set<LLUUID> selected_items; getSelectionList(selected_items); diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index d944a4fa18..8d9d52cd17 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -190,6 +190,9 @@ public: void openSelectedItems( void ); void propertiesSelectedItems( void ); + // change the folder type + void changeType(LLInventoryModel *model, LLAssetType::EType new_folder_type); + void autoOpenItem(LLFolderViewFolder* item); void closeAutoOpenedFolders(); BOOL autoOpenTest(LLFolderViewFolder* item); diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index 7032e86958..43f3ea8d8f 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -230,7 +230,7 @@ void LLFolderViewItem::refreshFromListener() // *TODO: to be removed when database supports multi language. This is a // temporary attempt to display the inventory folder in the user locale. - if (preferred_type != LLAssetType::AT_NONE) + if (LLAssetType::lookupIsProtectedCategoryType(preferred_type)) { mLabel = LLTrans::getString("InvFolder " + mLabel); }; diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index 57807005c2..31866c83c8 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -157,13 +157,6 @@ protected: BOOL mIsLoading; LLTimer mTimeSinceRequestStart; - // This function clears the currently selected item, and records - // the specified selected item appropriately for display and use - // in the UI. If open is TRUE, then folders are opened up along - // the way to the selection. - void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem, - BOOL take_keyboard_focus = TRUE); - // helper function to change the selection from the root. void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected); @@ -176,6 +169,13 @@ protected: virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; } public: + // This function clears the currently selected item, and records + // the specified selected item appropriately for display and use + // in the UI. If open is TRUE, then folders are opened up along + // the way to the selection. + void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem, + BOOL take_keyboard_focus = TRUE); + // This function is called when the folder view is dirty. It's // implemented here but called by derived classes when folding the // views. diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index b705543e44..edbeed2aa4 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -51,6 +51,7 @@ #include "llviewercontrol.h" #include "llfirstuse.h" +#include "llfoldertype.h" #include "llfloaterchat.h" #include "llfloatercustomize.h" #include "llfloaterproperties.h" @@ -604,7 +605,7 @@ BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const if(obj) { - *type = LLAssetType::lookupDragAndDropType(obj->getType()); + *type = LLAssetType::lookupDragAndDropType(obj->getActualType()); if(*type == DAD_NONE) { return FALSE; @@ -653,11 +654,11 @@ BOOL LLInvFVBridge::isLinkedObjectInTrash() const { if (isInTrash()) return TRUE; - LLInventoryModel* model = getInventoryModel(); - if(!model) return FALSE; - LLInventoryObject *obj = model->getObject(mUUID); + LLInventoryObject *obj = getInventoryObject(); if (obj && LLAssetType::lookupIsLinkType(obj->getActualType())) { + LLInventoryModel* model = getInventoryModel(); + if(!model) return FALSE; const LLUUID& trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); return model->isObjectDescendentOf(obj->getLinkedUUID(), trash_id); } @@ -735,6 +736,7 @@ const std::string safe_inv_type_lookup(LLInventoryType::EType inv_type) } LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, + LLAssetType::EType actual_asset_type, LLInventoryType::EType inv_type, LLInventoryPanel* inventory, const LLUUID& uuid, @@ -833,12 +835,22 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, break; case LLAssetType::AT_CATEGORY: case LLAssetType::AT_ROOT_CATEGORY: + if (actual_asset_type == LLAssetType::AT_LINK_FOLDER) + { + // Create a link folder handler instead. + new_listener = new LLLinkFolderBridge(inventory, uuid); + break; + } new_listener = new LLFolderBridge(inventory, uuid); break; case LLAssetType::AT_LINK: // Only should happen for broken links. new_listener = new LLLinkItemBridge(inventory, uuid); break; + case LLAssetType::AT_LINK_FOLDER: + // Only should happen for broken links. + new_listener = new LLLinkItemBridge(inventory, uuid); + break; default: llinfos << "Unhandled asset type (llassetstorage.h): " << (S32)asset_type << llendl; @@ -875,6 +887,10 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid) void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) { + if ("goto" == action) + { + gotoItem(folder); + } if ("open" == action) { openItem(); @@ -1005,6 +1021,19 @@ void LLItemBridge::restoreToWorld() } } +void LLItemBridge::gotoItem(LLFolderView *folder) +{ + LLInventoryObject *obj = getInventoryObject(); + if (obj && LLAssetType::lookupIsLinkType(obj->getActualType())) + { + LLInventoryPanel* active_panel = LLFloaterInventory::getActiveInventory()->getPanel(); + if (active_panel) + { + active_panel->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO); + } + } +} + LLUIImagePtr LLItemBridge::getIcon() const { return LLUI::getUIImage(ICON_NAME[OBJECT_ICON_NAME]); @@ -1075,7 +1104,8 @@ std::string LLItemBridge::getLabelSuffix() const static std::string NO_COPY =LLTrans::getString("no_copy"); static std::string NO_MOD = LLTrans::getString("no_modify"); static std::string NO_XFER = LLTrans::getString("no_transfer"); - + static std::string LINK = LLTrans::getString("link"); + static std::string BROKEN_LINK = LLTrans::getString("broken_link"); std::string suffix; LLInventoryItem* item = getItem(); if(item) @@ -1084,8 +1114,10 @@ std::string LLItemBridge::getLabelSuffix() const if(LLAssetType::AT_CALLINGCARD != item->getType() && item->getPermissions().getOwner() == gAgent.getID()) { - BOOL link = (item->getActualType() == LLAssetType::AT_LINK); - const char* LINK = " (link)"; // *TODO: Seraph translate + BOOL broken_link = LLAssetType::lookupIsLinkType(item->getType()); + if (broken_link) return BROKEN_LINK; + + BOOL link = LLAssetType::lookupIsLinkType(item->getActualType()); if (link) return LINK; BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID()); @@ -1146,7 +1178,7 @@ BOOL LLItemBridge::renameItem(const std::string& new_name) buildDisplayName(new_item, mDisplayName); new_item->updateServer(FALSE); model->updateItem(new_item); - renameLinkedItems(item->getUUID(),new_name); + model->updateLinkedObjects(item->getUUID()); model->notifyObservers(); } @@ -1204,7 +1236,7 @@ BOOL LLItemBridge::isItemCopyable() const // All items can be copied, not all can be pasted. // The only time an item can't be copied is if it's a link // return (item->getPermissions().allowCopyBy(gAgent.getID())); - if (item->getActualType() == LLAssetType::AT_LINK) + if (LLAssetType::lookupIsLinkType(item->getActualType())) { return FALSE; } @@ -1259,7 +1291,7 @@ BOOL LLFolderBridge::isItemMovable() LLInventoryObject* obj = getInventoryObject(); if(obj) { - return (LLAssetType::AT_NONE == ((LLInventoryCategory*)obj)->getPreferredType()); + return (!LLAssetType::lookupIsProtectedCategoryType(((LLInventoryCategory*)obj)->getPreferredType())); } return FALSE; } @@ -1295,7 +1327,7 @@ BOOL LLFolderBridge::isItemRemovable() return FALSE; } - if( LLAssetType::AT_NONE != category->getPreferredType() ) + if(LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType())) { return FALSE; } @@ -1308,7 +1340,7 @@ BOOL LLFolderBridge::isItemRemovable() for( i = 0; i < descendent_categories.count(); i++ ) { LLInventoryCategory* category = descendent_categories[i]; - if( LLAssetType::AT_NONE != category->getPreferredType() ) + if(LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType())) { return FALSE; } @@ -1403,7 +1435,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id); - BOOL is_movable = (LLAssetType::AT_NONE == inv_cat->getPreferredType()); + BOOL is_movable = (!LLAssetType::lookupIsProtectedCategoryType(inv_cat->getPreferredType())); if( is_movable ) { gInventory.collectDescendents( cat_id, descendent_categories, descendent_items, FALSE ); @@ -1411,7 +1443,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, for( i = 0; i < descendent_categories.count(); i++ ) { LLInventoryCategory* category = descendent_categories[i]; - if( LLAssetType::AT_NONE != category->getPreferredType() ) + if(LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType())) { // ...can't move "special folders" like Textures is_movable = FALSE; @@ -1868,7 +1900,7 @@ void LLFolderBridge::openItem() BOOL LLFolderBridge::isItemRenameable() const { LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)getCategory(); - if(cat && (cat->getPreferredType() == LLAssetType::AT_NONE) + if(cat && !LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType()) && (cat->getOwnerID() == gAgent.getID())) { return TRUE; @@ -1904,13 +1936,26 @@ LLAssetType::EType LLFolderBridge::getPreferredType() const // Icons for folders are based on the preferred type LLUIImagePtr LLFolderBridge::getIcon() const { - const char* control = NULL; LLAssetType::EType preferred_type = LLAssetType::AT_NONE; LLViewerInventoryCategory* cat = getCategory(); if(cat) { preferred_type = cat->getPreferredType(); } + return getIcon(preferred_type); +} + +LLUIImagePtr LLFolderBridge::getIcon(LLAssetType::EType preferred_type) +{ + if (preferred_type >= LLAssetType::AT_FOLDER_ENSEMBLE_START && + preferred_type <= LLAssetType::AT_FOLDER_ENSEMBLE_END) + { + LLUIImage* icon = LLUI::getUIImage(LLFolderType::lookupIconName(preferred_type)); + if (icon) + return icon; + } + + const char* control = NULL; switch(preferred_type) { case LLAssetType::AT_TEXTURE: @@ -1984,7 +2029,7 @@ BOOL LLFolderBridge::renameItem(const std::string& new_name) new_cat->rename(new_name); new_cat->updateServer(FALSE); model->updateCategory(new_cat); - renameLinkedItems(cat->getUUID(),new_name); + model->updateLinkedObjects(cat->getUUID()); model->notifyObservers(); } @@ -2066,15 +2111,24 @@ void LLFolderBridge::pasteLinkFromClipboard() LLInventoryModel* model = getInventoryModel(); if(model) { - LLInventoryItem* item = NULL; LLDynamicArray<LLUUID> objects; LLInventoryClipboard::instance().retrieve(objects); S32 count = objects.count(); LLUUID parent_id(mUUID); for(S32 i = 0; i < count; i++) { - item = model->getItem(objects.get(i)); - if (item) + const LLUUID &object_id = objects.get(i); + if (LLInventoryCategory *cat = model->getCategory(object_id)) + { + link_inventory_item( + gAgent.getID(), + cat->getUUID(), + parent_id, + cat->getName(), + LLAssetType::AT_LINK_FOLDER, + LLPointer<LLInventoryCallback>(NULL)); + } + else if (LLInventoryItem *item = model->getItem(object_id)) { link_inventory_item( gAgent.getID(), @@ -2103,7 +2157,7 @@ void LLFolderBridge::folderOptionsMenu() const LLInventoryCategory* category = model->getCategory(mUUID); bool is_default_folder = category && - (LLAssetType::AT_NONE != category->getPreferredType()); + (LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType())); // calling card related functionality for folders. @@ -2199,7 +2253,14 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) mItems.push_back(std::string("New Gesture")); mItems.push_back(std::string("New Clothes")); mItems.push_back(std::string("New Body Parts")); + mItems.push_back(std::string("Change Type")); + LLViewerInventoryCategory *cat = getCategory(); + if (cat && LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType())) + { + mDisabledItems.push_back(std::string("Change Type")); + } + getClipboardEntries(false, mItems, mDisabledItems, flags); //Added by spatters to force inventory pull on right-click to display folder options correctly. 07-17-06 @@ -2268,26 +2329,27 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop, BOOL accept = FALSE; switch(cargo_type) { - case DAD_TEXTURE: - case DAD_SOUND: - case DAD_CALLINGCARD: - case DAD_LANDMARK: - case DAD_SCRIPT: - case DAD_OBJECT: - case DAD_NOTECARD: - case DAD_CLOTHING: - case DAD_BODYPART: - case DAD_ANIMATION: - case DAD_GESTURE: - accept = dragItemIntoFolder((LLInventoryItem*)cargo_data, - drop); - break; - case DAD_CATEGORY: - accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, + case DAD_TEXTURE: + case DAD_SOUND: + case DAD_CALLINGCARD: + case DAD_LANDMARK: + case DAD_SCRIPT: + case DAD_OBJECT: + case DAD_NOTECARD: + case DAD_CLOTHING: + case DAD_BODYPART: + case DAD_ANIMATION: + case DAD_GESTURE: + case DAD_LINK: + accept = dragItemIntoFolder((LLInventoryItem*)cargo_data, drop); - break; - default: - break; + break; + case DAD_CATEGORY: + accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, + drop); + break; + default: + break; } return accept; } @@ -2490,14 +2552,14 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { BOOL is_movable = TRUE; - switch( inv_item->getType() ) + switch( inv_item->getActualType() ) { case LLAssetType::AT_ROOT_CATEGORY: is_movable = FALSE; break; case LLAssetType::AT_CATEGORY: - is_movable = ( LLAssetType::AT_NONE == ((LLInventoryCategory*)inv_item)->getPreferredType() ); + is_movable = !LLAssetType::lookupIsProtectedCategoryType(((LLInventoryCategory*)inv_item)->getPreferredType()); break; default: break; @@ -2511,11 +2573,11 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { case LLAssetType::AT_CLOTHING: case LLAssetType::AT_BODYPART: - is_movable = !gAgentWearables.isWearingItem(inv_item->getUUID()); + is_movable = !gAgentWearables.isWearingItem(inv_item->getUUID(), TRUE); break; case LLAssetType::AT_OBJECT: - is_movable = !avatar->isWearingAttachment(inv_item->getUUID()); + is_movable = !avatar->isWearingAttachment(inv_item->getUUID(), TRUE); break; default: break; @@ -3435,7 +3497,7 @@ LLFontGL::StyleFlags LLObjectBridge::getLabelStyle() const } LLInventoryItem* item = getItem(); - if (item->getActualType() == LLAssetType::AT_LINK) + if (LLAssetType::lookupIsLinkType(item->getActualType())) { font |= LLFontGL::ITALIC; } @@ -3533,13 +3595,18 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else { + LLInventoryItem* item = getItem(); + if (item && LLAssetType::lookupIsLinkType(item->getActualType())) + { + items.push_back(std::string("Goto Link")); + } + items.push_back(std::string("Properties")); getClipboardEntries(true, items, disabled_items, flags); LLObjectBridge::sContextMenuItemID = mUUID; - LLInventoryItem* item = getItem(); if(item) { LLVOAvatarSelf* avatarp = gAgent.getAvatarObject(); @@ -3619,7 +3686,7 @@ BOOL LLObjectBridge::renameItem(const std::string& new_name) buildDisplayName(new_item, mDisplayName); new_item->updateServer(FALSE); model->updateItem(new_item); - renameLinkedItems(item->getUUID(),new_name); + model->updateLinkedObjects(item->getUUID()); model->notifyObservers(); @@ -4513,6 +4580,11 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) items.push_back(std::string("Open")); } + if (item && LLAssetType::lookupIsLinkType(item->getActualType())) + { + items.push_back(std::string("Goto Link")); + } + items.push_back(std::string("Properties")); getClipboardEntries(true, items, disabled_items, flags); @@ -5093,3 +5165,94 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } hideContextEntries(menu, items, disabled_items); } + + +// +=================================================+ +// | LLLinkBridge | +// +=================================================+ +// For broken links. + +std::string LLLinkFolderBridge::sPrefix("Link: "); + + +LLUIImagePtr LLLinkFolderBridge::getIcon() const +{ + LLAssetType::EType preferred_type = LLAssetType::AT_NONE; + if (LLViewerInventoryItem *item = getItem()) + { + if (const LLViewerInventoryCategory* cat = item->getLinkedCategory()) + { + preferred_type = cat->getPreferredType(); + } + } + return LLFolderBridge::getIcon(preferred_type); +} + +void LLLinkFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + // *TODO: Translate + lldebugs << "LLLink::buildContextMenu()" << llendl; + std::vector<std::string> items; + std::vector<std::string> disabled_items; + + if(isInTrash()) + { + items.push_back(std::string("Purge Item")); + if (!isItemRemovable()) + { + disabled_items.push_back(std::string("Purge Item")); + } + + items.push_back(std::string("Restore Item")); + } + else + { + items.push_back(std::string("Goto Link")); + items.push_back(std::string("Delete")); + if (!isItemRemovable()) + { + disabled_items.push_back(std::string("Delete")); + } + } + hideContextEntries(menu, items, disabled_items); +} + +void LLLinkFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) +{ + if ("goto" == action) + { + gotoItem(folder); + return; + } + LLItemBridge::performAction(folder,model,action); +} + +void LLLinkFolderBridge::gotoItem(LLFolderView *folder) +{ + const LLUUID &cat_uuid = getFolderID(); + if (!cat_uuid.isNull()) + { + if (LLFolderViewItem *base_folder = folder->getItemByID(cat_uuid)) + { + if (LLInventoryModel* model = getInventoryModel()) + { + model->fetchDescendentsOf(cat_uuid); + } + base_folder->setOpen(TRUE); + folder->setSelectionFromRoot(base_folder,TRUE); + } + } +} + +const LLUUID &LLLinkFolderBridge::getFolderID() const +{ + if (LLViewerInventoryItem *link_item = getItem()) + { + if (const LLViewerInventoryCategory *cat = link_item->getLinkedCategory()) + { + const LLUUID& cat_uuid = cat->getUUID(); + return cat_uuid; + } + } + return LLUUID::null; +} diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index a37b7969ed..915dfec629 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -133,6 +133,7 @@ public: // This method is a convenience function which creates the correct // type of bridge based on some basic information static LLInvFVBridge* createBridge(LLAssetType::EType asset_type, + LLAssetType::EType actual_asset_type, LLInventoryType::EType inv_type, LLInventoryPanel* inventory, const LLUUID& uuid, @@ -156,6 +157,7 @@ public: } virtual std::string getLabelSuffix() const { return LLStringUtil::null; } virtual void openItem() {} + virtual void gotoItem(LLFolderView *folder) {} // for links virtual void previewItem() {openItem();} virtual void showProperties(); virtual BOOL isItemRenameable() const { return TRUE; } @@ -231,6 +233,7 @@ public: virtual void selectItem(); virtual void restoreItem(); virtual void restoreToWorld(); + virtual void gotoItem(LLFolderView *folder); virtual LLUIImagePtr getIcon() const; virtual const std::string& getDisplayName() const; @@ -274,6 +277,8 @@ public: virtual LLAssetType::EType getPreferredType() const; virtual LLUIImagePtr getIcon() const; + static LLUIImagePtr getIcon(LLAssetType::EType asset_type); + virtual BOOL renameItem(const std::string& new_name); virtual BOOL removeItem(); virtual void pasteFromClipboard(); @@ -591,6 +596,27 @@ protected: static std::string sPrefix; }; + +class LLLinkFolderBridge : public LLItemBridge +{ + friend class LLInvFVBridge; +public: + virtual const std::string& getPrefix() { return sPrefix; } + + virtual LLUIImagePtr getIcon() const; + virtual void buildContextMenu(LLMenuGL& menu, U32 flags); + virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action); + virtual void gotoItem(LLFolderView *folder); + +protected: + LLLinkFolderBridge(LLInventoryPanel* inventory, const LLUUID& uuid) : + LLItemBridge(inventory, uuid) {} + const LLUUID &getFolderID() const; + +protected: + static std::string sPrefix; +}; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLInvFVBridgeAction (& its derived classes) // diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 2c281a4615..bba0c9a90d 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -475,6 +475,35 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id, } } +void LLInventoryModel::updateLinkedObjects(const LLUUID& object_id) +{ + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + LLLinkedItemIDMatches is_linked_item_match(object_id); + collectDescendentsIf(gInventory.getRootFolderID(), + cat_array, + item_array, + LLInventoryModel::INCLUDE_TRASH, + is_linked_item_match); + + for (LLInventoryModel::cat_array_t::iterator cat_iter = cat_array.begin(); + cat_iter != cat_array.end(); + cat_iter++) + { + LLViewerInventoryCategory *linked_cat = (*cat_iter); + addChangedMask(LLInventoryObserver::LABEL, linked_cat->getUUID()); + }; + + for (LLInventoryModel::item_array_t::iterator iter = item_array.begin(); + iter != item_array.end(); + iter++) + { + LLViewerInventoryItem *linked_item = (*iter); + addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID()); + }; + notifyObservers(); +} + void LLInventoryModel::collectLinkedItems(const LLUUID& id, item_array_t& items) { @@ -825,10 +854,10 @@ void LLInventoryModel::purgeObject(const LLUUID &id) void LLInventoryModel::purgeLinkedObjects(const LLUUID &id) { - LLInventoryItem* itemp = getItem(id); - if (!itemp) return; + LLInventoryObject* objectp = getObject(id); + if (!objectp) return; - if (LLAssetType::lookupIsLinkType(itemp->getActualType())) + if (LLAssetType::lookupIsLinkType(objectp->getActualType())) { return; } diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index c402fea886..f470a77985 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -181,7 +181,6 @@ public: cat_array_t& categories, item_array_t& items, BOOL include_trash); - void collectDescendentsIf(const LLUUID& id, cat_array_t& categories, item_array_t& items, @@ -192,8 +191,9 @@ public: // Assumes item_id is itself not a linked item. void collectLinkedItems(const LLUUID& item_id, item_array_t& items); - - // This method will return false if this inventory model is in an usabel state. + // Updates all linked objects pointing to this id. + void updateLinkedObjects(const LLUUID& object_id); + // The inventory model usage is sensitive to the initial construction of the // model. bool isInventoryUsable(); diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 3a7ef4dfc9..d2e07f0725 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -473,6 +473,14 @@ LLToolDragAndDrop::dragOrDrop3dImpl LLToolDragAndDrop::sDragAndDrop3d[DAD_COUNT] &LLToolDragAndDrop::dad3dUpdateInventory, // Dest: DT_OBJECT &LLToolDragAndDrop::dad3dNULL,//dad3dAssetOnLand, // Dest: DT_LAND }, + // Source: DAD_LINK + { + &LLToolDragAndDrop::dad3dNULL, // Dest: DT_NONE + &LLToolDragAndDrop::dad3dNULL, // Dest: DT_SELF + &LLToolDragAndDrop::dad3dNULL, // Dest: DT_AVATAR + &LLToolDragAndDrop::dad3dNULL, // Dest: DT_OBJECT + &LLToolDragAndDrop::dad3dNULL,//dad3dAssetOnLand, // Dest: DT_LAND + }, }; LLToolDragAndDrop::LLToolDragAndDrop() @@ -1894,7 +1902,7 @@ BOOL LLToolDragAndDrop::isInventoryGroupGiveAcceptable(LLInventoryItem* item) acceptable = FALSE; break; case LLAssetType::AT_OBJECT: - if(my_avatar->isWearingAttachment(item->getUUID())) + if(my_avatar->isWearingAttachment(item->getUUID(), TRUE)) { acceptable = FALSE; } diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 54b0a4f568..66da7d89fb 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -403,7 +403,8 @@ void LLViewerInventoryCategory::updateParentOnServer(BOOL restamp) const void LLViewerInventoryCategory::updateServer(BOOL is_new) const { // communicate that change with the server. - if(LLAssetType::AT_NONE != mPreferredType) + + if (LLAssetType::lookupIsProtectedCategoryType(mPreferredType)) { LLNotifications::instance().add("CannotModifyProtectedCategories"); return; @@ -427,7 +428,7 @@ void LLViewerInventoryCategory::removeFromServer( void ) llinfos << "Removing inventory category " << mUUID << " from server." << llendl; // communicate that change with the server. - if(LLAssetType::AT_NONE != mPreferredType) + if(LLAssetType::lookupIsProtectedCategoryType(mPreferredType)) { LLNotifications::instance().add("CannotRemoveProtectedCategories"); return; @@ -977,7 +978,10 @@ LLAssetType::EType LLViewerInventoryItem::getType() const { return linked_item->getType(); } - + if (const LLViewerInventoryCategory *linked_category = getLinkedCategory()) + { + return linked_category->getType(); + } return LLInventoryItem::getType(); } @@ -997,6 +1001,10 @@ const std::string& LLViewerInventoryItem::getName() const { return linked_item->getName(); } + if (const LLViewerInventoryCategory *linked_category = getLinkedCategory()) + { + return linked_category->getName(); + } return LLInventoryItem::getName(); } diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 7084c9f37a..5198f5efc7 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -141,7 +141,6 @@ public: }; LLTransactionID getTransactionID() const { return mTransactionID; } -protected: const LLViewerInventoryItem *getLinkedItem() const; const LLViewerInventoryCategory *getLinkedCategory() const; diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 6f2fd5e5e5..c788f8f095 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -77,6 +77,14 @@ parameter="category" /> </menu_item_call> <menu_item_call + label="New Current" + layout="topleft" + name="New Current"> + <menu_item_call.on_click + function="Inventory.DoCreate" + parameter="current" /> + </menu_item_call> + <menu_item_call label="New Script" layout="topleft" name="New Script"> @@ -230,6 +238,91 @@ parameter="eyes" /> </menu_item_call> </menu> + <menu + label="Change Type" + layout="topleft" + name="Change Type"> + <menu_item_call + label="Default" + layout="topleft" + name="Default"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="change_folder_type_default" /> + </menu_item_call> + <menu_item_call + label="Gloves" + layout="topleft" + name="Gloves"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="change_folder_type_gloves" /> + </menu_item_call> + <menu_item_call + label="Jacket" + layout="topleft" + name="Jacket"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="change_folder_type_jacket" /> + </menu_item_call> + <menu_item_call + label="Pants" + layout="topleft" + name="Pants"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="change_folder_type_pants" /> + </menu_item_call> + <menu_item_call + label="Shape" + layout="topleft" + name="Shape"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="change_folder_type_shape" /> + </menu_item_call> + <menu_item_call + label="Shoes" + layout="topleft" + name="Shoes"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="change_folder_type_shoes" /> + </menu_item_call> + <menu_item_call + label="Shirt" + layout="topleft" + name="Shirt"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="change_folder_type_shirt" /> + </menu_item_call> + <menu_item_call + label="Skirt" + layout="topleft" + name="Skirt"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="change_folder_type_skirt" /> + </menu_item_call> + <menu_item_call + label="Underpants" + layout="topleft" + name="Underpants"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="change_folder_type_underpants" /> + </menu_item_call> + <menu_item_call + label="Undershirt" + layout="topleft" + name="Undershirt"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="change_folder_type_undershirt" /> + </menu_item_call> + </menu> <menu_item_call label="Teleport" layout="topleft" @@ -271,6 +364,14 @@ parameter="restore" /> </menu_item_call> <menu_item_call + label="Goto Link" + layout="topleft" + name="Goto Link"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="goto" /> + </menu_item_call> + <menu_item_call label="Open" layout="topleft" name="Open"> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index e54ef88f34..626c084f0c 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -346,6 +346,8 @@ this texture in your inventory <string name="no_modify" value=" (no modify)" /> <string name="no_copy" value=" (no copy)" /> <string name="worn" value=" (worn)" /> + <string name="link" value=" (link)" /> + <string name="broken_link" value=" (broken_link)" /> <string name="LoadingContents">Loading contents...</string> <string name="NoContents">No contents</string> |