diff options
30 files changed, 936 insertions, 622 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 28a5555ca2..7094d68292 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -226,6 +226,7 @@ set(viewer_SOURCE_FILES llfollowcam.cpp llfriendcard.cpp llgesturemgr.cpp + llgiveinventory.cpp llglsandbox.cpp llgroupactions.cpp llgroupiconctrl.cpp @@ -744,6 +745,7 @@ set(viewer_HEADER_FILES llfollowcam.h llfriendcard.h llgesturemgr.h + llgiveinventory.h llgroupactions.h llgroupiconctrl.h llgrouplist.h diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 00d9bbe18b..875ed72a12 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -54,7 +54,9 @@ #include "llfloaterreg.h" #include "llfloaterpay.h" #include "llfloaterworldmap.h" +#include "llgiveinventory.h" #include "llinventorymodel.h" // for gInventory.findCategoryUUIDForType +#include "llinventorypanel.h" #include "llimview.h" // for gIMMgr #include "llmutelist.h" #include "llnotificationsutil.h" // for LLNotificationsUtil @@ -429,13 +431,107 @@ void LLAvatarActions::share(const LLUUID& id) } } +namespace action_give_inventory +{ + typedef std::set<LLUUID> uuid_set_t; + + /** + * Checks My Inventory visibility. + */ + static bool is_give_inventory_acceptable() + { + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + if (NULL == active_panel) return false; + + // check selection in the panel + const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); + if (inventory_selected_uuids.empty()) return false; // nothing selected + + bool acceptable = false; + uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); + const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end(); + for (; it != it_end; ++it) + { + LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it); + // any category can be offered. + if (inv_cat) + { + acceptable = true; + continue; + } + + LLViewerInventoryItem* inv_item = gInventory.getItem(*it); + // check if inventory item can be given + if (LLGiveInventory::isInventoryGiveAcceptable(inv_item)) + { + acceptable = true; + continue; + } + + // there are neither item nor category in inventory + acceptable = false; + break; + } + return acceptable; + } + + /** + * Performs "give inventory" operations for provided avatars. + * + * Sends one requests to give all selected inventory items for each passed avatar. + * Avatars are represent by two vectors: names and UUIDs which must be sychronized with each other. + * + * @param avatar_names - avatar names request to be sent. + * @param avatar_uuids - avatar names request to be sent. + */ + static void give_inventory(const std::vector<std::string>& avatar_names, const uuid_vec_t& avatar_uuids) + { + llassert(avatar_names.size() == avatar_uuids.size()); + + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + if (NULL == active_panel) return; + + const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); + if (inventory_selected_uuids.empty()) return; + + S32 count = llmin(avatar_names.size(), avatar_uuids.size()); + + // iterate through avatars + for(S32 i = 0; i < count; ++i) + { + const std::string& avatar_name = avatar_names[i]; + const LLUUID& avatar_uuid = avatar_uuids[i]; + + // Start up IM before give the item + const LLUUID session_id = gIMMgr->addSession(avatar_name, IM_NOTHING_SPECIAL, avatar_uuid); + + uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); + const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end(); + + // iterate through selected inventory objects + for (; it != it_end; ++it) + { + LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it); + if (inv_cat) + { + LLGiveInventory::doGiveInventoryCategory(avatar_uuid, inv_cat, session_id); + break; + } + LLViewerInventoryItem* inv_item = gInventory.getItem(*it); + LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id); + } + } + } +} + //static void LLAvatarActions::shareWithAvatars() { - LLFloaterAvatarPicker* picker = - LLFloaterAvatarPicker::show(NULL, FALSE, TRUE); - picker->setOkBtnEnableCb(boost::lambda::constant(false)); + using namespace action_give_inventory; + LLFloaterAvatarPicker* picker = + LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE); + picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable)); LLNotificationsUtil::add("ShareNotification"); } diff --git a/indra/newview/llfilteredwearablelist.cpp b/indra/newview/llfilteredwearablelist.cpp index 01d3c3f22e..fd99f673e0 100644 --- a/indra/newview/llfilteredwearablelist.cpp +++ b/indra/newview/llfilteredwearablelist.cpp @@ -37,23 +37,21 @@ #include "llinventoryitemslist.h" #include "llinventorymodel.h" -class LLFindItemsByMask : public LLInventoryCollectFunctor +class LLFindNonLinksByMask : public LLInventoryCollectFunctor { public: - LLFindItemsByMask(U64 mask) + LLFindNonLinksByMask(U64 mask) : mFilterMask(mask) {} virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) { - if(item) + if(item && !item->getIsLinkType() && (mFilterMask & (1LL << item->getInventoryType())) ) { - if( mFilterMask & (1LL << item->getInventoryType()) ) - { - return TRUE; - } + return true; } - return FALSE; + + return false; } private: @@ -96,7 +94,7 @@ void LLFilteredWearableListManager::populateList() { LLInventoryModel::cat_array_t cat_array; LLInventoryModel::item_array_t item_array; - LLFindItemsByMask collector(mFilterMask); + LLFindNonLinksByMask collector(mFilterMask); gInventory.collectDescendentsIf( gInventory.getRootFolderID(), diff --git a/indra/newview/llfilteredwearablelist.h b/indra/newview/llfilteredwearablelist.h index 3f42833bb4..0780c02442 100644 --- a/indra/newview/llfilteredwearablelist.h +++ b/indra/newview/llfilteredwearablelist.h @@ -36,7 +36,7 @@ class LLInventoryItemsList; -// Class that fills LLInventoryItemsList with filtered data. +// Class that fills LLInventoryItemsList with filtered data (original items only (non-links)). class LLFilteredWearableListManager : public LLInventoryObserver { LOG_CLASS(LLFilteredWearableListManager); diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index d1e99fbd61..b40c19c2c6 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -314,6 +314,18 @@ void LLFloaterAvatarPicker::populateFriend() void LLFloaterAvatarPicker::draw() { + // sometimes it is hard to determine when Select/Ok button should be disabled (see LLAvatarActions::shareWithAvatars). + // lets check this via mOkButtonValidateSignal callback periodically. + static LLFrameTimer timer; + if (timer.hasExpired()) + { + timer.setTimerExpirySec(0.33f); // three times per second should be enough. + + // simulate list changes. + onList(); + timer.start(); + } + LLFloater::draw(); if (!mNearMeListComplete && childGetVisibleTab("ResidentChooserTabs") == getChild<LLPanel>("NearMePanel")) { diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index d8d7057c4e..a42f6ee00f 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -237,6 +237,7 @@ BOOL LLFloaterTools::postBuild() childSetValue("checkbox stretch textures",(BOOL)gSavedSettings.getBOOL("ScaleStretchTextures")); mTextGridMode = getChild<LLTextBox>("text ruler mode"); mComboGridMode = getChild<LLComboBox>("combobox grid mode"); + mCheckStretchUniformLabel = getChild<LLTextBox>("checkbox uniform label"); // // Create Buttons @@ -316,6 +317,7 @@ LLFloaterTools::LLFloaterTools(const LLSD& key) mComboGridMode(NULL), mCheckStretchUniform(NULL), mCheckStretchTexture(NULL), + mCheckStretchUniformLabel(NULL), mBtnRotateLeft(NULL), mBtnRotateReset(NULL), @@ -632,6 +634,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) //mCheckSelectLinked ->setVisible( edit_visible ); if (mCheckStretchUniform) mCheckStretchUniform->setVisible( edit_visible ); if (mCheckStretchTexture) mCheckStretchTexture->setVisible( edit_visible ); + if (mCheckStretchUniformLabel) mCheckStretchUniformLabel->setVisible( edit_visible ); // Create buttons BOOL create_visible = (tool == LLToolCompCreate::getInstance()); diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index e1f3c9b78c..91431969bb 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -149,6 +149,10 @@ public: LLCheckBoxCtrl* mCheckStretchUniform; LLCheckBoxCtrl* mCheckStretchTexture; + // !HACK! Replacement of mCheckStretchUniform label because LLCheckBoxCtrl + // doesn't support word_wrap of its label. Need to fix truncation bug EXT-6658 + LLTextBox* mCheckStretchUniformLabel; + LLButton *mBtnRotateLeft; LLButton *mBtnRotateReset; LLButton *mBtnRotateRight; diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp new file mode 100644 index 0000000000..d83d895dd0 --- /dev/null +++ b/indra/newview/llgiveinventory.cpp @@ -0,0 +1,541 @@ +/** + * @file llgiveinventory.cpp + * @brief LLGiveInventory class implementation + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llgiveinventory.h" + +// library includes +#include "llnotificationsutil.h" +#include "lltrans.h" + +// newview includes +#include "llagent.h" +#include "llagentdata.h" +#include "llagentui.h" +#include "llagentwearables.h" +#include "llfloatertools.h" // for gFloaterTool +#include "llhudeffecttrail.h" +#include "llhudmanager.h" +#include "llimview.h" +#include "llinventory.h" +#include "llinventoryfunctions.h" +#include "llmutelist.h" +#include "llrecentpeople.h" +#include "llviewerobjectlist.h" +#include "llvoavatarself.h" + +// MAX ITEMS is based on (sizeof(uuid)+2) * count must be < MTUBYTES +// or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a +// bit from there to give some pad. +const S32 MAX_ITEMS = 42; + +class LLGiveable : public LLInventoryCollectFunctor +{ +public: + LLGiveable() : mCountLosing(0) {} + virtual ~LLGiveable() {} + virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); + + S32 countNoCopy() const { return mCountLosing; } +protected: + S32 mCountLosing; +}; + +bool LLGiveable::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + // All categories can be given. + if (cat) + return true; + + bool allowed = false; + if (item) + { + allowed = itemTransferCommonlyAllowed(item); + if (allowed && + !item->getPermissions().allowOperationBy(PERM_TRANSFER, + gAgent.getID())) + { + allowed = FALSE; + } + if (allowed && + !item->getPermissions().allowCopyBy(gAgent.getID())) + { + ++mCountLosing; + } + } + return allowed; +} + +class LLUncopyableItems : public LLInventoryCollectFunctor +{ +public: + LLUncopyableItems() {} + virtual ~LLUncopyableItems() {} + virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); +}; + +bool LLUncopyableItems::operator()(LLInventoryCategory* cat, + LLInventoryItem* item) +{ + bool uncopyable = false; + if (item) + { + if (itemTransferCommonlyAllowed(item) && + !item->getPermissions().allowCopyBy(gAgent.getID())) + { + uncopyable = true; + } + } + return uncopyable; +} + +// static +bool LLGiveInventory::isInventoryGiveAcceptable(const LLInventoryItem* item) +{ + if (!item) return false; + + if (!isAgentAvatarValid()) return false; + + if (!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID)) + { + return false; + } + + bool acceptable = true; + switch(item->getType()) + { + case LLAssetType::AT_OBJECT: + if (gAgentAvatarp->isWearingAttachment(item->getUUID())) + { + acceptable = false; + } + break; + case LLAssetType::AT_BODYPART: + case LLAssetType::AT_CLOTHING: + { + BOOL copyable = false; + if (item->getPermissions().allowCopyBy(gAgentID)) copyable = true; + + if (!copyable && gAgentWearables.isWearingItem(item->getUUID())) + { + acceptable = false; + } + } + break; + default: + break; + } + return acceptable; +} + +// static +bool LLGiveInventory::isInventoryGroupGiveAcceptable(const LLInventoryItem* item) +{ + if (!item) return false; + + if (!isAgentAvatarValid()) return false; + + // These permissions are double checked in the simulator in + // LLGroupNoticeInventoryItemFetch::result(). + if (!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID)) + { + return false; + } + if (!item->getPermissions().allowCopyBy(gAgent.getID())) + { + return false; + } + + + bool acceptable = true; + switch(item->getType()) + { + case LLAssetType::AT_OBJECT: + if (gAgentAvatarp->isWearingAttachment(item->getUUID())) + { + acceptable = false; + } + break; + default: + break; + } + return acceptable; +} + +// static +void LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent, + const LLInventoryItem* item, + const LLUUID& im_session_id/* = LLUUID::null*/) + +{ + llinfos << "LLGiveInventory::giveInventory()" << llendl; + if (!isInventoryGiveAcceptable(item)) + { + return; + } + if (item->getPermissions().allowCopyBy(gAgentID)) + { + // just give it away. + LLGiveInventory::commitGiveInventoryItem(to_agent, item, im_session_id); + } + else + { + // ask if the agent is sure. + LLSD payload; + payload["agent_id"] = to_agent; + payload["item_id"] = item->getUUID(); + LLNotificationsUtil::add("CannotCopyWarning", LLSD(), payload, + &LLGiveInventory::handleCopyProtectedItem); + } +} + +void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent, + const LLInventoryCategory* cat, + const LLUUID& im_session_id) + +{ + if (!cat) return; + llinfos << "LLGiveInventory::giveInventoryCategory() - " + << cat->getUUID() << llendl; + + if (!isAgentAvatarValid()) return; + + // Test out how many items are being given. + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLGiveable giveable; + gInventory.collectDescendentsIf (cat->getUUID(), + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + giveable); + S32 count = cats.count(); + bool complete = true; + for(S32 i = 0; i < count; ++i) + { + if (!gInventory.isCategoryComplete(cats.get(i)->getUUID())) + { + complete = false; + break; + } + } + if (!complete) + { + LLNotificationsUtil::add("IncompleteInventory"); + return; + } + count = items.count() + cats.count(); + if (count > MAX_ITEMS) + { + LLNotificationsUtil::add("TooManyItems"); + return; + } + else if (count == 0) + { + LLNotificationsUtil::add("NoItems"); + return; + } + else + { + if (0 == giveable.countNoCopy()) + { + LLGiveInventory::commitGiveInventoryCategory(to_agent, cat, im_session_id); + } + else + { + LLSD args; + args["COUNT"] = llformat("%d",giveable.countNoCopy()); + LLSD payload; + payload["agent_id"] = to_agent; + payload["folder_id"] = cat->getUUID(); + LLNotificationsUtil::add("CannotCopyCountItems", args, payload, &LLGiveInventory::handleCopyProtectedCategory); + } + } +} + +////////////////////////////////////////////////////////////////////////// +// PRIVATE METHODS +////////////////////////////////////////////////////////////////////////// + +//static +void LLGiveInventory::logInventoryOffer(const LLUUID& to_agent, const LLUUID &im_session_id) +{ + // compute id of possible IM session with agent that has "to_agent" id + LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, to_agent); + // If this item was given by drag-and-drop into an IM panel, log this action in the IM panel chat. + if (im_session_id.notNull()) + { + LLSD args; + gIMMgr->addSystemMessage(im_session_id, "inventory_item_offered", args); + } + // If this item was given by drag-and-drop on avatar while IM panel was open, log this action in the IM panel chat. + else if (LLIMModel::getInstance()->findIMSession(session_id)) + { + LLSD args; + gIMMgr->addSystemMessage(session_id, "inventory_item_offered", args); + } + // If this item was given by drag-and-drop on avatar while IM panel wasn't open, log this action to IM history. + else + { + std::string full_name; + if (gCacheName->getFullName(to_agent, full_name)) + { + LLIMModel::instance().logToFile(full_name, LLTrans::getString("SECOND_LIFE"), im_session_id, LLTrans::getString("inventory_item_offered-im")); + } + } +} + +// static +bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + LLInventoryItem* item = NULL; + switch(option) + { + case 0: // "Yes" + item = gInventory.getItem(notification["payload"]["item_id"].asUUID()); + if (item) + { + LLGiveInventory::commitGiveInventoryItem(notification["payload"]["agent_id"].asUUID(), + item); + // delete it for now - it will be deleted on the server + // quickly enough. + gInventory.deleteObject(notification["payload"]["item_id"].asUUID()); + gInventory.notifyObservers(); + } + else + { + LLNotificationsUtil::add("CannotGiveItem"); + } + break; + + default: // no, cancel, whatever, who cares, not yes. + LLNotificationsUtil::add("TransactionCancelled"); + break; + } + return false; +} + +// static +void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent, + const LLInventoryItem* item, + const LLUUID& im_session_id) +{ + if (!item) return; + std::string name; + LLAgentUI::buildFullname(name); + LLUUID transaction_id; + transaction_id.generate(); + const S32 BUCKET_SIZE = sizeof(U8) + UUID_BYTES; + U8 bucket[BUCKET_SIZE]; + bucket[0] = (U8)item->getType(); + memcpy(&bucket[1], &(item->getUUID().mData), UUID_BYTES); /* Flawfinder: ignore */ + pack_instant_message( + gMessageSystem, + gAgentID, + FALSE, + gAgentSessionID, + to_agent, + name, + item->getName(), + IM_ONLINE, + IM_INVENTORY_OFFERED, + transaction_id, + 0, + LLUUID::null, + gAgent.getPositionAgent(), + NO_TIMESTAMP, + bucket, + BUCKET_SIZE); + gAgent.sendReliableMessage(); + + // VEFFECT: giveInventory + LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); + effectp->setSourceObject(gAgentAvatarp); + effectp->setTargetObject(gObjectList.findObject(to_agent)); + effectp->setDuration(LL_HUD_DUR_SHORT); + effectp->setColor(LLColor4U(gAgent.getEffectColor())); + gFloaterTools->dirty(); + + LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY); + + logInventoryOffer(to_agent, im_session_id); + + // add buddy to recent people list + LLRecentPeople::instance().add(to_agent); +} + +// static +bool LLGiveInventory::handleCopyProtectedCategory(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + LLInventoryCategory* cat = NULL; + switch(option) + { + case 0: // "Yes" + cat = gInventory.getCategory(notification["payload"]["folder_id"].asUUID()); + if (cat) + { + LLGiveInventory::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(), + cat); + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLUncopyableItems remove; + gInventory.collectDescendentsIf (cat->getUUID(), + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + remove); + S32 count = items.count(); + for(S32 i = 0; i < count; ++i) + { + gInventory.deleteObject(items.get(i)->getUUID()); + } + gInventory.notifyObservers(); + } + else + { + LLNotificationsUtil::add("CannotGiveCategory"); + } + break; + + default: // no, cancel, whatever, who cares, not yes. + LLNotificationsUtil::add("TransactionCancelled"); + break; + } + return false; +} + +// static +void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent, + const LLInventoryCategory* cat, + const LLUUID& im_session_id) + +{ + if (!cat) return; + llinfos << "LLGiveInventory::commitGiveInventoryCategory() - " + << cat->getUUID() << llendl; + + // add buddy to recent people list + LLRecentPeople::instance().add(to_agent); + + // Test out how many items are being given. + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLGiveable giveable; + gInventory.collectDescendentsIf (cat->getUUID(), + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + giveable); + + // MAX ITEMS is based on (sizeof(uuid)+2) * count must be < + // MTUBYTES or 18 * count < 1200 => count < 1200/18 => + // 66. I've cut it down a bit from there to give some pad. + S32 count = items.count() + cats.count(); + if (count > MAX_ITEMS) + { + LLNotificationsUtil::add("TooManyItems"); + return; + } + else if (count == 0) + { + LLNotificationsUtil::add("NoItems"); + return; + } + else + { + std::string name; + LLAgentUI::buildFullname(name); + LLUUID transaction_id; + transaction_id.generate(); + S32 bucket_size = (sizeof(U8) + UUID_BYTES) * (count + 1); + U8* bucket = new U8[bucket_size]; + U8* pos = bucket; + U8 type = (U8)cat->getType(); + memcpy(pos, &type, sizeof(U8)); /* Flawfinder: ignore */ + pos += sizeof(U8); + memcpy(pos, &(cat->getUUID()), UUID_BYTES); /* Flawfinder: ignore */ + pos += UUID_BYTES; + S32 i; + count = cats.count(); + for(i = 0; i < count; ++i) + { + memcpy(pos, &type, sizeof(U8)); /* Flawfinder: ignore */ + pos += sizeof(U8); + memcpy(pos, &(cats.get(i)->getUUID()), UUID_BYTES); /* Flawfinder: ignore */ + pos += UUID_BYTES; + } + count = items.count(); + for(i = 0; i < count; ++i) + { + type = (U8)items.get(i)->getType(); + memcpy(pos, &type, sizeof(U8)); /* Flawfinder: ignore */ + pos += sizeof(U8); + memcpy(pos, &(items.get(i)->getUUID()), UUID_BYTES); /* Flawfinder: ignore */ + pos += UUID_BYTES; + } + pack_instant_message( + gMessageSystem, + gAgent.getID(), + FALSE, + gAgent.getSessionID(), + to_agent, + name, + cat->getName(), + IM_ONLINE, + IM_INVENTORY_OFFERED, + transaction_id, + 0, + LLUUID::null, + gAgent.getPositionAgent(), + NO_TIMESTAMP, + bucket, + bucket_size); + gAgent.sendReliableMessage(); + delete[] bucket; + + // VEFFECT: giveInventoryCategory + LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); + effectp->setSourceObject(gAgentAvatarp); + effectp->setTargetObject(gObjectList.findObject(to_agent)); + effectp->setDuration(LL_HUD_DUR_SHORT); + effectp->setColor(LLColor4U(gAgent.getEffectColor())); + gFloaterTools->dirty(); + + LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY); + + logInventoryOffer(to_agent, im_session_id); + } +} + +// EOF diff --git a/indra/newview/llgiveinventory.h b/indra/newview/llgiveinventory.h new file mode 100644 index 0000000000..e589a0cc69 --- /dev/null +++ b/indra/newview/llgiveinventory.h @@ -0,0 +1,99 @@ +/** + * @file llgiveinventory.cpp + * @brief LLGiveInventory class declaration + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLGIVEINVENTORY_H +#define LL_LLGIVEINVENTORY_H + +class LLInventoryItem; +class LLInventoryCategory; + +/** + * Class represented give inventory related actions. + * + * It has only static methods and is not intended to be instantiated for now. + */ +class LLGiveInventory +{ +public: + /** + * Checks if inventory item you are attempting to transfer to a resident can be given. + * + * @return true if you can give, otherwise false. + */ + static bool isInventoryGiveAcceptable(const LLInventoryItem* item); + + /** + * Checks if inventory item you are attempting to transfer to a group can be given. + * + * @return true if you can give, otherwise false. + */ + static bool isInventoryGroupGiveAcceptable(const LLInventoryItem* item); + + /** + * Gives passed inventory item to specified avatar in specified session. + */ + static void doGiveInventoryItem(const LLUUID& to_agent, + const LLInventoryItem* item, + const LLUUID& im_session_id = LLUUID::null); + + /** + * Gives passed inventory category to specified avatar in specified session. + */ + static void doGiveInventoryCategory(const LLUUID& to_agent, + const LLInventoryCategory* item, + const LLUUID &session_id = LLUUID::null); + +private: + // this class is not intended to be instantiated. + LLGiveInventory(); + + /** + * logs "Inventory item offered" to IM + */ + static void logInventoryOffer(const LLUUID& to_agent, + const LLUUID &im_session_id = LLUUID::null); + + // give inventory item functionality + static bool handleCopyProtectedItem(const LLSD& notification, const LLSD& response); + static void commitGiveInventoryItem(const LLUUID& to_agent, + const LLInventoryItem* item, + const LLUUID &im_session_id = LLUUID::null); + + // give inventory category functionality + static bool handleCopyProtectedCategory(const LLSD& notification, const LLSD& response); + static void commitGiveInventoryCategory(const LLUUID& to_agent, + const LLInventoryCategory* cat, + const LLUUID &im_session_id = LLUUID::null); + +}; + +#endif // LL_LLGIVEINVENTORY_H diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index ab7eeae3e8..2d27c89074 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -47,6 +47,7 @@ #include "llfloaterworldmap.h" #include "llfriendcard.h" #include "llgesturemgr.h" +#include "llgiveinventory.h" #include "llimfloater.h" #include "llimview.h" #include "llinventoryclipboard.h" @@ -1016,11 +1017,7 @@ BOOL LLInvFVBridge::canShare() const { if (!LLInventoryCollectFunctor::itemTransferCommonlyAllowed(item)) return FALSE; - if (!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) - return FALSE; - if (!item->getPermissions().allowCopyBy(gAgent.getID())) - return FALSE; - return TRUE; + return (BOOL)LLGiveInventory::isInventoryGiveAcceptable(item); } // All categories can be given. @@ -3755,7 +3752,7 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop, rv = TRUE; if(drop) { - LLToolDragAndDrop::giveInventory(item->getCreatorUUID(), + LLGiveInventory::doGiveInventoryItem(item->getCreatorUUID(), (LLInventoryItem*)cargo_data); } } @@ -3776,7 +3773,7 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop, rv = TRUE; if(drop) { - LLToolDragAndDrop::giveInventoryCategory( + LLGiveInventory::doGiveInventoryCategory( item->getCreatorUUID(), inv_cat); } diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp index f94515d242..1c3eb547bb 100644 --- a/indra/newview/llinventoryitemslist.cpp +++ b/indra/newview/llinventoryitemslist.cpp @@ -336,7 +336,9 @@ LLInventoryItemsList::LLInventoryItemsList(const LLInventoryItemsList::Params& p // virtual LLInventoryItemsList::~LLInventoryItemsList() -{} +{ + gIdleCallbacks.deleteFunction(idle, this); +} void LLInventoryItemsList::refreshList(const LLInventoryModel::item_array_t item_array) { diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 362d8581f3..42ff514f09 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -44,7 +44,6 @@ #include "llfloaterinventory.h" #include "llagent.h" #include "llagentui.h" -#include "lltooldraganddrop.h" #include "lllineeditor.h" #include "lltexteditor.h" @@ -60,6 +59,7 @@ #include "llviewerwindow.h" #include "llviewermessage.h" #include "llnotificationsutil.h" +#include "llgiveinventory.h" static LLRegisterPanelClassWrapper<LLPanelGroupNotices> t_panel_group_notices("panel_group_notices"); @@ -162,7 +162,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, { LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data; if(gInventory.getItem(inv_item->getUUID()) - && LLToolDragAndDrop::isInventoryGroupGiveAcceptable(inv_item)) + && LLGiveInventory::isInventoryGroupGiveAcceptable(inv_item)) { // *TODO: get multiple object transfers working *accept = ACCEPT_YES_COPY_SINGLE; diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 4f3f73beca..ceb720908a 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -148,6 +148,8 @@ protected: else { mBaseOutfitId = baseoutfit_id; + mPanel->updateCurrentOutfitName(); + if (baseoutfit_id.isNull()) return; mBaseOutfitLastVersion = getCategoryVersion(mBaseOutfitId); @@ -643,6 +645,13 @@ void LLPanelOutfitEdit::displayCurrentOutfit() setVisible(TRUE); } + updateCurrentOutfitName(); + + update(); +} + +void LLPanelOutfitEdit::updateCurrentOutfitName() +{ std::string current_outfit_name; if (LLAppearanceMgr::getInstance()->getBaseOutfitName(current_outfit_name)) { @@ -652,8 +661,6 @@ void LLPanelOutfitEdit::displayCurrentOutfit() { mCurrentOutfitName->setText(getString("No Outfit")); } - - update(); } //private diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index a08dc653ef..5ebe1e0406 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -104,7 +104,8 @@ public: void onEditWearableClicked(void); void displayCurrentOutfit(); - + void updateCurrentOutfitName(); + void update(); void updateVerbs(); diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 774626f19d..8a8bdd2dba 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -38,7 +38,6 @@ // project headers #include "llagent.h" #include "llagentcamera.h" -#include "llagentui.h" #include "llagentwearables.h" #include "llappearancemgr.h" #include "lldictionary.h" @@ -46,31 +45,26 @@ #include "llfloaterreg.h" #include "llfloatertools.h" #include "llgesturemgr.h" +#include "llgiveinventory.h" #include "llhudmanager.h" #include "llhudeffecttrail.h" -#include "llimview.h" +//#include "llimview.h" #include "llinventorybridge.h" #include "llinventorydefines.h" #include "llinventoryfunctions.h" -#include "llmutelist.h" #include "llpreviewnotecard.h" -#include "llrecentpeople.h" #include "llrootview.h" #include "llselectmgr.h" #include "lltoolmgr.h" #include "lltooltip.h" #include "lltrans.h" #include "llviewerobjectlist.h" +#include "llviewerregion.h" #include "llviewerstats.h" #include "llviewerwindow.h" #include "llvoavatarself.h" #include "llworld.h" -// MAX ITEMS is based on (sizeof(uuid)+2) * count must be < MTUBYTES -// or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a -// bit from there to give some pad. -const S32 MAX_ITEMS = 42; - // syntactic sugar #define callMemberFunction(object,ptrToMember) ((object).*(ptrToMember)) @@ -145,29 +139,6 @@ bool LLDroppableItem::operator()(LLInventoryCategory* cat, return allowed; } -class LLUncopyableItems : public LLInventoryCollectFunctor -{ -public: - LLUncopyableItems() {} - virtual ~LLUncopyableItems() {} - virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); -}; - -bool LLUncopyableItems::operator()(LLInventoryCategory* cat, - LLInventoryItem* item) -{ - bool uncopyable = false; - if (item) - { - if (itemTransferCommonlyAllowed(item) && - !item->getPermissions().allowCopyBy(gAgent.getID())) - { - uncopyable = true; - } - } - return uncopyable; -} - class LLDropCopyableItems : public LLInventoryCollectFunctor { public: @@ -195,43 +166,6 @@ bool LLDropCopyableItems::operator()( return allowed; } -class LLGiveable : public LLInventoryCollectFunctor -{ -public: - LLGiveable() : mCountLosing(0) {} - virtual ~LLGiveable() {} - virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); - - S32 countNoCopy() const { return mCountLosing; } -protected: - S32 mCountLosing; -}; - -bool LLGiveable::operator()(LLInventoryCategory* cat, LLInventoryItem* item) -{ - // All categories can be given. - if (cat) - return true; - - bool allowed = false; - if (item) - { - allowed = itemTransferCommonlyAllowed(item); - if (allowed && - !item->getPermissions().allowOperationBy(PERM_TRANSFER, - gAgent.getID())) - { - allowed = FALSE; - } - if (allowed && - !item->getPermissions().allowCopyBy(gAgent.getID())) - { - ++mCountLosing; - } - } - return allowed; -} - // Starts a fetch on folders and items. This is really not used // as an observer in the traditional sense; we're just using it to // request a fetch and we don't care about when/if the response arrives. @@ -1419,422 +1353,6 @@ void LLToolDragAndDrop::dropInventory(LLViewerObject* hit_obj, gFloaterTools->dirty(); } -void LLToolDragAndDrop::giveInventory(const LLUUID& to_agent, - LLInventoryItem* item, - const LLUUID& im_session_id) - -{ - llinfos << "LLToolDragAndDrop::giveInventory()" << llendl; - if (!isInventoryGiveAcceptable(item)) - { - return; - } - if (item->getPermissions().allowCopyBy(gAgent.getID())) - { - // just give it away. - LLToolDragAndDrop::commitGiveInventoryItem(to_agent, item, im_session_id); - } - else - { - // ask if the agent is sure. - LLSD payload; - payload["agent_id"] = to_agent; - payload["item_id"] = item->getUUID(); - LLNotificationsUtil::add("CannotCopyWarning", LLSD(), payload, - &LLToolDragAndDrop::handleCopyProtectedItem); - } -} -// static -bool LLToolDragAndDrop::handleCopyProtectedItem(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - LLInventoryItem* item = NULL; - switch(option) - { - case 0: // "Yes" - item = gInventory.getItem(notification["payload"]["item_id"].asUUID()); - if (item) - { - LLToolDragAndDrop::commitGiveInventoryItem(notification["payload"]["agent_id"].asUUID(), - item); - // delete it for now - it will be deleted on the server - // quickly enough. - gInventory.deleteObject(notification["payload"]["item_id"].asUUID()); - gInventory.notifyObservers(); - } - else - { - LLNotificationsUtil::add("CannotGiveItem"); - } - break; - - default: // no, cancel, whatever, who cares, not yes. - LLNotificationsUtil::add("TransactionCancelled"); - break; - } - return false; -} - -// static -void LLToolDragAndDrop::commitGiveInventoryItem(const LLUUID& to_agent, - LLInventoryItem* item, - const LLUUID& im_session_id) -{ - if (!item) return; - std::string name; - LLAgentUI::buildFullname(name); - LLUUID transaction_id; - transaction_id.generate(); - const S32 BUCKET_SIZE = sizeof(U8) + UUID_BYTES; - U8 bucket[BUCKET_SIZE]; - bucket[0] = (U8)item->getType(); - memcpy(&bucket[1], &(item->getUUID().mData), UUID_BYTES); /* Flawfinder: ignore */ - pack_instant_message( - gMessageSystem, - gAgent.getID(), - FALSE, - gAgent.getSessionID(), - to_agent, - name, - item->getName(), - IM_ONLINE, - IM_INVENTORY_OFFERED, - transaction_id, - 0, - LLUUID::null, - gAgent.getPositionAgent(), - NO_TIMESTAMP, - bucket, - BUCKET_SIZE); - gAgent.sendReliableMessage(); - - // VEFFECT: giveInventory - LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); - effectp->setSourceObject(gAgentAvatarp); - effectp->setTargetObject(gObjectList.findObject(to_agent)); - effectp->setDuration(LL_HUD_DUR_SHORT); - effectp->setColor(LLColor4U(gAgent.getEffectColor())); - gFloaterTools->dirty(); - - LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY); - - logInventoryOffer(to_agent, im_session_id); - - // add buddy to recent people list - LLRecentPeople::instance().add(to_agent); -} - -//static -void LLToolDragAndDrop::logInventoryOffer(const LLUUID& to_agent, const LLUUID &im_session_id) -{ - // compute id of possible IM session with agent that has "to_agent" id - LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, to_agent); - // If this item was given by drag-and-drop into an IM panel, log this action in the IM panel chat. - if (im_session_id.notNull()) - { - LLSD args; - gIMMgr->addSystemMessage(im_session_id, "inventory_item_offered", args); - } - // If this item was given by drag-and-drop on avatar while IM panel was open, log this action in the IM panel chat. - else if (LLIMModel::getInstance()->findIMSession(session_id)) - { - LLSD args; - gIMMgr->addSystemMessage(session_id, "inventory_item_offered", args); - } - // If this item was given by drag-and-drop on avatar while IM panel wasn't open, log this action to IM history. - else - { - std::string full_name; - if (gCacheName->getFullName(to_agent, full_name)) - { - LLIMModel::instance().logToFile(full_name, LLTrans::getString("SECOND_LIFE"), im_session_id, LLTrans::getString("inventory_item_offered-im")); - } - } -} - -void LLToolDragAndDrop::giveInventoryCategory(const LLUUID& to_agent, - LLInventoryCategory* cat, - const LLUUID& im_session_id) - -{ - if (!cat) return; - llinfos << "LLToolDragAndDrop::giveInventoryCategory() - " - << cat->getUUID() << llendl; - - if (!isAgentAvatarValid()) return; - - // Test out how many items are being given. - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLGiveable giveable; - gInventory.collectDescendentsIf (cat->getUUID(), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - giveable); - S32 count = cats.count(); - bool complete = true; - for(S32 i = 0; i < count; ++i) - { - if (!gInventory.isCategoryComplete(cats.get(i)->getUUID())) - { - complete = false; - break; - } - } - if (!complete) - { - LLNotificationsUtil::add("IncompleteInventory"); - return; - } - count = items.count() + cats.count(); - if (count > MAX_ITEMS) - { - LLNotificationsUtil::add("TooManyItems"); - return; - } - else if (count == 0) - { - LLNotificationsUtil::add("NoItems"); - return; - } - else - { - if (0 == giveable.countNoCopy()) - { - LLToolDragAndDrop::commitGiveInventoryCategory(to_agent, cat, im_session_id); - } - else - { - LLSD args; - args["COUNT"] = llformat("%d",giveable.countNoCopy()); - LLSD payload; - payload["agent_id"] = to_agent; - payload["folder_id"] = cat->getUUID(); - LLNotificationsUtil::add("CannotCopyCountItems", args, payload, &LLToolDragAndDrop::handleCopyProtectedCategory); - } - } -} - - -// static -bool LLToolDragAndDrop::handleCopyProtectedCategory(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - LLInventoryCategory* cat = NULL; - switch(option) - { - case 0: // "Yes" - cat = gInventory.getCategory(notification["payload"]["folder_id"].asUUID()); - if (cat) - { - LLToolDragAndDrop::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(), - cat); - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLUncopyableItems remove; - gInventory.collectDescendentsIf (cat->getUUID(), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - remove); - S32 count = items.count(); - for(S32 i = 0; i < count; ++i) - { - gInventory.deleteObject(items.get(i)->getUUID()); - } - gInventory.notifyObservers(); - } - else - { - LLNotificationsUtil::add("CannotGiveCategory"); - } - break; - - default: // no, cancel, whatever, who cares, not yes. - LLNotificationsUtil::add("TransactionCancelled"); - break; - } - return false; -} - -// static -void LLToolDragAndDrop::commitGiveInventoryCategory(const LLUUID& to_agent, - LLInventoryCategory* cat, - const LLUUID& im_session_id) - -{ - if (!cat) return; - llinfos << "LLToolDragAndDrop::commitGiveInventoryCategory() - " - << cat->getUUID() << llendl; - - // add buddy to recent people list - LLRecentPeople::instance().add(to_agent); - - // Test out how many items are being given. - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLGiveable giveable; - gInventory.collectDescendentsIf (cat->getUUID(), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - giveable); - - // MAX ITEMS is based on (sizeof(uuid)+2) * count must be < - // MTUBYTES or 18 * count < 1200 => count < 1200/18 => - // 66. I've cut it down a bit from there to give some pad. - S32 count = items.count() + cats.count(); - if (count > MAX_ITEMS) - { - LLNotificationsUtil::add("TooManyItems"); - return; - } - else if (count == 0) - { - LLNotificationsUtil::add("NoItems"); - return; - } - else - { - std::string name; - LLAgentUI::buildFullname(name); - LLUUID transaction_id; - transaction_id.generate(); - S32 bucket_size = (sizeof(U8) + UUID_BYTES) * (count + 1); - U8* bucket = new U8[bucket_size]; - U8* pos = bucket; - U8 type = (U8)cat->getType(); - memcpy(pos, &type, sizeof(U8)); /* Flawfinder: ignore */ - pos += sizeof(U8); - memcpy(pos, &(cat->getUUID()), UUID_BYTES); /* Flawfinder: ignore */ - pos += UUID_BYTES; - S32 i; - count = cats.count(); - for(i = 0; i < count; ++i) - { - memcpy(pos, &type, sizeof(U8)); /* Flawfinder: ignore */ - pos += sizeof(U8); - memcpy(pos, &(cats.get(i)->getUUID()), UUID_BYTES); /* Flawfinder: ignore */ - pos += UUID_BYTES; - } - count = items.count(); - for(i = 0; i < count; ++i) - { - type = (U8)items.get(i)->getType(); - memcpy(pos, &type, sizeof(U8)); /* Flawfinder: ignore */ - pos += sizeof(U8); - memcpy(pos, &(items.get(i)->getUUID()), UUID_BYTES); /* Flawfinder: ignore */ - pos += UUID_BYTES; - } - pack_instant_message( - gMessageSystem, - gAgent.getID(), - FALSE, - gAgent.getSessionID(), - to_agent, - name, - cat->getName(), - IM_ONLINE, - IM_INVENTORY_OFFERED, - transaction_id, - 0, - LLUUID::null, - gAgent.getPositionAgent(), - NO_TIMESTAMP, - bucket, - bucket_size); - gAgent.sendReliableMessage(); - delete[] bucket; - - // VEFFECT: giveInventoryCategory - LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); - effectp->setSourceObject(gAgentAvatarp); - effectp->setTargetObject(gObjectList.findObject(to_agent)); - effectp->setDuration(LL_HUD_DUR_SHORT); - effectp->setColor(LLColor4U(gAgent.getEffectColor())); - gFloaterTools->dirty(); - - LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY); - - logInventoryOffer(to_agent, im_session_id); - } -} - -// static -BOOL LLToolDragAndDrop::isInventoryGiveAcceptable(LLInventoryItem* item) -{ - if (!item) - { - return FALSE; - } - if (!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) - { - return FALSE; - } - BOOL copyable = FALSE; - if (item->getPermissions().allowCopyBy(gAgent.getID())) copyable = TRUE; - - if (!isAgentAvatarValid()) return FALSE; - - BOOL acceptable = TRUE; - switch(item->getType()) - { - case LLAssetType::AT_OBJECT: - if (gAgentAvatarp->isWearingAttachment(item->getUUID())) - { - acceptable = FALSE; - } - break; - case LLAssetType::AT_BODYPART: - case LLAssetType::AT_CLOTHING: - if (!copyable && gAgentWearables.isWearingItem(item->getUUID())) - { - acceptable = FALSE; - } - break; - default: - break; - } - return acceptable; -} - -// Static -BOOL LLToolDragAndDrop::isInventoryGroupGiveAcceptable(LLInventoryItem* item) -{ - if (!item) - { - return FALSE; - } - - // These permissions are double checked in the simulator in - // LLGroupNoticeInventoryItemFetch::result(). - if (!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) - { - return FALSE; - } - if (!item->getPermissions().allowCopyBy(gAgent.getID())) - { - return FALSE; - } - - if (!isAgentAvatarValid()) return FALSE; - - BOOL acceptable = TRUE; - switch(item->getType()) - { - case LLAssetType::AT_OBJECT: - if (gAgentAvatarp->isWearingAttachment(item->getUUID())) - { - acceptable = FALSE; - } - break; - default: - break; - } - return acceptable; -} - // accessor that looks at permissions, copyability, and names of // inventory items to determine if a drop would be ok. EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LLInventoryItem* item) @@ -1928,13 +1446,13 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_ { LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data; if (gInventory.getItem(inv_item->getUUID()) - && LLToolDragAndDrop::isInventoryGiveAcceptable(inv_item)) + && LLGiveInventory::isInventoryGiveAcceptable(inv_item)) { // *TODO: get multiple object transfers working *accept = ACCEPT_YES_COPY_SINGLE; if (drop) { - LLToolDragAndDrop::giveInventory(dest_agent, inv_item, session_id); + LLGiveInventory::doGiveInventoryItem(dest_agent, inv_item, session_id); } } else @@ -1956,7 +1474,7 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_ *accept = ACCEPT_YES_COPY_SINGLE; if (drop) { - LLToolDragAndDrop::giveInventoryCategory(dest_agent, inv_cat, session_id); + LLGiveInventory::doGiveInventoryCategory(dest_agent, inv_cat, session_id); } } else @@ -2633,7 +2151,7 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventoryObject( { if (drop) { - giveInventory(obj->getID(), item ); + LLGiveInventory::doGiveInventoryItem(obj->getID(), item ); } // *TODO: deal with all the issues surrounding multi-object // inventory transfers. @@ -2653,13 +2171,13 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventory( LLViewerInventoryCategory* cat; locateInventory(item, cat); if (!item || !item->isFinished()) return ACCEPT_NO; - if (!isInventoryGiveAcceptable(item)) + if (!LLGiveInventory::isInventoryGiveAcceptable(item)) { return ACCEPT_NO; } if (drop && obj) { - giveInventory(obj->getID(), item); + LLGiveInventory::doGiveInventoryItem(obj->getID(), item); } // *TODO: deal with all the issues surrounding multi-object // inventory transfers. @@ -2676,7 +2194,7 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventoryCategory( LLViewerInventoryCategory* cat; locateInventory(item, cat); if (!cat) return ACCEPT_NO; - giveInventoryCategory(obj->getID(), cat); + LLGiveInventory::doGiveInventoryCategory(obj->getID(), cat); } // *TODO: deal with all the issues surrounding multi-object // inventory transfers. diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 85d003e5fc..18334b5ee1 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -214,32 +214,10 @@ protected: LLToolDragAndDrop::ESource source, const LLUUID& src_id); - - // give inventory item functionality - static bool handleCopyProtectedItem(const LLSD& notification, const LLSD& response); - static void commitGiveInventoryItem(const LLUUID& to_agent, - LLInventoryItem* item, - const LLUUID &im_session_id = LLUUID::null); - - // give inventory category functionality - static bool handleCopyProtectedCategory(const LLSD& notification, const LLSD& response); - static void commitGiveInventoryCategory(const LLUUID& to_agent, - LLInventoryCategory* cat, - const LLUUID &im_session_id = LLUUID::null); - - // log "Inventory item offered" to IM - static void logInventoryOffer(const LLUUID& to_agent, - const LLUUID &im_session_id = LLUUID::null); - public: // helper functions static BOOL isInventoryDropAcceptable(LLViewerObject* obj, LLInventoryItem* item) { return (ACCEPT_YES_COPY_SINGLE <= willObjectAcceptInventory(obj, item)); } - // This simple helper function assumes you are attempting to - // transfer item. returns true if you can give, otherwise false. - static BOOL isInventoryGiveAcceptable(LLInventoryItem* item); - static BOOL isInventoryGroupGiveAcceptable(LLInventoryItem* item); - BOOL dadUpdateInventory(LLViewerObject* obj, BOOL drop); BOOL dadUpdateInventoryCategory(LLViewerObject* obj, BOOL drop); @@ -265,13 +243,6 @@ public: ESource source, const LLUUID& src_id); - static void giveInventory(const LLUUID& to_agent, - LLInventoryItem* item, - const LLUUID &session_id = LLUUID::null); - static void giveInventoryCategory(const LLUUID& to_agent, - LLInventoryCategory* item, - const LLUUID &session_id = LLUUID::null); - static bool handleGiveDragAndDrop(LLUUID agent, LLUUID session, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, diff --git a/indra/newview/skins/default/xui/da/floater_tools.xml b/indra/newview/skins/default/xui/da/floater_tools.xml index a39a7e8698..b501722e92 100644 --- a/indra/newview/skins/default/xui/da/floater_tools.xml +++ b/indra/newview/skins/default/xui/da/floater_tools.xml @@ -67,7 +67,10 @@ <text name="RenderingCost" tool_tip="Hvis beregnede rendering omkostninger for dette objekt"> þ: [COUNT] </text> - <check_box label="Stræk begge sider" name="checkbox uniform"/> + <check_box name="checkbox uniform"/> + <text name="checkbox uniform label"> + Stræk begge sider + </text> <check_box initial_value="true" label="Stræk teksturer" name="checkbox stretch textures"/> <check_box initial_value="true" label="Benyt gitter" name="checkbox snap to grid"/> <combo_box name="combobox grid mode" tool_tip="Vælg hvilken type lineal der skal bruges til positionering af objekt"> diff --git a/indra/newview/skins/default/xui/de/floater_tools.xml b/indra/newview/skins/default/xui/de/floater_tools.xml index bb28f1b33f..c5c11faf93 100644 --- a/indra/newview/skins/default/xui/de/floater_tools.xml +++ b/indra/newview/skins/default/xui/de/floater_tools.xml @@ -67,7 +67,10 @@ <text name="RenderingCost" tool_tip="Zeigt die errechneten Wiedergabekosten für dieses Objekt"> þ: [COUNT] </text> - <check_box label="Beide Seiten dehnen" name="checkbox uniform"/> + <check_box name="checkbox uniform"/> + <text name="checkbox uniform label"> + Beide Seiten dehnen + </text> <check_box initial_value="true" label="Texturen dehnen" name="checkbox stretch textures"/> <check_box initial_value="true" label="An Raster ausrichten" name="checkbox snap to grid" top_pad="10"/> <combo_box name="combobox grid mode" tool_tip="Wählen Sie ein Rasterlineal zum Positionieren des Objekts aus."> diff --git a/indra/newview/skins/default/xui/en/floater_region_info.xml b/indra/newview/skins/default/xui/en/floater_region_info.xml index 262bcd07a0..32fb6f97e7 100644 --- a/indra/newview/skins/default/xui/en/floater_region_info.xml +++ b/indra/newview/skins/default/xui/en/floater_region_info.xml @@ -7,7 +7,7 @@ name="regioninfo" save_rect="true" title="REGION/ESTATE" - width="480"> + width="530"> <tab_container bottom="555" follows="left|right|top|bottom" diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index c3c63cec37..efc1a66d95 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -220,8 +220,8 @@ </radio_group> <radio_group follows="left|top" - left="10" - top="54" + left="5" + top="59" height="70" layout="topleft" name="edit_radio_group"> @@ -254,7 +254,8 @@ control_name="EditLinkedParts" label="Edit linked" layout="topleft" - name="checkbox edit linked parts" > + name="checkbox edit linked parts" + top_pad="0"> <check_box.commit_callback function="BuildTool.selectComponent"/> </check_box> @@ -274,20 +275,31 @@ <check_box control_name="ScaleUniform" height="19" - label="Stretch Both Sides" + label="" layout="topleft" left="143" name="checkbox uniform" top="50" - width="134" /> + width="20" /> + <text + height="19" + label="Stretch Both Sides" + left="163" + name="checkbox uniform label" + top="55" + width="120" + wrap="true"> + Stretch Both Sides + </text> <check_box control_name="ScaleStretchTextures" height="19" initial_value="true" label="Stretch Textures" layout="topleft" + left="143" name="checkbox stretch textures" - top_pad="0" + top_pad="7" width="134" /> <check_box control_name="SnapEnabled" @@ -295,7 +307,7 @@ initial_value="true" label="Snap to grid" layout="topleft" - top_pad="7" + top_pad="0" name="checkbox snap to grid" width="134" /> <combo_box @@ -304,6 +316,7 @@ follows="left|top" name="combobox grid mode" tool_tip="Choose the type of grid ruler for positioning the object" + top_pad="0" width="108"> <combo_box.item label="World grid" @@ -2330,7 +2343,7 @@ even though the user gets a free copy. height="19" label="Full Bright" layout="topleft" - left_delta="0" + left_delta="-5" name="checkbox fullbright" top_pad="4" width="81" /> diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml index 40fcc1d76c..71f740590b 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml @@ -233,7 +233,7 @@ left="0" </panel> <panel follows="all" - height="400" + height="408" layout="topleft" left="0" name="edit_subpanel_container" @@ -244,7 +244,7 @@ left="0" <panel filename="panel_edit_shape.xml" follows="all" - height="400" + height="408" layout="topleft" left="0" name="edit_shape_panel" @@ -254,7 +254,7 @@ left="0" <panel filename="panel_edit_skin.xml" follows="all" - height="392" + height="400" layout="topleft" left="0" name="edit_skin_panel" @@ -264,7 +264,7 @@ left="0" <panel filename="panel_edit_hair.xml" follows="all" - height="392" + height="400" layout="topleft" left="0" name="edit_hair_panel" @@ -274,7 +274,7 @@ left="0" <panel filename="panel_edit_eyes.xml" follows="all" - height="392" + height="400" layout="topleft" left="0" name="edit_eyes_panel" @@ -284,7 +284,7 @@ left="0" <panel filename="panel_edit_shirt.xml" follows="all" - height="392" + height="400" layout="topleft" left="0" name="edit_shirt_panel" @@ -294,7 +294,7 @@ left="0" <panel filename="panel_edit_pants.xml" follows="all" - height="392" + height="400" layout="topleft" left="0" name="edit_pants_panel" @@ -304,7 +304,7 @@ left="0" <panel filename="panel_edit_shoes.xml" follows="all" - height="392" + height="400" layout="topleft" left="0" name="edit_shoes_panel" @@ -314,7 +314,7 @@ left="0" <panel filename="panel_edit_socks.xml" follows="all" - height="392" + height="400" layout="topleft" left="0" name="edit_socks_panel" @@ -324,7 +324,7 @@ left="0" <panel filename="panel_edit_jacket.xml" follows="all" - height="392" + height="400" layout="topleft" left="0" name="edit_jacket_panel" @@ -334,7 +334,7 @@ left="0" <panel filename="panel_edit_skirt.xml" follows="all" - height="392" + height="400" layout="topleft" left="0" name="edit_skirt_panel" @@ -344,7 +344,7 @@ left="0" <panel filename="panel_edit_gloves.xml" follows="all" - height="392" + height="400" layout="topleft" left="0" name="edit_gloves_panel" @@ -354,7 +354,7 @@ left="0" <panel filename="panel_edit_undershirt.xml" follows="all" - height="392" + height="400" layout="topleft" left="0" name="edit_undershirt_panel" @@ -364,7 +364,7 @@ left="0" <panel filename="panel_edit_underpants.xml" follows="all" - height="392" + height="400" layout="topleft" left="0" name="edit_underpants_panel" @@ -374,7 +374,7 @@ left="0" <panel filename="panel_edit_alpha.xml" follows="all" - height="392" + height="400" layout="topleft" left="0" name="edit_alpha_panel" @@ -384,7 +384,7 @@ left="0" <panel filename="panel_edit_tattoo.xml" follows="all" - height="392" + height="400" layout="topleft" left="0" name="edit_tattoo_panel" @@ -393,58 +393,71 @@ left="0" width="333" /> </panel> <panel - follows="left|right|bottom" - height="38" + follows="bottom|left|right" + height="25" label="gear_buttom_panel" - layout="bottom|left|right" + layout="topleft" left="0" - bottom="25" name="gear_buttom_panel" + top_pad="0" width="333"> <button follows="bottom|left" tool_tip="Options" - height="18" + height="25" + image_hover_unselected="Toolbar_Left_Over" image_disabled="OptionsMenu_Disabled" - image_selected="OptionsMenu_Press" - image_unselected="OptionsMenu_Off" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Left_Selected" + image_unselected="Toolbar_Left_Off" layout="topleft" left="10" name="friends_viewsort_btn" - top="10" - width="18" /> + top="0" + width="31" /> <button follows="bottom|left" - height="18" - image_selected="AddItem_Press" - image_unselected="AddItem_Off" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="AddItem_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" image_disabled="AddItem_Disabled" layout="topleft" - left_pad="10" + left_pad="1" name="add_btn" tool_tip="TODO" - width="18" /> + width="31" /> + <icon + follows="bottom|left|right" + height="25" + image_name="Toolbar_Middle_Off" + layout="topleft" + left_pad="1" + name="dummy_right_icon" + width="218" > + </icon> <button - follows="bottom|left" - height="18" - image_selected="TrashItem_Press" - image_unselected="TrashItem_Off" + follows="bottom|right" + height="25" + image_hover_unselected="Toolbar_Right_Over" + image_overlay="TrashItem_Off" + image_selected="Toolbar_Right_Selected" + image_unselected="Toolbar_Right_Off" image_disabled="TrashItem_Disabled" layout="topleft" - left_pad="10" - right="-10" + left_pad="1" name="del_btn" tool_tip="TODO" - top_delta="0" - width="18" /> + width="31" /> </panel> <panel follows="bottom|left|right" - height="25" - layout="bottom|left|right" - left="0" + height="23" + layout="topleft" + left="2" name="button_panel" - bottom="5" + top_pad="6" width="333" > <button follows="bottomleft" @@ -462,6 +475,6 @@ left="0" label="Revert" left_pad="7" name="revert_button" - width="153" /> + width="152" /> </panel> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index 454a808f02..b473a7a282 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -310,13 +310,13 @@ allow_multi_select="true" border="false" follows="left|top|right|bottom" - height="130" + height="140" layout="topleft" left="0" mouse_opaque="false" name="inventory_items" top_pad="5" - width="311" + width="310" visible="false"/> <panel name="filtered_wearables_panel" @@ -325,7 +325,7 @@ layout="topleft" follows="left|top|right|bottom" border="false" - height="130" + height="140" left="0" mouse_opaque="false" width="311" @@ -336,8 +336,8 @@ allow_select="true" layout="topleft" follows="all" - width="311" - height="130" + width="310" + height="140" left="0" top="0"/> </panel> @@ -354,7 +354,7 @@ left="0" name="add_wearables_button_bar" top_pad="0" - width="300"> + width="313"> <button follows="bottom|left" height="25" @@ -406,6 +406,15 @@ name="add_to_outfit_btn" top="1" width="31" /> + <icon + follows="bottom|left|right" + height="25" + image_name="Toolbar_Right_Off" + layout="topleft" + left_pad="1" + name="dummy_right_icon" + width="184" > + </icon> </panel> </layout_panel> </layout_stack> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml index 0129d97616..40a644657a 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml @@ -174,9 +174,10 @@ Automatic position for: label="Opacity" layout="topleft" left="80" - label_width="60" + label_width="156" name="bubble_chat_opacity" - width="200" /> + top_pad = "10" + width="347" /> <color_swatch can_apply_immediately="true" color="0 0 0 1" @@ -184,7 +185,7 @@ Automatic position for: follows="left|top" height="50" layout="topleft" - left_pad="10" + left_pad="30" top="190" name="background" tool_tip="Choose color for bubble chat" @@ -202,10 +203,10 @@ Automatic position for: follows="left|top" height="12" layout="topleft" - left="30" + left="80" name="UI Size:" - top_pad="5" - width="300"> + top_pad="25" + width="160"> UI size </text> <slider @@ -216,7 +217,7 @@ Automatic position for: increment="0.025" initial_value="1" layout="topleft" - left_delta="52" + left_pad="0" max_val="1.4" min_val="0.75" name="ui_scale_slider" @@ -314,7 +315,7 @@ Automatic position for: label="Other Devices" left="30" name="joystick_setup_button" - top_pad="12" + top="27" width="155"> <button.commit_callback function="Floater.Show" diff --git a/indra/newview/skins/default/xui/es/floater_tools.xml b/indra/newview/skins/default/xui/es/floater_tools.xml index 59f953c239..5dc527c29a 100644 --- a/indra/newview/skins/default/xui/es/floater_tools.xml +++ b/indra/newview/skins/default/xui/es/floater_tools.xml @@ -67,7 +67,10 @@ <text name="RenderingCost" tool_tip="Muestra cuánto se calcula que cuesta renderizar este objeto"> þ: [COUNT] </text> - <check_box label="Estirar ambos lados" name="checkbox uniform"/> + <check_box name="checkbox uniform"/> + <text name="checkbox uniform label"> + Estirar ambos lados + </text> <check_box initial_value="true" label="Estirar las texturas" name="checkbox stretch textures"/> <check_box initial_value="true" label="Usar la cuadrícula" name="checkbox snap to grid"/> <combo_box name="combobox grid mode" tool_tip="Elige qué cuadricula usar para posicionar el objeto" width="82"> diff --git a/indra/newview/skins/default/xui/fr/floater_tools.xml b/indra/newview/skins/default/xui/fr/floater_tools.xml index 16d276f8c2..cd86e77eb5 100644 --- a/indra/newview/skins/default/xui/fr/floater_tools.xml +++ b/indra/newview/skins/default/xui/fr/floater_tools.xml @@ -67,7 +67,10 @@ <text name="RenderingCost" tool_tip="Affiche le coût du rendu calculé pour cet objet"> þ : [COUNT] </text> - <check_box label="Étirer les deux côtés" name="checkbox uniform"/> + <check_box name="checkbox uniform"/> + <text name="checkbox uniform label"> + Étirer les deux côtés + </text> <check_box initial_value="true" label="Étirer les textures" name="checkbox stretch textures"/> <check_box initial_value="true" label="Fixer sur la grille" name="checkbox snap to grid"/> <combo_box name="combobox grid mode" tool_tip="Choisissez le type d'axe de grille pour le positionnement de l'objet"> diff --git a/indra/newview/skins/default/xui/it/floater_tools.xml b/indra/newview/skins/default/xui/it/floater_tools.xml index cd16246f0f..04d61b97ff 100644 --- a/indra/newview/skins/default/xui/it/floater_tools.xml +++ b/indra/newview/skins/default/xui/it/floater_tools.xml @@ -67,7 +67,10 @@ <text name="RenderingCost" tool_tip="Mostra il costo di rendering calcolato per questo oggetto"> þ: [COUNT] </text> - <check_box label="Ridimens. simmetricamente" name="checkbox uniform"/> + <check_box name="checkbox uniform"/> + <text name="checkbox uniform label"> + Ridimens. simmetricamente + </text> <check_box initial_value="true" label="Ridimensiona le texture" name="checkbox stretch textures"/> <check_box initial_value="true" label="Posiziona nella griglia" name="checkbox snap to grid"/> <combo_box name="combobox grid mode" tool_tip="Scegli il tipo di righello per posizionare l'oggetto"> diff --git a/indra/newview/skins/default/xui/ja/floater_tools.xml b/indra/newview/skins/default/xui/ja/floater_tools.xml index a8261a7493..a7e687abeb 100644 --- a/indra/newview/skins/default/xui/ja/floater_tools.xml +++ b/indra/newview/skins/default/xui/ja/floater_tools.xml @@ -67,7 +67,10 @@ <text name="RenderingCost" tool_tip="このオブジェクトにかかるレンダリングコストを表示"> þ: [COUNT] </text> - <check_box label="両側を引伸ばす" left="116" name="checkbox uniform"/> + <check_box left="116" name="checkbox uniform"/> + <text name="checkbox uniform label"> + 両側を引伸ばす + </text> <check_box initial_value="true" label="テクスチャを引伸ばす" name="checkbox stretch textures"/> <check_box initial_value="true" label="グリッドにスナップ" left_delta="27" name="checkbox snap to grid"/> <combo_box left_delta="60" name="combobox grid mode" tool_tip="オブジェクトの配置に使うグリッドルーラを選択します" width="76"> diff --git a/indra/newview/skins/default/xui/nl/floater_tools.xml b/indra/newview/skins/default/xui/nl/floater_tools.xml index 0f8392428f..212cac0a5b 100644 --- a/indra/newview/skins/default/xui/nl/floater_tools.xml +++ b/indra/newview/skins/default/xui/nl/floater_tools.xml @@ -33,7 +33,10 @@ <combo_box.item name="Reference" label="Referentie" /> </combo_box> - <check_box left="136" label="Beide zijden uitrekken" name="checkbox uniform"/> + <check_box left="136" name="checkbox uniform"/> + <text name="checkbox uniform label"> + Beide zijden uitrekken + </text> <check_box left="136" label="Texturen uitrekken" name="checkbox stretch textures"/> <check_box left="136" label="Gebruik grid" name="checkbox snap to grid"/> <button label="Opties..." label_selected="Opties..." name="Options..." height="18" bottom_delta="-15"/> diff --git a/indra/newview/skins/default/xui/pl/floater_tools.xml b/indra/newview/skins/default/xui/pl/floater_tools.xml index 5bc3811ef6..5b4f99e9d1 100644 --- a/indra/newview/skins/default/xui/pl/floater_tools.xml +++ b/indra/newview/skins/default/xui/pl/floater_tools.xml @@ -67,7 +67,10 @@ <text name="RenderingCost" tool_tip="Pokazuje koszt renderowania tego obiektu"> þ: [COUNT] </text> - <check_box label="Rozciągnij 2 Strony" name="checkbox uniform"/> + <check_box name="checkbox uniform"/> + <text name="checkbox uniform label"> + Rozciągnij 2 Strony + </text> <check_box initial_value="true" label="Rozciągnij Teksturę" name="checkbox stretch textures"/> <check_box initial_value="true" label="Użyj siatki" name="checkbox snap to grid"/> <combo_box name="combobox grid mode" tool_tip="Wybierz rodzaj linijki siatki dla pozycjonowania obiektu"> diff --git a/indra/newview/skins/default/xui/pt/floater_tools.xml b/indra/newview/skins/default/xui/pt/floater_tools.xml index 3068880599..74b45f1d1e 100644 --- a/indra/newview/skins/default/xui/pt/floater_tools.xml +++ b/indra/newview/skins/default/xui/pt/floater_tools.xml @@ -67,7 +67,10 @@ <text name="RenderingCost" tool_tip="Mostra o cálculo do custo de renderização do objeto"> þ: [COUNT] </text> - <check_box label="Esticar ambos os lados" name="checkbox uniform"/> + <check_box name="checkbox uniform"/> + <text name="checkbox uniform label"> + Esticar ambos os lados + </text> <check_box initial_value="true" label="Esticar texturas" name="checkbox stretch textures"/> <check_box initial_value="true" label="Mostrar na grade" name="checkbox snap to grid"/> <combo_box name="combobox grid mode" tool_tip="Selecione o tipo de régua da grade onde o objeto será colocado"> |