aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.txt6
-rw-r--r--linden/indra/newview/llinventoryactions.cpp9
-rw-r--r--linden/indra/newview/llinventorybridge.cpp172
3 files changed, 136 insertions, 51 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 60d3534..abd78fb 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -37,6 +37,12 @@
37 modified: linden/indra/newview/skins/default/xui/en-us/panel_preferences_network.xml 37 modified: linden/indra/newview/skins/default/xui/en-us/panel_preferences_network.xml
38 modified: linden/indra/newview/app_settings/settings.xml 38 modified: linden/indra/newview/app_settings/settings.xml
39 39
40
41 * Applied patch to wear multiple attachments at once (VWR-5063).
42
43 modified: linden/indra/newview/llinventoryactions.cpp
44 modified: linden/indra/newview/llinventorybridge.cpp
45
40 46
412009-09-10 McCabe Maxsted <hakushakukun@gmail.com> 472009-09-10 McCabe Maxsted <hakushakukun@gmail.com>
42 48
diff --git a/linden/indra/newview/llinventoryactions.cpp b/linden/indra/newview/llinventoryactions.cpp
index 2ee7307..b598c83 100644
--- a/linden/indra/newview/llinventoryactions.cpp
+++ b/linden/indra/newview/llinventoryactions.cpp
@@ -85,6 +85,9 @@
85#include "lluictrlfactory.h" 85#include "lluictrlfactory.h"
86#include "llselectmgr.h" 86#include "llselectmgr.h"
87 87
88// Defined in llinventorybridge.cpp
89void wear_attachments_on_avatar(const std::set<LLUUID>& item_ids, BOOL remove);
90
88const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not) 91const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not)
89const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably not) 92const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably not)
90const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not) 93const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not)
@@ -115,6 +118,12 @@ bool doToSelected(LLFolderView* folder, std::string action)
115 std::set<LLUUID> selected_items; 118 std::set<LLUUID> selected_items;
116 folder->getSelectionList(selected_items); 119 folder->getSelectionList(selected_items);
117 120
121 if ( ("attach" == action) && (selected_items.size() > 1) )
122 {
123 wear_attachments_on_avatar(selected_items, FALSE);
124 return true;
125 }
126
118 LLMultiPreview* multi_previewp = NULL; 127 LLMultiPreview* multi_previewp = NULL;
119 LLMultiProperties* multi_propertiesp = NULL; 128 LLMultiProperties* multi_propertiesp = NULL;
120 129
diff --git a/linden/indra/newview/llinventorybridge.cpp b/linden/indra/newview/llinventorybridge.cpp
index 52b15cb..3505bd3 100644
--- a/linden/indra/newview/llinventorybridge.cpp
+++ b/linden/indra/newview/llinventorybridge.cpp
@@ -111,6 +111,8 @@ void remove_inventory_category_from_avatar(LLInventoryCategory* category);
111void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata); 111void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata);
112void move_task_inventory_callback(S32 option, void* user_data); 112void move_task_inventory_callback(S32 option, void* user_data);
113void confirm_replace_attachment_rez(S32 option, void* user_data); 113void confirm_replace_attachment_rez(S32 option, void* user_data);
114void wear_attachments_on_avatar(const std::set<LLUUID>& item_ids, BOOL remove);
115void wear_attachments_on_avatar(const LLInventoryModel::item_array_t& items, BOOL remove);
114 116
115std::string ICON_NAME[ICON_NAME_COUNT] = 117std::string ICON_NAME[ICON_NAME_COUNT] =
116{ 118{
@@ -3671,6 +3673,31 @@ private:
3671 bool mAppend; 3673 bool mAppend;
3672}; 3674};
3673 3675
3676class LLWearAttachmentsCallback : public LLInventoryCallback
3677{
3678public:
3679 LLWearAttachmentsCallback(bool append) : mAppend(append) {}
3680 void fire(const LLUUID& item_id)
3681 {
3682 mItemIDs.insert(item_id);
3683 }
3684protected:
3685 ~LLWearAttachmentsCallback()
3686 {
3687 if( LLInventoryCallbackManager::is_instantiated() )
3688 {
3689 wear_attachments_on_avatar(mItemIDs, mAppend);
3690 }
3691 else
3692 {
3693 llwarns << "Dropping unhandled LLWearAttachments" << llendl;
3694 }
3695 }
3696private:
3697 std::set<LLUUID> mItemIDs;
3698 bool mAppend;
3699};
3700
3674void LLOutfitObserver::done() 3701void LLOutfitObserver::done()
3675{ 3702{
3676 // We now have an outfit ready to be copied to agent inventory. Do 3703 // We now have an outfit ready to be copied to agent inventory. Do
@@ -4026,57 +4053,7 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata )
4026 if( obj_count > 0 ) 4053 if( obj_count > 0 )
4027 { 4054 {
4028 // We've found some attachements. Add these. 4055 // We've found some attachements. Add these.
4029 4056 wear_attachments_on_avatar(obj_item_array, !wear_info->mAppend);
4030 LLVOAvatar* avatar = gAgent.getAvatarObject();
4031 if( avatar )
4032 {
4033 // Build a compound message to send all the objects that need to be rezzed.
4034
4035 // Limit number of packets to send
4036 const S32 MAX_PACKETS_TO_SEND = 10;
4037 const S32 OBJECTS_PER_PACKET = 4;
4038 const S32 MAX_OBJECTS_TO_SEND = MAX_PACKETS_TO_SEND * OBJECTS_PER_PACKET;
4039 if( obj_count > MAX_OBJECTS_TO_SEND )
4040 {
4041 obj_count = MAX_OBJECTS_TO_SEND;
4042 }
4043
4044 // Create an id to keep the parts of the compound message together
4045 LLUUID compound_msg_id;
4046 compound_msg_id.generate();
4047 LLMessageSystem* msg = gMessageSystem;
4048
4049 for(i = 0; i < obj_count; ++i)
4050 {
4051 if( 0 == (i % OBJECTS_PER_PACKET) )
4052 {
4053 // Start a new message chunk
4054 msg->newMessageFast(_PREHASH_RezMultipleAttachmentsFromInv);
4055 msg->nextBlockFast(_PREHASH_AgentData);
4056 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
4057 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
4058 msg->nextBlockFast(_PREHASH_HeaderData);
4059 msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id );
4060 msg->addU8Fast(_PREHASH_TotalObjects, obj_count );
4061 msg->addBOOLFast(_PREHASH_FirstDetachAll, !wear_info->mAppend );
4062 }
4063
4064 LLInventoryItem* item = obj_item_array.get(i);
4065 msg->nextBlockFast(_PREHASH_ObjectData );
4066 msg->addUUIDFast(_PREHASH_ItemID, item->getUUID() );
4067 msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner());
4068 msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point
4069 pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
4070 msg->addStringFast(_PREHASH_Name, item->getName());
4071 msg->addStringFast(_PREHASH_Description, item->getDescription());
4072
4073 if( (i+1 == obj_count) || ((OBJECTS_PER_PACKET-1) == (i % OBJECTS_PER_PACKET)) )
4074 {
4075 // End of message chunk
4076 msg->sendReliable( gAgent.getRegion()->getHost() );
4077 }
4078 }
4079 }
4080 } 4057 }
4081 } 4058 }
4082 delete wear_info; 4059 delete wear_info;
@@ -4160,6 +4137,99 @@ void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, B
4160 dec_busy_count(); 4137 dec_busy_count();
4161} 4138}
4162 4139
4140void wear_attachments_on_avatar(const std::set<LLUUID>& item_ids, BOOL remove)
4141{
4142 // NOTE: the inventory items can reside in the user's inventory, the library, or any combination of the two
4143
4144 LLInventoryModel::item_array_t items;
4145 LLPointer<LLInventoryCallback> cb;
4146
4147 for (std::set<LLUUID>::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it)
4148 {
4149 LLViewerInventoryItem* item = gInventory.getItem(*it);
4150 if ( (item) && (LLAssetType::AT_OBJECT == item->getType()) )
4151 {
4152 if ( (gInventory.isObjectDescendentOf(*it, gAgent.getInventoryRootID())) )
4153 {
4154 items.put(item);
4155 }
4156 else if ( (item->isComplete()) )
4157 {
4158 if (cb.isNull())
4159 cb = new LLWearAttachmentsCallback(remove);
4160 copy_inventory_item(gAgent.getID(), item->getPermissions().getOwner(), item->getUUID(), LLUUID::null, std::string(), cb);
4161 }
4162 }
4163 }
4164
4165 wear_attachments_on_avatar(items, remove);
4166}
4167
4168void wear_attachments_on_avatar(const LLInventoryModel::item_array_t& items, BOOL remove)
4169{
4170 // NOTE: all inventory items must reside in the user's inventory
4171
4172 LLVOAvatar* avatarp = gAgent.getAvatarObject();
4173 if(!avatarp)
4174 {
4175 llwarns << "No avatar found." << llendl;
4176 return;
4177 }
4178
4179 // Build a compound message to send all the objects that need to be rezzed.
4180
4181 // Limit number of packets to send
4182 const S32 MAX_PACKETS_TO_SEND = 10;
4183 const S32 OBJECTS_PER_PACKET = 4;
4184 const S32 MAX_OBJECTS_TO_SEND = MAX_PACKETS_TO_SEND * OBJECTS_PER_PACKET;
4185
4186 S32 count = items.count();
4187 if ( !count )
4188 {
4189 return;
4190 }
4191 else if ( count > MAX_OBJECTS_TO_SEND )
4192 {
4193 count = MAX_OBJECTS_TO_SEND;
4194 }
4195
4196 // Create an id to keep the parts of the compound message together
4197 LLUUID compound_msg_id;
4198 compound_msg_id.generate();
4199 LLMessageSystem* msg = gMessageSystem;
4200
4201 for(S32 i = 0; i < count; ++i)
4202 {
4203 if( 0 == (i % OBJECTS_PER_PACKET) )
4204 {
4205 // Start a new message chunk
4206 msg->newMessageFast(_PREHASH_RezMultipleAttachmentsFromInv);
4207 msg->nextBlockFast(_PREHASH_AgentData);
4208 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
4209 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
4210 msg->nextBlockFast(_PREHASH_HeaderData);
4211 msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id );
4212 msg->addU8Fast(_PREHASH_TotalObjects, count );
4213 msg->addBOOLFast(_PREHASH_FirstDetachAll, remove );
4214 }
4215
4216 LLInventoryItem* item = items.get(i);
4217 msg->nextBlockFast(_PREHASH_ObjectData );
4218 msg->addUUIDFast(_PREHASH_ItemID, item->getUUID() );
4219 msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner());
4220 msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point
4221 pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
4222 msg->addStringFast(_PREHASH_Name, item->getName());
4223 msg->addStringFast(_PREHASH_Description, item->getDescription());
4224
4225 if( (i+1 == count) || ((OBJECTS_PER_PACKET-1) == (i % OBJECTS_PER_PACKET)) )
4226 {
4227 // End of message chunk
4228 msg->sendReliable( gAgent.getRegion()->getHost() );
4229 }
4230 }
4231}
4232
4163void remove_inventory_category_from_avatar( LLInventoryCategory* category ) 4233void remove_inventory_category_from_avatar( LLInventoryCategory* category )
4164{ 4234{
4165 if(!category) return; 4235 if(!category) return;