llpanelinventory.cpp

Go to the documentation of this file.
00001 
00032 //*****************************************************************************
00033 //
00034 // Implementation of the panel inventory - used to view and control a
00035 // task's inventory.
00036 //
00037 //*****************************************************************************
00038 
00039 #include "llviewerprecompiledheaders.h"
00040 
00041 #include <sstream> // for std::ostringstream
00042 #include <utility> // for std::pair<>
00043 
00044 #include "stdenums.h"
00045 #include "llpanelinventory.h"
00046 
00047 #include "message.h"
00048 #include "lldarray.h"
00049 #include "llfontgl.h"
00050 #include "llassetstorage.h"
00051 #include "llinventory.h"
00052 
00053 #include "llagent.h"
00054 #include "llcallbacklist.h"
00055 #include "llfocusmgr.h"
00056 #include "llfloaterbuycurrency.h"
00057 #include "llfloaterproperties.h"
00058 #include "llfolderview.h"
00059 #include "llgl.h"
00060 #include "llinventorymodel.h"
00061 #include "llinventoryview.h"
00062 #include "llmenugl.h"
00063 #include "llpreviewanim.h"
00064 #include "llpreviewgesture.h"
00065 #include "llpreviewnotecard.h"
00066 #include "llpreviewscript.h"
00067 #include "llpreviewsound.h"
00068 #include "llpreviewtexture.h"
00069 #include "roles_constants.h"
00070 #include "llscrollcontainer.h"
00071 #include "llselectmgr.h"
00072 #include "llstatusbar.h"
00073 #include "lltooldraganddrop.h"
00074 #include "llviewercontrol.h"
00075 #include "llviewerregion.h"
00076 #include "llviewerimagelist.h"
00077 #include "llviewerinventory.h"
00078 #include "llviewermessage.h"
00079 #include "llviewerobject.h"
00080 #include "llviewerobjectlist.h"
00081 #include "llviewerwindow.h"
00082 #include "llwearable.h"
00083 
00087 
00088 
00092 
00093 class LLTaskInvFVBridge : public LLFolderViewEventListener
00094 {
00095 protected:
00096         LLUUID mUUID;
00097         LLString mName;
00098         mutable LLString mDisplayName;
00099         LLPanelInventory* mPanel;
00100         U32 mFlags;
00101 
00102         LLInventoryItem* findItem() const;
00103 
00104 public:
00105         LLTaskInvFVBridge(
00106                 LLPanelInventory* panel,
00107                 const LLUUID& uuid,
00108                 const LLString& name,
00109                 U32 flags=0);
00110         virtual ~LLTaskInvFVBridge( void ) {}
00111 
00112         virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
00113         virtual LLString getLabelSuffix() const { return LLString::null; }
00114 
00115         static LLTaskInvFVBridge* createObjectBridge(LLPanelInventory* panel,
00116                                                                                                  LLInventoryObject* object);
00117         void showProperties();
00118         void buyItem();
00119         S32 getPrice();
00120         static void commitBuyItem(S32 option, void* data);
00121 
00122         // LLFolderViewEventListener functionality
00123         virtual const LLString& getName() const;
00124         virtual const LLString& getDisplayName() const;
00125         virtual PermissionMask getPermissionMask() const { return PERM_NONE; }
00126         virtual const LLUUID& getUUID() const { return mUUID; }
00127         virtual U32 getCreationDate() const;
00128         virtual LLUIImagePtr getIcon() const;
00129         virtual void openItem();
00130         virtual void previewItem();
00131         virtual void selectItem() {}
00132         virtual BOOL isItemRenameable() const;
00133         virtual BOOL renameItem(const LLString& new_name);
00134         virtual BOOL isItemMovable();
00135         virtual BOOL isItemRemovable();
00136         virtual BOOL removeItem();
00137         virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
00138         virtual void move(LLFolderViewEventListener* parent_listener);
00139         virtual BOOL isItemCopyable() const;
00140         virtual BOOL copyToClipboard() const;
00141         virtual void cutToClipboard();
00142         virtual BOOL isClipboardPasteable() const;
00143         virtual void pasteFromClipboard();
00144         virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
00145         virtual void performAction(LLFolderView* folder, LLInventoryModel* model, LLString action);
00146         virtual BOOL isUpToDate() const { return TRUE; }
00147         virtual BOOL hasChildren() const { return FALSE; }
00148         virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
00149         // LLDragAndDropBridge functionality
00150         virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
00151         virtual BOOL dragOrDrop(MASK mask, BOOL drop,
00152                                                         EDragAndDropType cargo_type,
00153                                                         void* cargo_data);
00154 //      virtual void dropped();
00155 
00156 };
00157 
00158 LLTaskInvFVBridge::LLTaskInvFVBridge(
00159         LLPanelInventory* panel,
00160         const LLUUID& uuid,
00161         const LLString& name,
00162         U32 flags):
00163         mUUID(uuid),
00164         mName(name),
00165         mPanel(panel),
00166         mFlags(flags)
00167 {
00168 
00169 }
00170 
00171 LLInventoryItem* LLTaskInvFVBridge::findItem() const
00172 {
00173         LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
00174         if(object)
00175         {
00176                 return (LLInventoryItem*)(object->getInventoryObject(mUUID));
00177         }
00178         return NULL;
00179 }
00180 
00181 void LLTaskInvFVBridge::showProperties()
00182 {
00183         if(!LLFloaterProperties::show(mUUID, mPanel->getTaskUUID()))
00184         {
00185                 S32 left, top;
00186                 gFloaterView->getNewFloaterPosition(&left, &top);
00187                 LLRect rect = gSavedSettings.getRect("PropertiesRect");
00188                 rect.translate( left - rect.mLeft, top - rect.mTop );
00189                 LLFloaterProperties* floater = new LLFloaterProperties("obj item properties",
00190                                                                                                            rect,
00191                                                                                                            "Object Inventory Item Properties",
00192                                                                                                            mUUID,
00193                                                                                                            mPanel->getTaskUUID());
00194                 floater->open();                /*Flawfinder: ignore*/
00195         }
00196 }
00197 
00198 struct LLBuyInvItemData
00199 {
00200         LLUUID mTaskID;
00201         LLUUID mItemID;
00202         LLAssetType::EType mType;
00203 
00204         LLBuyInvItemData(const LLUUID& task,
00205                                          const LLUUID& item,
00206                                          LLAssetType::EType type) :
00207                 mTaskID(task), mItemID(item), mType(type)
00208         {}
00209 };
00210 
00211 void LLTaskInvFVBridge::buyItem()
00212 {
00213         llinfos << "LLTaskInvFVBridge::buyItem()" << llendl;
00214         LLInventoryItem* item = findItem();
00215         if(!item || !item->getSaleInfo().isForSale()) return;
00216         LLBuyInvItemData* inv = new LLBuyInvItemData(mPanel->getTaskUUID(),
00217                                                                                                  mUUID,
00218                                                                                                  item->getType());
00219 
00220         const LLSaleInfo& sale_info = item->getSaleInfo();
00221         const LLPermissions& perm = item->getPermissions();
00222         const LLString owner_name; // no owner name currently... FIXME?
00223 
00224         LLViewerObject* obj;
00225         if( ( obj = gObjectList.findObject( mPanel->getTaskUUID() ) ) && obj->isAttachment() )
00226         {
00227                 gViewerWindow->alertXml("Cannot_Purchase_an_Attachment");
00228                 llinfos << "Attempt to purchase an attachment" << llendl;
00229                 delete inv;
00230         }
00231         else
00232         {
00233         LLString::format_map_t args;
00234         args["[PRICE]"] = llformat("%d",sale_info.getSalePrice());
00235         args["[OWNER]"] = owner_name;
00236         if (sale_info.getSaleType() != LLSaleInfo::FS_CONTENTS)
00237         {
00238                 U32 next_owner_mask = perm.getMaskNextOwner();
00239                 args["[MODIFYPERM]"] = LLAlertDialog::getTemplateMessage((next_owner_mask & PERM_MODIFY) ? "PermYes" : "PermNo");
00240                 args["[COPYPERM]"] = LLAlertDialog::getTemplateMessage((next_owner_mask & PERM_COPY) ? "PermYes" : "PermNo");
00241                 args["[RESELLPERM]"] = LLAlertDialog::getTemplateMessage((next_owner_mask & PERM_TRANSFER) ? "PermYes" : "PermNo");
00242         }
00243 
00244                 LLString alertdesc;
00245         switch(sale_info.getSaleType())
00246         {
00247           case LLSaleInfo::FS_ORIGINAL:
00248                 alertdesc = owner_name.empty() ? "BuyOriginalNoOwner" : "BuyOriginal";
00249                 break;
00250           case LLSaleInfo::FS_CONTENTS:
00251                 alertdesc = owner_name.empty() ? "BuyContentsNoOwner" : "BuyContents";
00252                 break;
00253                   case LLSaleInfo::FS_COPY:
00254           default:
00255                 alertdesc = owner_name.empty() ? "BuyCopyNoOwner" : "BuyCopy";
00256                 break;
00257         }
00258 
00259         gViewerWindow->alertXml(alertdesc, args, LLTaskInvFVBridge::commitBuyItem, (void*)inv);
00260         }
00261 }
00262 
00263 S32 LLTaskInvFVBridge::getPrice()
00264 {
00265         LLInventoryItem* item = findItem();
00266         if(item)
00267         {
00268                 return item->getSaleInfo().getSalePrice();
00269         }
00270         else
00271         {
00272                 return -1;
00273         }
00274 }
00275 
00276 // static
00277 void LLTaskInvFVBridge::commitBuyItem(S32 option, void* data)
00278 {
00279         LLBuyInvItemData* inv = (LLBuyInvItemData*)data;
00280         if(!inv) return;
00281         if(0 == option)
00282         {
00283                 LLViewerObject* object = gObjectList.findObject(inv->mTaskID);
00284                 if(!object || !object->getRegion()) return;
00285 
00286 
00287                 LLMessageSystem* msg = gMessageSystem;
00288                 msg->newMessageFast(_PREHASH_BuyObjectInventory);
00289                 msg->nextBlockFast(_PREHASH_AgentData);
00290                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00291                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00292                 msg->nextBlockFast(_PREHASH_Data);
00293                 msg->addUUIDFast(_PREHASH_ObjectID, inv->mTaskID);
00294                 msg->addUUIDFast(_PREHASH_ItemID, inv->mItemID);
00295                 msg->addUUIDFast(_PREHASH_FolderID,
00296                                                  gInventory.findCategoryUUIDForType(inv->mType));
00297                 msg->sendReliable(object->getRegion()->getHost());
00298         }
00299         delete inv;
00300 }
00301 
00302 const LLString& LLTaskInvFVBridge::getName() const
00303 {
00304         return mName;
00305 }
00306 
00307 const LLString& LLTaskInvFVBridge::getDisplayName() const
00308 {
00309         LLInventoryItem* item = findItem();
00310         if(item)
00311         {
00312                 mDisplayName.assign(item->getName());
00313 
00314                 const LLPermissions& perm(item->getPermissions());
00315                 BOOL copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE);
00316                 BOOL mod  = gAgent.allowOperation(PERM_MODIFY, perm, GP_OBJECT_MANIPULATE);
00317                 BOOL xfer = gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE);
00318 
00319                 if(!copy)
00320                 {
00321                         mDisplayName.append(" (no copy)");
00322                 }
00323                 if(!mod)
00324                 {
00325                         mDisplayName.append(" (no modify)");
00326                 }
00327                 if(!xfer)
00328                 {
00329                         mDisplayName.append(" (no transfer)");
00330                 }
00331         }
00332 
00333         return mDisplayName;
00334 }
00335 
00336 // BUG: No creation dates for task inventory
00337 U32 LLTaskInvFVBridge::getCreationDate() const
00338 {
00339         return 0;
00340 }
00341 
00342 LLUIImagePtr LLTaskInvFVBridge::getIcon() const
00343 {
00344         BOOL item_is_multi = FALSE;
00345         if ( mFlags & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS )
00346         {
00347                 item_is_multi = TRUE;
00348         }
00349 
00350         return get_item_icon(LLAssetType::AT_OBJECT, LLInventoryType::IT_OBJECT, 0, item_is_multi );
00351 }
00352 
00353 void LLTaskInvFVBridge::openItem()
00354 {
00355         // no-op.
00356         lldebugs << "LLTaskInvFVBridge::openItem()" << llendl;
00357 }
00358 
00359 void LLTaskInvFVBridge::previewItem()
00360 {
00361         openItem();
00362 }
00363 
00364 BOOL LLTaskInvFVBridge::isItemRenameable() const
00365 {
00366         if(gAgent.isGodlike()) return TRUE;
00367         LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
00368         if(object)
00369         {
00370                 LLInventoryItem* item;
00371                 item = (LLInventoryItem*)(object->getInventoryObject(mUUID));
00372                 if(item && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
00373                                                                                  GP_OBJECT_MANIPULATE, GOD_LIKE))
00374                 {
00375                         return TRUE;
00376                 }
00377         }
00378         return FALSE;
00379 }
00380 
00381 BOOL LLTaskInvFVBridge::renameItem(const LLString& new_name)
00382 {
00383         LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
00384         if(object)
00385         {
00386                 LLViewerInventoryItem* item = NULL;
00387                 item = (LLViewerInventoryItem*)object->getInventoryObject(mUUID);
00388                 if(item && (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
00389                                                                                 GP_OBJECT_MANIPULATE, GOD_LIKE)))
00390                 {
00391                         LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
00392                         new_item->rename(new_name);
00393                         object->updateInventory(
00394                                 new_item,
00395                                 TASK_INVENTORY_ITEM_KEY,
00396                                 false);
00397                 }
00398         }
00399         return TRUE;
00400 }
00401 
00402 BOOL LLTaskInvFVBridge::isItemMovable()
00403 {
00404         //LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
00405         //if(object && (object->permModify() || gAgent.isGodlike()))
00406         //{
00407         //      return TRUE;
00408         //}
00409         //return FALSE;
00410         return TRUE;
00411 }
00412 
00413 BOOL LLTaskInvFVBridge::isItemRemovable()
00414 {
00415         LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
00416         if(object
00417            && (object->permModify() || object->permYouOwner()))
00418         {
00419                 return TRUE;
00420         }
00421         return FALSE;
00422 }
00423 
00424 // helper for remove
00425 typedef std::pair<LLUUID, std::list<LLUUID> > two_uuids_list_t;
00426 typedef std::pair<LLPanelInventory*, two_uuids_list_t> remove_data_t;
00427 
00428 void remove_task_inventory_callback(S32 option, void* user_data)
00429 {
00430         remove_data_t* data = (remove_data_t*)user_data;
00431         LLViewerObject* object = NULL;
00432         object = gObjectList.findObject(data->second.first);
00433         if(option == 0 && object)
00434         {
00435                 // yes
00436                 std::list<LLUUID>::iterator list_it;
00437                 std::list<LLUUID>& id_list = data->second.second;
00438                 for (list_it = id_list.begin(); list_it != id_list.end(); ++list_it)
00439                 {
00440                         object->removeInventory(*list_it);
00441                 }
00442 
00443                 // refresh the UI.
00444                 data->first->refresh();
00445         }
00446         delete data;
00447 }
00448 
00449 BOOL LLTaskInvFVBridge::removeItem()
00450 {
00451         if(isItemRemovable() && mPanel)
00452         {
00453                 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
00454                 if(object)
00455                 {
00456                         if(object->permModify())
00457                         {
00458                                 // just do it.
00459                                 object->removeInventory(mUUID);
00460                                 return TRUE;
00461                         }
00462                         else
00463                         {
00464                                 remove_data_t* data = new remove_data_t;
00465                                 data->first = mPanel;
00466                                 data->second.first = mPanel->getTaskUUID();
00467                                 data->second.second.push_back(mUUID);
00468                                 gViewerWindow->alertXml("RemoveItemWarn", remove_task_inventory_callback, (void*)data);
00469                                 return FALSE;
00470                         }
00471                 }
00472         }
00473         return FALSE;
00474 }
00475 
00476 void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
00477 {
00478         if (!mPanel)
00479         {
00480                 return;
00481         }
00482 
00483         LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
00484         if (!object)
00485         {
00486                 return;
00487         }
00488 
00489         if (!object->permModify())
00490         {
00491                 remove_data_t* data = new remove_data_t;
00492                 data->first = mPanel;
00493                 data->second.first = mPanel->getTaskUUID();
00494                 for (S32 i = 0; i < (S32)batch.size(); i++)
00495                 {
00496                         LLTaskInvFVBridge* itemp = (LLTaskInvFVBridge*)batch[i];
00497                         data->second.second.push_back(itemp->getUUID());
00498                 }
00499                 gViewerWindow->alertXml("RemoveItemWarn", remove_task_inventory_callback, (void*)data);
00500         }
00501         else
00502         {
00503                 for (S32 i = 0; i < (S32)batch.size(); i++)
00504                 {
00505                         LLTaskInvFVBridge* itemp = (LLTaskInvFVBridge*)batch[i];
00506 
00507                         if(itemp->isItemRemovable())
00508                         {
00509                                 // just do it.
00510                                 object->removeInventory(itemp->getUUID());
00511                         }
00512                 }
00513         }
00514 }
00515 
00516 void LLTaskInvFVBridge::move(LLFolderViewEventListener* parent_listener)
00517 {
00518 }
00519 
00520 BOOL LLTaskInvFVBridge::isItemCopyable() const
00521 {
00522         LLInventoryItem* item = findItem();
00523         if(!item) return FALSE;
00524         return gAgent.allowOperation(PERM_COPY, item->getPermissions(),
00525                                                                 GP_OBJECT_MANIPULATE);
00526 }
00527 
00528 BOOL LLTaskInvFVBridge::copyToClipboard() const
00529 {
00530         return FALSE;
00531 }
00532 
00533 void LLTaskInvFVBridge::cutToClipboard()
00534 {
00535 }
00536 
00537 BOOL LLTaskInvFVBridge::isClipboardPasteable() const
00538 {
00539         return FALSE;
00540 }
00541 
00542 void LLTaskInvFVBridge::pasteFromClipboard()
00543 {
00544 }
00545 
00546 BOOL LLTaskInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
00547 {
00548         //llinfos << "LLTaskInvFVBridge::startDrag()" << llendl;
00549         if(mPanel)
00550         {
00551                 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
00552                 if(object)
00553                 {
00554                         LLInventoryItem* inv = NULL;
00555                         if((inv = (LLInventoryItem*)object->getInventoryObject(mUUID)))
00556                         {
00557                                 const LLPermissions& perm = inv->getPermissions();
00558                                 bool can_copy = gAgent.allowOperation(PERM_COPY, perm,
00559                                                                                                                 GP_OBJECT_MANIPULATE);
00560                                 if (object->isAttachment() && !can_copy)
00561                                 {
00562                     //RN: no copy contents of attachments cannot be dragged out
00563                     // due to a race condition and possible exploit where
00564                     // attached objects do not update their inventory items
00565                     // when their contents are manipulated
00566                     return FALSE;
00567                                 }
00568                                 if((can_copy && perm.allowTransferTo(gAgent.getID()))
00569                                    || object->permYouOwner())
00570 //                                 || gAgent.isGodlike())
00571 
00572                                 {
00573                                         *type = LLAssetType::lookupDragAndDropType(inv->getType());
00574 
00575                                         *id = inv->getUUID();
00576                                         return TRUE;
00577                                 }
00578                         }
00579                 }
00580         }
00581         return FALSE;
00582 }
00583 
00584 BOOL LLTaskInvFVBridge::dragOrDrop(MASK mask, BOOL drop,
00585                                                                    EDragAndDropType cargo_type,
00586                                                                    void* cargo_data)
00587 {
00588         //llinfos << "LLTaskInvFVBridge::dragOrDrop()" << llendl;
00589         return FALSE;
00590 }
00591 
00592 //void LLTaskInvFVBridge::dropped()
00593 //{
00594 //      llwarns << "LLTaskInvFVBridge::dropped() - not implemented" << llendl;
00595 //}
00596 
00597 // virtual
00598 void LLTaskInvFVBridge::performAction(LLFolderView* folder, LLInventoryModel* model, LLString action)
00599 {
00600         if (action == "task_buy")
00601         {
00602                 // Check the price of the item.
00603                 S32 price = getPrice();
00604                 if (-1 == price)
00605                 {
00606                         llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
00607                 }
00608                 else
00609                 {
00610                         if (price > 0 && price > gStatusBar->getBalance())
00611                         {
00612                                 LLFloaterBuyCurrency::buyCurrency("This costs", price);
00613                         }
00614                         else
00615                         {
00616                                 buyItem();
00617                         }
00618                 }
00619         }
00620         else if (action == "task_open")
00621         {
00622                 openItem();
00623         }
00624         else if (action == "task_properties")
00625         {
00626                 showProperties();
00627         }
00628 }
00629 
00630 void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
00631 {
00632         LLInventoryItem* item = findItem();
00633         if(!item) return;
00634         std::vector<LLString> items;
00635         std::vector<LLString> disabled_items;
00636 
00637         if(gAgent.allowOperation(PERM_OWNER, item->getPermissions(),
00638                                                          GP_OBJECT_MANIPULATE)
00639            && item->getSaleInfo().isForSale())
00640         {
00641                 items.push_back("Task Buy");
00642 
00643                 LLString label("Buy");
00644                 // Check the price of the item.
00645                 S32 price = getPrice();
00646                 if (-1 == price)
00647                 {
00648                         llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
00649                 }
00650                 else
00651                 {
00652                         std::ostringstream info;
00653                         info << "Buy for L$" << price;
00654                         label.assign(info.str());
00655                 }
00656 
00657                 const LLView::child_list_t *list = menu.getChildList();
00658                 LLView::child_list_t::const_iterator itor;
00659                 for (itor = list->begin(); itor != list->end(); ++itor)
00660                 {
00661                         LLString name = (*itor)->getName();
00662                         LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor);
00663                         if (name == "Task Buy" && menu_itemp)
00664                         {
00665                                 menu_itemp->setLabel(label);
00666                         }
00667                 }
00668         }
00669         else
00670         {
00671                 items.push_back("Task Open");
00672                 if (!isItemCopyable())
00673                 {
00674                         disabled_items.push_back("Task Open");
00675                 }
00676         }
00677         items.push_back("Task Properties");
00678         if(isItemRenameable())
00679         {
00680                 items.push_back("Task Rename");
00681         }
00682         if(isItemRemovable())
00683         {
00684                 items.push_back("Task Remove");
00685         }
00686 
00687         hideContextEntries(menu, items, disabled_items);
00688 }
00689 
00690 
00694 
00695 class LLTaskCategoryBridge : public LLTaskInvFVBridge
00696 {
00697 public:
00698         LLTaskCategoryBridge(
00699                 LLPanelInventory* panel,
00700                 const LLUUID& uuid,
00701                 const LLString& name);
00702 
00703         virtual LLUIImagePtr getIcon() const;
00704         virtual const LLString& getDisplayName() const { return getName(); }
00705         virtual BOOL isItemRenameable() const;
00706         virtual BOOL renameItem(const LLString& new_name);
00707         virtual BOOL isItemRemovable();
00708         virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
00709         virtual BOOL hasChildren() const;
00710         virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
00711         virtual BOOL dragOrDrop(MASK mask, BOOL drop,
00712                                                         EDragAndDropType cargo_type,
00713                                                         void* cargo_data);
00714 };
00715 
00716 LLTaskCategoryBridge::LLTaskCategoryBridge(
00717         LLPanelInventory* panel,
00718         const LLUUID& uuid,
00719         const LLString& name) :
00720         LLTaskInvFVBridge(panel, uuid, name)
00721 {
00722 }
00723 
00724 LLUIImagePtr LLTaskCategoryBridge::getIcon() const
00725 {
00726         return LLUI::getUIImage("inv_folder_plain_closed.tga");
00727 }
00728 
00729 BOOL LLTaskCategoryBridge::isItemRenameable() const
00730 {
00731         return FALSE;
00732 }
00733 
00734 BOOL LLTaskCategoryBridge::renameItem(const LLString& new_name)
00735 {
00736         return FALSE;
00737 }
00738 
00739 BOOL LLTaskCategoryBridge::isItemRemovable()
00740 {
00741         return FALSE;
00742 }
00743 
00744 void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
00745 {
00746         std::vector<LLString> items;
00747         std::vector<LLString> disabled_items;
00748         items.push_back("Task Open");
00749         hideContextEntries(menu, items, disabled_items);
00750 }
00751 
00752 BOOL LLTaskCategoryBridge::hasChildren() const
00753 {
00754         // return TRUE if we have or do know know if we have children.
00755         // *FIX: For now, return FALSE - we will know for sure soon enough.
00756         return FALSE;
00757 }
00758 
00759 BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
00760 {
00761         //llinfos << "LLTaskInvFVBridge::startDrag()" << llendl;
00762         if(mPanel)
00763         {
00764                 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
00765                 if(object)
00766                 {
00767                         LLInventoryItem* inv = NULL;
00768                         if((inv = (LLInventoryItem*)object->getInventoryObject(mUUID)))
00769                         {
00770                                 const LLPermissions& perm = inv->getPermissions();
00771                                 bool can_copy = gAgent.allowOperation(PERM_COPY, perm,
00772                                                                                                                 GP_OBJECT_MANIPULATE);
00773                                 if((can_copy && perm.allowTransferTo(gAgent.getID()))
00774                                    || object->permYouOwner())
00775 //                                 || gAgent.isGodlike())
00776 
00777                                 {
00778                                         *type = LLAssetType::lookupDragAndDropType(inv->getType());
00779 
00780                                         *id = inv->getUUID();
00781                                         return TRUE;
00782                                 }
00783                         }
00784                 }
00785         }
00786         return FALSE;
00787 }
00788 
00789 BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop,
00790                                                                           EDragAndDropType cargo_type,
00791                                                                           void* cargo_data)
00792 {
00793         //llinfos << "LLTaskCategoryBridge::dragOrDrop()" << llendl;
00794         BOOL accept = FALSE;
00795         LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
00796         if(object)
00797         {
00798                 switch(cargo_type)
00799                 {
00800                 case DAD_CATEGORY:
00801                         accept = LLToolDragAndDrop::getInstance()->dadUpdateInventoryCategory(object,drop);
00802                         break;
00803                 case DAD_TEXTURE:
00804                 case DAD_SOUND:
00805                 case DAD_LANDMARK:
00806                 case DAD_OBJECT:
00807                 case DAD_NOTECARD:
00808                 case DAD_CLOTHING:
00809                 case DAD_BODYPART:
00810                 case DAD_ANIMATION:
00811                 case DAD_GESTURE:
00812                         // *HACK: In order to resolve SL-22177, we need to block
00813                         // drags from notecards and objects onto other
00814                         // objects. uncomment the simpler version when we have
00815                         // that right.
00816                         //accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
00817                         if(LLToolDragAndDrop::isInventoryDropAcceptable(
00818                                    object, (LLViewerInventoryItem*)cargo_data)
00819                            && (LLToolDragAndDrop::SOURCE_WORLD != LLToolDragAndDrop::getInstance()->getSource())
00820                            && (LLToolDragAndDrop::SOURCE_NOTECARD != LLToolDragAndDrop::getInstance()->getSource()))
00821                         {
00822                                 accept = TRUE;
00823                         }
00824                         if(accept && drop)
00825                         {
00826                                 LLToolDragAndDrop::dropInventory(object,
00827                                                                                                  (LLViewerInventoryItem*)cargo_data,
00828                                                                                                  LLToolDragAndDrop::getInstance()->getSource(),
00829                                                                                                  LLToolDragAndDrop::getInstance()->getSourceID());
00830                         }
00831                         break;
00832                 case DAD_SCRIPT:
00833                         // *HACK: In order to resolve SL-22177, we need to block
00834                         // drags from notecards and objects onto other
00835                         // objects. uncomment the simpler version when we have
00836                         // that right.
00837                         //accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
00838                         if(LLToolDragAndDrop::isInventoryDropAcceptable(
00839                                    object, (LLViewerInventoryItem*)cargo_data)
00840                            && (LLToolDragAndDrop::SOURCE_WORLD != LLToolDragAndDrop::getInstance()->getSource())
00841                            && (LLToolDragAndDrop::SOURCE_NOTECARD != LLToolDragAndDrop::getInstance()->getSource()))
00842                         {
00843                                 accept = TRUE;
00844                         }
00845                         if(accept && drop)
00846                         {
00847                                 LLViewerInventoryItem* item = (LLViewerInventoryItem*)cargo_data;
00848                                 // rez in the script active by default, rez in
00849                                 // inactive if the control key is being held down.
00850                                 BOOL active = ((mask & MASK_CONTROL) == 0);
00851                                 LLToolDragAndDrop::dropScript(object, item, active,
00852                                                                                           LLToolDragAndDrop::getInstance()->getSource(),
00853                                                                                           LLToolDragAndDrop::getInstance()->getSourceID());
00854                         }
00855                         break;
00856                 case DAD_CALLINGCARD:
00857                 default:
00858                         break;
00859                 }
00860         }
00861         return accept;
00862 }
00863 
00867 
00868 class LLTaskTextureBridge : public LLTaskInvFVBridge
00869 {
00870 public:
00871         LLTaskTextureBridge(
00872                 LLPanelInventory* panel,
00873                 const LLUUID& uuid,
00874                 const LLString& name,
00875                 LLInventoryType::EType it);
00876 
00877         virtual LLUIImagePtr getIcon() const;
00878         virtual void openItem();
00879 protected:
00880         LLInventoryType::EType mInventoryType;
00881 };
00882 
00883 LLTaskTextureBridge::LLTaskTextureBridge(
00884         LLPanelInventory* panel,
00885         const LLUUID& uuid,
00886         const LLString& name,
00887         LLInventoryType::EType it) :
00888         LLTaskInvFVBridge(panel, uuid, name),
00889         mInventoryType(it)
00890 {
00891 }
00892 
00893 LLUIImagePtr LLTaskTextureBridge::getIcon() const
00894 {
00895         return get_item_icon(LLAssetType::AT_TEXTURE, mInventoryType, 0, FALSE);
00896 }
00897 
00898 void LLTaskTextureBridge::openItem()
00899 {
00900         llinfos << "LLTaskTextureBridge::openItem()" << llendl;
00901         if(!LLPreview::show(mUUID))
00902         {
00903                 // There isn't one, so make a new preview
00904                 S32 left, top;
00905                 gFloaterView->getNewFloaterPosition(&left, &top);
00906                 LLRect rect = gSavedSettings.getRect("PreviewTextureRect");
00907                 rect.translate( left - rect.mLeft, top - rect.mTop );
00908                 LLPreviewTexture* preview = new LLPreviewTexture("preview task texture",
00909                                                                                                  rect,
00910                                                                                                  getName(),
00911                                                                                                  mUUID,
00912                                                                                                  mPanel->getTaskUUID());
00913                 preview->setFocus(TRUE);
00914         }
00915 }
00916 
00917 
00921 
00922 class LLTaskSoundBridge : public LLTaskInvFVBridge
00923 {
00924 public:
00925         LLTaskSoundBridge(
00926                 LLPanelInventory* panel,
00927                 const LLUUID& uuid,
00928                 const LLString& name);
00929 
00930         virtual LLUIImagePtr getIcon() const;
00931         virtual void openItem();
00932         virtual void performAction(LLFolderView* folder, LLInventoryModel* model, LLString action);
00933         virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
00934         static void openSoundPreview(void* data);
00935 };
00936 
00937 LLTaskSoundBridge::LLTaskSoundBridge(
00938         LLPanelInventory* panel,
00939         const LLUUID& uuid,
00940         const LLString& name) :
00941         LLTaskInvFVBridge(panel, uuid, name)
00942 {
00943 }
00944 
00945 LLUIImagePtr LLTaskSoundBridge::getIcon() const
00946 {
00947         return get_item_icon(LLAssetType::AT_SOUND, LLInventoryType::IT_SOUND, 0, FALSE);
00948 }
00949 
00950 void LLTaskSoundBridge::openItem()
00951 {
00952         openSoundPreview((void*)this);
00953 }
00954 
00955 void LLTaskSoundBridge::openSoundPreview(void* data)
00956 {
00957         LLTaskSoundBridge* self = (LLTaskSoundBridge*)data;
00958         if(!self) return;
00959         if(!LLPreview::show(self->mUUID))
00960         {
00961                 // There isn't one, so make a new preview
00962                 S32 left, top;
00963                 gFloaterView->getNewFloaterPosition(&left, &top);
00964                 LLRect rect = gSavedSettings.getRect("PreviewSoundRect");
00965                 rect.translate(left - rect.mLeft, top - rect.mTop);
00966                 LLPreviewSound* floaterp =      new LLPreviewSound("preview task sound",
00967                                                            rect,
00968                                                            self->getName(),
00969                                                            self->mUUID,
00970                                                            self->mPanel->getTaskUUID());
00971                 floaterp->open();       /*Flawfinder: ignore*/
00972         }
00973 }
00974 
00975 // virtual
00976 void LLTaskSoundBridge::performAction(LLFolderView* folder, LLInventoryModel* model, LLString action)
00977 {
00978         if (action == "task_play")
00979         {
00980                 LLInventoryItem* item = findItem();
00981                 if(item)
00982                 {
00983                         send_sound_trigger(item->getAssetUUID(), 1.0);
00984                 }
00985         }
00986         LLTaskInvFVBridge::performAction(folder, model, action);
00987 }
00988 
00989 void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
00990 {
00991         LLInventoryItem* item = findItem();
00992         if(!item) return;
00993         std::vector<LLString> items;
00994         std::vector<LLString> disabled_items;
00995 
00996         if(item->getPermissions().getOwner() != gAgent.getID()
00997            && item->getSaleInfo().isForSale())
00998         {
00999                 items.push_back("Task Buy");
01000 
01001                 LLString label("Buy");
01002                 // Check the price of the item.
01003                 S32 price = getPrice();
01004                 if (-1 == price)
01005                 {
01006                         llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
01007                 }
01008                 else
01009                 {
01010                         std::ostringstream info;
01011                         info << "Buy for L$" << price;
01012                         label.assign(info.str());
01013                 }
01014 
01015                 const LLView::child_list_t *list = menu.getChildList();
01016                 LLView::child_list_t::const_iterator itor;
01017                 for (itor = list->begin(); itor != list->end(); ++itor)
01018                 {
01019                         LLString name = (*itor)->getName();
01020                         LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor);
01021                         if (name == "Task Buy" && menu_itemp)
01022                         {
01023                                 menu_itemp->setLabel(label);
01024                         }
01025                 }
01026         }
01027         else
01028         {
01029                 items.push_back("Task Open");
01030                 if (!isItemCopyable())
01031                 {
01032                         disabled_items.push_back("Task Open");
01033                 }
01034         }
01035         items.push_back("Task Properties");
01036         if(isItemRenameable())
01037         {
01038                 items.push_back("Task Rename");
01039         }
01040         if(isItemRemovable())
01041         {
01042                 items.push_back("Task Remove");
01043         }
01044 
01045         items.push_back("Task Play");
01046         /*menu.appendSeparator();
01047         menu.append(new LLMenuItemCallGL("Play",
01048                                                                          &LLTaskSoundBridge::playSound,
01049                                                                          NULL,
01050                                                                          (void*)this));*/
01051 
01052         hideContextEntries(menu, items, disabled_items);
01053 }
01054 
01058 
01059 class LLTaskLandmarkBridge : public LLTaskInvFVBridge
01060 {
01061 public:
01062         LLTaskLandmarkBridge(
01063                 LLPanelInventory* panel,
01064                 const LLUUID& uuid,
01065                 const LLString& name);
01066 
01067         virtual LLUIImagePtr getIcon() const;
01068 };
01069 
01070 LLTaskLandmarkBridge::LLTaskLandmarkBridge(
01071         LLPanelInventory* panel,
01072         const LLUUID& uuid,
01073         const LLString& name) :
01074         LLTaskInvFVBridge(panel, uuid, name)
01075 {
01076 }
01077 
01078 LLUIImagePtr LLTaskLandmarkBridge::getIcon() const
01079 {
01080         return get_item_icon(LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, 0, FALSE);
01081 }
01082 
01083 
01087 
01088 class LLTaskCallingCardBridge : public LLTaskInvFVBridge
01089 {
01090 public:
01091         LLTaskCallingCardBridge(
01092                 LLPanelInventory* panel,
01093                 const LLUUID& uuid,
01094                 const LLString& name);
01095 
01096         virtual LLUIImagePtr getIcon() const;
01097         virtual BOOL isItemRenameable() const;
01098         virtual BOOL renameItem(const LLString& new_name);
01099 };
01100 
01101 LLTaskCallingCardBridge::LLTaskCallingCardBridge(
01102         LLPanelInventory* panel,
01103         const LLUUID& uuid,
01104         const LLString& name) :
01105         LLTaskInvFVBridge(panel, uuid, name)
01106 {
01107 }
01108 
01109 LLUIImagePtr LLTaskCallingCardBridge::getIcon() const
01110 {
01111         return get_item_icon(LLAssetType::AT_CALLINGCARD, LLInventoryType::IT_CALLINGCARD, 0, FALSE);
01112 }
01113 
01114 BOOL LLTaskCallingCardBridge::isItemRenameable() const
01115 {
01116         return FALSE;
01117 }
01118 
01119 BOOL LLTaskCallingCardBridge::renameItem(const LLString& new_name)
01120 {
01121         return FALSE;
01122 }
01123 
01124 
01128 
01129 class LLTaskScriptBridge : public LLTaskInvFVBridge
01130 {
01131 public:
01132         LLTaskScriptBridge(
01133                 LLPanelInventory* panel,
01134                 const LLUUID& uuid,
01135                 const LLString& name);
01136 
01137         virtual LLUIImagePtr getIcon() const;
01138         //static BOOL enableIfCopyable( void* userdata );
01139 };
01140 
01141 LLTaskScriptBridge::LLTaskScriptBridge(
01142         LLPanelInventory* panel,
01143         const LLUUID& uuid,
01144         const LLString& name) :
01145         LLTaskInvFVBridge(panel, uuid, name)
01146 {
01147 }
01148 
01149 LLUIImagePtr LLTaskScriptBridge::getIcon() const
01150 {
01151         return get_item_icon(LLAssetType::AT_SCRIPT, LLInventoryType::IT_LSL, 0, FALSE);
01152 }
01153 
01154 
01155 class LLTaskLSLBridge : public LLTaskScriptBridge
01156 {
01157 public:
01158         LLTaskLSLBridge(
01159                 LLPanelInventory* panel,
01160                 const LLUUID& uuid,
01161                 const LLString& name);
01162 
01163         virtual void openItem();
01164         virtual BOOL removeItem();
01165         //virtual void buildContextMenu(LLMenuGL& menu);
01166 
01167         //static void copyToInventory(void* userdata);
01168 };
01169 
01170 LLTaskLSLBridge::LLTaskLSLBridge(
01171         LLPanelInventory* panel,
01172         const LLUUID& uuid,
01173         const LLString& name) :
01174         LLTaskScriptBridge(panel, uuid, name)
01175 {
01176 }
01177 
01178 void LLTaskLSLBridge::openItem()
01179 {
01180         llinfos << "LLTaskLSLBridge::openItem() " << mUUID << llendl;
01181         if(LLLiveLSLEditor::show(mUUID, mPanel->getTaskUUID()))
01182         {
01183                 return;
01184         }
01185         LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
01186         if(!object || object->isInventoryPending())
01187         {
01188                 return;
01189         }
01190         if(object->permModify() || gAgent.isGodlike())
01191         {
01192                 LLString title("Script: ");
01193                 LLInventoryItem* item = findItem();
01194                 if (item)
01195                 {
01196                         title.append(item->getName());
01197                 }
01198 
01199                 S32 left, top;
01200                 gFloaterView->getNewFloaterPosition(&left, &top);
01201                 LLRect rect = gSavedSettings.getRect("PreviewScriptRect");
01202                 rect.translate(left - rect.mLeft, top - rect.mTop);
01203                 LLLiveLSLEditor* editor;
01204                 editor = new LLLiveLSLEditor("lsl ed",
01205                                                                            rect,
01206                                                                            title,
01207                                                                            mPanel->getTaskUUID(),
01208                                                                            mUUID);
01209                 LLMultiFloater* previous_host = LLFloater::getFloaterHost();
01210                 LLFloater::setFloaterHost(NULL);
01211                 editor->open(); /*Flawfinder: ignore*/
01212                 LLFloater::setFloaterHost(previous_host);
01213 
01214                 // keep onscreen
01215                 gFloaterView->adjustToFitScreen(editor, FALSE);
01216         }
01217 }
01218 
01219 BOOL LLTaskLSLBridge::removeItem()
01220 {
01221         LLLiveLSLEditor::hide(mUUID, mPanel->getTaskUUID());
01222         return LLTaskInvFVBridge::removeItem();
01223 }
01224 
01228 
01229 class LLTaskObjectBridge : public LLTaskInvFVBridge
01230 {
01231 public:
01232         LLTaskObjectBridge(
01233                 LLPanelInventory* panel,
01234                 const LLUUID& uuid,
01235                 const LLString& name);
01236 
01237         virtual LLUIImagePtr getIcon() const;
01238 };
01239 
01240 LLTaskObjectBridge::LLTaskObjectBridge(
01241         LLPanelInventory* panel,
01242         const LLUUID& uuid,
01243         const LLString& name) :
01244         LLTaskInvFVBridge(panel, uuid, name)
01245 {
01246 }
01247 
01248 LLUIImagePtr LLTaskObjectBridge::getIcon() const
01249 {
01250         BOOL item_is_multi = FALSE;
01251         if ( mFlags & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS )
01252         {
01253                 item_is_multi = TRUE;
01254         }
01255 
01256         return get_item_icon(LLAssetType::AT_OBJECT, LLInventoryType::IT_OBJECT, 0, item_is_multi);
01257 }
01258 
01262 
01263 class LLTaskNotecardBridge : public LLTaskInvFVBridge
01264 {
01265 public:
01266         LLTaskNotecardBridge(
01267                 LLPanelInventory* panel,
01268                 const LLUUID& uuid,
01269                 const LLString& name);
01270 
01271         virtual LLUIImagePtr getIcon() const;
01272         virtual void openItem();
01273         virtual BOOL removeItem();
01274 };
01275 
01276 LLTaskNotecardBridge::LLTaskNotecardBridge(
01277         LLPanelInventory* panel,
01278         const LLUUID& uuid,
01279         const LLString& name) :
01280         LLTaskInvFVBridge(panel, uuid, name)
01281 {
01282 }
01283 
01284 LLUIImagePtr LLTaskNotecardBridge::getIcon() const
01285 {
01286         return get_item_icon(LLAssetType::AT_NOTECARD, LLInventoryType::IT_NOTECARD, 0, FALSE);
01287 }
01288 
01289 void LLTaskNotecardBridge::openItem()
01290 {
01291         if(LLPreview::show(mUUID))
01292         {
01293                 return;
01294         }
01295         LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
01296         if(!object || object->isInventoryPending())
01297         {
01298                 return;
01299         }
01300         if(object->permModify() || gAgent.isGodlike())
01301         {
01302                 S32 left, top;
01303                 gFloaterView->getNewFloaterPosition(&left, &top);
01304                 LLRect rect = gSavedSettings.getRect("PreviewScriptRect");
01305                 rect.translate(left - rect.mLeft, top - rect.mTop);
01306                 LLPreviewNotecard* preview;
01307                 preview = new LLPreviewNotecard("live notecard editor",
01308                                                                                  rect,
01309                                                                                  getName(),
01310                                                                                  mUUID,
01311                                                                                  mPanel->getTaskUUID());
01312                 preview->setFocus(TRUE);  // if you're opening a notecard from an object's inventory, it takes focus
01313 
01314                 // keep onscreen
01315                 gFloaterView->adjustToFitScreen(preview, FALSE);
01316         }
01317 }
01318 
01319 BOOL LLTaskNotecardBridge::removeItem()
01320 {
01321         LLPreview::hide(mUUID);
01322         return LLTaskInvFVBridge::removeItem();
01323 }
01324 
01328 
01329 class LLTaskGestureBridge : public LLTaskInvFVBridge
01330 {
01331 public:
01332         LLTaskGestureBridge(
01333                 LLPanelInventory* panel,
01334                 const LLUUID& uuid,
01335                 const LLString& name);
01336 
01337         virtual LLUIImagePtr getIcon() const;
01338         virtual void openItem();
01339         virtual BOOL removeItem();
01340 };
01341 
01342 LLTaskGestureBridge::LLTaskGestureBridge(
01343         LLPanelInventory* panel,
01344         const LLUUID& uuid,
01345         const LLString& name) :
01346         LLTaskInvFVBridge(panel, uuid, name)
01347 {
01348 }
01349 
01350 LLUIImagePtr LLTaskGestureBridge::getIcon() const
01351 {
01352         return get_item_icon(LLAssetType::AT_GESTURE, LLInventoryType::IT_GESTURE, 0, FALSE);
01353 }
01354 
01355 void LLTaskGestureBridge::openItem()
01356 {
01357         if(LLPreview::show(mUUID))
01358         {
01359                 return;
01360         }
01361         LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
01362         if(!object || object->isInventoryPending())
01363         {
01364                 return;
01365         }
01366 
01367         // TODO: save rectangle
01368         LLString title = getName();
01369         LLUUID item_id = mUUID;
01370         LLUUID object_id = mPanel->getTaskUUID();
01371         LLPreviewGesture* preview = LLPreviewGesture::show(title, item_id, object_id);
01372 
01373         // keep onscreen
01374         gFloaterView->adjustToFitScreen(preview, FALSE);
01375 }
01376 
01377 BOOL LLTaskGestureBridge::removeItem()
01378 {
01379         // Don't need to deactivate gesture because gestures inside objects
01380         // can never be active.
01381         LLPreview::hide(mUUID);
01382         return LLTaskInvFVBridge::removeItem();
01383 }
01384 
01388 
01389 class LLTaskAnimationBridge : public LLTaskInvFVBridge
01390 {
01391 public:
01392         LLTaskAnimationBridge(
01393                 LLPanelInventory* panel,
01394                 const LLUUID& uuid,
01395                 const LLString& name);
01396 
01397         virtual LLUIImagePtr getIcon() const;
01398         virtual void openItem();
01399         virtual BOOL removeItem();
01400 };
01401 
01402 LLTaskAnimationBridge::LLTaskAnimationBridge(
01403         LLPanelInventory* panel,
01404         const LLUUID& uuid,
01405         const LLString& name) :
01406         LLTaskInvFVBridge(panel, uuid, name)
01407 {
01408 }
01409 
01410 LLUIImagePtr LLTaskAnimationBridge::getIcon() const
01411 {
01412         return get_item_icon(LLAssetType::AT_ANIMATION, LLInventoryType::IT_ANIMATION, 0, FALSE);
01413 }
01414 
01415 void LLTaskAnimationBridge::openItem()
01416 {
01417         if(LLPreview::show(mUUID))
01418         {
01419                 return;
01420         }
01421         LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
01422         if(!object || object->isInventoryPending())
01423         {
01424                 return;
01425         }
01426 
01427         // TODO: what permissions allow looking at animation?
01428         if(object->permModify() || gAgent.isGodlike())
01429         {
01430                 // TODO: save rectangle
01431                 LLString title = getName();
01432                 LLUUID item_id = mUUID;
01433                 LLUUID object_id = mPanel->getTaskUUID();
01434 
01435                 if(!LLPreview::show(mUUID))
01436                 {
01437                         // There isn't one, so make a new preview
01438                         S32 left, top;
01439                         gFloaterView->getNewFloaterPosition(&left, &top);
01440                         LLRect rect = gSavedSettings.getRect("PreviewAnimRect");
01441                         rect.translate(left - rect.mLeft, top - rect.mTop);
01442 
01443                         LLPreviewAnim* preview = new LLPreviewAnim("preview anim",
01444                                                                         rect,
01445                                                                    getName(),
01446                                                                    mUUID,
01447                                                                    0,
01448                                                                    mPanel->getTaskUUID());
01449                         preview->setFocus(TRUE);  // take focus if you're looking at one of these
01450 
01451                         // Force to be entirely onscreen.
01452                         gFloaterView->adjustToFitScreen(preview, FALSE);
01453                 }
01454         }
01455 }
01456 
01457 BOOL LLTaskAnimationBridge::removeItem()
01458 {
01459         LLPreview::hide(mUUID);
01460         return LLTaskInvFVBridge::removeItem();
01461 }
01462 
01466 
01467 class LLTaskWearableBridge : public LLTaskInvFVBridge
01468 {
01469 public:
01470         LLTaskWearableBridge(
01471                 LLPanelInventory* panel,
01472                 const LLUUID& uuid,
01473                 const LLString& name,
01474                 LLAssetType::EType asset_type,
01475                 U32 flags);
01476 
01477         virtual LLUIImagePtr getIcon() const;
01478 
01479 protected:
01480         LLAssetType::EType              mAssetType;
01481 };
01482 
01483 LLTaskWearableBridge::LLTaskWearableBridge(
01484         LLPanelInventory* panel,
01485         const LLUUID& uuid,
01486         const LLString& name,
01487         LLAssetType::EType asset_type,
01488         U32 flags) :
01489         LLTaskInvFVBridge(panel, uuid, name, flags),
01490         mAssetType( asset_type )
01491 {
01492 }
01493 
01494 LLUIImagePtr LLTaskWearableBridge::getIcon() const
01495 {
01496         return get_item_icon(mAssetType, LLInventoryType::IT_WEARABLE, mFlags, FALSE );
01497 }
01498 
01499 
01502 //----------------------------------------------------------------------------
01503 
01504 LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelInventory* panel,
01505                                                                                                                  LLInventoryObject* object)
01506 {
01507         LLTaskInvFVBridge* new_bridge = NULL;
01508         LLAssetType::EType type = object->getType();
01509         LLInventoryItem* item = NULL;
01510         switch(type)
01511         {
01512         case LLAssetType::AT_TEXTURE:
01513                 item = (LLInventoryItem*)object;
01514                 new_bridge = new LLTaskTextureBridge(panel,
01515                                                                                          object->getUUID(),
01516                                                                                          object->getName(),
01517                                                                                          item->getInventoryType());
01518                 break;
01519         case LLAssetType::AT_SOUND:
01520                 new_bridge = new LLTaskSoundBridge(panel,
01521                                                                                    object->getUUID(),
01522                                                                                    object->getName());
01523                 break;
01524         case LLAssetType::AT_LANDMARK:
01525                 new_bridge = new LLTaskLandmarkBridge(panel,
01526                                                                                           object->getUUID(),
01527                                                                                           object->getName());
01528                 break;
01529         case LLAssetType::AT_CALLINGCARD:
01530                 new_bridge = new LLTaskCallingCardBridge(panel,
01531                                                                                                  object->getUUID(),
01532                                                                                                  object->getName());
01533                 break;
01534         case LLAssetType::AT_SCRIPT:
01535                 // OLD SCRIPTS DEPRECATED - JC
01536                 llwarns << "Old script" << llendl;
01537                 //new_bridge = new LLTaskOldScriptBridge(panel,
01538                 //                                                                         object->getUUID(),
01539                 //                                                                         object->getName());
01540                 break;
01541         case LLAssetType::AT_OBJECT:
01542                 new_bridge = new LLTaskObjectBridge(panel,
01543                                                                                         object->getUUID(),
01544                                                                                         object->getName());
01545                 break;
01546         case LLAssetType::AT_NOTECARD:
01547                 new_bridge = new LLTaskNotecardBridge(panel,
01548                                                                                           object->getUUID(),
01549                                                                                           object->getName());
01550                 break;
01551         case LLAssetType::AT_ANIMATION:
01552                 new_bridge = new LLTaskAnimationBridge(panel,
01553                                                                                           object->getUUID(),
01554                                                                                           object->getName());
01555                 break;
01556         case LLAssetType::AT_GESTURE:
01557                 new_bridge = new LLTaskGestureBridge(panel,
01558                                                                                           object->getUUID(),
01559                                                                                           object->getName());
01560                 break;
01561         case LLAssetType::AT_CLOTHING:
01562         case LLAssetType::AT_BODYPART:
01563                 item = (LLInventoryItem*)object;
01564                 new_bridge = new LLTaskWearableBridge(panel,
01565                                                                                           object->getUUID(),
01566                                                                                           object->getName(),
01567                                                                                           type,
01568                                                                                           item->getFlags());
01569                 break;
01570         case LLAssetType::AT_CATEGORY:
01571                 new_bridge = new LLTaskCategoryBridge(panel,
01572                                                                                           object->getUUID(),
01573                                                                                           object->getName());
01574                 break;
01575         case LLAssetType::AT_LSL_TEXT:
01576                 new_bridge = new LLTaskLSLBridge(panel,
01577                                                                                  object->getUUID(),
01578                                                                                  object->getName());
01579                 break;
01580         default:
01581                 llinfos << "Unhandled inventory type (llassetstorage.h): "
01582                                 << (S32)type << llendl;
01583                 break;
01584         }
01585         return new_bridge;
01586 }
01587 
01588 
01592 
01593 // Default constructor
01594 LLPanelInventory::LLPanelInventory(const LLString& name, const LLRect& rect) :
01595         LLPanel(name, rect),
01596         mScroller(NULL),
01597         mFolders(NULL),
01598         mHaveInventory(FALSE),
01599         mIsInventoryEmpty(TRUE),
01600         mInventoryNeedsUpdate(FALSE)
01601 {
01602         reset();
01603         // Callbacks
01604         init_object_inventory_panel_actions(this);
01605         gIdleCallbacks.addFunction(idle, this);
01606 }
01607 
01608 // Destroys the object
01609 LLPanelInventory::~LLPanelInventory()
01610 {
01611         if (!gIdleCallbacks.deleteFunction(idle, this))
01612         {
01613                 llwarns << "LLPanelInventory::~LLPanelInventory() failed to delete callback" << llendl;
01614         }
01615 }
01616 
01617 
01618 void LLPanelInventory::clearContents()
01619 {
01620         mHaveInventory = FALSE;
01621         mIsInventoryEmpty = TRUE;
01622         if (LLToolDragAndDrop::getInstance() && LLToolDragAndDrop::getInstance()->getSource() == LLToolDragAndDrop::SOURCE_WORLD)
01623         {
01624                 LLToolDragAndDrop::getInstance()->endDrag();
01625         }
01626 
01627         if( mScroller )
01628         {
01629                 // removes mFolders
01630                 removeChild( mScroller );
01631                 mScroller->die();
01632                 mScroller = NULL;
01633                 mFolders = NULL;
01634         }
01635 }
01636 
01637 
01638 void LLPanelInventory::reset()
01639 {
01640         clearContents();
01641 
01642         setBorderVisible(FALSE);
01643 
01644         LLRect dummy_rect(0, 1, 1, 0);
01645         mFolders = new LLFolderView("task inventory", NULL, dummy_rect, getTaskUUID(), this);
01646         // this ensures that we never say "searching..." or "no items found"
01647         mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
01648 
01649         LLRect scroller_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
01650         mScroller = new LLScrollableContainerView(
01651                 "task inventory scroller", scroller_rect, mFolders );
01652         mScroller->setFollowsAll();
01653         addChild(mScroller);
01654 
01655         mFolders->setScrollContainer( mScroller );
01656 }
01657 
01658 void LLPanelInventory::inventoryChanged(LLViewerObject* object,
01659                                                                                 InventoryObjectList* inventory,
01660                                                                                 S32 serial_num,
01661                                                                                 void* data)
01662 {
01663         if(!object) return;
01664 
01665         //llinfos << "invetnory arrived: \n"
01666         //              << " panel UUID: " << panel->mTaskUUID << "\n"
01667         //              << " task  UUID: " << object->mID << llendl;
01668         if(mTaskUUID == object->mID)
01669         {
01670                 mInventoryNeedsUpdate = TRUE;
01671         }
01672 
01673         // refresh any properties floaters that are hanging around.
01674         if(inventory)
01675         {
01676                 // We need to copy the ones that need refreshing onto a
01677                 // temporary object because we cannot iterate through the
01678                 // object inventory twice... A pox on stateful iteration!
01679                 LLFloaterProperties* floater = NULL;
01680                 LLDynamicArray<LLFloaterProperties*> refresh;
01681 
01682                 InventoryObjectList::const_iterator it = inventory->begin();
01683                 InventoryObjectList::const_iterator end = inventory->end();
01684                 for( ;  it != end;      ++it)
01685                 {
01686                         floater = LLFloaterProperties::find((*it)->getUUID(),
01687                                                                                                 object->getID());
01688                         if(floater)
01689                         {
01690                                 refresh.put(floater);
01691                         }
01692                 }
01693                 S32 count = refresh.count();
01694                 for(S32 i = 0; i < count; ++i)
01695                 {
01696                         refresh.get(i)->refresh();
01697                 }
01698         }
01699 }
01700 
01701 void LLPanelInventory::updateInventory()
01702 {
01703         //llinfos << "inventory arrived: \n"
01704         //              << " panel UUID: " << panel->mTaskUUID << "\n"
01705         //              << " task  UUID: " << object->mID << llendl;
01706         // We're still interested in this task's inventory.
01707         std::set<LLUUID> selected_items;
01708         BOOL inventory_has_focus = FALSE;
01709         if (mHaveInventory && mFolders->getNumSelectedDescendants())
01710         {
01711                 mFolders->getSelectionList(selected_items);
01712                 inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders);
01713         }
01714 
01715         reset();
01716 
01717         LLViewerObject* objectp = gObjectList.findObject(mTaskUUID);
01718         if (objectp)
01719         {
01720                 LLInventoryObject* inventory_root = objectp->getInventoryRoot();
01721                 InventoryObjectList contents;
01722                 objectp->getInventoryContents(contents);
01723                 if (inventory_root)
01724                 {
01725                         createFolderViews(inventory_root, contents);
01726                         mHaveInventory = TRUE;
01727                         mIsInventoryEmpty = FALSE;
01728                         mFolders->setEnabled(TRUE);
01729                 }
01730                 else
01731                 {
01732                         // TODO: create an empty inventory
01733                         mIsInventoryEmpty = TRUE;
01734                         mHaveInventory = TRUE;
01735                 }
01736         }
01737         else
01738         {
01739                 // TODO: create an empty inventory
01740                 mIsInventoryEmpty = TRUE;
01741                 mHaveInventory = TRUE;
01742         }
01743 
01744         // restore previous selection
01745         std::set<LLUUID>::iterator selection_it;
01746         BOOL first_item = TRUE;
01747         for (selection_it = selected_items.begin(); selection_it != selected_items.end(); ++selection_it)
01748         {
01749                 LLFolderViewItem* selected_item = mFolders->getItemByID(*selection_it);
01750                 if (selected_item)
01751                 {
01752                         //HACK: "set" first item then "change" each other one to get keyboard focus right
01753                         if (first_item)
01754                         {
01755                                 mFolders->setSelection(selected_item, TRUE, inventory_has_focus);
01756                                 first_item = FALSE;
01757                         }
01758                         else
01759                         {
01760                                 mFolders->changeSelection(selected_item, TRUE);
01761                         }
01762                 }
01763         }
01764 
01765         mFolders->arrangeFromRoot();
01766         mInventoryNeedsUpdate = FALSE;
01767 }
01768 
01769 // *FIX: This is currently a very expensive operation, because we have
01770 // to iterate through the inventory one time for each category. This
01771 // leads to an N^2 based on the category count. This could be greatly
01772 // speeded with an efficient multimap implementation, but we don't
01773 // have that in our current arsenal.
01774 void LLPanelInventory::createFolderViews(LLInventoryObject* inventory_root, InventoryObjectList& contents)
01775 {
01776         if (!inventory_root)
01777         {
01778                 return;
01779         }
01780         // Create a visible root category.
01781         LLTaskInvFVBridge* bridge = NULL;
01782         bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root);
01783         if(bridge)
01784         {
01785                 LLFolderViewFolder* new_folder = NULL;
01786                 new_folder = new LLFolderViewFolder(inventory_root->getName(),
01787                                                                                         bridge->getIcon(),
01788                                                                                         mFolders,
01789                                                                                         bridge);
01790                 new_folder->addToFolder(mFolders, mFolders);
01791                 new_folder->toggleOpen();
01792 
01793                 createViewsForCategory(&contents, inventory_root, new_folder);
01794         }
01795 }
01796 
01797 typedef std::pair<LLInventoryObject*, LLFolderViewFolder*> obj_folder_pair;
01798 
01799 void LLPanelInventory::createViewsForCategory(InventoryObjectList* inventory, 
01800                                                                                           LLInventoryObject* parent,
01801                                                                                           LLFolderViewFolder* folder)
01802 {
01803         // Find all in the first pass
01804         LLDynamicArray<obj_folder_pair*> child_categories;
01805         LLTaskInvFVBridge* bridge;
01806         LLFolderViewItem* view;
01807 
01808         InventoryObjectList::iterator it = inventory->begin();
01809         InventoryObjectList::iterator end = inventory->end();
01810         for( ; it != end; ++it)
01811         {
01812                 LLInventoryObject* obj = *it;
01813 
01814                 if(parent->getUUID() == obj->getParentUUID())
01815                 {
01816                         bridge = LLTaskInvFVBridge::createObjectBridge(this, obj);
01817                         if(!bridge)
01818                         {
01819                                 continue;
01820                         }
01821                         if(LLAssetType::AT_CATEGORY == obj->getType())
01822                         {
01823                                 view = new LLFolderViewFolder(obj->getName(),
01824                                                                                           bridge->getIcon(),
01825                                                                                           mFolders,
01826                                                                                           bridge);
01827                                 child_categories.put(new obj_folder_pair(obj,
01828                                                                                                                  (LLFolderViewFolder*)view));
01829                         }
01830                         else
01831                         {
01832                                 view = new LLFolderViewItem(obj->getName(),
01833                                                                                         bridge->getIcon(),
01834                                                                                         bridge->getCreationDate(),
01835                                                                                         mFolders,
01836                                                                                         bridge);
01837                         }
01838                         view->addToFolder(folder, mFolders);
01839                 }
01840         }
01841 
01842         // now, for each category, do the second pass
01843         for(S32 i = 0; i < child_categories.count(); i++)
01844         {
01845                 createViewsForCategory(inventory, child_categories[i]->first,
01846                                                            child_categories[i]->second );
01847                 delete child_categories[i];
01848         }
01849 }
01850 
01851 void LLPanelInventory::refresh()
01852 {
01853         //llinfos << "LLPanelInventory::refresh()" << llendl;
01854         BOOL has_inventory = FALSE;
01855         const BOOL non_root_ok = TRUE;
01856         LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(NULL, non_root_ok);
01857         if(node)
01858         {
01859                 LLViewerObject* object = node->getObject();
01860                 if(object && ((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1)
01861                                           || (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)))
01862                 {
01863                         // determine if we need to make a request. Start with a
01864                         // default based on if we have inventory at all.
01865                         BOOL make_request = !mHaveInventory;
01866 
01867                         // If the task id is different than what we've stored,
01868                         // then make the request.
01869                         if(mTaskUUID != object->mID)
01870                         {
01871                                 mTaskUUID = object->mID;
01872                                 make_request = TRUE;
01873 
01874                                 // This is a new object so pre-emptively clear the contents
01875                                 // Otherwise we show the old stuff until the update comes in
01876                                 clearContents();
01877 
01878                                 // Register for updates from this object,
01879                                 registerVOInventoryListener(object,NULL);
01880                         }
01881 
01882                         // Based on the node information, we may need to dirty the
01883                         // object inventory and get it again.
01884                         if(node->mValid)
01885                         {
01886                                 if(node->mInventorySerial != object->getInventorySerial() || object->isInventoryDirty())
01887                                 {
01888                                         make_request = TRUE;
01889                                 }
01890                         }
01891 
01892                         // do the request if necessary.
01893                         if(make_request)
01894                         {
01895                                 requestVOInventory();
01896                         }
01897                         has_inventory = TRUE;
01898                 }
01899         }
01900         if(!has_inventory)
01901         {
01902                 mTaskUUID = LLUUID::null;
01903                 removeVOInventoryListener();
01904                 clearContents();
01905         }
01906         //llinfos << "LLPanelInventory::refresh() " << mTaskUUID << llendl;
01907 }
01908 
01909 void LLPanelInventory::removeSelectedItem()
01910 {
01911         if(mFolders)
01912         {
01913                 mFolders->removeSelectedItems();
01914         }
01915 }
01916 
01917 void LLPanelInventory::startRenamingSelectedItem()
01918 {
01919         if(mFolders)
01920         {
01921                 mFolders->startRenamingSelectedItem();
01922         }
01923 }
01924 
01925 void LLPanelInventory::draw()
01926 {
01927         LLPanel::draw();
01928 
01929         if(mIsInventoryEmpty)
01930         {
01931                 if((LLUUID::null != mTaskUUID) && (!mHaveInventory))
01932                 {
01933                         LLFontGL::sSansSerif->renderUTF8("Loading contents...", 0,
01934                                                                                  (S32)(getRect().getWidth() * 0.5f),
01935                                                                                  10,
01936                                                                                  LLColor4( 1, 1, 1, 1 ),
01937                                                                                  LLFontGL::HCENTER,
01938                                                                                  LLFontGL::BOTTOM);
01939                 }
01940                 else if(mHaveInventory)
01941                 {
01942                         LLFontGL::sSansSerif->renderUTF8("No contents", 0,
01943                                                                                  (S32)(getRect().getWidth() * 0.5f),
01944                                                                                  10,
01945                                                                                  LLColor4( 1, 1, 1, 1 ),
01946                                                                                  LLFontGL::HCENTER,
01947                                                                                  LLFontGL::BOTTOM);
01948                 }
01949         }
01950 }
01951 
01952 void LLPanelInventory::deleteAllChildren()
01953 {
01954         mScroller = NULL;
01955         mFolders = NULL;
01956         LLView::deleteAllChildren();
01957 }
01958 
01959 BOOL LLPanelInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, LLString& tooltip_msg)
01960 {
01961         if (mFolders && mHaveInventory)
01962         {
01963                 LLFolderViewItem* folderp = mFolders->getNextFromChild(NULL);
01964                 if (!folderp)
01965                 {
01966                         return FALSE;
01967                 }
01968                 // Try to pass on unmodified mouse coordinates
01969                 S32 local_x = x - mFolders->getRect().mLeft;
01970                 S32 local_y = y - mFolders->getRect().mBottom;
01971 
01972                 if (mFolders->pointInView(local_x, local_y))
01973                 {
01974                         return mFolders->handleDragAndDrop(local_x, local_y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
01975                 }
01976                 else
01977                 {
01978                         //force mouse coordinates to be inside folder rectangle
01979                         return mFolders->handleDragAndDrop(5, 1, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
01980                 }
01981         }
01982         else
01983         {
01984                 return FALSE;
01985         }
01986 }
01987 
01988 //static
01989 void LLPanelInventory::idle(void* user_data)
01990 {
01991         LLPanelInventory* self = (LLPanelInventory*)user_data;
01992 
01993 
01994         if (self->mInventoryNeedsUpdate)
01995         {
01996                 self->updateInventory();
01997         }
01998 }

Generated on Fri May 16 08:33:54 2008 for SecondLife by  doxygen 1.5.5