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