PageRenderTime 155ms CodeModel.GetById 27ms app.highlight 114ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/newview/llpanelobjectinventory.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1940 lines | 1543 code | 219 blank | 178 comment | 216 complexity | 69acd202263f54f062d764cfc54cf727 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/**
   2 * @file llsidepanelinventory.cpp
   3 * @brief LLPanelObjectInventory class implementation
   4 *
   5 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
   6 * Second Life Viewer Source Code
   7 * Copyright (C) 2010, Linden Research, Inc.
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation;
  12 * version 2.1 of the License only.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22 * 
  23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  24 * $/LicenseInfo$
  25 */
  26
  27//*****************************************************************************
  28//
  29// Implementation of the panel inventory - used to view and control a
  30// task's inventory.
  31//
  32//*****************************************************************************
  33
  34#include "llviewerprecompiledheaders.h"
  35
  36#include "llpanelobjectinventory.h"
  37
  38#include "llmenugl.h"
  39#include "llnotificationsutil.h"
  40#include "roles_constants.h"
  41
  42#include "llagent.h"
  43#include "llavataractions.h"
  44#include "llcallbacklist.h"
  45#include "llbuycurrencyhtml.h"
  46#include "llfloaterreg.h"
  47#include "llfolderview.h"
  48#include "llinventorybridge.h"
  49#include "llinventorydefines.h"
  50#include "llinventoryfilter.h"
  51#include "llinventoryfunctions.h"
  52#include "llpreviewanim.h"
  53#include "llpreviewgesture.h"
  54#include "llpreviewnotecard.h"
  55#include "llpreviewscript.h"
  56#include "llpreviewsound.h"
  57#include "llpreviewtexture.h"
  58#include "llscrollcontainer.h"
  59#include "llselectmgr.h"
  60#include "llstatusbar.h"
  61#include "lltooldraganddrop.h"
  62#include "lltrans.h"
  63#include "llviewerassettype.h"
  64#include "llviewerinventory.h"
  65#include "llviewerregion.h"
  66#include "llviewerobjectlist.h"
  67#include "llviewermessage.h"
  68
  69
  70///----------------------------------------------------------------------------
  71/// Class LLTaskInvFVBridge
  72///----------------------------------------------------------------------------
  73
  74class LLTaskInvFVBridge : public LLFolderViewEventListener
  75{
  76protected:
  77	LLUUID mUUID;
  78	std::string mName;
  79	mutable std::string mDisplayName;
  80	LLPanelObjectInventory* mPanel;
  81	U32 mFlags;
  82	LLAssetType::EType mAssetType;	
  83	LLInventoryType::EType mInventoryType;
  84
  85	LLInventoryObject* findInvObject() const;
  86	LLInventoryItem* findItem() const;
  87
  88public:
  89	LLTaskInvFVBridge(LLPanelObjectInventory* panel,
  90					  const LLUUID& uuid,
  91					  const std::string& name,
  92					  U32 flags=0);
  93	virtual ~LLTaskInvFVBridge() {}
  94
  95	virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
  96	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
  97
  98	static LLTaskInvFVBridge* createObjectBridge(LLPanelObjectInventory* panel,
  99												 LLInventoryObject* object);
 100	void showProperties();
 101	void buyItem();
 102	S32 getPrice();
 103	static bool commitBuyItem(const LLSD& notification, const LLSD& response);
 104
 105	// LLFolderViewEventListener functionality
 106	virtual const std::string& getName() const;
 107	virtual const std::string& getDisplayName() const;
 108	virtual PermissionMask getPermissionMask() const { return PERM_NONE; }
 109	/*virtual*/ LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; }
 110	virtual const LLUUID& getUUID() const { return mUUID; }
 111	virtual time_t getCreationDate() const;
 112	virtual LLUIImagePtr getIcon() const;
 113	virtual void openItem();
 114	virtual BOOL canOpenItem() const { return FALSE; }
 115	virtual void closeItem() {}
 116	virtual void previewItem();
 117	virtual void selectItem() {}
 118	virtual BOOL isItemRenameable() const;
 119	virtual BOOL renameItem(const std::string& new_name);
 120	virtual BOOL isItemMovable() const;
 121	virtual BOOL isItemRemovable() const;
 122	virtual BOOL removeItem();
 123	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
 124	virtual void move(LLFolderViewEventListener* parent_listener);
 125	virtual BOOL isItemCopyable() const;
 126	virtual BOOL copyToClipboard() const;
 127	virtual void cutToClipboard();
 128	virtual BOOL isClipboardPasteable() const;
 129	virtual void pasteFromClipboard();
 130	virtual void pasteLinkFromClipboard();
 131	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
 132	virtual void performAction(LLInventoryModel* model, std::string action);
 133	virtual BOOL isUpToDate() const { return TRUE; }
 134	virtual BOOL hasChildren() const { return FALSE; }
 135	virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
 136	virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
 137
 138	// LLDragAndDropBridge functionality
 139	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
 140	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 141							EDragAndDropType cargo_type,
 142							void* cargo_data,
 143							std::string& tooltip_msg);
 144};
 145
 146LLTaskInvFVBridge::LLTaskInvFVBridge(
 147	LLPanelObjectInventory* panel,
 148	const LLUUID& uuid,
 149	const std::string& name,
 150	U32 flags):
 151	mUUID(uuid),
 152	mName(name),
 153	mPanel(panel),
 154	mFlags(flags),
 155	mAssetType(LLAssetType::AT_NONE),
 156	mInventoryType(LLInventoryType::IT_NONE)
 157{
 158	const LLInventoryItem *item = findItem();
 159	if (item)
 160	{
 161		mAssetType = item->getType();
 162		mInventoryType = item->getInventoryType();
 163	}
 164}
 165
 166LLInventoryObject* LLTaskInvFVBridge::findInvObject() const
 167{
 168	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 169	if (object)
 170	{
 171		return object->getInventoryObject(mUUID);
 172	}
 173	return NULL;
 174}
 175
 176
 177LLInventoryItem* LLTaskInvFVBridge::findItem() const
 178{
 179	return dynamic_cast<LLInventoryItem*>(findInvObject());
 180}
 181
 182void LLTaskInvFVBridge::showProperties()
 183{
 184	show_task_item_profile(mUUID, mPanel->getTaskUUID());
 185}
 186
 187struct LLBuyInvItemData
 188{
 189	LLUUID mTaskID;
 190	LLUUID mItemID;
 191	LLAssetType::EType mType;
 192
 193	LLBuyInvItemData(const LLUUID& task,
 194					 const LLUUID& item,
 195					 LLAssetType::EType type) :
 196		mTaskID(task), mItemID(item), mType(type)
 197	{}
 198};
 199
 200void LLTaskInvFVBridge::buyItem()
 201{
 202	llinfos << "LLTaskInvFVBridge::buyItem()" << llendl;
 203	LLInventoryItem* item = findItem();
 204	if(!item || !item->getSaleInfo().isForSale()) return;
 205	LLBuyInvItemData* inv = new LLBuyInvItemData(mPanel->getTaskUUID(),
 206												 mUUID,
 207												 item->getType());
 208
 209	const LLSaleInfo& sale_info = item->getSaleInfo();
 210	const LLPermissions& perm = item->getPermissions();
 211	const std::string owner_name; // no owner name currently... FIXME?
 212
 213	LLViewerObject* obj;
 214	if( ( obj = gObjectList.findObject( mPanel->getTaskUUID() ) ) && obj->isAttachment() )
 215	{
 216		LLNotificationsUtil::add("Cannot_Purchase_an_Attachment");
 217		llinfos << "Attempt to purchase an attachment" << llendl;
 218		delete inv;
 219	}
 220	else
 221	{
 222        LLSD args;
 223        args["PRICE"] = llformat("%d",sale_info.getSalePrice());
 224        args["OWNER"] = owner_name;
 225        if (sale_info.getSaleType() != LLSaleInfo::FS_CONTENTS)
 226        {
 227        	U32 next_owner_mask = perm.getMaskNextOwner();
 228        	args["MODIFYPERM"] = LLTrans::getString((next_owner_mask & PERM_MODIFY) ? "PermYes" : "PermNo");
 229        	args["COPYPERM"] = LLTrans::getString((next_owner_mask & PERM_COPY) ? "PermYes" : "PermNo");
 230        	args["RESELLPERM"] = LLTrans::getString((next_owner_mask & PERM_TRANSFER) ? "PermYes" : "PermNo");
 231        }
 232
 233		std::string alertdesc;
 234       	switch(sale_info.getSaleType())
 235       	{
 236       	  case LLSaleInfo::FS_ORIGINAL:
 237       		alertdesc = owner_name.empty() ? "BuyOriginalNoOwner" : "BuyOriginal";
 238       		break;
 239       	  case LLSaleInfo::FS_CONTENTS:
 240       		alertdesc = owner_name.empty() ? "BuyContentsNoOwner" : "BuyContents";
 241       		break;
 242		  case LLSaleInfo::FS_COPY:
 243       	  default:
 244       		alertdesc = owner_name.empty() ? "BuyCopyNoOwner" : "BuyCopy";
 245       		break;
 246       	}
 247
 248		LLSD payload;
 249		payload["task_id"] = inv->mTaskID;
 250		payload["item_id"] = inv->mItemID;
 251		payload["type"] = inv->mType;
 252		LLNotificationsUtil::add(alertdesc, args, payload, LLTaskInvFVBridge::commitBuyItem);
 253	}
 254}
 255
 256S32 LLTaskInvFVBridge::getPrice()
 257{
 258	LLInventoryItem* item = findItem();
 259	if(item)
 260	{
 261		return item->getSaleInfo().getSalePrice();
 262	}
 263	else
 264	{
 265		return -1;
 266	}
 267}
 268
 269// static
 270bool LLTaskInvFVBridge::commitBuyItem(const LLSD& notification, const LLSD& response)
 271{
 272	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 273	if(0 == option)
 274	{
 275		LLViewerObject* object = gObjectList.findObject(notification["payload"]["task_id"].asUUID());
 276		if(!object || !object->getRegion()) return false;
 277
 278
 279		LLMessageSystem* msg = gMessageSystem;
 280		msg->newMessageFast(_PREHASH_BuyObjectInventory);
 281		msg->nextBlockFast(_PREHASH_AgentData);
 282		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 283		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 284		msg->nextBlockFast(_PREHASH_Data);
 285		msg->addUUIDFast(_PREHASH_ObjectID, notification["payload"]["task_id"].asUUID());
 286		msg->addUUIDFast(_PREHASH_ItemID, notification["payload"]["item_id"].asUUID());
 287		msg->addUUIDFast(_PREHASH_FolderID,
 288			gInventory.findCategoryUUIDForType((LLFolderType::EType)notification["payload"]["type"].asInteger()));
 289		msg->sendReliable(object->getRegion()->getHost());
 290	}
 291	return false;
 292}
 293
 294const std::string& LLTaskInvFVBridge::getName() const
 295{
 296	return mName;
 297}
 298
 299const std::string& LLTaskInvFVBridge::getDisplayName() const
 300{
 301	LLInventoryItem* item = findItem();
 302
 303	if(item)
 304	{
 305		mDisplayName.assign(item->getName());
 306
 307		// Localize "New Script", "New Script 1", "New Script 2", etc.
 308		if (item->getType() == LLAssetType::AT_LSL_TEXT &&
 309			LLStringUtil::startsWith(item->getName(), "New Script"))
 310		{
 311			LLStringUtil::replaceString(mDisplayName, "New Script", LLTrans::getString("PanelContentsNewScript"));
 312		}
 313
 314		const LLPermissions& perm(item->getPermissions());
 315		BOOL copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE);
 316		BOOL mod  = gAgent.allowOperation(PERM_MODIFY, perm, GP_OBJECT_MANIPULATE);
 317		BOOL xfer = gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE);
 318
 319		if(!copy)
 320		{
 321			mDisplayName.append(LLTrans::getString("no_copy"));
 322		}
 323		if(!mod)
 324		{
 325			mDisplayName.append(LLTrans::getString("no_modify"));
 326		}
 327		if(!xfer)
 328		{
 329			mDisplayName.append(LLTrans::getString("no_transfer"));
 330		}
 331	}
 332
 333	return mDisplayName;
 334}
 335
 336// BUG: No creation dates for task inventory
 337time_t LLTaskInvFVBridge::getCreationDate() const
 338{
 339	return 0;
 340}
 341
 342LLUIImagePtr LLTaskInvFVBridge::getIcon() const
 343{
 344	const BOOL item_is_multi = (mFlags & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS);
 345
 346	return LLInventoryIcon::getIcon(mAssetType, mInventoryType, 0, item_is_multi );
 347}
 348
 349void LLTaskInvFVBridge::openItem()
 350{
 351	// no-op.
 352	lldebugs << "LLTaskInvFVBridge::openItem()" << llendl;
 353}
 354
 355void LLTaskInvFVBridge::previewItem()
 356{
 357	openItem();
 358}
 359
 360BOOL LLTaskInvFVBridge::isItemRenameable() const
 361{
 362	if(gAgent.isGodlike()) return TRUE;
 363	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 364	if(object)
 365	{
 366		LLInventoryItem* item = (LLInventoryItem*)(object->getInventoryObject(mUUID));
 367		if(item && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
 368										 GP_OBJECT_MANIPULATE, GOD_LIKE))
 369		{
 370			return TRUE;
 371		}
 372	}
 373	return FALSE;
 374}
 375
 376BOOL LLTaskInvFVBridge::renameItem(const std::string& new_name)
 377{
 378	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 379	if(object)
 380	{
 381		LLViewerInventoryItem* item = NULL;
 382		item = (LLViewerInventoryItem*)object->getInventoryObject(mUUID);
 383		if(item && (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
 384										GP_OBJECT_MANIPULATE, GOD_LIKE)))
 385		{
 386			LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
 387			new_item->rename(new_name);
 388			object->updateInventory(
 389				new_item,
 390				TASK_INVENTORY_ITEM_KEY,
 391				false);
 392		}
 393	}
 394	return TRUE;
 395}
 396
 397BOOL LLTaskInvFVBridge::isItemMovable() const
 398{
 399	//LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 400	//if(object && (object->permModify() || gAgent.isGodlike()))
 401	//{
 402	//	return TRUE;
 403	//}
 404	//return FALSE;
 405	return TRUE;
 406}
 407
 408BOOL LLTaskInvFVBridge::isItemRemovable() const
 409{
 410	const LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 411	if(object
 412	   && (object->permModify() || object->permYouOwner()))
 413	{
 414		return TRUE;
 415	}
 416	return FALSE;
 417}
 418
 419bool remove_task_inventory_callback(const LLSD& notification, const LLSD& response, LLPanelObjectInventory* panel)
 420{
 421	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 422	LLViewerObject* object = gObjectList.findObject(notification["payload"]["task_id"].asUUID());
 423	if(option == 0 && object)
 424	{
 425		// yes
 426		LLSD::array_const_iterator list_end = notification["payload"]["inventory_ids"].endArray();
 427		for (LLSD::array_const_iterator list_it = notification["payload"]["inventory_ids"].beginArray();
 428			list_it != list_end; 
 429			++list_it)
 430		{
 431			object->removeInventory(list_it->asUUID());
 432		}
 433
 434		// refresh the UI.
 435		panel->refresh();
 436	}
 437	return false;
 438}
 439
 440// helper for remove
 441// ! REFACTOR ! two_uuids_list_t is also defined in llinventorybridge.h, but differently.
 442typedef std::pair<LLUUID, std::list<LLUUID> > panel_two_uuids_list_t;
 443typedef std::pair<LLPanelObjectInventory*, panel_two_uuids_list_t> remove_data_t;
 444BOOL LLTaskInvFVBridge::removeItem()
 445{
 446	if(isItemRemovable() && mPanel)
 447	{
 448		LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 449		if(object)
 450		{
 451			if(object->permModify())
 452			{
 453				// just do it.
 454				object->removeInventory(mUUID);
 455				return TRUE;
 456			}
 457			else
 458			{
 459				LLSD payload;
 460				payload["task_id"] = mPanel->getTaskUUID();
 461				payload["inventory_ids"].append(mUUID);
 462				LLNotificationsUtil::add("RemoveItemWarn", LLSD(), payload, boost::bind(&remove_task_inventory_callback, _1, _2, mPanel));
 463				return FALSE;
 464			}
 465		}
 466	}
 467	return FALSE;
 468}
 469
 470void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
 471{
 472	if (!mPanel)
 473	{
 474		return;
 475	}
 476
 477	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 478	if (!object)
 479	{
 480		return;
 481	}
 482
 483	if (!object->permModify())
 484	{
 485		LLSD payload;
 486		payload["task_id"] = mPanel->getTaskUUID();
 487		for (S32 i = 0; i < (S32)batch.size(); i++)
 488		{
 489			LLTaskInvFVBridge* itemp = (LLTaskInvFVBridge*)batch[i];
 490			payload["inventory_ids"].append(itemp->getUUID());
 491		}
 492		LLNotificationsUtil::add("RemoveItemWarn", LLSD(), payload, boost::bind(&remove_task_inventory_callback, _1, _2, mPanel));
 493		
 494	}
 495	else
 496	{
 497		for (S32 i = 0; i < (S32)batch.size(); i++)
 498		{
 499			LLTaskInvFVBridge* itemp = (LLTaskInvFVBridge*)batch[i];
 500
 501			if(itemp->isItemRemovable())
 502			{
 503				// just do it.
 504				object->removeInventory(itemp->getUUID());
 505			}
 506		}
 507	}
 508}
 509
 510void LLTaskInvFVBridge::move(LLFolderViewEventListener* parent_listener)
 511{
 512}
 513
 514BOOL LLTaskInvFVBridge::isItemCopyable() const
 515{
 516	LLInventoryItem* item = findItem();
 517	if(!item) return FALSE;
 518	return gAgent.allowOperation(PERM_COPY, item->getPermissions(),
 519								GP_OBJECT_MANIPULATE);
 520}
 521
 522BOOL LLTaskInvFVBridge::copyToClipboard() const
 523{
 524	return FALSE;
 525}
 526
 527void LLTaskInvFVBridge::cutToClipboard()
 528{
 529}
 530
 531BOOL LLTaskInvFVBridge::isClipboardPasteable() const
 532{
 533	return FALSE;
 534}
 535
 536void LLTaskInvFVBridge::pasteFromClipboard()
 537{
 538}
 539
 540void LLTaskInvFVBridge::pasteLinkFromClipboard()
 541{
 542}
 543
 544BOOL LLTaskInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
 545{
 546	//llinfos << "LLTaskInvFVBridge::startDrag()" << llendl;
 547	if(mPanel)
 548	{
 549		LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 550		if(object)
 551		{
 552			LLInventoryItem* inv = NULL;
 553			if((inv = (LLInventoryItem*)object->getInventoryObject(mUUID)))
 554			{
 555				const LLPermissions& perm = inv->getPermissions();
 556				bool can_copy = gAgent.allowOperation(PERM_COPY, perm,
 557														GP_OBJECT_MANIPULATE);
 558				if (object->isAttachment() && !can_copy)
 559				{
 560                    //RN: no copy contents of attachments cannot be dragged out
 561                    // due to a race condition and possible exploit where
 562                    // attached objects do not update their inventory items
 563                    // when their contents are manipulated
 564                    return FALSE;
 565				}
 566				if((can_copy && perm.allowTransferTo(gAgent.getID()))
 567				   || object->permYouOwner())
 568//				   || gAgent.isGodlike())
 569
 570				{
 571					*type = LLViewerAssetType::lookupDragAndDropType(inv->getType());
 572
 573					*id = inv->getUUID();
 574					return TRUE;
 575				}
 576			}
 577		}
 578	}
 579	return FALSE;
 580}
 581
 582BOOL LLTaskInvFVBridge::dragOrDrop(MASK mask, BOOL drop,
 583								   EDragAndDropType cargo_type,
 584								   void* cargo_data,
 585								   std::string& tooltip_msg)
 586{
 587	//llinfos << "LLTaskInvFVBridge::dragOrDrop()" << llendl;
 588	return FALSE;
 589}
 590
 591// virtual
 592void LLTaskInvFVBridge::performAction(LLInventoryModel* model, std::string action)
 593{
 594	if (action == "task_buy")
 595	{
 596		// Check the price of the item.
 597		S32 price = getPrice();
 598		if (-1 == price)
 599		{
 600			llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
 601		}
 602		else
 603		{
 604			if (price > 0 && price > gStatusBar->getBalance())
 605			{
 606				LLStringUtil::format_map_t args;
 607				args["AMOUNT"] = llformat("%d", price);
 608				LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("this_costs", args), price );
 609			}
 610			else
 611			{
 612				buyItem();
 613			}
 614		}
 615	}
 616	else if (action == "task_open")
 617	{
 618		openItem();
 619	}
 620	else if (action == "task_properties")
 621	{
 622		showProperties();
 623	}
 624}
 625
 626void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 627{
 628	LLInventoryItem* item = findItem();
 629	std::vector<std::string> items;
 630	std::vector<std::string> disabled_items;
 631	
 632	if (!item)
 633	{
 634		hide_context_entries(menu, items, disabled_items);
 635		return;
 636	}
 637
 638	if(gAgent.allowOperation(PERM_OWNER, item->getPermissions(),
 639							 GP_OBJECT_MANIPULATE)
 640	   && item->getSaleInfo().isForSale())
 641	{
 642		items.push_back(std::string("Task Buy"));
 643
 644		std::string label= LLTrans::getString("Buy");
 645		// Check the price of the item.
 646		S32 price = getPrice();
 647		if (-1 == price)
 648		{
 649			llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
 650		}
 651		else
 652		{
 653			std::ostringstream info;
 654			info << LLTrans::getString("BuyforL$") << price;
 655			label.assign(info.str());
 656		}
 657
 658		const LLView::child_list_t *list = menu.getChildList();
 659		LLView::child_list_t::const_iterator itor;
 660		for (itor = list->begin(); itor != list->end(); ++itor)
 661		{
 662			std::string name = (*itor)->getName();
 663			LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor);
 664			if (name == "Task Buy" && menu_itemp)
 665			{
 666				menu_itemp->setLabel(label);
 667			}
 668		}
 669	}
 670	else if (canOpenItem())
 671	{
 672		items.push_back(std::string("Task Open"));
 673		if (!isItemCopyable())
 674		{
 675			disabled_items.push_back(std::string("Task Open"));
 676		}
 677	}
 678	items.push_back(std::string("Task Properties"));
 679	if(isItemRenameable())
 680	{
 681		items.push_back(std::string("Task Rename"));
 682	}
 683	if(isItemRemovable())
 684	{
 685		items.push_back(std::string("Task Remove"));
 686	}
 687
 688	hide_context_entries(menu, items, disabled_items);
 689}
 690
 691
 692///----------------------------------------------------------------------------
 693/// Class LLTaskFolderBridge
 694///----------------------------------------------------------------------------
 695
 696class LLTaskCategoryBridge : public LLTaskInvFVBridge
 697{
 698public:
 699	LLTaskCategoryBridge(
 700		LLPanelObjectInventory* panel,
 701		const LLUUID& uuid,
 702		const std::string& name);
 703
 704	virtual LLUIImagePtr getIcon() const;
 705	virtual const std::string& getDisplayName() const;
 706	virtual BOOL isItemRenameable() const;
 707	// virtual BOOL isItemCopyable() const { return FALSE; }
 708	virtual BOOL renameItem(const std::string& new_name);
 709	virtual BOOL isItemRemovable() const;
 710	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
 711	virtual BOOL hasChildren() const;
 712	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
 713	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 714							EDragAndDropType cargo_type,
 715							void* cargo_data,
 716							std::string& tooltip_msg);
 717	virtual BOOL canOpenItem() const { return TRUE; }
 718	virtual void openItem();
 719};
 720
 721LLTaskCategoryBridge::LLTaskCategoryBridge(
 722	LLPanelObjectInventory* panel,
 723	const LLUUID& uuid,
 724	const std::string& name) :
 725	LLTaskInvFVBridge(panel, uuid, name)
 726{
 727}
 728
 729LLUIImagePtr LLTaskCategoryBridge::getIcon() const
 730{
 731	return LLUI::getUIImage("Inv_FolderClosed");
 732}
 733
 734// virtual
 735const std::string& LLTaskCategoryBridge::getDisplayName() const
 736{
 737	LLInventoryObject* cat = findInvObject();
 738
 739	if (cat)
 740	{
 741		// Localize "Contents" folder.
 742		if (cat->getParentUUID().isNull() && cat->getName() == "Contents")
 743		{
 744			mDisplayName.assign(LLTrans::getString("ViewerObjectContents"));
 745		}
 746		else
 747		{
 748			mDisplayName.assign(cat->getName());
 749		}
 750	}
 751
 752	return mDisplayName;
 753}
 754
 755BOOL LLTaskCategoryBridge::isItemRenameable() const
 756{
 757	return FALSE;
 758}
 759
 760BOOL LLTaskCategoryBridge::renameItem(const std::string& new_name)
 761{
 762	return FALSE;
 763}
 764
 765BOOL LLTaskCategoryBridge::isItemRemovable() const
 766{
 767	return FALSE;
 768}
 769
 770void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 771{
 772	std::vector<std::string> items;
 773	std::vector<std::string> disabled_items;
 774	hide_context_entries(menu, items, disabled_items);
 775}
 776
 777BOOL LLTaskCategoryBridge::hasChildren() const
 778{
 779	// return TRUE if we have or do know know if we have children.
 780	// *FIX: For now, return FALSE - we will know for sure soon enough.
 781	return FALSE;
 782}
 783
 784void LLTaskCategoryBridge::openItem()
 785{
 786}
 787
 788BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
 789{
 790	//llinfos << "LLTaskInvFVBridge::startDrag()" << llendl;
 791	if(mPanel && mUUID.notNull())
 792	{
 793		LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 794		if(object)
 795		{
 796			const LLInventoryObject* cat = object->getInventoryObject(mUUID);
 797			if ( (cat) && (move_inv_category_world_to_agent(mUUID, LLUUID::null, FALSE)) )
 798			{
 799				*type = LLViewerAssetType::lookupDragAndDropType(cat->getType());
 800				*id = mUUID;
 801				return TRUE;
 802			}
 803		}
 804	}
 805	return FALSE;
 806}
 807
 808BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop,
 809									  EDragAndDropType cargo_type,
 810									  void* cargo_data,
 811									  std::string& tooltip_msg)
 812{
 813	//llinfos << "LLTaskCategoryBridge::dragOrDrop()" << llendl;
 814	BOOL accept = FALSE;
 815	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 816	if(object)
 817	{
 818		switch(cargo_type)
 819		{
 820		case DAD_CATEGORY:
 821			accept = LLToolDragAndDrop::getInstance()->dadUpdateInventoryCategory(object,drop);
 822			break;
 823		case DAD_TEXTURE:
 824		case DAD_SOUND:
 825		case DAD_LANDMARK:
 826		case DAD_OBJECT:
 827		case DAD_NOTECARD:
 828		case DAD_CLOTHING:
 829		case DAD_BODYPART:
 830		case DAD_ANIMATION:
 831		case DAD_GESTURE:
 832		case DAD_CALLINGCARD:
 833		case DAD_MESH:
 834			accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
 835			if(accept && drop)
 836			{
 837				LLToolDragAndDrop::dropInventory(object,
 838												 (LLViewerInventoryItem*)cargo_data,
 839												 LLToolDragAndDrop::getInstance()->getSource(),
 840												 LLToolDragAndDrop::getInstance()->getSourceID());
 841			}
 842			break;
 843		case DAD_SCRIPT:
 844			// *HACK: In order to resolve SL-22177, we need to block
 845			// drags from notecards and objects onto other
 846			// objects. uncomment the simpler version when we have
 847			// that right.
 848			//accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
 849			if(LLToolDragAndDrop::isInventoryDropAcceptable(
 850				   object, (LLViewerInventoryItem*)cargo_data)
 851			   && (LLToolDragAndDrop::SOURCE_WORLD != LLToolDragAndDrop::getInstance()->getSource())
 852			   && (LLToolDragAndDrop::SOURCE_NOTECARD != LLToolDragAndDrop::getInstance()->getSource()))
 853			{
 854				accept = TRUE;
 855			}
 856			if(accept && drop)
 857			{
 858				LLViewerInventoryItem* item = (LLViewerInventoryItem*)cargo_data;
 859				// rez in the script active by default, rez in
 860				// inactive if the control key is being held down.
 861				BOOL active = ((mask & MASK_CONTROL) == 0);
 862				LLToolDragAndDrop::dropScript(object, item, active,
 863											  LLToolDragAndDrop::getInstance()->getSource(),
 864											  LLToolDragAndDrop::getInstance()->getSourceID());
 865			}
 866			break;
 867		default:
 868			break;
 869		}
 870	}
 871	return accept;
 872}
 873
 874///----------------------------------------------------------------------------
 875/// Class LLTaskTextureBridge
 876///----------------------------------------------------------------------------
 877
 878class LLTaskTextureBridge : public LLTaskInvFVBridge
 879{
 880public:
 881	LLTaskTextureBridge(LLPanelObjectInventory* panel,
 882						const LLUUID& uuid,
 883						const std::string& name) :
 884		LLTaskInvFVBridge(panel, uuid, name) {}
 885
 886	virtual BOOL canOpenItem() const { return TRUE; }
 887	virtual void openItem();
 888};
 889
 890void LLTaskTextureBridge::openItem()
 891{
 892	llinfos << "LLTaskTextureBridge::openItem()" << llendl;
 893	LLPreviewTexture* preview = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(mUUID), TAKE_FOCUS_YES);
 894	if(preview)
 895	{
 896		preview->setObjectID(mPanel->getTaskUUID());
 897	}
 898}
 899
 900
 901///----------------------------------------------------------------------------
 902/// Class LLTaskSoundBridge
 903///----------------------------------------------------------------------------
 904
 905class LLTaskSoundBridge : public LLTaskInvFVBridge
 906{
 907public:
 908	LLTaskSoundBridge(LLPanelObjectInventory* panel,
 909					  const LLUUID& uuid,
 910					  const std::string& name) :
 911		LLTaskInvFVBridge(panel, uuid, name) {}
 912
 913	virtual BOOL canOpenItem() const { return TRUE; }
 914	virtual void openItem();
 915	virtual void performAction(LLInventoryModel* model, std::string action);
 916	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
 917	static void openSoundPreview(void* data);
 918};
 919
 920void LLTaskSoundBridge::openItem()
 921{
 922	openSoundPreview((void*)this);
 923}
 924
 925void LLTaskSoundBridge::openSoundPreview(void* data)
 926{
 927	LLTaskSoundBridge* self = (LLTaskSoundBridge*)data;
 928	if(!self)
 929		return;
 930
 931	LLPreviewSound* preview = LLFloaterReg::showTypedInstance<LLPreviewSound>("preview_sound", LLSD(self->mUUID), TAKE_FOCUS_YES);
 932	if (preview)
 933	{
 934		preview->setObjectID(self->mPanel->getTaskUUID());
 935	}
 936}
 937
 938// virtual
 939void LLTaskSoundBridge::performAction(LLInventoryModel* model, std::string action)
 940{
 941	if (action == "task_play")
 942	{
 943		LLInventoryItem* item = findItem();
 944		if(item)
 945		{
 946			send_sound_trigger(item->getAssetUUID(), 1.0);
 947		}
 948	}
 949	LLTaskInvFVBridge::performAction(model, action);
 950}
 951
 952void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 953{
 954	LLInventoryItem* item = findItem();
 955	if(!item) return;
 956	std::vector<std::string> items;
 957	std::vector<std::string> disabled_items;
 958
 959	if(item->getPermissions().getOwner() != gAgent.getID()
 960	   && item->getSaleInfo().isForSale())
 961	{
 962		items.push_back(std::string("Task Buy"));
 963
 964		std::string label= LLTrans::getString("Buy");
 965		// Check the price of the item.
 966		S32 price = getPrice();
 967		if (-1 == price)
 968		{
 969			llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
 970		}
 971		else
 972		{
 973			std::ostringstream info;
 974			info <<  LLTrans::getString("BuyforL$") << price;
 975			label.assign(info.str());
 976		}
 977
 978		const LLView::child_list_t *list = menu.getChildList();
 979		LLView::child_list_t::const_iterator itor;
 980		for (itor = list->begin(); itor != list->end(); ++itor)
 981		{
 982			std::string name = (*itor)->getName();
 983			LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor);
 984			if (name == "Task Buy" && menu_itemp)
 985			{
 986				menu_itemp->setLabel(label);
 987			}
 988		}
 989	}
 990	else if (canOpenItem())
 991	{
 992		if (!isItemCopyable())
 993		{
 994			disabled_items.push_back(std::string("Task Open"));
 995		}
 996	}
 997	items.push_back(std::string("Task Properties"));
 998	if(isItemRenameable())
 999	{
1000		items.push_back(std::string("Task Rename"));
1001	}
1002	if(isItemRemovable())
1003	{
1004		items.push_back(std::string("Task Remove"));
1005	}
1006
1007	items.push_back(std::string("Task Play"));
1008
1009
1010	hide_context_entries(menu, items, disabled_items);
1011}
1012
1013///----------------------------------------------------------------------------
1014/// Class LLTaskLandmarkBridge
1015///----------------------------------------------------------------------------
1016
1017class LLTaskLandmarkBridge : public LLTaskInvFVBridge
1018{
1019public:
1020	LLTaskLandmarkBridge(LLPanelObjectInventory* panel,
1021						 const LLUUID& uuid,
1022						 const std::string& name) :
1023		LLTaskInvFVBridge(panel, uuid, name) {}
1024};
1025
1026///----------------------------------------------------------------------------
1027/// Class LLTaskCallingCardBridge
1028///----------------------------------------------------------------------------
1029
1030class LLTaskCallingCardBridge : public LLTaskInvFVBridge
1031{
1032public:
1033	LLTaskCallingCardBridge(LLPanelObjectInventory* panel,
1034							const LLUUID& uuid,
1035							const std::string& name) :
1036		LLTaskInvFVBridge(panel, uuid, name) {}
1037
1038	virtual BOOL isItemRenameable() const;
1039	virtual BOOL renameItem(const std::string& new_name);
1040};
1041
1042BOOL LLTaskCallingCardBridge::isItemRenameable() const
1043{
1044	return FALSE;
1045}
1046
1047BOOL LLTaskCallingCardBridge::renameItem(const std::string& new_name)
1048{
1049	return FALSE;
1050}
1051
1052
1053///----------------------------------------------------------------------------
1054/// Class LLTaskScriptBridge
1055///----------------------------------------------------------------------------
1056
1057class LLTaskScriptBridge : public LLTaskInvFVBridge
1058{
1059public:
1060	LLTaskScriptBridge(LLPanelObjectInventory* panel,
1061					   const LLUUID& uuid,
1062					   const std::string& name) :
1063		LLTaskInvFVBridge(panel, uuid, name) {}
1064
1065	//static BOOL enableIfCopyable( void* userdata );
1066};
1067
1068class LLTaskLSLBridge : public LLTaskScriptBridge
1069{
1070public:
1071	LLTaskLSLBridge(LLPanelObjectInventory* panel,
1072					const LLUUID& uuid,
1073					const std::string& name) :
1074		LLTaskScriptBridge(panel, uuid, name) {}
1075
1076	virtual BOOL canOpenItem() const { return TRUE; }
1077	virtual void openItem();
1078	virtual BOOL removeItem();
1079	//virtual void buildContextMenu(LLMenuGL& menu);
1080
1081	//static void copyToInventory(void* userdata);
1082};
1083
1084void LLTaskLSLBridge::openItem()
1085{
1086	llinfos << "LLTaskLSLBridge::openItem() " << mUUID << llendl;
1087	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
1088	if(!object || object->isInventoryPending())
1089	{
1090		return;
1091	}
1092	if (object->permModify() || gAgent.isGodlike())
1093	{
1094		LLLiveLSLEditor* preview = LLFloaterReg::showTypedInstance<LLLiveLSLEditor>("preview_scriptedit", LLSD(mUUID), TAKE_FOCUS_YES);
1095		if (preview)
1096		{
1097			preview->setObjectID(mPanel->getTaskUUID());
1098		}
1099	}
1100	else
1101	{	
1102		LLNotificationsUtil::add("CannotOpenScriptObjectNoMod");
1103	}
1104}
1105
1106BOOL LLTaskLSLBridge::removeItem()
1107{
1108	LLFloaterReg::hideInstance("preview_scriptedit", LLSD(mUUID));
1109	return LLTaskInvFVBridge::removeItem();
1110}
1111
1112///----------------------------------------------------------------------------
1113/// Class LLTaskObjectBridge
1114///----------------------------------------------------------------------------
1115
1116class LLTaskObjectBridge : public LLTaskInvFVBridge
1117{
1118public:
1119	LLTaskObjectBridge(LLPanelObjectInventory* panel,
1120					   const LLUUID& uuid,
1121					   const std::string& name,
1122					   U32 flags = 0) :
1123		LLTaskInvFVBridge(panel, uuid, name, flags) {}
1124};
1125
1126///----------------------------------------------------------------------------
1127/// Class LLTaskNotecardBridge
1128///----------------------------------------------------------------------------
1129
1130class LLTaskNotecardBridge : public LLTaskInvFVBridge
1131{
1132public:
1133	LLTaskNotecardBridge(LLPanelObjectInventory* panel,
1134						 const LLUUID& uuid,
1135						 const std::string& name) :
1136		LLTaskInvFVBridge(panel, uuid, name) {}
1137
1138	virtual BOOL canOpenItem() const { return TRUE; }
1139	virtual void openItem();
1140	virtual BOOL removeItem();
1141};
1142
1143void LLTaskNotecardBridge::openItem()
1144{
1145	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
1146	if(!object || object->isInventoryPending())
1147	{
1148		return;
1149	}
1150	if(object->permModify() || gAgent.isGodlike())
1151	{
1152		LLPreviewNotecard* preview = LLFloaterReg::showTypedInstance<LLPreviewNotecard>("preview_notecard", LLSD(mUUID), TAKE_FOCUS_YES);
1153		if (preview)
1154		{
1155			preview->setObjectID(mPanel->getTaskUUID());
1156		}
1157	}
1158}
1159
1160BOOL LLTaskNotecardBridge::removeItem()
1161{
1162	LLFloaterReg::hideInstance("preview_notecard", LLSD(mUUID));
1163	return LLTaskInvFVBridge::removeItem();
1164}
1165
1166///----------------------------------------------------------------------------
1167/// Class LLTaskGestureBridge
1168///----------------------------------------------------------------------------
1169
1170class LLTaskGestureBridge : public LLTaskInvFVBridge
1171{
1172public:
1173	LLTaskGestureBridge(LLPanelObjectInventory* panel,
1174						const LLUUID& uuid,
1175						const std::string& name) :
1176	LLTaskInvFVBridge(panel, uuid, name) {}
1177
1178	virtual BOOL canOpenItem() const { return TRUE; }
1179	virtual void openItem();
1180	virtual BOOL removeItem();
1181};
1182
1183void LLTaskGestureBridge::openItem()
1184{
1185	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
1186	if(!object || object->isInventoryPending())
1187	{
1188		return;
1189	}
1190	LLPreviewGesture::show(mUUID, mPanel->getTaskUUID());
1191}
1192
1193BOOL LLTaskGestureBridge::removeItem()
1194{
1195	// Don't need to deactivate gesture because gestures inside objects can never be active.
1196	LLFloaterReg::hideInstance("preview_gesture", LLSD(mUUID));
1197	return LLTaskInvFVBridge::removeItem();
1198}
1199
1200///----------------------------------------------------------------------------
1201/// Class LLTaskAnimationBridge
1202///----------------------------------------------------------------------------
1203
1204class LLTaskAnimationBridge : public LLTaskInvFVBridge
1205{
1206public:
1207	LLTaskAnimationBridge(LLPanelObjectInventory* panel,
1208						  const LLUUID& uuid,
1209						  const std::string& name) :
1210		LLTaskInvFVBridge(panel, uuid, name) {}
1211
1212	virtual BOOL canOpenItem() const { return TRUE; }
1213	virtual void openItem();
1214	virtual BOOL removeItem();
1215};
1216
1217void LLTaskAnimationBridge::openItem()
1218{
1219	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
1220	if(!object || object->isInventoryPending())
1221	{
1222		return;
1223	}
1224
1225	LLPreviewAnim* preview = LLFloaterReg::showTypedInstance<LLPreviewAnim>("preview_anim", LLSD(mUUID), TAKE_FOCUS_YES);
1226	if (preview && (object->permModify() || gAgent.isGodlike()))
1227	{
1228		preview->setObjectID(mPanel->getTaskUUID());
1229	}
1230}
1231
1232BOOL LLTaskAnimationBridge::removeItem()
1233{
1234	LLFloaterReg::hideInstance("preview_anim", LLSD(mUUID));
1235	return LLTaskInvFVBridge::removeItem();
1236}
1237
1238///----------------------------------------------------------------------------
1239/// Class LLTaskWearableBridge
1240///----------------------------------------------------------------------------
1241
1242class LLTaskWearableBridge : public LLTaskInvFVBridge
1243{
1244public:
1245	LLTaskWearableBridge(LLPanelObjectInventory* panel,
1246						 const LLUUID& uuid,
1247						 const std::string& name,
1248						 U32 flags) :
1249		LLTaskInvFVBridge(panel, uuid, name, flags) {}
1250
1251	virtual LLUIImagePtr getIcon() const;
1252};
1253
1254LLUIImagePtr LLTaskWearableBridge::getIcon() const
1255{
1256	return LLInventoryIcon::getIcon(mAssetType, mInventoryType, mFlags, FALSE );
1257}
1258
1259///----------------------------------------------------------------------------
1260/// Class LLTaskMeshBridge
1261///----------------------------------------------------------------------------
1262
1263class LLTaskMeshBridge : public LLTaskInvFVBridge
1264{
1265public:
1266	LLTaskMeshBridge(
1267		LLPanelObjectInventory* panel,
1268		const LLUUID& uuid,
1269		const std::string& name);
1270
1271	virtual LLUIImagePtr getIcon() const;
1272	virtual void openItem();
1273	virtual void performAction(LLInventoryModel* model, std::string action);
1274	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
1275};
1276
1277LLTaskMeshBridge::LLTaskMeshBridge(
1278	LLPanelObjectInventory* panel,
1279	const LLUUID& uuid,
1280	const std::string& name) :
1281	LLTaskInvFVBridge(panel, uuid, name)
1282{
1283}
1284
1285LLUIImagePtr LLTaskMeshBridge::getIcon() const
1286{
1287	return LLInventoryIcon::getIcon(LLAssetType::AT_MESH, LLInventoryType::IT_MESH, 0, FALSE);
1288}
1289
1290void LLTaskMeshBridge::openItem()
1291{
1292	// open mesh
1293}
1294
1295
1296// virtual
1297void LLTaskMeshBridge::performAction(LLInventoryModel* model, std::string action)
1298{
1299	if (action == "mesh action")
1300	{
1301		LLInventoryItem* item = findItem();
1302		if(item)
1303		{
1304			// do action
1305		}
1306	}
1307	LLTaskInvFVBridge::performAction(model, action);
1308}
1309
1310void LLTaskMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
1311{
1312	LLInventoryItem* item = findItem();
1313	if(!item) return;
1314	std::vector<std::string> items;
1315	std::vector<std::string> disabled_items;
1316
1317	if(item->getPermissions().getOwner() != gAgent.getID()
1318	   && item->getSaleInfo().isForSale())
1319	{
1320		items.push_back(std::string("Task Buy"));
1321
1322		std::string label= LLTrans::getString("Buy");
1323		// Check the price of the item.
1324		S32 price = getPrice();
1325		if (-1 == price)
1326		{
1327			llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
1328		}
1329		else
1330		{
1331			std::ostringstream info;
1332			info <<  LLTrans::getString("BuyforL$") << price;
1333			label.assign(info.str());
1334		}
1335
1336		const LLView::child_list_t *list = menu.getChildList();
1337		LLView::child_list_t::const_iterator itor;
1338		for (itor = list->begin(); itor != list->end(); ++itor)
1339		{
1340			std::string name = (*itor)->getName();
1341			LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor);
1342			if (name == "Task Buy" && menu_itemp)
1343			{
1344				menu_itemp->setLabel(label);
1345			}
1346		}
1347	}
1348	else
1349	{
1350		items.push_back(std::string("Task Open")); 
1351		if (!isItemCopyable())
1352		{
1353			disabled_items.push_back(std::string("Task Open"));
1354		}
1355	}
1356	items.push_back(std::string("Task Properties"));
1357	if(isItemRenameable())
1358	{
1359		items.push_back(std::string("Task Rename"));
1360	}
1361	if(isItemRemovable())
1362	{
1363		items.push_back(std::string("Task Remove"));
1364	}
1365
1366
1367	hide_context_entries(menu, items, disabled_items);
1368}
1369
1370///----------------------------------------------------------------------------
1371/// LLTaskInvFVBridge impl
1372//----------------------------------------------------------------------------
1373
1374LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory* panel,
1375														 LLInventoryObject* object)
1376{
1377	LLTaskInvFVBridge* new_bridge = NULL;
1378	const LLInventoryItem* item = dynamic_cast<LLInventoryItem*>(object);
1379	const U32 itemflags = ( NULL == item ? 0 : item->getFlags() );
1380	LLAssetType::EType type = object ? object->getType() : LLAssetType::AT_CATEGORY;
1381	LLUUID object_id = object ? object->getUUID() : LLUUID::null;
1382	std::string object_name = object ? object->getName() : std::string();
1383
1384	switch(type)
1385	{
1386	case LLAssetType::AT_TEXTURE:
1387		new_bridge = new LLTaskTextureBridge(panel,
1388						     object_id,
1389						     object_name);
1390		break;
1391	case LLAssetType::AT_SOUND:
1392		new_bridge = new LLTaskSoundBridge(panel,
1393						   object_id,
1394						   object_name);
1395		break;
1396	case LLAssetType::AT_LANDMARK:
1397		new_bridge = new LLTaskLandmarkBridge(panel,
1398						      object_id,
1399						      object_name);
1400		break;
1401	case LLAssetType::AT_CALLINGCARD:
1402		new_bridge = new LLTaskCallingCardBridge(panel,
1403							 object_id,
1404							 object_name);
1405		break;
1406	case LLAssetType::AT_SCRIPT:
1407		// OLD SCRIPTS DEPRECATED - JC
1408		llwarns << "Old script" << llendl;
1409		//new_bridge = new LLTaskOldScriptBridge(panel,
1410		//									   object_id,
1411		//									   object_name);
1412		break;
1413	case LLAssetType::AT_OBJECT:
1414		new_bridge = new LLTaskObjectBridge(panel,
1415						    object_id,
1416						    object_name,
1417						    itemflags);
1418		break;
1419	case LLAssetType::AT_NOTECARD:
1420		new_bridge = new LLTaskNotecardBridge(panel,
1421						      object_id,
1422						      object_name);
1423		break;
1424	case LLAssetType::AT_ANIMATION:
1425		new_bridge = new LLTaskAnimationBridge(panel,
1426						       object_id,
1427						       object_name);
1428		break;
1429	case LLAssetType::AT_GESTURE:
1430		new_bridge = new LLTaskGestureBridge(panel,
1431						     object_id,
1432						     object_name);
1433		break;
1434	case LLAssetType::AT_CLOTHING:
1435	case LLAssetType::AT_BODYPART:
1436		new_bridge = new LLTaskWearableBridge(panel,
1437						      object_id,
1438						      object_name,
1439						      itemflags);
1440		break;
1441	case LLAssetType::AT_CATEGORY:
1442		new_bridge = new LLTaskCategoryBridge(panel,
1443						      object_id,
1444						      object_name);
1445		break;
1446	case LLAssetType::AT_LSL_TEXT:
1447		new_bridge = new LLTaskLSLBridge(panel,
1448						 object_id,
1449						 object_name);
1450		break;
1451	case LLAssetType::AT_MESH:
1452		new_bridge = new LLTaskMeshBridge(panel,
1453										  object_id,
1454										  object_name);
1455		break;
1456	default:
1457		llinfos << "Unhandled inventory type (llassetstorage.h): "
1458				<< (S32)type << llendl;
1459		break;
1460	}
1461	return new_bridge;
1462}
1463
1464
1465///----------------------------------------------------------------------------
1466/// Class LLPanelObjectInventory
1467///----------------------------------------------------------------------------
1468
1469static LLDefaultChildRegistry::Register<LLPanelObjectInventory> r("panel_inventory_object");
1470
1471void do_nothing()
1472{
1473}
1474
1475// Default constructor
1476LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Params& p) :
1477	LLPanel(p),
1478	mScroller(NULL),
1479	mFolders(NULL),
1480	mHaveInventory(FALSE),
1481	mIsInventoryEmpty(TRUE),
1482	mInventoryNeedsUpdate(FALSE)
1483{
1484	// Setup context menu callbacks
1485	mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelObjectInventory::doToSelected, this, _2));
1486	mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH));
1487	mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND));
1488	mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&do_nothing));
1489	mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&do_nothing));
1490	mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&do_nothing));
1491	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars));
1492}
1493
1494// Destroys the object
1495LLPanelObjectInventory::~LLPanelObjectInventory()
1496{
1497	if (!gIdleCallbacks.deleteFunction(idle, this))
1498	{
1499		llwarns << "LLPanelObjectInventory::~LLPanelObjectInventory() failed to delete callback" << llendl;
1500	}
1501}
1502
1503BOOL LLPanelObjectInventory::postBuild()
1504{
1505	// clear contents and initialize menus, sets up mFolders
1506	reset();
1507
1508	// Register an idle update callback
1509	gIdleCallbacks.addFunction(idle, this);
1510
1511	return TRUE;
1512}
1513
1514void LLPanelObjectInventory::doToSelected(const LLSD& userdata)
1515{
1516	mFolders->doToSelected(&gInventory, userdata);
1517}
1518
1519void LLPanelObjectInventory::clearContents()
1520{
1521	mHaveInventory = FALSE;
1522	mIsInventoryEmpty = TRUE;
1523	if (LLToolDragAndDrop::getInstance() && LLToolDragAndDrop::getInstance()->getSource() == LLToolDragAndDrop::SOURCE_WORLD)
1524	{
1525		LLToolDragAndDrop::getInstance()->endDrag();
1526	}
1527
1528	if( mScroller )
1529	{
1530		// removes mFolders
1531		removeChild( mScroller ); //*TODO: Really shouldn't do this during draw()/refresh()
1532		mScroller->die();
1533		mScroller = NULL;
1534		mFolders = NULL;
1535	}
1536}
1537
1538
1539void LLPanelObjectInventory::reset()
1540{
1541	clearContents();
1542
1543	//setBorderVisible(FALSE);
1544	
1545	mCommitCallbackRegistrar.pushScope(); // push local callbacks
1546	
1547	LLRect dummy_rect(0, 1, 1, 0);
1548	LLFolderView::Params p;
1549	p.name = "task inventory";
1550	p.title = "task inventory";
1551	p.task_id = getTaskUUID();
1552	p.parent_panel = this;
1553	p.tool_tip= LLTrans::getString("PanelContentsTooltip");
1554	p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL);
1555	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
1556	// this ensures that we never say "searching..." or "no items found"
1557	mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
1558	mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
1559
1560	if (hasFocus())
1561	{
1562		LLEditMenuHandler::gEditMenuHandler = mFolders;
1563	}
1564
1565	LLRect scroller_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
1566	LLScrollContainer::Params scroll_p;
1567	scroll_p.name("task inventory scroller");
1568	scroll_p.rect(scroller_rect);
1569	scroll_p.tab_stop(true);
1570	scroll_p.follows.flags(FOLLOWS_ALL);
1571	mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroll_p);
1572	addChild(mScroller);
1573	mScroller->addChild(mFolders);
1574	
1575	mFolders->setScrollContainer( mScroller );
1576	
1577	mCommitCallbackRegistrar.popScope();
1578}
1579
1580void LLPanelObjectInventory::inventoryChanged(LLViewerObject* object,
1581										LLInventoryObject::object_list_t* inventory,
1582										S32 serial_num,
1583										void* data)
1584{
1585	if(!object) return;
1586
1587	//llinfos << "invetnory arrived: \n"
1588	//		<< " panel UUID: " << panel->mTaskUUID << "\n"
1589	//		<< " task  UUID: " << object->mID << llendl;
1590	if(mTaskUUID == object->mID)
1591	{
1592		mInventoryNeedsUpdate = TRUE;
1593	}
1594
1595	// refresh any properties floaters that are hanging around.
1596	if(inventory)
1597	{
1598		for (LLInventoryObject::object_list_t::const_iterator iter = inventory->begin();
1599			 iter != inventory->end(); )
1600		{
1601			LLInventoryObject* item = *iter++;
1602			LLFloaterProperties* floater = LLFloaterReg::findTypedInstance<LLFloaterProperties>("properites", item->getUUID());
1603			if(floater)
1604			{
1605				floater->refresh();
1606			}
1607		}
1608	}
1609}
1610
1611void LLPanelObjectInventory::updateInventory()
1612{
1613	//llinfos << "inventory arrived: \n"
1614	//		<< " panel UUID: " << panel->mTaskUUID << "\n"
1615	//		<< " task  UUID: " << object->mID << llendl;
1616	// We're still interested in this task's inventory.
1617	std::set<LLUUID> selected_items;
1618	BOOL inventory_has_focus = FALSE;
1619	if (mHaveInventory)
1620	{
1621		selected_items = mFolders->getSelectionList();
1622		inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders);
1623	}
1624
1625	reset();
1626
1627	LLViewerObject* objectp = gObjectList.findObject(mTaskUUID);
1628	if (objectp)
1629	{
1630		LLInventoryObject* inventory_root = objectp->getInventoryRoot();
1631		LLInventoryObject::object_list_t contents;
1632		objectp->getInventoryContents(contents);
1633		if (inventory_root)
1634		{
1635			createFolderViews(inventory_root, contents);
1636			mHaveInventory = TRUE;
1637			mIsInventoryEmpty = FALSE;
1638			mFolders->setEnabled(TRUE);
1639		}
1640		else
1641		{
1642			// TODO: create an empty inventory
1643			mIsInventoryEmpty = TRUE;
1644			mHaveInventory = TRUE;
1645		}
1646	}
1647	else
1648	{
1649		// TODO: create an empty inventory
1650		mIsInventoryEmpty = TRUE;
1651		mHaveInventory = TRUE;
1652	}
1653
1654	// restore previous selection
1655	std::set<LLUUID>::iterator selection_it;
1656	BOOL first_item = TRUE;
1657	for (selection_it = selected_items.begin(); selection_it != selected_items.end(); ++selection_it)
1658	{
1659		LLFolderViewItem* selected_item = mFolders->getItemByID(*selection_it);
1660		if (selected_item)
1661		{
1662			//HACK: "set" first item then "change" each other one to get keyboard focus right
1663			if (first_item)
1664			{
1665				mFolders->setSelection(selected_item, TRUE, inventory_has_focus);
1666				first_item = FALSE;
1667			}
1668			else
1669			{
1670				mFolders->changeSelection(selected_item, TRUE);
1671			}
1672		}
1673	}
1674
1675	mFolders->requestArrange();
1676	mInventoryNeedsUpdate = FALSE;
1677	// Edit menu handler is set in onFocusReceived
1678}
1679
1680// *FIX: This is currently a very expensive operation, because we have
1681// to iterate through the inventory one time for each category. This
1682// leads to an N^2 based on the category count. This could be greatly
1683// speeded with an efficient multimap implementation, but we don't
1684// have that in our current arsenal.
1685void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root, LLInventoryObject::object_list_t& contents)
1686{
1687	if (!inventory_root)
1688	{
1689		return;
1690	}
1691	// Create a visible root category.
1692	LLTaskInvFVBridge* bridge = NULL;
1693	bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root);
1694	if(bridge)
1695	{
1696		LLFolderViewFolder* new_folder = NULL;
1697		LLFolderViewFolder::Params p;
1698		p.name = inventory_root->getName();
1699		p.icon = LLUI::getUIImage("Inv_FolderClosed");
1700		p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
1701		p.root = mFolders;
1702		p.listener = bridge;
1703		p.tool_tip = p.name;
1704		new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
1705		new_folder->addToFolder(mFolders, mFolders);
1706		new_folder->toggleOpen();
1707
1708		createViewsForCategory(&contents, inventory_root, new_folder);
1709	}
1710}
1711
1712typedef std::pair<LLInventoryObject*, LLFolderViewFolder*> obj_folder_pair;
1713
1714void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_list_t* inventory, 
1715											  LLInventoryObject* parent,
1716											  LLFolderViewFolder* folder)
1717{
1718	// Find all in the first pass
1719	LLDynamicArray<obj_folder_pair*> child_categories;
1720	LLTaskInvFVBridge* bridge;
1721	LLFolderViewItem* view;
1722
1723	LLInventoryObject::object_list_t::iterator it = inventory->begin();
1724	LLInventoryObject::object_list_t::iterator end = inventory->end();
1725	for( ; it != end; ++it)
1726	{
1727		LLInventoryObject* obj = *it;
1728
1729		if(parent->getUUID() == obj->getParentUUID())
1730		{
1731			bridge = LLTaskInvFVBridge::createObjectBridge(this, obj);
1732			if(!bridge)
1733			{
1734				continue;
1735			}
1736			if(LLAssetType::AT_CATEGORY == obj->getType())
1737			{
1738				LLFolderViewFolder::Params p;
1739				p.name = obj->getName();
1740				p.icon = LLUI::getUIImage("Inv_FolderClosed");
1741				p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
1742				p.root = mFolders;
1743				p.listener = bridge;
1744				p.tool_tip = p.name;
1745				view = LLUICtrlFactory::create<LLFolderViewFolder>(p);
1746				child_categories.put(new obj_folder_pair(obj,
1747														 (LLFolderViewFolder*)view));
1748			}
1749			else
1750			{
1751				LLFolderViewItem::Params params;
1752				params.name(obj->getName());
1753				params.icon(bridge->getIcon());
1754				params.creation_date(bridge->getCreationDate());
1755				params.root(mFolders);
1756				params.listener(bridge);
1757				params.rect(LLRect());
1758				params.tool_tip = params.name;
1759				view = LLUICtrlFactory::create<LLFolderViewItem> (params);
1760			}
1761			view->addToFolder(folder, mFolders);
1762		}
1763	}
1764
1765	// now, for each category, do the second pass
1766	for(S32 i = 0; i < child_categories.count(); i++)
1767	{
1768		createViewsForCategory(inventory, child_categories[i]->first,
1769							   child_categories[i]->second );
1770		delete child_categories[i];
1771	}
1772}
1773
1774void LLPanelObjectInventory::refresh()
1775{
1776	//llinfos << "LLPanelObjectInventory::refresh()" << llendl;
1777	BOOL has_inventory = FALSE;
1778	const BOOL non_root_ok = TRUE;
1779	LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(NULL, non_root_ok);
1780	if(node)
1781	{
1782		LLViewerObject* object = node->getObject();
1783		if(object && ((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1)
1784					  || (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)))
1785		{
1786			// determine if we need to make a request. Start with a
1787			// default based on if we have invento…

Large files files are truncated, but you can click here to view the full file