diff options
69 files changed, 1669 insertions, 903 deletions
diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt index d39055e118..88564c6085 100644 --- a/indra/integration_tests/llui_libtest/CMakeLists.txt +++ b/indra/integration_tests/llui_libtest/CMakeLists.txt @@ -1,5 +1,7 @@ # -*- cmake -*- +# Only set this up for viewer builds, because the llui library is most closely +# related to the viewer if (VIEWER) project (llui_libtest) @@ -91,8 +93,9 @@ if (WINDOWS) ) endif (WINDOWS) - # Ensure people working on the viewer don't break this library - # *NOTE: This could be removed, or only built by Parabuild, if the build - # and link times become too long. JC - add_dependencies(viewer llui_libtest) +# Ensure people working on the viewer don't break this library +# *NOTE: This could be removed, or only built by Parabuild, if the build +# and link times become too long. JC +add_dependencies(viewer llui_libtest) + endif (VIEWER) diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index 6715b6722d..e4102a622d 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -46,7 +46,8 @@ struct AssetEntry : public LLDictionaryEntry const char *type_name, // 8 character limit! const char *human_name, const char *category_name, // used by llinventorymodel when creating new categories - EDragAndDropType dad_type); + EDragAndDropType dad_type, + bool can_link); // limited to 8 characters const char *mTypeName; @@ -55,6 +56,7 @@ struct AssetEntry : public LLDictionaryEntry const char *mHumanName; const char *mCategoryName; EDragAndDropType mDadType; + bool mCanLink; }; class LLAssetDictionary : public LLSingleton<LLAssetDictionary>, @@ -66,44 +68,49 @@ public: LLAssetDictionary::LLAssetDictionary() { - addEntry(LLAssetType::AT_TEXTURE, new AssetEntry("TEXTURE", "texture", "texture", "Textures", DAD_TEXTURE)); - addEntry(LLAssetType::AT_SOUND, new AssetEntry("SOUND", "sound", "sound", "Sounds", DAD_SOUND)); - addEntry(LLAssetType::AT_CALLINGCARD, new AssetEntry("CALLINGCARD", "callcard", "calling card", "Calling Cards", DAD_CALLINGCARD)); - addEntry(LLAssetType::AT_LANDMARK, new AssetEntry("LANDMARK", "landmark", "landmark", "Landmarks", DAD_LANDMARK)); - addEntry(LLAssetType::AT_SCRIPT, new AssetEntry("SCRIPT", "script", "legacy script", "Scripts", DAD_NONE)); - addEntry(LLAssetType::AT_CLOTHING, new AssetEntry("CLOTHING", "clothing", "clothing", "Clothing", DAD_CLOTHING)); - addEntry(LLAssetType::AT_OBJECT, new AssetEntry("OBJECT", "object", "object", "Objects", DAD_OBJECT)); - addEntry(LLAssetType::AT_NOTECARD, new AssetEntry("NOTECARD", "notecard", "note card", "Notecards", DAD_NOTECARD)); - addEntry(LLAssetType::AT_CATEGORY, new AssetEntry("CATEGORY", "category", "folder", "New Folder", DAD_CATEGORY)); - addEntry(LLAssetType::AT_ROOT_CATEGORY, new AssetEntry("ROOT_CATEGORY", "root", "root", "Inventory", DAD_ROOT_CATEGORY)); - addEntry(LLAssetType::AT_LSL_TEXT, new AssetEntry("LSL_TEXT", "lsltext", "lsl2 script", "Scripts", DAD_SCRIPT)); - addEntry(LLAssetType::AT_LSL_BYTECODE, new AssetEntry("LSL_BYTECODE", "lslbyte", "lsl bytecode", "Scripts", DAD_NONE)); - addEntry(LLAssetType::AT_TEXTURE_TGA, new AssetEntry("TEXTURE_TGA", "txtr_tga", "tga texture", "Uncompressed Images", DAD_NONE)); - addEntry(LLAssetType::AT_BODYPART, new AssetEntry("BODYPART", "bodypart", "body part", "Body Parts", DAD_BODYPART)); - addEntry(LLAssetType::AT_TRASH, new AssetEntry("TRASH", "trash", "trash", "Trash", DAD_NONE)); - addEntry(LLAssetType::AT_SNAPSHOT_CATEGORY, new AssetEntry("SNAPSHOT_CATEGORY", "snapshot", "snapshot", "Photo Album", DAD_NONE)); - addEntry(LLAssetType::AT_LOST_AND_FOUND, new AssetEntry("LOST_AND_FOUND", "lstndfnd", "lost and found", "Lost And Found", DAD_NONE)); - addEntry(LLAssetType::AT_SOUND_WAV, new AssetEntry("SOUND_WAV", "snd_wav", "sound", "Uncompressed Sounds", DAD_NONE)); - addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", "Uncompressed Images", DAD_NONE)); - addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", "Uncompressed Images", DAD_NONE)); - addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", "Animations", DAD_ANIMATION)); - addEntry(LLAssetType::AT_GESTURE, new AssetEntry("GESTURE", "gesture", "gesture", "Gestures", DAD_GESTURE)); - addEntry(LLAssetType::AT_SIMSTATE, new AssetEntry("SIMSTATE", "simstate", "simstate", "New Folder", DAD_NONE)); - addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "symbolic link", "New Folder", DAD_NONE)); - addEntry(LLAssetType::AT_FAVORITE, new AssetEntry("FAVORITE", "favorite", "favorite", "favorite", DAD_NONE)); - addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, "New Folder", DAD_NONE)); + addEntry(LLAssetType::AT_TEXTURE, new AssetEntry("TEXTURE", "texture", "texture", "Textures", DAD_TEXTURE, FALSE)); + addEntry(LLAssetType::AT_SOUND, new AssetEntry("SOUND", "sound", "sound", "Sounds", DAD_SOUND, FALSE)); + addEntry(LLAssetType::AT_CALLINGCARD, new AssetEntry("CALLINGCARD", "callcard", "calling card", "Calling Cards", DAD_CALLINGCARD, FALSE)); + addEntry(LLAssetType::AT_LANDMARK, new AssetEntry("LANDMARK", "landmark", "landmark", "Landmarks", DAD_LANDMARK, FALSE)); + addEntry(LLAssetType::AT_SCRIPT, new AssetEntry("SCRIPT", "script", "legacy script", "Scripts", DAD_NONE, FALSE)); + addEntry(LLAssetType::AT_CLOTHING, new AssetEntry("CLOTHING", "clothing", "clothing", "Clothing", DAD_CLOTHING, TRUE)); + addEntry(LLAssetType::AT_OBJECT, new AssetEntry("OBJECT", "object", "object", "Objects", DAD_OBJECT, TRUE)); + addEntry(LLAssetType::AT_NOTECARD, new AssetEntry("NOTECARD", "notecard", "note card", "Notecards", DAD_NOTECARD, FALSE)); + addEntry(LLAssetType::AT_CATEGORY, new AssetEntry("CATEGORY", "category", "folder", "New Folder", DAD_CATEGORY, TRUE)); + addEntry(LLAssetType::AT_ROOT_CATEGORY, new AssetEntry("ROOT_CATEGORY", "root", "root", "Inventory", DAD_ROOT_CATEGORY, TRUE)); + addEntry(LLAssetType::AT_LSL_TEXT, new AssetEntry("LSL_TEXT", "lsltext", "lsl2 script", "Scripts", DAD_SCRIPT, FALSE)); + addEntry(LLAssetType::AT_LSL_BYTECODE, new AssetEntry("LSL_BYTECODE", "lslbyte", "lsl bytecode", "Scripts", DAD_NONE, FALSE)); + addEntry(LLAssetType::AT_TEXTURE_TGA, new AssetEntry("TEXTURE_TGA", "txtr_tga", "tga texture", "Uncompressed Images", DAD_NONE, FALSE)); + addEntry(LLAssetType::AT_BODYPART, new AssetEntry("BODYPART", "bodypart", "body part", "Body Parts", DAD_BODYPART, TRUE)); + addEntry(LLAssetType::AT_TRASH, new AssetEntry("TRASH", "trash", "trash", "Trash", DAD_NONE, FALSE)); + addEntry(LLAssetType::AT_SNAPSHOT_CATEGORY, new AssetEntry("SNAPSHOT_CATEGORY", "snapshot", "snapshot", "Photo Album", DAD_NONE, FALSE)); + addEntry(LLAssetType::AT_LOST_AND_FOUND, new AssetEntry("LOST_AND_FOUND", "lstndfnd", "lost and found", "Lost And Found", DAD_NONE, FALSE)); + addEntry(LLAssetType::AT_SOUND_WAV, new AssetEntry("SOUND_WAV", "snd_wav", "sound", "Uncompressed SoundS", DAD_NONE, FALSE)); + addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", "Uncompressed Images", DAD_NONE, FALSE)); + addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", "Uncompressed Images", DAD_NONE, FALSE)); + addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", "Animations", DAD_ANIMATION, FALSE)); + addEntry(LLAssetType::AT_GESTURE, new AssetEntry("GESTURE", "gesture", "gesture", "Gestures", DAD_GESTURE, FALSE)); + addEntry(LLAssetType::AT_SIMSTATE, new AssetEntry("SIMSTATE", "simstate", "simstate", "New Folder", DAD_NONE, FALSE)); + addEntry(LLAssetType::AT_FAVORITE, new AssetEntry("FAVORITE", "favorite", "favorite", "favorite", DAD_NONE, FALSE)); + + addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "symbolic link", "New Folder", DAD_NONE, FALSE)); + addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "symbolic folder link", "New Folder", DAD_NONE, FALSE)); + + addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, "New Folder", DAD_NONE, FALSE)); }; AssetEntry::AssetEntry(const char *desc_name, const char *type_name, const char *human_name, const char *category_name, - EDragAndDropType dad_type) : + EDragAndDropType dad_type, + bool can_link) : LLDictionaryEntry(desc_name), mTypeName(type_name), mHumanName(human_name), mCategoryName(category_name), - mDadType(dad_type) + mDadType(dad_type), + mCanLink(can_link) { llassert(strlen(mTypeName) <= 8); } @@ -231,6 +238,29 @@ EDragAndDropType LLAssetType::lookupDragAndDropType(EType asset_type) return DAD_NONE; } +// static +bool LLAssetType::lookupCanLink(EType asset_type) +{ + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + const AssetEntry *entry = dict->lookup(asset_type); + if (entry) + { + return entry->mCanLink; + } + return false; +} + +// static +// Not adding this to dictionary since we probably will only have these two types +bool LLAssetType::lookupIsLinkType(EType asset_type) +{ + if (asset_type == AT_LINK || asset_type == AT_LINK_FOLDER) + { + return true; + } + return false; +} + // static. Generate a good default description void LLAssetType::generateDescriptionFor(LLAssetType::EType asset_type, std::string& description) diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index 2f54031688..353bd57bb9 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -125,23 +125,25 @@ public: AT_SIMSTATE = 22, // Simstate file. - - AT_LINK = 23, - // Inventory symbolic link - - AT_FAVORITE = 24, + + AT_FAVORITE = 23, // favorite items - // +*********************************************+ - // | TO ADD AN ELEMENT TO THIS ENUM: | - // +************************************************+ - // | 1. INSERT BEFORE AT_COUNT | - // | 2. INCREMENT AT_COUNT BY 1 | - // | 3. ADD TO LLAssetType::mAssetTypeNames | - // | 4. ADD TO LLAssetType::mAssetTypeHumanNames | - // +*********************************************+ + AT_LINK = 24, + // Inventory symbolic link + + AT_LINK_FOLDER = 25, + // Inventory folder link - AT_COUNT = 25, + AT_COUNT = 26, + + // +************************************************+ + // | TO ADD AN ELEMENT TO THIS ENUM: | + // +************************************************+ + // | 1. INSERT BEFORE AT_COUNT | + // | 2. INCREMENT AT_COUNT BY 1 | + // | 3. ADD TO LLAssetDictionary in llassettype.cpp | + // +************************************************+ AT_NONE = -1 }; @@ -166,6 +168,8 @@ public: static EType getType(const std::string& desc_name); static const std::string& getDesc(EType asset_type); static EDragAndDropType lookupDragAndDropType(EType asset_type); + static bool lookupCanLink(EType asset_type); + static bool lookupIsLinkType(EType asset_type); /* TODO: Change return types from "const char *" to "const std::string &". This is fairly straightforward, but requires changing some calls to use .c_str(). diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index adc80b2ed3..597e19e7ea 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -126,6 +126,20 @@ const std::string& LLInventoryObject::getName() const return mName; } +// To bypass linked items, since llviewerinventory's getType +// will return the linked-to item's type instead of this object's type. +LLAssetType::EType LLInventoryObject::getActualType() const +{ + return mType; +} + +// See LLInventoryItem override. +// virtual +const LLUUID& LLInventoryObject::getLinkedUUID() const +{ + return mUUID; +} + LLAssetType::EType LLInventoryObject::getType() const { return mType; @@ -333,6 +347,19 @@ void LLInventoryItem::copyItem(const LLInventoryItem* other) mCreationDate = other->mCreationDate; } +// If this is a linked item, then the UUID of the base object is +// this item's assetID. +// virtual +const LLUUID& LLInventoryItem::getLinkedUUID() const +{ + if (LLAssetType::lookupIsLinkType(getActualType())) + { + return mAssetUUID; + } + + return LLInventoryObject::getLinkedUUID(); +} + const LLPermissions& LLInventoryItem::getPermissions() const { return mPermissions; diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h index 3f79cedc23..ce64317f48 100644 --- a/indra/llinventory/llinventory.h +++ b/indra/llinventory/llinventory.h @@ -92,9 +92,12 @@ public: // accessors virtual const LLUUID& getUUID() const; const LLUUID& getParentUUID() const; + virtual const LLUUID& getLinkedUUID() const; // get the inventoryID that this item points to, else this item's inventoryID + virtual const std::string& getName() const; virtual LLAssetType::EType getType() const; - LLAssetType::EType getActualType() const { return mType; } + LLAssetType::EType getActualType() const; // bypasses indirection for linked items + // mutators - will not call updateServer(); void setUUID(const LLUUID& new_uuid); void rename(const std::string& new_name); @@ -240,15 +243,16 @@ public: void generateUUID() { mUUID.generate(); } // accessors - const LLPermissions& getPermissions() const; - const LLUUID& getCreatorUUID() const; + virtual const LLUUID& getLinkedUUID() const; + virtual const LLPermissions& getPermissions() const; + virtual const LLUUID& getCreatorUUID() const; virtual const LLUUID& getAssetUUID() const; - const std::string& getDescription() const; - const LLSaleInfo& getSaleInfo() const; - LLInventoryType::EType getInventoryType() const; - U32 getFlags() const; - time_t getCreationDate() const; - U32 getCRC32() const; // really more of a checksum. + virtual const std::string& getDescription() const; + virtual const LLSaleInfo& getSaleInfo() const; + virtual LLInventoryType::EType getInventoryType() const; + virtual U32 getFlags() const; + virtual time_t getCreationDate() const; + virtual U32 getCRC32() const; // really more of a checksum. // mutators - will not call updateServer(), and will never fail // (though it may correct to sane values) diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp index ff9c698943..2dc229226f 100644 --- a/indra/llinventory/llinventorytype.cpp +++ b/indra/llinventory/llinventorytype.cpp @@ -113,8 +113,10 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] = LLInventoryType::IT_NONE, // AT_IMAGE_JPEG LLInventoryType::IT_ANIMATION, // AT_ANIMATION LLInventoryType::IT_GESTURE, // AT_GESTURE - LLInventoryType::IT_NONE, // AT_LINK + LLInventoryType::IT_NONE, // AT_SIMSTATE LLInventoryType::IT_FAVORITE, // AT_FAVORITE + LLInventoryType::IT_NONE, // AT_LINK + LLInventoryType::IT_NONE, // AT_LINK_FOLDER }; InventoryEntry::InventoryEntry(const std::string &name, diff --git a/indra/llmath/xform.h b/indra/llmath/xform.h index d3be28f41d..5b7b1900bc 100644 --- a/indra/llmath/xform.h +++ b/indra/llmath/xform.h @@ -173,7 +173,7 @@ BOOL LLXform::setParent(LLXform* parent) { if (cur_par == this) { - llwarns << "LLXform::setParent Creating loop when setting parent!" << llendl; + //llwarns << "LLXform::setParent Creating loop when setting parent!" << llendl; return FALSE; } cur_par = cur_par->mParent; diff --git a/indra/llmessage/lltransfersourceasset.cpp b/indra/llmessage/lltransfersourceasset.cpp index 059c1bdfa1..c715e16e34 100644 --- a/indra/llmessage/lltransfersourceasset.cpp +++ b/indra/llmessage/lltransfersourceasset.cpp @@ -264,17 +264,17 @@ bool is_asset_fetch_by_id_allowed(LLAssetType::EType type) bool rv = false; switch(type) { - case LLAssetType::AT_SOUND: - case LLAssetType::AT_LANDMARK: - case LLAssetType::AT_CLOTHING: - case LLAssetType::AT_BODYPART: - case LLAssetType::AT_ANIMATION: - case LLAssetType::AT_GESTURE: - case LLAssetType::AT_FAVORITE: - rv = true; - break; - default: - break; + case LLAssetType::AT_SOUND: + case LLAssetType::AT_LANDMARK: + case LLAssetType::AT_CLOTHING: + case LLAssetType::AT_BODYPART: + case LLAssetType::AT_ANIMATION: + case LLAssetType::AT_GESTURE: + case LLAssetType::AT_FAVORITE: + rv = true; + break; + default: + break; } return rv; } @@ -285,15 +285,17 @@ bool is_asset_id_knowable(LLAssetType::EType type) bool rv = false; switch(type) { - case LLAssetType::AT_TEXTURE: - case LLAssetType::AT_SOUND: - case LLAssetType::AT_LANDMARK: - case LLAssetType::AT_CLOTHING: - case LLAssetType::AT_NOTECARD: - case LLAssetType::AT_BODYPART: - case LLAssetType::AT_ANIMATION: - case LLAssetType::AT_GESTURE: - case LLAssetType::AT_FAVORITE: + case LLAssetType::AT_TEXTURE: + case LLAssetType::AT_SOUND: + case LLAssetType::AT_LANDMARK: + case LLAssetType::AT_CLOTHING: + case LLAssetType::AT_NOTECARD: + case LLAssetType::AT_BODYPART: + case LLAssetType::AT_ANIMATION: + case LLAssetType::AT_GESTURE: + case LLAssetType::AT_FAVORITE: + case LLAssetType::AT_LINK: + case LLAssetType::AT_LINK_FOLDER: rv = true; break; default: diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index 4e657067cd..9e3986f257 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -174,6 +174,7 @@ char* _PREHASH_UpdateInventoryItem = LLMessageStringTable::getInstance()->getStr char* _PREHASH_UpdateCreateInventoryItem = LLMessageStringTable::getInstance()->getString("UpdateCreateInventoryItem"); char* _PREHASH_MoveInventoryItem = LLMessageStringTable::getInstance()->getString("MoveInventoryItem"); char* _PREHASH_CopyInventoryItem = LLMessageStringTable::getInstance()->getString("CopyInventoryItem"); +char* _PREHASH_LinkInventoryItem = LLMessageStringTable::getInstance()->getString("LinkInventoryItem"); char* _PREHASH_RemoveInventoryItem = LLMessageStringTable::getInstance()->getString("RemoveInventoryItem"); char* _PREHASH_CreateInventoryItem = LLMessageStringTable::getInstance()->getString("CreateInventoryItem"); char* _PREHASH_PathTwistBegin = LLMessageStringTable::getInstance()->getString("PathTwistBegin"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index f8ef610408..e73ec3e5e1 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -174,6 +174,7 @@ extern char * _PREHASH_UpdateInventoryItem; extern char * _PREHASH_UpdateCreateInventoryItem; extern char * _PREHASH_MoveInventoryItem; extern char * _PREHASH_CopyInventoryItem; +extern char * _PREHASH_LinkInventoryItem; extern char * _PREHASH_RemoveInventoryItem; extern char * _PREHASH_CreateInventoryItem; extern char * _PREHASH_PathTwistBegin; diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 452f18b40b..50fee41029 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -160,6 +160,12 @@ private: bool filterIgnoredNotifications(LLNotificationPtr notification) { + // filter everything if we are to ignore ALL + if(LLNotifications::instance().getIgnoreAllNotifications()) + { + return false; + } + LLNotificationFormPtr form = notification->getForm(); // Check to see if the user wants to ignore this alert if (form->getIgnoreType() != LLNotificationForm::IGNORE_NO) @@ -231,7 +237,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLXMLNodeP LLSD item_entry; std::string element_name = child->getName()->mString; - if (element_name == "ignore") + if (element_name == "ignore" ) { bool save_option = false; child->getAttribute_bool("save_option", save_option); @@ -925,7 +931,8 @@ std::string LLNotificationChannel::summarize() // LLNotifications implementation // --- LLNotifications::LLNotifications() : LLNotificationChannelBase(LLNotificationFilters::includeEverything, - LLNotificationComparators::orderByUUID()) + LLNotificationComparators::orderByUUID()), + mIgnoreAllNotifications(false) { LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2)); } @@ -1473,6 +1480,14 @@ std::string LLNotifications::getGlobalString(const std::string& key) const } } +void LLNotifications::setIgnoreAllNotifications(bool setting) +{ + mIgnoreAllNotifications = setting; +} +bool LLNotifications::getIgnoreAllNotifications() +{ + return mIgnoreAllNotifications; +} // --- // END OF LLNotifications implementation diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index b749724b4e..512886790c 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -870,6 +870,9 @@ public: std::string getGlobalString(const std::string& key) const; + void setIgnoreAllNotifications(bool ignore); + bool getIgnoreAllNotifications(); + private: // we're a singleton, so we don't have a public constructor LLNotifications(); @@ -898,6 +901,8 @@ private: typedef std::map<std::string, std::string> GlobalStringMap; GlobalStringMap mGlobalStrings; + + bool mIgnoreAllNotifications; }; diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index f5d06b7258..b80080e458 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -35,6 +35,7 @@ include_directories( set(llwindow_SOURCE_FILES llkeyboard.cpp llwindowheadless.cpp + llwindowcallbacks.cpp ) set(llwindow_HEADER_FILES @@ -42,27 +43,28 @@ set(llwindow_HEADER_FILES llkeyboard.h llwindowheadless.h + llwindowcallbacks.h ) set(viewer_SOURCE_FILES llwindow.cpp llmousehandler.cpp - llwindowcallbacks.cpp ) set(viewer_HEADER_FILES llwindow.h - llwindowcallbacks.h llpreeditor.h llmousehandler.h ) # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level -set(llwindow_LINK_LIBRARIES - ${UI_LIBRARIES} # for GTK - ${SDL_LIBRARY} - ) +if (NOT LINUX OR VIEWER) + set(llwindow_LINK_LIBRARIES + ${UI_LIBRARIES} # for GTK + ${SDL_LIBRARY} + ) +endif (VIEWER) if (DARWIN) list(APPEND llwindow_SOURCE_FILES @@ -85,7 +87,7 @@ if (DARWIN) ) endif (DARWIN) -if (LINUX) +if (LINUX AND VIEWER) list(APPEND viewer_SOURCE_FILES llkeyboardsdl.cpp llwindowsdl.cpp diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index 783a886fdd..5f143431de 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -146,6 +146,14 @@ <string>ReplaySession</string> </map> + <key>nonotifications</key> + <map> + <key>desc</key> + <string>User will not get any notifications. NOTE: All notifications that occur will get added to ignore file for future runs.</string> + <key>map-to</key> + <string>IgnoreAllNotifications</string> + </map> + <key>rotate</key> <map> <key>map-to</key> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 5ad49774a9..afa7f707f1 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3560,6 +3560,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>IgnoreAllNotifications</key> + <map> + <key>Comment</key> + <string>Ignore all notifications so we never need user input on them.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>IgnorePixelDepth</key> <map> <key>Comment</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index a70d31431f..a8094a5850 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -64,6 +64,9 @@ #include "llmorphview.h" #include "llmoveview.h" #include "llparcel.h" +#include "llquantize.h" +#include "llrand.h" +#include "llregionhandle.h" #include "llsdutil.h" #include "llselectmgr.h" #include "llsky.h" @@ -71,6 +74,7 @@ #include "llsmoothstep.h" #include "llsidetray.h" #include "llstatusbar.h" +#include "llteleportflags.h" #include "llteleporthistory.h" #include "lltool.h" #include "lltoolcomp.h" diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 1c756b1441..1da54ad08c 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -626,9 +626,24 @@ const LLUUID& LLAgentWearables::getWearableItem(EWearableType type, U32 index) c } -BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id) const +// Warning: include_linked_items = TRUE makes this operation expensive. +BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id, BOOL include_linked_items) const { - return (getWearableFromWearableItem(item_id) != NULL); + if (getWearableFromWearableItem(item_id) != NULL) return TRUE; + if (include_linked_items) + { + LLInventoryModel::item_array_t item_array; + gInventory.collectLinkedItems(item_id, item_array); + for (LLInventoryModel::item_array_t::iterator iter = item_array.begin(); + iter != item_array.end(); + iter++) + { + LLViewerInventoryItem *linked_item = (*iter); + const LLUUID &item_id = linked_item->getUUID(); + if (getWearableFromWearableItem(item_id) != NULL) return TRUE; + } + } + return FALSE; } // MULTI-WEARABLE: update for multiple diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 98f49203d3..31d6e30069 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -63,7 +63,7 @@ protected: // Queries //-------------------------------------------------------------------- public: - BOOL isWearingItem(const LLUUID& item_id) const; + BOOL isWearingItem(const LLUUID& item_id, const BOOL include_linked_items = FALSE) const; BOOL isWearableModifiable(EWearableType type, U32 index /*= 0*/) const; BOOL isWearableCopyable(EWearableType type, U32 index /*= 0*/) const; BOOL areWearablesLoaded() const { return mWearablesLoaded; } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index ff5ddbfcfb..f9e6db52c3 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -641,6 +641,11 @@ bool LLAppViewer::init() // Get the single value from the crash settings file, if it exists std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE); gCrashSettings.loadFromFile(crash_settings_filename); + if(gSavedSettings.getBOOL("IgnoreAllNotifications")) + { + gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, CRASH_BEHAVIOR_ALWAYS_SEND); + gCrashSettings.saveToFile(crash_settings_filename, FALSE); + } ///////////////////////////////////////////////// // OS-specific login dialogs @@ -1971,6 +1976,11 @@ bool LLAppViewer::initConfiguration() { LLAgentPilot::sReplaySession = TRUE; } + + if (clp.hasOption("nonotifications")) + { + gSavedSettings.setBOOL("IgnoreAllNotifications", TRUE); + } if (clp.hasOption("debugsession")) { diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index b23bd8cc81..540c878543 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -33,14 +33,19 @@ #ifndef LL_LLAPPVIEWER_H #define LL_LLAPPVIEWER_H +#include "llallocator.h" #include "llcontrol.h" +#include "llsys.h" // for LLOSInfo +class LLCommandLineParser; +class LLFrameTimer; +class LLPumpIO; class LLTextureCache; -class LLWorkerThread; class LLTextureFetch; +class LLTimer; +class LLVFS; class LLWatchdogTimeout; -class LLCommandLineParser; -class LLAllocator; +class LLWorkerThread; diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 4cd9647603..1379073bba 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -58,11 +58,13 @@ #include "lltexlayer.h" // library includes +#include "lldir.h" #include "lleconomy.h" #include "llfloaterreg.h" #include "llfocusmgr.h" #include "llscrolllistctrl.h" #include "llsdserialize.h" +#include "llvfs.h" // When uploading multiple files, don't display any of them when uploading more than this number. static const S32 FILE_COUNT_DISPLAY_THRESHOLD = 5; diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index 807f2f035c..3cd6126739 100644 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -41,6 +41,8 @@ #include "llmenugl.h" #include "lluictrlfactory.h" +#include "llcachename.h" + #define MENU_ITEM_VIEW_PROFILE 0 #define MENU_ITEM_SEND_IM 1 diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h index 4d50541d9a..2e10dea834 100644 --- a/indra/newview/llavatarpropertiesprocessor.h +++ b/indra/newview/llavatarpropertiesprocessor.h @@ -34,6 +34,8 @@ #define LL_LLAVATARPROPERTIESPROCESSOR_H #include "lluuid.h" +#include "llsingleton.h" +#include "v3dmath.h" // LLVector3d #include <map> /* diff --git a/indra/newview/llcapabilitylistener.cpp b/indra/newview/llcapabilitylistener.cpp index 0a41ad614e..785a647fa2 100644 --- a/indra/newview/llcapabilitylistener.cpp +++ b/indra/newview/llcapabilitylistener.cpp @@ -21,6 +21,7 @@ // other Linden headers #include "stringize.h" #include "llcapabilityprovider.h" +#include "message.h" class LLCapabilityListener::CapabilityMappers: public LLSingleton<LLCapabilityListener::CapabilityMappers> { diff --git a/indra/newview/llcapabilitylistener.h b/indra/newview/llcapabilitylistener.h index 061227e04d..ce16b7da5d 100644 --- a/indra/newview/llcapabilitylistener.h +++ b/indra/newview/llcapabilitylistener.h @@ -17,6 +17,7 @@ #include "llerror.h" // LOG_CLASS() class LLCapabilityProvider; +class LLMessageSystem; class LLSD; class LLCapabilityListener diff --git a/indra/newview/llcaphttpsender.cpp b/indra/newview/llcaphttpsender.cpp index 1127f43424..b44e1f11fa 100644 --- a/indra/newview/llcaphttpsender.cpp +++ b/indra/newview/llcaphttpsender.cpp @@ -32,9 +32,10 @@ #include "llviewerprecompiledheaders.h" -#include "linden_common.h" #include "llcaphttpsender.h" +#include "llhost.h" + LLCapHTTPSender::LLCapHTTPSender(const std::string& cap) : mCap(cap) { diff --git a/indra/newview/llcloud.cpp b/indra/newview/llcloud.cpp index 0099817de4..af6f4e3286 100644 --- a/indra/newview/llcloud.cpp +++ b/indra/newview/llcloud.cpp @@ -37,6 +37,7 @@ #include "v3math.h" #include "v4math.h" #include "llquaternion.h" +#include "llrand.h" #include "v4color.h" #include "llwind.h" diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index 096777ddd4..9d3b92d937 100644 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -56,10 +56,12 @@ #include "llviewerobject.h" #include "llviewerregion.h" #include "llresmgr.h" + #include "llbutton.h" #include "lldir.h" #include "llfloaterchat.h" #include "llviewerstats.h" +#include "llvfile.h" #include "lluictrlfactory.h" #include "lltrans.h" diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h index 5a20eaef9b..22e5a4819d 100644 --- a/indra/newview/lldynamictexture.h +++ b/indra/newview/lldynamictexture.h @@ -33,6 +33,7 @@ #ifndef LL_LLDYNAMICTEXTURE_H #define LL_LLDYNAMICTEXTURE_H +#include "llcamera.h" #include "llgl.h" #include "llcoord.h" #include "llimagegl.h" diff --git a/indra/newview/lleventpoll.h b/indra/newview/lleventpoll.h index 12e4b49d57..f2465a361e 100644 --- a/indra/newview/lleventpoll.h +++ b/indra/newview/lleventpoll.h @@ -35,6 +35,9 @@ #include "llhttpclient.h" +class LLHost; + + class LLEventPoll ///< implements the viewer side of server-to-viewer pushed events. { diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h index 537bf0c6a4..383963a41d 100644 --- a/indra/newview/llfeaturemanager.h +++ b/indra/newview/llfeaturemanager.h @@ -35,6 +35,7 @@ #include "stdtypes.h" +#include "llsingleton.h" #include "llstring.h" #include <map> diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp index 5a8afc2277..dc72b66949 100644 --- a/indra/newview/llfloaterproperties.cpp +++ b/indra/newview/llfloaterproperties.cpp @@ -305,10 +305,11 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) BOOL is_complete = i->isComplete(); const LLPermissions& perm = item->getPermissions(); - BOOL can_agent_manipulate = gAgent.allowOperation(PERM_OWNER, perm, - GP_OBJECT_MANIPULATE); - BOOL can_agent_sell = gAgent.allowOperation(PERM_OWNER, perm, - GP_OBJECT_SET_SALE); + const BOOL can_agent_manipulate = gAgent.allowOperation(PERM_OWNER, perm, + GP_OBJECT_MANIPULATE); + const BOOL can_agent_sell = gAgent.allowOperation(PERM_OWNER, perm, + GP_OBJECT_SET_SALE); + const BOOL is_link = LLAssetType::lookupIsLinkType(i->getActualType()); // You need permission to modify the object to modify an inventory // item in it. @@ -491,7 +492,12 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) ///////////// // Check for ability to change values. - if (is_obj_modify && can_agent_manipulate) + if (is_link) + { + childSetEnabled("CheckShareWithGroup",FALSE); + childSetEnabled("CheckEveryoneCopy",FALSE); + } + else if (is_obj_modify && can_agent_manipulate) { childSetEnabled("CheckShareWithGroup",TRUE); childSetEnabled("CheckEveryoneCopy",(owner_mask & PERM_COPY) && (owner_mask & PERM_TRANSFER)); diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 251539088b..2fe817625a 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -57,6 +57,7 @@ #include "llslurl.h" #include "lltextbox.h" #include "lltracker.h" +#include "llviewerinventory.h" // LLViewerInventoryItem #include "llviewermenu.h" #include "llviewerregion.h" #include "llviewerstats.h" diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 9d91f0d64e..3386a7fb0e 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -103,6 +103,7 @@ public: virtual void cutToClipboard() = 0; virtual BOOL isClipboardPasteable() const = 0; virtual void pasteFromClipboard() = 0; + virtual void pasteLinkFromClipboard() = 0; virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0; virtual BOOL isUpToDate() const = 0; virtual BOOL hasChildren() const = 0; diff --git a/indra/newview/llhudeffectpointat.h b/indra/newview/llhudeffectpointat.h index 81db3da1c7..278c69fe2b 100644 --- a/indra/newview/llhudeffectpointat.h +++ b/indra/newview/llhudeffectpointat.h @@ -33,6 +33,7 @@ #ifndef LL_LLHUDEFFECTPOINTAT_H #define LL_LLHUDEFFECTPOINTAT_H +#include "llframetimer.h" #include "llhudeffect.h" class LLViewerObject; diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 469f6ec21d..37dcd1593f 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -33,6 +33,7 @@ #ifndef LL_LLIMVIEW_H #define LL_LLIMVIEW_H +#include "lldarray.h" #include "llmodaldialog.h" #include "llinstantmessage.h" #include "lluuid.h" diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 540cefbc46..af653238d3 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -202,6 +202,38 @@ BOOL LLInvFVBridge::isItemRemovable() return FALSE; } +// Sends an update to all link items that point to the base item. +void LLInvFVBridge::renameLinkedItems(const LLUUID &item_id, const std::string& new_name) +{ + LLInventoryModel* model = getInventoryModel(); + if(!model) return; + + LLInventoryItem* itemp = model->getItem(mUUID); + if (!itemp) return; + + if (LLAssetType::lookupIsLinkType(itemp->getActualType())) + { + return; + } + + LLInventoryModel::item_array_t item_array; + model->collectLinkedItems(item_id, item_array); + for (LLInventoryModel::item_array_t::iterator iter = item_array.begin(); + iter != item_array.end(); + iter++) + { + LLViewerInventoryItem *linked_item = (*iter); + if (linked_item->getUUID() == item_id) continue; + + LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(linked_item); + new_item->rename(new_name); + new_item->updateServer(FALSE); + model->updateItem(new_item); + // model->addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID()); + } + model->notifyObservers(); +} + // Can be moved to another folder BOOL LLInvFVBridge::isItemMovable() { @@ -370,15 +402,71 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener* BOOL LLInvFVBridge::isClipboardPasteable() const { + if (!LLInventoryClipboard::instance().hasContents() || !isAgentInventory()) + { + return FALSE; + } LLInventoryModel* model = getInventoryModel(); - if(!model) return FALSE; - BOOL is_agent_inventory = model->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID()); + if (!model) + { + return FALSE; + } + + const LLUUID &agent_id = gAgent.getID(); - if(LLInventoryClipboard::instance().hasContents() && is_agent_inventory) + LLDynamicArray<LLUUID> objects; + LLInventoryClipboard::instance().retrieve(objects); + S32 count = objects.count(); + for(S32 i = 0; i < count; i++) { - return TRUE; + const LLUUID &item_id = objects.get(i); + + // Can't paste folders + const LLInventoryCategory *cat = model->getCategory(item_id); + if (cat) + { + return FALSE; + } + + const LLInventoryItem *item = model->getItem(item_id); + if (item) + { + if (!item->getPermissions().allowCopyBy(agent_id)) + { + return FALSE; + } + } } - return FALSE; + return TRUE; +} + +BOOL LLInvFVBridge::isClipboardPasteableAsLink() const +{ + if (!LLInventoryClipboard::instance().hasContents() || !isAgentInventory()) + { + return FALSE; + } + LLInventoryModel* model = getInventoryModel(); + if (!model) + { + return FALSE; + } + + LLDynamicArray<LLUUID> objects; + LLInventoryClipboard::instance().retrieve(objects); + S32 count = objects.count(); + for(S32 i = 0; i < count; i++) + { + LLInventoryItem *item = model->getItem(objects.get(i)); + if (item) + { + if (!LLAssetType::lookupCanLink(item->getActualType())) + { + return FALSE; + } + } + } + return TRUE; } void hideContextEntries(LLMenuGL& menu, @@ -461,6 +549,11 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, disabled_items.push_back(std::string("Paste")); } + items.push_back(std::string("Paste As Link")); + if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0) + { + disabled_items.push_back(std::string("Paste As Link")); + } items.push_back(std::string("Paste Separator")); items.push_back(std::string("Delete")); @@ -544,10 +637,25 @@ BOOL LLInvFVBridge::isInTrash() const { LLInventoryModel* model = getInventoryModel(); if(!model) return FALSE; - LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); + const LLUUID& trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); return model->isObjectDescendentOf(mUUID, trash_id); } +BOOL LLInvFVBridge::isLinkedObjectInTrash() const +{ + if (isInTrash()) return TRUE; + + LLInventoryModel* model = getInventoryModel(); + if(!model) return FALSE; + LLInventoryObject *obj = model->getObject(mUUID); + if (obj && LLAssetType::lookupIsLinkType(obj->getActualType())) + { + const LLUUID& trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); + return model->isObjectDescendentOf(obj->getLinkedUUID(), trash_id); + } + return FALSE; +} + BOOL LLInvFVBridge::isAgentInventory() const { LLInventoryModel* model = getInventoryModel(); @@ -627,108 +735,106 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, LLInvFVBridge* new_listener = NULL; switch(asset_type) { - case LLAssetType::AT_TEXTURE: - if(!(inv_type == LLInventoryType::IT_TEXTURE || inv_type == LLInventoryType::IT_SNAPSHOT)) - { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; - } - new_listener = new LLTextureBridge(inventory, uuid, inv_type); - break; + case LLAssetType::AT_TEXTURE: + if(!(inv_type == LLInventoryType::IT_TEXTURE || inv_type == LLInventoryType::IT_SNAPSHOT)) + { + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + } + new_listener = new LLTextureBridge(inventory, uuid, inv_type); + break; - case LLAssetType::AT_SOUND: - if(!(inv_type == LLInventoryType::IT_SOUND)) - { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; - } - new_listener = new LLSoundBridge(inventory, uuid); - break; + case LLAssetType::AT_SOUND: + if(!(inv_type == LLInventoryType::IT_SOUND)) + { + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + } + new_listener = new LLSoundBridge(inventory, uuid); + break; - case LLAssetType::AT_LANDMARK: - if(!(inv_type == LLInventoryType::IT_LANDMARK)) - { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; - } - new_listener = new LLLandmarkBridge(inventory, uuid, flags); - break; + case LLAssetType::AT_LANDMARK: + if(!(inv_type == LLInventoryType::IT_LANDMARK)) + { + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + } + new_listener = new LLLandmarkBridge(inventory, uuid, flags); + break; - case LLAssetType::AT_CALLINGCARD: - if(!(inv_type == LLInventoryType::IT_CALLINGCARD)) - { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; - } - new_listener = new LLCallingCardBridge(inventory, uuid); - break; - - case LLAssetType::AT_SCRIPT: - if(!(inv_type == LLInventoryType::IT_LSL)) - { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; - } - new_listener = new LLScriptBridge(inventory, uuid); - break; - - case LLAssetType::AT_OBJECT: - if(!(inv_type == LLInventoryType::IT_OBJECT || inv_type == LLInventoryType::IT_ATTACHMENT)) - { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; - } - new_listener = new LLObjectBridge(inventory, uuid, inv_type, flags); - break; + case LLAssetType::AT_CALLINGCARD: + if(!(inv_type == LLInventoryType::IT_CALLINGCARD)) + { + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + } + new_listener = new LLCallingCardBridge(inventory, uuid); + break; - case LLAssetType::AT_NOTECARD: - if(!(inv_type == LLInventoryType::IT_NOTECARD)) - { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; - } - new_listener = new LLNotecardBridge(inventory, uuid); - break; + case LLAssetType::AT_SCRIPT: + if(!(inv_type == LLInventoryType::IT_LSL)) + { + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + } + new_listener = new LLScriptBridge(inventory, uuid); + break; - case LLAssetType::AT_ANIMATION: - if(!(inv_type == LLInventoryType::IT_ANIMATION)) - { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; - } - new_listener = new LLAnimationBridge(inventory, uuid); - break; + case LLAssetType::AT_OBJECT: + if(!(inv_type == LLInventoryType::IT_OBJECT || inv_type == LLInventoryType::IT_ATTACHMENT)) + { + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + } + new_listener = new LLObjectBridge(inventory, uuid, inv_type, flags); + break; - case LLAssetType::AT_GESTURE: - if(!(inv_type == LLInventoryType::IT_GESTURE)) - { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; - } - new_listener = new LLGestureBridge(inventory, uuid); - break; + case LLAssetType::AT_NOTECARD: + if(!(inv_type == LLInventoryType::IT_NOTECARD)) + { + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + } + new_listener = new LLNotecardBridge(inventory, uuid); + break; - case LLAssetType::AT_LSL_TEXT: - if(!(inv_type == LLInventoryType::IT_LSL)) - { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; - } - new_listener = new LLLSLTextBridge(inventory, uuid); - break; + case LLAssetType::AT_ANIMATION: + if(!(inv_type == LLInventoryType::IT_ANIMATION)) + { + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + } + new_listener = new LLAnimationBridge(inventory, uuid); + break; - case LLAssetType::AT_CLOTHING: - case LLAssetType::AT_BODYPART: - if(!(inv_type == LLInventoryType::IT_WEARABLE)) - { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; - } - new_listener = new LLWearableBridge(inventory, uuid, asset_type, inv_type, (EWearableType)flags); - break; + case LLAssetType::AT_GESTURE: + if(!(inv_type == LLInventoryType::IT_GESTURE)) + { + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + } + new_listener = new LLGestureBridge(inventory, uuid); + break; - case LLAssetType::AT_CATEGORY: - case LLAssetType::AT_ROOT_CATEGORY: - new_listener = new LLFolderBridge(inventory, uuid); - break; + case LLAssetType::AT_LSL_TEXT: + if(!(inv_type == LLInventoryType::IT_LSL)) + { + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + } + new_listener = new LLLSLTextBridge(inventory, uuid); + break; - case LLAssetType::AT_FAVORITE: - new_listener = new LLFolderBridge(inventory, uuid); - break; - - default: - llinfos << "Unhandled asset type (llassetstorage.h): " - << (S32)asset_type << llendl; - break; + case LLAssetType::AT_CLOTHING: + case LLAssetType::AT_BODYPART: + if(!(inv_type == LLInventoryType::IT_WEARABLE)) + { + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + } + new_listener = new LLWearableBridge(inventory, uuid, asset_type, inv_type, (EWearableType)flags); + break; + case LLAssetType::AT_CATEGORY: + case LLAssetType::AT_ROOT_CATEGORY: + new_listener = new LLFolderBridge(inventory, uuid); + break; + case LLAssetType::AT_LINK: + // Only should happen for broken links. + new_listener = new LLLinkItemBridge(inventory, uuid); + break; + default: + llinfos << "Unhandled asset type (llassetstorage.h): " + << (S32)asset_type << llendl; + break; } if (new_listener) @@ -739,6 +845,22 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, return new_listener; } +void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid) +{ + LLInventoryCategory* cat = model->getCategory(uuid); + if (cat) + { + model->purgeDescendentsOf(uuid); + model->notifyObservers(); + } + LLInventoryObject* obj = model->getObject(uuid); + if (obj) + { + model->purgeObject(uuid); + model->notifyObservers(); + } +} + // +=================================================+ // | LLItemBridge | // +=================================================+ @@ -748,32 +870,27 @@ void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model, if ("open" == action) { openItem(); + return; } else if ("properties" == action) { showProperties(); + return; } else if ("purge" == action) { - LLInventoryCategory* cat = model->getCategory(mUUID); - if(cat) - { - model->purgeDescendentsOf(mUUID); - } - LLInventoryObject* obj = model->getObject(mUUID); - if(!obj) return; - obj->removeFromServer(); - LLPreview::hide(mUUID); - model->deleteObject(mUUID); - model->notifyObservers(); + purgeItem(model, mUUID); + return; } else if ("restoreToWorld" == action) { restoreToWorld(); + return; } else if ("restore" == action) { restoreItem(); + return; } else if ("copy_uuid" == action) { @@ -804,6 +921,18 @@ void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model, folder_view_itemp->getListener()->pasteFromClipboard(); return; } + else if ("paste_link" == action) + { + // Single item only + LLInventoryItem* itemp = model->getItem(mUUID); + if (!itemp) return; + + LLFolderViewItem* folder_view_itemp = folder->getItemByID(itemp->getParentUUID()); + if (!folder_view_itemp) return; + + folder_view_itemp->getListener()->pasteLinkFromClipboard(); + return; + } } void LLItemBridge::selectItem() @@ -913,6 +1042,24 @@ void LLItemBridge::buildDisplayName(LLInventoryItem* item, std::string& name) } } +LLFontGL::StyleFlags LLItemBridge::getLabelStyle() const +{ + U8 font = LLFontGL::NORMAL; + + if( gAgentWearables.isWearingItem( mUUID ) ) + { + // llinfos << "BOLD" << llendl; + font |= LLFontGL::BOLD; + } + + const LLViewerInventoryItem* item = getItem(); + if (LLAssetType::lookupIsLinkType(item->getActualType())) + { + font |= LLFontGL::ITALIC; + } + return (LLFontGL::StyleFlags)font; +} + std::string LLItemBridge::getLabelSuffix() const { // assume that this won't be called before string table is loaded @@ -932,8 +1079,12 @@ std::string LLItemBridge::getLabelSuffix() const BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID()); BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); + BOOL link = (item->getActualType() == LLAssetType::AT_LINK); const char* EMPTY = ""; + const char* LINK = " (link)"; // *TODO: Seraph translate + if (link) return LINK; + const char* scopy; if(copy) scopy = EMPTY; else scopy = NO_COPY; @@ -986,6 +1137,8 @@ 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->notifyObservers(); } // return FALSE because we either notified observers (& therefore @@ -1034,13 +1187,19 @@ BOOL LLItemBridge::isItemCopyable() const return FALSE; } - if( avatarp->isWearingAttachment( mUUID ) ) + if( avatarp->isWearingAttachment( mUUID, TRUE ) ) { return FALSE; } - - - return (item->getPermissions().allowCopyBy(gAgent.getID())); + + // 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) + { + return FALSE; + } + return TRUE; } return FALSE; } @@ -1152,7 +1311,7 @@ BOOL LLFolderBridge::isItemRemovable() if( (item->getType() == LLAssetType::AT_CLOTHING) || (item->getType() == LLAssetType::AT_BODYPART) ) { - if( gAgentWearables.isWearingItem( item->getUUID() ) ) + if( gAgentWearables.isWearingItem( item->getUUID(), TRUE ) ) { return FALSE; } @@ -1160,7 +1319,7 @@ BOOL LLFolderBridge::isItemRemovable() else if( item->getType() == LLAssetType::AT_OBJECT ) { - if( avatar->isWearingAttachment( item->getUUID() ) ) + if( avatar->isWearingAttachment( item->getUUID(), TRUE ) ) { return FALSE; } @@ -1183,6 +1342,21 @@ BOOL LLFolderBridge::isUpToDate() const return category->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN; } +BOOL LLFolderBridge::isItemCopyable() const +{ + return TRUE; +} + +BOOL LLFolderBridge::copyToClipboard() const +{ + if(isItemCopyable()) + { + LLInventoryClipboard::instance().add(mUUID); + return TRUE; + } + return FALSE; +} + BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, BOOL drop) { @@ -1620,22 +1794,37 @@ void LLFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model if ("open" == action) { openItem(); + return; } else if ("paste" == action) { pasteFromClipboard(); + return; + } + else if ("paste_link" == action) + { + pasteLinkFromClipboard(); + return; } else if ("properties" == action) { showProperties(); + return; } else if ("replaceoutfit" == action) { modifyOutfit(FALSE); + return; } else if ("addtooutfit" == action) { modifyOutfit(TRUE); + return; + } + else if ("copy" == action) + { + copyToClipboard(); + return; } else if ("removefromoutfit" == action) { @@ -1645,25 +1834,17 @@ void LLFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model if(!cat) return; remove_inventory_category_from_avatar ( cat ); + return; } else if ("purge" == action) { - LLViewerInventoryCategory* cat; - cat = (LLViewerInventoryCategory*)getCategory(); - - if(cat) - { - model->purgeDescendentsOf(mUUID); - } - LLInventoryObject* obj = model->getObject(mUUID); - if(!obj) return; - obj->removeFromServer(); - model->deleteObject(mUUID); - model->notifyObservers(); + purgeItem(model, mUUID); + return; } else if ("restore" == action) { restoreItem(); + return; } } @@ -1723,59 +1904,59 @@ LLUIImagePtr LLFolderBridge::getIcon() const } switch(preferred_type) { - case LLAssetType::AT_TEXTURE: - control = "inv_folder_texture.tga"; - break; - case LLAssetType::AT_SOUND: - control = "inv_folder_sound.tga"; - break; - case LLAssetType::AT_CALLINGCARD: - control = "inv_folder_callingcard.tga"; - break; - case LLAssetType::AT_LANDMARK: - control = "inv_folder_landmark.tga"; - break; - case LLAssetType::AT_SCRIPT: - case LLAssetType::AT_LSL_TEXT: - control = "inv_folder_script.tga"; - break; - case LLAssetType::AT_OBJECT: - control = "inv_folder_object.tga"; - break; - case LLAssetType::AT_NOTECARD: - control = "inv_folder_notecard.tga"; - break; - case LLAssetType::AT_CATEGORY: - control = "inv_folder_plain_closed.tga"; - break; - case LLAssetType::AT_CLOTHING: - control = "inv_folder_clothing.tga"; - break; - case LLAssetType::AT_BODYPART: - control = "inv_folder_bodypart.tga"; - break; - case LLAssetType::AT_TRASH: - control = "inv_folder_trash.tga"; - break; - case LLAssetType::AT_SNAPSHOT_CATEGORY: - control = "inv_folder_snapshot.tga"; - break; - case LLAssetType::AT_LOST_AND_FOUND: - control = "inv_folder_lostandfound.tga"; - break; - case LLAssetType::AT_ANIMATION: - control = "inv_folder_animation.tga"; - break; - case LLAssetType::AT_GESTURE: - control = "inv_folder_gesture.tga"; - break; - case LLAssetType::AT_FAVORITE: - //TODO - need icon - control = "inv_folder_plain_closed.tga"; - break; - default: - control = "inv_folder_plain_closed.tga"; - break; + case LLAssetType::AT_TEXTURE: + control = "inv_folder_texture.tga"; + break; + case LLAssetType::AT_SOUND: + control = "inv_folder_sound.tga"; + break; + case LLAssetType::AT_CALLINGCARD: + control = "inv_folder_callingcard.tga"; + break; + case LLAssetType::AT_LANDMARK: + control = "inv_folder_landmark.tga"; + break; + case LLAssetType::AT_SCRIPT: + case LLAssetType::AT_LSL_TEXT: + control = "inv_folder_script.tga"; + break; + case LLAssetType::AT_OBJECT: + control = "inv_folder_object.tga"; + break; + case LLAssetType::AT_NOTECARD: + control = "inv_folder_notecard.tga"; + break; + case LLAssetType::AT_CATEGORY: + control = "inv_folder_plain_closed.tga"; + break; + case LLAssetType::AT_CLOTHING: + control = "inv_folder_clothing.tga"; + break; + case LLAssetType::AT_BODYPART: + control = "inv_folder_bodypart.tga"; + break; + case LLAssetType::AT_TRASH: + control = "inv_folder_trash.tga"; + break; + case LLAssetType::AT_SNAPSHOT_CATEGORY: + control = "inv_folder_snapshot.tga"; + break; + case LLAssetType::AT_LOST_AND_FOUND: + control = "inv_folder_lostandfound.tga"; + break; + case LLAssetType::AT_ANIMATION: + control = "inv_folder_animation.tga"; + break; + case LLAssetType::AT_GESTURE: + control = "inv_folder_gesture.tga"; + break; + case LLAssetType::AT_FAVORITE: + //TODO - need icon + control = "inv_folder_plain_closed.tga"; + break; + default: + control = "inv_folder_plain_closed.tga"; + break; } return LLUI::getUIImage(control); } @@ -1794,6 +1975,8 @@ 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->notifyObservers(); } // return FALSE because we either notified observers (& therefore @@ -1842,15 +2025,6 @@ BOOL LLFolderBridge::removeItem() return TRUE; } -BOOL LLFolderBridge::isClipboardPasteable() const -{ - if(LLInventoryClipboard::instance().hasContents() && isAgentInventory()) - { - return TRUE; - } - return FALSE; -} - void LLFolderBridge::pasteFromClipboard() { LLInventoryModel* model = getInventoryModel(); @@ -1878,6 +2052,33 @@ void LLFolderBridge::pasteFromClipboard() } } +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) + { + link_inventory_item( + gAgent.getID(), + item->getUUID(), + parent_id, + item->getName(), + LLAssetType::AT_LINK, + LLPointer<LLInventoryCallback>(NULL)); + } + } + } +} + void LLFolderBridge::staticFolderOptionsMenu() { if (!sSelf) return; @@ -1948,6 +2149,9 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv // Flags unused void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { + mItems.clear(); + mDisabledItems.clear(); + lldebugs << "LLFolderBridge::buildContextMenu()" << llendl; // std::vector<std::string> disabled_items; LLInventoryModel* model = getInventoryModel(); @@ -3116,7 +3320,7 @@ BOOL LLObjectBridge::isItemRemovable() { LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); if(!avatar) return FALSE; - if(avatar->isWearingAttachment(mUUID)) return FALSE; + if(avatar->isWearingAttachment(mUUID, TRUE)) return FALSE; return LLInvFVBridge::isItemRemovable(); } @@ -3125,6 +3329,17 @@ LLUIImagePtr LLObjectBridge::getIcon() const return get_item_icon(LLAssetType::AT_OBJECT, mInvType, mAttachPt, mIsMultiObject ); } +LLInventoryObject* LLObjectBridge::getObject() const +{ + LLInventoryObject* object = NULL; + LLInventoryModel* model = getInventoryModel(); + if(model) + { + object = (LLInventoryObject*)model->getObject(mUUID); + } + return object; +} + // virtual void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) { @@ -3194,15 +3409,21 @@ void LLObjectBridge::openItem() LLFontGL::StyleFlags LLObjectBridge::getLabelStyle() const { + U8 font = LLFontGL::NORMAL; + LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); if( avatar && avatar->isWearingAttachment( mUUID ) ) { - return LLFontGL::BOLD; + font |= LLFontGL::BOLD; } - else + + LLInventoryItem* item = getItem(); + if (item->getActualType() == LLAssetType::AT_LINK) { - return LLFontGL::NORMAL; + font |= LLFontGL::ITALIC; } + + return (LLFontGL::StyleFlags)font; } std::string LLObjectBridge::getLabelSuffix() const @@ -3223,7 +3444,7 @@ std::string LLObjectBridge::getLabelSuffix() const void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment) { LLSD payload; - payload["item_id"] = item->getUUID(); + payload["item_id"] = item->getLinkedUUID(); // Wear the base object in case this is a link. S32 attach_pt = 0; if (gAgent.getAvatarObject() && attachment) @@ -3315,7 +3536,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) items.push_back(std::string("Detach From Yourself")); } else - if( !isInTrash() ) + if( !isInTrash() && !isLinkedObjectInTrash() ) { items.push_back(std::string("Attach Separator")); items.push_back(std::string("Object Wear")); @@ -3381,6 +3602,8 @@ 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->notifyObservers(); LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); @@ -4141,23 +4364,10 @@ BOOL LLWearableBridge::renameItem(const std::string& new_name) BOOL LLWearableBridge::isItemRemovable() { - if(gAgentWearables.isWearingItem(mUUID)) return FALSE; + if (gAgentWearables.isWearingItem(mUUID, TRUE)) return FALSE; return LLInvFVBridge::isItemRemovable(); } -LLFontGL::StyleFlags LLWearableBridge::getLabelStyle() const -{ - if( gAgentWearables.isWearingItem( mUUID ) ) - { - // llinfos << "BOLD" << llendl; - return LLFontGL::BOLD; - } - else - { - return LLFontGL::NORMAL; - } -} - std::string LLWearableBridge::getLabelSuffix() const { if( gAgentWearables.isWearingItem( mUUID ) ) @@ -4300,6 +4510,13 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { disabled_items.push_back(std::string("Wearable Edit")); } + // Don't allow items to be worn if their baseobj is in the trash. + if (isLinkedObjectInTrash()) + { + disabled_items.push_back(std::string("Wearable Wear")); + disabled_items.push_back(std::string("Wearable Add")); + disabled_items.push_back(std::string("Wearable Edit")); + } if( item && (item->getType() == LLAssetType::AT_CLOTHING) ) { @@ -4534,9 +4751,8 @@ void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable, delete item_id; } - LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_type, - const LLUUID& uuid,LLInventoryModel* model) + const LLUUID& uuid,LLInventoryModel* model) { LLInvFVBridgeAction* action = NULL; switch(asset_type) @@ -4819,3 +5035,44 @@ void LLWearableBridgeAction::doIt() LLInvFVBridgeAction::doIt(); } + +// +=================================================+ +// | LLLinkItemBridge | +// +=================================================+ +// For broken links + +std::string LLLinkItemBridge::sPrefix("Link: "); + + +LLUIImagePtr LLLinkItemBridge::getIcon() const +{ + return get_item_icon(LLAssetType::AT_LINK, LLInventoryType::IT_NONE, 0, FALSE); +} + +void LLLinkItemBridge::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("Delete")); + if (!isItemRemovable()) + { + disabled_items.push_back(std::string("Delete")); + } + } + hideContextEntries(menu, items, disabled_items); +} diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 3958f7e9c2..016eb701d6 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -167,7 +167,9 @@ public: virtual BOOL copyToClipboard() const { return FALSE; } virtual void cutToClipboard() {} virtual BOOL isClipboardPasteable() const; + virtual BOOL isClipboardPasteableAsLink() const; virtual void pasteFromClipboard() {} + virtual void pasteLinkFromClipboard() {} void getClipboardEntries(bool show_asset_id, std::vector<std::string> &items, std::vector<std::string> &disabled_items, U32 flags); virtual void buildContextMenu(LLMenuGL& menu, U32 flags); @@ -191,6 +193,8 @@ protected: LLInventoryModel* getInventoryModel() const; BOOL isInTrash() const; + BOOL isLinkedObjectInTrash() const; // Is this obj or its baseobj in the trash? + // return true if the item is in agent inventory. if false, it // must be lost or in the inventory library. BOOL isAgentInventory() const; @@ -204,11 +208,13 @@ protected: const LLUUID& new_parent, BOOL restamp); void removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch); - + void renameLinkedItems(const LLUUID &item_id, const std::string& new_name); + protected: LLHandle<LLPanel> mInventoryPanel; - LLUUID mUUID; // item id + const LLUUID mUUID; // item id LLInventoryType::EType mInvType; + void purgeItem(LLInventoryModel *model, const LLUUID &uuid); }; @@ -227,6 +233,7 @@ public: virtual LLUIImagePtr getIcon() const; virtual const std::string& getDisplayName() const; virtual std::string getLabelSuffix() const; + virtual LLFontGL::StyleFlags getLabelStyle() const; virtual PermissionMask getPermissionMask() const; virtual time_t getCreationDate() const; virtual BOOL isItemRenameable() const; @@ -267,8 +274,8 @@ public: virtual LLUIImagePtr getIcon() const; virtual BOOL renameItem(const std::string& new_name); virtual BOOL removeItem(); - virtual BOOL isClipboardPasteable() const; virtual void pasteFromClipboard(); + virtual void pasteLinkFromClipboard(); virtual void buildContextMenu(LLMenuGL& menu, U32 flags); virtual BOOL hasChildren() const; virtual BOOL dragOrDrop(MASK mask, BOOL drop, @@ -278,7 +285,9 @@ public: virtual BOOL isItemRemovable(); virtual BOOL isItemMovable(); virtual BOOL isUpToDate() const; - + virtual BOOL isItemCopyable() const; + virtual BOOL copyToClipboard() const; + static void createWearable(LLFolderBridge* bridge, EWearableType type); static void createWearable(LLUUID parent_folder_id, EWearableType type); @@ -489,6 +498,8 @@ public: virtual BOOL isItemRemovable(); virtual BOOL renameItem(const std::string& new_name); + LLInventoryObject* getObject() const; + protected: LLObjectBridge(LLInventoryPanel* inventory, const LLUUID& uuid, LLInventoryType::EType type, U32 flags) : LLItemBridge(inventory, uuid), mInvType(type) @@ -527,7 +538,6 @@ public: virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action); virtual void openItem(); virtual void buildContextMenu(LLMenuGL& menu, U32 flags); - virtual LLFontGL::StyleFlags getLabelStyle() const; virtual std::string getLabelSuffix() const; virtual BOOL isItemRemovable(); virtual BOOL renameItem(const std::string& new_name); @@ -562,8 +572,25 @@ protected: EWearableType mWearableType; }; +class LLLinkItemBridge : public LLItemBridge +{ + friend class LLInvFVBridge; +public: + virtual const std::string& getPrefix() { return sPrefix; } + + virtual LLUIImagePtr getIcon() const; + virtual void buildContextMenu(LLMenuGL& menu, U32 flags); + +protected: + LLLinkItemBridge(LLInventoryPanel* inventory, const LLUUID& uuid) : + LLItemBridge(inventory, uuid) {} + +protected: + static std::string sPrefix; +}; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLInvFVBridgeAction (& it's derived classes) +// Class LLInvFVBridgeAction (& its derived classes) // // This is an implementation class to be able to // perform action to view inventory items. diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 3ee529aedf..665ad5b1a2 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -464,6 +464,18 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id, } } +void LLInventoryModel::collectLinkedItems(const LLUUID& id, + item_array_t& items) +{ + LLInventoryModel::cat_array_t cat_array; + LLLinkedItemIDMatches is_linked_item_match(id); + collectDescendentsIf(gAgent.getInventoryRootID(), + cat_array, + items, + LLInventoryModel::INCLUDE_TRASH, + is_linked_item_match); +} + // Generates a string containing the path to the item specified by // item_id. void LLInventoryModel::appendPath(const LLUUID& id, std::string& path) @@ -747,6 +759,7 @@ void LLInventoryModel::moveObject(const LLUUID& object_id, const LLUUID& cat_id) // Delete a particular inventory object by ID. void LLInventoryModel::deleteObject(const LLUUID& id) { + purgeLinkedObjects(id); lldebugs << "LLInventoryModel::deleteObject()" << llendl; LLPointer<LLInventoryObject> obj = getObject(id); if(obj) @@ -786,6 +799,42 @@ void LLInventoryModel::deleteObject(const LLUUID& id) } } +// Delete a particular inventory item by ID, and remove it from the server. +void LLInventoryModel::purgeObject(const LLUUID &id) +{ + lldebugs << "LLInventoryModel::purgeObject()" << llendl; + LLPointer<LLInventoryObject> obj = getObject(id); + if(obj) + { + obj->removeFromServer(); + LLPreview::hide(id); + deleteObject(id); + } +} + +void LLInventoryModel::purgeLinkedObjects(const LLUUID &id) +{ + LLInventoryItem* itemp = getItem(id); + if (!itemp) return; + + if (LLAssetType::lookupIsLinkType(itemp->getActualType())) + { + return; + } + + LLInventoryModel::item_array_t item_array; + collectLinkedItems(id, item_array); + + for (LLInventoryModel::item_array_t::iterator iter = item_array.begin(); + iter != item_array.end(); + iter++) + { + LLViewerInventoryItem *linked_item = (*iter); + if (linked_item->getUUID() == id) continue; + purgeObject(linked_item->getUUID()); + } +} + // This is a method which collects the descendents of the id // provided. If the category is not found, no action is // taken. This method goes through the long winded process of @@ -3906,11 +3955,20 @@ void LLInventoryTransactionObserver::changed(U32 mask) ///---------------------------------------------------------------------------- /// LLAssetIDMatches ///---------------------------------------------------------------------------- -bool LLAssetIDMatches ::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +bool LLAssetIDMatches::operator()(LLInventoryCategory* cat, LLInventoryItem* item) { return (item && item->getAssetUUID() == mAssetID); } +///---------------------------------------------------------------------------- +/// LLLinkedItemIDMatches +///---------------------------------------------------------------------------- +bool LLLinkedItemIDMatches::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + return (item && + (LLAssetType::lookupIsLinkType(item->getActualType())) && + (item->getLinkedUUID() == mBaseItemID)); // A linked item's assetID will be the compared-to item's itemID. +} ///---------------------------------------------------------------------------- /// Local function definitions diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 0ba64d20e4..8dc3c1605f 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -35,6 +35,8 @@ #include "llassettype.h" #include "lldarray.h" +#include "llframetimer.h" +#include "llhttpclient.h" #include "lluuid.h" #include "llpermissionsflags.h" #include "llstring.h" @@ -111,7 +113,7 @@ public: LLInventoryModel(); ~LLInventoryModel(); - class fetchInventoryResponder: public LLHTTPClient::Responder + class fetchInventoryResponder : public LLHTTPClient::Responder { public: fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {}; @@ -167,7 +169,7 @@ public: item_array_t*& items); void unlockDirectDescendentArrays(const LLUUID& cat_id); - // Starting with the object specified, add it's descendents to the + // Starting with the object specified, add its descendents to the // array provided, but do not add the inventory object specified // by id. There is no guaranteed order. Neither array will be // erased before adding objects to it. Do not store a copy of the @@ -185,6 +187,11 @@ public: BOOL include_trash, LLInventoryCollectFunctor& add); + // Collect all items in inventory that are linked to item_id. + // 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. // The inventory model usage is sensitive to the initial construction of the // model. @@ -225,8 +232,13 @@ public: // delete a particular inventory object by ID. This will purge one // object from the internal data structures maintaining a // cosistent internal state. No cache accounting, observer - // notification, or server update is performed. + // notification, or server update is performed. Purges linked items. void deleteObject(const LLUUID& id); + + // delete a particular inventory object by ID, and delete it from + // the server. Also purges linked items via purgeLinkedObjects. + void purgeObject(const LLUUID& id); + void purgeLinkedObjects(const LLUUID& id); // This is a method which collects the descendents of the id // provided. If the category is not found, no action is @@ -526,6 +538,22 @@ protected: LLUUID mAssetID; }; +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLLinkedItemIDMatches +// +// This functor finds inventory items linked to the specific inventory id. +// Assumes the inventory id is itself not a linked item. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLLinkedItemIDMatches : public LLInventoryCollectFunctor +{ +public: + LLLinkedItemIDMatches(const LLUUID& item_id) : mBaseItemID(item_id) {} + virtual ~LLLinkedItemIDMatches() {} + bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); + +protected: + LLUUID mBaseItemID; +}; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLIsType diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp index 64713108af..676943ff87 100644 --- a/indra/newview/llpreview.cpp +++ b/indra/newview/llpreview.cpp @@ -61,6 +61,7 @@ LLPreview::LLPreview(const LLSD& key) : LLFloater(key), mItemUUID(key.asUUID()), + mObjectUUID(), // set later by setObjectID() mCopyToInvBtn( NULL ), mForceClose(FALSE), mUserResized(FALSE), @@ -194,6 +195,13 @@ void LLPreview::changed(U32 mask) mDirty = TRUE; } +void LLPreview::setNotecardInfo(const LLUUID& notecard_inv_id, + const LLUUID& object_id) +{ + mNotecardInventoryID = notecard_inv_id; + mNotecardObjectID = object_id; +} + void LLPreview::draw() { LLFloater::draw(); @@ -338,6 +346,12 @@ void LLPreview::onOpen(const LLSD& key) } } +void LLPreview::setAuxItem( const LLInventoryItem* item ) +{ + if ( mAuxItem ) + mAuxItem->copyItem(item); +} + // static void LLPreview::onBtnCopyToInv(void* userdata) { @@ -349,7 +363,7 @@ void LLPreview::onBtnCopyToInv(void* userdata) // Copy to inventory if (self->mNotecardInventoryID.notNull()) { - copy_inventory_from_notecard(self->mObjectID, + copy_inventory_from_notecard(self->mNotecardObjectID, self->mNotecardInventoryID, item); } else diff --git a/indra/newview/llpreview.h b/indra/newview/llpreview.h index f6042f065b..c5f2bfcf47 100644 --- a/indra/newview/llpreview.h +++ b/indra/newview/llpreview.h @@ -35,13 +35,12 @@ #include "llmultifloater.h" #include "llresizehandle.h" -#include "llmap.h" +#include "llpointer.h" #include "lluuid.h" -#include "llviewerinventory.h" -#include "lltabcontainer.h" -#include "llinventorymodel.h" +#include "llinventorymodel.h" // LLInventoryObserver #include <map> +class LLInventoryItem; class LLLineEditor; class LLRadioGroup; class LLPreview; @@ -88,11 +87,7 @@ public: virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual void onOpen(const LLSD& key); - void setAuxItem( const LLInventoryItem* item ) - { - if ( mAuxItem ) - mAuxItem->copyItem(item); - } + void setAuxItem( const LLInventoryItem* item ); static void onBtnCopyToInv(void* userdata); @@ -107,11 +102,12 @@ public: virtual EAssetStatus getAssetStatus() { return mAssetStatus;} static LLPreview* getFirstPreviewForSource(const LLUUID& source_id); - void setNotecardInfo(const LLUUID& notecard_inv_id, const LLUUID& object_id) - { mNotecardInventoryID = notecard_inv_id; mObjectID = object_id; } + + // Why is this at the LLPreview level? JC + void setNotecardInfo(const LLUUID& notecard_inv_id, const LLUUID& object_id); // llview - virtual void draw(); + /*virtual*/ void draw(); void refreshFromItem(); protected: @@ -129,7 +125,7 @@ protected: protected: LLUUID mItemUUID; - // mObjectID will have a value if it is associated with a task in + // mObjectUUID will have a value if it is associated with a task in // the world, and will be == LLUUID::null if it's in the agent // inventory. LLUUID mObjectUUID; @@ -152,7 +148,9 @@ protected: EAssetStatus mAssetStatus; LLUUID mNotecardInventoryID; - LLUUID mObjectID; + // I am unsure if this is always the same as mObjectUUID, or why it exists + // at the LLPreview level. JC 2009-06-24 + LLUUID mNotecardObjectID; }; diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 9de2f38aff..7c50bc5977 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -1424,7 +1424,7 @@ void LLLiveLSLEditor::callbackLSLCompileSucceeded(const LLUUID& task_id, bool is_script_running) { lldebugs << "LSL Bytecode saved" << llendl; - mScriptEd->mErrorList->setCommentText(LLTrans::getString("Compilesuccessful")); + mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileSuccessful")); mScriptEd->mErrorList->setCommentText(LLTrans::getString("SaveComplete")); closeIfNeeded(); } @@ -1441,6 +1441,7 @@ void LLLiveLSLEditor::callbackLSLCompileFailed(const LLSD& compile_errors) std::string error_message = line->asString(); LLStringUtil::stripNonprintable(error_message); row["columns"][0]["value"] = error_message; + // *TODO: change to "MONOSPACE" and change llfontgl.cpp? row["columns"][0]["font"] = "OCRA"; mScriptEd->mErrorList->addElement(row); } @@ -1767,7 +1768,7 @@ void LLLiveLSLEditor::onSearchReplace(void* userdata) struct LLLiveLSLSaveData { LLLiveLSLSaveData(const LLUUID& id, const LLViewerInventoryItem* item, BOOL active); - LLUUID mObjectID; + LLUUID mSaveObjectID; LLPointer<LLViewerInventoryItem> mItem; BOOL mActive; }; @@ -1775,7 +1776,7 @@ struct LLLiveLSLSaveData LLLiveLSLSaveData::LLLiveLSLSaveData(const LLUUID& id, const LLViewerInventoryItem* item, BOOL active) : - mObjectID(id), + mSaveObjectID(id), mActive(active) { llassert(item); @@ -1785,7 +1786,7 @@ LLLiveLSLSaveData::LLLiveLSLSaveData(const LLUUID& id, void LLLiveLSLEditor::saveIfNeeded() { llinfos << "LLLiveLSLEditor::saveIfNeeded()" << llendl; - LLViewerObject* object = gObjectList.findObject(mObjectID); + LLViewerObject* object = gObjectList.findObject(mObjectUUID); if(!object) { LLNotifications::instance().add("SaveScriptFailObjectNotFound"); @@ -1865,7 +1866,7 @@ void LLLiveLSLEditor::saveIfNeeded() BOOL is_running = getChild<LLCheckBoxCtrl>( "running")->get(); if (!url.empty()) { - uploadAssetViaCaps(url, filename, mObjectID, mItemUUID, is_running); + uploadAssetViaCaps(url, filename, mObjectUUID, mItemUUID, is_running); } else if (gAssetStorage) { @@ -1894,7 +1895,7 @@ void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename, const LLTransactionID& tid, BOOL is_running) { - LLLiveLSLSaveData* data = new LLLiveLSLSaveData(mObjectID, + LLLiveLSLSaveData* data = new LLLiveLSLSaveData(mObjectUUID, mItem, is_running); gAssetStorage->storeAssetData(filename, tid, @@ -1965,7 +1966,7 @@ void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename, getWindow()->incBusyCount(); mPendingUploads++; LLLiveLSLSaveData* data = NULL; - data = new LLLiveLSLSaveData(mObjectID, + data = new LLLiveLSLSaveData(mObjectUUID, mItem, is_running); gAssetStorage->storeAssetData(dst_filename, @@ -2001,7 +2002,7 @@ void LLLiveLSLEditor::onSaveTextComplete(const LLUUID& asset_uuid, void* user_da } else { - LLLiveLSLEditor* self = LLFloaterReg::findTypedInstance<LLLiveLSLEditor>("preview_scriptedit", data->mItem->getUUID()); // ^ data->mObjectID + LLLiveLSLEditor* self = LLFloaterReg::findTypedInstance<LLLiveLSLEditor>("preview_scriptedit", data->mItem->getUUID()); // ^ data->mSaveObjectID if (self) { self->getWindow()->decBusyCount(); @@ -2026,7 +2027,7 @@ void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* use if(0 ==status) { llinfos << "LSL Bytecode saved" << llendl; - LLLiveLSLEditor* self = LLFloaterReg::findTypedInstance<LLLiveLSLEditor>("preview_scriptedit", data->mItem->getUUID()); // ^ data->mObjectID + LLLiveLSLEditor* self = LLFloaterReg::findTypedInstance<LLLiveLSLEditor>("preview_scriptedit", data->mItem->getUUID()); // ^ data->mSaveObjectID if (self) { // Tell the user that the compile worked. @@ -2040,7 +2041,7 @@ void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* use self->closeFloater(); } } - LLViewerObject* object = gObjectList.findObject(data->mObjectID); + LLViewerObject* object = gObjectList.findObject(data->mSaveObjectID); if(object) { object->saveScript(data->mItem, data->mActive, false); @@ -2122,7 +2123,7 @@ void LLLiveLSLEditor::processScriptRunningReply(LLMessageSystem* msg, void**) void LLLiveLSLEditor::onMonoCheckboxClicked(LLUICtrl*, void* userdata) { LLLiveLSLEditor* self = static_cast<LLLiveLSLEditor*>(userdata); - self->mMonoCheckbox->setEnabled(have_script_upload_cap(self->mObjectID)); + self->mMonoCheckbox->setEnabled(have_script_upload_cap(self->mObjectUUID)); self->mScriptEd->enableSave(self->getIsModifiable()); } diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index 9615d00200..b99dd39584 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -34,8 +34,9 @@ #define LL_LLVIEWERCAMERA_H #include "llcamera.h" -#include "lltimer.h" +#include "llsingleton.h" #include "llstat.h" +#include "lltimer.h" #include "m4math.h" class LLCoordGL; diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 45d24ee7e8..2c79e67ebc 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -244,8 +244,7 @@ BOOL LLViewerInventoryItem::unpackMessage(LLSD item) } // virtual -BOOL LLViewerInventoryItem::unpackMessage( - LLMessageSystem* msg, const char* block, S32 block_num) +BOOL LLViewerInventoryItem::unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num) { BOOL rv = LLInventoryItem::unpackMessage(msg, block, block_num); mIsComplete = TRUE; @@ -742,6 +741,32 @@ void copy_inventory_item( gAgent.sendReliableMessage(); } +void link_inventory_item( + const LLUUID& agent_id, + const LLUUID& item_id, + const LLUUID& parent_id, + const std::string& new_name, + const LLAssetType::EType asset_type, + LLPointer<LLInventoryCallback> cb) +{ + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_LinkInventoryItem); + msg->nextBlockFast(_PREHASH_AgentData); + { + msg->addUUIDFast(_PREHASH_AgentID, agent_id); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + } + msg->nextBlockFast(_PREHASH_InventoryData); + { + msg->addU32Fast(_PREHASH_CallbackID, gInventoryCallbacks.registerCB(cb)); + msg->addUUIDFast(_PREHASH_FolderID, parent_id); + msg->addUUIDFast(_PREHASH_OldItemID, item_id); + msg->addStringFast(_PREHASH_Name, new_name); + msg->addU8Fast(_PREHASH_AssetType, asset_type); + } + gAgent.sendReliableMessage(); +} + void move_inventory_item( const LLUUID& agent_id, const LLUUID& session_id, @@ -948,26 +973,19 @@ void menu_create_inventory_item(LLFolderView* folder, LLFolderBridge *bridge, co LLAssetType::EType LLViewerInventoryItem::getType() const { - if (mType == LLAssetType::AT_LINK) + if (const LLViewerInventoryItem *linked_item = getLinkedItem()) { - LLInventoryItem *linked_item = gInventory.getItem(mAssetUUID); - if (linked_item) - { - return linked_item->getType(); - } + return linked_item->getType(); } + return LLInventoryItem::getType(); } const LLUUID& LLViewerInventoryItem::getAssetUUID() const { - if (mType == LLAssetType::AT_LINK) + if (const LLViewerInventoryItem *linked_item = getLinkedItem()) { - LLInventoryItem *linked_item = gInventory.getItem(mAssetUUID); - if (linked_item) - { - return linked_item->getAssetUUID(); - } + return linked_item->getAssetUUID(); } return LLInventoryItem::getAssetUUID(); @@ -975,11 +993,96 @@ const LLUUID& LLViewerInventoryItem::getAssetUUID() const const std::string& LLViewerInventoryItem::getName() const { - if (mType == LLAssetType::AT_LINK) + if (const LLViewerInventoryItem *linked_item = getLinkedItem()) { - return LLInventoryItem::getName(); //+" link"; + return linked_item->getName(); } return LLInventoryItem::getName(); } +const LLPermissions& LLViewerInventoryItem::getPermissions() const +{ + // Use the actual permissions of the symlink, not its parent. + return LLInventoryItem::getPermissions(); +} + +const LLUUID& LLViewerInventoryItem::getCreatorUUID() const +{ + if (const LLViewerInventoryItem *linked_item = getLinkedItem()) + { + return linked_item->getCreatorUUID(); + } + + return LLInventoryItem::getCreatorUUID(); +} + +const std::string& LLViewerInventoryItem::getDescription() const +{ + if (const LLViewerInventoryItem *linked_item = getLinkedItem()) + { + return linked_item->getDescription(); + } + + return LLInventoryItem::getDescription(); +} + +const LLSaleInfo& LLViewerInventoryItem::getSaleInfo() const +{ + if (const LLViewerInventoryItem *linked_item = getLinkedItem()) + { + return linked_item->getSaleInfo(); + } + + return LLInventoryItem::getSaleInfo(); +} + +LLInventoryType::EType LLViewerInventoryItem::getInventoryType() const +{ + if (const LLViewerInventoryItem *linked_item = getLinkedItem()) + { + return linked_item->getInventoryType(); + } + + return LLInventoryItem::getInventoryType(); +} + +U32 LLViewerInventoryItem::getFlags() const +{ + if (const LLViewerInventoryItem *linked_item = getLinkedItem()) + { + return linked_item->getFlags(); + } + + return LLInventoryItem::getFlags(); +} + +time_t LLViewerInventoryItem::getCreationDate() const +{ + return LLInventoryItem::getCreationDate(); +} + +U32 LLViewerInventoryItem::getCRC32() const +{ + return LLInventoryItem::getCRC32(); +} + +const LLViewerInventoryItem *LLViewerInventoryItem::getLinkedItem() const +{ + if (mType == LLAssetType::AT_LINK) + { + const LLViewerInventoryItem *linked_item = gInventory.getItem(mAssetUUID); + return linked_item; + } + return NULL; +} + +const LLViewerInventoryCategory *LLViewerInventoryItem::getLinkedCategory() const +{ + if (mType == LLAssetType::AT_LINK_FOLDER) + { + const LLViewerInventoryCategory *linked_category = gInventory.getCategory(mAssetUUID); + return linked_category; + } + return NULL; +} diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 8318931dde..7084c9f37a 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -39,6 +39,7 @@ class LLFolderView; class LLFolderBridge; +class LLViewerInventoryCategory; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLViewerInventoryItem @@ -59,7 +60,15 @@ public: virtual LLAssetType::EType getType() const; virtual const LLUUID& getAssetUUID() const; virtual const std::string& getName() const; - + virtual const LLPermissions& getPermissions() const; + virtual const LLUUID& getCreatorUUID() const; + virtual const std::string& getDescription() const; + virtual const LLSaleInfo& getSaleInfo() const; + virtual LLInventoryType::EType getInventoryType() const; + virtual U32 getFlags() const; + virtual time_t getCreationDate() const; + virtual U32 getCRC32() const; // really more of a checksum. + // construct a complete viewer inventory item LLViewerInventoryItem(const LLUUID& uuid, const LLUUID& parent_uuid, const LLPermissions& permissions, @@ -133,6 +142,9 @@ public: LLTransactionID getTransactionID() const { return mTransactionID; } protected: + const LLViewerInventoryItem *getLinkedItem() const; + const LLViewerInventoryCategory *getLinkedCategory() const; + BOOL mIsComplete; LLTransactionID mTransactionID; }; @@ -279,6 +291,14 @@ void copy_inventory_item( const std::string& new_name, LLPointer<LLInventoryCallback> cb); +void link_inventory_item( + const LLUUID& agent_id, + const LLUUID& item_id, + const LLUUID& parent_id, + const std::string& new_name, + const LLAssetType::EType asset_type, + LLPointer<LLInventoryCallback> cb); + void move_inventory_item( const LLUUID& agent_id, const LLUUID& session_id, diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h index 90a54e2b9c..c15e5df675 100644 --- a/indra/newview/llviewermessage.h +++ b/indra/newview/llviewermessage.h @@ -34,6 +34,7 @@ #define LL_LLVIEWERMESSAGE_H #include "llinstantmessage.h" +#include "llpointer.h" #include "lltransactiontypes.h" #include "lluuid.h" #include "stdenums.h" @@ -42,10 +43,11 @@ // Forward declarations // class LLColor4; -class LLViewerObject; class LLInventoryObject; class LLInventoryItem; +class LLMeanCollisionData; class LLMessageSystem; +class LLViewerObject; class LLViewerRegion; // diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index dc4f2b2990..a96ccfd848 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -512,15 +512,24 @@ BOOL LLViewerObject::isOverGroupOwnedLand() const && mRegionp->getParcelOverlay()->isOwnedGroup(getPositionRegion()); } -void LLViewerObject::setParent(LLViewerObject* parent) +BOOL LLViewerObject::setParent(LLViewerObject* parent) { - LLPrimitive::setParent(parent); + if(mParent != parent) + { + LLViewerObject* old_parent = (LLViewerObject*)mParent ; + BOOL ret = LLPrimitive::setParent(parent); + if(ret && old_parent && parent) + { + old_parent->removeChild(this) ; + } + return ret ; + } + + return FALSE ; } void LLViewerObject::addChild(LLViewerObject *childp) { - BOOL result = TRUE; - for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i) { if (*i == childp) @@ -535,18 +544,9 @@ void LLViewerObject::addChild(LLViewerObject *childp) childp->mbCanSelect = mbCanSelect; } - childp->setParent(this); - mChildList.push_back(childp); - - if (!result) + if(childp->setParent(this)) { - llwarns << "Failed to attach child " << childp->getID() << " to object " << getID() << llendl; - removeChild(childp); - if (mJointInfo) - { - delete mJointInfo; - mJointInfo = NULL; - } + mChildList.push_back(childp); } } @@ -562,7 +562,11 @@ void LLViewerObject::removeChild(LLViewerObject *childp) } mChildList.erase(i); - childp->setParent(NULL); + + if(childp->getParent() == this) + { + childp->setParent(NULL); + } break; } } @@ -644,11 +648,14 @@ BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp) return FALSE; } + BOOL ret = mDrawable->mXform.setParent(parentp ? &parentp->mXform : NULL); + if(!ret) + { + return FALSE ; + } LLDrawable* old_parent = mDrawable->mParent; - mDrawable->mParent = parentp; - - BOOL ret = mDrawable->mXform.setParent(parentp ? &parentp->mXform : NULL); + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); if( old_parent != parentp && old_parent || (parentp && parentp->isActive())) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 21a99c58d9..2b2c2d5a95 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -64,6 +64,7 @@ class LLWorld; class LLNameValue; class LLNetMap; class LLMessageSystem; +class LLPartSysData; class LLPrimitive; class LLPipeline; class LLTextureEntry; @@ -236,7 +237,7 @@ public: BOOL isProbablyModifiable() const; */ - virtual void setParent(LLViewerObject* parent); + virtual BOOL setParent(LLViewerObject* parent); virtual void addChild(LLViewerObject *childp); virtual void removeChild(LLViewerObject *childp); const_child_list_t& getChildren() const { return mChildList; } diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 0f906a4d7f..ace5c5038e 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -39,11 +39,13 @@ // common includes #include "llstat.h" #include "lldarrayptr.h" +#include "llmap.h" // *TODO: switch to std::map #include "llstring.h" // project includes #include "llviewerobject.h" +class LLCamera; class LLNetMap; class LLDebugBeacon; diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 35f374a4c8..49d0900f2a 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -51,6 +51,7 @@ #include "llweb.h" #include "llcapabilityprovider.h" #include "llcapabilitylistener.h" +#include "m4math.h" // LLMatrix4 // Surface id's #define LAND 1 diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index fb501b023f..5c9f8af216 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1269,6 +1269,8 @@ LLViewerWindow::LLViewerWindow( LLNotifications::instance().getChannel("VW_alerts")->connectChanged(&LLViewerWindow::onAlert); LLNotifications::instance().getChannel("VW_alertmodal")->connectChanged(&LLViewerWindow::onAlert); + LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications")); + llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl; // Default to application directory. LLViewerWindow::sSnapshotBaseName = "Snapshot"; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 176f8fb37b..c2b54ec9c6 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5315,12 +5315,13 @@ void LLVOAvatar::hideSkirt() mMeshLOD[MESH_ID_SKIRT]->setVisible(FALSE, TRUE); } -void LLVOAvatar::setParent(LLViewerObject* parent) +BOOL LLVOAvatar::setParent(LLViewerObject* parent) { + BOOL ret ; if (parent == NULL) { getOffObject(); - LLViewerObject::setParent(parent); + ret = LLViewerObject::setParent(parent); if (isSelf()) { gAgent.resetCamera(); @@ -5328,9 +5329,13 @@ void LLVOAvatar::setParent(LLViewerObject* parent) } else { - LLViewerObject::setParent(parent); - sitOnObject(parent); + ret = LLViewerObject::setParent(parent); + if(ret) + { + sitOnObject(parent); + } } + return ret ; } void LLVOAvatar::addChild(LLViewerObject *childp) diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 301c032b25..b22c0deb33 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -39,6 +39,7 @@ #include <string> #include <vector> +#include "imageids.h" // IMG_INVISIBLE #include "llchat.h" #include "lldrawpoolalpha.h" #include "llviewerobject.h" @@ -49,6 +50,7 @@ #include "llvoavatardefines.h" #include "lltexglobalcolor.h" #include "lldriverparam.h" +#include "material_codes.h" // LL_MCODE_END extern const LLUUID ANIM_AGENT_BODY_NOISE; extern const LLUUID ANIM_AGENT_BREATHE_ROT; @@ -774,7 +776,7 @@ private: **/ public: - virtual void setParent(LLViewerObject* parent); + virtual BOOL setParent(LLViewerObject* parent); virtual void addChild(LLViewerObject *childp); virtual void removeChild(LLViewerObject *childp); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index d629767bbe..e7d7d74f62 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -907,18 +907,43 @@ void LLVOAvatarSelf::wearableUpdated( EWearableType type ) //----------------------------------------------------------------------------- // isWearingAttachment() //----------------------------------------------------------------------------- -BOOL LLVOAvatarSelf::isWearingAttachment( const LLUUID& inv_item_id ) +// Warning: include_linked_items = TRUE makes this operation expensive. +BOOL LLVOAvatarSelf::isWearingAttachment( const LLUUID& inv_item_id , BOOL include_linked_items ) const { - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ) { - attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; + attachment_map_t::const_iterator curiter = iter++; + const LLViewerJointAttachment* attachment = curiter->second; if( attachment->getItemID() == inv_item_id ) { return TRUE; } } + + if (include_linked_items) + { + LLInventoryModel::item_array_t item_array; + gInventory.collectLinkedItems(inv_item_id, item_array); + for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin(); + iter != item_array.end(); + iter++) + { + const LLViewerInventoryItem *linked_item = (*iter); + const LLUUID &item_id = linked_item->getUUID(); + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) + { + attachment_map_t::const_iterator curiter = iter++; + const LLViewerJointAttachment* attachment = curiter->second; + if( attachment->getItemID() == item_id ) + { + return TRUE; + } + } + } + } + return FALSE; } diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 431c814382..02a77cba90 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -267,7 +267,7 @@ public: //-------------------------------------------------------------------- public: void updateAttachmentVisibility(U32 camera_mode); - BOOL isWearingAttachment(const LLUUID& inv_item_id); + BOOL isWearingAttachment(const LLUUID& inv_item_id, BOOL include_linked_items = FALSE) const; LLViewerObject* getWornAttachment(const LLUUID& inv_item_id ) const; const std::string getAttachedPointName(const LLUUID& inv_item_id) const; /*virtual*/ LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object); diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 1066ac73f1..8b3bbb68bb 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -43,6 +43,7 @@ class LLVivoxProtocolParser; #include "llframetimer.h" #include "llviewerregion.h" #include "llcallingcard.h" // for LLFriendObserver +#include "m3math.h" // LLMatrix3 class LLVoiceClientParticipantObserver { diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index aff8fe8f1d..f31f09f60e 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -934,17 +934,20 @@ void LLVOVolume::updateFaceFlags() } } -void LLVOVolume::setParent(LLViewerObject* parent) +BOOL LLVOVolume::setParent(LLViewerObject* parent) { + BOOL ret = FALSE ; if (parent != getParent()) { - LLViewerObject::setParent(parent); - if (mDrawable) + ret = LLViewerObject::setParent(parent); + if (ret && mDrawable) { gPipeline.markMoved(mDrawable); gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); } } + + return ret ; } // NOTE: regenFaces() MUST be followed by genTriangles()! diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 9b4e715194..5d7b373b3c 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -37,6 +37,8 @@ #include "llviewerimage.h" #include "llframetimer.h" #include "llapr.h" +#include "m3math.h" // LLMatrix3 +#include "m4math.h" // LLMatrix4 #include <map> class LLViewerTextureAnim; @@ -105,7 +107,7 @@ public: /*virtual*/ BOOL isHUDAttachment() const; void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point); - /*virtual*/ void setParent(LLViewerObject* parent); + /*virtual*/ BOOL setParent(LLViewerObject* parent); S32 getLOD() const { return mLOD; } const LLVector3 getPivotPositionAgent() const; const LLMatrix4& getRelativeXform() const { return mRelativeXform; } diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index 92de94636b..1275312676 100644 --- a/indra/newview/llwearablelist.cpp +++ b/indra/newview/llwearablelist.cpp @@ -77,14 +77,17 @@ LLWearableList::~LLWearableList() void LLWearableList::getAsset(const LLAssetID& _assetID, const std::string& wearable_name, LLAssetType::EType asset_type, void(*asset_arrived_callback)(LLWearable*, void* userdata), void* userdata) { LLAssetID assetID = _assetID; - if (asset_type == LLAssetType::AT_LINK) + + // A bit of a hack since wearables database doesn't contain asset types... + // Perform indirection in case this assetID is in fact a link. This only works + // because of the assumption that all assetIDs and itemIDs are unique (i.e. + // no assetID is also used as an itemID elsewhere); therefore if the assetID + // exists as an itemID in the user's inventory, then this must be a link. + const LLInventoryItem *linked_item = gInventory.getItem(_assetID); + if (linked_item) { - LLInventoryItem *linked_item = gInventory.getItem(_assetID); - if (linked_item) - { - assetID = linked_item->getAssetUUID(); - asset_type = linked_item->getType(); - } + assetID = linked_item->getAssetUUID(); + asset_type = linked_item->getType(); } llassert( (asset_type == LLAssetType::AT_CLOTHING) || (asset_type == LLAssetType::AT_BODYPART) ); LLWearable* instance = get_if_there(mList, assetID, (LLWearable*)NULL ); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index c017e9b64f..5358fce766 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -33,6 +33,7 @@ #ifndef LL_PIPELINE_H #define LL_PIPELINE_H +#include "llcamera.h" #include "llerror.h" #include "lldarrayptr.h" #include "lldqueueptr.h" diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml index f4fd6b01b4..afac4a4051 100644 --- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml +++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml @@ -1,32 +1,32 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater
- background_opaque="false"
- background_visible="true"
- bevel_style="in"
- bg_alpha_color="0.3 0.3 0.3 1.0"
- height="300"
- layout="topleft"
- name="nearby_chat"
- save_rect="true"
- title="Nearby Chat"
- width="320">
- <panel top="20" width="320" height="30" background_visible="true" background_opaque="false" bg_alpha_color="0.0 0.0 0.0 1.0" name="chat_caption">
- <text
- width="140" left="25" height="20" follows="left|right|top"
- font="SansSerifBigBold" text_color="white" word_wrap="true"
- mouse_opaque="true" name="sender_name" >NEARBY CHAT </text>
- <icon top="5" left="250"
- width="20" height="20" follows="top|right"
- color="1 1 1 1" enabled="true" image_name="icn_voice-groupfocus.tga"
- mouse_opaque="true" name="nearby_speakers_btn"/>
- <icon top="5" left="275"
- width="20" height="20" follows="top|right"
- color="1 1 1 1" enabled="true" image_name="inv_item_landmark_visited.tga"
- mouse_opaque="true" name="tearoff_btn"/>
- <icon top="5" left="300"
- width="15" height="15" follows="top|right"
- color="1 1 1 1" enabled="true" image_name="closebox.tga"
- name="close_btn"/>
- </panel>
- <chat_history_view bottom="0" width="250" height="320" follows="left|right|top|bottom" name="chat_scroll" />
-</floater>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater + background_opaque="false" + background_visible="true" + bevel_style="in" + bg_alpha_color="0.3 0.3 0.3 1.0" + height="300" + layout="topleft" + name="nearby_chat" + save_rect="true" + title="Nearby Chat" + width="320"> + <panel top="20" width="320" height="30" background_visible="true" background_opaque="false" bg_alpha_color="0.0 0.0 0.0 1.0" name="chat_caption"> + <text + width="140" left="25" height="20" follows="left|right|top" + font="SansSerifBigBold" text_color="white" word_wrap="true" + mouse_opaque="true" name="sender_name" >NEARBY CHAT </text> + <icon top="5" left="250" + width="20" height="20" follows="top|right" + color="1 1 1 1" enabled="true" image_name="icn_voice-groupfocus.tga" + mouse_opaque="true" name="nearby_speakers_btn"/> + <icon top="5" left="275" + width="20" height="20" follows="top|right" + color="1 1 1 1" enabled="true" image_name="inv_item_landmark_visited.tga" + mouse_opaque="true" name="tearoff_btn"/> + <icon top="5" left="300" + width="15" height="15" follows="top|right" + color="1 1 1 1" enabled="true" image_name="closebox.tga" + name="close_btn"/> + </panel> + <chat_history_view bottom="0" width="250" height="320" follows="left|right|top|bottom" name="chat_scroll" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_test_combobox.xml b/indra/newview/skins/default/xui/en/floater_test_combobox.xml index 9e1253ec56..4bc1b8b644 100644 --- a/indra/newview/skins/default/xui/en/floater_test_combobox.xml +++ b/indra/newview/skins/default/xui/en/floater_test_combobox.xml @@ -1,143 +1,143 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- can_resize="true"
- height="400"
- layout="topleft"
- name="floater_test_combobox"
- width="400">
- <text
- type="string"
- length="1"
- height="16"
- layout="topleft"
- left="10"
- top="24"
- width="200">
- Real world usage (login location):
- </text>
- <combo_box
- allow_text_entry="true"
- control_name="LoginLocation"
- follows="left|bottom"
- height="18"
- layout="topleft"
- left_delta="0"
- max_chars="128"
- name="start_location_combo"
- top_pad="2"
- width="155">
- <combo_box.item
- label="My Last Location"
- value="last" />
- <combo_box.item
- label="My Home"
- value="home" />
- <combo_box.item
- label="<Type region name>"
- value="" />
- </combo_box>
- <text
- type="string"
- length="1"
- height="16"
- layout="topleft"
- left_delta="0"
- top_pad="24"
- width="200">
- Minimal combobox:
- </text>
- <combo_box
- height="18"
- layout="topleft"
- left_delta="0"
- name="minimal_combo"
- top_pad="2"
- width="150">
- <combo_box.item
- label="First Item"
- value="first" />
- <combo_box.item
- label="Second Item"
- value="second" />
- </combo_box>
- <text
- type="string"
- length="1"
- height="16"
- layout="topleft"
- left_delta="0"
- top_pad="24"
- width="200">
- Allow text input:
- </text>
- <combo_box
- allow_text_entry="true"
- height="18"
- layout="topleft"
- left_delta="0"
- name="text_entry_combo"
- top_pad="2"
- width="150">
- <combo_box.item
- label="First Item"
- value="first" />
- <combo_box.item
- label="Second Item"
- value="second" />
- </combo_box>
- <text
- type="string"
- length="1"
- height="16"
- layout="topleft"
- left_delta="0"
- top_pad="24"
- width="200">
- Allow text input, default to second item:
- </text>
- <combo_box
- allow_text_entry="true"
- height="18"
- initial_value="second"
- layout="topleft"
- left_delta="0"
- name="text_entry_combo"
- top_pad="2"
- width="150">
- <combo_box.item
- label="First Item"
- value="first" />
- <combo_box.item
- label="Second Item"
- value="second" />
- </combo_box>
- <text
- type="string"
- length="1"
- height="16"
- layout="topleft"
- left_delta="0"
- top_pad="24"
- width="200">
- Two character max input:
- </text>
- <combo_box
- allow_text_entry="true"
- height="16"
- layout="topleft"
- left_delta="0"
- max_chars="2"
- name="state_combo"
- top_pad="4"
- width="150">
- <combo_box.item
- label="CA"
- value="ca" />
- <combo_box.item
- label="NY"
- value="ny" />
- <combo_box.item
- label="TX"
- value="tx" />
- </combo_box>
-</floater>
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_resize="true" + height="400" + layout="topleft" + name="floater_test_combobox" + width="400"> + <text + type="string" + length="1" + height="16" + layout="topleft" + left="10" + top="24" + width="200"> + Real world usage (login location): + </text> + <combo_box + allow_text_entry="true" + control_name="LoginLocation" + follows="left|bottom" + height="18" + layout="topleft" + left_delta="0" + max_chars="128" + name="start_location_combo" + top_pad="2" + width="155"> + <combo_box.item + label="My Last Location" + value="last" /> + <combo_box.item + label="My Home" + value="home" /> + <combo_box.item + label="<Type region name>" + value="" /> + </combo_box> + <text + type="string" + length="1" + height="16" + layout="topleft" + left_delta="0" + top_pad="24" + width="200"> + Minimal combobox: + </text> + <combo_box + height="18" + layout="topleft" + left_delta="0" + name="minimal_combo" + top_pad="2" + width="150"> + <combo_box.item + label="First Item" + value="first" /> + <combo_box.item + label="Second Item" + value="second" /> + </combo_box> + <text + type="string" + length="1" + height="16" + layout="topleft" + left_delta="0" + top_pad="24" + width="200"> + Allow text input: + </text> + <combo_box + allow_text_entry="true" + height="18" + layout="topleft" + left_delta="0" + name="text_entry_combo" + top_pad="2" + width="150"> + <combo_box.item + label="First Item" + value="first" /> + <combo_box.item + label="Second Item" + value="second" /> + </combo_box> + <text + type="string" + length="1" + height="16" + layout="topleft" + left_delta="0" + top_pad="24" + width="200"> + Allow text input, default to second item: + </text> + <combo_box + allow_text_entry="true" + height="18" + initial_value="second" + layout="topleft" + left_delta="0" + name="text_entry_combo" + top_pad="2" + width="150"> + <combo_box.item + label="First Item" + value="first" /> + <combo_box.item + label="Second Item" + value="second" /> + </combo_box> + <text + type="string" + length="1" + height="16" + layout="topleft" + left_delta="0" + top_pad="24" + width="200"> + Two character max input: + </text> + <combo_box + allow_text_entry="true" + height="16" + layout="topleft" + left_delta="0" + max_chars="2" + name="state_combo" + top_pad="4" + width="150"> + <combo_box.item + label="CA" + value="ca" /> + <combo_box.item + label="NY" + value="ny" /> + <combo_box.item + label="TX" + value="tx" /> + </combo_box> +</floater> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 808618ba96..6f2fd5e5e5 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -320,6 +320,14 @@ function="Inventory.DoToSelected" parameter="paste" /> </menu_item_call> + <menu_item_call + label="Paste As Link" + layout="topleft" + name="Paste As Link"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="paste_link" /> + </menu_item_call> <menu_item_separator layout="topleft" /> <menu_item_call diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml index 5a452bd706..f059f4f3c1 100644 --- a/indra/newview/skins/default/xui/en/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml @@ -1,190 +1,190 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- bevel_style="none"
- border_style="line"
- bottom="550"
- follows="left|top|right|bottom"
- height="508"
- layout="topleft"
- left="0"
- name="script panel"
- width="500">
- <panel.string
- name="loading">
- Loading...
- </panel.string>
- <panel.string
- name="can_not_view">
- You are not allowed to view this script.
- </panel.string>
- <panel.string
- name="public_objects_can_not_run">
- Public Objects cannot run scripts
- </panel.string>
- <panel.string
- name="script_running">
- Running
- </panel.string>
- <panel.string
- name="Title">
- Script: [NAME]
- </panel.string>
- <text_editor
- type="string"
- length="1"
- bevel_style="none"
- border_style="line"
- bottom="393"
- follows="left|top|right|bottom"
- font="Monospace"
- height="376"
- ignore_tab="false"
- layout="topleft"
- left="4"
- max_length="65536"
- name="Script Editor"
- width="492"
- word_wrap="true">
- Loading...
- </text_editor>
- <button
- bottom="499"
- follows="right|bottom"
- height="20"
- label="Save"
- label_selected="Save"
- layout="topleft"
- left="360"
- name="Save_btn"
- width="128" />
- <scroll_list
- bottom="457"
- follows="left|right|bottom"
- height="60"
- layout="topleft"
- left="4"
- name="lsl errors"
- width="492" />
- <combo_box
- bottom="499"
- follows="left|bottom"
- height="20"
- label="Insert..."
- layout="topleft"
- left="12"
- name="Insert..."
- width="128" />
- <text
- bottom="473"
- follows="left|bottom"
- height="12"
- layout="topleft"
- left="12"
- name="line_col"
- width="128" />
- <menu_bar
- bg_visible="false"
- bottom="18"
- follows="left|top|right"
- height="18"
- layout="topleft"
- left="8"
- mouse_opaque="false"
- name="script_menu"
- width="476">
- <menu
- bottom="18"
- height="62"
- label="File"
- layout="topleft"
- left="0"
- mouse_opaque="false"
- name="File"
- width="138">
- <menu_item_call
- label="Save"
- layout="topleft"
- name="Save" />
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Revert All Changes"
- layout="topleft"
- name="Revert All Changes" />
- </menu>
- <menu
- bottom="-647"
- height="198"
- label="Edit"
- layout="topleft"
- left="222"
- mouse_opaque="false"
- name="Edit"
- width="139">
- <menu_item_call
- enabled="false"
- label="Undo"
- layout="topleft"
- name="Undo" />
- <menu_item_call
- enabled="false"
- label="Redo"
- layout="topleft"
- name="Redo" />
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- enabled="false"
- label="Cut"
- layout="topleft"
- name="Cut" />
- <menu_item_call
- enabled="false"
- label="Copy"
- layout="topleft"
- name="Copy" />
- <menu_item_call
- enabled="false"
- label="Paste"
- layout="topleft"
- name="Paste" />
- <menu_item_separator
- layout="topleft"
- name="separator2" />
- <menu_item_call
- label="Select All"
- layout="topleft"
- name="Select All" />
- <menu_item_call
- enabled="false"
- label="Deselect"
- layout="topleft"
- name="Deselect" />
- <menu_item_separator
- layout="topleft"
- name="separator3" />
- <menu_item_call
- label="Search / Replace..."
- layout="topleft"
- name="Search / Replace..." />
- </menu>
- <menu
- bottom="18"
- height="34"
- label="Help"
- layout="topleft"
- left="0"
- mouse_opaque="false"
- name="Help"
- width="112">
- <menu_item_call
- label="Help..."
- layout="topleft"
- name="Help..." />
- <menu_item_call
- label="LSL Wiki Help..."
- layout="topleft"
- name="LSL Wiki Help..." />
- </menu>
- </menu_bar>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + bevel_style="none" + border_style="line" + bottom="550" + follows="left|top|right|bottom" + height="508" + layout="topleft" + left="0" + name="script panel" + width="500"> + <panel.string + name="loading"> + Loading... + </panel.string> + <panel.string + name="can_not_view"> + You are not allowed to view this script. + </panel.string> + <panel.string + name="public_objects_can_not_run"> + Public Objects cannot run scripts + </panel.string> + <panel.string + name="script_running"> + Running + </panel.string> + <panel.string + name="Title"> + Script: [NAME] + </panel.string> + <text_editor + type="string" + length="1" + bevel_style="none" + border_style="line" + bottom="393" + follows="left|top|right|bottom" + font="Monospace" + height="376" + ignore_tab="false" + layout="topleft" + left="4" + max_length="65536" + name="Script Editor" + width="492" + word_wrap="true"> + Loading... + </text_editor> + <button + bottom="499" + follows="right|bottom" + height="20" + label="Save" + label_selected="Save" + layout="topleft" + left="360" + name="Save_btn" + width="128" /> + <scroll_list + bottom="457" + follows="left|right|bottom" + height="60" + layout="topleft" + left="4" + name="lsl errors" + width="492" /> + <combo_box + bottom="499" + follows="left|bottom" + height="20" + label="Insert..." + layout="topleft" + left="12" + name="Insert..." + width="128" /> + <text + bottom="473" + follows="left|bottom" + height="12" + layout="topleft" + left="12" + name="line_col" + width="128" /> + <menu_bar + bg_visible="false" + bottom="18" + follows="left|top|right" + height="18" + layout="topleft" + left="8" + mouse_opaque="false" + name="script_menu" + width="476"> + <menu + bottom="18" + height="62" + label="File" + layout="topleft" + left="0" + mouse_opaque="false" + name="File" + width="138"> + <menu_item_call + label="Save" + layout="topleft" + name="Save" /> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="Revert All Changes" + layout="topleft" + name="Revert All Changes" /> + </menu> + <menu + bottom="-647" + height="198" + label="Edit" + layout="topleft" + left="222" + mouse_opaque="false" + name="Edit" + width="139"> + <menu_item_call + enabled="false" + label="Undo" + layout="topleft" + name="Undo" /> + <menu_item_call + enabled="false" + label="Redo" + layout="topleft" + name="Redo" /> + <menu_item_separator + layout="topleft" /> + <menu_item_call + enabled="false" + label="Cut" + layout="topleft" + name="Cut" /> + <menu_item_call + enabled="false" + label="Copy" + layout="topleft" + name="Copy" /> + <menu_item_call + enabled="false" + label="Paste" + layout="topleft" + name="Paste" /> + <menu_item_separator + layout="topleft" + name="separator2" /> + <menu_item_call + label="Select All" + layout="topleft" + name="Select All" /> + <menu_item_call + enabled="false" + label="Deselect" + layout="topleft" + name="Deselect" /> + <menu_item_separator + layout="topleft" + name="separator3" /> + <menu_item_call + label="Search / Replace..." + layout="topleft" + name="Search / Replace..." /> + </menu> + <menu + bottom="18" + height="34" + label="Help" + layout="topleft" + left="0" + mouse_opaque="false" + name="Help" + width="112"> + <menu_item_call + label="Help..." + layout="topleft" + name="Help..." /> + <menu_item_call + label="LSL Wiki Help..." + layout="topleft" + name="LSL Wiki Help..." /> + </menu> + </menu_bar> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml index e447e541e0..4ae90380f8 100644 --- a/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml +++ b/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel name="sidetray_tab_panel" bottom="0" height="25" left="0" background_visible="false" bg_visible="false" border="false" border_visible="false" @@ -12,4 +12,4 @@ name="sidetray_tab_title" width="100"> Side Panel </text> -</panel>
+</panel> diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml index 8f6a2d7648..b7ce812dc8 100644 --- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml +++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel name="Teleport History" bottom="0" height="326" left="0" width="380" border="true" follows="left|top|right|bottom"> <scroll_list bottom="0" can_resize="true" column_padding="0" draw_heading="true" @@ -9,4 +9,4 @@ <column dynamicwidth="true" label="Region" name="region" /> <column name="index" width="0" /> </scroll_list> -</panel>
+</panel> diff --git a/indra/newview/skins/default/xui/en/panel_world_map.xml b/indra/newview/skins/default/xui/en/panel_world_map.xml index 532f487780..ee355fa95c 100644 --- a/indra/newview/skins/default/xui/en/panel_world_map.xml +++ b/indra/newview/skins/default/xui/en/panel_world_map.xml @@ -1,128 +1,128 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- follows="left|top|right|bottom"
- height="300"
- layout="topleft"
- name="world_map"
- width="400">
- <panel.string
- name="Loading">
- Loading...
- </panel.string>
- <panel.string
- name="InvalidLocation">
- Invalid Location
- </panel.string>
- <panel.string
- name="world_map_north">
- N
- </panel.string>
- <panel.string
- name="world_map_east">
- E
- </panel.string>
- <panel.string
- name="world_map_west">
- W
- </panel.string>
- <panel.string
- name="world_map_south">
- S
- </panel.string>
- <panel.string
- name="world_map_southeast">
- SE
- </panel.string>
- <panel.string
- name="world_map_northeast">
- NE
- </panel.string>
- <panel.string
- name="world_map_southwest">
- SW
- </panel.string>
- <panel.string
- name="world_map_northwest">
- NW
- </panel.string>
- <text
- type="string"
- length="1"
- label="N"
- layout="topleft"
- name="floater_map_north"
- text="N"
- text_color="1 1 1 0.7">
- N
- </text>
- <text
- type="string"
- length="1"
- label="E"
- layout="topleft"
- name="floater_map_east"
- text="E"
- text_color="1 1 1 0.7">
- E
- </text>
- <text
- type="string"
- length="1"
- label="W"
- layout="topleft"
- name="floater_map_west"
- text="W"
- text_color="1 1 1 0.7">
- W
- </text>
- <text
- type="string"
- length="1"
- label="S"
- layout="topleft"
- name="floater_map_south"
- text="S"
- text_color="1 1 1 0.7">
- S
- </text>
- <text
- type="string"
- length="1"
- label="SE"
- layout="topleft"
- name="floater_map_southeast"
- text="SE"
- text_color="1 1 1 0.7">
- SE
- </text>
- <text
- type="string"
- length="1"
- label="NE"
- layout="topleft"
- name="floater_map_northeast"
- text="NE"
- text_color="1 1 1 0.7">
- NE
- </text>
- <text
- type="string"
- length="1"
- label="SW"
- layout="topleft"
- name="floater_map_southwest"
- text="SW"
- text_color="1 1 1 0.7">
- SW
- </text>
- <text
- type="string"
- length="1"
- label="NW"
- layout="topleft"
- name="floater_map_northwest"
- text="NW"
- text_color="1 1 1 0.7">
- NW
- </text>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + follows="left|top|right|bottom" + height="300" + layout="topleft" + name="world_map" + width="400"> + <panel.string + name="Loading"> + Loading... + </panel.string> + <panel.string + name="InvalidLocation"> + Invalid Location + </panel.string> + <panel.string + name="world_map_north"> + N + </panel.string> + <panel.string + name="world_map_east"> + E + </panel.string> + <panel.string + name="world_map_west"> + W + </panel.string> + <panel.string + name="world_map_south"> + S + </panel.string> + <panel.string + name="world_map_southeast"> + SE + </panel.string> + <panel.string + name="world_map_northeast"> + NE + </panel.string> + <panel.string + name="world_map_southwest"> + SW + </panel.string> + <panel.string + name="world_map_northwest"> + NW + </panel.string> + <text + type="string" + length="1" + label="N" + layout="topleft" + name="floater_map_north" + text="N" + text_color="1 1 1 0.7"> + N + </text> + <text + type="string" + length="1" + label="E" + layout="topleft" + name="floater_map_east" + text="E" + text_color="1 1 1 0.7"> + E + </text> + <text + type="string" + length="1" + label="W" + layout="topleft" + name="floater_map_west" + text="W" + text_color="1 1 1 0.7"> + W + </text> + <text + type="string" + length="1" + label="S" + layout="topleft" + name="floater_map_south" + text="S" + text_color="1 1 1 0.7"> + S + </text> + <text + type="string" + length="1" + label="SE" + layout="topleft" + name="floater_map_southeast" + text="SE" + text_color="1 1 1 0.7"> + SE + </text> + <text + type="string" + length="1" + label="NE" + layout="topleft" + name="floater_map_northeast" + text="NE" + text_color="1 1 1 0.7"> + NE + </text> + <text + type="string" + length="1" + label="SW" + layout="topleft" + name="floater_map_southwest" + text="SW" + text_color="1 1 1 0.7"> + SW + </text> + <text + type="string" + length="1" + label="NW" + layout="topleft" + name="floater_map_northwest" + text="NW" + text_color="1 1 1 0.7"> + NW + </text> +</panel> diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg index 23efd65c45..67233cbda0 100644 --- a/scripts/messages/message_template.msg +++ b/scripts/messages/message_template.msg @@ -8945,3 +8945,21 @@ version 2.0 { CRC U32 } } } + +{ + LinkInventoryItem Low 426 NotTrusted Zerocoded + { + AgentData Single + { AgentID LLUUID } + { SessionID LLUUID } + } + { + InventoryData Variable + { CallbackID U32 } // Async Response + { FolderID LLUUID } + { OldItemID LLUUID } + { Name Variable 1 } + { AssetType U8 } + } +} + |