aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/lltooldraganddrop.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/lltooldraganddrop.cpp')
-rw-r--r--linden/indra/newview/lltooldraganddrop.cpp402
1 files changed, 143 insertions, 259 deletions
diff --git a/linden/indra/newview/lltooldraganddrop.cpp b/linden/indra/newview/lltooldraganddrop.cpp
index 7a378a9..72ee24b 100644
--- a/linden/indra/newview/lltooldraganddrop.cpp
+++ b/linden/indra/newview/lltooldraganddrop.cpp
@@ -42,6 +42,7 @@
42#include "llfirstuse.h" 42#include "llfirstuse.h"
43#include "llfloater.h" 43#include "llfloater.h"
44#include "llfloatertools.h" 44#include "llfloatertools.h"
45#include "llfocusmgr.h"
45#include "llgesturemgr.h" 46#include "llgesturemgr.h"
46#include "llhudeffecttrail.h" 47#include "llhudeffecttrail.h"
47#include "llhudmanager.h" 48#include "llhudmanager.h"
@@ -52,6 +53,7 @@
52#include "llpreviewnotecard.h" 53#include "llpreviewnotecard.h"
53#include "llselectmgr.h" 54#include "llselectmgr.h"
54#include "lltoolmgr.h" 55#include "lltoolmgr.h"
56#include "lltrans.h"
55#include "llui.h" 57#include "llui.h"
56#include "llviewerimagelist.h" 58#include "llviewerimagelist.h"
57#include "llviewerinventory.h" 59#include "llviewerinventory.h"
@@ -70,10 +72,6 @@
70// or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a 72// or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a
71// bit from there to give some pad. 73// bit from there to give some pad.
72const S32 MAX_ITEMS = 42; 74const S32 MAX_ITEMS = 42;
73const char* FOLDER_INCLUDES_ATTACHMENTS_BEING_WORN =
74 "Cannot give folders that contain objects that are attached to you.\n"
75 "Detach the object(s) and then try again.";
76
77 75
78// syntactic sugar 76// syntactic sugar
79#define callMemberFunction(object,ptrToMember) ((object).*(ptrToMember)) 77#define callMemberFunction(object,ptrToMember) ((object).*(ptrToMember))
@@ -127,41 +125,17 @@ protected:
127}; 125};
128 126
129bool LLDroppableItem::operator()(LLInventoryCategory* cat, 127bool LLDroppableItem::operator()(LLInventoryCategory* cat,
130 LLInventoryItem* item) 128 LLInventoryItem* item)
131{ 129{
132 bool allowed = false; 130 bool allowed = false;
133 if(item) 131 if(item)
134 { 132 {
135 LLVOAvatar* my_avatar = NULL; 133 allowed = itemTransferCommonlyAllowed(item);
136 switch(item->getType())
137 {
138 case LLAssetType::AT_CALLINGCARD:
139 // not allowed
140 break;
141
142 case LLAssetType::AT_OBJECT:
143 my_avatar = gAgent.getAvatarObject();
144 if(my_avatar && !my_avatar->isWearingAttachment(item->getUUID()))
145 {
146 allowed = true;
147 }
148 break;
149 134
150 case LLAssetType::AT_BODYPART: 135 if(allowed
151 case LLAssetType::AT_CLOTHING: 136 && mIsTransfer
152 if(!gAgent.isWearingItem(item->getUUID()))
153 {
154 allowed = true;
155 }
156 break;
157
158 default:
159 allowed = true;
160 break;
161 }
162 if(mIsTransfer
163 && !item->getPermissions().allowOperationBy(PERM_TRANSFER, 137 && !item->getPermissions().allowOperationBy(PERM_TRANSFER,
164 gAgent.getID())) 138 gAgent.getID()))
165 { 139 {
166 allowed = false; 140 allowed = false;
167 } 141 }
@@ -182,45 +156,18 @@ public:
182}; 156};
183 157
184bool LLUncopyableItems::operator()(LLInventoryCategory* cat, 158bool LLUncopyableItems::operator()(LLInventoryCategory* cat,
185 LLInventoryItem* item) 159 LLInventoryItem* item)
186{ 160{
187 BOOL uncopyable = FALSE; 161 bool uncopyable = false;
188 if(item) 162 if(item)
189 { 163 {
190 BOOL allowed = FALSE; 164 if (itemTransferCommonlyAllowed(item) &&
191 LLVOAvatar* my_avatar = NULL; 165 !item->getPermissions().allowCopyBy(gAgent.getID()))
192 switch(item->getType())
193 {
194 case LLAssetType::AT_CALLINGCARD:
195 // not allowed
196 break;
197
198 case LLAssetType::AT_OBJECT:
199 my_avatar = gAgent.getAvatarObject();
200 if(my_avatar && !my_avatar->isWearingAttachment(item->getUUID()))
201 {
202 allowed = TRUE;
203 }
204 break;
205
206 case LLAssetType::AT_BODYPART:
207 case LLAssetType::AT_CLOTHING:
208 if(!gAgent.isWearingItem(item->getUUID()))
209 {
210 allowed = TRUE;
211 }
212 break;
213
214 default:
215 allowed = TRUE;
216 break;
217 }
218 if(allowed && !item->getPermissions().allowCopyBy(gAgent.getID()))
219 { 166 {
220 uncopyable = TRUE; 167 uncopyable = true;
221 } 168 }
222 } 169 }
223 return (uncopyable ? true : false); 170 return uncopyable;
224} 171}
225 172
226class LLDropCopyableItems : public LLInventoryCollectFunctor 173class LLDropCopyableItems : public LLInventoryCollectFunctor
@@ -233,45 +180,21 @@ public:
233 180
234 181
235bool LLDropCopyableItems::operator()( 182bool LLDropCopyableItems::operator()(
236 LLInventoryCategory* cat, LLInventoryItem* item) 183 LLInventoryCategory* cat,
184 LLInventoryItem* item)
237{ 185{
238 BOOL allowed = FALSE; 186 bool allowed = false;
239 if(item) 187 if(item)
240 { 188 {
241 LLVOAvatar* my_avatar = NULL; 189 allowed = itemTransferCommonlyAllowed(item);
242 switch(item->getType()) 190 if(allowed &&
243 { 191 !item->getPermissions().allowCopyBy(gAgent.getID()))
244 case LLAssetType::AT_CALLINGCARD:
245 // not allowed
246 break;
247
248 case LLAssetType::AT_OBJECT:
249 my_avatar = gAgent.getAvatarObject();
250 if(my_avatar && !my_avatar->isWearingAttachment(item->getUUID()))
251 {
252 allowed = TRUE;
253 }
254 break;
255
256 case LLAssetType::AT_BODYPART:
257 case LLAssetType::AT_CLOTHING:
258 if(!gAgent.isWearingItem(item->getUUID()))
259 {
260 allowed = TRUE;
261 }
262 break;
263
264 default:
265 allowed = TRUE;
266 break;
267 }
268 if(allowed && !item->getPermissions().allowCopyBy(gAgent.getID()))
269 { 192 {
270 // whoops, can't copy it - don't allow it. 193 // whoops, can't copy it - don't allow it.
271 allowed = FALSE; 194 allowed = false;
272 } 195 }
273 } 196 }
274 return (allowed ? true : false); 197 return allowed;
275} 198}
276 199
277class LLGiveable : public LLInventoryCollectFunctor 200class LLGiveable : public LLInventoryCollectFunctor
@@ -289,48 +212,26 @@ protected:
289bool LLGiveable::operator()(LLInventoryCategory* cat, LLInventoryItem* item) 212bool LLGiveable::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
290{ 213{
291 // All categories can be given. 214 // All categories can be given.
292 if(cat) return TRUE; 215 if (cat)
293 BOOL allowed = FALSE; 216 return true;
217
218 bool allowed = false;
294 if(item) 219 if(item)
295 { 220 {
296 LLVOAvatar* my_avatar = NULL; 221 allowed = itemTransferCommonlyAllowed(item);
297 switch(item->getType()) 222 if(allowed &&
298 { 223 !item->getPermissions().allowOperationBy(PERM_TRANSFER,
299 case LLAssetType::AT_CALLINGCARD: 224 gAgent.getID()))
300 // not allowed
301 break;
302
303 case LLAssetType::AT_OBJECT:
304 my_avatar = gAgent.getAvatarObject();
305 if(my_avatar && !my_avatar->isWearingAttachment(item->getUUID()))
306 {
307 allowed = TRUE;
308 }
309 break;
310
311 case LLAssetType::AT_BODYPART:
312 case LLAssetType::AT_CLOTHING:
313 if(!gAgent.isWearingItem(item->getUUID()))
314 {
315 allowed = TRUE;
316 }
317 break;
318
319 default:
320 allowed = TRUE;
321 break;
322 }
323 if(!item->getPermissions().allowOperationBy(PERM_TRANSFER,
324 gAgent.getID()))
325 { 225 {
326 allowed = FALSE; 226 allowed = FALSE;
327 } 227 }
328 if(allowed && !item->getPermissions().allowCopyBy(gAgent.getID())) 228 if(allowed &&
229 !item->getPermissions().allowCopyBy(gAgent.getID()))
329 { 230 {
330 ++mCountLosing; 231 ++mCountLosing;
331 } 232 }
332 } 233 }
333 return (allowed ? true : false); 234 return allowed;
334} 235}
335 236
336class LLCategoryFireAndForget : public LLInventoryFetchComboObserver 237class LLCategoryFireAndForget : public LLInventoryFetchComboObserver
@@ -569,8 +470,7 @@ LLToolDragAndDrop::dragOrDrop3dImpl LLToolDragAndDrop::sDragAndDrop3d[DAD_COUNT]
569}; 470};
570 471
571LLToolDragAndDrop::LLToolDragAndDrop() 472LLToolDragAndDrop::LLToolDragAndDrop()
572 : 473: LLTool(std::string("draganddrop"), NULL),
573 LLTool("draganddrop", NULL),
574 mDragStartX(0), 474 mDragStartX(0),
575 mDragStartY(0), 475 mDragStartY(0),
576 mSource(SOURCE_AGENT), 476 mSource(SOURCE_AGENT),
@@ -688,7 +588,7 @@ void LLToolDragAndDrop::beginMultiDrag(
688 mCursor = UI_CURSOR_NO; 588 mCursor = UI_CURSOR_NO;
689 if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY)) 589 if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY))
690 { 590 {
691 // find cats in the cargo. 591 // find categories (i.e. inventory folders) in the cargo.
692 LLInventoryCategory* cat = NULL; 592 LLInventoryCategory* cat = NULL;
693 S32 count = llmin(cargo_ids.size(), types.size()); 593 S32 count = llmin(cargo_ids.size(), types.size());
694 std::set<LLUUID> cat_ids; 594 std::set<LLUUID> cat_ids;
@@ -737,7 +637,7 @@ void LLToolDragAndDrop::endDrag()
737 637
738void LLToolDragAndDrop::onMouseCaptureLost() 638void LLToolDragAndDrop::onMouseCaptureLost()
739{ 639{
740 // Called whenever the drag ends or if mouse captue is simply lost 640 // Called whenever the drag ends or if mouse capture is simply lost
741 LLToolMgr::getInstance()->clearTransientTool(); 641 LLToolMgr::getInstance()->clearTransientTool();
742 mCargoTypes.clear(); 642 mCargoTypes.clear();
743 mCargoIDs.clear(); 643 mCargoIDs.clear();
@@ -757,11 +657,8 @@ BOOL LLToolDragAndDrop::handleMouseUp( S32 x, S32 y, MASK mask )
757 return TRUE; 657 return TRUE;
758} 658}
759 659
760BOOL LLToolDragAndDrop::handleHover( S32 x, S32 y, MASK mask ) 660ECursorType LLToolDragAndDrop::acceptanceToCursor( EAcceptance acceptance )
761{ 661{
762 EAcceptance acceptance = ACCEPT_NO;
763 dragOrDrop( x, y, mask, FALSE, &acceptance );
764
765 switch( acceptance ) 662 switch( acceptance )
766 { 663 {
767 case ACCEPT_YES_MULTI: 664 case ACCEPT_YES_MULTI:
@@ -774,8 +671,16 @@ BOOL LLToolDragAndDrop::handleHover( S32 x, S32 y, MASK mask )
774 mCursor = UI_CURSOR_ARROWDRAG; 671 mCursor = UI_CURSOR_ARROWDRAG;
775 } 672 }
776 break; 673 break;
777 case ACCEPT_YES_SINGLE: 674 case ACCEPT_YES_SINGLE:
778 mCursor = UI_CURSOR_ARROWDRAG; 675 if (mCargoIDs.size() > 1)
676 {
677 mToolTipMsg = LLTrans::getString("TooltipMustSingleDrop");
678 mCursor = UI_CURSOR_NO;
679 }
680 else
681 {
682 mCursor = UI_CURSOR_ARROWDRAG;
683 }
779 break; 684 break;
780 685
781 case ACCEPT_NO_LOCKED: 686 case ACCEPT_NO_LOCKED:
@@ -797,7 +702,15 @@ BOOL LLToolDragAndDrop::handleHover( S32 x, S32 y, MASK mask )
797 } 702 }
798 break; 703 break;
799 case ACCEPT_YES_COPY_SINGLE: 704 case ACCEPT_YES_COPY_SINGLE:
800 mCursor = UI_CURSOR_ARROWCOPY; 705 if (mCargoIDs.size() > 1)
706 {
707 mToolTipMsg = LLTrans::getString("TooltipMustSingleDrop");
708 mCursor = UI_CURSOR_NO;
709 }
710 else
711 {
712 mCursor = UI_CURSOR_ARROWCOPY;
713 }
801 break; 714 break;
802 case ACCEPT_POSTPONED: 715 case ACCEPT_POSTPONED:
803 break; 716 break;
@@ -805,7 +718,17 @@ BOOL LLToolDragAndDrop::handleHover( S32 x, S32 y, MASK mask )
805 llassert( FALSE ); 718 llassert( FALSE );
806 } 719 }
807 720
808 gViewerWindow->getWindow()->setCursor( mCursor ); 721 return mCursor;
722}
723
724BOOL LLToolDragAndDrop::handleHover( S32 x, S32 y, MASK mask )
725{
726 EAcceptance acceptance = ACCEPT_NO;
727 dragOrDrop( x, y, mask, FALSE, &acceptance );
728
729 ECursorType cursor = acceptanceToCursor(acceptance);
730 gViewerWindow->getWindow()->setCursor( cursor );
731
809 lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolDragAndDrop" << llendl; 732 lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolDragAndDrop" << llendl;
810 return TRUE; 733 return TRUE;
811} 734}
@@ -822,12 +745,12 @@ BOOL LLToolDragAndDrop::handleKey(KEY key, MASK mask)
822 return FALSE; 745 return FALSE;
823} 746}
824 747
825BOOL LLToolDragAndDrop::handleToolTip(S32 x, S32 y, LLString& msg, LLRect *sticky_rect_screen) 748BOOL LLToolDragAndDrop::handleToolTip(S32 x, S32 y, std::string& msg, LLRect *sticky_rect_screen)
826{ 749{
827 if (!mToolTipMsg.empty()) 750 if (!mToolTipMsg.empty())
828 { 751 {
829 msg = mToolTipMsg; 752 msg = mToolTipMsg;
830 //*stick_rect_screen = gViewerWindow->getWindowRect(); 753 //*sticky_rect_screen = gViewerWindow->getWindowRect();
831 return TRUE; 754 return TRUE;
832 } 755 }
833 return FALSE; 756 return FALSE;
@@ -846,11 +769,11 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
846 769
847 BOOL handled = FALSE; 770 BOOL handled = FALSE;
848 771
849 LLView* top_view = gViewerWindow->getTopCtrl(); 772 LLView* top_view = gFocusMgr.getTopCtrl();
850 LLViewerInventoryItem* item; 773 LLViewerInventoryItem* item;
851 LLViewerInventoryCategory* cat; 774 LLViewerInventoryCategory* cat;
852 775
853 mToolTipMsg.assign(""); 776 mToolTipMsg.clear();
854 777
855 if(top_view) 778 if(top_view)
856 { 779 {
@@ -885,17 +808,15 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
885 // all objects passed, go ahead and perform drop if necessary 808 // all objects passed, go ahead and perform drop if necessary
886 if (handled && drop && (U32)*acceptance >= ACCEPT_YES_COPY_SINGLE) 809 if (handled && drop && (U32)*acceptance >= ACCEPT_YES_COPY_SINGLE)
887 { 810 {
888 // drop all items 811 if ((U32)*acceptance < ACCEPT_YES_COPY_MULTI &&
889 if ((U32)*acceptance >= ACCEPT_YES_COPY_MULTI) 812 mCargoIDs.size() > 1)
890 { 813 {
891 mCurItemIndex = 0; 814 // tried to give multi-cargo to a single-acceptor - refuse and return.
892 } 815 *acceptance = ACCEPT_NO;
893 // drop just last item 816 return;
894 else
895 {
896 mCurItemIndex = mCargoIDs.size() - 1;
897 } 817 }
898 for (; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) 818
819 for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
899 { 820 {
900 LLInventoryObject* cargo = locateInventory(item, cat); 821 LLInventoryObject* cargo = locateInventory(item, cat);
901 822
@@ -950,30 +871,26 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
950 // all objects passed, go ahead and perform drop if necessary 871 // all objects passed, go ahead and perform drop if necessary
951 if (handled && drop && (U32)*acceptance > ACCEPT_NO_LOCKED) 872 if (handled && drop && (U32)*acceptance > ACCEPT_NO_LOCKED)
952 { 873 {
953 // drop all items 874 if ((U32)*acceptance < ACCEPT_YES_COPY_MULTI &&
954 if ((U32)*acceptance >= ACCEPT_YES_COPY_MULTI) 875 mCargoIDs.size() > 1)
955 { 876 {
956 mCurItemIndex = 0; 877 // tried to give multi-cargo to a single-acceptor - refuse and return.
957 } 878 *acceptance = ACCEPT_NO;
958 // drop just last item 879 return;
959 else
960 {
961 mCurItemIndex = mCargoIDs.size() - 1;
962 } 880 }
963 for (; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++) 881
882 for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
964 { 883 {
965 LLInventoryObject* cargo = locateInventory(item, cat); 884 LLInventoryObject* cargo = locateInventory(item, cat);
966 885
967 if (cargo) 886 if (cargo)
968 { 887 {
969 //S32 local_x, local_y;
970
971 EAcceptance item_acceptance; 888 EAcceptance item_acceptance;
972 handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE, 889 handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE,
973 mCargoTypes[mCurItemIndex], 890 mCargoTypes[mCurItemIndex],
974 (void*)cargo, 891 (void*)cargo,
975 &item_acceptance, 892 &item_acceptance,
976 mToolTipMsg); 893 mToolTipMsg);
977 } 894 }
978 } 895 }
979 } 896 }
@@ -995,32 +912,37 @@ void LLToolDragAndDrop::dragOrDrop3D( S32 x, S32 y, MASK mask, BOOL drop, EAccep
995 mDrop = drop; 912 mDrop = drop;
996 if (mDrop) 913 if (mDrop)
997 { 914 {
998 gPickFaces = TRUE;
999 // don't allow drag and drop onto transparent objects 915 // don't allow drag and drop onto transparent objects
1000 gViewerWindow->hitObjectOrLandGlobalImmediate(x, y, pickCallback, FALSE); 916 pickCallback(gViewerWindow->pickImmediate(x, y, FALSE));
1001 } 917 }
1002 else 918 else
1003 { 919 {
1004 // Don't pick faces during hover. Nothing currently requires per-face
1005 // data.
1006 // don't allow drag and drop onto transparent objects 920 // don't allow drag and drop onto transparent objects
1007 gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback, FALSE); 921 gViewerWindow->pickAsync(x, y, mask, pickCallback, FALSE);
1008 } 922 }
1009 923
1010 *acceptance = mLastAccept; 924 *acceptance = mLastAccept;
1011} 925}
1012 926
1013void LLToolDragAndDrop::pickCallback(S32 x, S32 y, MASK mask) 927void LLToolDragAndDrop::pickCallback(const LLPickInfo& pick_info)
1014{ 928{
1015 EDropTarget target = DT_NONE; 929 EDropTarget target = DT_NONE;
1016 S32 hit_face = -1; 930 S32 hit_face = -1;
1017 931
1018 LLViewerObject* hit_obj = gViewerWindow->lastNonFloraObjectHit(); 932 LLViewerObject* hit_obj = pick_info.getObject();
1019 LLSelectMgr::getInstance()->unhighlightAll(); 933 LLSelectMgr::getInstance()->unhighlightAll();
1020 934
1021 // Treat attachments as part of the avatar they are attached to. 935 // Treat attachments as part of the avatar they are attached to.
1022 if (hit_obj) 936 if (hit_obj)
1023 { 937 {
938 // don't allow drag and drop on grass, trees, etc.
939 if(pick_info.mPickType == LLPickInfo::PICK_FLORA)
940 {
941 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_NO;
942 gViewerWindow->getWindow()->setCursor( LLToolDragAndDrop::getInstance()->mCursor );
943 return;
944 }
945
1024 if(hit_obj->isAttachment() && !hit_obj->isHUDAttachment()) 946 if(hit_obj->isAttachment() && !hit_obj->isHUDAttachment())
1025 { 947 {
1026 LLVOAvatar* avatar = LLVOAvatar::findAvatarFromAttachment( hit_obj ); 948 LLVOAvatar* avatar = LLVOAvatar::findAvatarFromAttachment( hit_obj );
@@ -1051,12 +973,12 @@ void LLToolDragAndDrop::pickCallback(S32 x, S32 y, MASK mask)
1051 else 973 else
1052 { 974 {
1053 target = DT_OBJECT; 975 target = DT_OBJECT;
1054 hit_face = gLastHitNonFloraObjectFace; 976 hit_face = pick_info.mObjectFace;
1055 // if any item being dragged will be applied to the object under our cursor 977 // if any item being dragged will be applied to the object under our cursor
1056 // highlight that object 978 // highlight that object
1057 for (S32 i = 0; i < (S32)LLToolDragAndDrop::getInstance()->mCargoIDs.size(); i++) 979 for (S32 i = 0; i < (S32)LLToolDragAndDrop::getInstance()->mCargoIDs.size(); i++)
1058 { 980 {
1059 if (LLToolDragAndDrop::getInstance()->mCargoTypes[i] != DAD_OBJECT || (mask & MASK_CONTROL)) 981 if (LLToolDragAndDrop::getInstance()->mCargoTypes[i] != DAD_OBJECT || (pick_info.mKeyMask & MASK_CONTROL))
1060 { 982 {
1061 LLSelectMgr::getInstance()->highlightObjectAndFamily(hit_obj); 983 LLSelectMgr::getInstance()->highlightObjectAndFamily(hit_obj);
1062 break; 984 break;
@@ -1064,7 +986,7 @@ void LLToolDragAndDrop::pickCallback(S32 x, S32 y, MASK mask)
1064 } 986 }
1065 } 987 }
1066 } 988 }
1067 else if(gLastHitLand) 989 else if(pick_info.mPickType == LLPickInfo::PICK_LAND)
1068 { 990 {
1069 target = DT_LAND; 991 target = DT_LAND;
1070 hit_face = -1; 992 hit_face = -1;
@@ -1080,79 +1002,39 @@ void LLToolDragAndDrop::pickCallback(S32 x, S32 y, MASK mask)
1080 (U32)LLToolDragAndDrop::getInstance()->mLastAccept, 1002 (U32)LLToolDragAndDrop::getInstance()->mLastAccept,
1081 (U32)callMemberFunction((*LLToolDragAndDrop::getInstance()), 1003 (U32)callMemberFunction((*LLToolDragAndDrop::getInstance()),
1082 LLToolDragAndDrop::getInstance()->sDragAndDrop3d[LLToolDragAndDrop::getInstance()->mCargoTypes[LLToolDragAndDrop::getInstance()->mCurItemIndex]][target]) 1004 LLToolDragAndDrop::getInstance()->sDragAndDrop3d[LLToolDragAndDrop::getInstance()->mCargoTypes[LLToolDragAndDrop::getInstance()->mCurItemIndex]][target])
1083 (hit_obj, hit_face, mask, FALSE)); 1005 (hit_obj, hit_face, pick_info.mKeyMask, FALSE));
1084 } 1006 }
1085 1007
1086 if (LLToolDragAndDrop::getInstance()->mDrop && (U32)LLToolDragAndDrop::getInstance()->mLastAccept >= ACCEPT_YES_COPY_SINGLE) 1008 if (LLToolDragAndDrop::getInstance()->mDrop &&
1009 (U32)LLToolDragAndDrop::getInstance()->mLastAccept >= ACCEPT_YES_COPY_SINGLE)
1087 { 1010 {
1088 // if target allows multi-drop, go ahead and start iteration at beginning of cargo list 1011 // if target allows multi-drop or there is only one item being dropped, go ahead
1089 if (LLToolDragAndDrop::getInstance()->mLastAccept >= ACCEPT_YES_COPY_MULTI) 1012 if (LLToolDragAndDrop::getInstance()->mLastAccept >= ACCEPT_YES_COPY_MULTI ||
1013 LLToolDragAndDrop::getInstance()->mCargoIDs.size() == 1)
1090 { 1014 {
1091 LLToolDragAndDrop::getInstance()->mCurItemIndex = 0; 1015 // Target accepts multi, or cargo is a single-drop
1016 for (LLToolDragAndDrop::getInstance()->mCurItemIndex = 0;
1017 LLToolDragAndDrop::getInstance()->mCurItemIndex < (S32)LLToolDragAndDrop::getInstance()->mCargoIDs.size();
1018 LLToolDragAndDrop::getInstance()->mCurItemIndex++)
1019 {
1020 // Call the right implementation function
1021 (U32)callMemberFunction((*LLToolDragAndDrop::getInstance()),
1022 LLToolDragAndDrop::getInstance()->sDragAndDrop3d[LLToolDragAndDrop::getInstance()->mCargoTypes[LLToolDragAndDrop::getInstance()->mCurItemIndex]][target])
1023 (hit_obj, hit_face, pick_info.mKeyMask, TRUE);
1024 }
1092 } 1025 }
1093 // otherwise start at end, to follow selection rules (last selected item is most current)
1094 else 1026 else
1095 { 1027 {
1096 LLToolDragAndDrop::getInstance()->mCurItemIndex = LLToolDragAndDrop::getInstance()->mCargoIDs.size() - 1; 1028 // Target does not accept multi, but cargo is multi
1097 } 1029 LLToolDragAndDrop::getInstance()->mLastAccept = ACCEPT_NO;
1098
1099 for (; LLToolDragAndDrop::getInstance()->mCurItemIndex < (S32)LLToolDragAndDrop::getInstance()->mCargoIDs.size();
1100 LLToolDragAndDrop::getInstance()->mCurItemIndex++)
1101 {
1102 // Call the right implementation function
1103 (U32)callMemberFunction((*LLToolDragAndDrop::getInstance()),
1104 LLToolDragAndDrop::getInstance()->sDragAndDrop3d[LLToolDragAndDrop::getInstance()->mCargoTypes[LLToolDragAndDrop::getInstance()->mCurItemIndex]][target])
1105 (hit_obj, hit_face, mask, TRUE);
1106 } 1030 }
1107 } 1031 }
1108 1032
1109 switch( LLToolDragAndDrop::getInstance()->mLastAccept ) 1033 ECursorType cursor = LLToolDragAndDrop::getInstance()->acceptanceToCursor( LLToolDragAndDrop::getInstance()->mLastAccept );
1110 { 1034 gViewerWindow->getWindow()->setCursor( cursor );
1111 case ACCEPT_YES_MULTI:
1112 if (LLToolDragAndDrop::getInstance()->mCargoIDs.size() > 1)
1113 {
1114 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWDRAGMULTI;
1115 }
1116 else
1117 {
1118 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWDRAG;
1119 }
1120 break;
1121 case ACCEPT_YES_SINGLE:
1122 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWDRAG;
1123 break;
1124 1035
1125 case ACCEPT_NO_LOCKED: 1036 LLToolDragAndDrop::getInstance()->mLastHitPos = pick_info.mPosGlobal;
1126 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_NOLOCKED;
1127 break;
1128
1129 case ACCEPT_NO:
1130 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_NO;
1131 break;
1132
1133 case ACCEPT_YES_COPY_MULTI:
1134 if (LLToolDragAndDrop::getInstance()->mCargoIDs.size() > 1)
1135 {
1136 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWCOPYMULTI;
1137 }
1138 else
1139 {
1140 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWCOPY;
1141 }
1142 break;
1143 case ACCEPT_YES_COPY_SINGLE:
1144 LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWCOPY;
1145 break;
1146 case ACCEPT_POSTPONED:
1147 break;
1148 default:
1149 llassert( FALSE );
1150 }
1151
1152 LLToolDragAndDrop::getInstance()->mLastHitPos = gLastHitPosGlobal + gLastHitObjectOffset;
1153 LLToolDragAndDrop::getInstance()->mLastCameraPos = gAgent.getCameraPositionGlobal(); 1037 LLToolDragAndDrop::getInstance()->mLastCameraPos = gAgent.getCameraPositionGlobal();
1154
1155 gViewerWindow->getWindow()->setCursor( LLToolDragAndDrop::getInstance()->mCursor );
1156} 1038}
1157 1039
1158// static 1040// static
@@ -1175,7 +1057,7 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
1175 if (hit_obj->isInventoryDirty()) 1057 if (hit_obj->isInventoryDirty())
1176 { 1058 {
1177 hit_obj->fetchInventoryFromServer(); 1059 hit_obj->fetchInventoryFromServer();
1178 LLString::format_map_t args; 1060 LLStringUtil::format_map_t args;
1179 args["[ERROR_MESSAGE]"] = "Unable to add texture.\nPlease wait a few seconds and try again."; 1061 args["[ERROR_MESSAGE]"] = "Unable to add texture.\nPlease wait a few seconds and try again.";
1180 gViewerWindow->alertXml("ErrorMessage", args); 1062 gViewerWindow->alertXml("ErrorMessage", args);
1181 return FALSE; 1063 return FALSE;
@@ -1231,7 +1113,7 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
1231 else if(!item->getPermissions().allowOperationBy(PERM_TRANSFER, 1113 else if(!item->getPermissions().allowOperationBy(PERM_TRANSFER,
1232 gAgent.getID())) 1114 gAgent.getID()))
1233 { 1115 {
1234 // Check that we can add the testure as inventory to the object 1116 // Check that we can add the texture as inventory to the object
1235 if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE ) 1117 if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE )
1236 { 1118 {
1237 return FALSE; 1119 return FALSE;
@@ -1552,7 +1434,7 @@ void LLToolDragAndDrop::dropInventory(LLViewerObject* hit_obj,
1552 } 1434 }
1553 1435
1554 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); 1436 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
1555 S32 creation_date = time_corrected(); 1437 time_t creation_date = time_corrected();
1556 new_item->setCreationDate(creation_date); 1438 new_item->setCreationDate(creation_date);
1557 1439
1558 if(!item->getPermissions().allowCopyBy(gAgent.getID())) 1440 if(!item->getPermissions().allowCopyBy(gAgent.getID()))
@@ -1607,7 +1489,7 @@ struct LLGiveInventoryInfo
1607}; 1489};
1608 1490
1609void LLToolDragAndDrop::giveInventory(const LLUUID& to_agent, 1491void LLToolDragAndDrop::giveInventory(const LLUUID& to_agent,
1610 LLInventoryItem* item) 1492 LLInventoryItem* item)
1611{ 1493{
1612 llinfos << "LLToolDragAndDrop::giveInventory()" << llendl; 1494 llinfos << "LLToolDragAndDrop::giveInventory()" << llendl;
1613 if(!isInventoryGiveAcceptable(item)) 1495 if(!isInventoryGiveAcceptable(item))
@@ -1623,11 +1505,11 @@ void LLToolDragAndDrop::giveInventory(const LLUUID& to_agent,
1623 { 1505 {
1624 // ask if the agent is sure. 1506 // ask if the agent is sure.
1625 LLGiveInventoryInfo* info = new LLGiveInventoryInfo(to_agent, 1507 LLGiveInventoryInfo* info = new LLGiveInventoryInfo(to_agent,
1626 item->getUUID()); 1508 item->getUUID());
1627 1509
1628 gViewerWindow->alertXml("CannotCopyWarning", 1510 gViewerWindow->alertXml("CannotCopyWarning",
1629 &LLToolDragAndDrop::handleCopyProtectedItem, 1511 &LLToolDragAndDrop::handleCopyProtectedItem,
1630 (void*)info); 1512 (void*)info);
1631 } 1513 }
1632} 1514}
1633 1515
@@ -1680,8 +1562,8 @@ void LLToolDragAndDrop::commitGiveInventoryItem(const LLUUID& to_agent,
1680 FALSE, 1562 FALSE,
1681 gAgent.getSessionID(), 1563 gAgent.getSessionID(),
1682 to_agent, 1564 to_agent,
1683 name.c_str(), 1565 name,
1684 item->getName().c_str(), 1566 item->getName(),
1685 IM_ONLINE, 1567 IM_ONLINE,
1686 IM_INVENTORY_OFFERED, 1568 IM_INVENTORY_OFFERED,
1687 transaction_id, 1569 transaction_id,
@@ -1762,7 +1644,7 @@ void LLToolDragAndDrop::giveInventoryCategory(const LLUUID& to_agent,
1762 { 1644 {
1763 LLGiveInventoryInfo* info = NULL; 1645 LLGiveInventoryInfo* info = NULL;
1764 info = new LLGiveInventoryInfo(to_agent, cat->getUUID()); 1646 info = new LLGiveInventoryInfo(to_agent, cat->getUUID());
1765 LLStringBase<char>::format_map_t args; 1647 LLStringUtil::format_map_t args;
1766 args["[COUNT]"] = llformat("%d",giveable.countNoCopy()); 1648 args["[COUNT]"] = llformat("%d",giveable.countNoCopy());
1767 gViewerWindow->alertXml("CannotCopyCountItems", args, 1649 gViewerWindow->alertXml("CannotCopyCountItems", args,
1768 &LLToolDragAndDrop::handleCopyProtectedCategory, 1650 &LLToolDragAndDrop::handleCopyProtectedCategory,
@@ -1883,8 +1765,8 @@ void LLToolDragAndDrop::commitGiveInventoryCategory(const LLUUID& to_agent,
1883 FALSE, 1765 FALSE,
1884 gAgent.getSessionID(), 1766 gAgent.getSessionID(),
1885 to_agent, 1767 to_agent,
1886 name.c_str(), 1768 name,
1887 cat->getName().c_str(), 1769 cat->getName(),
1888 IM_ONLINE, 1770 IM_ONLINE,
1889 IM_INVENTORY_OFFERED, 1771 IM_INVENTORY_OFFERED,
1890 transaction_id, 1772 transaction_id,
@@ -1922,11 +1804,13 @@ BOOL LLToolDragAndDrop::isInventoryGiveAcceptable(LLInventoryItem* item)
1922 } 1804 }
1923 BOOL copyable = FALSE; 1805 BOOL copyable = FALSE;
1924 if(item->getPermissions().allowCopyBy(gAgent.getID())) copyable = TRUE; 1806 if(item->getPermissions().allowCopyBy(gAgent.getID())) copyable = TRUE;
1807
1925 LLVOAvatar* my_avatar = gAgent.getAvatarObject(); 1808 LLVOAvatar* my_avatar = gAgent.getAvatarObject();
1926 if(!my_avatar) 1809 if(!my_avatar)
1927 { 1810 {
1928 return FALSE; 1811 return FALSE;
1929 } 1812 }
1813
1930 BOOL acceptable = TRUE; 1814 BOOL acceptable = TRUE;
1931 switch(item->getType()) 1815 switch(item->getType())
1932 { 1816 {
@@ -2996,11 +2880,11 @@ LLInventoryObject* LLToolDragAndDrop::locateMultipleInventory(LLViewerInventoryC
2996} 2880}
2997*/ 2881*/
2998 2882
2999void LLToolDragAndDrop::createContainer(LLViewerInventoryItem::item_array_t &items, const char* preferred_name ) 2883// void LLToolDragAndDrop::createContainer(LLViewerInventoryItem::item_array_t &items, const char* preferred_name )
3000{ 2884// {
3001 llwarns << "LLToolDragAndDrop::createContainer()" << llendl; 2885// llwarns << "LLToolDragAndDrop::createContainer()" << llendl;
3002 return; 2886// return;
3003} 2887// }
3004 2888
3005 2889
3006// utility functions 2890// utility functions