llviewerinventory.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 #include "llviewerinventory.h"
00034 
00035 #include "message.h"
00036 #include "indra_constants.h"
00037 
00038 #include "llagent.h"
00039 #include "llviewercontrol.h"
00040 #include "llconsole.h"
00041 #include "llinventorymodel.h"
00042 #include "llnotify.h"
00043 #include "llimview.h"
00044 #include "llgesturemgr.h"
00045 
00046 #include "llinventoryview.h"
00047 
00048 #include "llviewerregion.h"
00049 #include "llviewerobjectlist.h"
00050 #include "llpreviewgesture.h"
00051 #include "llviewerwindow.h"
00052 
00056 
00060 
00061 LLViewerInventoryItem::LLViewerInventoryItem(const LLUUID& uuid,
00062                                                                                          const LLUUID& parent_uuid,
00063                                                                                          const LLPermissions& perm,
00064                                                                                          const LLUUID& asset_uuid,
00065                                                                                          LLAssetType::EType type,
00066                                                                                          LLInventoryType::EType inv_type,
00067                                                                                          const LLString& name,
00068                                                                                          const LLString& desc,
00069                                                                                          const LLSaleInfo& sale_info,
00070                                                                                          U32 flags,
00071                                                                                          S32 creation_date_utc) :
00072         LLInventoryItem(uuid, parent_uuid, perm, asset_uuid, type, inv_type,
00073                                         name, desc, sale_info, flags, creation_date_utc),
00074         mIsComplete(TRUE)
00075 {
00076 }
00077 
00078 LLViewerInventoryItem::LLViewerInventoryItem(const LLUUID& item_id,
00079                                                                                          const LLUUID& parent_id,
00080                                                                                          const char* name,
00081                                                                                          LLInventoryType::EType inv_type) :
00082         LLInventoryItem(),
00083         mIsComplete(FALSE)
00084 {
00085         mUUID = item_id;
00086         mParentUUID = parent_id;
00087         mInventoryType = inv_type;
00088         mName.assign(name);
00089 }
00090 
00091 LLViewerInventoryItem::LLViewerInventoryItem() :
00092         LLInventoryItem(),
00093         mIsComplete(FALSE)
00094 {
00095 }
00096 
00097 LLViewerInventoryItem::LLViewerInventoryItem(const LLViewerInventoryItem* other) :
00098         LLInventoryItem()
00099 {
00100         copyViewerItem(other);
00101         if (!mIsComplete)
00102         {
00103                 llwarns << "LLViewerInventoryItem copy constructor for incomplete item"
00104                         << mUUID << llendl;
00105         }
00106 }
00107 
00108 LLViewerInventoryItem::LLViewerInventoryItem(const LLInventoryItem *other) :
00109         LLInventoryItem(other),
00110         mIsComplete(TRUE)
00111 {
00112 }
00113 
00114 
00115 LLViewerInventoryItem::~LLViewerInventoryItem()
00116 {
00117 }
00118 
00119 void LLViewerInventoryItem::copyViewerItem(const LLViewerInventoryItem* other)
00120 {
00121         LLInventoryItem::copyItem(other);
00122         mIsComplete = other->mIsComplete;
00123         mTransactionID = other->mTransactionID;
00124 }
00125 
00126 // virtual
00127 void LLViewerInventoryItem::copyItem(const LLInventoryItem *other)
00128 {
00129         LLInventoryItem::copyItem(other);
00130         mIsComplete = true;
00131         mTransactionID.setNull();
00132 }
00133 
00134 void LLViewerInventoryItem::cloneViewerItem(LLPointer<LLViewerInventoryItem>& newitem) const
00135 {
00136         newitem = new LLViewerInventoryItem(this);
00137         if(newitem.notNull())
00138         {
00139                 LLUUID item_id;
00140                 item_id.generate();
00141                 newitem->setUUID(item_id);
00142         }
00143 }
00144 
00145 void LLViewerInventoryItem::removeFromServer()
00146 {
00147         llinfos << "Removing inventory item " << mUUID << " from server."
00148                         << llendl;
00149 
00150         LLInventoryModel::LLCategoryUpdate up(mParentUUID, -1);
00151         gInventory.accountForUpdate(up);
00152 
00153         LLMessageSystem* msg = gMessageSystem;
00154         msg->newMessageFast(_PREHASH_RemoveInventoryItem);
00155         msg->nextBlockFast(_PREHASH_AgentData);
00156         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00157         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 
00158         msg->nextBlockFast(_PREHASH_InventoryData);
00159         msg->addUUIDFast(_PREHASH_ItemID, mUUID);
00160         gAgent.sendReliableMessage();
00161 }
00162 
00163 void LLViewerInventoryItem::updateServer(BOOL is_new) const
00164 {
00165         if(!mIsComplete)
00166         {
00167                 // *FIX: deal with this better.
00168                 // If we're crashing here then the UI is incorrectly enabled.
00169                 llerrs << "LLViewerInventoryItem::updateServer() - for incomplete item"
00170                            << llendl;
00171                 return;
00172         }
00173         if(gAgent.getID() != mPermissions.getOwner())
00174         {
00175                 // *FIX: deal with this better.
00176                 llwarns << "LLViewerInventoryItem::updateServer() - for unowned item"
00177                                 << llendl;
00178                 return;
00179         }
00180         LLInventoryModel::LLCategoryUpdate up(mParentUUID, is_new ? 1 : 0);
00181         gInventory.accountForUpdate(up);
00182 
00183         LLMessageSystem* msg = gMessageSystem;
00184         msg->newMessageFast(_PREHASH_UpdateInventoryItem);
00185         msg->nextBlockFast(_PREHASH_AgentData);
00186         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00187         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00188         msg->addUUIDFast(_PREHASH_TransactionID, mTransactionID);
00189         msg->nextBlockFast(_PREHASH_InventoryData);
00190         msg->addU32Fast(_PREHASH_CallbackID, 0);
00191         packMessage(msg);
00192         gAgent.sendReliableMessage();
00193 }
00194 
00195 void LLViewerInventoryItem::fetchFromServer(void) const
00196 {
00197         if(!mIsComplete)
00198         {
00199                 LLMessageSystem* msg = gMessageSystem;
00200                 msg->newMessage("FetchInventory");
00201                 msg->nextBlock("AgentData");
00202                 msg->addUUID("AgentID", gAgent.getID());
00203                 msg->addUUID("SessionID", gAgent.getSessionID());
00204                 msg->nextBlock("InventoryData");
00205                 msg->addUUID("OwnerID", mPermissions.getOwner());
00206                 msg->addUUID("ItemID", mUUID);
00207                 gAgent.sendReliableMessage();
00208         }
00209         else
00210         {
00211                 // *FIX: this can be removed after a bit.
00212                 llwarns << "request to fetch complete item" << llendl;
00213         }
00214 }
00215 
00216 // virtual
00217 BOOL LLViewerInventoryItem::unpackMessage(LLSD item)
00218 {
00219         BOOL rv = LLInventoryItem::fromLLSD(item);
00220         mIsComplete = TRUE;
00221         return rv;
00222 }
00223 
00224 // virtual
00225 BOOL LLViewerInventoryItem::unpackMessage(
00226         LLMessageSystem* msg, const char* block, S32 block_num)
00227 {
00228         BOOL rv = LLInventoryItem::unpackMessage(msg, block, block_num);
00229         mIsComplete = TRUE;
00230         return rv;
00231 }
00232 
00233 void LLViewerInventoryItem::setTransactionID(const LLTransactionID& transaction_id)
00234 {
00235         mTransactionID = transaction_id;
00236 }
00237 // virtual
00238 void LLViewerInventoryItem::packMessage(LLMessageSystem* msg) const
00239 {
00240         msg->addUUIDFast(_PREHASH_ItemID, mUUID);
00241         msg->addUUIDFast(_PREHASH_FolderID, mParentUUID);
00242         mPermissions.packMessage(msg);
00243         msg->addUUIDFast(_PREHASH_TransactionID, mTransactionID);
00244         S8 type = static_cast<S8>(mType);
00245         msg->addS8Fast(_PREHASH_Type, type);
00246         type = static_cast<S8>(mInventoryType);
00247         msg->addS8Fast(_PREHASH_InvType, type);
00248         msg->addU32Fast(_PREHASH_Flags, mFlags);
00249         mSaleInfo.packMessage(msg);
00250         msg->addStringFast(_PREHASH_Name, mName);
00251         msg->addStringFast(_PREHASH_Description, mDescription);
00252         msg->addS32Fast(_PREHASH_CreationDate, mCreationDate);
00253         U32 crc = getCRC32();
00254         msg->addU32Fast(_PREHASH_CRC, crc);
00255 }
00256 // virtual
00257 BOOL LLViewerInventoryItem::importFile(LLFILE* fp)
00258 {
00259         BOOL rv = LLInventoryItem::importFile(fp);
00260         mIsComplete = TRUE;
00261         return rv;
00262 }
00263 
00264 // virtual
00265 BOOL LLViewerInventoryItem::importLegacyStream(std::istream& input_stream)
00266 {
00267         BOOL rv = LLInventoryItem::importLegacyStream(input_stream);
00268         mIsComplete = TRUE;
00269         return rv;
00270 }
00271 
00272 bool LLViewerInventoryItem::importFileLocal(LLFILE* fp)
00273 {
00274         // TODO: convert all functions that return BOOL to return bool
00275         bool rv = (LLInventoryItem::importFile(fp) ? true : false);
00276         mIsComplete = false;
00277         return rv;
00278 }
00279 
00280 bool LLViewerInventoryItem::exportFileLocal(LLFILE* fp) const
00281 {
00282         char uuid_str[UUID_STR_LENGTH];         /* Flawfinder: ignore */
00283         fprintf(fp, "\tinv_item\t0\n\t{\n");
00284         mUUID.toString(uuid_str);
00285         fprintf(fp, "\t\titem_id\t%s\n", uuid_str);
00286         mParentUUID.toString(uuid_str);
00287         fprintf(fp, "\t\tparent_id\t%s\n", uuid_str);
00288         mPermissions.exportFile(fp);
00289         fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
00290         const char* inv_type_str = LLInventoryType::lookup(mInventoryType);
00291         if(inv_type_str) fprintf(fp, "\t\tinv_type\t%s\n", inv_type_str);
00292         fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
00293         fprintf(fp, "\t\tcreation_date\t%d\n", mCreationDate);
00294         fprintf(fp,"\t}\n");
00295         return true;
00296 }
00297 
00298 void LLViewerInventoryItem::updateParentOnServer(BOOL restamp) const
00299 {
00300         LLMessageSystem* msg = gMessageSystem;
00301         msg->newMessageFast(_PREHASH_MoveInventoryItem);
00302         msg->nextBlockFast(_PREHASH_AgentData);
00303         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00304         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00305         msg->addBOOLFast(_PREHASH_Stamp, restamp);
00306         msg->nextBlockFast(_PREHASH_InventoryData);
00307         msg->addUUIDFast(_PREHASH_ItemID, mUUID);
00308         msg->addUUIDFast(_PREHASH_FolderID, mParentUUID);
00309         msg->addString("NewName", NULL);
00310         gAgent.sendReliableMessage();
00311 }
00312 
00313 //void LLViewerInventoryItem::setCloneCount(S32 clones)
00314 //{
00315 //      mClones = clones;
00316 //}
00317 
00318 //S32 LLViewerInventoryItem::getCloneCount() const
00319 //{
00320 //      return mClones;
00321 //}
00322 
00326 
00327 LLViewerInventoryCategory::LLViewerInventoryCategory(const LLUUID& uuid,
00328                                                                                                          const LLUUID& parent_uuid,
00329                                                                                                          LLAssetType::EType pref,
00330                                                                                                          const LLString& name,
00331                                                                                                          const LLUUID& owner_id) :
00332         LLInventoryCategory(uuid, parent_uuid, pref, name),
00333         mOwnerID(owner_id),
00334         mVersion(LLViewerInventoryCategory::VERSION_UNKNOWN),
00335         mDescendentCount(LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)
00336 {
00337         mDescendentsRequested.reset();
00338 }
00339 
00340 LLViewerInventoryCategory::LLViewerInventoryCategory(const LLUUID& owner_id) :
00341         mOwnerID(owner_id),
00342         mVersion(LLViewerInventoryCategory::VERSION_UNKNOWN),
00343         mDescendentCount(LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)
00344 {
00345         mDescendentsRequested.reset();
00346 }
00347 
00348 LLViewerInventoryCategory::LLViewerInventoryCategory(const LLViewerInventoryCategory* other)
00349 {
00350         copyViewerCategory(other);
00351 }
00352 
00353 LLViewerInventoryCategory::~LLViewerInventoryCategory()
00354 {
00355 }
00356 
00357 void LLViewerInventoryCategory::copyViewerCategory(const LLViewerInventoryCategory* other)
00358 {
00359         copyCategory(other);
00360         mOwnerID = other->mOwnerID;
00361         mVersion = other->mVersion;
00362         mDescendentCount = other->mDescendentCount;
00363         mDescendentsRequested = other->mDescendentsRequested;
00364 }
00365 
00366 
00367 void LLViewerInventoryCategory::updateParentOnServer(BOOL restamp) const
00368 {
00369         LLMessageSystem* msg = gMessageSystem;
00370         msg->newMessageFast(_PREHASH_MoveInventoryFolder);
00371         msg->nextBlockFast(_PREHASH_AgentData);
00372         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00373         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00374 
00375         msg->addBOOL("Stamp", restamp);
00376         msg->nextBlockFast(_PREHASH_InventoryData);
00377         msg->addUUIDFast(_PREHASH_FolderID, mUUID);
00378         msg->addUUIDFast(_PREHASH_ParentID, mParentUUID);
00379         gAgent.sendReliableMessage();
00380 }
00381 
00382 void LLViewerInventoryCategory::updateServer(BOOL is_new) const
00383 {
00384         // communicate that change with the server.
00385         if(LLAssetType::AT_NONE != mPreferredType)
00386         {
00387                 LLNotifyBox::showXml("CannotModifyProtectedCategories");
00388                 return;
00389         }
00390 
00391         LLInventoryModel::LLCategoryUpdate up(mParentUUID, is_new ? 1 : 0);
00392         gInventory.accountForUpdate(up);
00393 
00394         LLMessageSystem* msg = gMessageSystem;
00395         msg->newMessageFast(_PREHASH_UpdateInventoryFolder);
00396         msg->nextBlockFast(_PREHASH_AgentData);
00397         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00398         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00399         msg->nextBlockFast(_PREHASH_FolderData);
00400         packMessage(msg);
00401         gAgent.sendReliableMessage();
00402 }
00403 
00404 void LLViewerInventoryCategory::removeFromServer( void )
00405 {
00406         llinfos << "Removing inventory category " << mUUID << " from server."
00407                         << llendl;
00408         // communicate that change with the server.
00409         if(LLAssetType::AT_NONE != mPreferredType)
00410         {
00411                 LLNotifyBox::showXml("CannotRemoveProtectedCategories");
00412                 return;
00413         }
00414 
00415         LLInventoryModel::LLCategoryUpdate up(mParentUUID, -1);
00416         gInventory.accountForUpdate(up);
00417 
00418         LLMessageSystem* msg = gMessageSystem;
00419         msg->newMessageFast(_PREHASH_RemoveInventoryFolder);
00420         msg->nextBlockFast(_PREHASH_AgentData);
00421         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00422         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00423         msg->nextBlockFast(_PREHASH_FolderData);
00424         msg->addUUIDFast(_PREHASH_FolderID, mUUID);
00425         gAgent.sendReliableMessage();
00426 }
00427 
00428 bool LLViewerInventoryCategory::fetchDescendents()
00429 {
00430         if((VERSION_UNKNOWN == mVersion)
00431            && mDescendentsRequested.hasExpired())       //Expired check prevents multiple downloads.
00432         {
00433                 const F32 FETCH_TIMER_EXPIRY = 10.0f;
00434                 mDescendentsRequested.reset();
00435                 mDescendentsRequested.setTimerExpirySec(FETCH_TIMER_EXPIRY);
00436 
00437                 // bitfield
00438                 // 1 = by date
00439                 // 2 = folders by date
00440                 // Need to mask off anything but the first bit.
00441                 // This comes from LLInventoryFilter from llfolderview.h
00442                 U32 sort_order = gSavedSettings.getU32("InventorySortOrder") & 0x1;
00443 
00444                 std::string url = gAgent.getRegion()->getCapability("FetchInventoryDescendents");
00445    
00446                 if (!url.empty()) //Capability found.  Build up LLSD and use it.
00447                 {
00448                         LLInventoryModel::startBackgroundFetch(mUUID);                  
00449                 }
00450                 else
00451                 {       //Deprecated, but if we don't have a capability, use the old system.
00452                         llinfos << "FetchInventoryDescendents capability not found.  Using deprecated UDP message." << llendl;
00453                         LLMessageSystem* msg = gMessageSystem;
00454                         msg->newMessage("FetchInventoryDescendents");
00455                         msg->nextBlock("AgentData");
00456                         msg->addUUID("AgentID", gAgent.getID());
00457                         msg->addUUID("SessionID", gAgent.getSessionID());
00458                         msg->nextBlock("InventoryData");
00459                         msg->addUUID("FolderID", mUUID);
00460                         msg->addUUID("OwnerID", mOwnerID);
00461 
00462                         msg->addS32("SortOrder", sort_order);
00463                         msg->addBOOL("FetchFolders", FALSE);
00464                         msg->addBOOL("FetchItems", TRUE);
00465                         gAgent.sendReliableMessage();
00466                 }
00467                 return true;
00468         }
00469         return false;
00470 }
00471 
00472 bool LLViewerInventoryCategory::importFileLocal(LLFILE* fp)
00473 {
00474         // *NOTE: This buffer size is hard coded into scanf() below.
00475         char buffer[MAX_STRING];                /* Flawfinder: ignore */
00476         char keyword[MAX_STRING];               /* Flawfinder: ignore */
00477         char valuestr[MAX_STRING];              /* Flawfinder: ignore */
00478 
00479         keyword[0] = '\0';
00480         valuestr[0] = '\0';
00481         while(!feof(fp))
00482         {
00483                 if (fgets(buffer, MAX_STRING, fp) == NULL)
00484                 {
00485                         buffer[0] = '\0';
00486                 }
00487                 
00488                 sscanf( /* Flawfinder: ignore */
00489                         buffer, " %254s %254s", keyword, valuestr); 
00490                 if(0 == strcmp("{",keyword))
00491                 {
00492                         continue;
00493                 }
00494                 if(0 == strcmp("}", keyword))
00495                 {
00496                         break;
00497                 }
00498                 else if(0 == strcmp("cat_id", keyword))
00499                 {
00500                         mUUID.set(valuestr);
00501                 }
00502                 else if(0 == strcmp("parent_id", keyword))
00503                 {
00504                         mParentUUID.set(valuestr);
00505                 }
00506                 else if(0 == strcmp("type", keyword))
00507                 {
00508                         mType = LLAssetType::lookup(valuestr);
00509                 }
00510                 else if(0 == strcmp("pref_type", keyword))
00511                 {
00512                         mPreferredType = LLAssetType::lookup(valuestr);
00513                 }
00514                 else if(0 == strcmp("name", keyword))
00515                 {
00516                         //strcpy(valuestr, buffer + strlen(keyword) + 3);
00517                         // *NOTE: Not ANSI C, but widely supported.
00518                         sscanf( /* Flawfinder: ignore */
00519                                 buffer, " %254s %254[^|]", keyword, valuestr);
00520                         mName.assign(valuestr);
00521                         LLString::replaceNonstandardASCII(mName, ' ');
00522                         LLString::replaceChar(mName, '|', ' ');
00523                 }
00524                 else if(0 == strcmp("owner_id", keyword))
00525                 {
00526                         mOwnerID.set(valuestr);
00527                 }
00528                 else if(0 == strcmp("version", keyword))
00529                 {
00530                         sscanf(valuestr, "%d", &mVersion);
00531                 }
00532                 else
00533                 {
00534                         llwarns << "unknown keyword '" << keyword
00535                                         << "' in inventory import category "  << mUUID << llendl;
00536                 }
00537         }
00538         return true;
00539 }
00540 
00541 bool LLViewerInventoryCategory::exportFileLocal(LLFILE* fp) const
00542 {
00543         char uuid_str[UUID_STR_LENGTH];         /* Flawfinder: ignore */
00544         fprintf(fp, "\tinv_category\t0\n\t{\n");
00545         mUUID.toString(uuid_str);
00546         fprintf(fp, "\t\tcat_id\t%s\n", uuid_str);
00547         mParentUUID.toString(uuid_str);
00548         fprintf(fp, "\t\tparent_id\t%s\n", uuid_str);
00549         fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
00550         fprintf(fp, "\t\tpref_type\t%s\n", LLAssetType::lookup(mPreferredType));
00551         fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
00552         mOwnerID.toString(uuid_str);
00553         fprintf(fp, "\t\towner_id\t%s\n", uuid_str);
00554         fprintf(fp, "\t\tversion\t%d\n", mVersion);
00555         fprintf(fp,"\t}\n");
00556         return true;
00557 }
00558 
00562 
00563 /*
00564 void inventory_reliable_callback(void**, S32 status)
00565 {
00566         if(0 != status)
00567         {
00568                 char buffer[MAX_STRING];
00569                 sprintf(buffer, "Reliable packet failure: %d", status);
00570                 llwarns << buffer << llendl;
00571         }
00572 }
00573 */
00574 LLInventoryCallbackManager *LLInventoryCallbackManager::sInstance = NULL;
00575 
00576 LLInventoryCallbackManager::LLInventoryCallbackManager() :
00577         mLastCallback(0)
00578 {
00579         if( sInstance != NULL )
00580         {
00581                 llwarns << "LLInventoryCallbackManager::LLInventoryCallbackManager: unexpected multiple instances" << llendl;
00582                 return;
00583         }
00584         sInstance = this;
00585 }
00586 
00587 LLInventoryCallbackManager::~LLInventoryCallbackManager()
00588 {
00589         if( sInstance != this )
00590         {
00591                 llwarns << "LLInventoryCallbackManager::~LLInventoryCallbackManager: unexpected multiple instances" << llendl;
00592                 return;
00593         }
00594         sInstance = NULL;
00595 }
00596 
00597 U32 LLInventoryCallbackManager::registerCB(LLPointer<LLInventoryCallback> cb)
00598 {
00599         if (cb.isNull())
00600                 return 0;
00601 
00602         mLastCallback++;
00603         if (!mLastCallback)
00604                 mLastCallback++;
00605 
00606         mMap[mLastCallback] = cb;
00607         return mLastCallback;
00608 }
00609 
00610 void LLInventoryCallbackManager::fire(U32 callback_id, const LLUUID& item_id)
00611 {
00612         if (!callback_id || item_id.isNull())
00613                 return;
00614 
00615         std::map<U32, LLPointer<LLInventoryCallback> >::iterator i;
00616 
00617         i = mMap.find(callback_id);
00618         if (i != mMap.end())
00619         {
00620                 (*i).second->fire(item_id);
00621                 mMap.erase(i);
00622         }
00623 }
00624 
00625 void WearOnAvatarCallback::fire(const LLUUID& inv_item)
00626 {
00627         if (inv_item.isNull())
00628                 return;
00629 
00630         LLViewerInventoryItem *item = gInventory.getItem(inv_item);
00631         if (item)
00632         {
00633                 wear_inventory_item_on_avatar(item);
00634         }
00635 }
00636 
00637 RezAttachmentCallback::RezAttachmentCallback(LLViewerJointAttachment *attachmentp)
00638 {
00639         mAttach = attachmentp;
00640 }
00641 RezAttachmentCallback::~RezAttachmentCallback()
00642 {
00643 }
00644 
00645 void RezAttachmentCallback::fire(const LLUUID& inv_item)
00646 {
00647         if (inv_item.isNull())
00648                 return;
00649 
00650         LLViewerInventoryItem *item = gInventory.getItem(inv_item);
00651         if (item)
00652         {
00653                 rez_attachment(item, mAttach);
00654         }
00655 }
00656 
00657 extern LLGestureManager gGestureManager;
00658 void ActivateGestureCallback::fire(const LLUUID& inv_item)
00659 {
00660         if (inv_item.isNull())
00661                 return;
00662 
00663         gGestureManager.activateGesture(inv_item);
00664 }
00665 
00666 void CreateGestureCallback::fire(const LLUUID& inv_item)
00667 {
00668         if (inv_item.isNull())
00669                 return;
00670 
00671         gGestureManager.activateGesture(inv_item);
00672         
00673         LLViewerInventoryItem* item = gInventory.getItem(inv_item);
00674         if (!item) return;
00675     gInventory.updateItem(item);
00676     gInventory.notifyObservers();
00677 
00678         if(!LLPreview::show(inv_item,FALSE))
00679         {
00680                 LLPreviewGesture* preview = LLPreviewGesture::show(LLString("Gesture: ") + item->getName(), inv_item,  LLUUID::null);
00681                 // Force to be entirely onscreen.
00682                 gFloaterView->adjustToFitScreen(preview, FALSE);
00683         }
00684 }
00685 
00686 LLInventoryCallbackManager gInventoryCallbacks;
00687 
00688 void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
00689                                                    const LLUUID& parent, const LLTransactionID& transaction_id,
00690                                                    const std::string& name,
00691                                                    const std::string& desc, LLAssetType::EType asset_type,
00692                                                    LLInventoryType::EType inv_type, EWearableType wtype,
00693                                                    U32 next_owner_perm,
00694                                                    LLPointer<LLInventoryCallback> cb)
00695 {
00696         LLMessageSystem* msg = gMessageSystem;
00697         msg->newMessageFast(_PREHASH_CreateInventoryItem);
00698         msg->nextBlock(_PREHASH_AgentData);
00699         msg->addUUIDFast(_PREHASH_AgentID, agent_id);
00700         msg->addUUIDFast(_PREHASH_SessionID, session_id);
00701         msg->nextBlock(_PREHASH_InventoryBlock);
00702         msg->addU32Fast(_PREHASH_CallbackID, gInventoryCallbacks.registerCB(cb));
00703         msg->addUUIDFast(_PREHASH_FolderID, parent);
00704         msg->addUUIDFast(_PREHASH_TransactionID, transaction_id);
00705         msg->addU32Fast(_PREHASH_NextOwnerMask, next_owner_perm);
00706         msg->addS8Fast(_PREHASH_Type, (S8)asset_type);
00707         msg->addS8Fast(_PREHASH_InvType, (S8)inv_type);
00708         msg->addU8Fast(_PREHASH_WearableType, (U8)wtype);
00709         msg->addStringFast(_PREHASH_Name, name);
00710         msg->addStringFast(_PREHASH_Description, desc);
00711         
00712         gAgent.sendReliableMessage();
00713 }
00714 
00715 void copy_inventory_item(
00716         const LLUUID& agent_id,
00717         const LLUUID& current_owner,
00718         const LLUUID& item_id,
00719         const LLUUID& parent_id,
00720         const std::string& new_name,
00721         LLPointer<LLInventoryCallback> cb)
00722 {
00723         LLMessageSystem* msg = gMessageSystem;
00724         msg->newMessageFast(_PREHASH_CopyInventoryItem);
00725         msg->nextBlockFast(_PREHASH_AgentData);
00726         msg->addUUIDFast(_PREHASH_AgentID, agent_id);
00727         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00728         msg->nextBlockFast(_PREHASH_InventoryData);
00729         msg->addU32Fast(_PREHASH_CallbackID, gInventoryCallbacks.registerCB(cb));
00730         msg->addUUIDFast(_PREHASH_OldAgentID, current_owner);
00731         msg->addUUIDFast(_PREHASH_OldItemID, item_id);
00732         msg->addUUIDFast(_PREHASH_NewFolderID, parent_id);
00733         msg->addStringFast(_PREHASH_NewName, new_name);
00734         gAgent.sendReliableMessage();
00735 }
00736 
00737 void move_inventory_item(
00738         const LLUUID& agent_id,
00739         const LLUUID& session_id,
00740         const LLUUID& item_id,
00741         const LLUUID& parent_id,
00742         const std::string& new_name,
00743         LLPointer<LLInventoryCallback> cb)
00744 {
00745         LLMessageSystem* msg = gMessageSystem;
00746         msg->newMessageFast(_PREHASH_MoveInventoryItem);
00747         msg->nextBlockFast(_PREHASH_AgentData);
00748         msg->addUUIDFast(_PREHASH_AgentID, agent_id);
00749         msg->addUUIDFast(_PREHASH_SessionID, session_id);
00750         msg->addBOOLFast(_PREHASH_Stamp, FALSE);
00751         msg->nextBlockFast(_PREHASH_InventoryData);
00752         msg->addUUIDFast(_PREHASH_ItemID, item_id);
00753         msg->addUUIDFast(_PREHASH_FolderID, parent_id);
00754         msg->addStringFast(_PREHASH_NewName, new_name);
00755         gAgent.sendReliableMessage();
00756 }
00757 
00758 class LLCopyInventoryFromNotecardResponder : public LLHTTPClient::Responder
00759 {
00760 public:
00761         //If we get back a normal response, handle it here
00762         virtual void result(const LLSD& content)
00763         {
00764                 // What do we do here?
00765                 llinfos << "CopyInventoryFromNotecard request successful." << llendl;
00766         }
00767 
00768         //If we get back an error (not found, etc...), handle it here
00769         virtual void error(U32 status, const std::string& reason)
00770         {
00771                 llinfos << "LLCopyInventoryFromNotecardResponder::error "
00772                         << status << ": " << reason << llendl;
00773         }
00774 };
00775 
00776 void copy_inventory_from_notecard(const LLUUID& object_id, const LLUUID& notecard_inv_id, const LLInventoryItem *src, U32 callback_id)
00777 {
00778         LLSD body;
00779         LLViewerRegion* viewer_region = NULL;
00780         if(object_id.notNull())
00781         {
00782                 LLViewerObject* vo = gObjectList.findObject(object_id);
00783                 if(vo)
00784                 {
00785                         viewer_region = vo->getRegion();
00786                 }
00787         }
00788 
00789         // Fallback to the agents region if for some reason the 
00790         // object isn't found in the viewer.
00791         if(!viewer_region)
00792         {
00793                 viewer_region = gAgent.getRegion();
00794         }
00795 
00796         if(viewer_region)
00797         {
00798                 std::string url = viewer_region->getCapability("CopyInventoryFromNotecard");
00799                 if (!url.empty())
00800                 {
00801                         body["notecard-id"] = notecard_inv_id;
00802                         body["object-id"] = object_id;
00803                         body["item-id"] = src->getUUID();
00804                         body["folder-id"] = gInventory.findCategoryUUIDForType(src->getType());
00805                         body["callback-id"] = (LLSD::Integer)callback_id;
00806 
00807                         LLHTTPClient::post(url, body, new LLCopyInventoryFromNotecardResponder());
00808                 }
00809         }
00810 }

Generated on Fri May 16 08:34:10 2008 for SecondLife by  doxygen 1.5.5