diff options
Diffstat (limited to 'linden/indra/newview/lltooldraganddrop.cpp')
-rw-r--r-- | linden/indra/newview/lltooldraganddrop.cpp | 402 |
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. |
72 | const S32 MAX_ITEMS = 42; | 74 | const S32 MAX_ITEMS = 42; |
73 | const 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 | ||
129 | bool LLDroppableItem::operator()(LLInventoryCategory* cat, | 127 | bool 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 | ||
184 | bool LLUncopyableItems::operator()(LLInventoryCategory* cat, | 158 | bool 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 | ||
226 | class LLDropCopyableItems : public LLInventoryCollectFunctor | 173 | class LLDropCopyableItems : public LLInventoryCollectFunctor |
@@ -233,45 +180,21 @@ public: | |||
233 | 180 | ||
234 | 181 | ||
235 | bool LLDropCopyableItems::operator()( | 182 | bool 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 | ||
277 | class LLGiveable : public LLInventoryCollectFunctor | 200 | class LLGiveable : public LLInventoryCollectFunctor |
@@ -289,48 +212,26 @@ protected: | |||
289 | bool LLGiveable::operator()(LLInventoryCategory* cat, LLInventoryItem* item) | 212 | bool 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 | ||
336 | class LLCategoryFireAndForget : public LLInventoryFetchComboObserver | 237 | class LLCategoryFireAndForget : public LLInventoryFetchComboObserver |
@@ -569,8 +470,7 @@ LLToolDragAndDrop::dragOrDrop3dImpl LLToolDragAndDrop::sDragAndDrop3d[DAD_COUNT] | |||
569 | }; | 470 | }; |
570 | 471 | ||
571 | LLToolDragAndDrop::LLToolDragAndDrop() | 472 | LLToolDragAndDrop::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 | ||
738 | void LLToolDragAndDrop::onMouseCaptureLost() | 638 | void 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 | ||
760 | BOOL LLToolDragAndDrop::handleHover( S32 x, S32 y, MASK mask ) | 660 | ECursorType 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 | |||
724 | BOOL 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 | ||
825 | BOOL LLToolDragAndDrop::handleToolTip(S32 x, S32 y, LLString& msg, LLRect *sticky_rect_screen) | 748 | BOOL 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 | ||
1013 | void LLToolDragAndDrop::pickCallback(S32 x, S32 y, MASK mask) | 927 | void 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 | ||
1609 | void LLToolDragAndDrop::giveInventory(const LLUUID& to_agent, | 1491 | void 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 | ||
2999 | void 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 |