00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include <utility>
00035
00036 #include "llinventoryview.h"
00037 #include "llinventorybridge.h"
00038
00039 #include "message.h"
00040
00041 #include "llagent.h"
00042 #include "llcallingcard.h"
00043 #include "llcheckboxctrl.h"
00044 #include "llradiogroup.h"
00045 #include "llspinctrl.h"
00046 #include "lltextbox.h"
00047 #include "llui.h"
00048
00049 #include "llviewercontrol.h"
00050 #include "llfirstuse.h"
00051 #include "llfloateravatarinfo.h"
00052 #include "llfloaterchat.h"
00053 #include "llfloatercustomize.h"
00054 #include "llfloaterproperties.h"
00055 #include "llfloaterworldmap.h"
00056 #include "llfocusmgr.h"
00057 #include "llfolderview.h"
00058 #include "llgesturemgr.h"
00059 #include "lliconctrl.h"
00060 #include "llinventorymodel.h"
00061 #include "llinventoryclipboard.h"
00062 #include "lllineeditor.h"
00063 #include "llmenugl.h"
00064 #include "llpreviewanim.h"
00065 #include "llpreviewgesture.h"
00066 #include "llpreviewlandmark.h"
00067 #include "llpreviewnotecard.h"
00068 #include "llpreviewscript.h"
00069 #include "llpreviewsound.h"
00070 #include "llpreviewtexture.h"
00071 #include "llresmgr.h"
00072 #include "llscrollcontainer.h"
00073 #include "llimview.h"
00074 #include "lltooldraganddrop.h"
00075 #include "llviewerimagelist.h"
00076 #include "llviewerinventory.h"
00077 #include "llviewerobjectlist.h"
00078 #include "llviewerwindow.h"
00079 #include "llwearable.h"
00080 #include "llwearablelist.h"
00081 #include "llviewermessage.h"
00082 #include "llviewerregion.h"
00083 #include "lltabcontainer.h"
00084 #include "lluictrlfactory.h"
00085 #include "llselectmgr.h"
00086 #include "llfloateropenobject.h"
00087
00088
00089
00090 void inc_busy_count()
00091 {
00092
00093
00094
00095 }
00096 void dec_busy_count()
00097 {
00098
00099
00100
00101 }
00102
00103
00104 struct LLWearableHoldingPattern;
00105 void wear_inventory_category_on_avatar(LLInventoryCategory* category, BOOL append);
00106 void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata);
00107 void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void*);
00108 void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, BOOL append);
00109 void remove_inventory_category_from_avatar(LLInventoryCategory* category);
00110 void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata);
00111 void move_task_inventory_callback(S32 option, void* user_data);
00112 void confirm_replace_attachment_rez(S32 option, void* user_data);
00113
00114 const char* ICON_NAME[ICON_NAME_COUNT] =
00115 {
00116 "inv_item_texture.tga",
00117 "inv_item_sound.tga",
00118 "inv_item_callingcard_online.tga",
00119 "inv_item_callingcard_offline.tga",
00120 "inv_item_landmark.tga",
00121 "inv_item_landmark_visited.tga",
00122 "inv_item_script.tga",
00123 "inv_item_clothing.tga",
00124 "inv_item_object.tga",
00125 "inv_item_object_multi.tga",
00126 "inv_item_notecard.tga",
00127 "inv_item_skin.tga",
00128 "inv_item_snapshot.tga",
00129
00130 "inv_item_shape.tga",
00131 "inv_item_skin.tga",
00132 "inv_item_hair.tga",
00133 "inv_item_eyes.tga",
00134 "inv_item_shirt.tga",
00135 "inv_item_pants.tga",
00136 "inv_item_shoes.tga",
00137 "inv_item_socks.tga",
00138 "inv_item_jacket.tga",
00139 "inv_item_gloves.tga",
00140 "inv_item_undershirt.tga",
00141 "inv_item_underpants.tga",
00142 "inv_item_skirt.tga",
00143
00144 "inv_item_animation.tga",
00145 "inv_item_gesture.tga",
00146 };
00147
00148 struct LLWearInfo
00149 {
00150 LLUUID mCategoryID;
00151 BOOL mAppend;
00152 };
00153
00154 BOOL gAddToOutfit = FALSE;
00155
00156
00157
00158
00159
00160 const LLString& LLInvFVBridge::getName() const
00161 {
00162 LLInventoryObject* obj = getInventoryObject();
00163 if(obj)
00164 {
00165 return obj->getName();
00166 }
00167 return LLString::null;
00168 }
00169
00170 const LLString& LLInvFVBridge::getDisplayName() const
00171 {
00172 return getName();
00173 }
00174
00175
00176 PermissionMask LLInvFVBridge::getPermissionMask() const
00177 {
00178
00179 return PERM_ALL;
00180 }
00181
00182
00183 U32 LLInvFVBridge::getCreationDate() const
00184 {
00185 return 0;
00186 }
00187
00188
00189 BOOL LLInvFVBridge::isItemRemovable()
00190 {
00191 LLInventoryModel* model = mInventoryPanel->getModel();
00192 if(!model) return FALSE;
00193 if(model->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID()))
00194 {
00195 return TRUE;
00196 }
00197 return FALSE;
00198 }
00199
00200
00201 BOOL LLInvFVBridge::isItemMovable()
00202 {
00203 return TRUE;
00204 }
00205
00206
00207 void LLInvFVBridge::showProperties()
00208 {
00209 LLShowProps::showProperties(mUUID);
00210 }
00211
00212 void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
00213 {
00214
00215 LLInvFVBridge* bridge;
00216 LLInventoryModel* model = mInventoryPanel->getModel();
00217 LLViewerInventoryItem* item = NULL;
00218 LLViewerInventoryCategory* cat = NULL;
00219 LLInventoryModel::cat_array_t descendent_categories;
00220 LLInventoryModel::item_array_t descendent_items;
00221 S32 count = batch.count();
00222 S32 i,j;
00223 for(i = 0; i < count; ++i)
00224 {
00225 bridge = (LLInvFVBridge*)(batch.get(i));
00226 if(!bridge || !bridge->isItemRemovable()) continue;
00227 item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());
00228 if (item)
00229 {
00230 if(LLAssetType::AT_GESTURE == item->getType())
00231 {
00232 gGestureManager.deactivateGesture(item->getUUID());
00233 }
00234 }
00235 }
00236 for(i = 0; i < count; ++i)
00237 {
00238 bridge = (LLInvFVBridge*)(batch.get(i));
00239 if(!bridge || !bridge->isItemRemovable()) continue;
00240 cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID());
00241 if (cat)
00242 {
00243 gInventory.collectDescendents( cat->getUUID(), descendent_categories, descendent_items, FALSE );
00244 for (j=0; j<descendent_items.count(); j++)
00245 {
00246 if(LLAssetType::AT_GESTURE == descendent_items[j]->getType())
00247 {
00248 gGestureManager.deactivateGesture(descendent_items[j]->getUUID());
00249 }
00250 }
00251 }
00252 }
00253 removeBatchNoCheck(batch);
00254 }
00255
00256 void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch)
00257 {
00258
00259
00260
00261
00262
00263 LLInvFVBridge* bridge;
00264 LLInventoryModel* model = mInventoryPanel->getModel();
00265 if(!model) return;
00266 LLMessageSystem* msg = gMessageSystem;
00267 LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
00268 LLViewerInventoryItem* item = NULL;
00269 LLViewerInventoryCategory* cat = NULL;
00270 std::vector<LLUUID> move_ids;
00271 LLInventoryModel::update_map_t update;
00272 bool start_new_message = true;
00273 S32 count = batch.count();
00274 S32 i;
00275 for(i = 0; i < count; ++i)
00276 {
00277 bridge = (LLInvFVBridge*)(batch.get(i));
00278 if(!bridge || !bridge->isItemRemovable()) continue;
00279 item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());
00280 if(item)
00281 {
00282 if(item->getParentUUID() == trash_id) continue;
00283 move_ids.push_back(item->getUUID());
00284 LLPreview::hide(item->getUUID());
00285 --update[item->getParentUUID()];
00286 ++update[trash_id];
00287 if(start_new_message)
00288 {
00289 start_new_message = false;
00290 msg->newMessageFast(_PREHASH_MoveInventoryItem);
00291 msg->nextBlockFast(_PREHASH_AgentData);
00292 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00293 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00294 msg->addBOOLFast(_PREHASH_Stamp, TRUE);
00295 }
00296 msg->nextBlockFast(_PREHASH_InventoryData);
00297 msg->addUUIDFast(_PREHASH_ItemID, item->getUUID());
00298 msg->addUUIDFast(_PREHASH_FolderID, trash_id);
00299 msg->addString("NewName", NULL);
00300 if(msg->isSendFullFast(_PREHASH_InventoryData))
00301 {
00302 start_new_message = true;
00303 gAgent.sendReliableMessage();
00304 gInventory.accountForUpdate(update);
00305 update.clear();
00306 }
00307 }
00308 }
00309 if(!start_new_message)
00310 {
00311 start_new_message = true;
00312 gAgent.sendReliableMessage();
00313 gInventory.accountForUpdate(update);
00314 update.clear();
00315 }
00316 for(i = 0; i < count; ++i)
00317 {
00318 bridge = (LLInvFVBridge*)(batch.get(i));
00319 if(!bridge || !bridge->isItemRemovable()) continue;
00320 cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID());
00321 if(cat)
00322 {
00323 if(cat->getParentUUID() == trash_id) continue;
00324 move_ids.push_back(cat->getUUID());
00325 --update[cat->getParentUUID()];
00326 ++update[trash_id];
00327 if(start_new_message)
00328 {
00329 start_new_message = false;
00330 msg->newMessageFast(_PREHASH_MoveInventoryFolder);
00331 msg->nextBlockFast(_PREHASH_AgentData);
00332 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00333 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00334 msg->addBOOL("Stamp", TRUE);
00335 }
00336 msg->nextBlockFast(_PREHASH_InventoryData);
00337 msg->addUUIDFast(_PREHASH_FolderID, cat->getUUID());
00338 msg->addUUIDFast(_PREHASH_ParentID, trash_id);
00339 if(msg->isSendFullFast(_PREHASH_InventoryData))
00340 {
00341 start_new_message = true;
00342 gAgent.sendReliableMessage();
00343 gInventory.accountForUpdate(update);
00344 update.clear();
00345 }
00346 }
00347 }
00348 if(!start_new_message)
00349 {
00350 gAgent.sendReliableMessage();
00351 gInventory.accountForUpdate(update);
00352 }
00353
00354
00355 std::vector<LLUUID>::iterator it = move_ids.begin();
00356 std::vector<LLUUID>::iterator end = move_ids.end();
00357 for(; it != end; ++it)
00358 {
00359 gInventory.moveObject((*it), trash_id);
00360 }
00361
00362
00363 model->notifyObservers();
00364 }
00365
00366 BOOL LLInvFVBridge::isClipboardPasteable() const
00367 {
00368 LLInventoryModel* model = mInventoryPanel->getModel();
00369 if(!model) return FALSE;
00370 BOOL is_agent_inventory = model->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID());
00371
00372 if(LLInventoryClipboard::instance().hasContents() && is_agent_inventory)
00373 {
00374 return TRUE;
00375 }
00376 return FALSE;
00377 }
00378
00379 void hideContextEntries(LLMenuGL& menu,
00380 const std::vector<LLString> &entries_to_show,
00381 const std::vector<LLString> &disabled_entries)
00382 {
00383 const LLView::child_list_t *list = menu.getChildList();
00384
00385 LLView::child_list_t::const_iterator itor;
00386 for (itor = list->begin(); itor != list->end(); ++itor)
00387 {
00388 LLString name = (*itor)->getName();
00389
00390
00391 LLMenuItemBranchGL* branchp = dynamic_cast<LLMenuItemBranchGL*>(*itor);
00392 if ((name == "More") && branchp)
00393 {
00394 hideContextEntries(*branchp->getBranch(), entries_to_show, disabled_entries);
00395 }
00396
00397
00398 bool found = false;
00399 std::vector<LLString>::const_iterator itor2;
00400 for (itor2 = entries_to_show.begin(); itor2 != entries_to_show.end(); ++itor2)
00401 {
00402 if (*itor2 == name)
00403 {
00404 found = true;
00405 }
00406 }
00407 if (!found)
00408 {
00409 (*itor)->setVisible(FALSE);
00410 }
00411 else
00412 {
00413 for (itor2 = disabled_entries.begin(); itor2 != disabled_entries.end(); ++itor2)
00414 {
00415 if (*itor2 == name)
00416 {
00417 (*itor)->setEnabled(FALSE);
00418 }
00419 }
00420 }
00421 }
00422 }
00423
00424
00425 void LLInvFVBridge::getClipboardEntries(bool show_asset_id, std::vector<LLString> &items,
00426 std::vector<LLString> &disabled_items, U32 flags)
00427 {
00428 items.push_back("Rename");
00429 if (!isItemRenameable() || (flags & FIRST_SELECTED_ITEM) == 0)
00430 {
00431 disabled_items.push_back("Rename");
00432 }
00433
00434 if (show_asset_id)
00435 {
00436 items.push_back("Copy Asset UUID");
00437 if ( (! ( isItemPermissive() || gAgent.isGodlike() ) )
00438 || (flags & FIRST_SELECTED_ITEM) == 0)
00439 {
00440 disabled_items.push_back("Copy Asset UUID");
00441 }
00442 }
00443
00444 items.push_back("Copy Separator");
00445
00446 items.push_back("Copy");
00447 if (!isItemCopyable())
00448 {
00449 disabled_items.push_back("Copy");
00450 }
00451
00452 items.push_back("Paste");
00453 if (!isClipboardPasteable() || (flags & FIRST_SELECTED_ITEM) == 0)
00454 {
00455 disabled_items.push_back("Paste");
00456 }
00457
00458 items.push_back("Paste Separator");
00459
00460 items.push_back("Delete");
00461 if (!isItemRemovable())
00462 {
00463 disabled_items.push_back("Delete");
00464 }
00465 }
00466
00467 void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
00468 {
00469 lldebugs << "LLInvFVBridge::buildContextMenu()" << llendl;
00470 std::vector<LLString> items;
00471 std::vector<LLString> disabled_items;
00472 if(isInTrash())
00473 {
00474 items.push_back("Purge Item");
00475 if (!isItemRemovable())
00476 {
00477 disabled_items.push_back("Purge Item");
00478 }
00479 items.push_back("Restore Item");
00480 }
00481 else
00482 {
00483 items.push_back("Open");
00484 items.push_back("Properties");
00485
00486 getClipboardEntries(true, items, disabled_items, flags);
00487 }
00488 hideContextEntries(menu, items, disabled_items);
00489 }
00490
00491
00492 BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
00493 {
00494 BOOL rv = FALSE;
00495
00496 const LLInventoryObject* obj = getInventoryObject();
00497
00498 if(obj)
00499 {
00500 *type = LLAssetType::lookupDragAndDropType(obj->getType());
00501 if(*type == DAD_NONE)
00502 {
00503 return FALSE;
00504 }
00505
00506 *id = obj->getUUID();
00507
00508
00509 if (*type == DAD_CATEGORY)
00510 {
00511 gInventory.startBackgroundFetch(obj->getUUID());
00512 }
00513
00514 rv = TRUE;
00515 }
00516
00517 return rv;
00518 }
00519
00520 LLInventoryObject* LLInvFVBridge::getInventoryObject() const
00521 {
00522 LLInventoryObject* obj = NULL;
00523 LLInventoryModel* model = mInventoryPanel->getModel();
00524 if(model)
00525 {
00526 obj = (LLInventoryObject*)model->getObject(mUUID);
00527 }
00528 return obj;
00529 }
00530
00531 BOOL LLInvFVBridge::isInTrash() const
00532 {
00533 LLInventoryModel* model = mInventoryPanel->getModel();
00534 if(!model) return FALSE;
00535 LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
00536 return model->isObjectDescendentOf(mUUID, trash_id);
00537 }
00538
00539 BOOL LLInvFVBridge::isAgentInventory() const
00540 {
00541 LLInventoryModel* model = mInventoryPanel->getModel();
00542 if(!model) return FALSE;
00543 if(gAgent.getInventoryRootID() == mUUID) return TRUE;
00544 return model->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID());
00545 }
00546
00547 BOOL LLInvFVBridge::isItemPermissive() const
00548 {
00549 return FALSE;
00550 }
00551
00552
00553 void LLInvFVBridge::changeItemParent(LLInventoryModel* model,
00554 LLViewerInventoryItem* item,
00555 const LLUUID& new_parent,
00556 BOOL restamp)
00557 {
00558 if(item->getParentUUID() != new_parent)
00559 {
00560 LLInventoryModel::update_list_t update;
00561 LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1);
00562 update.push_back(old_folder);
00563 LLInventoryModel::LLCategoryUpdate new_folder(new_parent, 1);
00564 update.push_back(new_folder);
00565 gInventory.accountForUpdate(update);
00566
00567 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
00568 new_item->setParent(new_parent);
00569 new_item->updateParentOnServer(restamp);
00570 model->updateItem(new_item);
00571 model->notifyObservers();
00572 }
00573 }
00574
00575
00576 void LLInvFVBridge::changeCategoryParent(LLInventoryModel* model,
00577 LLViewerInventoryCategory* cat,
00578 const LLUUID& new_parent,
00579 BOOL restamp)
00580 {
00581 if(cat->getParentUUID() != new_parent)
00582 {
00583 LLInventoryModel::update_list_t update;
00584 LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1);
00585 update.push_back(old_folder);
00586 LLInventoryModel::LLCategoryUpdate new_folder(new_parent, 1);
00587 update.push_back(new_folder);
00588 gInventory.accountForUpdate(update);
00589
00590 LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
00591 new_cat->setParent(new_parent);
00592 new_cat->updateParentOnServer(restamp);
00593 model->updateCategory(new_cat);
00594 model->notifyObservers();
00595 }
00596 }
00597
00598
00599 const char* safe_inv_type_lookup(LLInventoryType::EType inv_type)
00600 {
00601 const char* rv = LLInventoryType::lookup(inv_type);
00602 if(!rv)
00603 {
00604 const char* INVALID_TYPE = "<invalid>";
00605 rv = INVALID_TYPE;
00606 }
00607 return rv;
00608 }
00609
00610 LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
00611 LLInventoryType::EType inv_type,
00612 LLInventoryPanel* inventory,
00613 const LLUUID& uuid,
00614 U32 flags)
00615 {
00616 LLInvFVBridge* new_listener = NULL;
00617 switch(asset_type)
00618 {
00619 case LLAssetType::AT_TEXTURE:
00620 if(!(inv_type == LLInventoryType::IT_TEXTURE || inv_type == LLInventoryType::IT_SNAPSHOT))
00621 {
00622 llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
00623 }
00624 new_listener = new LLTextureBridge(inventory, uuid, inv_type);
00625 break;
00626
00627 case LLAssetType::AT_SOUND:
00628 if(!(inv_type == LLInventoryType::IT_SOUND))
00629 {
00630 llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
00631 }
00632 new_listener = new LLSoundBridge(inventory, uuid);
00633 break;
00634
00635 case LLAssetType::AT_LANDMARK:
00636 if(!(inv_type == LLInventoryType::IT_LANDMARK))
00637 {
00638 llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
00639 }
00640 new_listener = new LLLandmarkBridge(inventory, uuid, flags);
00641 break;
00642
00643 case LLAssetType::AT_CALLINGCARD:
00644 if(!(inv_type == LLInventoryType::IT_CALLINGCARD))
00645 {
00646 llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
00647 }
00648 new_listener = new LLCallingCardBridge(inventory, uuid);
00649 break;
00650
00651 case LLAssetType::AT_SCRIPT:
00652 if(!(inv_type == LLInventoryType::IT_LSL))
00653 {
00654 llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
00655 }
00656 new_listener = new LLScriptBridge(inventory, uuid);
00657 break;
00658
00659 case LLAssetType::AT_OBJECT:
00660 if(!(inv_type == LLInventoryType::IT_OBJECT || inv_type == LLInventoryType::IT_ATTACHMENT))
00661 {
00662 llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
00663 }
00664 new_listener = new LLObjectBridge(inventory, uuid, inv_type, flags);
00665 break;
00666
00667 case LLAssetType::AT_NOTECARD:
00668 if(!(inv_type == LLInventoryType::IT_NOTECARD))
00669 {
00670 llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
00671 }
00672 new_listener = new LLNotecardBridge(inventory, uuid);
00673 break;
00674
00675 case LLAssetType::AT_ANIMATION:
00676 if(!(inv_type == LLInventoryType::IT_ANIMATION))
00677 {
00678 llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
00679 }
00680 new_listener = new LLAnimationBridge(inventory, uuid);
00681 break;
00682
00683 case LLAssetType::AT_GESTURE:
00684 if(!(inv_type == LLInventoryType::IT_GESTURE))
00685 {
00686 llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
00687 }
00688 new_listener = new LLGestureBridge(inventory, uuid);
00689 break;
00690
00691 case LLAssetType::AT_LSL_TEXT:
00692 if(!(inv_type == LLInventoryType::IT_LSL))
00693 {
00694 llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
00695 }
00696 new_listener = new LLLSLTextBridge(inventory, uuid);
00697 break;
00698
00699 case LLAssetType::AT_CLOTHING:
00700 case LLAssetType::AT_BODYPART:
00701 if(!(inv_type == LLInventoryType::IT_WEARABLE))
00702 {
00703 llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
00704 }
00705 new_listener = new LLWearableBridge(inventory, uuid, asset_type, inv_type, (EWearableType)flags);
00706 break;
00707
00708 case LLAssetType::AT_CATEGORY:
00709 case LLAssetType::AT_ROOT_CATEGORY:
00710 new_listener = new LLFolderBridge(inventory, uuid);
00711 break;
00712
00713 default:
00714 llinfos << "Unhandled asset type (llassetstorage.h): "
00715 << (S32)asset_type << llendl;
00716 break;
00717 }
00718
00719 if (new_listener)
00720 {
00721 new_listener->mInvType = inv_type;
00722 }
00723
00724 return new_listener;
00725 }
00726
00727
00728
00729
00730
00731 void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model, LLString action)
00732 {
00733 if ("open" == action)
00734 {
00735 openItem();
00736 }
00737 else if ("properties" == action)
00738 {
00739 showProperties();
00740 }
00741 else if ("purge" == action)
00742 {
00743 LLInventoryCategory* cat = model->getCategory(mUUID);
00744 if(cat)
00745 {
00746 model->purgeDescendentsOf(mUUID);
00747 }
00748 LLInventoryObject* obj = model->getObject(mUUID);
00749 if(!obj) return;
00750 obj->removeFromServer();
00751 LLPreview::hide(mUUID);
00752 model->deleteObject(mUUID);
00753 model->notifyObservers();
00754 }
00755 else if ("restore" == action)
00756 {
00757 restoreItem();
00758 }
00759 else if ("copy_uuid" == action)
00760 {
00761
00762 LLInventoryItem* item = model->getItem(mUUID);
00763 if(!item) return;
00764 LLUUID asset_id = item->getAssetUUID();
00765 char buffer[UUID_STR_LENGTH];
00766 asset_id.toString(buffer);
00767
00768 gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(buffer));
00769 return;
00770 }
00771 else if ("copy" == action)
00772 {
00773 copyToClipboard();
00774 return;
00775 }
00776 else if ("paste" == action)
00777 {
00778
00779 LLInventoryItem* itemp = model->getItem(mUUID);
00780 if (!itemp) return;
00781
00782 LLFolderViewItem* folder_view_itemp = folder->getItemByID(itemp->getParentUUID());
00783 if (!folder_view_itemp) return;
00784
00785 folder_view_itemp->getListener()->pasteFromClipboard();
00786 return;
00787 }
00788 }
00789
00790 void LLItemBridge::selectItem()
00791 {
00792 LLViewerInventoryItem* item = (LLViewerInventoryItem*)getItem();
00793 if(item && !item->isComplete())
00794 {
00795 item->fetchFromServer();
00796 }
00797 }
00798
00799 void LLItemBridge::restoreItem()
00800 {
00801 LLViewerInventoryItem* item = (LLViewerInventoryItem*)getItem();
00802 if(item)
00803 {
00804 LLInventoryModel* model = mInventoryPanel->getModel();
00805 LLUUID new_parent = model->findCategoryUUIDForType(item->getType());
00806
00807 LLInvFVBridge::changeItemParent(model, item, new_parent, FALSE);
00808 }
00809 }
00810
00811 LLUIImagePtr LLItemBridge::getIcon() const
00812 {
00813 return LLUI::getUIImage(ICON_NAME[OBJECT_ICON_NAME]);
00814 }
00815
00816 PermissionMask LLItemBridge::getPermissionMask() const
00817 {
00818 LLViewerInventoryItem* item = getItem();
00819 PermissionMask perm_mask = 0;
00820 if(item)
00821 {
00822 BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
00823 BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID());
00824 BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER,
00825 gAgent.getID());
00826
00827 if (copy) perm_mask |= PERM_COPY;
00828 if (mod) perm_mask |= PERM_MODIFY;
00829 if (xfer) perm_mask |= PERM_TRANSFER;
00830
00831 }
00832 return perm_mask;
00833 }
00834
00835 const LLString& LLItemBridge::getDisplayName() const
00836 {
00837 if(mDisplayName.empty())
00838 {
00839 buildDisplayName(getItem(), mDisplayName);
00840 }
00841 return mDisplayName;
00842 }
00843
00844 void LLItemBridge::buildDisplayName(LLInventoryItem* item, LLString& name)
00845 {
00846 if(item)
00847 {
00848 name.assign(item->getName());
00849 }
00850 else
00851 {
00852 name.assign(LLString::null);
00853 }
00854 }
00855
00856 LLString LLItemBridge::getLabelSuffix() const
00857 {
00858 LLString suffix;
00859 LLInventoryItem* item = getItem();
00860 if(item)
00861 {
00862
00863 if(LLAssetType::AT_CALLINGCARD != item->getType()
00864 && item->getPermissions().getOwner() == gAgent.getID())
00865 {
00866 BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
00867 BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID());
00868 BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER,
00869 gAgent.getID());
00870 const char* EMPTY = "";
00871 const char* NO_COPY = " (no copy)";
00872 const char* NO_MOD = " (no modify)";
00873 const char* NO_XFER = " (no transfer)";
00874 const char* scopy;
00875 if(copy) scopy = EMPTY;
00876 else scopy = NO_COPY;
00877 const char* smod;
00878 if(mod) smod = EMPTY;
00879 else smod = NO_MOD;
00880 const char* sxfer;
00881 if(xfer) sxfer = EMPTY;
00882 else sxfer = NO_XFER;
00883 char buffer[MAX_STRING];
00884 snprintf(
00885 buffer,
00886 MAX_STRING,
00887 "%s%s%s",
00888 scopy,
00889 smod,
00890 sxfer);
00891 suffix.assign(buffer);
00892 }
00893 }
00894 return suffix;
00895 }
00896
00897 U32 LLItemBridge::getCreationDate() const
00898 {
00899 LLViewerInventoryItem* item = getItem();
00900 if (item)
00901 {
00902 return item->getCreationDate();
00903 }
00904 return 0;
00905 }
00906
00907
00908 BOOL LLItemBridge::isItemRenameable() const
00909 {
00910 LLViewerInventoryItem* item = getItem();
00911 if(item)
00912 {
00913 return (item->getPermissions().allowModifyBy(gAgent.getID()));
00914 }
00915 return FALSE;
00916 }
00917
00918 BOOL LLItemBridge::renameItem(const LLString& new_name)
00919 {
00920 if(!isItemRenameable()) return FALSE;
00921 LLPreview::rename(mUUID, getPrefix() + new_name);
00922 LLInventoryModel* model = mInventoryPanel->getModel();
00923 if(!model) return FALSE;
00924 LLViewerInventoryItem* item = getItem();
00925 if(item && (item->getName() != new_name))
00926 {
00927 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
00928 new_item->rename(new_name);
00929 buildDisplayName(new_item, mDisplayName);
00930 new_item->updateServer(FALSE);
00931 model->updateItem(new_item);
00932 model->notifyObservers();
00933 }
00934
00935
00936 return FALSE;
00937 }
00938
00939
00940 BOOL LLItemBridge::removeItem()
00941 {
00942 if(!isItemRemovable())
00943 {
00944 return FALSE;
00945 }
00946
00947 LLPreview::hide(mUUID, TRUE);
00948 LLInventoryModel* model = mInventoryPanel->getModel();
00949 if(!model) return FALSE;
00950 LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
00951 LLViewerInventoryItem* item = getItem();
00952
00953
00954 if(item && !model->isObjectDescendentOf(mUUID, trash_id))
00955 {
00956
00957 LLInvFVBridge::changeItemParent(model, item, trash_id, TRUE);
00958
00959 return TRUE;
00960 }
00961 else
00962 {
00963
00964 return FALSE;
00965 }
00966 }
00967
00968 BOOL LLItemBridge::isItemCopyable() const
00969 {
00970 LLViewerInventoryItem* item = getItem();
00971 if (item)
00972 {
00973 return (item->getPermissions().allowCopyBy(gAgent.getID()));
00974 }
00975 return FALSE;
00976 }
00977 BOOL LLItemBridge::copyToClipboard() const
00978 {
00979 if(isItemCopyable())
00980 {
00981 LLInventoryClipboard::instance().add(mUUID);
00982 return TRUE;
00983 }
00984 return FALSE;
00985 }
00986
00987 LLViewerInventoryItem* LLItemBridge::getItem() const
00988 {
00989 LLViewerInventoryItem* item = NULL;
00990 LLInventoryModel* model = mInventoryPanel->getModel();
00991 if(model)
00992 {
00993 item = (LLViewerInventoryItem*)model->getItem(mUUID);
00994 }
00995 return item;
00996 }
00997
00998 BOOL LLItemBridge::isItemPermissive() const
00999 {
01000 LLViewerInventoryItem* item = getItem();
01001 if(item)
01002 {
01003 U32 mask = item->getPermissions().getMaskBase();
01004 if((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
01005 {
01006 return TRUE;
01007 }
01008 }
01009 return FALSE;
01010 }
01011
01012
01013
01014
01015
01016 LLFolderBridge* LLFolderBridge::sSelf=NULL;
01017
01018
01019 BOOL LLFolderBridge::isItemMovable()
01020 {
01021 LLInventoryObject* obj = getInventoryObject();
01022 if(obj)
01023 {
01024 return (LLAssetType::AT_NONE == ((LLInventoryCategory*)obj)->getPreferredType());
01025 }
01026 return FALSE;
01027 }
01028
01029 void LLFolderBridge::selectItem()
01030 {
01031 }
01032
01033
01034
01035 BOOL LLFolderBridge::isItemRemovable()
01036 {
01037 LLInventoryModel* model = mInventoryPanel->getModel();
01038 if(!model)
01039 {
01040 return FALSE;
01041 }
01042
01043 if(!model->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID()))
01044 {
01045 return FALSE;
01046 }
01047
01048 LLVOAvatar* avatar = gAgent.getAvatarObject();
01049 if( !avatar )
01050 {
01051 return FALSE;
01052 }
01053
01054 LLInventoryCategory* category = model->getCategory(mUUID);
01055 if( !category )
01056 {
01057 return FALSE;
01058 }
01059
01060 if( LLAssetType::AT_NONE != category->getPreferredType() )
01061 {
01062 return FALSE;
01063 }
01064
01065 LLInventoryModel::cat_array_t descendent_categories;
01066 LLInventoryModel::item_array_t descendent_items;
01067 gInventory.collectDescendents( mUUID, descendent_categories, descendent_items, FALSE );
01068
01069 S32 i;
01070 for( i = 0; i < descendent_categories.count(); i++ )
01071 {
01072 LLInventoryCategory* category = descendent_categories[i];
01073 if( LLAssetType::AT_NONE != category->getPreferredType() )
01074 {
01075 return FALSE;
01076 }
01077 }
01078
01079 for( i = 0; i < descendent_items.count(); i++ )
01080 {
01081 LLInventoryItem* item = descendent_items[i];
01082 if( (item->getType() == LLAssetType::AT_CLOTHING) ||
01083 (item->getType() == LLAssetType::AT_BODYPART) )
01084 {
01085 if( gAgent.isWearingItem( item->getUUID() ) )
01086 {
01087 return FALSE;
01088 }
01089 }
01090 else
01091 if( item->getType() == LLAssetType::AT_OBJECT )
01092 {
01093 if( avatar->isWearingAttachment( item->getUUID() ) )
01094 {
01095 return FALSE;
01096 }
01097 }
01098 }
01099
01100 return TRUE;
01101 }
01102
01103 BOOL LLFolderBridge::isUpToDate() const
01104 {
01105 LLInventoryModel* model = mInventoryPanel->getModel();
01106 if(!model) return FALSE;
01107 LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID);
01108 if( !category )
01109 {
01110 return FALSE;
01111 }
01112
01113 return category->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN;
01114 }
01115
01116 BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
01117 BOOL drop)
01118 {
01119
01120
01121 if(!inv_cat) return FALSE;
01122
01123 LLInventoryModel* model = mInventoryPanel->getModel();
01124 if(!model) return FALSE;
01125
01126 LLVOAvatar* avatar = gAgent.getAvatarObject();
01127 if(!avatar) return FALSE;
01128
01129
01130 if(!isAgentInventory())
01131 {
01132 return FALSE;
01133 }
01134
01135
01136 LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource();
01137 BOOL is_agent_inventory = (model->getCategory(inv_cat->getUUID()) != NULL)
01138 && (LLToolDragAndDrop::SOURCE_AGENT == source);
01139
01140 BOOL accept = FALSE;
01141 S32 i;
01142 LLInventoryModel::cat_array_t descendent_categories;
01143 LLInventoryModel::item_array_t descendent_items;
01144 if(is_agent_inventory)
01145 {
01146 const LLUUID& cat_id = inv_cat->getUUID();
01147
01148
01149 LLUUID trash_id;
01150 trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
01151 BOOL move_is_into_trash = (mUUID == trash_id)
01152 || model->isObjectDescendentOf(mUUID, trash_id);
01153 BOOL is_movable = (LLAssetType::AT_NONE == inv_cat->getPreferredType());
01154 if( is_movable )
01155 {
01156 gInventory.collectDescendents( cat_id, descendent_categories, descendent_items, FALSE );
01157
01158 for( i = 0; i < descendent_categories.count(); i++ )
01159 {
01160 LLInventoryCategory* category = descendent_categories[i];
01161 if( LLAssetType::AT_NONE != category->getPreferredType() )
01162 {
01163
01164 is_movable = FALSE;
01165 break;
01166 }
01167 }
01168
01169 if( is_movable )
01170 {
01171 if( move_is_into_trash )
01172 {
01173 for( i = 0; i < descendent_items.count(); i++ )
01174 {
01175 LLInventoryItem* item = descendent_items[i];
01176 if( (item->getType() == LLAssetType::AT_CLOTHING) ||
01177 (item->getType() == LLAssetType::AT_BODYPART) )
01178 {
01179 if( gAgent.isWearingItem( item->getUUID() ) )
01180 {
01181 is_movable = FALSE;
01182 break;
01183 }
01184 }
01185 else
01186 if( item->getType() == LLAssetType::AT_OBJECT )
01187 {
01188 if( avatar->isWearingAttachment( item->getUUID() ) )
01189 {
01190 is_movable = FALSE;
01191 break;
01192 }
01193 }
01194 }
01195 }
01196 }
01197 }
01198
01199
01200 accept = is_movable
01201 && (mUUID != cat_id)
01202 && (mUUID != inv_cat->getParentUUID())
01203 && !(model->isObjectDescendentOf(mUUID, cat_id));
01204 if(accept && drop)
01205 {
01206
01207 if (move_is_into_trash)
01208 {
01209 for (i = 0; i < descendent_items.count(); i++)
01210 {
01211 LLInventoryItem* item = descendent_items[i];
01212 if (item->getType() == LLAssetType::AT_GESTURE
01213 && gGestureManager.isGestureActive(item->getUUID()))
01214 {
01215 gGestureManager.deactivateGesture(item->getUUID());
01216 }
01217 }
01218 }
01219
01220
01221
01222 LLInvFVBridge::changeCategoryParent(
01223 model,
01224 (LLViewerInventoryCategory*)inv_cat,
01225 mUUID,
01226 move_is_into_trash);
01227 }
01228 }
01229 else if(LLToolDragAndDrop::SOURCE_WORLD == source)
01230 {
01231
01232 LLUUID object_id = inv_cat->getUUID();
01233 LLUUID category_id = mUUID;
01234 accept = move_inv_category_world_to_agent(object_id, category_id, drop);
01235 }
01236 return accept;
01237 }
01238
01239 void warn_move_inventory(LLViewerObject* object, LLMoveInv* move_inv)
01240 {
01241 const char* dialog = NULL;
01242 if (object->flagScripted())
01243 {
01244 dialog = "MoveInventoryFromScriptedObject";
01245 }
01246 else
01247 {
01248 dialog = "MoveInventoryFromObject";
01249 }
01250 gViewerWindow->alertXml(dialog, move_task_inventory_callback, move_inv);
01251 }
01252
01253
01254
01255 BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
01256 const LLUUID& category_id,
01257 BOOL drop,
01258 void (*callback)(S32, void*),
01259 void* user_data)
01260 {
01261
01262
01263
01264
01265 LLViewerObject* object = gObjectList.findObject(object_id);
01266 if(!object)
01267 {
01268 llinfos << "Object not found for drop." << llendl;
01269 return FALSE;
01270 }
01271
01272
01273
01274 InventoryObjectList inventory_objects;
01275 object->getInventoryContents(inventory_objects);
01276
01277 if (inventory_objects.empty())
01278 {
01279 llinfos << "Object contents not found for drop." << llendl;
01280 return FALSE;
01281 }
01282
01283 BOOL accept = TRUE;
01284 BOOL is_move = FALSE;
01285
01286
01287
01288 InventoryObjectList::iterator it = inventory_objects.begin();
01289 InventoryObjectList::iterator end = inventory_objects.end();
01290 for ( ; it != end; ++it)
01291 {
01292
01293
01294 LLPermissions perm(((LLInventoryItem*)((LLInventoryObject*)(*it)))->getPermissions());
01295 if((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID())
01296 && perm.allowTransferTo(gAgent.getID())))
01297
01298 {
01299 accept = TRUE;
01300 }
01301 else if(object->permYouOwner())
01302 {
01303
01304
01305
01306 is_move = TRUE;
01307 accept = TRUE;
01308 }
01309 else
01310 {
01311 accept = FALSE;
01312 break;
01313 }
01314 }
01315
01316 if(drop && accept)
01317 {
01318 it = inventory_objects.begin();
01319 InventoryObjectList::iterator first_it = inventory_objects.begin();
01320 LLMoveInv* move_inv = new LLMoveInv;
01321 move_inv->mObjectID = object_id;
01322 move_inv->mCategoryID = category_id;
01323 move_inv->mCallback = callback;
01324 move_inv->mUserData = user_data;
01325
01326 for ( ; it != end; ++it)
01327 {
01328 two_uuids_t two(category_id, (*it)->getUUID());
01329 move_inv->mMoveList.push_back(two);
01330 }
01331
01332 if(is_move)
01333 {
01334
01335 warn_move_inventory(object, move_inv);
01336 }
01337 else
01338 {
01339 move_task_inventory_callback(0, (void*)(move_inv));
01340 }
01341 }
01342 return accept;
01343 }
01344
01345 class LLFindWearables : public LLInventoryCollectFunctor
01346 {
01347 public:
01348 LLFindWearables() {}
01349 virtual ~LLFindWearables() {}
01350 virtual bool operator()(LLInventoryCategory* cat,
01351 LLInventoryItem* item);
01352 };
01353
01354 bool LLFindWearables::operator()(LLInventoryCategory* cat,
01355 LLInventoryItem* item)
01356 {
01357 if(item)
01358 {
01359 if((item->getType() == LLAssetType::AT_CLOTHING)
01360 || (item->getType() == LLAssetType::AT_BODYPART))
01361 {
01362 return TRUE;
01363 }
01364 }
01365 return FALSE;
01366 }
01367
01368
01369 class LLRightClickInventoryFetchObserver : public LLInventoryFetchObserver
01370 {
01371 public:
01372 LLRightClickInventoryFetchObserver() {};
01373 LLRightClickInventoryFetchObserver(const LLUUID& cat_id, bool copy_items) :
01374 mCatID(cat_id),
01375 mCopyItems(copy_items)
01376 { };
01377 virtual void done()
01378 {
01379
01380 LLFolderBridge::staticFolderOptionsMenu();
01381
01382 gInventory.removeObserver(this);
01383 delete this;
01384 }
01385
01386
01387 protected:
01388 LLUUID mCatID;
01389 bool mCopyItems;
01390
01391 };
01392
01393
01394 class LLRightClickInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver
01395 {
01396 public:
01397 LLRightClickInventoryFetchDescendentsObserver(bool copy_items) : mCopyItems(copy_items) {}
01398 ~LLRightClickInventoryFetchDescendentsObserver() {}
01399 virtual void done();
01400 protected:
01401 bool mCopyItems;
01402 };
01403
01404 void LLRightClickInventoryFetchDescendentsObserver::done()
01405 {
01406
01407
01408 if( mCompleteFolders.empty() )
01409 {
01410 llwarns << "LLRightClickInventoryFetchDescendentsObserver::done with empty mCompleteFolders" << llendl;
01411 dec_busy_count();
01412 gInventory.removeObserver(this);
01413 delete this;
01414 return;
01415 }
01416
01417
01418
01419
01420 LLInventoryModel::cat_array_t cat_array;
01421 LLInventoryModel::item_array_t item_array;
01422 gInventory.collectDescendents(mCompleteFolders.front(),
01423 cat_array,
01424 item_array,
01425 LLInventoryModel::EXCLUDE_TRASH);
01426 S32 count = item_array.count();
01427 #if 0 // HACK/TODO: Why?
01428
01429 if(!count)
01430 {
01431 llwarns << "Nothing fetched in category " << mCompleteFolders.front()
01432 << llendl;
01433 dec_busy_count();
01434 gInventory.removeObserver(this);
01435 delete this;
01436 return;
01437 }
01438 #endif
01439
01440 LLRightClickInventoryFetchObserver* outfit;
01441 outfit = new LLRightClickInventoryFetchObserver(mCompleteFolders.front(), mCopyItems);
01442 LLInventoryFetchObserver::item_ref_t ids;
01443 for(S32 i = 0; i < count; ++i)
01444 {
01445 ids.push_back(item_array.get(i)->getUUID());
01446 }
01447
01448
01449
01450
01451 dec_busy_count();
01452 gInventory.removeObserver(this);
01453 delete this;
01454
01455
01456
01457 inc_busy_count();
01458
01459
01460 outfit->fetchItems(ids);
01461 outfit->done();
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474 }
01475
01476
01477
01478
01479
01480
01481
01482
01483 class LLInventoryCopyAndWearObserver : public LLInventoryObserver
01484 {
01485 public:
01486 LLInventoryCopyAndWearObserver(const LLUUID& cat_id, int count) :mCatID(cat_id), mContentsCount(count), mFolderAdded(FALSE) {}
01487 virtual ~LLInventoryCopyAndWearObserver() {}
01488 virtual void changed(U32 mask);
01489
01490 protected:
01491 LLUUID mCatID;
01492 int mContentsCount;
01493 BOOL mFolderAdded;
01494 };
01495
01496
01497
01498 void LLInventoryCopyAndWearObserver::changed(U32 mask)
01499 {
01500 if((mask & (LLInventoryObserver::ADD)) != 0)
01501 {
01502 if (!mFolderAdded)
01503 {
01504 const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
01505
01506 std::set<LLUUID>::const_iterator id_it = changed_items.begin();
01507 std::set<LLUUID>::const_iterator id_end = changed_items.end();
01508 for (;id_it != id_end; ++id_it)
01509 {
01510 if ((*id_it) == mCatID)
01511 {
01512 mFolderAdded = TRUE;
01513 break;
01514 }
01515 }
01516 }
01517
01518 if (mFolderAdded)
01519 {
01520 LLViewerInventoryCategory* category = gInventory.getCategory(mCatID);
01521
01522 if (NULL == category)
01523 {
01524 llwarns << "gInventory.getCategory(" << mCatID
01525 << ") was NULL" << llendl;
01526 }
01527 else
01528 {
01529 if (category->getDescendentCount() ==
01530 mContentsCount)
01531 {
01532 gInventory.removeObserver(this);
01533 wear_inventory_category(category, FALSE, TRUE);
01534 delete this;
01535 }
01536 }
01537 }
01538
01539 }
01540 }
01541
01542
01543
01544 void LLFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model, LLString action)
01545 {
01546 if ("open" == action)
01547 {
01548 openItem();
01549 }
01550 else if ("paste" == action)
01551 {
01552 pasteFromClipboard();
01553 }
01554 else if ("properties" == action)
01555 {
01556 showProperties();
01557 }
01558 else if ("replaceoutfit" == action)
01559 {
01560 modifyOutfit(FALSE);
01561 }
01562 else if ("addtooutfit" == action)
01563 {
01564 modifyOutfit(TRUE);
01565 }
01566 else if ("removefromoutfit" == action)
01567 {
01568 LLInventoryModel* model = mInventoryPanel->getModel();
01569 if(!model) return;
01570 LLViewerInventoryCategory* cat = getCategory();
01571 if(!cat) return;
01572
01573 remove_inventory_category_from_avatar ( cat );
01574 }
01575 else if ("purge" == action)
01576 {
01577 LLViewerInventoryCategory* cat;
01578 cat = (LLViewerInventoryCategory*)getCategory();
01579
01580 if(cat)
01581 {
01582 model->purgeDescendentsOf(mUUID);
01583 }
01584 LLInventoryObject* obj = model->getObject(mUUID);
01585 if(!obj) return;
01586 obj->removeFromServer();
01587 model->deleteObject(mUUID);
01588 model->notifyObservers();
01589 }
01590 else if ("restore" == action)
01591 {
01592 restoreItem();
01593 }
01594 }
01595
01596 void LLFolderBridge::openItem()
01597 {
01598 lldebugs << "LLFolderBridge::openItem()" << llendl;
01599 LLInventoryModel* model = mInventoryPanel->getModel();
01600 if(!model) return;
01601 model->fetchDescendentsOf(mUUID);
01602 }
01603
01604 BOOL LLFolderBridge::isItemRenameable() const
01605 {
01606 LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)getCategory();
01607 if(cat && (cat->getPreferredType() == LLAssetType::AT_NONE)
01608 && (cat->getOwnerID() == gAgent.getID()))
01609 {
01610 return TRUE;
01611 }
01612 return FALSE;
01613 }
01614
01615 void LLFolderBridge::restoreItem()
01616 {
01617 LLViewerInventoryCategory* cat;
01618 cat = (LLViewerInventoryCategory*)getCategory();
01619 if(cat)
01620 {
01621 LLInventoryModel* model = mInventoryPanel->getModel();
01622 LLUUID new_parent = model->findCategoryUUIDForType(cat->getType());
01623
01624 LLInvFVBridge::changeCategoryParent(model, cat, new_parent, FALSE);
01625 }
01626 }
01627
01628
01629 LLUIImagePtr LLFolderBridge::getIcon() const
01630 {
01631 const char* control = NULL;
01632 LLAssetType::EType preferred_type = LLAssetType::AT_NONE;
01633 LLViewerInventoryCategory* cat = getCategory();
01634 if(cat)
01635 {
01636 preferred_type = cat->getPreferredType();
01637 }
01638 switch(preferred_type)
01639 {
01640 case LLAssetType::AT_TEXTURE:
01641 control = "inv_folder_texture.tga";
01642 break;
01643 case LLAssetType::AT_SOUND:
01644 control = "inv_folder_sound.tga";
01645 break;
01646 case LLAssetType::AT_CALLINGCARD:
01647 control = "inv_folder_callingcard.tga";
01648 break;
01649 case LLAssetType::AT_LANDMARK:
01650 control = "inv_folder_landmark.tga";
01651 break;
01652 case LLAssetType::AT_SCRIPT:
01653 case LLAssetType::AT_LSL_TEXT:
01654 control = "inv_folder_script.tga";
01655 break;
01656 case LLAssetType::AT_OBJECT:
01657 control = "inv_folder_object.tga";
01658 break;
01659 case LLAssetType::AT_NOTECARD:
01660 control = "inv_folder_notecard.tga";
01661 break;
01662 case LLAssetType::AT_CATEGORY:
01663 control = "inv_folder_plain_closed.tga";
01664 break;
01665 case LLAssetType::AT_CLOTHING:
01666 control = "inv_folder_clothing.tga";
01667 break;
01668 case LLAssetType::AT_BODYPART:
01669 control = "inv_folder_bodypart.tga";
01670 break;
01671 case LLAssetType::AT_TRASH:
01672 control = "inv_folder_trash.tga";
01673 break;
01674 case LLAssetType::AT_SNAPSHOT_CATEGORY:
01675 control = "inv_folder_snapshot.tga";
01676 break;
01677 case LLAssetType::AT_LOST_AND_FOUND:
01678 control = "inv_folder_lostandfound.tga";
01679 break;
01680 case LLAssetType::AT_ANIMATION:
01681 control = "inv_folder_animation.tga";
01682 break;
01683 case LLAssetType::AT_GESTURE:
01684 control = "inv_folder_gesture.tga";
01685 break;
01686 default:
01687 control = "inv_folder_plain_closed.tga";
01688 break;
01689 }
01690 return LLUI::getUIImage(control);
01691 }
01692
01693 BOOL LLFolderBridge::renameItem(const LLString& new_name)
01694 {
01695 if(!isItemRenameable()) return FALSE;
01696 LLInventoryModel* model = mInventoryPanel->getModel();
01697 if(!model) return FALSE;
01698 LLViewerInventoryCategory* cat = getCategory();
01699 if(cat && (cat->getName() != new_name))
01700 {
01701 LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
01702 new_cat->rename(new_name);
01703 new_cat->updateServer(FALSE);
01704 model->updateCategory(new_cat);
01705 model->notifyObservers();
01706 }
01707
01708
01709 return FALSE;
01710 }
01711
01712 BOOL LLFolderBridge::removeItem()
01713 {
01714 if(!isItemRemovable())
01715 {
01716 return FALSE;
01717 }
01718
01719 LLPreview::hide(mUUID);
01720 LLInventoryModel* model = mInventoryPanel->getModel();
01721 if(!model) return FALSE;
01722
01723 LLUUID trash_id;
01724 trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
01725
01726
01727 LLInventoryModel::cat_array_t descendent_categories;
01728 LLInventoryModel::item_array_t descendent_items;
01729 gInventory.collectDescendents( mUUID, descendent_categories, descendent_items, FALSE );
01730
01731 S32 i;
01732 for (i = 0; i < descendent_items.count(); i++)
01733 {
01734 LLInventoryItem* item = descendent_items[i];
01735 if (item->getType() == LLAssetType::AT_GESTURE
01736 && gGestureManager.isGestureActive(item->getUUID()))
01737 {
01738 gGestureManager.deactivateGesture(item->getUUID());
01739 }
01740 }
01741
01742
01743
01744 LLViewerInventoryCategory* cat = getCategory();
01745 if(cat)
01746 {
01747 LLInvFVBridge::changeCategoryParent(model, cat, trash_id, TRUE);
01748 }
01749
01750 return TRUE;
01751 }
01752
01753 BOOL LLFolderBridge::isClipboardPasteable() const
01754 {
01755 if(LLInventoryClipboard::instance().hasContents() && isAgentInventory())
01756 {
01757 return TRUE;
01758 }
01759 return FALSE;
01760 }
01761
01762 void LLFolderBridge::pasteFromClipboard()
01763 {
01764 LLInventoryModel* model = mInventoryPanel->getModel();
01765 if(model && isClipboardPasteable())
01766 {
01767 LLInventoryItem* item = NULL;
01768 LLDynamicArray<LLUUID> objects;
01769 LLInventoryClipboard::instance().retrieve(objects);
01770 S32 count = objects.count();
01771 LLUUID parent_id(mUUID);
01772 for(S32 i = 0; i < count; i++)
01773 {
01774 item = model->getItem(objects.get(i));
01775 if (item)
01776 {
01777 copy_inventory_item(
01778 gAgent.getID(),
01779 item->getPermissions().getOwner(),
01780 item->getUUID(),
01781 parent_id,
01782 std::string(),
01783 LLPointer<LLInventoryCallback>(NULL));
01784 }
01785 }
01786 }
01787 }
01788
01789 void LLFolderBridge::staticFolderOptionsMenu()
01790 {
01791 if (!sSelf) return;
01792 sSelf->folderOptionsMenu();
01793 }
01794
01795 void LLFolderBridge::folderOptionsMenu()
01796 {
01797 std::vector<LLString> disabled_items;
01798
01799 LLInventoryModel* model = mInventoryPanel->getModel();
01800 if(!model) return;
01801
01802
01803
01804 LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
01805 if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard))
01806 {
01807 mItems.push_back("Calling Card Separator");
01808 mItems.push_back("Conference Chat Folder");
01809 mItems.push_back("IM All Contacts In Folder");
01810 }
01811
01812
01813
01814 LLFindWearables is_wearable;
01815 LLIsType is_object( LLAssetType::AT_OBJECT );
01816 LLIsType is_gesture( LLAssetType::AT_GESTURE );
01817
01818 if (mWearables ||
01819 checkFolderForContentsOfType(model, is_wearable) ||
01820 checkFolderForContentsOfType(model, is_object) ||
01821 checkFolderForContentsOfType(model, is_gesture) )
01822 {
01823 mItems.push_back("Folder Wearables Separator");
01824
01825
01826 const LLInventoryCategory* category = model->getCategory(mUUID);
01827 if (!category || (LLAssetType::AT_NONE == category->getPreferredType()))
01828 {
01829 mItems.push_back("Add To Outfit");
01830 mItems.push_back("Replace Outfit");
01831 }
01832 mItems.push_back("Take Off Items");
01833 }
01834 hideContextEntries(*mMenu, mItems, disabled_items);
01835 }
01836
01837 BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& is_type)
01838 {
01839 LLInventoryModel::cat_array_t cat_array;
01840 LLInventoryModel::item_array_t item_array;
01841 model->collectDescendentsIf(mUUID,
01842 cat_array,
01843 item_array,
01844 LLInventoryModel::EXCLUDE_TRASH,
01845 is_type);
01846 return ((item_array.count() > 0) ? TRUE : FALSE );
01847 }
01848
01849
01850 void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
01851 {
01852 lldebugs << "LLFolderBridge::buildContextMenu()" << llendl;
01853
01854 LLInventoryModel* model = mInventoryPanel->getModel();
01855 if(!model) return;
01856 LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
01857 LLUUID lost_and_found_id = model->findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND);
01858
01859 if (lost_and_found_id == mUUID)
01860 {
01861
01862 mItems.push_back("Empty Lost And Found");
01863 }
01864
01865 if(trash_id == mUUID)
01866 {
01867
01868 mItems.push_back("Empty Trash");
01869 }
01870 else if(model->isObjectDescendentOf(mUUID, trash_id))
01871 {
01872
01873 mItems.clear();
01874 mItems.push_back("Purge Item");
01875 if (!isItemRemovable())
01876 {
01877 mDisabledItems.push_back("Purge Item");
01878 }
01879
01880 mItems.push_back("Restore Item");
01881 }
01882 else if(isAgentInventory())
01883 {
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909 mItems.push_back("New Folder");
01910 mItems.push_back("New Script");
01911 mItems.push_back("New Note");
01912 mItems.push_back("New Gesture");
01913 mItems.push_back("New Clothes");
01914 mItems.push_back("New Body Parts");
01915
01916 getClipboardEntries(false, mItems, mDisabledItems, flags);
01917
01918
01919 mCallingCards = mWearables = FALSE;
01920
01921 LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
01922 if (checkFolderForContentsOfType(model, is_callingcard))
01923 {
01924 mCallingCards=TRUE;
01925 }
01926
01927 LLFindWearables is_wearable;
01928 LLIsType is_object( LLAssetType::AT_OBJECT );
01929 LLIsType is_gesture( LLAssetType::AT_GESTURE );
01930
01931 if (checkFolderForContentsOfType(model, is_wearable) ||
01932 checkFolderForContentsOfType(model, is_object) ||
01933 checkFolderForContentsOfType(model, is_gesture) )
01934 {
01935 mWearables=TRUE;
01936 }
01937
01938 mMenu = &menu;
01939 sSelf = this;
01940 LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(FALSE);
01941
01942 LLInventoryFetchDescendentsObserver::folder_ref_t folders;
01943 LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID);
01944 folders.push_back(category->getUUID());
01945 fetch->fetchDescendents(folders);
01946 inc_busy_count();
01947 if(fetch->isEverythingComplete())
01948 {
01949
01950 fetch->done();
01951 }
01952 else
01953 {
01954
01955
01956 gInventory.addObserver(fetch);
01957 }
01958 }
01959 else
01960 {
01961 mItems.push_back("--no options--");
01962 mDisabledItems.push_back("--no options--");
01963 }
01964 hideContextEntries(menu, mItems, mDisabledItems);
01965 }
01966
01967 BOOL LLFolderBridge::hasChildren() const
01968 {
01969 LLInventoryModel* model = mInventoryPanel->getModel();
01970 if(!model) return FALSE;
01971 LLInventoryModel::EHasChildren has_children;
01972 has_children = gInventory.categoryHasChildren(mUUID);
01973 return has_children != LLInventoryModel::CHILDREN_NO;
01974 }
01975
01976 BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
01977 EDragAndDropType cargo_type,
01978 void* cargo_data)
01979 {
01980
01981 BOOL accept = FALSE;
01982 switch(cargo_type)
01983 {
01984 case DAD_TEXTURE:
01985 case DAD_SOUND:
01986 case DAD_CALLINGCARD:
01987 case DAD_LANDMARK:
01988 case DAD_SCRIPT:
01989 case DAD_OBJECT:
01990 case DAD_NOTECARD:
01991 case DAD_CLOTHING:
01992 case DAD_BODYPART:
01993 case DAD_ANIMATION:
01994 case DAD_GESTURE:
01995 accept = dragItemIntoFolder((LLInventoryItem*)cargo_data,
01996 drop);
01997 break;
01998 case DAD_CATEGORY:
01999 accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data,
02000 drop);
02001 break;
02002 default:
02003 break;
02004 }
02005 return accept;
02006 }
02007
02008 LLViewerInventoryCategory* LLFolderBridge::getCategory() const
02009 {
02010 LLViewerInventoryCategory* cat = NULL;
02011 LLInventoryModel* model = mInventoryPanel->getModel();
02012 if(model)
02013 {
02014 cat = (LLViewerInventoryCategory*)model->getCategory(mUUID);
02015 }
02016 return cat;
02017 }
02018
02019
02020
02021 void LLFolderBridge::pasteClipboard(void* user_data)
02022 {
02023 LLFolderBridge* self = (LLFolderBridge*)user_data;
02024 if(self) self->pasteFromClipboard();
02025 }
02026
02027 void LLFolderBridge::createNewCategory(void* user_data)
02028 {
02029 LLFolderBridge* bridge = (LLFolderBridge*)user_data;
02030 if(!bridge) return;
02031 LLInventoryPanel* panel = bridge->mInventoryPanel;
02032 LLInventoryModel* model = panel->getModel();
02033 if(!model) return;
02034 LLUUID id;
02035 id = model->createNewCategory(bridge->getUUID(),
02036 LLAssetType::AT_NONE,
02037 NULL);
02038 model->notifyObservers();
02039
02040
02041
02042 panel->setSelection(id, TAKE_FOCUS_YES);
02043 }
02044
02045 void LLFolderBridge::createNewShirt(void* user_data)
02046 {
02047 LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SHIRT);
02048 }
02049
02050 void LLFolderBridge::createNewPants(void* user_data)
02051 {
02052 LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_PANTS);
02053 }
02054
02055 void LLFolderBridge::createNewShoes(void* user_data)
02056 {
02057 LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SHOES);
02058 }
02059
02060 void LLFolderBridge::createNewSocks(void* user_data)
02061 {
02062 LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SOCKS);
02063 }
02064
02065 void LLFolderBridge::createNewJacket(void* user_data)
02066 {
02067 LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_JACKET);
02068 }
02069
02070 void LLFolderBridge::createNewSkirt(void* user_data)
02071 {
02072 LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SKIRT);
02073 }
02074
02075 void LLFolderBridge::createNewGloves(void* user_data)
02076 {
02077 LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_GLOVES);
02078 }
02079
02080 void LLFolderBridge::createNewUndershirt(void* user_data)
02081 {
02082 LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_UNDERSHIRT);
02083 }
02084
02085 void LLFolderBridge::createNewUnderpants(void* user_data)
02086 {
02087 LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_UNDERPANTS);
02088 }
02089
02090 void LLFolderBridge::createNewShape(void* user_data)
02091 {
02092 LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SHAPE);
02093 }
02094
02095 void LLFolderBridge::createNewSkin(void* user_data)
02096 {
02097 LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SKIN);
02098 }
02099
02100 void LLFolderBridge::createNewHair(void* user_data)
02101 {
02102 LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_HAIR);
02103 }
02104
02105 void LLFolderBridge::createNewEyes(void* user_data)
02106 {
02107 LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_EYES);
02108 }
02109
02110
02111 void LLFolderBridge::createWearable(LLFolderBridge* bridge, EWearableType type)
02112 {
02113 if(!bridge) return;
02114 LLUUID parent_id = bridge->getUUID();
02115 createWearable(parent_id, type);
02116 }
02117
02118
02119
02120
02121 void LLFolderBridge::createWearable(LLUUID parent_id, EWearableType type)
02122 {
02123 LLWearable* wearable = gWearableList.createNewWearable(type);
02124 LLAssetType::EType asset_type = wearable->getAssetType();
02125 LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;
02126 create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
02127 parent_id, wearable->getTransactionID(), wearable->getName(),
02128 wearable->getDescription(), asset_type, inv_type, wearable->getType(),
02129 wearable->getPermissions().getMaskNextOwner(),
02130 LLPointer<LLInventoryCallback>(NULL));
02131 }
02132
02133 void LLFolderBridge::modifyOutfit(BOOL append)
02134 {
02135 LLInventoryModel* model = mInventoryPanel->getModel();
02136 if(!model) return;
02137 LLViewerInventoryCategory* cat = getCategory();
02138 if(!cat) return;
02139
02140 wear_inventory_category_on_avatar( cat, append );
02141 }
02142
02143
02144 void move_task_inventory_callback(S32 option, void* user_data)
02145 {
02146 LLMoveInv* move_inv = (LLMoveInv*)user_data;
02147 LLFloaterOpenObject::LLCatAndWear* cat_and_wear = (LLFloaterOpenObject::LLCatAndWear* )move_inv->mUserData;
02148 LLViewerObject* object = gObjectList.findObject(move_inv->mObjectID);
02149
02150 if(option == 0 && object)
02151 {
02152 if (cat_and_wear && cat_and_wear->mWear)
02153 {
02154 InventoryObjectList inventory_objects;
02155 object->getInventoryContents(inventory_objects);
02156 int contents_count = inventory_objects.size()-1;
02157
02158 LLInventoryCopyAndWearObserver* inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count);
02159 gInventory.addObserver(inventoryObserver);
02160 }
02161
02162 two_uuids_list_t::iterator move_it;
02163 for (move_it = move_inv->mMoveList.begin();
02164 move_it != move_inv->mMoveList.end();
02165 ++move_it)
02166 {
02167 object->moveInventory(move_it->first, move_it->second);
02168 }
02169
02170
02171 dialog_refresh_all();
02172 }
02173
02174 if (move_inv->mCallback)
02175 {
02176 move_inv->mCallback(option, move_inv->mUserData);
02177 }
02178
02179 delete move_inv;
02180 }
02181
02182 BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
02183 BOOL drop)
02184 {
02185 LLInventoryModel* model = mInventoryPanel->getModel();
02186 if(!model) return FALSE;
02187
02188
02189 if(!isAgentInventory())
02190 {
02191 return FALSE;
02192 }
02193
02194 LLVOAvatar* avatar = gAgent.getAvatarObject();
02195 if(!avatar) return FALSE;
02196
02197 LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource();
02198 BOOL accept = FALSE;
02199 LLViewerObject* object = NULL;
02200 if(LLToolDragAndDrop::SOURCE_AGENT == source)
02201 {
02202
02203 BOOL is_movable = TRUE;
02204 switch( inv_item->getType() )
02205 {
02206 case LLAssetType::AT_ROOT_CATEGORY:
02207 is_movable = FALSE;
02208 break;
02209
02210 case LLAssetType::AT_CATEGORY:
02211 is_movable = ( LLAssetType::AT_NONE == ((LLInventoryCategory*)inv_item)->getPreferredType() );
02212 break;
02213 default:
02214 break;
02215 }
02216
02217 LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
02218 BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id);
02219 if(is_movable && move_is_into_trash)
02220 {
02221 switch(inv_item->getType())
02222 {
02223 case LLAssetType::AT_CLOTHING:
02224 case LLAssetType::AT_BODYPART:
02225 is_movable = !gAgent.isWearingItem(inv_item->getUUID());
02226 break;
02227
02228 case LLAssetType::AT_OBJECT:
02229 is_movable = !avatar->isWearingAttachment(inv_item->getUUID());
02230 break;
02231 default:
02232 break;
02233 }
02234 }
02235
02236 accept = is_movable && (mUUID != inv_item->getParentUUID());
02237 if(accept && drop)
02238 {
02239 if (inv_item->getType() == LLAssetType::AT_GESTURE
02240 && gGestureManager.isGestureActive(inv_item->getUUID()))
02241 {
02242 gGestureManager.deactivateGesture(inv_item->getUUID());
02243 }
02244
02245
02246
02247
02248 if (LLInventoryView::getActiveInventory())
02249 {
02250 LLInventoryPanel* active_panel = LLInventoryView::getActiveInventory()->getPanel();
02251 if (active_panel && (mInventoryPanel != active_panel))
02252 {
02253 active_panel->unSelectAll();
02254 }
02255 }
02256
02257
02258 LLInvFVBridge::changeItemParent(
02259 model,
02260 (LLViewerInventoryItem*)inv_item,
02261 mUUID,
02262 move_is_into_trash);
02263 }
02264 }
02265 else if(LLToolDragAndDrop::SOURCE_WORLD == source)
02266 {
02267
02268
02269
02270 object = gObjectList.findObject(inv_item->getParentUUID());
02271 if(!object)
02272 {
02273 llinfos << "Object not found for drop." << llendl;
02274 return FALSE;
02275 }
02276
02277
02278
02279 LLPermissions perm(inv_item->getPermissions());
02280 BOOL is_move = FALSE;
02281 if((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID())
02282 && perm.allowTransferTo(gAgent.getID())))
02283
02284
02285 {
02286 accept = TRUE;
02287 }
02288 else if(object->permYouOwner())
02289 {
02290
02291
02292
02293 is_move = TRUE;
02294 accept = TRUE;
02295 }
02296 if(drop && accept)
02297 {
02298 LLMoveInv* move_inv = new LLMoveInv;
02299 move_inv->mObjectID = inv_item->getParentUUID();
02300 two_uuids_t item_pair(mUUID, inv_item->getUUID());
02301 move_inv->mMoveList.push_back(item_pair);
02302 move_inv->mCallback = NULL;
02303 move_inv->mUserData = NULL;
02304 if(is_move)
02305 {
02306 warn_move_inventory(object, move_inv);
02307 }
02308 else
02309 {
02310 move_task_inventory_callback(0, (void*)(move_inv));
02311 }
02312 }
02313
02314 }
02315 else if(LLToolDragAndDrop::SOURCE_NOTECARD == source)
02316 {
02317 accept = TRUE;
02318 if(drop)
02319 {
02320 copy_inventory_from_notecard(LLToolDragAndDrop::getInstance()->getObjectID(),
02321 LLToolDragAndDrop::getInstance()->getSourceID(), inv_item);
02322 }
02323 }
02324 else if(LLToolDragAndDrop::SOURCE_LIBRARY == source)
02325 {
02326 LLViewerInventoryItem* item = (LLViewerInventoryItem*)inv_item;
02327 if(item && item->isComplete())
02328 {
02329 accept = TRUE;
02330 if(drop)
02331 {
02332 copy_inventory_item(
02333 gAgent.getID(),
02334 inv_item->getPermissions().getOwner(),
02335 inv_item->getUUID(),
02336 mUUID,
02337 std::string(),
02338 LLPointer<LLInventoryCallback>(NULL));
02339 }
02340 }
02341 }
02342 else
02343 {
02344 llwarns << "unhandled drag source" << llendl;
02345 }
02346 return accept;
02347 }
02348
02349
02350
02351
02352
02353 LLUIImagePtr LLScriptBridge::getIcon() const
02354 {
02355 return get_item_icon(LLAssetType::AT_SCRIPT, LLInventoryType::IT_LSL, 0, FALSE);
02356 }
02357
02358
02359
02360
02361
02362 LLString LLTextureBridge::sPrefix("Texture: ");
02363
02364
02365 LLUIImagePtr LLTextureBridge::getIcon() const
02366 {
02367 return get_item_icon(LLAssetType::AT_TEXTURE, mInvType, 0, FALSE);
02368 }
02369
02370 void open_texture(const LLUUID& item_id,
02371 const LLString& title,
02372 BOOL show_keep_discard,
02373 const LLUUID& source_id,
02374 BOOL take_focus)
02375 {
02376
02377 if( !LLPreview::show( item_id, take_focus ) )
02378 {
02379
02380 S32 left, top;
02381 gFloaterView->getNewFloaterPosition(&left, &top);
02382 LLRect rect = gSavedSettings.getRect("PreviewTextureRect");
02383 rect.translate( left - rect.mLeft, top - rect.mTop );
02384
02385 LLPreviewTexture* preview;
02386 preview = new LLPreviewTexture("preview texture",
02387 rect,
02388 title,
02389 item_id,
02390 LLUUID::null,
02391 show_keep_discard);
02392 preview->setSourceID(source_id);
02393 if(take_focus) preview->setFocus(TRUE);
02394
02395 gFloaterView->adjustToFitScreen(preview, FALSE);
02396 }
02397 }
02398
02399 void LLTextureBridge::openItem()
02400 {
02401 LLViewerInventoryItem* item = getItem();
02402 if(item)
02403 {
02404 open_texture(mUUID, getPrefix() + item->getName(), FALSE);
02405 }
02406 }
02407
02408
02409
02410
02411
02412 LLString LLSoundBridge::sPrefix("Sound: ");
02413
02414
02415 LLUIImagePtr LLSoundBridge::getIcon() const
02416 {
02417 return get_item_icon(LLAssetType::AT_SOUND, LLInventoryType::IT_SOUND, 0, FALSE);
02418 }
02419
02420 void LLSoundBridge::openItem()
02421 {
02422
02423
02424
02425
02426 LLViewerInventoryItem* item = getItem();
02427 if(item)
02428 {
02429 openSoundPreview((void*)this);
02430
02431 }
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444 }
02445
02446 void LLSoundBridge::previewItem()
02447 {
02448 LLViewerInventoryItem* item = getItem();
02449 if(item)
02450 {
02451 send_sound_trigger(item->getAssetUUID(), 1.0);
02452 }
02453 }
02454
02455 void LLSoundBridge::openSoundPreview(void* which)
02456 {
02457 LLSoundBridge *me = (LLSoundBridge *)which;
02458 if(!LLPreview::show(me->mUUID))
02459 {
02460 S32 left, top;
02461 gFloaterView->getNewFloaterPosition(&left, &top);
02462 LLRect rect = gSavedSettings.getRect("PreviewSoundRect");
02463 rect.translate(left - rect.mLeft, top - rect.mTop);
02464 LLPreviewSound* preview = new LLPreviewSound("preview sound",
02465 rect,
02466 me->getPrefix() + me->getName(),
02467 me->mUUID);
02468 preview->setFocus(TRUE);
02469
02470 gFloaterView->adjustToFitScreen(preview, FALSE);
02471 }
02472 }
02473
02474 void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
02475 {
02476 lldebugs << "LLTextureBridge::buildContextMenu()" << llendl;
02477 std::vector<LLString> items;
02478 std::vector<LLString> disabled_items;
02479
02480 if(isInTrash())
02481 {
02482 items.push_back("Purge Item");
02483 if (!isItemRemovable())
02484 {
02485 disabled_items.push_back("Purge Item");
02486 }
02487
02488 items.push_back("Restore Item");
02489 }
02490 else
02491 {
02492 items.push_back("Sound Open");
02493 items.push_back("Properties");
02494
02495 getClipboardEntries(true, items, disabled_items, flags);
02496 }
02497
02498 items.push_back("Sound Separator");
02499 items.push_back("Sound Play");
02500
02501 hideContextEntries(menu, items, disabled_items);
02502 }
02503
02504
02505
02506
02507
02508 LLString LLLandmarkBridge::sPrefix("Landmark: ");
02509
02510 LLUIImagePtr LLLandmarkBridge::getIcon() const
02511 {
02512 return get_item_icon(LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, mVisited, FALSE);
02513 }
02514
02515 void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
02516 {
02517 std::vector<LLString> items;
02518 std::vector<LLString> disabled_items;
02519
02520 lldebugs << "LLLandmarkBridge::buildContextMenu()" << llendl;
02521 if(isInTrash())
02522 {
02523 items.push_back("Purge Item");
02524 if (!isItemRemovable())
02525 {
02526 disabled_items.push_back("Purge Item");
02527 }
02528
02529 items.push_back("Restore Item");
02530 }
02531 else
02532 {
02533 items.push_back("Landmark Open");
02534 items.push_back("Properties");
02535
02536 getClipboardEntries(true, items, disabled_items, flags);
02537 }
02538
02539 items.push_back("Landmark Separator");
02540 items.push_back("Teleport To Landmark");
02541
02542 hideContextEntries(menu, items, disabled_items);
02543
02544 }
02545
02546
02547 void LLLandmarkBridge::performAction(LLFolderView* folder, LLInventoryModel* model, LLString action)
02548 {
02549 if ("teleport" == action)
02550 {
02551 LLViewerInventoryItem* item = getItem();
02552 if(item)
02553 {
02554 gAgent.teleportViaLandmark(item->getAssetUUID());
02555
02556
02557
02558 if( gFloaterWorldMap )
02559 {
02560 gFloaterWorldMap->trackLandmark( item->getAssetUUID() );
02561 }
02562 }
02563 }
02564 if ("about" == action)
02565 {
02566 LLViewerInventoryItem* item = getItem();
02567 if(item)
02568 {
02569 open_landmark(item, LLString(" ") + getPrefix() + item->getName(), FALSE);
02570 }
02571 }
02572 else LLItemBridge::performAction(folder, model, action);
02573 }
02574
02575 void open_landmark(LLViewerInventoryItem* inv_item,
02576 const LLString& title,
02577 BOOL show_keep_discard,
02578 const LLUUID& source_id,
02579 BOOL take_focus)
02580 {
02581
02582 if( !LLPreview::show( inv_item->getUUID(), take_focus ) )
02583 {
02584
02585 S32 left, top;
02586 gFloaterView->getNewFloaterPosition(&left, &top);
02587 LLRect rect = gSavedSettings.getRect("PreviewLandmarkRect");
02588 rect.translate( left - rect.mLeft, top - rect.mTop );
02589
02590 LLPreviewLandmark* preview = new LLPreviewLandmark(title,
02591 rect,
02592 title,
02593 inv_item->getUUID(),
02594 show_keep_discard,
02595 inv_item);
02596 preview->setSourceID(source_id);
02597 if(take_focus) preview->setFocus(TRUE);
02598
02599 gFloaterView->adjustToFitScreen(preview, FALSE);
02600 }
02601 }
02602
02603 static void open_landmark_callback(S32 option, void* data)
02604 {
02605 LLUUID* asset_idp = (LLUUID*)data;
02606 if (option == 0)
02607 {
02608
02609 gAgent.teleportViaLandmark( *asset_idp );
02610
02611
02612
02613 if( gFloaterWorldMap )
02614 {
02615 gFloaterWorldMap->trackLandmark( *asset_idp );
02616 }
02617 }
02618 delete asset_idp;
02619 }
02620
02621 void LLLandmarkBridge::openItem()
02622 {
02623 LLViewerInventoryItem* item = getItem();
02624 if( item )
02625 {
02626
02627
02628
02629 LLUUID* asset_idp = new LLUUID(item->getAssetUUID());
02630 LLAlertDialog::showXml("TeleportFromLandmark",
02631 open_landmark_callback, (void*)asset_idp);
02632 }
02633 }
02634
02635
02636
02637
02638
02639 void LLCallingCardObserver::changed(U32 mask)
02640 {
02641 mBridgep->refreshFolderViewItem();
02642 }
02643
02644
02645
02646
02647
02648 LLString LLCallingCardBridge::sPrefix("Calling Card: ");
02649
02650 LLCallingCardBridge::LLCallingCardBridge( LLInventoryPanel* inventory, const LLUUID& uuid ) :
02651 LLItemBridge(inventory, uuid)
02652 {
02653 mObserver = new LLCallingCardObserver(this);
02654 LLAvatarTracker::instance().addObserver(mObserver);
02655 }
02656
02657 LLCallingCardBridge::~LLCallingCardBridge()
02658 {
02659 LLAvatarTracker::instance().removeObserver(mObserver);
02660 delete mObserver;
02661 }
02662
02663 void LLCallingCardBridge::refreshFolderViewItem()
02664 {
02665 LLFolderViewItem* itemp = mInventoryPanel->getRootFolder()->getItemByID(mUUID);
02666 if (itemp)
02667 {
02668 itemp->refresh();
02669 }
02670 }
02671
02672
02673 void LLCallingCardBridge::performAction(LLFolderView* folder, LLInventoryModel* model, LLString action)
02674 {
02675 if ("begin_im" == action)
02676 {
02677 LLViewerInventoryItem *item = getItem();
02678 if (item && (item->getCreatorUUID() != gAgent.getID()) &&
02679 (!item->getCreatorUUID().isNull()))
02680 {
02681 gIMMgr->setFloaterOpen(TRUE);
02682 gIMMgr->addSession(item->getName(), IM_NOTHING_SPECIAL, item->getCreatorUUID());
02683 }
02684 }
02685 else if ("lure" == action)
02686 {
02687 LLViewerInventoryItem *item = getItem();
02688 if (item && (item->getCreatorUUID() != gAgent.getID()) &&
02689 (!item->getCreatorUUID().isNull()))
02690 {
02691 handle_lure(item->getCreatorUUID());
02692 }
02693 }
02694 else LLItemBridge::performAction(folder, model, action);
02695 }
02696
02697 LLUIImagePtr LLCallingCardBridge::getIcon() const
02698 {
02699 BOOL online = FALSE;
02700 LLViewerInventoryItem* item = getItem();
02701 if(item)
02702 {
02703 online = LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID());
02704 }
02705 return get_item_icon(LLAssetType::AT_CALLINGCARD, LLInventoryType::IT_CALLINGCARD, online, FALSE);
02706 }
02707
02708 LLString LLCallingCardBridge::getLabelSuffix() const
02709 {
02710 LLViewerInventoryItem* item = getItem();
02711 if( item && LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID()) )
02712 {
02713 return LLItemBridge::getLabelSuffix() + " (online)";
02714 }
02715 else
02716 {
02717 return LLItemBridge::getLabelSuffix();
02718 }
02719 }
02720
02721 void LLCallingCardBridge::openItem()
02722 {
02723 LLViewerInventoryItem* item = getItem();
02724 if(item && !item->getCreatorUUID().isNull())
02725 {
02726 BOOL online;
02727 online = LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID());
02728 LLFloaterAvatarInfo::showFromFriend(item->getCreatorUUID(), online);
02729 }
02730 }
02731
02732 void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
02733 {
02734 lldebugs << "LLCallingCardBridge::buildContextMenu()" << llendl;
02735 std::vector<LLString> items;
02736 std::vector<LLString> disabled_items;
02737
02738 if(isInTrash())
02739 {
02740 items.push_back("Purge Item");
02741 if (!isItemRemovable())
02742 {
02743 disabled_items.push_back("Purge Item");
02744 }
02745
02746 items.push_back("Restore Item");
02747 }
02748 else
02749 {
02750 items.push_back("Open");
02751 items.push_back("Properties");
02752
02753 getClipboardEntries(true, items, disabled_items, flags);
02754
02755 LLInventoryItem* item = getItem();
02756 BOOL good_card = (item
02757 && (LLUUID::null != item->getCreatorUUID())
02758 && (item->getCreatorUUID() != gAgent.getID()));
02759 BOOL user_online = (LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID()));
02760 items.push_back("Send Instant Message Separator");
02761 items.push_back("Send Instant Message");
02762 items.push_back("Offer Teleport...");
02763 items.push_back("Conference Chat");
02764
02765 if (!good_card)
02766 {
02767 disabled_items.push_back("Send Instant Message");
02768 }
02769 if (!good_card || !user_online)
02770 {
02771 disabled_items.push_back("Offer Teleport...");
02772 disabled_items.push_back("Conference Chat");
02773 }
02774 }
02775 hideContextEntries(menu, items, disabled_items);
02776 }
02777
02778 BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,
02779 EDragAndDropType cargo_type,
02780 void* cargo_data)
02781 {
02782 LLViewerInventoryItem* item = getItem();
02783 BOOL rv = FALSE;
02784 if(item)
02785 {
02786
02787 switch(cargo_type)
02788 {
02789 case DAD_TEXTURE:
02790 case DAD_SOUND:
02791 case DAD_LANDMARK:
02792 case DAD_SCRIPT:
02793 case DAD_CLOTHING:
02794 case DAD_OBJECT:
02795 case DAD_NOTECARD:
02796 case DAD_BODYPART:
02797 case DAD_ANIMATION:
02798 case DAD_GESTURE:
02799 {
02800 LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
02801 const LLPermissions& perm = inv_item->getPermissions();
02802 if(gInventory.getItem(inv_item->getUUID())
02803 && perm.allowOperationBy(PERM_TRANSFER, gAgent.getID()))
02804 {
02805 rv = TRUE;
02806 if(drop)
02807 {
02808 LLToolDragAndDrop::giveInventory(item->getCreatorUUID(),
02809 (LLInventoryItem*)cargo_data);
02810 }
02811 }
02812 else
02813 {
02814
02815
02816
02817 rv = FALSE;
02818 }
02819 break;
02820 }
02821 case DAD_CATEGORY:
02822 {
02823 LLInventoryCategory* inv_cat = (LLInventoryCategory*)cargo_data;
02824 if( gInventory.getCategory( inv_cat->getUUID() ) )
02825 {
02826 rv = TRUE;
02827 if(drop)
02828 {
02829 LLToolDragAndDrop::giveInventoryCategory(
02830 item->getCreatorUUID(),
02831 inv_cat);
02832 }
02833 }
02834 else
02835 {
02836
02837
02838
02839 rv = FALSE;
02840 }
02841 break;
02842 }
02843 default:
02844 break;
02845 }
02846 }
02847 return rv;
02848 }
02849
02850
02851
02852
02853
02854 LLString LLNotecardBridge::sPrefix("Note: ");
02855
02856
02857 LLUIImagePtr LLNotecardBridge::getIcon() const
02858 {
02859 return get_item_icon(LLAssetType::AT_NOTECARD, LLInventoryType::IT_NOTECARD, 0, FALSE);
02860 }
02861
02862 void open_notecard(LLViewerInventoryItem* inv_item,
02863 const LLString& title,
02864 const LLUUID& object_id,
02865 BOOL show_keep_discard,
02866 const LLUUID& source_id,
02867 BOOL take_focus)
02868 {
02869
02870 if(!LLPreview::show(inv_item->getUUID(), take_focus))
02871 {
02872
02873 S32 left, top;
02874 gFloaterView->getNewFloaterPosition(&left, &top);
02875 LLRect rect = gSavedSettings.getRect("NotecardEditorRect");
02876 rect.translate(left - rect.mLeft, top - rect.mTop);
02877 LLPreviewNotecard* preview;
02878 preview = new LLPreviewNotecard("preview notecard", rect, title,
02879 inv_item->getUUID(), object_id, inv_item->getAssetUUID(),
02880 show_keep_discard, inv_item);
02881 preview->setSourceID(source_id);
02882 if(take_focus) preview->setFocus(TRUE);
02883
02884 gFloaterView->adjustToFitScreen(preview, FALSE);
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905 }
02906 }
02907
02908
02909 void LLNotecardBridge::openItem()
02910 {
02911 LLViewerInventoryItem* item = getItem();
02912 if (item)
02913 {
02914 open_notecard(item, getPrefix() + item->getName(), LLUUID::null, FALSE);
02915 }
02916 }
02917
02918
02919
02920
02921
02922
02923 LLString LLGestureBridge::sPrefix("Gesture: ");
02924
02925 LLUIImagePtr LLGestureBridge::getIcon() const
02926 {
02927 return get_item_icon(LLAssetType::AT_GESTURE, LLInventoryType::IT_GESTURE, 0, FALSE);
02928 }
02929
02930 LLFontGL::StyleFlags LLGestureBridge::getLabelStyle() const
02931 {
02932 if( gGestureManager.isGestureActive(mUUID) )
02933 {
02934 return LLFontGL::BOLD;
02935 }
02936 else
02937 {
02938 return LLFontGL::NORMAL;
02939 }
02940 }
02941
02942 LLString LLGestureBridge::getLabelSuffix() const
02943 {
02944 if( gGestureManager.isGestureActive(mUUID) )
02945 {
02946 return LLItemBridge::getLabelSuffix() + " (active)";
02947 }
02948 else
02949 {
02950 return LLItemBridge::getLabelSuffix();
02951 }
02952 }
02953
02954
02955 void LLGestureBridge::performAction(LLFolderView* folder, LLInventoryModel* model, LLString action)
02956 {
02957 if ("activate" == action)
02958 {
02959 gGestureManager.activateGesture(mUUID);
02960
02961 LLViewerInventoryItem* item = gInventory.getItem(mUUID);
02962 if (!item) return;
02963
02964
02965
02966 gInventory.updateItem(item);
02967 gInventory.notifyObservers();
02968 }
02969 else if ("deactivate" == action)
02970 {
02971 gGestureManager.deactivateGesture(mUUID);
02972
02973 LLViewerInventoryItem* item = gInventory.getItem(mUUID);
02974 if (!item) return;
02975
02976
02977
02978 gInventory.updateItem(item);
02979 gInventory.notifyObservers();
02980 }
02981 else LLItemBridge::performAction(folder, model, action);
02982 }
02983
02984 void LLGestureBridge::openItem()
02985 {
02986 LLViewerInventoryItem* item = getItem();
02987 if (!item) return;
02988
02989
02990 if(!LLPreview::show(mUUID))
02991 {
02992 LLUUID item_id = mUUID;
02993 LLString title = getPrefix() + item->getName();
02994 LLUUID object_id = LLUUID::null;
02995
02996
02997 LLPreviewGesture* preview = LLPreviewGesture::show(title, item_id, object_id);
02998 preview->setFocus(TRUE);
02999
03000
03001 gFloaterView->adjustToFitScreen(preview, FALSE);
03002 }
03003 }
03004
03005 BOOL LLGestureBridge::removeItem()
03006 {
03007
03008 gGestureManager.deactivateGesture(mUUID);
03009 return LLItemBridge::removeItem();
03010 }
03011
03012 void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
03013 {
03014 lldebugs << "LLGestureBridge::buildContextMenu()" << llendl;
03015 std::vector<LLString> items;
03016 std::vector<LLString> disabled_items;
03017 if(isInTrash())
03018 {
03019 items.push_back("Purge Item");
03020 if (!isItemRemovable())
03021 {
03022 disabled_items.push_back("Purge Item");
03023 }
03024
03025 items.push_back("Restore Item");
03026 }
03027 else
03028 {
03029 items.push_back("Open");
03030 items.push_back("Properties");
03031
03032 getClipboardEntries(true, items, disabled_items, flags);
03033
03034 items.push_back("Gesture Separator");
03035 items.push_back("Activate");
03036 items.push_back("Deactivate");
03037
03038
03039
03040
03041
03042
03043
03044
03045
03046 }
03047 hideContextEntries(menu, items, disabled_items);
03048 }
03049
03050
03051
03052
03053
03054 LLString LLAnimationBridge::sPrefix("Animation: ");
03055
03056
03057 LLUIImagePtr LLAnimationBridge::getIcon() const
03058 {
03059 return get_item_icon(LLAssetType::AT_ANIMATION, LLInventoryType::IT_ANIMATION, 0, FALSE);
03060 }
03061
03062 void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
03063 {
03064 std::vector<LLString> items;
03065 std::vector<LLString> disabled_items;
03066
03067 lldebugs << "LLAnimationBridge::buildContextMenu()" << llendl;
03068 if(isInTrash())
03069 {
03070 items.push_back("Purge Item");
03071 if (!isItemRemovable())
03072 {
03073 disabled_items.push_back("Purge Item");
03074 }
03075
03076 items.push_back("Restore Item");
03077 }
03078 else
03079 {
03080 items.push_back("Animation Open");
03081 items.push_back("Properties");
03082
03083 getClipboardEntries(true, items, disabled_items, flags);
03084 }
03085
03086 items.push_back("Animation Separator");
03087 items.push_back("Animation Play");
03088 items.push_back("Animation Audition");
03089
03090 hideContextEntries(menu, items, disabled_items);
03091
03092 }
03093
03094
03095 void LLAnimationBridge::performAction(LLFolderView* folder, LLInventoryModel* model, LLString action)
03096 {
03097 S32 activate = 0;
03098
03099 if ((action == "playworld") || (action == "playlocal"))
03100 {
03101
03102 if ("playworld" == action) activate = 1;
03103 if ("playlocal" == action) activate = 2;
03104
03105
03106 if( !LLPreview::show( mUUID ) )
03107 {
03108
03109 LLViewerInventoryItem* item = getItem();
03110 if( item )
03111 {
03112 S32 left, top;
03113 gFloaterView->getNewFloaterPosition(&left, &top);
03114 LLRect rect = gSavedSettings.getRect("PreviewAnimRect");
03115 rect.translate( left - rect.mLeft, top - rect.mTop );
03116 LLPreviewAnim* preview = new LLPreviewAnim("preview anim",
03117 rect,
03118 getPrefix() + item->getName(),
03119 mUUID,
03120 activate);
03121
03122 gFloaterView->adjustToFitScreen(preview, FALSE);
03123 }
03124 }
03125 }
03126 else
03127 {
03128 LLItemBridge::performAction(folder, model, action);
03129 }
03130 }
03131
03132 void LLAnimationBridge::openItem()
03133 {
03134
03135 if( !LLPreview::show( mUUID ) )
03136 {
03137
03138 LLViewerInventoryItem* item = getItem();
03139 if( item )
03140 {
03141 S32 left, top;
03142 gFloaterView->getNewFloaterPosition(&left, &top);
03143 LLRect rect = gSavedSettings.getRect("PreviewAnimRect");
03144 rect.translate( left - rect.mLeft, top - rect.mTop );
03145 LLPreviewAnim* preview = new LLPreviewAnim("preview anim",
03146 rect,
03147 getPrefix() + item->getName(),
03148 mUUID,
03149 0);
03150 preview->setFocus(TRUE);
03151
03152 gFloaterView->adjustToFitScreen(preview, FALSE);
03153 }
03154 }
03155 }
03156
03157
03158
03159
03160
03161
03162 LLString LLObjectBridge::sPrefix("Object: ");
03163
03164
03165 LLUUID LLObjectBridge::sContextMenuItemID;
03166
03167 BOOL LLObjectBridge::isItemRemovable()
03168 {
03169 LLVOAvatar* avatar = gAgent.getAvatarObject();
03170 if(!avatar) return FALSE;
03171 if(avatar->isWearingAttachment(mUUID)) return FALSE;
03172 return LLInvFVBridge::isItemRemovable();
03173 }
03174
03175 LLUIImagePtr LLObjectBridge::getIcon() const
03176 {
03177 return get_item_icon(LLAssetType::AT_OBJECT, mInvType, mAttachPt, mIsMultiObject );
03178 }
03179
03180 void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment);
03181
03182
03183 void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model, LLString action)
03184 {
03185 if ("attach" == action)
03186 {
03187 LLUUID object_id = mUUID;
03188 LLViewerInventoryItem* item;
03189 item = (LLViewerInventoryItem*)gInventory.getItem(object_id);
03190 if(item && gInventory.isObjectDescendentOf(object_id, gAgent.getInventoryRootID()))
03191 {
03192 rez_attachment(item, NULL);
03193 }
03194 else if(item && item->isComplete())
03195 {
03196
03197 LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0);
03198 copy_inventory_item(
03199 gAgent.getID(),
03200 item->getPermissions().getOwner(),
03201 item->getUUID(),
03202 LLUUID::null,
03203 std::string(),
03204 cb);
03205 }
03206 gFocusMgr.setKeyboardFocus(NULL);
03207 }
03208 else if ("detach" == action)
03209 {
03210 LLInventoryItem* item = gInventory.getItem(mUUID);
03211 if( item )
03212 {
03213 gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
03214 gMessageSystem->nextBlockFast(_PREHASH_ObjectData );
03215 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
03216 gMessageSystem->addUUIDFast(_PREHASH_ItemID, item->getUUID() );
03217
03218 gMessageSystem->sendReliable( gAgent.getRegion()->getHost() );
03219 }
03220
03221 LLViewerObject *found_obj =
03222 gObjectList.findObject(item->getUUID());
03223 if (found_obj)
03224 {
03225 LLSelectMgr::getInstance()->remove(found_obj);
03226 }
03227 else
03228 {
03229 llwarns << "object not found - ignoring" << llendl;
03230 }
03231 }
03232 else LLItemBridge::performAction(folder, model, action);
03233 }
03234
03235 void LLObjectBridge::openItem()
03236 {
03237
03238
03239
03240 LLShowProps::showProperties(mUUID);
03241 }
03242
03243 LLFontGL::StyleFlags LLObjectBridge::getLabelStyle() const
03244 {
03245 LLVOAvatar* avatar = gAgent.getAvatarObject();
03246 if( avatar && avatar->isWearingAttachment( mUUID ) )
03247 {
03248 return LLFontGL::BOLD;
03249 }
03250 else
03251 {
03252 return LLFontGL::NORMAL;
03253 }
03254 }
03255
03256 LLString LLObjectBridge::getLabelSuffix() const
03257 {
03258 LLVOAvatar* avatar = gAgent.getAvatarObject();
03259 if( avatar && avatar->isWearingAttachment( mUUID ) )
03260 {
03261 LLString attachment_point_name = avatar->getAttachedPointName(mUUID);
03262 LLString::toLower(attachment_point_name);
03263 return LLItemBridge::getLabelSuffix() + LLString(" (worn on ") + attachment_point_name + LLString(")");
03264 }
03265 else
03266 {
03267 return LLItemBridge::getLabelSuffix();
03268 }
03269 }
03270
03271 void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment)
03272 {
03273 LLAttachmentRezAction* rez_action = new LLAttachmentRezAction;
03274 rez_action->mItemID = item->getUUID();
03275 S32 attach_pt = 0;
03276 if (gAgent.getAvatarObject() && attachment)
03277 {
03278 for (LLVOAvatar::attachment_map_t::iterator iter = gAgent.getAvatarObject()->mAttachmentPoints.begin();
03279 iter != gAgent.getAvatarObject()->mAttachmentPoints.end(); ++iter)
03280 {
03281 if (iter->second == attachment)
03282 {
03283 attach_pt = iter->first;
03284 break;
03285 }
03286 }
03287 }
03288 rez_action->mAttachPt = attach_pt;
03289 if (attachment && attachment->getObject())
03290 {
03291 gViewerWindow->alertXml("ReplaceAttachment", confirm_replace_attachment_rez, (void*)rez_action);
03292 }
03293 else
03294 {
03295 confirm_replace_attachment_rez(0, (void*)rez_action);
03296 }
03297 }
03298
03299 void confirm_replace_attachment_rez(S32 option, void* user_data)
03300 {
03301 LLAttachmentRezAction* rez_action = (LLAttachmentRezAction*)user_data;
03302 if (option == 0)
03303 {
03304 if (rez_action)
03305 {
03306 LLViewerInventoryItem* itemp = gInventory.getItem(rez_action->mItemID);
03307
03308 if (itemp)
03309 {
03310 LLMessageSystem* msg = gMessageSystem;
03311 msg->newMessageFast(_PREHASH_RezSingleAttachmentFromInv);
03312 msg->nextBlockFast(_PREHASH_AgentData);
03313 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
03314 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03315 msg->nextBlockFast(_PREHASH_ObjectData);
03316 msg->addUUIDFast(_PREHASH_ItemID, itemp->getUUID());
03317 msg->addUUIDFast(_PREHASH_OwnerID, itemp->getPermissions().getOwner());
03318 msg->addU8Fast(_PREHASH_AttachmentPt, rez_action->mAttachPt);
03319 pack_permissions_slam(msg, itemp->getFlags(), itemp->getPermissions());
03320 msg->addStringFast(_PREHASH_Name, itemp->getName());
03321 msg->addStringFast(_PREHASH_Description, itemp->getDescription());
03322 msg->sendReliable(gAgent.getRegion()->getHost());
03323 }
03324 }
03325 }
03326 delete rez_action;
03327 }
03328
03329 void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
03330 {
03331 std::vector<LLString> items;
03332 std::vector<LLString> disabled_items;
03333 if(isInTrash())
03334 {
03335 items.push_back("Purge Item");
03336 if (!isItemRemovable())
03337 {
03338 disabled_items.push_back("Purge Item");
03339 }
03340
03341 items.push_back("Restore Item");
03342 }
03343 else
03344 {
03345 items.push_back("Properties");
03346
03347 getClipboardEntries(true, items, disabled_items, flags);
03348
03349 LLObjectBridge::sContextMenuItemID = mUUID;
03350
03351 LLInventoryItem* item = getItem();
03352 if(item)
03353 {
03354 LLVOAvatar *avatarp = gAgent.getAvatarObject();
03355 if( !avatarp )
03356 {
03357 return;
03358 }
03359
03360 if( avatarp->isWearingAttachment( mUUID ) )
03361 {
03362 items.push_back("Detach From Yourself");
03363 }
03364 else
03365 if( !isInTrash() )
03366 {
03367 items.push_back("Attach Separator");
03368 items.push_back("Object Wear");
03369 items.push_back("Attach To");
03370 items.push_back("Attach To HUD");
03371
03372 LLMenuGL* attach_menu = menu.getChildMenuByName("Attach To", TRUE);
03373 LLMenuGL* attach_hud_menu = menu.getChildMenuByName("Attach To HUD", TRUE);
03374 LLVOAvatar *avatarp = gAgent.getAvatarObject();
03375 if (attach_menu && (attach_menu->getChildCount() == 0) &&
03376 attach_hud_menu && (attach_hud_menu->getChildCount() == 0) &&
03377 avatarp)
03378 {
03379 for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
03380 iter != avatarp->mAttachmentPoints.end(); )
03381 {
03382 LLVOAvatar::attachment_map_t::iterator curiter = iter++;
03383 LLViewerJointAttachment* attachment = curiter->second;
03384 LLMenuItemCallGL *new_item;
03385 if (attachment->getIsHUDAttachment())
03386 {
03387 attach_hud_menu->append(new_item = new LLMenuItemCallGL(attachment->getName(),
03388 NULL,
03389 NULL, &attach_label, (void*)attachment));
03390 }
03391 else
03392 {
03393 attach_menu->append(new_item = new LLMenuItemCallGL(attachment->getName(),
03394 NULL,
03395 NULL, &attach_label, (void*)attachment));
03396 }
03397
03398 LLSimpleListener* callback = mInventoryPanel->getListenerByName("Inventory.AttachObject");
03399
03400 if (callback)
03401 {
03402 new_item->addListener(callback, "on_click", LLSD(attachment->getName()));
03403 }
03404 }
03405 }
03406 }
03407 }
03408 }
03409 hideContextEntries(menu, items, disabled_items);
03410 }
03411
03412 BOOL LLObjectBridge::renameItem(const LLString& new_name)
03413 {
03414 if(!isItemRenameable()) return FALSE;
03415 LLPreview::rename(mUUID, getPrefix() + new_name);
03416 LLInventoryModel* model = mInventoryPanel->getModel();
03417 if(!model) return FALSE;
03418 LLViewerInventoryItem* item = getItem();
03419 if(item && (item->getName() != new_name))
03420 {
03421 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
03422 new_item->rename(new_name);
03423 buildDisplayName(new_item, mDisplayName);
03424 new_item->updateServer(FALSE);
03425 model->updateItem(new_item);
03426 model->notifyObservers();
03427
03428 LLVOAvatar* avatar = gAgent.getAvatarObject();
03429 if( avatar )
03430 {
03431 LLViewerObject* obj = avatar->getWornAttachment( item->getUUID() );
03432 if( obj )
03433 {
03434 LLSelectMgr::getInstance()->deselectAll();
03435 LLSelectMgr::getInstance()->addAsIndividual( obj, SELECT_ALL_TES, FALSE );
03436 LLSelectMgr::getInstance()->selectionSetObjectName( new_name );
03437 LLSelectMgr::getInstance()->deselectAll();
03438 }
03439 }
03440 }
03441
03442
03443 return FALSE;
03444 }
03445
03446
03447
03448
03449
03450 LLString LLLSLTextBridge::sPrefix("Script: ");
03451
03452 LLUIImagePtr LLLSLTextBridge::getIcon() const
03453 {
03454 return get_item_icon(LLAssetType::AT_SCRIPT, LLInventoryType::IT_LSL, 0, FALSE);
03455 }
03456
03457 void LLLSLTextBridge::openItem()
03458 {
03459
03460 if(!LLPreview::show(mUUID))
03461 {
03462 LLViewerInventoryItem* item = getItem();
03463 if (item)
03464 {
03465
03466 S32 left, top;
03467 gFloaterView->getNewFloaterPosition(&left, &top);
03468 LLRect rect = gSavedSettings.getRect("PreviewScriptRect");
03469 rect.translate(left - rect.mLeft, top - rect.mTop);
03470
03471 LLPreviewLSL* preview = new LLPreviewLSL("preview lsl text",
03472 rect,
03473 getPrefix() + item->getName(),
03474 mUUID);
03475 preview->setFocus(TRUE);
03476
03477 gFloaterView->adjustToFitScreen(preview, FALSE);
03478 }
03479 }
03480 }
03481
03482
03483
03484
03485
03486
03487 void wear_inventory_item_on_avatar( LLInventoryItem* item )
03488 {
03489 if(item)
03490 {
03491 lldebugs << "wear_inventory_item_on_avatar( " << item->getName()
03492 << " )" << llendl;
03493
03494 gWearableList.getAsset(item->getAssetUUID(),
03495 item->getName(),
03496 item->getType(),
03497 LLWearableBridge::onWearOnAvatarArrived,
03498 new LLUUID(item->getUUID()));
03499 }
03500 }
03501
03502 struct LLFoundData
03503 {
03504 LLFoundData(const LLUUID& item_id,
03505 const LLUUID& asset_id,
03506 const LLString& name,
03507 LLAssetType::EType asset_type) :
03508 mItemID(item_id),
03509 mAssetID(asset_id),
03510 mName(name),
03511 mAssetType(asset_type),
03512 mWearable( NULL ) {}
03513
03514 LLUUID mItemID;
03515 LLUUID mAssetID;
03516 LLString mName;
03517 LLAssetType::EType mAssetType;
03518 LLWearable* mWearable;
03519 };
03520
03521 struct LLWearableHoldingPattern
03522 {
03523 LLWearableHoldingPattern() : mResolved(0) {}
03524 ~LLWearableHoldingPattern()
03525 {
03526 for_each(mFoundList.begin(), mFoundList.end(), DeletePointer());
03527 mFoundList.clear();
03528 }
03529 typedef std::list<LLFoundData*> found_list_t;
03530 found_list_t mFoundList;
03531 S32 mResolved;
03532 };
03533
03534
03535 class LLOutfitObserver : public LLInventoryFetchObserver
03536 {
03537 public:
03538 LLOutfitObserver(const LLUUID& cat_id, bool copy_items, bool append) :
03539 mCatID(cat_id),
03540 mCopyItems(copy_items),
03541 mAppend(append)
03542 {}
03543 ~LLOutfitObserver() {}
03544 virtual void done();
03545
03546 protected:
03547 LLUUID mCatID;
03548 bool mCopyItems;
03549 bool mAppend;
03550 };
03551
03552 class LLWearInventoryCategoryCallback : public LLInventoryCallback
03553 {
03554 public:
03555 LLWearInventoryCategoryCallback(const LLUUID& cat_id, bool append)
03556 {
03557 mCatID = cat_id;
03558 mAppend = append;
03559 }
03560 void fire(const LLUUID& item_id)
03561 {
03562
03563
03564
03565
03566
03567
03568
03569
03570 }
03571
03572 protected:
03573 ~LLWearInventoryCategoryCallback()
03574 {
03575
03576
03577 if( LLInventoryCallbackManager::is_instantiated() )
03578 {
03579 wear_inventory_category_on_avatar(gInventory.getCategory(mCatID), mAppend);
03580 }
03581 else
03582 {
03583 llwarns << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl;
03584 }
03585 }
03586
03587 private:
03588 LLUUID mCatID;
03589 bool mAppend;
03590 };
03591
03592 void LLOutfitObserver::done()
03593 {
03594
03595
03596 if(mCopyItems)
03597 {
03598 LLInventoryCategory* cat = gInventory.getCategory(mCatID);
03599 LLString name;
03600 if(!cat)
03601 {
03602
03603 name = "New Outfit";
03604 }
03605 else
03606 {
03607 name = cat->getName();
03608 }
03609 LLViewerInventoryItem* item = NULL;
03610 item_ref_t::iterator it = mComplete.begin();
03611 item_ref_t::iterator end = mComplete.end();
03612 LLUUID pid;
03613 for(; it < end; ++it)
03614 {
03615 item = (LLViewerInventoryItem*)gInventory.getItem(*it);
03616 if(item)
03617 {
03618 if(LLInventoryType::IT_GESTURE == item->getInventoryType())
03619 {
03620 pid = gInventory.findCategoryUUIDForType(LLAssetType::AT_GESTURE);
03621 }
03622 else
03623 {
03624 pid = gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING);
03625 }
03626 break;
03627 }
03628 }
03629 if(pid.isNull())
03630 {
03631 pid = gAgent.getInventoryRootID();
03632 }
03633
03634 LLUUID cat_id = gInventory.createNewCategory(
03635 pid,
03636 LLAssetType::AT_NONE,
03637 name);
03638 mCatID = cat_id;
03639 LLPointer<LLInventoryCallback> cb = new LLWearInventoryCategoryCallback(mCatID, mAppend);
03640 it = mComplete.begin();
03641 for(; it < end; ++it)
03642 {
03643 item = (LLViewerInventoryItem*)gInventory.getItem(*it);
03644 if(item)
03645 {
03646 copy_inventory_item(
03647 gAgent.getID(),
03648 item->getPermissions().getOwner(),
03649 item->getUUID(),
03650 cat_id,
03651 std::string(),
03652 cb);
03653 }
03654 }
03655 }
03656 else
03657 {
03658
03659 wear_inventory_category_on_avatar(gInventory.getCategory(mCatID), mAppend);
03660 }
03661 }
03662
03663 class LLOutfitFetch : public LLInventoryFetchDescendentsObserver
03664 {
03665 public:
03666 LLOutfitFetch(bool copy_items, bool append) : mCopyItems(copy_items), mAppend(append) {}
03667 ~LLOutfitFetch() {}
03668 virtual void done();
03669 protected:
03670 bool mCopyItems;
03671 bool mAppend;
03672 };
03673
03674 void LLOutfitFetch::done()
03675 {
03676
03677
03678
03679 LLInventoryModel::cat_array_t cat_array;
03680 LLInventoryModel::item_array_t item_array;
03681 gInventory.collectDescendents(mCompleteFolders.front(),
03682 cat_array,
03683 item_array,
03684 LLInventoryModel::EXCLUDE_TRASH);
03685 S32 count = item_array.count();
03686 if(!count)
03687 {
03688 llwarns << "Nothing fetched in category " << mCompleteFolders.front()
03689 << llendl;
03690 dec_busy_count();
03691 gInventory.removeObserver(this);
03692 delete this;
03693 return;
03694 }
03695
03696 LLOutfitObserver* outfit;
03697 outfit = new LLOutfitObserver(mCompleteFolders.front(), mCopyItems, mAppend);
03698 LLInventoryFetchObserver::item_ref_t ids;
03699 for(S32 i = 0; i < count; ++i)
03700 {
03701 ids.push_back(item_array.get(i)->getUUID());
03702 }
03703
03704
03705
03706
03707 dec_busy_count();
03708 gInventory.removeObserver(this);
03709 delete this;
03710
03711
03712
03713 inc_busy_count();
03714
03715
03716 outfit->fetchItems(ids);
03717 if(outfit->isEverythingComplete())
03718 {
03719
03720 outfit->done();
03721 }
03722 else
03723 {
03724
03725
03726 gInventory.addObserver(outfit);
03727 }
03728 }
03729
03730 void wear_outfit_by_name(const char* name)
03731 {
03732 llinfos << "Wearing category " << name << llendl;
03733 inc_busy_count();
03734
03735 LLInventoryModel::cat_array_t cat_array;
03736 LLInventoryModel::item_array_t item_array;
03737 LLNameCategoryCollector has_name(name);
03738 gInventory.collectDescendentsIf(gAgent.getInventoryRootID(),
03739 cat_array,
03740 item_array,
03741 LLInventoryModel::EXCLUDE_TRASH,
03742 has_name);
03743 bool copy_items = false;
03744 LLInventoryCategory* cat = NULL;
03745 if (cat_array.count() > 0)
03746 {
03747
03748 cat = cat_array.get(0);
03749 }
03750 else
03751 {
03752 gInventory.collectDescendentsIf(LLUUID::null,
03753 cat_array,
03754 item_array,
03755 LLInventoryModel::EXCLUDE_TRASH,
03756 has_name);
03757 if(cat_array.count() > 0)
03758 {
03759 cat = cat_array.get(0);
03760 copy_items = true;
03761 }
03762 }
03763
03764 if(cat)
03765 {
03766 wear_inventory_category(cat, copy_items, false);
03767 }
03768 else
03769 {
03770 llwarns << "Couldn't find outfit " <<name<< " in wear_outfit_by_name()"
03771 << llendl;
03772 }
03773
03774 dec_busy_count();
03775 }
03776
03777 void wear_inventory_category(LLInventoryCategory* category, bool copy, bool append)
03778 {
03779 if(!category) return;
03780
03781 lldebugs << "wear_inventory_category( " << category->getName()
03782 << " )" << llendl;
03783
03784
03785
03786 LLOutfitFetch* outfit;
03787 outfit = new LLOutfitFetch(copy, append);
03788 LLInventoryFetchDescendentsObserver::folder_ref_t folders;
03789 folders.push_back(category->getUUID());
03790 outfit->fetchDescendents(folders);
03791 inc_busy_count();
03792 if(outfit->isEverythingComplete())
03793 {
03794
03795 outfit->done();
03796 }
03797 else
03798 {
03799
03800
03801 gInventory.addObserver(outfit);
03802 }
03803 }
03804
03805
03806 void wear_inventory_category_on_avatar( LLInventoryCategory* category, BOOL append )
03807 {
03808
03809
03810
03811 if(!category) return;
03812 lldebugs << "wear_inventory_category_on_avatar( " << category->getName()
03813 << " )" << llendl;
03814
03815 LLWearInfo* userdata = new LLWearInfo;
03816 userdata->mAppend = append;
03817 userdata->mCategoryID = category->getUUID();
03818
03819 if( gFloaterCustomize )
03820 {
03821 gFloaterCustomize->askToSaveAllIfDirty(
03822 wear_inventory_category_on_avatar_step2,
03823 userdata);
03824 }
03825 else
03826 {
03827 wear_inventory_category_on_avatar_step2(
03828 TRUE,
03829 userdata );
03830 }
03831 }
03832
03833
03834 void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata )
03835 {
03836 LLWearInfo* wear_info = (LLWearInfo*)userdata;
03837 if (!wear_info) return;
03838
03839
03840 lldebugs << "wear_inventory_category_on_avatar_step2()" << llendl;
03841 if(proceed)
03842 {
03843 LLInventoryModel::cat_array_t cat_array;
03844 LLInventoryModel::item_array_t item_array;
03845 LLFindWearables is_wearable;
03846 gInventory.collectDescendentsIf(wear_info->mCategoryID,
03847 cat_array,
03848 item_array,
03849 LLInventoryModel::EXCLUDE_TRASH,
03850 is_wearable);
03851 S32 i;
03852 S32 wearable_count = item_array.count();
03853
03854 LLInventoryModel::cat_array_t obj_cat_array;
03855 LLInventoryModel::item_array_t obj_item_array;
03856 LLIsType is_object( LLAssetType::AT_OBJECT );
03857 gInventory.collectDescendentsIf(wear_info->mCategoryID,
03858 obj_cat_array,
03859 obj_item_array,
03860 LLInventoryModel::EXCLUDE_TRASH,
03861 is_object);
03862 S32 obj_count = obj_item_array.count();
03863
03864
03865 LLInventoryModel::cat_array_t gest_cat_array;
03866 LLInventoryModel::item_array_t gest_item_array;
03867 LLIsType is_gesture( LLAssetType::AT_GESTURE );
03868 gInventory.collectDescendentsIf(wear_info->mCategoryID,
03869 gest_cat_array,
03870 gest_item_array,
03871 LLInventoryModel::EXCLUDE_TRASH,
03872 is_gesture);
03873 S32 gest_count = gest_item_array.count();
03874
03875 if( !wearable_count && !obj_count && !gest_count)
03876 {
03877 gViewerWindow->alertXml("CouldNotPutOnOutfit");
03878 delete wear_info;
03879 return;
03880 }
03881
03882
03883 if (wearable_count > 0 || obj_count > 0)
03884 {
03885 inc_busy_count();
03886 }
03887
03888
03889 if (gest_count > 0)
03890 {
03891 llinfos << "Activating " << gest_count << " gestures" << llendl;
03892
03893 gGestureManager.activateGestures(gest_item_array);
03894
03895
03896
03897 LLViewerInventoryCategory* catp = gInventory.getCategory(wear_info->mCategoryID);
03898 if (catp)
03899 {
03900 gInventory.updateCategory(catp);
03901 gInventory.notifyObservers();
03902 }
03903 }
03904
03905 if(wearable_count > 0)
03906 {
03907
03908
03909
03910
03911 LLWearableHoldingPattern* holder = new LLWearableHoldingPattern;
03912 LLFoundData* found;
03913 LLDynamicArray<LLFoundData*> found_container;
03914 for(i = 0; i < wearable_count; ++i)
03915 {
03916 found = new LLFoundData(item_array.get(i)->getUUID(),
03917 item_array.get(i)->getAssetUUID(),
03918 item_array.get(i)->getName(),
03919 item_array.get(i)->getType());
03920 holder->mFoundList.push_front(found);
03921 found_container.put(found);
03922 }
03923 for(i = 0; i < wearable_count; ++i)
03924 {
03925 gAddToOutfit = wear_info->mAppend;
03926
03927 found = found_container.get(i);
03928 gWearableList.getAsset(found->mAssetID,
03929 found->mName,
03930 found->mAssetType,
03931 wear_inventory_category_on_avatar_loop,
03932 (void*)holder);
03933 }
03934 }
03935
03936
03937
03938 if (!wear_info->mAppend
03939 && !(wearable_count == 0 && obj_count == 0 && gest_count > 0) )
03940 {
03941 LLAgent::userRemoveAllAttachments(NULL);
03942 }
03943
03944 if( obj_count > 0 )
03945 {
03946
03947
03948 LLVOAvatar* avatar = gAgent.getAvatarObject();
03949 if( avatar )
03950 {
03951
03952
03953
03954 const S32 MAX_PACKETS_TO_SEND = 10;
03955 const S32 OBJECTS_PER_PACKET = 4;
03956 const S32 MAX_OBJECTS_TO_SEND = MAX_PACKETS_TO_SEND * OBJECTS_PER_PACKET;
03957 if( obj_count > MAX_OBJECTS_TO_SEND )
03958 {
03959 obj_count = MAX_OBJECTS_TO_SEND;
03960 }
03961
03962
03963 LLUUID compound_msg_id;
03964 compound_msg_id.generate();
03965 LLMessageSystem* msg = gMessageSystem;
03966
03967 for(i = 0; i < obj_count; ++i)
03968 {
03969 if( 0 == (i % OBJECTS_PER_PACKET) )
03970 {
03971
03972 msg->newMessageFast(_PREHASH_RezMultipleAttachmentsFromInv);
03973 msg->nextBlockFast(_PREHASH_AgentData);
03974 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
03975 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03976 msg->nextBlockFast(_PREHASH_HeaderData);
03977 msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id );
03978 msg->addU8Fast(_PREHASH_TotalObjects, obj_count );
03979 msg->addBOOLFast(_PREHASH_FirstDetachAll, !wear_info->mAppend );
03980 }
03981
03982 LLInventoryItem* item = obj_item_array.get(i);
03983 msg->nextBlockFast(_PREHASH_ObjectData );
03984 msg->addUUIDFast(_PREHASH_ItemID, item->getUUID() );
03985 msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner());
03986 msg->addU8Fast(_PREHASH_AttachmentPt, 0 );
03987 pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
03988 msg->addStringFast(_PREHASH_Name, item->getName());
03989 msg->addStringFast(_PREHASH_Description, item->getDescription());
03990
03991 if( (i+1 == obj_count) || ((OBJECTS_PER_PACKET-1) == (i % OBJECTS_PER_PACKET)) )
03992 {
03993
03994 msg->sendReliable( gAgent.getRegion()->getHost() );
03995 }
03996 }
03997 }
03998 }
03999 }
04000 delete wear_info;
04001 wear_info = NULL;
04002 }
04003
04004 void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void* data)
04005 {
04006 LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data;
04007 BOOL append= gAddToOutfit;
04008
04009 if(wearable)
04010 {
04011 for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin();
04012 iter != holder->mFoundList.end(); ++iter)
04013 {
04014 LLFoundData* data = *iter;
04015 if(wearable->getID() == data->mAssetID)
04016 {
04017 data->mWearable = wearable;
04018 break;
04019 }
04020 }
04021 }
04022 holder->mResolved += 1;
04023 if(holder->mResolved >= (S32)holder->mFoundList.size())
04024 {
04025 wear_inventory_category_on_avatar_step3(holder, append);
04026 }
04027 }
04028
04029 void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, BOOL append)
04030 {
04031 lldebugs << "wear_inventory_category_on_avatar_step3()" << llendl;
04032 LLInventoryItem::item_array_t items;
04033 LLDynamicArray< LLWearable* > wearables;
04034
04035
04036
04037 for( S32 i = 0; i < WT_COUNT; i++ )
04038 {
04039 for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin();
04040 iter != holder->mFoundList.end(); ++iter)
04041 {
04042 LLFoundData* data = *iter;
04043 LLWearable* wearable = data->mWearable;
04044 if( wearable && ((S32)wearable->getType() == i) )
04045 {
04046 LLViewerInventoryItem* item;
04047 item = (LLViewerInventoryItem*)gInventory.getItem(data->mItemID);
04048 if( item && (item->getAssetUUID() == wearable->getID()) )
04049 {
04050
04051
04052
04053
04054
04055
04056
04057
04058
04059
04060
04061
04062 items.put(item);
04063 wearables.put(wearable);
04064 }
04065 break;
04066 }
04067 }
04068 }
04069
04070 if(wearables.count() > 0)
04071 {
04072 gAgent.setWearableOutfit(items, wearables, !append);
04073 gInventory.notifyObservers();
04074 }
04075
04076 delete holder;
04077
04078 dec_busy_count();
04079 }
04080
04081 void remove_inventory_category_from_avatar( LLInventoryCategory* category )
04082 {
04083 if(!category) return;
04084 lldebugs << "remove_inventory_category_from_avatar( " << category->getName()
04085 << " )" << llendl;
04086
04087
04088 LLUUID* uuid = new LLUUID(category->getUUID());
04089
04090 if( gFloaterCustomize )
04091 {
04092 gFloaterCustomize->askToSaveAllIfDirty(
04093 remove_inventory_category_from_avatar_step2,
04094 uuid);
04095 }
04096 else
04097 {
04098 remove_inventory_category_from_avatar_step2(
04099 TRUE,
04100 uuid );
04101 }
04102 }
04103
04104
04105 void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata)
04106 {
04107
04108
04109 LLUUID* category_id = (LLUUID *)userdata;
04110
04111 lldebugs << "remove_inventory_category_from_avatar_step2()" << llendl;
04112 if(proceed)
04113 {
04114 LLInventoryModel::cat_array_t cat_array;
04115 LLInventoryModel::item_array_t item_array;
04116 LLFindWearables is_wearable;
04117 gInventory.collectDescendentsIf(*category_id,
04118 cat_array,
04119 item_array,
04120 LLInventoryModel::EXCLUDE_TRASH,
04121 is_wearable);
04122 S32 i;
04123 S32 wearable_count = item_array.count();
04124
04125 LLInventoryModel::cat_array_t obj_cat_array;
04126 LLInventoryModel::item_array_t obj_item_array;
04127 LLIsType is_object( LLAssetType::AT_OBJECT );
04128 gInventory.collectDescendentsIf(*category_id,
04129 obj_cat_array,
04130 obj_item_array,
04131 LLInventoryModel::EXCLUDE_TRASH,
04132 is_object);
04133 S32 obj_count = obj_item_array.count();
04134
04135
04136 LLInventoryModel::cat_array_t gest_cat_array;
04137 LLInventoryModel::item_array_t gest_item_array;
04138 LLIsType is_gesture( LLAssetType::AT_GESTURE );
04139 gInventory.collectDescendentsIf(*category_id,
04140 gest_cat_array,
04141 gest_item_array,
04142 LLInventoryModel::EXCLUDE_TRASH,
04143 is_gesture);
04144 S32 gest_count = gest_item_array.count();
04145
04146 if (wearable_count > 0)
04147 {
04148 for(i = 0; i < wearable_count; ++i)
04149 {
04150 if( gAgent.isWearingItem (item_array.get(i)->getUUID()) )
04151 {
04152 gWearableList.getAsset(item_array.get(i)->getAssetUUID(),
04153 item_array.get(i)->getName(),
04154 item_array.get(i)->getType(),
04155 LLWearableBridge::onRemoveFromAvatarArrived,
04156 new LLUUID(item_array.get(i)->getUUID()));
04157
04158 }
04159 }
04160 }
04161
04162
04163 if (obj_count > 0)
04164 {
04165 for(i = 0; i < obj_count; ++i)
04166 {
04167 gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
04168 gMessageSystem->nextBlockFast(_PREHASH_ObjectData );
04169 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
04170 gMessageSystem->addUUIDFast(_PREHASH_ItemID, obj_item_array.get(i)->getUUID() );
04171
04172 gMessageSystem->sendReliable( gAgent.getRegion()->getHost() );
04173
04174
04175 LLViewerObject *found_obj = gObjectList.findObject( obj_item_array.get(i)->getUUID());
04176 if (found_obj)
04177 {
04178 LLSelectMgr::getInstance()->remove(found_obj);
04179 }
04180 else
04181 {
04182 llwarns << "object not found, ignoring" << llendl;
04183 }
04184 }
04185 }
04186
04187 if (gest_count > 0)
04188 {
04189 for(i = 0; i < gest_count; ++i)
04190 {
04191 if ( gGestureManager.isGestureActive( gest_item_array.get(i)->getUUID()) )
04192 {
04193 gGestureManager.deactivateGesture( gest_item_array.get(i)->getUUID() );
04194 gInventory.updateItem( gest_item_array.get(i) );
04195 gInventory.notifyObservers();
04196 }
04197
04198 }
04199 }
04200 }
04201 delete category_id;
04202 category_id = NULL;
04203 }
04204
04205 BOOL LLWearableBridge::renameItem(const LLString& new_name)
04206 {
04207 if( gAgent.isWearingItem( mUUID ) )
04208 {
04209 gAgent.setWearableName( mUUID, new_name );
04210 }
04211 return LLItemBridge::renameItem(new_name);
04212 }
04213
04214 BOOL LLWearableBridge::isItemRemovable()
04215 {
04216 if(gAgent.isWearingItem(mUUID)) return FALSE;
04217 return LLInvFVBridge::isItemRemovable();
04218 }
04219
04220 LLFontGL::StyleFlags LLWearableBridge::getLabelStyle() const
04221 {
04222 if( gAgent.isWearingItem( mUUID ) )
04223 {
04224
04225 return LLFontGL::BOLD;
04226 }
04227 else
04228 {
04229 return LLFontGL::NORMAL;
04230 }
04231 }
04232
04233 LLString LLWearableBridge::getLabelSuffix() const
04234 {
04235 if( gAgent.isWearingItem( mUUID ) )
04236 {
04237 return LLItemBridge::getLabelSuffix() + " (worn)";
04238 }
04239 else
04240 {
04241 return LLItemBridge::getLabelSuffix();
04242 }
04243 }
04244
04245 LLUIImagePtr LLWearableBridge::getIcon() const
04246 {
04247 return get_item_icon(mAssetType, mInvType, mWearableType, FALSE);
04248 }
04249
04250
04251 void LLWearableBridge::performAction(LLFolderView* folder, LLInventoryModel* model, LLString action)
04252 {
04253 if ("wear" == action)
04254 {
04255 wearOnAvatar();
04256 }
04257 else if ("edit" == action)
04258 {
04259 editOnAvatar();
04260 return;
04261 }
04262 else if ("take_off" == action)
04263 {
04264 if(gAgent.isWearingItem(mUUID))
04265 {
04266 LLViewerInventoryItem* item = getItem();
04267 if (item)
04268 {
04269 gWearableList.getAsset(item->getAssetUUID(),
04270 item->getName(),
04271 item->getType(),
04272 LLWearableBridge::onRemoveFromAvatarArrived,
04273 new LLUUID(mUUID));
04274 }
04275 }
04276 }
04277 else LLItemBridge::performAction(folder, model, action);
04278 }
04279
04280 void LLWearableBridge::openItem()
04281 {
04282 if( isInTrash() )
04283 {
04284 gViewerWindow->alertXml("CannotWearTrash");
04285 }
04286 else if(isAgentInventory())
04287 {
04288 if( !gAgent.isWearingItem( mUUID ) )
04289 {
04290 wearOnAvatar();
04291 }
04292 }
04293 else
04294 {
04295
04296
04297 LLViewerInventoryItem* item = getItem();
04298 if(item && item->isComplete())
04299 {
04300 LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
04301 copy_inventory_item(
04302 gAgent.getID(),
04303 item->getPermissions().getOwner(),
04304 item->getUUID(),
04305 LLUUID::null,
04306 std::string(),
04307 cb);
04308 }
04309 else if(item)
04310 {
04311
04312
04313 gViewerWindow->alertXml("CannotWearInfoNotComplete");
04314 }
04315 }
04316 }
04317
04318 void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
04319 {
04320 lldebugs << "LLWearableBridge::buildContextMenu()" << llendl;
04321 std::vector<LLString> items;
04322 std::vector<LLString> disabled_items;
04323 if(isInTrash())
04324 {
04325 items.push_back("Purge Item");
04326 if (!isItemRemovable())
04327 {
04328 disabled_items.push_back("Purge Item");
04329 }
04330
04331 items.push_back("Restore Item");
04332 }
04333 else
04334 {
04335 BOOL no_open = ((flags & SUPPRESS_OPEN_ITEM) == SUPPRESS_OPEN_ITEM);
04336
04337
04338 LLViewerInventoryItem* item = getItem();
04339 if( !no_open && item )
04340 {
04341 no_open = (item->getType() == LLAssetType::AT_CLOTHING) ||
04342 (item->getType() == LLAssetType::AT_BODYPART);
04343 }
04344 if (!no_open)
04345 {
04346 items.push_back("Open");
04347 }
04348
04349 items.push_back("Properties");
04350
04351 getClipboardEntries(true, items, disabled_items, flags);
04352
04353 items.push_back("Wearable Separator");
04354
04355 items.push_back("Wearable Wear");
04356 items.push_back("Wearable Edit");
04357
04358
04359 if ((flags & FIRST_SELECTED_ITEM) == 0)
04360 {
04361 disabled_items.push_back("Wearable Edit");
04362 }
04363
04364
04365
04366
04367
04368
04369
04370
04371
04372
04373 if( item && (item->getType() == LLAssetType::AT_CLOTHING) )
04374 {
04375 items.push_back("Take Off");
04376
04377
04378
04379
04380 }
04381 }
04382 hideContextEntries(menu, items, disabled_items);
04383 }
04384
04385
04386
04387 BOOL LLWearableBridge::canWearOnAvatar(void* user_data)
04388 {
04389 LLWearableBridge* self = (LLWearableBridge*)user_data;
04390 if(!self) return FALSE;
04391 if(!self->isAgentInventory())
04392 {
04393 LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->getItem();
04394 if(!item || !item->isComplete()) return FALSE;
04395 }
04396 return (!gAgent.isWearingItem(self->mUUID));
04397 }
04398
04399
04400
04401 void LLWearableBridge::onWearOnAvatar(void* user_data)
04402 {
04403 LLWearableBridge* self = (LLWearableBridge*)user_data;
04404 if(!self) return;
04405 self->wearOnAvatar();
04406 }
04407
04408 void LLWearableBridge::wearOnAvatar()
04409 {
04410
04411
04412 if (!gAgent.areWearablesLoaded())
04413 {
04414 gViewerWindow->alertXml("CanNotChangeAppearanceUntilLoaded");
04415 return;
04416 }
04417
04418 LLViewerInventoryItem* item = getItem();
04419 if(item)
04420 {
04421 if(!isAgentInventory())
04422 {
04423 LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
04424 copy_inventory_item(
04425 gAgent.getID(),
04426 item->getPermissions().getOwner(),
04427 item->getUUID(),
04428 LLUUID::null,
04429 std::string(),
04430 cb);
04431 }
04432 else
04433 {
04434 wear_inventory_item_on_avatar(item);
04435 }
04436 }
04437 }
04438
04439
04440 void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userdata )
04441 {
04442 LLUUID* item_id = (LLUUID*) userdata;
04443 if(wearable)
04444 {
04445 LLViewerInventoryItem* item = NULL;
04446 item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
04447 if(item)
04448 {
04449 if(item->getAssetUUID() == wearable->getID())
04450 {
04451
04452
04453
04454
04455
04456
04457
04458
04459
04460
04461
04462
04463
04464
04465
04466 gAgent.setWearable(item, wearable);
04467 gInventory.notifyObservers();
04468
04469 }
04470 else
04471 {
04472 llinfos << "By the time wearable asset arrived, its inv item already pointed to a different asset." << llendl;
04473 }
04474 }
04475 }
04476 delete item_id;
04477 }
04478
04479
04480 BOOL LLWearableBridge::canEditOnAvatar(void* user_data)
04481 {
04482 LLWearableBridge* self = (LLWearableBridge*)user_data;
04483 if(!self) return FALSE;
04484
04485 return (gAgent.isWearingItem(self->mUUID));
04486 }
04487
04488
04489 void LLWearableBridge::onEditOnAvatar(void* user_data)
04490 {
04491 LLWearableBridge* self = (LLWearableBridge*)user_data;
04492 if(self)
04493 {
04494 self->editOnAvatar();
04495 }
04496 }
04497
04498 void LLWearableBridge::editOnAvatar()
04499 {
04500 LLWearable* wearable = gAgent.getWearableFromWearableItem(mUUID);
04501 if( wearable )
04502 {
04503
04504 LLFloaterCustomize::setCurrentWearableType( wearable->getType() );
04505
04506 if( CAMERA_MODE_CUSTOMIZE_AVATAR != gAgent.getCameraMode() )
04507 {
04508
04509 gAgent.changeCameraToCustomizeAvatar();
04510 }
04511 }
04512 }
04513
04514
04515 BOOL LLWearableBridge::canRemoveFromAvatar(void* user_data)
04516 {
04517 LLWearableBridge* self = (LLWearableBridge*)user_data;
04518 if( self && (LLAssetType::AT_BODYPART != self->mAssetType) )
04519 {
04520 return gAgent.isWearingItem( self->mUUID );
04521 }
04522 return FALSE;
04523 }
04524
04525
04526 void LLWearableBridge::onRemoveFromAvatar(void* user_data)
04527 {
04528 LLWearableBridge* self = (LLWearableBridge*)user_data;
04529 if(!self) return;
04530 if(gAgent.isWearingItem(self->mUUID))
04531 {
04532 LLViewerInventoryItem* item = self->getItem();
04533 if (item)
04534 {
04535 gWearableList.getAsset(item->getAssetUUID(),
04536 item->getName(),
04537 item->getType(),
04538 onRemoveFromAvatarArrived,
04539 new LLUUID(self->mUUID));
04540 }
04541 }
04542 }
04543
04544
04545 void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable,
04546 void* userdata)
04547 {
04548 LLUUID* item_id = (LLUUID*) userdata;
04549 if(wearable)
04550 {
04551 if( gAgent.isWearingItem( *item_id ) )
04552 {
04553 EWearableType type = wearable->getType();
04554
04555 if( !(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR ) )
04557 {
04558 gAgent.removeWearable( type );
04559 }
04560 }
04561 }
04562 delete item_id;
04563 }