aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llpanelinventory.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llpanelinventory.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/llpanelinventory.cpp')
-rw-r--r--linden/indra/newview/llpanelinventory.cpp1976
1 files changed, 1976 insertions, 0 deletions
diff --git a/linden/indra/newview/llpanelinventory.cpp b/linden/indra/newview/llpanelinventory.cpp
new file mode 100644
index 0000000..bd32ad2
--- /dev/null
+++ b/linden/indra/newview/llpanelinventory.cpp
@@ -0,0 +1,1976 @@
1/**
2 * @file llpanelinventory.cpp
3 * @brief LLPanelInventory class implementation
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28//*****************************************************************************
29//
30// Implementation of the panel inventory - used to view and control a
31// task's inventory.
32//
33//*****************************************************************************
34
35#include "llviewerprecompiledheaders.h"
36
37#include <sstream> // for std::ostringstream
38#include <utility> // for std::pair<>
39
40#include "stdenums.h"
41#include "llpanelinventory.h"
42
43#include "message.h"
44#include "lldarray.h"
45#include "llfontgl.h"
46#include "llassetstorage.h"
47#include "llinventory.h"
48
49#include "llagent.h"
50#include "llcallbacklist.h"
51#include "llfocusmgr.h"
52#include "llfloaterbuycurrency.h"
53#include "llfloaterproperties.h"
54#include "llfolderview.h"
55#include "llgl.h"
56#include "llinventorymodel.h"
57#include "llinventoryview.h"
58#include "llmenugl.h"
59#include "llpreviewanim.h"
60#include "llpreviewgesture.h"
61#include "llpreviewnotecard.h"
62#include "llpreviewscript.h"
63#include "llpreviewsound.h"
64#include "llpreviewtexture.h"
65#include "roles_constants.h"
66#include "llscrollcontainer.h"
67#include "llselectmgr.h"
68#include "llstatusbar.h"
69#include "lltooldraganddrop.h"
70#include "llviewercontrol.h"
71#include "llviewerregion.h"
72#include "llviewerimagelist.h"
73#include "llviewerinventory.h"
74#include "llviewermessage.h"
75#include "llviewerobject.h"
76#include "llviewerobjectlist.h"
77#include "llviewerwindow.h"
78#include "llwearable.h"
79
80///----------------------------------------------------------------------------
81/// Local function declarations, constants, enums, and typedefs
82///----------------------------------------------------------------------------
83
84
85///----------------------------------------------------------------------------
86/// Class LLTaskInvFVBridge
87///----------------------------------------------------------------------------
88
89class LLTaskInvFVBridge : public LLFolderViewEventListener
90{
91protected:
92 LLUUID mUUID;
93 LLString mName;
94 mutable LLString mDisplayName;
95 LLPanelInventory* mPanel;
96
97 LLInventoryItem* findItem() const;
98
99public:
100 LLTaskInvFVBridge(
101 LLPanelInventory* panel,
102 const LLUUID& uuid,
103 const LLString& name);
104 virtual ~LLTaskInvFVBridge( void ) {}
105
106 virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
107 virtual LLString getLabelSuffix() const { return LLString::null; }
108
109 static LLTaskInvFVBridge* createObjectBridge(LLPanelInventory* panel,
110 LLInventoryObject* object);
111 void showProperties();
112 void buyItem();
113 S32 getPrice();
114 static void commitBuyItem(S32 option, void* data);
115
116 // LLFolderViewEventListener functionality
117 virtual const LLString& getName() const;
118 virtual const LLString& getDisplayName() const;
119 virtual PermissionMask getPermissionMask() const { return PERM_NONE; }
120 virtual const LLUUID& getUUID() const { return mUUID; }
121 virtual U32 getCreationDate() const;
122 virtual LLViewerImage* getIcon() const;
123 virtual void openItem();
124 virtual void previewItem();
125 virtual void selectItem() {}
126 virtual BOOL isItemRenameable() const;
127 virtual BOOL renameItem(const LLString& new_name);
128 virtual BOOL isItemMovable();
129 virtual BOOL isItemRemovable();
130 virtual BOOL removeItem();
131 virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
132 virtual void move(LLFolderViewEventListener* parent_listener);
133 virtual BOOL isItemCopyable() const;
134 virtual BOOL copyToClipboard() const;
135 virtual void cutToClipboard();
136 virtual BOOL isClipboardPasteable() const;
137 virtual void pasteFromClipboard();
138 virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
139 virtual void performAction(LLFolderView* folder, LLInventoryModel* model, LLString action);
140 virtual BOOL isUpToDate() const { return TRUE; }
141 virtual BOOL hasChildren() const { return FALSE; }
142 virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
143 // LLDragAndDropBridge functionality
144 virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id);
145 virtual BOOL dragOrDrop(MASK mask, BOOL drop,
146 EDragAndDropType cargo_type,
147 void* cargo_data);
148// virtual void dropped();
149
150};
151
152LLTaskInvFVBridge::LLTaskInvFVBridge(
153 LLPanelInventory* panel,
154 const LLUUID& uuid,
155 const LLString& name):
156 mUUID(uuid),
157 mName(name),
158 mPanel(panel)
159{
160}
161
162LLInventoryItem* LLTaskInvFVBridge::findItem() const
163{
164 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
165 if(object)
166 {
167 return (LLInventoryItem*)(object->getInventoryObject(mUUID));
168 }
169 return NULL;
170}
171
172void LLTaskInvFVBridge::showProperties()
173{
174 if(!LLFloaterProperties::show(mUUID, mPanel->getTaskUUID()))
175 {
176 S32 left, top;
177 gFloaterView->getNewFloaterPosition(&left, &top);
178 LLRect rect = gSavedSettings.getRect("PropertiesRect");
179 rect.translate( left - rect.mLeft, top - rect.mTop );
180 LLFloaterProperties* floater = new LLFloaterProperties("obj item properties",
181 rect,
182 "Object Inventory Item Properties",
183 mUUID,
184 mPanel->getTaskUUID());
185 floater->open();
186 }
187}
188
189struct LLBuyInvItemData
190{
191 LLUUID mTaskID;
192 LLUUID mItemID;
193 LLAssetType::EType mType;
194
195 LLBuyInvItemData(const LLUUID& task,
196 const LLUUID& item,
197 LLAssetType::EType type) :
198 mTaskID(task), mItemID(item), mType(type)
199 {}
200};
201
202void LLTaskInvFVBridge::buyItem()
203{
204 llinfos << "LLTaskInvFVBridge::buyItem()" << llendl;
205 LLInventoryItem* item = findItem();
206 if(!item || !item->getSaleInfo().isForSale()) return;
207 LLBuyInvItemData* inv = new LLBuyInvItemData(mPanel->getTaskUUID(),
208 mUUID,
209 item->getType());
210
211 const LLSaleInfo& sale_info = item->getSaleInfo();
212 const LLPermissions& perm = item->getPermissions();
213 const LLString owner_name; // no owner name currently... FIXME?
214
215 LLString::format_map_t args;
216 args["[PRICE]"] = llformat("%d",sale_info.getSalePrice());
217 args["[OWNER]"] = owner_name;
218 if (sale_info.getSaleType() != LLSaleInfo::FS_CONTENTS)
219 {
220 U32 next_owner_mask = perm.getMaskNextOwner();
221 args["[MODIFYPERM]"] = LLAlertDialog::getTemplateMessage((next_owner_mask & PERM_MODIFY) ? "PermYes" : "PermNo");
222 args["[COPYPERM]"] = LLAlertDialog::getTemplateMessage((next_owner_mask & PERM_COPY) ? "PermYes" : "PermNo");
223 args["[RESELLPERM]"] = LLAlertDialog::getTemplateMessage((next_owner_mask & PERM_TRANSFER) ? "PermYes" : "PermNo");
224 }
225
226 LLString alertdesc;
227 switch(sale_info.getSaleType())
228 {
229 case LLSaleInfo::FS_ORIGINAL:
230 alertdesc = owner_name.empty() ? "BuyOriginalNoOwner" : "BuyOriginal";
231 break;
232 case LLSaleInfo::FS_COPY:
233 default:
234 alertdesc = owner_name.empty() ? "BuyCopyNoOwner" : "BuyCopy";
235 break;
236 case LLSaleInfo::FS_CONTENTS:
237 alertdesc = owner_name.empty() ? "BuyContentsNoOwner" : "BuyContents";
238 break;
239 }
240
241 gViewerWindow->alertXml(alertdesc, args, LLTaskInvFVBridge::commitBuyItem, (void*)inv);
242}
243
244S32 LLTaskInvFVBridge::getPrice()
245{
246 LLInventoryItem* item = findItem();
247 if(item)
248 {
249 return item->getSaleInfo().getSalePrice();
250 }
251 else
252 {
253 return -1;
254 }
255}
256
257// static
258void LLTaskInvFVBridge::commitBuyItem(S32 option, void* data)
259{
260 LLBuyInvItemData* inv = (LLBuyInvItemData*)data;
261 if(!inv) return;
262 if(0 == option)
263 {
264 LLViewerObject* object = gObjectList.findObject(inv->mTaskID);
265 if(!object || !object->getRegion()) return;
266
267
268 LLMessageSystem* msg = gMessageSystem;
269 msg->newMessageFast(_PREHASH_BuyObjectInventory);
270 msg->nextBlockFast(_PREHASH_AgentData);
271 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
272 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
273 msg->nextBlockFast(_PREHASH_Data);
274 msg->addUUIDFast(_PREHASH_ObjectID, inv->mTaskID);
275 msg->addUUIDFast(_PREHASH_ItemID, inv->mItemID);
276 msg->addUUIDFast(_PREHASH_FolderID,
277 gInventory.findCategoryUUIDForType(inv->mType));
278 msg->sendReliable(object->getRegion()->getHost());
279 }
280 delete inv;
281}
282
283const LLString& LLTaskInvFVBridge::getName() const
284{
285 return mName;
286}
287
288const LLString& LLTaskInvFVBridge::getDisplayName() const
289{
290 LLInventoryItem* item = findItem();
291 if(item)
292 {
293 mDisplayName.assign(item->getName());
294
295 const LLPermissions& perm(item->getPermissions());
296 BOOL copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE);
297 BOOL mod = gAgent.allowOperation(PERM_MODIFY, perm, GP_OBJECT_MANIPULATE);
298 BOOL xfer = gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE);
299
300 if(!copy)
301 {
302 mDisplayName.append(" (no copy)");
303 }
304 if(!mod)
305 {
306 mDisplayName.append(" (no modify)");
307 }
308 if(!xfer)
309 {
310 mDisplayName.append(" (no transfer)");
311 }
312 }
313
314 return mDisplayName;
315}
316
317// BUG: No creation dates for task inventory
318U32 LLTaskInvFVBridge::getCreationDate() const
319{
320 return 0;
321}
322
323LLViewerImage* LLTaskInvFVBridge::getIcon() const
324{
325 return get_item_icon(LLAssetType::AT_OBJECT, LLInventoryType::IT_OBJECT, 0);
326}
327
328void LLTaskInvFVBridge::openItem()
329{
330 // no-op.
331 lldebugs << "LLTaskInvFVBridge::openItem()" << llendl;
332}
333
334void LLTaskInvFVBridge::previewItem()
335{
336 openItem();
337}
338
339BOOL LLTaskInvFVBridge::isItemRenameable() const
340{
341 if(gAgent.isGodlike()) return TRUE;
342 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
343 if(object)
344 {
345 LLInventoryItem* item;
346 item = (LLInventoryItem*)(object->getInventoryObject(mUUID));
347 if(item && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
348 GP_OBJECT_MANIPULATE, GOD_LIKE))
349 {
350 return TRUE;
351 }
352 }
353 return FALSE;
354}
355
356BOOL LLTaskInvFVBridge::renameItem(const LLString& new_name)
357{
358 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
359 if(object)
360 {
361 LLViewerInventoryItem* item = NULL;
362 item = (LLViewerInventoryItem*)object->getInventoryObject(mUUID);
363 if(item && (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
364 GP_OBJECT_MANIPULATE, GOD_LIKE)))
365 {
366 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
367 new_item->rename(new_name);
368 object->updateInventory(
369 new_item,
370 TASK_INVENTORY_ITEM_KEY,
371 false);
372 }
373 }
374 return TRUE;
375}
376
377BOOL LLTaskInvFVBridge::isItemMovable()
378{
379 //LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
380 //if(object && (object->permModify() || gAgent.isGodlike()))
381 //{
382 // return TRUE;
383 //}
384 //return FALSE;
385 return TRUE;
386}
387
388BOOL LLTaskInvFVBridge::isItemRemovable()
389{
390 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
391 if(object
392 && (object->permModify() || object->permYouOwner()))
393 {
394 return TRUE;
395 }
396 return FALSE;
397}
398
399// helper for remove
400typedef std::pair<LLUUID, std::list<LLUUID> > two_uuids_list_t;
401typedef std::pair<LLPanelInventory*, two_uuids_list_t> remove_data_t;
402
403void remove_task_inventory_callback(S32 option, void* user_data)
404{
405 remove_data_t* data = (remove_data_t*)user_data;
406 LLViewerObject* object = NULL;
407 object = gObjectList.findObject(data->second.first);
408 if(option == 0 && object)
409 {
410 // yes
411 std::list<LLUUID>::iterator list_it;
412 std::list<LLUUID>& id_list = data->second.second;
413 for (list_it = id_list.begin(); list_it != id_list.end(); ++list_it)
414 {
415 object->removeInventory(*list_it);
416 }
417
418 // refresh the UI.
419 data->first->refresh();
420 }
421 delete data;
422}
423
424BOOL LLTaskInvFVBridge::removeItem()
425{
426 if(isItemRemovable() && mPanel)
427 {
428 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
429 if(object)
430 {
431 if(object->permModify())
432 {
433 // just do it.
434 object->removeInventory(mUUID);
435 return TRUE;
436 }
437 else
438 {
439 remove_data_t* data = new remove_data_t;
440 data->first = mPanel;
441 data->second.first = mPanel->getTaskUUID();
442 data->second.second.push_back(mUUID);
443 gViewerWindow->alertXml("RemoveItemWarn", remove_task_inventory_callback, (void*)data);
444 return FALSE;
445 }
446 }
447 }
448 return FALSE;
449}
450
451void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
452{
453 if (!mPanel)
454 {
455 return;
456 }
457
458 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
459 if (!object)
460 {
461 return;
462 }
463
464 if (!object->permModify())
465 {
466 remove_data_t* data = new remove_data_t;
467 data->first = mPanel;
468 data->second.first = mPanel->getTaskUUID();
469 for (S32 i = 0; i < (S32)batch.size(); i++)
470 {
471 LLTaskInvFVBridge* itemp = (LLTaskInvFVBridge*)batch[i];
472 data->second.second.push_back(itemp->getUUID());
473 }
474 gViewerWindow->alertXml("RemoveItemWarn", remove_task_inventory_callback, (void*)data);
475 }
476 else
477 {
478 for (S32 i = 0; i < (S32)batch.size(); i++)
479 {
480 LLTaskInvFVBridge* itemp = (LLTaskInvFVBridge*)batch[i];
481
482 if(itemp->isItemRemovable())
483 {
484 // just do it.
485 object->removeInventory(itemp->getUUID());
486 }
487 }
488 }
489}
490
491void LLTaskInvFVBridge::move(LLFolderViewEventListener* parent_listener)
492{
493}
494
495BOOL LLTaskInvFVBridge::isItemCopyable() const
496{
497 LLInventoryItem* item = findItem();
498 if(!item) return FALSE;
499 return gAgent.allowOperation(PERM_COPY, item->getPermissions(),
500 GP_OBJECT_MANIPULATE);
501}
502
503BOOL LLTaskInvFVBridge::copyToClipboard() const
504{
505 return FALSE;
506}
507
508void LLTaskInvFVBridge::cutToClipboard()
509{
510}
511
512BOOL LLTaskInvFVBridge::isClipboardPasteable() const
513{
514 return FALSE;
515}
516
517void LLTaskInvFVBridge::pasteFromClipboard()
518{
519}
520
521BOOL LLTaskInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id)
522{
523 //llinfos << "LLTaskInvFVBridge::startDrag()" << llendl;
524 if(mPanel)
525 {
526 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
527 if(object)
528 {
529 LLInventoryItem* inv = NULL;
530 if((inv = (LLInventoryItem*)object->getInventoryObject(mUUID)))
531 {
532 const LLPermissions& perm = inv->getPermissions();
533 bool can_copy = gAgent.allowOperation(PERM_COPY, perm,
534 GP_OBJECT_MANIPULATE);
535 if (object->isAttachment() && !can_copy)
536 {
537 //RN: no copy contents of attachments cannot be dragged out
538 // due to a race condition and possible exploit where
539 // attached objects do not update their inventory items
540 // when their contents are manipulated
541 return FALSE;
542 }
543 if((can_copy && perm.allowTransferTo(gAgent.getID()))
544 || object->permYouOwner())
545// || gAgent.isGodlike())
546
547 {
548 *type = LLAssetType::lookupDragAndDropType(inv->getType());
549
550 *id = inv->getUUID();
551 return TRUE;
552 }
553 }
554 }
555 }
556 return FALSE;
557}
558
559BOOL LLTaskInvFVBridge::dragOrDrop(MASK mask, BOOL drop,
560 EDragAndDropType cargo_type,
561 void* cargo_data)
562{
563 //llinfos << "LLTaskInvFVBridge::dragOrDrop()" << llendl;
564 return FALSE;
565}
566
567//void LLTaskInvFVBridge::dropped()
568//{
569// llwarns << "LLTaskInvFVBridge::dropped() - not implemented" << llendl;
570//}
571
572// virtual
573void LLTaskInvFVBridge::performAction(LLFolderView* folder, LLInventoryModel* model, LLString action)
574{
575 if (action == "task_buy")
576 {
577 // Check the price of the item.
578 S32 price = getPrice();
579 if (-1 == price)
580 {
581 llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
582 }
583 else
584 {
585 if (price > gStatusBar->getBalance())
586 {
587 LLFloaterBuyCurrency::buyCurrency("This costs", price);
588 }
589 else
590 {
591 buyItem();
592 }
593 }
594 }
595 else if (action == "task_open")
596 {
597 openItem();
598 }
599 else if (action == "task_properties")
600 {
601 showProperties();
602 }
603}
604
605void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
606{
607 LLInventoryItem* item = findItem();
608 if(!item) return;
609 std::vector<LLString> items;
610 std::vector<LLString> disabled_items;
611
612 if(gAgent.allowOperation(PERM_OWNER, item->getPermissions(),
613 GP_OBJECT_MANIPULATE)
614 && item->getSaleInfo().isForSale())
615 {
616 items.push_back("Task Buy");
617
618 LLString label("Buy");
619 // Check the price of the item.
620 S32 price = getPrice();
621 if (-1 == price)
622 {
623 llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
624 }
625 else
626 {
627 std::ostringstream info;
628 info << "Buy for L$" << price;
629 label.assign(info.str());
630 }
631
632 const LLView::child_list_t *list = menu.getChildList();
633 LLView::child_list_t::const_iterator itor;
634 for (itor = list->begin(); itor != list->end(); ++itor)
635 {
636 LLString name = (*itor)->getName();
637 if (name == "Task Buy" && (*itor)->getWidgetTag() == LL_MENU_ITEM_CALL_GL_TAG)
638 {
639 ((LLMenuItemCallGL*)(*itor))->setLabel(label);
640 }
641 }
642 }
643 else
644 {
645 items.push_back("Task Open");
646 if (!isItemCopyable())
647 {
648 disabled_items.push_back("Task Open");
649 }
650 }
651 items.push_back("Task Properties");
652 if(isItemRenameable())
653 {
654 items.push_back("Task Rename");
655 }
656 if(isItemRemovable())
657 {
658 items.push_back("Task Remove");
659 }
660
661 hideContextEntries(menu, items, disabled_items);
662}
663
664
665///----------------------------------------------------------------------------
666/// Class LLTaskFolderBridge
667///----------------------------------------------------------------------------
668
669class LLTaskCategoryBridge : public LLTaskInvFVBridge
670{
671public:
672 LLTaskCategoryBridge(
673 LLPanelInventory* panel,
674 const LLUUID& uuid,
675 const LLString& name);
676
677 virtual LLViewerImage* getIcon() const;
678 virtual const LLString& getDisplayName() const { return getName(); }
679 virtual BOOL isItemRenameable() const;
680 virtual BOOL renameItem(const LLString& new_name);
681 virtual BOOL isItemRemovable();
682 virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
683 virtual BOOL hasChildren() const;
684 virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id);
685 virtual BOOL dragOrDrop(MASK mask, BOOL drop,
686 EDragAndDropType cargo_type,
687 void* cargo_data);
688};
689
690LLTaskCategoryBridge::LLTaskCategoryBridge(
691 LLPanelInventory* panel,
692 const LLUUID& uuid,
693 const LLString& name) :
694 LLTaskInvFVBridge(panel, uuid, name)
695{
696}
697
698LLViewerImage* LLTaskCategoryBridge::getIcon() const
699{
700 LLString uuid_string = gViewerArt.getString("inv_folder_plain_closed.tga");
701 return gImageList.getImage(LLUUID(uuid_string), MIPMAP_FALSE, TRUE);
702}
703
704BOOL LLTaskCategoryBridge::isItemRenameable() const
705{
706 return FALSE;
707}
708
709BOOL LLTaskCategoryBridge::renameItem(const LLString& new_name)
710{
711 return FALSE;
712}
713
714BOOL LLTaskCategoryBridge::isItemRemovable()
715{
716 return FALSE;
717}
718
719void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
720{
721 std::vector<LLString> items;
722 std::vector<LLString> disabled_items;
723 items.push_back("Task Open");
724 hideContextEntries(menu, items, disabled_items);
725}
726
727BOOL LLTaskCategoryBridge::hasChildren() const
728{
729 // return TRUE if we have or do know know if we have children.
730 // *FIX: For now, return FALSE - we will know for sure soon enough.
731 return FALSE;
732}
733
734BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id)
735{
736 //llinfos << "LLTaskInvFVBridge::startDrag()" << llendl;
737 if(mPanel)
738 {
739 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
740 if(object)
741 {
742 LLInventoryItem* inv = NULL;
743 if((inv = (LLInventoryItem*)object->getInventoryObject(mUUID)))
744 {
745 const LLPermissions& perm = inv->getPermissions();
746 bool can_copy = gAgent.allowOperation(PERM_COPY, perm,
747 GP_OBJECT_MANIPULATE);
748 if((can_copy && perm.allowTransferTo(gAgent.getID()))
749 || object->permYouOwner())
750// || gAgent.isGodlike())
751
752 {
753 *type = LLAssetType::lookupDragAndDropType(inv->getType());
754
755 *id = inv->getUUID();
756 return TRUE;
757 }
758 }
759 }
760 }
761 return FALSE;
762}
763
764BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop,
765 EDragAndDropType cargo_type,
766 void* cargo_data)
767{
768 //llinfos << "LLTaskCategoryBridge::dragOrDrop()" << llendl;
769 BOOL accept = FALSE;
770 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
771 if(object)
772 {
773 switch(cargo_type)
774 {
775 case DAD_CATEGORY:
776 accept = gToolDragAndDrop->dadUpdateInventoryCategory(object,drop);
777 break;
778 case DAD_TEXTURE:
779 case DAD_SOUND:
780 case DAD_LANDMARK:
781 case DAD_OBJECT:
782 case DAD_NOTECARD:
783 case DAD_CLOTHING:
784 case DAD_BODYPART:
785 case DAD_ANIMATION:
786 case DAD_GESTURE:
787 // *HACK: In order to resolve SL-22177, we need to block
788 // drags from notecards and objects onto other
789 // objects. uncomment the simpler version when we have
790 // that right.
791 //accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
792 if(LLToolDragAndDrop::isInventoryDropAcceptable(
793 object, (LLViewerInventoryItem*)cargo_data)
794 && (LLToolDragAndDrop::SOURCE_WORLD != gToolDragAndDrop->getSource())
795 && (LLToolDragAndDrop::SOURCE_NOTECARD != gToolDragAndDrop->getSource()))
796 {
797 accept = TRUE;
798 }
799 if(accept && drop)
800 {
801 LLToolDragAndDrop::dropInventory(object,
802 (LLViewerInventoryItem*)cargo_data,
803 gToolDragAndDrop->getSource(),
804 gToolDragAndDrop->getSourceID());
805 }
806 break;
807 case DAD_SCRIPT:
808 // *HACK: In order to resolve SL-22177, we need to block
809 // drags from notecards and objects onto other
810 // objects. uncomment the simpler version when we have
811 // that right.
812 //accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
813 if(LLToolDragAndDrop::isInventoryDropAcceptable(
814 object, (LLViewerInventoryItem*)cargo_data)
815 && (LLToolDragAndDrop::SOURCE_WORLD != gToolDragAndDrop->getSource())
816 && (LLToolDragAndDrop::SOURCE_NOTECARD != gToolDragAndDrop->getSource()))
817 {
818 accept = TRUE;
819 }
820 if(accept && drop)
821 {
822 LLViewerInventoryItem* item = (LLViewerInventoryItem*)cargo_data;
823 // rez in the script active by default, rez in
824 // inactive if the control key is being held down.
825 BOOL active = ((mask & MASK_CONTROL) == 0);
826 LLToolDragAndDrop::dropScript(object, item, active,
827 gToolDragAndDrop->getSource(),
828 gToolDragAndDrop->getSourceID());
829 }
830 break;
831 case DAD_CALLINGCARD:
832 default:
833 break;
834 }
835 }
836 return accept;
837}
838
839///----------------------------------------------------------------------------
840/// Class LLTaskTextureBridge
841///----------------------------------------------------------------------------
842
843class LLTaskTextureBridge : public LLTaskInvFVBridge
844{
845public:
846 LLTaskTextureBridge(
847 LLPanelInventory* panel,
848 const LLUUID& uuid,
849 const LLString& name,
850 LLInventoryType::EType it);
851
852 virtual LLViewerImage* getIcon() const;
853 virtual void openItem();
854protected:
855 LLInventoryType::EType mInventoryType;
856};
857
858LLTaskTextureBridge::LLTaskTextureBridge(
859 LLPanelInventory* panel,
860 const LLUUID& uuid,
861 const LLString& name,
862 LLInventoryType::EType it) :
863 LLTaskInvFVBridge(panel, uuid, name),
864 mInventoryType(it)
865{
866}
867
868LLViewerImage* LLTaskTextureBridge::getIcon() const
869{
870 return get_item_icon(LLAssetType::AT_TEXTURE, mInventoryType, 0);
871}
872
873void LLTaskTextureBridge::openItem()
874{
875 llinfos << "LLTaskTextureBridge::openItem()" << llendl;
876 if(!LLPreview::show(mUUID))
877 {
878 // There isn't one, so make a new preview
879 S32 left, top;
880 gFloaterView->getNewFloaterPosition(&left, &top);
881 LLRect rect = gSavedSettings.getRect("PreviewTextureRect");
882 rect.translate( left - rect.mLeft, top - rect.mTop );
883 LLPreviewTexture* preview = new LLPreviewTexture("preview task texture",
884 rect,
885 getName(),
886 mUUID,
887 mPanel->getTaskUUID());
888 preview->setFocus(TRUE);
889 }
890}
891
892
893///----------------------------------------------------------------------------
894/// Class LLTaskSoundBridge
895///----------------------------------------------------------------------------
896
897class LLTaskSoundBridge : public LLTaskInvFVBridge
898{
899public:
900 LLTaskSoundBridge(
901 LLPanelInventory* panel,
902 const LLUUID& uuid,
903 const LLString& name);
904
905 virtual LLViewerImage* getIcon() const;
906 virtual void openItem();
907 virtual void performAction(LLFolderView* folder, LLInventoryModel* model, LLString action);
908 virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
909 static void openSoundPreview(void* data);
910};
911
912LLTaskSoundBridge::LLTaskSoundBridge(
913 LLPanelInventory* panel,
914 const LLUUID& uuid,
915 const LLString& name) :
916 LLTaskInvFVBridge(panel, uuid, name)
917{
918}
919
920LLViewerImage* LLTaskSoundBridge::getIcon() const
921{
922 return get_item_icon(LLAssetType::AT_SOUND, LLInventoryType::IT_SOUND, 0);
923}
924
925void LLTaskSoundBridge::openItem()
926{
927 openSoundPreview((void*)this);
928}
929
930void LLTaskSoundBridge::openSoundPreview(void* data)
931{
932 LLTaskSoundBridge* self = (LLTaskSoundBridge*)data;
933 if(!self) return;
934 if(!LLPreview::show(self->mUUID))
935 {
936 // There isn't one, so make a new preview
937 S32 left, top;
938 gFloaterView->getNewFloaterPosition(&left, &top);
939 LLRect rect = gSavedSettings.getRect("PreviewSoundRect");
940 rect.translate(left - rect.mLeft, top - rect.mTop);
941 LLPreviewSound* floaterp = new LLPreviewSound("preview task sound",
942 rect,
943 self->getName(),
944 self->mUUID,
945 self->mPanel->getTaskUUID());
946 floaterp->open();
947 }
948}
949
950// virtual
951void LLTaskSoundBridge::performAction(LLFolderView* folder, LLInventoryModel* model, LLString action)
952{
953 if (action == "task_play")
954 {
955 LLInventoryItem* item = findItem();
956 if(item)
957 {
958 send_sound_trigger(item->getAssetUUID(), 1.0);
959 }
960 }
961 LLTaskInvFVBridge::performAction(folder, model, action);
962}
963
964void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
965{
966 LLInventoryItem* item = findItem();
967 if(!item) return;
968 std::vector<LLString> items;
969 std::vector<LLString> disabled_items;
970
971 if(item->getPermissions().getOwner() != gAgent.getID()
972 && item->getSaleInfo().isForSale())
973 {
974 items.push_back("Task Buy");
975
976 LLString label("Buy");
977 // Check the price of the item.
978 S32 price = getPrice();
979 if (-1 == price)
980 {
981 llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
982 }
983 else
984 {
985 std::ostringstream info;
986 info << "Buy for L$" << price;
987 label.assign(info.str());
988 }
989
990 const LLView::child_list_t *list = menu.getChildList();
991 LLView::child_list_t::const_iterator itor;
992 for (itor = list->begin(); itor != list->end(); ++itor)
993 {
994 LLString name = (*itor)->getName();
995 if (name == "Task Buy" && (*itor)->getWidgetTag() == LL_MENU_ITEM_CALL_GL_TAG)
996 {
997 ((LLMenuItemCallGL*)(*itor))->setLabel(label);
998 }
999 }
1000 }
1001 else
1002 {
1003 items.push_back("Task Open");
1004 if (!isItemCopyable())
1005 {
1006 disabled_items.push_back("Task Open");
1007 }
1008 }
1009 items.push_back("Task Properties");
1010 if(isItemRenameable())
1011 {
1012 items.push_back("Task Rename");
1013 }
1014 if(isItemRemovable())
1015 {
1016 items.push_back("Task Remove");
1017 }
1018
1019 items.push_back("Task Play");
1020 /*menu.appendSeparator();
1021 menu.append(new LLMenuItemCallGL("Play",
1022 &LLTaskSoundBridge::playSound,
1023 NULL,
1024 (void*)this));*/
1025
1026 hideContextEntries(menu, items, disabled_items);
1027}
1028
1029///----------------------------------------------------------------------------
1030/// Class LLTaskLandmarkBridge
1031///----------------------------------------------------------------------------
1032
1033class LLTaskLandmarkBridge : public LLTaskInvFVBridge
1034{
1035public:
1036 LLTaskLandmarkBridge(
1037 LLPanelInventory* panel,
1038 const LLUUID& uuid,
1039 const LLString& name);
1040
1041 virtual LLViewerImage* getIcon() const;
1042};
1043
1044LLTaskLandmarkBridge::LLTaskLandmarkBridge(
1045 LLPanelInventory* panel,
1046 const LLUUID& uuid,
1047 const LLString& name) :
1048 LLTaskInvFVBridge(panel, uuid, name)
1049{
1050}
1051
1052LLViewerImage* LLTaskLandmarkBridge::getIcon() const
1053{
1054 return get_item_icon(LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, 0);
1055}
1056
1057
1058///----------------------------------------------------------------------------
1059/// Class LLTaskCallingCardBridge
1060///----------------------------------------------------------------------------
1061
1062class LLTaskCallingCardBridge : public LLTaskInvFVBridge
1063{
1064public:
1065 LLTaskCallingCardBridge(
1066 LLPanelInventory* panel,
1067 const LLUUID& uuid,
1068 const LLString& name);
1069
1070 virtual LLViewerImage* getIcon() const;
1071 virtual BOOL isItemRenameable() const;
1072 virtual BOOL renameItem(const LLString& new_name);
1073};
1074
1075LLTaskCallingCardBridge::LLTaskCallingCardBridge(
1076 LLPanelInventory* panel,
1077 const LLUUID& uuid,
1078 const LLString& name) :
1079 LLTaskInvFVBridge(panel, uuid, name)
1080{
1081}
1082
1083LLViewerImage* LLTaskCallingCardBridge::getIcon() const
1084{
1085 return get_item_icon(LLAssetType::AT_CALLINGCARD, LLInventoryType::IT_CALLINGCARD, 0);
1086}
1087
1088BOOL LLTaskCallingCardBridge::isItemRenameable() const
1089{
1090 return FALSE;
1091}
1092
1093BOOL LLTaskCallingCardBridge::renameItem(const LLString& new_name)
1094{
1095 return FALSE;
1096}
1097
1098
1099///----------------------------------------------------------------------------
1100/// Class LLTaskScriptBridge
1101///----------------------------------------------------------------------------
1102
1103class LLTaskScriptBridge : public LLTaskInvFVBridge
1104{
1105public:
1106 LLTaskScriptBridge(
1107 LLPanelInventory* panel,
1108 const LLUUID& uuid,
1109 const LLString& name);
1110
1111 virtual LLViewerImage* getIcon() const;
1112 //static BOOL enableIfCopyable( void* userdata );
1113};
1114
1115LLTaskScriptBridge::LLTaskScriptBridge(
1116 LLPanelInventory* panel,
1117 const LLUUID& uuid,
1118 const LLString& name) :
1119 LLTaskInvFVBridge(panel, uuid, name)
1120{
1121}
1122
1123LLViewerImage* LLTaskScriptBridge::getIcon() const
1124{
1125 return get_item_icon(LLAssetType::AT_SCRIPT, LLInventoryType::IT_LSL, 0);
1126}
1127
1128
1129class LLTaskLSLBridge : public LLTaskScriptBridge
1130{
1131public:
1132 LLTaskLSLBridge(
1133 LLPanelInventory* panel,
1134 const LLUUID& uuid,
1135 const LLString& name);
1136
1137 virtual void openItem();
1138 virtual BOOL removeItem();
1139 //virtual void buildContextMenu(LLMenuGL& menu);
1140
1141 //static void copyToInventory(void* userdata);
1142};
1143
1144LLTaskLSLBridge::LLTaskLSLBridge(
1145 LLPanelInventory* panel,
1146 const LLUUID& uuid,
1147 const LLString& name) :
1148 LLTaskScriptBridge(panel, uuid, name)
1149{
1150}
1151
1152void LLTaskLSLBridge::openItem()
1153{
1154 llinfos << "LLTaskLSLBridge::openItem() " << mUUID << llendl;
1155 if(LLLiveLSLEditor::show(mUUID, mPanel->getTaskUUID()))
1156 {
1157 return;
1158 }
1159 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
1160 if(!object || object->isInventoryPending())
1161 {
1162 return;
1163 }
1164 if(object->permModify() || gAgent.isGodlike())
1165 {
1166 LLString title("Script: ");
1167 LLInventoryItem* item = findItem();
1168 if (item)
1169 {
1170 title.append(item->getName());
1171 }
1172
1173 S32 left, top;
1174 gFloaterView->getNewFloaterPosition(&left, &top);
1175 LLRect rect = gSavedSettings.getRect("PreviewScriptRect");
1176 rect.translate(left - rect.mLeft, top - rect.mTop);
1177 LLLiveLSLEditor* editor;
1178 editor = new LLLiveLSLEditor("lsl ed",
1179 rect,
1180 title,
1181 mPanel->getTaskUUID(),
1182 mUUID);
1183 LLMultiFloater* previous_host = LLFloater::getFloaterHost();
1184 LLFloater::setFloaterHost(NULL);
1185 editor->open();
1186 LLFloater::setFloaterHost(previous_host);
1187
1188 // keep onscreen
1189 gFloaterView->adjustToFitScreen(editor, FALSE);
1190 }
1191}
1192
1193BOOL LLTaskLSLBridge::removeItem()
1194{
1195 LLLiveLSLEditor::hide(mUUID, mPanel->getTaskUUID());
1196 return LLTaskInvFVBridge::removeItem();
1197}
1198
1199///----------------------------------------------------------------------------
1200/// Class LLTaskObjectBridge
1201///----------------------------------------------------------------------------
1202
1203class LLTaskObjectBridge : public LLTaskInvFVBridge
1204{
1205public:
1206 LLTaskObjectBridge(
1207 LLPanelInventory* panel,
1208 const LLUUID& uuid,
1209 const LLString& name);
1210
1211 virtual LLViewerImage* getIcon() const;
1212};
1213
1214LLTaskObjectBridge::LLTaskObjectBridge(
1215 LLPanelInventory* panel,
1216 const LLUUID& uuid,
1217 const LLString& name) :
1218 LLTaskInvFVBridge(panel, uuid, name)
1219{
1220}
1221
1222LLViewerImage* LLTaskObjectBridge::getIcon() const
1223{
1224 return get_item_icon(LLAssetType::AT_OBJECT, LLInventoryType::IT_OBJECT, 0);
1225}
1226
1227
1228///----------------------------------------------------------------------------
1229/// Class LLTaskNotecardBridge
1230///----------------------------------------------------------------------------
1231
1232class LLTaskNotecardBridge : public LLTaskInvFVBridge
1233{
1234public:
1235 LLTaskNotecardBridge(
1236 LLPanelInventory* panel,
1237 const LLUUID& uuid,
1238 const LLString& name);
1239
1240 virtual LLViewerImage* getIcon() const;
1241 virtual void openItem();
1242 virtual BOOL removeItem();
1243};
1244
1245LLTaskNotecardBridge::LLTaskNotecardBridge(
1246 LLPanelInventory* panel,
1247 const LLUUID& uuid,
1248 const LLString& name) :
1249 LLTaskInvFVBridge(panel, uuid, name)
1250{
1251}
1252
1253LLViewerImage* LLTaskNotecardBridge::getIcon() const
1254{
1255 return get_item_icon(LLAssetType::AT_NOTECARD, LLInventoryType::IT_NOTECARD, 0);
1256}
1257
1258void LLTaskNotecardBridge::openItem()
1259{
1260 if(LLPreview::show(mUUID))
1261 {
1262 return;
1263 }
1264 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
1265 if(!object || object->isInventoryPending())
1266 {
1267 return;
1268 }
1269 if(object->permModify() || gAgent.isGodlike())
1270 {
1271 S32 left, top;
1272 gFloaterView->getNewFloaterPosition(&left, &top);
1273 LLRect rect = gSavedSettings.getRect("PreviewScriptRect");
1274 rect.translate(left - rect.mLeft, top - rect.mTop);
1275 LLPreviewNotecard* preview;
1276 preview = new LLPreviewNotecard("live notecard editor",
1277 rect,
1278 getName(),
1279 mUUID,
1280 mPanel->getTaskUUID());
1281 preview->setFocus(TRUE); // if you're opening a notecard from an object's inventory, it takes focus
1282
1283 // keep onscreen
1284 gFloaterView->adjustToFitScreen(preview, FALSE);
1285 }
1286}
1287
1288BOOL LLTaskNotecardBridge::removeItem()
1289{
1290 LLPreview::hide(mUUID);
1291 return LLTaskInvFVBridge::removeItem();
1292}
1293
1294///----------------------------------------------------------------------------
1295/// Class LLTaskGestureBridge
1296///----------------------------------------------------------------------------
1297
1298class LLTaskGestureBridge : public LLTaskInvFVBridge
1299{
1300public:
1301 LLTaskGestureBridge(
1302 LLPanelInventory* panel,
1303 const LLUUID& uuid,
1304 const LLString& name);
1305
1306 virtual LLViewerImage* getIcon() const;
1307 virtual void openItem();
1308 virtual BOOL removeItem();
1309};
1310
1311LLTaskGestureBridge::LLTaskGestureBridge(
1312 LLPanelInventory* panel,
1313 const LLUUID& uuid,
1314 const LLString& name) :
1315 LLTaskInvFVBridge(panel, uuid, name)
1316{
1317}
1318
1319LLViewerImage* LLTaskGestureBridge::getIcon() const
1320{
1321 return get_item_icon(LLAssetType::AT_GESTURE, LLInventoryType::IT_GESTURE, 0);
1322}
1323
1324void LLTaskGestureBridge::openItem()
1325{
1326 if(LLPreview::show(mUUID))
1327 {
1328 return;
1329 }
1330 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
1331 if(!object || object->isInventoryPending())
1332 {
1333 return;
1334 }
1335
1336 // TODO: save rectangle
1337 LLString title = getName();
1338 LLUUID item_id = mUUID;
1339 LLUUID object_id = mPanel->getTaskUUID();
1340 LLPreviewGesture* preview = LLPreviewGesture::show(title, item_id, object_id);
1341
1342 // keep onscreen
1343 gFloaterView->adjustToFitScreen(preview, FALSE);
1344}
1345
1346BOOL LLTaskGestureBridge::removeItem()
1347{
1348 // Don't need to deactivate gesture because gestures inside objects
1349 // can never be active.
1350 LLPreview::hide(mUUID);
1351 return LLTaskInvFVBridge::removeItem();
1352}
1353
1354///----------------------------------------------------------------------------
1355/// Class LLTaskAnimationBridge
1356///----------------------------------------------------------------------------
1357
1358class LLTaskAnimationBridge : public LLTaskInvFVBridge
1359{
1360public:
1361 LLTaskAnimationBridge(
1362 LLPanelInventory* panel,
1363 const LLUUID& uuid,
1364 const LLString& name);
1365
1366 virtual LLViewerImage* getIcon() const;
1367 virtual void openItem();
1368 virtual BOOL removeItem();
1369};
1370
1371LLTaskAnimationBridge::LLTaskAnimationBridge(
1372 LLPanelInventory* panel,
1373 const LLUUID& uuid,
1374 const LLString& name) :
1375 LLTaskInvFVBridge(panel, uuid, name)
1376{
1377}
1378
1379LLViewerImage* LLTaskAnimationBridge::getIcon() const
1380{
1381 return get_item_icon(LLAssetType::AT_ANIMATION, LLInventoryType::IT_ANIMATION, 0);
1382}
1383
1384void LLTaskAnimationBridge::openItem()
1385{
1386 if(LLPreview::show(mUUID))
1387 {
1388 return;
1389 }
1390 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
1391 if(!object || object->isInventoryPending())
1392 {
1393 return;
1394 }
1395
1396 // TODO: what permissions allow looking at animation?
1397 if(object->permModify() || gAgent.isGodlike())
1398 {
1399 // TODO: save rectangle
1400 LLString title = getName();
1401 LLUUID item_id = mUUID;
1402 LLUUID object_id = mPanel->getTaskUUID();
1403
1404 if(!LLPreview::show(mUUID))
1405 {
1406 // There isn't one, so make a new preview
1407 S32 left, top;
1408 gFloaterView->getNewFloaterPosition(&left, &top);
1409 LLRect rect = gSavedSettings.getRect("PreviewAnimRect");
1410 rect.translate(left - rect.mLeft, top - rect.mTop);
1411
1412 LLPreviewAnim* preview = new LLPreviewAnim("preview anim",
1413 rect,
1414 getName(),
1415 mUUID,
1416 0,
1417 mPanel->getTaskUUID());
1418 preview->setFocus(TRUE); // take focus if you're looking at one of these
1419
1420 // Force to be entirely onscreen.
1421 gFloaterView->adjustToFitScreen(preview, FALSE);
1422 }
1423 }
1424}
1425
1426BOOL LLTaskAnimationBridge::removeItem()
1427{
1428 LLPreview::hide(mUUID);
1429 return LLTaskInvFVBridge::removeItem();
1430}
1431
1432///----------------------------------------------------------------------------
1433/// Class LLTaskWearableBridge
1434///----------------------------------------------------------------------------
1435
1436class LLTaskWearableBridge : public LLTaskInvFVBridge
1437{
1438public:
1439 LLTaskWearableBridge(
1440 LLPanelInventory* panel,
1441 const LLUUID& uuid,
1442 const LLString& name,
1443 LLAssetType::EType asset_type,
1444 U32 flags);
1445
1446 virtual LLViewerImage* getIcon() const;
1447
1448protected:
1449 LLAssetType::EType mAssetType;
1450 U32 mWearableType;
1451};
1452
1453LLTaskWearableBridge::LLTaskWearableBridge(
1454 LLPanelInventory* panel,
1455 const LLUUID& uuid,
1456 const LLString& name,
1457 LLAssetType::EType asset_type,
1458 U32 flags) :
1459 LLTaskInvFVBridge(panel, uuid, name),
1460 mAssetType( asset_type ),
1461 mWearableType(flags)
1462{
1463}
1464
1465LLViewerImage* LLTaskWearableBridge::getIcon() const
1466{
1467 return get_item_icon(mAssetType, LLInventoryType::IT_WEARABLE, mWearableType);
1468}
1469
1470
1471///----------------------------------------------------------------------------
1472/// LLTaskInvFVBridge impl
1473//----------------------------------------------------------------------------
1474
1475LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelInventory* panel,
1476 LLInventoryObject* object)
1477{
1478 LLTaskInvFVBridge* new_bridge = NULL;
1479 LLAssetType::EType type = object->getType();
1480 LLInventoryItem* item = NULL;
1481 switch(type)
1482 {
1483 case LLAssetType::AT_TEXTURE:
1484 item = (LLInventoryItem*)object;
1485 new_bridge = new LLTaskTextureBridge(panel,
1486 object->getUUID(),
1487 object->getName(),
1488 item->getInventoryType());
1489 break;
1490 case LLAssetType::AT_SOUND:
1491 new_bridge = new LLTaskSoundBridge(panel,
1492 object->getUUID(),
1493 object->getName());
1494 break;
1495 case LLAssetType::AT_LANDMARK:
1496 new_bridge = new LLTaskLandmarkBridge(panel,
1497 object->getUUID(),
1498 object->getName());
1499 break;
1500 case LLAssetType::AT_CALLINGCARD:
1501 new_bridge = new LLTaskCallingCardBridge(panel,
1502 object->getUUID(),
1503 object->getName());
1504 break;
1505 case LLAssetType::AT_SCRIPT:
1506 // OLD SCRIPTS DEPRECATED - JC
1507 llwarns << "Old script" << llendl;
1508 //new_bridge = new LLTaskOldScriptBridge(panel,
1509 // object->getUUID(),
1510 // object->getName());
1511 break;
1512 case LLAssetType::AT_OBJECT:
1513 new_bridge = new LLTaskObjectBridge(panel,
1514 object->getUUID(),
1515 object->getName());
1516 break;
1517 case LLAssetType::AT_NOTECARD:
1518 new_bridge = new LLTaskNotecardBridge(panel,
1519 object->getUUID(),
1520 object->getName());
1521 break;
1522 case LLAssetType::AT_ANIMATION:
1523 new_bridge = new LLTaskAnimationBridge(panel,
1524 object->getUUID(),
1525 object->getName());
1526 break;
1527 case LLAssetType::AT_GESTURE:
1528 new_bridge = new LLTaskGestureBridge(panel,
1529 object->getUUID(),
1530 object->getName());
1531 break;
1532 case LLAssetType::AT_CLOTHING:
1533 case LLAssetType::AT_BODYPART:
1534 item = (LLInventoryItem*)object;
1535 new_bridge = new LLTaskWearableBridge(panel,
1536 object->getUUID(),
1537 object->getName(),
1538 type,
1539 item->getFlags());
1540 break;
1541 case LLAssetType::AT_CATEGORY:
1542 new_bridge = new LLTaskCategoryBridge(panel,
1543 object->getUUID(),
1544 object->getName());
1545 break;
1546 case LLAssetType::AT_LSL_TEXT:
1547 new_bridge = new LLTaskLSLBridge(panel,
1548 object->getUUID(),
1549 object->getName());
1550 break;
1551 default:
1552 llinfos << "Unhandled inventory type (llassetstorage.h): "
1553 << (S32)type << llendl;
1554 break;
1555 }
1556 return new_bridge;
1557}
1558
1559
1560///----------------------------------------------------------------------------
1561/// Class LLPanelInventory
1562///----------------------------------------------------------------------------
1563
1564// Default constructor
1565LLPanelInventory::LLPanelInventory(const LLString& name, const LLRect& rect) :
1566 LLPanel(name, rect),
1567 mScroller(NULL),
1568 mFolders(NULL),
1569 mHaveInventory(FALSE),
1570 mIsInventoryEmpty(TRUE),
1571 mInventoryNeedsUpdate(FALSE)
1572{
1573 reset();
1574 // Callbacks
1575 init_object_inventory_panel_actions(this);
1576 gIdleCallbacks.addFunction(idle, this);
1577}
1578
1579// Destroys the object
1580LLPanelInventory::~LLPanelInventory()
1581{
1582 if (!gIdleCallbacks.deleteFunction(idle, this))
1583 {
1584 llwarns << "LLPanelInventory::~LLPanelInventory() failed to delete callback" << llendl;
1585 }
1586}
1587
1588
1589void LLPanelInventory::clearContents()
1590{
1591 mHaveInventory = FALSE;
1592 mIsInventoryEmpty = TRUE;
1593 if (gToolDragAndDrop && gToolDragAndDrop->getSource() == LLToolDragAndDrop::SOURCE_WORLD)
1594 {
1595 gToolDragAndDrop->endDrag();
1596 }
1597
1598 if( mScroller )
1599 {
1600 // removes mFolders
1601 removeChild( mScroller );
1602 mScroller->die();
1603 mScroller = NULL;
1604 mFolders = NULL;
1605 }
1606}
1607
1608
1609void LLPanelInventory::reset()
1610{
1611 clearContents();
1612
1613 setBorderVisible(FALSE);
1614
1615 LLRect dummy_rect(0, 1, 1, 0);
1616 mFolders = new LLFolderView("task inventory", NULL, dummy_rect, getTaskUUID(), this);
1617 // this ensures that we never say "searching..." or "no items found"
1618 mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
1619
1620 LLRect scroller_rect(0, mRect.getHeight(), mRect.getWidth(), 0);
1621 mScroller = new LLScrollableContainerView(
1622 "task inventory scroller", scroller_rect, mFolders );
1623 mScroller->setFollowsAll();
1624 addChild(mScroller);
1625
1626 mFolders->setScrollContainer( mScroller );
1627}
1628
1629void LLPanelInventory::inventoryChanged(LLViewerObject* object,
1630 InventoryObjectList* inventory,
1631 S32 serial_num,
1632 void* data)
1633{
1634 if(!object) return;
1635
1636 //llinfos << "invetnory arrived: \n"
1637 // << " panel UUID: " << panel->mTaskUUID << "\n"
1638 // << " task UUID: " << object->mID << llendl;
1639 if(mTaskUUID == object->mID)
1640 {
1641 mInventoryNeedsUpdate = TRUE;
1642 }
1643
1644 // refresh any properties floaters that are hanging around.
1645 if(inventory)
1646 {
1647 // We need to copy the ones that need refreshing onto a
1648 // temporary object because we cannot iterate through the
1649 // object inventory twice... A pox on stateful iteration!
1650 LLFloaterProperties* floater = NULL;
1651 LLDynamicArray<LLFloaterProperties*> refresh;
1652
1653 InventoryObjectList::const_iterator it = inventory->begin();
1654 InventoryObjectList::const_iterator end = inventory->end();
1655 for( ; it != end; ++it)
1656 {
1657 floater = LLFloaterProperties::find((*it)->getUUID(),
1658 object->getID());
1659 if(floater)
1660 {
1661 refresh.put(floater);
1662 }
1663 }
1664 S32 count = refresh.count();
1665 for(S32 i = 0; i < count; ++i)
1666 {
1667 refresh.get(i)->refresh();
1668 }
1669 }
1670}
1671
1672void LLPanelInventory::updateInventory()
1673{
1674 //llinfos << "inventory arrived: \n"
1675 // << " panel UUID: " << panel->mTaskUUID << "\n"
1676 // << " task UUID: " << object->mID << llendl;
1677 // We're still interested in this task's inventory.
1678 std::set<LLUUID> selected_items;
1679 BOOL inventory_has_focus = FALSE;
1680 if (mHaveInventory && mFolders->getNumSelectedDescendants())
1681 {
1682 mFolders->getSelectionList(selected_items);
1683 inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders);
1684 }
1685
1686 reset();
1687
1688 LLViewerObject* objectp = gObjectList.findObject(mTaskUUID);
1689 if (objectp)
1690 {
1691 LLInventoryObject* inventory_root = objectp->getInventoryRoot();
1692 InventoryObjectList contents;
1693 objectp->getInventoryContents(contents);
1694 if (inventory_root)
1695 {
1696 createFolderViews(inventory_root, contents);
1697 mHaveInventory = TRUE;
1698 mIsInventoryEmpty = FALSE;
1699 mFolders->setEnabled(TRUE);
1700 }
1701 else
1702 {
1703 // TODO: create an empty inventory
1704 mIsInventoryEmpty = TRUE;
1705 mHaveInventory = TRUE;
1706 }
1707 }
1708 else
1709 {
1710 // TODO: create an empty inventory
1711 mIsInventoryEmpty = TRUE;
1712 mHaveInventory = TRUE;
1713 }
1714
1715 // restore previous selection
1716 std::set<LLUUID>::iterator selection_it;
1717 BOOL first_item = TRUE;
1718 for (selection_it = selected_items.begin(); selection_it != selected_items.end(); ++selection_it)
1719 {
1720 LLFolderViewItem* selected_item = mFolders->getItemByID(*selection_it);
1721 if (selected_item)
1722 {
1723 //HACK: "set" first item then "change" each other one to get keyboard focus right
1724 if (first_item)
1725 {
1726 mFolders->setSelection(selected_item, TRUE, inventory_has_focus);
1727 first_item = FALSE;
1728 }
1729 else
1730 {
1731 mFolders->changeSelection(selected_item, TRUE);
1732 }
1733 }
1734 }
1735
1736 mFolders->arrangeFromRoot();
1737 mInventoryNeedsUpdate = FALSE;
1738}
1739
1740// *FIX: This is currently a very expensive operation, because we have
1741// to iterate through the inventory one time for each category. This
1742// leads to an N^2 based on the category count. This could be greatly
1743// speeded with an efficient multimap implementation, but we don't
1744// have that in our current arsenal.
1745void LLPanelInventory::createFolderViews(LLInventoryObject* inventory_root, InventoryObjectList& contents)
1746{
1747 if (!inventory_root)
1748 {
1749 return;
1750 }
1751 // Create a visible root category.
1752 LLTaskInvFVBridge* bridge = NULL;
1753 bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root);
1754 if(bridge)
1755 {
1756 LLFolderViewFolder* new_folder = NULL;
1757 new_folder = new LLFolderViewFolder(inventory_root->getName(),
1758 bridge->getIcon(),
1759 mFolders,
1760 bridge);
1761 new_folder->addToFolder(mFolders, mFolders);
1762 new_folder->toggleOpen();
1763
1764 createViewsForCategory(&contents, inventory_root, new_folder);
1765 }
1766}
1767
1768typedef std::pair<LLInventoryObject*, LLFolderViewFolder*> obj_folder_pair;
1769
1770// Replace LLLinkedList with std:: equivalant.
1771void LLPanelInventory::createViewsForCategory(InventoryObjectList* inventory, //LLLinkedList<LLInventoryObject>* inventory,
1772 LLInventoryObject* parent,
1773 LLFolderViewFolder* folder)
1774{
1775 // Find all in the first pass
1776 LLDynamicArray<obj_folder_pair*> child_categories;
1777 LLTaskInvFVBridge* bridge;
1778 LLFolderViewItem* view;
1779
1780 InventoryObjectList::iterator it = inventory->begin();
1781 InventoryObjectList::iterator end = inventory->end();
1782 for( ; it != end; ++it)
1783 {
1784 LLInventoryObject* obj = *it;
1785
1786 if(parent->getUUID() == obj->getParentUUID())
1787 {
1788 bridge = LLTaskInvFVBridge::createObjectBridge(this, obj);
1789 if(!bridge)
1790 {
1791 continue;
1792 }
1793 if(LLAssetType::AT_CATEGORY == obj->getType())
1794 {
1795 view = new LLFolderViewFolder(obj->getName(),
1796 bridge->getIcon(),
1797 mFolders,
1798 bridge);
1799 child_categories.put(new obj_folder_pair(obj,
1800 (LLFolderViewFolder*)view));
1801 }
1802 else
1803 {
1804 view = new LLFolderViewItem(obj->getName(),
1805 bridge->getIcon(),
1806 bridge->getCreationDate(),
1807 mFolders,
1808 bridge);
1809 }
1810 view->addToFolder(folder, mFolders);
1811 }
1812 }
1813
1814 // now, for each category, do the second pass
1815 for(S32 i = 0; i < child_categories.count(); i++)
1816 {
1817 createViewsForCategory(inventory, child_categories[i]->first,
1818 child_categories[i]->second );
1819 delete child_categories[i];
1820 }
1821}
1822
1823void LLPanelInventory::refresh()
1824{
1825 //llinfos << "LLPanelInventory::refresh()" << llendl;
1826 BOOL has_inventory = FALSE;
1827 LLSelectNode* node = gSelectMgr->getFirstRootNode();
1828 if(!node)
1829 {
1830 node = gSelectMgr->getFirstNode();
1831 }
1832 if(node)
1833 {
1834 LLViewerObject* object = node->getObject();
1835 if(object && ((gSelectMgr->getRootObjectCount() == 1)
1836 || (gSelectMgr->getObjectCount() == 1)))
1837 {
1838 // determine if we need to make a request. Start with a
1839 // default based on if we have inventory at all.
1840 BOOL make_request = !mHaveInventory;
1841
1842 // If the task id is different than what we've stored,
1843 // then make the request.
1844 if(mTaskUUID != object->mID)
1845 {
1846 mTaskUUID = object->mID;
1847 make_request = TRUE;
1848
1849 // This is a new object so pre-emptively clear the contents
1850 // Otherwise we show the old stuff until the update comes in
1851 clearContents();
1852
1853 // Register for updates from this object,
1854 registerVOInventoryListener(object,NULL);
1855 }
1856
1857 // Based on the node information, we may need to dirty the
1858 // object inventory and get it again.
1859 if(node->mValid)
1860 {
1861 if(node->mInventorySerial != object->getInventorySerial() || object->isInventoryDirty())
1862 {
1863 make_request = TRUE;
1864 }
1865 }
1866
1867 // do the request if necessary.
1868 if(make_request)
1869 {
1870 requestVOInventory();
1871 }
1872 has_inventory = TRUE;
1873 }
1874 }
1875 if(!has_inventory)
1876 {
1877 mTaskUUID = LLUUID::null;
1878 removeVOInventoryListener();
1879 clearContents();
1880 }
1881 //llinfos << "LLPanelInventory::refresh() " << mTaskUUID << llendl;
1882}
1883
1884void LLPanelInventory::removeSelectedItem()
1885{
1886 if(mFolders)
1887 {
1888 mFolders->removeSelectedItems();
1889 }
1890}
1891
1892void LLPanelInventory::startRenamingSelectedItem()
1893{
1894 if(mFolders)
1895 {
1896 mFolders->startRenamingSelectedItem();
1897 }
1898}
1899
1900void LLPanelInventory::draw()
1901{
1902 if( getVisible() )
1903 {
1904 LLPanel::draw();
1905
1906 if(mIsInventoryEmpty)
1907 {
1908 if((LLUUID::null != mTaskUUID) && (!mHaveInventory))
1909 {
1910 LLFontGL::sSansSerif->renderUTF8("Loading contents...", 0,
1911 (S32)(mRect.getWidth() * 0.5f),
1912 10,
1913 LLColor4( 1, 1, 1, 1 ),
1914 LLFontGL::HCENTER,
1915 LLFontGL::BOTTOM);
1916 }
1917 else if(mHaveInventory)
1918 {
1919 LLFontGL::sSansSerif->renderUTF8("No contents", 0,
1920 (S32)(mRect.getWidth() * 0.5f),
1921 10,
1922 LLColor4( 1, 1, 1, 1 ),
1923 LLFontGL::HCENTER,
1924 LLFontGL::BOTTOM);
1925 }
1926 }
1927 }
1928}
1929
1930void LLPanelInventory::deleteAllChildren()
1931{
1932 mScroller = NULL;
1933 mFolders = NULL;
1934 LLView::deleteAllChildren();
1935}
1936
1937BOOL LLPanelInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, LLString& tooltip_msg)
1938{
1939 if (mFolders && mHaveInventory)
1940 {
1941 LLFolderViewItem* folderp = mFolders->getNextFromChild(NULL);
1942 if (!folderp)
1943 {
1944 return FALSE;
1945 }
1946 // Try to pass on unmodified mouse coordinates
1947 S32 local_x = x - mFolders->getRect().mLeft;
1948 S32 local_y = y - mFolders->getRect().mBottom;
1949
1950 if (mFolders->pointInView(local_x, local_y))
1951 {
1952 return mFolders->handleDragAndDrop(local_x, local_y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
1953 }
1954 else
1955 {
1956 //force mouse coordinates to be inside folder rectangle
1957 return mFolders->handleDragAndDrop(5, 1, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
1958 }
1959 }
1960 else
1961 {
1962 return FALSE;
1963 }
1964}
1965
1966//static
1967void LLPanelInventory::idle(void* user_data)
1968{
1969 LLPanelInventory* self = (LLPanelInventory*)user_data;
1970
1971
1972 if (self->mInventoryNeedsUpdate)
1973 {
1974 self->updateInventory();
1975 }
1976}