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