00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "message.h"
00035 #include "lltooldraganddrop.h"
00036
00037 #include "llinstantmessage.h"
00038 #include "lldir.h"
00039
00040 #include "llagent.h"
00041 #include "llviewercontrol.h"
00042 #include "llfirstuse.h"
00043 #include "llfloater.h"
00044 #include "llfloatertools.h"
00045 #include "llgesturemgr.h"
00046 #include "llhudeffecttrail.h"
00047 #include "llhudmanager.h"
00048 #include "llinventorymodel.h"
00049 #include "llinventoryview.h"
00050 #include "llmutelist.h"
00051 #include "llnotify.h"
00052 #include "llpreviewnotecard.h"
00053 #include "llselectmgr.h"
00054 #include "lltoolmgr.h"
00055 #include "llui.h"
00056 #include "llviewerimagelist.h"
00057 #include "llviewerinventory.h"
00058 #include "llviewerobject.h"
00059 #include "llviewerobjectlist.h"
00060 #include "llviewerregion.h"
00061 #include "llviewerstats.h"
00062 #include "llviewerwindow.h"
00063 #include "llvoavatar.h"
00064 #include "llvolume.h"
00065 #include "llworld.h"
00066 #include "object_flags.h"
00067
00068
00069
00070
00071
00072 const S32 MAX_ITEMS = 42;
00073 const char* FOLDER_INCLUDES_ATTACHMENTS_BEING_WORN =
00074 "Cannot give folders that contain objects that are attached to you.\n"
00075 "Detach the object(s) and then try again.";
00076
00077
00078
00079 #define callMemberFunction(object,ptrToMember) ((object).*(ptrToMember))
00080
00081 class LLNoPreferredType : public LLInventoryCollectFunctor
00082 {
00083 public:
00084 LLNoPreferredType() {}
00085 virtual ~LLNoPreferredType() {}
00086 virtual bool operator()(LLInventoryCategory* cat,
00087 LLInventoryItem* item)
00088 {
00089 if(cat && (cat->getPreferredType() == LLAssetType::AT_NONE))
00090 {
00091 return true;
00092 }
00093 return false;
00094 }
00095 };
00096
00097 class LLNoPreferredTypeOrItem : public LLInventoryCollectFunctor
00098 {
00099 public:
00100 LLNoPreferredTypeOrItem() {}
00101 virtual ~LLNoPreferredTypeOrItem() {}
00102 virtual bool operator()(LLInventoryCategory* cat,
00103 LLInventoryItem* item)
00104 {
00105 if(item) return true;
00106 if(cat && (cat->getPreferredType() == LLAssetType::AT_NONE))
00107 {
00108 return true;
00109 }
00110 return false;
00111 }
00112 };
00113
00114 class LLDroppableItem : public LLInventoryCollectFunctor
00115 {
00116 public:
00117 LLDroppableItem(BOOL is_transfer) :
00118 mCountLosing(0), mIsTransfer(is_transfer) {}
00119 virtual ~LLDroppableItem() {}
00120 virtual bool operator()(LLInventoryCategory* cat,
00121 LLInventoryItem* item);
00122 S32 countNoCopy() const { return mCountLosing; }
00123
00124 protected:
00125 S32 mCountLosing;
00126 BOOL mIsTransfer;
00127 };
00128
00129 bool LLDroppableItem::operator()(LLInventoryCategory* cat,
00130 LLInventoryItem* item)
00131 {
00132 bool allowed = false;
00133 if(item)
00134 {
00135 LLVOAvatar* my_avatar = NULL;
00136 switch(item->getType())
00137 {
00138 case LLAssetType::AT_CALLINGCARD:
00139
00140 break;
00141
00142 case LLAssetType::AT_OBJECT:
00143 my_avatar = gAgent.getAvatarObject();
00144 if(my_avatar && !my_avatar->isWearingAttachment(item->getUUID()))
00145 {
00146 allowed = true;
00147 }
00148 break;
00149
00150 case LLAssetType::AT_BODYPART:
00151 case LLAssetType::AT_CLOTHING:
00152 if(!gAgent.isWearingItem(item->getUUID()))
00153 {
00154 allowed = true;
00155 }
00156 break;
00157
00158 default:
00159 allowed = true;
00160 break;
00161 }
00162 if(mIsTransfer
00163 && !item->getPermissions().allowOperationBy(PERM_TRANSFER,
00164 gAgent.getID()))
00165 {
00166 allowed = false;
00167 }
00168 if(allowed && !item->getPermissions().allowCopyBy(gAgent.getID()))
00169 {
00170 ++mCountLosing;
00171 }
00172 }
00173 return allowed;
00174 }
00175
00176 class LLUncopyableItems : public LLInventoryCollectFunctor
00177 {
00178 public:
00179 LLUncopyableItems() {}
00180 virtual ~LLUncopyableItems() {}
00181 virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item);
00182 };
00183
00184 bool LLUncopyableItems::operator()(LLInventoryCategory* cat,
00185 LLInventoryItem* item)
00186 {
00187 BOOL uncopyable = FALSE;
00188 if(item)
00189 {
00190 BOOL allowed = FALSE;
00191 LLVOAvatar* my_avatar = NULL;
00192 switch(item->getType())
00193 {
00194 case LLAssetType::AT_CALLINGCARD:
00195
00196 break;
00197
00198 case LLAssetType::AT_OBJECT:
00199 my_avatar = gAgent.getAvatarObject();
00200 if(my_avatar && !my_avatar->isWearingAttachment(item->getUUID()))
00201 {
00202 allowed = TRUE;
00203 }
00204 break;
00205
00206 case LLAssetType::AT_BODYPART:
00207 case LLAssetType::AT_CLOTHING:
00208 if(!gAgent.isWearingItem(item->getUUID()))
00209 {
00210 allowed = TRUE;
00211 }
00212 break;
00213
00214 default:
00215 allowed = TRUE;
00216 break;
00217 }
00218 if(allowed && !item->getPermissions().allowCopyBy(gAgent.getID()))
00219 {
00220 uncopyable = TRUE;
00221 }
00222 }
00223 return (uncopyable ? true : false);
00224 }
00225
00226 class LLDropCopyableItems : public LLInventoryCollectFunctor
00227 {
00228 public:
00229 LLDropCopyableItems() {}
00230 virtual ~LLDropCopyableItems() {}
00231 virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item);
00232 };
00233
00234
00235 bool LLDropCopyableItems::operator()(
00236 LLInventoryCategory* cat, LLInventoryItem* item)
00237 {
00238 BOOL allowed = FALSE;
00239 if(item)
00240 {
00241 LLVOAvatar* my_avatar = NULL;
00242 switch(item->getType())
00243 {
00244 case LLAssetType::AT_CALLINGCARD:
00245
00246 break;
00247
00248 case LLAssetType::AT_OBJECT:
00249 my_avatar = gAgent.getAvatarObject();
00250 if(my_avatar && !my_avatar->isWearingAttachment(item->getUUID()))
00251 {
00252 allowed = TRUE;
00253 }
00254 break;
00255
00256 case LLAssetType::AT_BODYPART:
00257 case LLAssetType::AT_CLOTHING:
00258 if(!gAgent.isWearingItem(item->getUUID()))
00259 {
00260 allowed = TRUE;
00261 }
00262 break;
00263
00264 default:
00265 allowed = TRUE;
00266 break;
00267 }
00268 if(allowed && !item->getPermissions().allowCopyBy(gAgent.getID()))
00269 {
00270
00271 allowed = FALSE;
00272 }
00273 }
00274 return (allowed ? true : false);
00275 }
00276
00277 class LLGiveable : public LLInventoryCollectFunctor
00278 {
00279 public:
00280 LLGiveable() : mCountLosing(0) {}
00281 virtual ~LLGiveable() {}
00282 virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item);
00283
00284 S32 countNoCopy() const { return mCountLosing; }
00285 protected:
00286 S32 mCountLosing;
00287 };
00288
00289 bool LLGiveable::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
00290 {
00291
00292 if(cat) return TRUE;
00293 BOOL allowed = FALSE;
00294 if(item)
00295 {
00296 LLVOAvatar* my_avatar = NULL;
00297 switch(item->getType())
00298 {
00299 case LLAssetType::AT_CALLINGCARD:
00300
00301 break;
00302
00303 case LLAssetType::AT_OBJECT:
00304 my_avatar = gAgent.getAvatarObject();
00305 if(my_avatar && !my_avatar->isWearingAttachment(item->getUUID()))
00306 {
00307 allowed = TRUE;
00308 }
00309 break;
00310
00311 case LLAssetType::AT_BODYPART:
00312 case LLAssetType::AT_CLOTHING:
00313 if(!gAgent.isWearingItem(item->getUUID()))
00314 {
00315 allowed = TRUE;
00316 }
00317 break;
00318
00319 default:
00320 allowed = TRUE;
00321 break;
00322 }
00323 if(!item->getPermissions().allowOperationBy(PERM_TRANSFER,
00324 gAgent.getID()))
00325 {
00326 allowed = FALSE;
00327 }
00328 if(allowed && !item->getPermissions().allowCopyBy(gAgent.getID()))
00329 {
00330 ++mCountLosing;
00331 }
00332 }
00333 return (allowed ? true : false);
00334 }
00335
00336 class LLCategoryFireAndForget : public LLInventoryFetchComboObserver
00337 {
00338 public:
00339 LLCategoryFireAndForget() {}
00340 ~LLCategoryFireAndForget() {}
00341 virtual void done()
00342 {
00343
00344 lldebugs << "LLCategoryFireAndForget::done()" << llendl;
00345 }
00346 };
00347
00348 class LLCategoryDropObserver : public LLInventoryFetchObserver
00349 {
00350 public:
00351 LLCategoryDropObserver(
00352 const LLUUID& obj_id, LLToolDragAndDrop::ESource src) :
00353 mObjectID(obj_id),
00354 mSource(src)
00355 {}
00356 ~LLCategoryDropObserver() {}
00357 virtual void done();
00358
00359 protected:
00360 LLUUID mObjectID;
00361 LLToolDragAndDrop::ESource mSource;
00362 };
00363
00364 void LLCategoryDropObserver::done()
00365 {
00366 gInventory.removeObserver(this);
00367 LLViewerObject* dst_obj = gObjectList.findObject(mObjectID);
00368 if(dst_obj)
00369 {
00370
00371 LLInventoryItem* item = NULL;
00372 item_ref_t::iterator it = mComplete.begin();
00373 item_ref_t::iterator end = mComplete.end();
00374 for(; it < end; ++it)
00375 {
00376 item = gInventory.getItem(*it);
00377 if(item)
00378 {
00379 LLToolDragAndDrop::dropInventory(
00380 dst_obj,
00381 item,
00382 mSource,
00383 LLUUID::null);
00384 }
00385 }
00386 }
00387 delete this;
00388 }
00389
00390 class LLCategoryDropDescendentsObserver : public LLInventoryFetchDescendentsObserver
00391 {
00392 public:
00393 LLCategoryDropDescendentsObserver(
00394 const LLUUID& obj_id, LLToolDragAndDrop::ESource src) :
00395 mObjectID(obj_id),
00396 mSource(src)
00397 {}
00398 ~LLCategoryDropDescendentsObserver() {}
00399 virtual void done();
00400
00401 protected:
00402 LLUUID mObjectID;
00403 LLToolDragAndDrop::ESource mSource;
00404 };
00405
00406 void LLCategoryDropDescendentsObserver::done()
00407 {
00408
00409 gInventory.removeObserver(this);
00410 folder_ref_t::iterator it = mCompleteFolders.begin();
00411 folder_ref_t::iterator end = mCompleteFolders.end();
00412 LLViewerInventoryCategory::cat_array_t cats;
00413 LLViewerInventoryItem::item_array_t items;
00414 for(; it != end; ++it)
00415 {
00416 gInventory.collectDescendents(
00417 (*it),
00418 cats,
00419 items,
00420 LLInventoryModel::EXCLUDE_TRASH);
00421 }
00422
00423 S32 count = items.count();
00424 if(count)
00425 {
00426 std::set<LLUUID> unique_ids;
00427 for(S32 i = 0; i < count; ++i)
00428 {
00429 unique_ids.insert(items.get(i)->getUUID());
00430 }
00431 LLInventoryFetchObserver::item_ref_t ids;
00432 std::back_insert_iterator<LLInventoryFetchObserver::item_ref_t> copier(ids);
00433 std::copy(unique_ids.begin(), unique_ids.end(), copier);
00434 LLCategoryDropObserver* dropper;
00435 dropper = new LLCategoryDropObserver(mObjectID, mSource);
00436 dropper->fetchItems(ids);
00437 if(dropper->isEverythingComplete())
00438 {
00439 dropper->done();
00440 }
00441 else
00442 {
00443 gInventory.addObserver(dropper);
00444 }
00445 }
00446 delete this;
00447 }
00448
00449
00450
00451
00452
00453 LLToolDragAndDrop::dragOrDrop3dImpl LLToolDragAndDrop::sDragAndDrop3d[DAD_COUNT][LLToolDragAndDrop::DT_COUNT] =
00454 {
00455
00456 {
00457 &LLToolDragAndDrop::dad3dNULL,
00458 &LLToolDragAndDrop::dad3dNULL,
00459 &LLToolDragAndDrop::dad3dNULL,
00460 &LLToolDragAndDrop::dad3dNULL,
00461 &LLToolDragAndDrop::dad3dNULL,
00462 },
00463
00464 {
00465 &LLToolDragAndDrop::dad3dNULL,
00466 &LLToolDragAndDrop::dad3dNULL,
00467 &LLToolDragAndDrop::dad3dGiveInventory,
00468 &LLToolDragAndDrop::dad3dTextureObject,
00469 &LLToolDragAndDrop::dad3dNULL,
00470 },
00471
00472 {
00473 &LLToolDragAndDrop::dad3dNULL,
00474 &LLToolDragAndDrop::dad3dNULL,
00475 &LLToolDragAndDrop::dad3dGiveInventory,
00476 &LLToolDragAndDrop::dad3dUpdateInventory,
00477 &LLToolDragAndDrop::dad3dNULL,
00478 },
00479
00480 {
00481 &LLToolDragAndDrop::dad3dNULL,
00482 &LLToolDragAndDrop::dad3dNULL,
00483 &LLToolDragAndDrop::dad3dNULL,
00484 &LLToolDragAndDrop::dad3dNULL,
00485 &LLToolDragAndDrop::dad3dNULL,
00486 },
00487
00488 {
00489 &LLToolDragAndDrop::dad3dNULL,
00490 &LLToolDragAndDrop::dad3dNULL,
00491 &LLToolDragAndDrop::dad3dGiveInventory,
00492 &LLToolDragAndDrop::dad3dUpdateInventory,
00493 &LLToolDragAndDrop::dad3dNULL,
00494 },
00495
00496 {
00497 &LLToolDragAndDrop::dad3dNULL,
00498 &LLToolDragAndDrop::dad3dNULL,
00499 &LLToolDragAndDrop::dad3dGiveInventory,
00500 &LLToolDragAndDrop::dad3dRezScript,
00501 &LLToolDragAndDrop::dad3dNULL,
00502 },
00503
00504 {
00505 &LLToolDragAndDrop::dad3dNULL,
00506 &LLToolDragAndDrop::dad3dWearItem,
00507 &LLToolDragAndDrop::dad3dGiveInventory,
00508 &LLToolDragAndDrop::dad3dUpdateInventory,
00509 &LLToolDragAndDrop::dad3dNULL,
00510 },
00511
00512 {
00513 &LLToolDragAndDrop::dad3dNULL,
00514 &LLToolDragAndDrop::dad3dRezAttachmentFromInv,
00515 &LLToolDragAndDrop::dad3dGiveInventoryObject,
00516 &LLToolDragAndDrop::dad3dRezObjectOnObject,
00517 &LLToolDragAndDrop::dad3dRezObjectOnLand,
00518 },
00519
00520 {
00521 &LLToolDragAndDrop::dad3dNULL,
00522 &LLToolDragAndDrop::dad3dNULL,
00523 &LLToolDragAndDrop::dad3dGiveInventory,
00524 &LLToolDragAndDrop::dad3dUpdateInventory,
00525 &LLToolDragAndDrop::dad3dNULL,
00526 },
00527
00528 {
00529 &LLToolDragAndDrop::dad3dNULL,
00530 &LLToolDragAndDrop::dad3dWearCategory,
00531 &LLToolDragAndDrop::dad3dGiveInventoryCategory,
00532 &LLToolDragAndDrop::dad3dUpdateInventoryCategory,
00533 &LLToolDragAndDrop::dad3dNULL,
00534 },
00535
00536 {
00537 &LLToolDragAndDrop::dad3dNULL,
00538 &LLToolDragAndDrop::dad3dNULL,
00539 &LLToolDragAndDrop::dad3dNULL,
00540 &LLToolDragAndDrop::dad3dNULL,
00541 &LLToolDragAndDrop::dad3dNULL,
00542 },
00543
00544 {
00545 &LLToolDragAndDrop::dad3dNULL,
00546 &LLToolDragAndDrop::dad3dWearItem,
00547 &LLToolDragAndDrop::dad3dGiveInventory,
00548 &LLToolDragAndDrop::dad3dUpdateInventory,
00549 &LLToolDragAndDrop::dad3dNULL,
00550 },
00551
00552
00553 {
00554 &LLToolDragAndDrop::dad3dNULL,
00555 &LLToolDragAndDrop::dad3dNULL,
00556 &LLToolDragAndDrop::dad3dGiveInventory,
00557 &LLToolDragAndDrop::dad3dUpdateInventory,
00558 &LLToolDragAndDrop::dad3dNULL,
00559 },
00560
00561
00562 {
00563 &LLToolDragAndDrop::dad3dNULL,
00564 &LLToolDragAndDrop::dad3dActivateGesture,
00565 &LLToolDragAndDrop::dad3dGiveInventory,
00566 &LLToolDragAndDrop::dad3dUpdateInventory,
00567 &LLToolDragAndDrop::dad3dNULL,
00568 },
00569 };
00570
00571 LLToolDragAndDrop::LLToolDragAndDrop()
00572 :
00573 LLTool("draganddrop", NULL),
00574 mDragStartX(0),
00575 mDragStartY(0),
00576 mSource(SOURCE_AGENT),
00577 mCursor(UI_CURSOR_NO),
00578 mLastAccept(ACCEPT_NO),
00579 mDrop(FALSE),
00580 mCurItemIndex(0)
00581 {
00582
00583 }
00584
00585 void LLToolDragAndDrop::setDragStart(S32 x, S32 y)
00586 {
00587 mDragStartX = x;
00588 mDragStartY = y;
00589 }
00590
00591 BOOL LLToolDragAndDrop::isOverThreshold(S32 x,S32 y)
00592 {
00593 const S32 MIN_MANHATTAN_DIST = 3;
00594 S32 manhattan_dist = llabs( x - mDragStartX ) + llabs( y - mDragStartY );
00595 return manhattan_dist >= MIN_MANHATTAN_DIST;
00596 }
00597
00598 void LLToolDragAndDrop::beginDrag(EDragAndDropType type,
00599 const LLUUID& cargo_id,
00600 ESource source,
00601 const LLUUID& source_id,
00602 const LLUUID& object_id)
00603 {
00604 if(type == DAD_NONE)
00605 {
00606 llwarns << "Attempted to start drag without a cargo type" << llendl;
00607 return;
00608 }
00609 mCargoTypes.clear();
00610 mCargoTypes.push_back(type);
00611 mCargoIDs.clear();
00612 mCargoIDs.push_back(cargo_id);
00613 mSource = source;
00614 mSourceID = source_id;
00615 mObjectID = object_id;
00616
00617 setMouseCapture( TRUE );
00618 LLToolMgr::getInstance()->setTransientTool( this );
00619 mCursor = UI_CURSOR_NO;
00620 if((mCargoTypes[0] == DAD_CATEGORY)
00621 && ((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY)))
00622 {
00623 LLInventoryCategory* cat = gInventory.getCategory(cargo_id);
00624
00625
00626 if(cat)
00627 {
00628 LLViewerInventoryCategory::cat_array_t cats;
00629 LLViewerInventoryItem::item_array_t items;
00630 LLNoPreferredTypeOrItem is_not_preferred;
00631 LLInventoryFetchComboObserver::folder_ref_t folder_ids;
00632 LLInventoryFetchComboObserver::item_ref_t item_ids;
00633 if(is_not_preferred(cat, NULL))
00634 {
00635 folder_ids.push_back(cargo_id);
00636 }
00637 gInventory.collectDescendentsIf(
00638 cargo_id,
00639 cats,
00640 items,
00641 LLInventoryModel::EXCLUDE_TRASH,
00642 is_not_preferred);
00643 S32 count = cats.count();
00644 S32 i;
00645 for(i = 0; i < count; ++i)
00646 {
00647 folder_ids.push_back(cats.get(i)->getUUID());
00648 }
00649 count = items.count();
00650 for(i = 0; i < count; ++i)
00651 {
00652 item_ids.push_back(items.get(i)->getUUID());
00653 }
00654 if(!folder_ids.empty() || !item_ids.empty())
00655 {
00656 LLCategoryFireAndForget fetcher;
00657 fetcher.fetch(folder_ids, item_ids);
00658 }
00659 }
00660 }
00661 }
00662
00663 void LLToolDragAndDrop::beginMultiDrag(
00664 const std::vector<EDragAndDropType> types,
00665 const std::vector<LLUUID>& cargo_ids,
00666 ESource source,
00667 const LLUUID& source_id)
00668 {
00669
00670
00671
00672 std::vector<EDragAndDropType>::const_iterator types_it;
00673 for (types_it = types.begin(); types_it != types.end(); ++types_it)
00674 {
00675 if(DAD_NONE == *types_it)
00676 {
00677 llwarns << "Attempted to start drag without a cargo type" << llendl;
00678 return;
00679 }
00680 }
00681 mCargoTypes = types;
00682 mCargoIDs = cargo_ids;
00683 mSource = source;
00684 mSourceID = source_id;
00685
00686 setMouseCapture( TRUE );
00687 LLToolMgr::getInstance()->setTransientTool( this );
00688 mCursor = UI_CURSOR_NO;
00689 if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY))
00690 {
00691
00692 LLInventoryCategory* cat = NULL;
00693 S32 count = llmin(cargo_ids.size(), types.size());
00694 std::set<LLUUID> cat_ids;
00695 for(S32 i = 0; i < count; ++i)
00696 {
00697 cat = gInventory.getCategory(cargo_ids[i]);
00698 if(cat)
00699 {
00700 LLViewerInventoryCategory::cat_array_t cats;
00701 LLViewerInventoryItem::item_array_t items;
00702 LLNoPreferredType is_not_preferred;
00703 if(is_not_preferred(cat, NULL))
00704 {
00705 cat_ids.insert(cat->getUUID());
00706 }
00707 gInventory.collectDescendentsIf(
00708 cat->getUUID(),
00709 cats,
00710 items,
00711 LLInventoryModel::EXCLUDE_TRASH,
00712 is_not_preferred);
00713 S32 cat_count = cats.count();
00714 for(S32 i = 0; i < cat_count; ++i)
00715 {
00716 cat_ids.insert(cat->getUUID());
00717 }
00718 }
00719 }
00720 if(!cat_ids.empty())
00721 {
00722 LLInventoryFetchComboObserver::folder_ref_t folder_ids;
00723 LLInventoryFetchComboObserver::item_ref_t item_ids;
00724 std::back_insert_iterator<LLInventoryFetchDescendentsObserver::folder_ref_t> copier(folder_ids);
00725 std::copy(cat_ids.begin(), cat_ids.end(), copier);
00726 LLCategoryFireAndForget fetcher;
00727 fetcher.fetch(folder_ids, item_ids);
00728 }
00729 }
00730 }
00731
00732 void LLToolDragAndDrop::endDrag()
00733 {
00734 LLSelectMgr::getInstance()->unhighlightAll();
00735 setMouseCapture(FALSE);
00736 }
00737
00738 void LLToolDragAndDrop::onMouseCaptureLost()
00739 {
00740
00741 LLToolMgr::getInstance()->clearTransientTool();
00742 mCargoTypes.clear();
00743 mCargoIDs.clear();
00744 mSource = SOURCE_AGENT;
00745 mSourceID.setNull();
00746 mObjectID.setNull();
00747 }
00748
00749 BOOL LLToolDragAndDrop::handleMouseUp( S32 x, S32 y, MASK mask )
00750 {
00751 if( hasMouseCapture() )
00752 {
00753 EAcceptance acceptance = ACCEPT_NO;
00754 dragOrDrop( x, y, mask, TRUE, &acceptance );
00755 endDrag();
00756 }
00757 return TRUE;
00758 }
00759
00760 BOOL LLToolDragAndDrop::handleHover( S32 x, S32 y, MASK mask )
00761 {
00762 EAcceptance acceptance = ACCEPT_NO;
00763 dragOrDrop( x, y, mask, FALSE, &acceptance );
00764
00765 switch( acceptance )
00766 {
00767 case ACCEPT_YES_MULTI:
00768 if (mCargoIDs.size() > 1)
00769 {
00770 mCursor = UI_CURSOR_ARROWDRAGMULTI;
00771 }
00772 else
00773 {
00774 mCursor = UI_CURSOR_ARROWDRAG;
00775 }
00776 break;
00777 case ACCEPT_YES_SINGLE:
00778 mCursor = UI_CURSOR_ARROWDRAG;
00779 break;
00780
00781 case ACCEPT_NO_LOCKED:
00782 mCursor = UI_CURSOR_NOLOCKED;
00783 break;
00784
00785 case ACCEPT_NO:
00786 mCursor = UI_CURSOR_NO;
00787 break;
00788
00789 case ACCEPT_YES_COPY_MULTI:
00790 if (mCargoIDs.size() > 1)
00791 {
00792 mCursor = UI_CURSOR_ARROWCOPYMULTI;
00793 }
00794 else
00795 {
00796 mCursor = UI_CURSOR_ARROWCOPY;
00797 }
00798 break;
00799 case ACCEPT_YES_COPY_SINGLE:
00800 mCursor = UI_CURSOR_ARROWCOPY;
00801 break;
00802 case ACCEPT_POSTPONED:
00803 break;
00804 default:
00805 llassert( FALSE );
00806 }
00807
00808 gViewerWindow->getWindow()->setCursor( mCursor );
00809 lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolDragAndDrop" << llendl;
00810 return TRUE;
00811 }
00812
00813 BOOL LLToolDragAndDrop::handleKey(KEY key, MASK mask)
00814 {
00815 if (key == KEY_ESCAPE)
00816 {
00817
00818 endDrag();
00819 return TRUE;
00820 }
00821
00822 return FALSE;
00823 }
00824
00825 BOOL LLToolDragAndDrop::handleToolTip(S32 x, S32 y, LLString& msg, LLRect *sticky_rect_screen)
00826 {
00827 if (!mToolTipMsg.empty())
00828 {
00829 msg = mToolTipMsg;
00830
00831 return TRUE;
00832 }
00833 return FALSE;
00834 }
00835
00836 void LLToolDragAndDrop::handleDeselect()
00837 {
00838 mToolTipMsg.clear();
00839 }
00840
00841
00842 void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
00843 EAcceptance* acceptance)
00844 {
00845 *acceptance = ACCEPT_YES_MULTI;
00846
00847 BOOL handled = FALSE;
00848
00849 LLView* top_view = gViewerWindow->getTopCtrl();
00850 LLViewerInventoryItem* item;
00851 LLViewerInventoryCategory* cat;
00852
00853 mToolTipMsg.assign("");
00854
00855 if(top_view)
00856 {
00857 handled = TRUE;
00858
00859 for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
00860 {
00861 LLInventoryObject* cargo = locateInventory(item, cat);
00862
00863 if (cargo)
00864 {
00865 S32 local_x, local_y;
00866 top_view->screenPointToLocal( x, y, &local_x, &local_y );
00867 EAcceptance item_acceptance = ACCEPT_NO;
00868 handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE,
00869 mCargoTypes[mCurItemIndex],
00870 (void*)cargo,
00871 &item_acceptance,
00872 mToolTipMsg);
00873 if (handled)
00874 {
00875
00876 *acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance);
00877 }
00878 }
00879 else
00880 {
00881 return;
00882 }
00883 }
00884
00885
00886 if (handled && drop && (U32)*acceptance >= ACCEPT_YES_COPY_SINGLE)
00887 {
00888
00889 if ((U32)*acceptance >= ACCEPT_YES_COPY_MULTI)
00890 {
00891 mCurItemIndex = 0;
00892 }
00893
00894 else
00895 {
00896 mCurItemIndex = mCargoIDs.size() - 1;
00897 }
00898 for (; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
00899 {
00900 LLInventoryObject* cargo = locateInventory(item, cat);
00901
00902 if (cargo)
00903 {
00904 S32 local_x, local_y;
00905
00906 EAcceptance item_acceptance;
00907 top_view->screenPointToLocal( x, y, &local_x, &local_y );
00908 handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, TRUE,
00909 mCargoTypes[mCurItemIndex],
00910 (void*)cargo,
00911 &item_acceptance,
00912 mToolTipMsg);
00913 }
00914 }
00915 }
00916 if (handled)
00917 {
00918 mLastAccept = (EAcceptance)*acceptance;
00919 }
00920 }
00921
00922 if(!handled)
00923 {
00924 handled = TRUE;
00925
00926 LLView* root_view = gViewerWindow->getRootView();
00927
00928 for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
00929 {
00930 LLInventoryObject* cargo = locateInventory(item, cat);
00931
00932 EAcceptance item_acceptance = ACCEPT_NO;
00933 handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
00934 mCargoTypes[mCurItemIndex],
00935 (void*)cargo,
00936 &item_acceptance,
00937 mToolTipMsg);
00938 if (handled)
00939 {
00940
00941 *acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance);
00942 }
00943 }
00944
00945 if (handled && drop && (U32)*acceptance > ACCEPT_NO_LOCKED)
00946 {
00947
00948 if ((U32)*acceptance >= ACCEPT_YES_COPY_MULTI)
00949 {
00950 mCurItemIndex = 0;
00951 }
00952
00953 else
00954 {
00955 mCurItemIndex = mCargoIDs.size() - 1;
00956 }
00957 for (; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
00958 {
00959 LLInventoryObject* cargo = locateInventory(item, cat);
00960
00961 if (cargo)
00962 {
00963
00964
00965 EAcceptance item_acceptance;
00966 handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE,
00967 mCargoTypes[mCurItemIndex],
00968 (void*)cargo,
00969 &item_acceptance,
00970 mToolTipMsg);
00971 }
00972 }
00973 }
00974
00975 if (handled)
00976 {
00977 mLastAccept = (EAcceptance)*acceptance;
00978 }
00979 }
00980
00981 if ( !handled )
00982 {
00983 dragOrDrop3D( x, y, mask, drop, acceptance );
00984 }
00985 }
00986
00987 void LLToolDragAndDrop::dragOrDrop3D( S32 x, S32 y, MASK mask, BOOL drop, EAcceptance* acceptance )
00988 {
00989 mDrop = drop;
00990 if (mDrop)
00991 {
00992 gPickFaces = TRUE;
00993
00994 gViewerWindow->hitObjectOrLandGlobalImmediate(x, y, pickCallback, FALSE);
00995 }
00996 else
00997 {
00998
00999
01000
01001 gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback, FALSE);
01002 }
01003
01004 *acceptance = mLastAccept;
01005 }
01006
01007 void LLToolDragAndDrop::pickCallback(S32 x, S32 y, MASK mask)
01008 {
01009 EDropTarget target = DT_NONE;
01010 S32 hit_face = -1;
01011
01012 LLViewerObject* hit_obj = gViewerWindow->lastNonFloraObjectHit();
01013 LLSelectMgr::getInstance()->unhighlightAll();
01014
01015
01016 if (hit_obj)
01017 {
01018 if(hit_obj->isAttachment() && !hit_obj->isHUDAttachment())
01019 {
01020 LLVOAvatar* avatar = LLVOAvatar::findAvatarFromAttachment( hit_obj );
01021 if( !avatar )
01022 {
01023 LLToolDragAndDrop::getInstance()->mLastAccept = ACCEPT_NO;
01024 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_NO;
01025 gViewerWindow->getWindow()->setCursor( LLToolDragAndDrop::getInstance()->mCursor );
01026 return;
01027 }
01028
01029 hit_obj = avatar;
01030 }
01031
01032 if(hit_obj->isAvatar())
01033 {
01034 if(((LLVOAvatar*) hit_obj)->mIsSelf)
01035 {
01036 target = DT_SELF;
01037 hit_face = -1;
01038 }
01039 else
01040 {
01041 target = DT_AVATAR;
01042 hit_face = -1;
01043 }
01044 }
01045 else
01046 {
01047 target = DT_OBJECT;
01048 hit_face = gLastHitNonFloraObjectFace;
01049
01050
01051 for (S32 i = 0; i < (S32)LLToolDragAndDrop::getInstance()->mCargoIDs.size(); i++)
01052 {
01053 if (LLToolDragAndDrop::getInstance()->mCargoTypes[i] != DAD_OBJECT || (mask & MASK_CONTROL))
01054 {
01055 LLSelectMgr::getInstance()->highlightObjectAndFamily(hit_obj);
01056 break;
01057 }
01058 }
01059 }
01060 }
01061 else if(gLastHitLand)
01062 {
01063 target = DT_LAND;
01064 hit_face = -1;
01065 }
01066
01067 LLToolDragAndDrop::getInstance()->mLastAccept = ACCEPT_YES_MULTI;
01068
01069 for (LLToolDragAndDrop::getInstance()->mCurItemIndex = 0; LLToolDragAndDrop::getInstance()->mCurItemIndex < (S32)LLToolDragAndDrop::getInstance()->mCargoIDs.size();
01070 LLToolDragAndDrop::getInstance()->mCurItemIndex++)
01071 {
01072
01073 LLToolDragAndDrop::getInstance()->mLastAccept = (EAcceptance)llmin(
01074 (U32)LLToolDragAndDrop::getInstance()->mLastAccept,
01075 (U32)callMemberFunction((*LLToolDragAndDrop::getInstance()),
01076 LLToolDragAndDrop::getInstance()->sDragAndDrop3d[LLToolDragAndDrop::getInstance()->mCargoTypes[LLToolDragAndDrop::getInstance()->mCurItemIndex]][target])
01077 (hit_obj, hit_face, mask, FALSE));
01078 }
01079
01080 if (LLToolDragAndDrop::getInstance()->mDrop && (U32)LLToolDragAndDrop::getInstance()->mLastAccept >= ACCEPT_YES_COPY_SINGLE)
01081 {
01082
01083 if (LLToolDragAndDrop::getInstance()->mLastAccept >= ACCEPT_YES_COPY_MULTI)
01084 {
01085 LLToolDragAndDrop::getInstance()->mCurItemIndex = 0;
01086 }
01087
01088 else
01089 {
01090 LLToolDragAndDrop::getInstance()->mCurItemIndex = LLToolDragAndDrop::getInstance()->mCargoIDs.size() - 1;
01091 }
01092
01093 for (; LLToolDragAndDrop::getInstance()->mCurItemIndex < (S32)LLToolDragAndDrop::getInstance()->mCargoIDs.size();
01094 LLToolDragAndDrop::getInstance()->mCurItemIndex++)
01095 {
01096
01097 (U32)callMemberFunction((*LLToolDragAndDrop::getInstance()),
01098 LLToolDragAndDrop::getInstance()->sDragAndDrop3d[LLToolDragAndDrop::getInstance()->mCargoTypes[LLToolDragAndDrop::getInstance()->mCurItemIndex]][target])
01099 (hit_obj, hit_face, mask, TRUE);
01100 }
01101 }
01102
01103 switch( LLToolDragAndDrop::getInstance()->mLastAccept )
01104 {
01105 case ACCEPT_YES_MULTI:
01106 if (LLToolDragAndDrop::getInstance()->mCargoIDs.size() > 1)
01107 {
01108 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWDRAGMULTI;
01109 }
01110 else
01111 {
01112 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWDRAG;
01113 }
01114 break;
01115 case ACCEPT_YES_SINGLE:
01116 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWDRAG;
01117 break;
01118
01119 case ACCEPT_NO_LOCKED:
01120 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_NOLOCKED;
01121 break;
01122
01123 case ACCEPT_NO:
01124 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_NO;
01125 break;
01126
01127 case ACCEPT_YES_COPY_MULTI:
01128 if (LLToolDragAndDrop::getInstance()->mCargoIDs.size() > 1)
01129 {
01130 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWCOPYMULTI;
01131 }
01132 else
01133 {
01134 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWCOPY;
01135 }
01136 break;
01137 case ACCEPT_YES_COPY_SINGLE:
01138 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWCOPY;
01139 break;
01140 case ACCEPT_POSTPONED:
01141 break;
01142 default:
01143 llassert( FALSE );
01144 }
01145
01146 LLToolDragAndDrop::getInstance()->mLastHitPos = gLastHitPosGlobal + gLastHitObjectOffset;
01147 LLToolDragAndDrop::getInstance()->mLastCameraPos = gAgent.getCameraPositionGlobal();
01148
01149 gViewerWindow->getWindow()->setCursor( LLToolDragAndDrop::getInstance()->mCursor );
01150 }
01151
01152
01153 BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
01154 LLInventoryItem* item,
01155 LLToolDragAndDrop::ESource source,
01156 const LLUUID& src_id)
01157 {
01158
01159
01160
01161 if(SOURCE_LIBRARY == source)
01162 {
01163
01164 return TRUE;
01165 }
01166
01167
01168
01169 if (hit_obj->isInventoryDirty())
01170 {
01171 hit_obj->fetchInventoryFromServer();
01172 LLString::format_map_t args;
01173 args["[ERROR_MESSAGE]"] = "Unable to add texture.\nPlease wait a few seconds and try again.";
01174 gViewerWindow->alertXml("ErrorMessage", args);
01175 return FALSE;
01176 }
01177 if (hit_obj->getInventoryItemByAsset(item->getAssetUUID()))
01178 {
01179
01180
01181
01182
01183 return TRUE;
01184 }
01185
01186 if (!item) return FALSE;
01187
01188 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
01189 if(!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
01190 {
01191
01192 if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE )
01193 {
01194 return FALSE;
01195 }
01196
01197 if(SOURCE_AGENT == source)
01198 {
01199
01200
01201 gInventory.deleteObject(item->getUUID());
01202 gInventory.notifyObservers();
01203 }
01204 else if(SOURCE_WORLD == source)
01205 {
01206
01207
01208
01209 LLViewerObject* src_obj = gObjectList.findObject(src_id);
01210 if(src_obj)
01211 {
01212 src_obj->removeInventory(item->getUUID());
01213 }
01214 else
01215 {
01216 llwarns << "Unable to find source object." << llendl;
01217 return FALSE;
01218 }
01219 }
01220
01221 hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
01222
01223
01224 }
01225 else if(!item->getPermissions().allowOperationBy(PERM_TRANSFER,
01226 gAgent.getID()))
01227 {
01228
01229 if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE )
01230 {
01231 return FALSE;
01232 }
01233
01234
01235
01236 hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
01237
01238 hit_obj->fetchInventoryFromServer();
01239
01240
01241 }
01242 return TRUE;
01243 }
01244
01245 void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,
01246 LLInventoryItem* item,
01247 LLToolDragAndDrop::ESource source,
01248 const LLUUID& src_id)
01249 {
01250 if (!item)
01251 {
01252 llwarns << "LLToolDragAndDrop::dropTextureAllFaces no texture item." << llendl;
01253 return;
01254 }
01255 LLUUID asset_id = item->getAssetUUID();
01256 BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id);
01257 if(!success)
01258 {
01259 return;
01260 }
01261 LLViewerImage* image = gImageList.getImage(asset_id);
01262 LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
01263 S32 num_faces = hit_obj->getNumTEs();
01264 for( S32 face = 0; face < num_faces; face++ )
01265 {
01266
01267
01268 hit_obj->setTEImage(face, image);
01269 dialog_refresh_all();
01270 }
01271
01272 hit_obj->sendTEUpdate();
01273 }
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285 void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
01286 S32 hit_face,
01287 LLInventoryItem* item,
01288 LLToolDragAndDrop::ESource source,
01289 const LLUUID& src_id)
01290 {
01291 if (hit_face == -1) return;
01292 if (!item)
01293 {
01294 llwarns << "LLToolDragAndDrop::dropTextureOneFace no texture item." << llendl;
01295 return;
01296 }
01297 LLUUID asset_id = item->getAssetUUID();
01298 BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id);
01299 if(!success)
01300 {
01301 return;
01302 }
01303
01304 LLViewerImage* image = gImageList.getImage(asset_id);
01305 LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
01306 hit_obj->setTEImage(hit_face, image);
01307 dialog_refresh_all();
01308
01309
01310 hit_obj->sendTEUpdate();
01311 }
01312
01313
01314 void LLToolDragAndDrop::dropScript(LLViewerObject* hit_obj,
01315 LLInventoryItem* item,
01316 BOOL active,
01317 ESource source,
01318 const LLUUID& src_id)
01319 {
01320
01321
01322 if((SOURCE_WORLD == LLToolDragAndDrop::getInstance()->mSource)
01323 || (SOURCE_NOTECARD == LLToolDragAndDrop::getInstance()->mSource))
01324 {
01325 llwarns << "Call to LLToolDragAndDrop::dropScript() from world"
01326 << " or notecard." << llendl;
01327 return;
01328 }
01329 if(hit_obj && item)
01330 {
01331 LLPointer<LLViewerInventoryItem> new_script = new LLViewerInventoryItem(item);
01332 if(!item->getPermissions().allowCopyBy(gAgent.getID()))
01333 {
01334 if(SOURCE_AGENT == source)
01335 {
01336
01337
01338 gInventory.deleteObject(item->getUUID());
01339 gInventory.notifyObservers();
01340 }
01341 else if(SOURCE_WORLD == source)
01342 {
01343
01344
01345
01346 LLViewerObject* src_obj = gObjectList.findObject(src_id);
01347 if(src_obj)
01348 {
01349 src_obj->removeInventory(item->getUUID());
01350 }
01351 else
01352 {
01353 llwarns << "Unable to find source object." << llendl;
01354 return;
01355 }
01356 }
01357 }
01358 hit_obj->saveScript(new_script, active, true);
01359 gFloaterTools->dirty();
01360
01361
01362 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
01363 effectp->setSourceObject(gAgent.getAvatarObject());
01364 effectp->setTargetObject(hit_obj);
01365 effectp->setDuration(LL_HUD_DUR_SHORT);
01366 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
01367 }
01368 }
01369
01370 void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target,
01371 BOOL bypass_sim_raycast,
01372 BOOL from_task_inventory,
01373 BOOL remove_from_inventory)
01374 {
01375 LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(mLastHitPos);
01376 if (!regionp)
01377 {
01378 llwarns << "Couldn't find region to rez object" << llendl;
01379 return;
01380 }
01381
01382
01383 make_ui_sound("UISndObjectRezIn");
01384 LLViewerInventoryItem* item;
01385 LLViewerInventoryCategory* cat;
01386 locateInventory(item, cat);
01387 if(!item || !item->isComplete()) return;
01388
01389 if (regionp
01390 && (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX))
01391 {
01392 LLFirstUse::useSandbox();
01393 }
01394
01395
01396
01397
01398 if(!remove_from_inventory
01399 && !item->getPermissions().allowCopyBy(gAgent.getID()))
01400 {
01401 remove_from_inventory = TRUE;
01402 }
01403
01404
01405
01406
01407
01408 LLUUID ray_target_id;
01409 if( raycast_target )
01410 {
01411 ray_target_id = raycast_target->getID();
01412 }
01413 else
01414 {
01415 ray_target_id.setNull();
01416 }
01417
01418
01419 bool is_in_trash = false;
01420 LLUUID trash_id;
01421 trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
01422 if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id))
01423 {
01424 is_in_trash = true;
01425 remove_from_inventory = TRUE;
01426 }
01427
01428 LLUUID source_id = from_task_inventory ? mSourceID : LLUUID::null;
01429
01430
01431 BOOL rez_selected = LLToolMgr::getInstance()->inEdit();
01432
01433
01434 LLVector3 ray_start = regionp->getPosRegionFromGlobal(mLastCameraPos);
01435 LLVector3 ray_end = regionp->getPosRegionFromGlobal(mLastHitPos);
01436
01437
01438
01439 if (bypass_sim_raycast == FALSE)
01440 {
01441 LLVector3 ray_direction = ray_start - ray_end;
01442 ray_end = ray_end - ray_direction;
01443 }
01444
01445
01446
01447 LLMessageSystem* msg = gMessageSystem;
01448 if (mSource == SOURCE_NOTECARD)
01449 {
01450 msg->newMessageFast(_PREHASH_RezObjectFromNotecard);
01451 }
01452 else
01453 {
01454 msg->newMessageFast(_PREHASH_RezObject);
01455 }
01456 msg->nextBlockFast(_PREHASH_AgentData);
01457 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
01458 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
01459 msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
01460
01461 msg->nextBlock("RezData");
01462
01463
01464
01465
01466
01467 msg->addUUIDFast(_PREHASH_FromTaskID, source_id);
01468 msg->addU8Fast(_PREHASH_BypassRaycast, (U8) bypass_sim_raycast);
01469 msg->addVector3Fast(_PREHASH_RayStart, ray_start);
01470 msg->addVector3Fast(_PREHASH_RayEnd, ray_end);
01471 msg->addUUIDFast(_PREHASH_RayTargetID, ray_target_id );
01472 msg->addBOOLFast(_PREHASH_RayEndIsIntersection, FALSE);
01473 msg->addBOOLFast(_PREHASH_RezSelected, rez_selected);
01474 msg->addBOOLFast(_PREHASH_RemoveItem, remove_from_inventory);
01475
01476
01477 pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
01478
01479 LLUUID folder_id = item->getParentUUID();
01480 if((SOURCE_LIBRARY == mSource) || (is_in_trash))
01481 {
01482
01483
01484 item->setParent(LLUUID::null);
01485
01486
01487
01488 }
01489 if (mSource == SOURCE_NOTECARD)
01490 {
01491 msg->nextBlockFast(_PREHASH_NotecardData);
01492 msg->addUUIDFast(_PREHASH_NotecardItemID, mSourceID);
01493 msg->addUUIDFast(_PREHASH_ObjectID, mObjectID);
01494 msg->nextBlockFast(_PREHASH_InventoryData);
01495 msg->addUUIDFast(_PREHASH_ItemID, item->getUUID());
01496 }
01497 else
01498 {
01499 msg->nextBlockFast(_PREHASH_InventoryData);
01500 item->packMessage(msg);
01501 }
01502 msg->sendReliable(regionp->getHost());
01503
01504 item->setParent(folder_id);
01505
01506
01507
01508 if (rez_selected)
01509 {
01510 LLSelectMgr::getInstance()->deselectAll();
01511 gViewerWindow->getWindow()->incBusyCount();
01512 }
01513
01514 if(remove_from_inventory)
01515 {
01516
01517
01518
01519 gInventory.deleteObject(item->getUUID());
01520 gInventory.notifyObservers();
01521 }
01522
01523
01524 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
01525 effectp->setSourceObject(gAgent.getAvatarObject());
01526 effectp->setPositionGlobal(mLastHitPos);
01527 effectp->setDuration(LL_HUD_DUR_SHORT);
01528 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
01529
01530 LLViewerStats::getInstance()->incStat(LLViewerStats::ST_REZ_COUNT);
01531 }
01532
01533 void LLToolDragAndDrop::dropInventory(LLViewerObject* hit_obj,
01534 LLInventoryItem* item,
01535 LLToolDragAndDrop::ESource source,
01536 const LLUUID& src_id)
01537 {
01538
01539
01540 if((SOURCE_WORLD == LLToolDragAndDrop::getInstance()->mSource)
01541 || (SOURCE_NOTECARD == LLToolDragAndDrop::getInstance()->mSource))
01542 {
01543 llwarns << "Call to LLToolDragAndDrop::dropInventory() from world"
01544 << " or notecard." << llendl;
01545 return;
01546 }
01547
01548 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
01549 S32 creation_date = time_corrected();
01550 new_item->setCreationDate(creation_date);
01551
01552 if(!item->getPermissions().allowCopyBy(gAgent.getID()))
01553 {
01554 if(SOURCE_AGENT == source)
01555 {
01556
01557
01558
01559 gInventory.deleteObject(item->getUUID());
01560 gInventory.notifyObservers();
01561 }
01562 else if(SOURCE_WORLD == source)
01563 {
01564
01565
01566
01567 LLViewerObject* src_obj = gObjectList.findObject(src_id);
01568 if(src_obj)
01569 {
01570 src_obj->removeInventory(item->getUUID());
01571 }
01572 else
01573 {
01574 llwarns << "Unable to find source object." << llendl;
01575 return;
01576 }
01577 }
01578 }
01579 hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
01580 if (gFloaterTools->getVisible())
01581 {
01582
01583 gFloaterTools->showPanel(LLFloaterTools::PANEL_CONTENTS);
01584 }
01585
01586
01587 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
01588 effectp->setSourceObject(gAgent.getAvatarObject());
01589 effectp->setTargetObject(hit_obj);
01590 effectp->setDuration(LL_HUD_DUR_SHORT);
01591 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
01592 gFloaterTools->dirty();
01593 }
01594
01595 struct LLGiveInventoryInfo
01596 {
01597 LLUUID mToAgentID;
01598 LLUUID mInventoryObjectID;
01599 LLGiveInventoryInfo(const LLUUID& to_agent, const LLUUID& obj_id) :
01600 mToAgentID(to_agent), mInventoryObjectID(obj_id) {}
01601 };
01602
01603 void LLToolDragAndDrop::giveInventory(const LLUUID& to_agent,
01604 LLInventoryItem* item)
01605 {
01606 llinfos << "LLToolDragAndDrop::giveInventory()" << llendl;
01607 if(!isInventoryGiveAcceptable(item))
01608 {
01609 return;
01610 }
01611 if(item->getPermissions().allowCopyBy(gAgent.getID()))
01612 {
01613
01614 LLToolDragAndDrop::commitGiveInventoryItem(to_agent, item);
01615 }
01616 else
01617 {
01618
01619 LLGiveInventoryInfo* info = new LLGiveInventoryInfo(to_agent,
01620 item->getUUID());
01621
01622 gViewerWindow->alertXml("CannotCopyWarning",
01623 &LLToolDragAndDrop::handleCopyProtectedItem,
01624 (void*)info);
01625 }
01626 }
01627
01628
01629 void LLToolDragAndDrop::handleCopyProtectedItem(S32 option, void* data)
01630 {
01631 LLGiveInventoryInfo* info = (LLGiveInventoryInfo*)data;
01632 LLInventoryItem* item = NULL;
01633 switch(option)
01634 {
01635 case 0:
01636 item = gInventory.getItem(info->mInventoryObjectID);
01637 if(item)
01638 {
01639 LLToolDragAndDrop::commitGiveInventoryItem(info->mToAgentID,
01640 item);
01641
01642
01643 gInventory.deleteObject(info->mInventoryObjectID);
01644 gInventory.notifyObservers();
01645 }
01646 else
01647 {
01648 gViewerWindow->alertXml("CannotGiveItem");
01649 }
01650 break;
01651
01652 default:
01653 gViewerWindow->alertXml("TransactionCancelled");
01654 break;
01655 }
01656 }
01657
01658
01659 void LLToolDragAndDrop::commitGiveInventoryItem(const LLUUID& to_agent,
01660 LLInventoryItem* item)
01661 {
01662 if(!item) return;
01663 std::string name;
01664 gAgent.buildFullname(name);
01665 LLUUID transaction_id;
01666 transaction_id.generate();
01667 const S32 BUCKET_SIZE = sizeof(U8) + UUID_BYTES;
01668 U8 bucket[BUCKET_SIZE];
01669 bucket[0] = (U8)item->getType();
01670 memcpy(&bucket[1], &(item->getUUID().mData), UUID_BYTES);
01671 pack_instant_message(
01672 gMessageSystem,
01673 gAgent.getID(),
01674 FALSE,
01675 gAgent.getSessionID(),
01676 to_agent,
01677 name.c_str(),
01678 item->getName().c_str(),
01679 IM_ONLINE,
01680 IM_INVENTORY_OFFERED,
01681 transaction_id,
01682 0,
01683 LLUUID::null,
01684 gAgent.getPositionAgent(),
01685 NO_TIMESTAMP,
01686 bucket,
01687 BUCKET_SIZE);
01688 gAgent.sendReliableMessage();
01689
01690
01691 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
01692 effectp->setSourceObject(gAgent.getAvatarObject());
01693 effectp->setTargetObject(gObjectList.findObject(to_agent));
01694 effectp->setDuration(LL_HUD_DUR_SHORT);
01695 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
01696 gFloaterTools->dirty();
01697
01698 LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY);
01699 }
01700
01701 void LLToolDragAndDrop::giveInventoryCategory(const LLUUID& to_agent,
01702 LLInventoryCategory* cat)
01703 {
01704 if(!cat) return;
01705 llinfos << "LLToolDragAndDrop::giveInventoryCategory() - "
01706 << cat->getUUID() << llendl;
01707
01708 LLVOAvatar* my_avatar = gAgent.getAvatarObject();
01709 if( !my_avatar )
01710 {
01711 return;
01712 }
01713
01714
01715 LLViewerInventoryCategory::cat_array_t cats;
01716 LLViewerInventoryItem::item_array_t items;
01717 LLGiveable giveable;
01718 gInventory.collectDescendentsIf(cat->getUUID(),
01719 cats,
01720 items,
01721 LLInventoryModel::EXCLUDE_TRASH,
01722 giveable);
01723 S32 count = cats.count();
01724 bool complete = true;
01725 for(S32 i = 0; i < count; ++i)
01726 {
01727 if(!gInventory.isCategoryComplete(cats.get(i)->getUUID()))
01728 {
01729 complete = false;
01730 break;
01731 }
01732 }
01733 if(!complete)
01734 {
01735 LLNotifyBox::showXml("IncompleteInventory");
01736 return;
01737 }
01738 count = items.count() + cats.count();
01739 if(count > MAX_ITEMS)
01740 {
01741 gViewerWindow->alertXml("TooManyItems");
01742 return;
01743 }
01744 else if(count == 0)
01745 {
01746 gViewerWindow->alertXml("NoItems");
01747 return;
01748 }
01749 else
01750 {
01751 if(0 == giveable.countNoCopy())
01752 {
01753 LLToolDragAndDrop::commitGiveInventoryCategory(to_agent, cat);
01754 }
01755 else
01756 {
01757 LLGiveInventoryInfo* info = NULL;
01758 info = new LLGiveInventoryInfo(to_agent, cat->getUUID());
01759 LLStringBase<char>::format_map_t args;
01760 args["[COUNT]"] = llformat("%d",giveable.countNoCopy());
01761 gViewerWindow->alertXml("CannotCopyCountItems", args,
01762 &LLToolDragAndDrop::handleCopyProtectedCategory,
01763 (void*)info);
01764
01765 }
01766 }
01767 }
01768
01769
01770
01771 void LLToolDragAndDrop::handleCopyProtectedCategory(S32 option, void* data)
01772 {
01773 LLGiveInventoryInfo* info = (LLGiveInventoryInfo*)data;
01774 LLInventoryCategory* cat = NULL;
01775 switch(option)
01776 {
01777 case 0:
01778 cat = gInventory.getCategory(info->mInventoryObjectID);
01779 if(cat)
01780 {
01781 LLToolDragAndDrop::commitGiveInventoryCategory(info->mToAgentID,
01782 cat);
01783 LLViewerInventoryCategory::cat_array_t cats;
01784 LLViewerInventoryItem::item_array_t items;
01785 LLUncopyableItems remove;
01786 gInventory.collectDescendentsIf(cat->getUUID(),
01787 cats,
01788 items,
01789 LLInventoryModel::EXCLUDE_TRASH,
01790 remove);
01791 S32 count = items.count();
01792 for(S32 i = 0; i < count; ++i)
01793 {
01794 gInventory.deleteObject(items.get(i)->getUUID());
01795 }
01796 gInventory.notifyObservers();
01797 }
01798 else
01799 {
01800 gViewerWindow->alertXml("CannotGiveCategory");
01801 }
01802 break;
01803
01804 default:
01805 gViewerWindow->alertXml("TransactionCancelled");
01806 break;
01807 }
01808 }
01809
01810
01811 void LLToolDragAndDrop::commitGiveInventoryCategory(const LLUUID& to_agent,
01812 LLInventoryCategory* cat)
01813 {
01814 if(!cat) return;
01815 llinfos << "LLToolDragAndDrop::commitGiveInventoryCategory() - "
01816 << cat->getUUID() << llendl;
01817
01818
01819 LLViewerInventoryCategory::cat_array_t cats;
01820 LLViewerInventoryItem::item_array_t items;
01821 LLGiveable giveable;
01822 gInventory.collectDescendentsIf(cat->getUUID(),
01823 cats,
01824 items,
01825 LLInventoryModel::EXCLUDE_TRASH,
01826 giveable);
01827
01828
01829
01830
01831 S32 count = items.count() + cats.count();
01832 if(count > MAX_ITEMS)
01833 {
01834 gViewerWindow->alertXml("TooManyItems");
01835 return;
01836 }
01837 else if(count == 0)
01838 {
01839 gViewerWindow->alertXml("NoItems");
01840 return;
01841 }
01842 else
01843 {
01844 std::string name;
01845 gAgent.buildFullname(name);
01846 LLUUID transaction_id;
01847 transaction_id.generate();
01848 S32 bucket_size = (sizeof(U8) + UUID_BYTES) * (count + 1);
01849 U8* bucket = new U8[bucket_size];
01850 U8* pos = bucket;
01851 U8 type = (U8)cat->getType();
01852 memcpy(pos, &type, sizeof(U8));
01853 pos += sizeof(U8);
01854 memcpy(pos, &(cat->getUUID()), UUID_BYTES);
01855 pos += UUID_BYTES;
01856 S32 i;
01857 count = cats.count();
01858 for(i = 0; i < count; ++i)
01859 {
01860 memcpy(pos, &type, sizeof(U8));
01861 pos += sizeof(U8);
01862 memcpy(pos, &(cats.get(i)->getUUID()), UUID_BYTES);
01863 pos += UUID_BYTES;
01864 }
01865 count = items.count();
01866 for(i = 0; i < count; ++i)
01867 {
01868 type = (U8)items.get(i)->getType();
01869 memcpy(pos, &type, sizeof(U8));
01870 pos += sizeof(U8);
01871 memcpy(pos, &(items.get(i)->getUUID()), UUID_BYTES);
01872 pos += UUID_BYTES;
01873 }
01874 pack_instant_message(
01875 gMessageSystem,
01876 gAgent.getID(),
01877 FALSE,
01878 gAgent.getSessionID(),
01879 to_agent,
01880 name.c_str(),
01881 cat->getName().c_str(),
01882 IM_ONLINE,
01883 IM_INVENTORY_OFFERED,
01884 transaction_id,
01885 0,
01886 LLUUID::null,
01887 gAgent.getPositionAgent(),
01888 NO_TIMESTAMP,
01889 bucket,
01890 bucket_size);
01891 gAgent.sendReliableMessage();
01892 delete[] bucket;
01893
01894
01895 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
01896 effectp->setSourceObject(gAgent.getAvatarObject());
01897 effectp->setTargetObject(gObjectList.findObject(to_agent));
01898 effectp->setDuration(LL_HUD_DUR_SHORT);
01899 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
01900 gFloaterTools->dirty();
01901
01902 LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY);
01903 }
01904 }
01905
01906
01907 BOOL LLToolDragAndDrop::isInventoryGiveAcceptable(LLInventoryItem* item)
01908 {
01909 if(!item)
01910 {
01911 return FALSE;
01912 }
01913 if(!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
01914 {
01915 return FALSE;
01916 }
01917 BOOL copyable = FALSE;
01918 if(item->getPermissions().allowCopyBy(gAgent.getID())) copyable = TRUE;
01919 LLVOAvatar* my_avatar = gAgent.getAvatarObject();
01920 if(!my_avatar)
01921 {
01922 return FALSE;
01923 }
01924 BOOL acceptable = TRUE;
01925 switch(item->getType())
01926 {
01927 case LLAssetType::AT_CALLINGCARD:
01928 acceptable = FALSE;
01929 break;
01930 case LLAssetType::AT_OBJECT:
01931 if(my_avatar->isWearingAttachment(item->getUUID()))
01932 {
01933 acceptable = FALSE;
01934 }
01935 break;
01936 case LLAssetType::AT_BODYPART:
01937 case LLAssetType::AT_CLOTHING:
01938 if(!copyable && gAgent.isWearingItem(item->getUUID()))
01939 {
01940 acceptable = FALSE;
01941 }
01942 break;
01943 default:
01944 break;
01945 }
01946 return acceptable;
01947 }
01948
01949
01950 BOOL LLToolDragAndDrop::isInventoryGroupGiveAcceptable(LLInventoryItem* item)
01951 {
01952 if(!item)
01953 {
01954 return FALSE;
01955 }
01956
01957
01958
01959 if(!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
01960 {
01961 return FALSE;
01962 }
01963 if(!item->getPermissions().allowCopyBy(gAgent.getID()))
01964 {
01965 return FALSE;
01966 }
01967
01968 LLVOAvatar* my_avatar = gAgent.getAvatarObject();
01969 if(!my_avatar)
01970 {
01971 return FALSE;
01972 }
01973
01974 BOOL acceptable = TRUE;
01975 switch(item->getType())
01976 {
01977 case LLAssetType::AT_CALLINGCARD:
01978 acceptable = FALSE;
01979 break;
01980 case LLAssetType::AT_OBJECT:
01981 if(my_avatar->isWearingAttachment(item->getUUID()))
01982 {
01983 acceptable = FALSE;
01984 }
01985 break;
01986 default:
01987 break;
01988 }
01989 return acceptable;
01990 }
01991
01992
01993
01994 EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LLInventoryItem* item)
01995 {
01996
01997 if(!item || !obj) return ACCEPT_NO;
01998
01999 LLViewerInventoryItem* vitem = (LLViewerInventoryItem*)item;
02000 if(!vitem->isComplete()) return ACCEPT_NO;
02001
02002
02003
02004
02005
02006 if(obj->getID() == item->getParentUUID())
02007 {
02008 return ACCEPT_NO;
02009 }
02010
02011
02012
02013
02014 BOOL worn = FALSE;
02015 LLVOAvatar* my_avatar = NULL;
02016 switch(item->getType())
02017 {
02018 case LLAssetType::AT_OBJECT:
02019 my_avatar = gAgent.getAvatarObject();
02020 if(my_avatar && my_avatar->isWearingAttachment(item->getUUID()))
02021 {
02022 worn = TRUE;
02023 }
02024 break;
02025 case LLAssetType::AT_BODYPART:
02026 case LLAssetType::AT_CLOTHING:
02027 if(gAgent.isWearingItem(item->getUUID()))
02028 {
02029 worn = TRUE;
02030 }
02031 break;
02032 default:
02033 break;
02034 }
02035 const LLPermissions& perm = item->getPermissions();
02036 BOOL modify = (obj->permModify() || obj->flagAllowInventoryAdd());
02037 BOOL transfer = FALSE;
02038 if((obj->permYouOwner() && (perm.getOwner() == gAgent.getID()))
02039 || perm.allowOperationBy(PERM_TRANSFER, gAgent.getID()))
02040 {
02041 transfer = TRUE;
02042 }
02043 BOOL volume = (LL_PCODE_VOLUME == obj->getPCode());
02044 BOOL attached = obj->isAttachment();
02045 BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE;
02046 if(attached && !unrestricted)
02047 {
02048 return ACCEPT_NO_LOCKED;
02049 }
02050 else if(modify && transfer && volume && !worn)
02051 {
02052 return ACCEPT_YES_MULTI;
02053 }
02054 else if(!modify)
02055 {
02056 return ACCEPT_NO_LOCKED;
02057 }
02058 return ACCEPT_NO;
02059 }
02060
02064
02065 EAcceptance LLToolDragAndDrop::dad3dNULL(
02066 LLViewerObject*, S32, MASK, BOOL)
02067 {
02068 lldebugs << "LLToolDragAndDrop::dad3dNULL()" << llendl;
02069 return ACCEPT_NO;
02070 }
02071
02072 EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
02073 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
02074 {
02075 lldebugs << "LLToolDragAndDrop::dad3dRezAttachmentFromInv()" << llendl;
02076
02077 if(mSource != SOURCE_AGENT && mSource != SOURCE_LIBRARY)
02078 {
02079 return ACCEPT_NO;
02080 }
02081
02082 LLViewerInventoryItem* item;
02083 LLViewerInventoryCategory* cat;
02084 locateInventory(item, cat);
02085 if(!item || !item->isComplete()) return ACCEPT_NO;
02086
02087
02088 LLUUID trash_id(gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH));
02089 if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) )
02090 {
02091 return ACCEPT_NO;
02092 }
02093
02094
02095 LLVOAvatar* avatar = gAgent.getAvatarObject();
02096 if( !avatar || avatar->isWearingAttachment(item->getUUID()) )
02097 {
02098 return ACCEPT_NO;
02099 }
02100
02101 if( drop )
02102 {
02103 if(mSource == SOURCE_LIBRARY)
02104 {
02105 LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0);
02106 copy_inventory_item(
02107 gAgent.getID(),
02108 item->getPermissions().getOwner(),
02109 item->getUUID(),
02110 LLUUID::null,
02111 std::string(),
02112 cb);
02113 }
02114 else
02115 {
02116 rez_attachment(item, 0);
02117 }
02118 }
02119 return ACCEPT_YES_SINGLE;
02120 }
02121
02122
02123 EAcceptance LLToolDragAndDrop::dad3dRezObjectOnLand(
02124 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
02125 {
02126 if (mSource == SOURCE_WORLD)
02127 {
02128 return dad3dRezFromObjectOnLand(obj, face, mask, drop);
02129 }
02130
02131 lldebugs << "LLToolDragAndDrop::dad3dRezObjectOnLand()" << llendl;
02132 LLViewerInventoryItem* item;
02133 LLViewerInventoryCategory* cat;
02134 locateInventory(item, cat);
02135 if(!item || !item->isComplete()) return ACCEPT_NO;
02136
02137 LLVOAvatar* my_avatar = gAgent.getAvatarObject();
02138 if( !my_avatar || my_avatar->isWearingAttachment( item->getUUID() ) )
02139 {
02140 return ACCEPT_NO;
02141 }
02142
02143 EAcceptance accept;
02144 BOOL remove_inventory;
02145
02146
02147 if (mask & MASK_SHIFT)
02148 {
02149
02150
02151
02152 accept = ACCEPT_YES_COPY_SINGLE;
02153 remove_inventory = FALSE;
02154 }
02155 else
02156 {
02157 accept = ACCEPT_YES_COPY_SINGLE;
02158 remove_inventory = FALSE;
02159 }
02160
02161
02162
02163 if(!item->getPermissions().allowCopyBy(gAgent.getID()))
02164 {
02165 accept = ACCEPT_YES_SINGLE;
02166 remove_inventory = TRUE;
02167 }
02168
02169
02170 LLUUID trash_id;
02171 trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
02172 if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id))
02173 {
02174 accept = ACCEPT_YES_SINGLE;
02175 remove_inventory = TRUE;
02176 }
02177
02178 if(drop)
02179 {
02180 dropObject(obj, TRUE, FALSE, remove_inventory);
02181 }
02182
02183 return accept;
02184 }
02185
02186 EAcceptance LLToolDragAndDrop::dad3dRezObjectOnObject(
02187 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
02188 {
02189
02190 if (mSource == SOURCE_WORLD)
02191 {
02192 return dad3dRezFromObjectOnObject(obj, face, mask, drop);
02193 }
02194
02195 lldebugs << "LLToolDragAndDrop::dad3dRezObjectOnObject()" << llendl;
02196 LLViewerInventoryItem* item;
02197 LLViewerInventoryCategory* cat;
02198 locateInventory(item, cat);
02199 if(!item || !item->isComplete()) return ACCEPT_NO;
02200 LLVOAvatar* my_avatar = gAgent.getAvatarObject();
02201 if( !my_avatar || my_avatar->isWearingAttachment( item->getUUID() ) )
02202 {
02203 return ACCEPT_NO;
02204 }
02205
02206 if((mask & MASK_CONTROL))
02207 {
02208
02209
02210 if(mSource == SOURCE_NOTECARD)
02211 {
02212 return ACCEPT_NO;
02213 }
02214
02215 EAcceptance rv = willObjectAcceptInventory(obj, item);
02216 if(drop && (ACCEPT_YES_SINGLE <= rv))
02217 {
02218 dropInventory(obj, item, mSource, mSourceID);
02219 }
02220 return rv;
02221 }
02222
02223 EAcceptance accept;
02224 BOOL remove_inventory;
02225
02226 if (mask & MASK_SHIFT)
02227 {
02228
02229
02230
02231 accept = ACCEPT_YES_COPY_SINGLE;
02232 remove_inventory = FALSE;
02233 }
02234 else
02235 {
02236 accept = ACCEPT_YES_COPY_SINGLE;
02237 remove_inventory = FALSE;
02238 }
02239
02240
02241
02242 if(!item->getPermissions().allowCopyBy(gAgent.getID()))
02243 {
02244 accept = ACCEPT_YES_SINGLE;
02245 remove_inventory = TRUE;
02246 }
02247
02248
02249 LLUUID trash_id;
02250 trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
02251 if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id))
02252 {
02253 accept = ACCEPT_YES_SINGLE;
02254 remove_inventory = TRUE;
02255 }
02256
02257 if(drop)
02258 {
02259 dropObject(obj, FALSE, FALSE, remove_inventory);
02260 }
02261
02262 return accept;
02263 }
02264
02265 EAcceptance LLToolDragAndDrop::dad3dRezScript(
02266 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
02267 {
02268 lldebugs << "LLToolDragAndDrop::dad3dRezScript()" << llendl;
02269
02270
02271
02272 if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource))
02273 {
02274 return ACCEPT_NO;
02275 }
02276
02277 LLViewerInventoryItem* item;
02278 LLViewerInventoryCategory* cat;
02279 locateInventory(item, cat);
02280 if(!item || !item->isComplete()) return ACCEPT_NO;
02281 EAcceptance rv = willObjectAcceptInventory(obj, item);
02282 if(drop && (ACCEPT_YES_SINGLE <= rv))
02283 {
02284
02285
02286 BOOL active = ((mask & MASK_CONTROL) == 0);
02287
02288 LLViewerObject* root_object = obj;
02289 if (obj && obj->getParent())
02290 {
02291 LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent();
02292 if (!parent_obj->isAvatar())
02293 {
02294 root_object = parent_obj;
02295 }
02296 }
02297
02298 dropScript(root_object, item, active, mSource, mSourceID);
02299 }
02300 return rv;
02301 }
02302
02303 EAcceptance LLToolDragAndDrop::dad3dTextureObject(
02304 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
02305 {
02306 lldebugs << "LLToolDragAndDrop::dad3dTextureObject()" << llendl;
02307
02308
02309
02310 if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource))
02311 {
02312 return ACCEPT_NO;
02313 }
02314
02315 LLViewerInventoryItem* item;
02316 LLViewerInventoryCategory* cat;
02317 locateInventory(item, cat);
02318 if(!item || !item->isComplete()) return ACCEPT_NO;
02319 EAcceptance rv = willObjectAcceptInventory(obj, item);
02320 if((mask & MASK_CONTROL))
02321 {
02322 if((ACCEPT_YES_SINGLE <= rv) && drop)
02323 {
02324 dropInventory(obj, item, mSource, mSourceID);
02325 }
02326 return rv;
02327 }
02328 if(!obj->permModify())
02329 {
02330 return ACCEPT_NO_LOCKED;
02331 }
02332
02333 if(!item->getPermissions().allowCopyBy(gAgent.getID()))
02334 {
02335 return ACCEPT_NO;
02336 }
02337
02338 if(drop && (ACCEPT_YES_SINGLE <= rv))
02339 {
02340 if((mask & MASK_SHIFT))
02341 {
02342 dropTextureAllFaces(obj, item, mSource, mSourceID);
02343 }
02344 else
02345 {
02346 dropTextureOneFace(obj, face, item, mSource, mSourceID);
02347 }
02348
02349
02350 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
02351 effectp->setSourceObject(gAgent.getAvatarObject());
02352 effectp->setTargetObject(obj);
02353 effectp->setDuration(LL_HUD_DUR_SHORT);
02354 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
02355 }
02356
02357
02358 return ACCEPT_YES_MULTI;
02359 }
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376 EAcceptance LLToolDragAndDrop::dad3dWearItem(
02377 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
02378 {
02379 lldebugs << "LLToolDragAndDrop::dad3dWearItem()" << llendl;
02380 LLViewerInventoryItem* item;
02381 LLViewerInventoryCategory* cat;
02382 locateInventory(item, cat);
02383 if(!item || !item->isComplete()) return ACCEPT_NO;
02384
02385 if(mSource == SOURCE_AGENT || mSource == SOURCE_LIBRARY)
02386 {
02387
02388 LLUUID trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
02389 if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) )
02390 {
02391 return ACCEPT_NO;
02392 }
02393
02394 if( drop )
02395 {
02396
02397
02398 if (!gAgent.areWearablesLoaded())
02399 {
02400 gViewerWindow->alertXml("CanNotChangeAppearanceUntilLoaded");
02401 return ACCEPT_NO;
02402 }
02403
02404 if(mSource == SOURCE_LIBRARY)
02405 {
02406
02407
02408 LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
02409 copy_inventory_item(
02410 gAgent.getID(),
02411 item->getPermissions().getOwner(),
02412 item->getUUID(),
02413 LLUUID::null,
02414 std::string(),
02415 cb);
02416 }
02417 else
02418 {
02419 wear_inventory_item_on_avatar( item );
02420 }
02421 }
02422 return ACCEPT_YES_MULTI;
02423 }
02424 else
02425 {
02426
02427 return ACCEPT_NO;
02428 }
02429 }
02430
02431 EAcceptance LLToolDragAndDrop::dad3dActivateGesture(
02432 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
02433 {
02434 lldebugs << "LLToolDragAndDrop::dad3dActivateGesture()" << llendl;
02435 LLViewerInventoryItem* item;
02436 LLViewerInventoryCategory* cat;
02437 locateInventory(item, cat);
02438 if(!item || !item->isComplete()) return ACCEPT_NO;
02439
02440 if(mSource == SOURCE_AGENT || mSource == SOURCE_LIBRARY)
02441 {
02442
02443 LLUUID trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
02444 if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) )
02445 {
02446 return ACCEPT_NO;
02447 }
02448
02449 if( drop )
02450 {
02451 LLUUID item_id;
02452 if(mSource == SOURCE_LIBRARY)
02453 {
02454
02455
02456 LLPointer<LLInventoryCallback> cb = new ActivateGestureCallback();
02457 copy_inventory_item(
02458 gAgent.getID(),
02459 item->getPermissions().getOwner(),
02460 item->getUUID(),
02461 LLUUID::null,
02462 std::string(),
02463 cb);
02464 }
02465 else
02466 {
02467 gGestureManager.activateGesture(item->getUUID());
02468 gInventory.updateItem(item);
02469 gInventory.notifyObservers();
02470 }
02471 }
02472 return ACCEPT_YES_MULTI;
02473 }
02474 else
02475 {
02476 return ACCEPT_NO;
02477 }
02478 }
02479
02480 EAcceptance LLToolDragAndDrop::dad3dWearCategory(
02481 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
02482 {
02483 lldebugs << "LLToolDragAndDrop::dad3dWearCategory()" << llendl;
02484 LLViewerInventoryItem* item;
02485 LLViewerInventoryCategory* category;
02486 locateInventory(item, category);
02487 if(!category) return ACCEPT_NO;
02488
02489 if (drop)
02490 {
02491
02492
02493 if (!gAgent.areWearablesLoaded())
02494 {
02495 gViewerWindow->alertXml("CanNotChangeAppearanceUntilLoaded");
02496 return ACCEPT_NO;
02497 }
02498 }
02499
02500 if(mSource == SOURCE_AGENT)
02501 {
02502 LLUUID trash_id(gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH));
02503 if( gInventory.isObjectDescendentOf( category->getUUID(), trash_id ) )
02504 {
02505 return ACCEPT_NO;
02506 }
02507
02508 if(drop)
02509 {
02510 BOOL append = ( (mask & MASK_SHIFT) ? TRUE : FALSE );
02511 wear_inventory_category(category, false, append);
02512 }
02513 return ACCEPT_YES_MULTI;
02514 }
02515 else if(mSource == SOURCE_LIBRARY)
02516 {
02517 if(drop)
02518 {
02519 wear_inventory_category(category, true, false);
02520 }
02521 return ACCEPT_YES_MULTI;
02522 }
02523 else
02524 {
02525
02526 return ACCEPT_NO;
02527 }
02528 }
02529
02530
02531 EAcceptance LLToolDragAndDrop::dad3dUpdateInventory(
02532 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
02533 {
02534 lldebugs << "LLToolDragAndDrop::dadUpdateInventory()" << llendl;
02535
02536
02537
02538 if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource))
02539 {
02540 return ACCEPT_NO;
02541 }
02542
02543 LLViewerInventoryItem* item;
02544 LLViewerInventoryCategory* cat;
02545 locateInventory(item, cat);
02546 if(!item || !item->isComplete()) return ACCEPT_NO;
02547 LLViewerObject* root_object = obj;
02548 if (obj && obj->getParent())
02549 {
02550 LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent();
02551 if (!parent_obj->isAvatar())
02552 {
02553 root_object = parent_obj;
02554 }
02555 }
02556
02557 EAcceptance rv = willObjectAcceptInventory(root_object, item);
02558 if(root_object && drop && (ACCEPT_YES_COPY_SINGLE <= rv))
02559 {
02560 dropInventory(root_object, item, mSource, mSourceID);
02561 }
02562 return rv;
02563 }
02564
02565 BOOL LLToolDragAndDrop::dadUpdateInventory(LLViewerObject* obj, BOOL drop)
02566 {
02567 EAcceptance rv = dad3dUpdateInventory(obj, -1, MASK_NONE, drop);
02568 return (rv >= ACCEPT_YES_COPY_SINGLE);
02569 }
02570
02571 EAcceptance LLToolDragAndDrop::dad3dUpdateInventoryCategory(
02572 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
02573 {
02574 lldebugs << "LLToolDragAndDrop::dad3dUpdateInventoryCategory()" << llendl;
02575 if (NULL==obj)
02576 {
02577 llwarns << "obj is NULL; aborting func with ACCEPT_NO" << llendl;
02578 return ACCEPT_NO;
02579 }
02580
02581 if (mSource != SOURCE_AGENT && mSource != SOURCE_LIBRARY)
02582 {
02583 return ACCEPT_NO;
02584 }
02585 if(obj->isAttachment()) return ACCEPT_NO_LOCKED;
02586 LLViewerInventoryItem* item;
02587 LLViewerInventoryCategory* cat;
02588 locateInventory(item, cat);
02589 if(!cat) return ACCEPT_NO;
02590 EAcceptance rv = ACCEPT_NO;
02591
02592
02593 LLDroppableItem droppable(!obj->permYouOwner());
02594 LLInventoryModel::cat_array_t cats;
02595 LLInventoryModel::item_array_t items;
02596 gInventory.collectDescendentsIf(cat->getUUID(),
02597 cats,
02598 items,
02599 LLInventoryModel::EXCLUDE_TRASH,
02600 droppable);
02601 cats.put(cat);
02602 if(droppable.countNoCopy() > 0)
02603 {
02604 llwarns << "*** Need to confirm this step" << llendl;
02605 }
02606 LLViewerObject* root_object = obj;
02607 if (obj->getParent())
02608 {
02609 LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent();
02610 if (!parent_obj->isAvatar())
02611 {
02612 root_object = parent_obj;
02613 }
02614 }
02615
02616
02617 S32 i;
02618 S32 count = cats.count();
02619 for(i = 0; i < count; ++i)
02620 {
02621 rv = gInventory.isCategoryComplete(cats.get(i)->getUUID()) ? ACCEPT_YES_MULTI : ACCEPT_NO;
02622 if(rv < ACCEPT_YES_SINGLE)
02623 {
02624 lldebugs << "Category " << cats.get(i)->getUUID()
02625 << "is not complete." << llendl;
02626 break;
02627 }
02628 }
02629 if(ACCEPT_YES_COPY_SINGLE <= rv)
02630 {
02631 count = items.count();
02632 for(i = 0; i < count; ++i)
02633 {
02634 rv = willObjectAcceptInventory(root_object, items.get(i));
02635 if(rv < ACCEPT_YES_COPY_SINGLE)
02636 {
02637 lldebugs << "Object will not accept "
02638 << items.get(i)->getUUID() << llendl;
02639 break;
02640 }
02641 }
02642 }
02643
02644
02645 if(drop && (ACCEPT_YES_COPY_SINGLE <= rv))
02646 {
02647 S32 count = items.count();
02648 LLInventoryFetchObserver::item_ref_t ids;
02649 for(i = 0; i < count; ++i)
02650 {
02651
02652 ids.push_back(items.get(i)->getUUID());
02653 }
02654 LLCategoryDropObserver* dropper;
02655 dropper = new LLCategoryDropObserver(obj->getID(), mSource);
02656 dropper->fetchItems(ids);
02657 if(dropper->isEverythingComplete())
02658 {
02659 dropper->done();
02660 }
02661 else
02662 {
02663 gInventory.addObserver(dropper);
02664 }
02665 }
02666 return rv;
02667 }
02668
02669 BOOL LLToolDragAndDrop::dadUpdateInventoryCategory(LLViewerObject* obj,
02670 BOOL drop)
02671 {
02672 EAcceptance rv = dad3dUpdateInventoryCategory(obj, -1, MASK_NONE, drop);
02673 return (rv >= ACCEPT_YES_COPY_SINGLE);
02674 }
02675
02676 EAcceptance LLToolDragAndDrop::dad3dGiveInventoryObject(
02677 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
02678 {
02679 lldebugs << "LLToolDragAndDrop::dad3dGiveInventoryObject()" << llendl;
02680
02681
02682 if(mSource != SOURCE_AGENT) return ACCEPT_NO;
02683
02684
02685 LLViewerInventoryItem* item;
02686 LLViewerInventoryCategory* cat;
02687 locateInventory(item, cat);
02688 if(!item || !item->isComplete()) return ACCEPT_NO;
02689 if(!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
02690 {
02691
02692 return ACCEPT_NO;
02693 }
02694 LLVOAvatar* avatar = gAgent.getAvatarObject();
02695 if(avatar && avatar->isWearingAttachment( item->getUUID() ) )
02696 {
02697
02698 return ACCEPT_NO;
02699 }
02700 if( obj && avatar )
02701 {
02702 if(drop)
02703 {
02704 giveInventory(obj->getID(), item );
02705 }
02706
02707
02708 return ACCEPT_YES_SINGLE;
02709 }
02710 return ACCEPT_NO;
02711 }
02712
02713
02714 EAcceptance LLToolDragAndDrop::dad3dGiveInventory(
02715 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
02716 {
02717 lldebugs << "LLToolDragAndDrop::dad3dGiveInventory()" << llendl;
02718
02719 if(mSource != SOURCE_AGENT) return ACCEPT_NO;
02720 LLViewerInventoryItem* item;
02721 LLViewerInventoryCategory* cat;
02722 locateInventory(item, cat);
02723 if(!item || !item->isComplete()) return ACCEPT_NO;
02724 if(!isInventoryGiveAcceptable(item))
02725 {
02726 return ACCEPT_NO;
02727 }
02728 if(drop && obj)
02729 {
02730 giveInventory(obj->getID(), item);
02731 }
02732
02733
02734 return ACCEPT_YES_SINGLE;
02735 }
02736
02737 EAcceptance LLToolDragAndDrop::dad3dGiveInventoryCategory(
02738 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
02739 {
02740 lldebugs << "LLToolDragAndDrop::dad3dGiveInventoryCategory()" << llendl;
02741 if(drop && obj)
02742 {
02743 LLViewerInventoryItem* item;
02744 LLViewerInventoryCategory* cat;
02745 locateInventory(item, cat);
02746 if(!cat) return ACCEPT_NO;
02747 giveInventoryCategory(obj->getID(), cat);
02748 }
02749
02750
02751 return ACCEPT_YES_SINGLE;
02752 }
02753
02754
02755 EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnLand(
02756 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
02757 {
02758 lldebugs << "LLToolDragAndDrop::dad3dRezFromObjectOnLand()" << llendl;
02759 LLViewerInventoryItem* item = NULL;
02760 LLViewerInventoryCategory* cat = NULL;
02761 locateInventory(item, cat);
02762 if(!item || !item->isComplete()) return ACCEPT_NO;
02763
02764 if(!gAgent.allowOperation(PERM_COPY, item->getPermissions())
02765 || !item->getPermissions().allowTransferTo(LLUUID::null))
02766 {
02767 return ACCEPT_NO_LOCKED;
02768 }
02769 if(drop)
02770 {
02771 dropObject(obj, TRUE, TRUE, FALSE);
02772 }
02773 return ACCEPT_YES_SINGLE;
02774 }
02775
02776 EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnObject(
02777 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
02778 {
02779 lldebugs << "LLToolDragAndDrop::dad3dRezFromObjectOnObject()" << llendl;
02780 LLViewerInventoryItem* item;
02781 LLViewerInventoryCategory* cat;
02782 locateInventory(item, cat);
02783 if(!item || !item->isComplete()) return ACCEPT_NO;
02784 if((mask & MASK_CONTROL))
02785 {
02786
02787
02788 return ACCEPT_NO;
02789
02790
02791
02792
02793
02794
02795
02796
02797 }
02798 if(!item->getPermissions().allowCopyBy(gAgent.getID(),
02799 gAgent.getGroupID())
02800 || !item->getPermissions().allowTransferTo(LLUUID::null))
02801 {
02802 return ACCEPT_NO_LOCKED;
02803 }
02804 if(drop)
02805 {
02806 dropObject(obj, FALSE, TRUE, FALSE);
02807 }
02808 return ACCEPT_YES_SINGLE;
02809 }
02810
02811 EAcceptance LLToolDragAndDrop::dad3dCategoryOnLand(
02812 LLViewerObject *obj, S32 face, MASK mask, BOOL drop)
02813 {
02814 return ACCEPT_NO;
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843 }
02844
02845
02846
02847
02848
02849 EAcceptance LLToolDragAndDrop::dad3dAssetOnLand(
02850 LLViewerObject *obj, S32 face, MASK mask, BOOL drop)
02851 {
02852 return ACCEPT_NO;
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878 }
02879
02880 LLInventoryObject* LLToolDragAndDrop::locateInventory(
02881 LLViewerInventoryItem*& item,
02882 LLViewerInventoryCategory*& cat)
02883 {
02884 item = NULL;
02885 cat = NULL;
02886 if(mCargoIDs.empty()) return NULL;
02887 if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY))
02888 {
02889
02890 item = (LLViewerInventoryItem*)gInventory.getItem(mCargoIDs[mCurItemIndex]);
02891 cat = (LLViewerInventoryCategory*)gInventory.getCategory(mCargoIDs[mCurItemIndex]);
02892 }
02893 else if(mSource == SOURCE_WORLD)
02894 {
02895
02896 LLViewerObject* obj = gObjectList.findObject(mSourceID);
02897 if(obj)
02898 {
02899 if((mCargoTypes[mCurItemIndex] == DAD_CATEGORY)
02900 || (mCargoTypes[mCurItemIndex] == DAD_ROOT_CATEGORY))
02901 {
02902 cat = (LLViewerInventoryCategory*)obj->getInventoryObject(mCargoIDs[mCurItemIndex]);
02903 }
02904 else
02905 {
02906 item = (LLViewerInventoryItem*)obj->getInventoryObject(mCargoIDs[mCurItemIndex]);
02907 }
02908 }
02909 }
02910 else if(mSource == SOURCE_NOTECARD)
02911 {
02912 LLPreviewNotecard* card;
02913 card = (LLPreviewNotecard*)LLPreview::find(mSourceID);
02914 if(card)
02915 {
02916 item = (LLViewerInventoryItem*)card->getDragItem();
02917 }
02918 }
02919 if(item) return item;
02920 if(cat) return cat;
02921 return NULL;
02922 }
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993 void LLToolDragAndDrop::createContainer(LLViewerInventoryItem::item_array_t &items, const char* preferred_name )
02994 {
02995 llwarns << "LLToolDragAndDrop::createContainer()" << llendl;
02996 return;
02997 }
02998
02999
03000
03001
03002 void pack_permissions_slam(LLMessageSystem* msg, U32 flags, const LLPermissions& perms)
03003 {
03004 U32 group_mask = perms.getMaskGroup();
03005 U32 everyone_mask = perms.getMaskEveryone();
03006 U32 next_owner_mask = perms.getMaskNextOwner();
03007
03008 msg->addU32Fast(_PREHASH_ItemFlags, flags);
03009 msg->addU32Fast(_PREHASH_GroupMask, group_mask);
03010 msg->addU32Fast(_PREHASH_EveryoneMask, everyone_mask);
03011 msg->addU32Fast(_PREHASH_NextOwnerMask, next_owner_mask);
03012 }