diff options
75 files changed, 1143 insertions, 264 deletions
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index 1c664e093b..2cd29448ae 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -77,23 +77,23 @@ LLAssetDictionary::LLAssetDictionary() { // DESCRIPTION TYPE NAME HUMAN NAME CAN LINK? CAN FETCH? CAN KNOW? // |--------------------|-----------|-------------------|-----------|-----------|---------| - addEntry(LLAssetType::AT_TEXTURE, new AssetEntry("TEXTURE", "texture", "texture", false, false, true)); - addEntry(LLAssetType::AT_SOUND, new AssetEntry("SOUND", "sound", "sound", false, true, true)); - addEntry(LLAssetType::AT_CALLINGCARD, new AssetEntry("CALLINGCARD", "callcard", "calling card", false, false, false)); - addEntry(LLAssetType::AT_LANDMARK, new AssetEntry("LANDMARK", "landmark", "landmark", false, true, true)); - addEntry(LLAssetType::AT_SCRIPT, new AssetEntry("SCRIPT", "script", "legacy script", false, false, false)); + addEntry(LLAssetType::AT_TEXTURE, new AssetEntry("TEXTURE", "texture", "texture", true, false, true)); + addEntry(LLAssetType::AT_SOUND, new AssetEntry("SOUND", "sound", "sound", true, true, true)); + addEntry(LLAssetType::AT_CALLINGCARD, new AssetEntry("CALLINGCARD", "callcard", "calling card", true, false, false)); + addEntry(LLAssetType::AT_LANDMARK, new AssetEntry("LANDMARK", "landmark", "landmark", true, true, true)); + addEntry(LLAssetType::AT_SCRIPT, new AssetEntry("SCRIPT", "script", "legacy script", true, false, false)); addEntry(LLAssetType::AT_CLOTHING, new AssetEntry("CLOTHING", "clothing", "clothing", true, true, true)); addEntry(LLAssetType::AT_OBJECT, new AssetEntry("OBJECT", "object", "object", true, false, false)); - addEntry(LLAssetType::AT_NOTECARD, new AssetEntry("NOTECARD", "notecard", "note card", false, false, true)); + addEntry(LLAssetType::AT_NOTECARD, new AssetEntry("NOTECARD", "notecard", "note card", true, false, true)); addEntry(LLAssetType::AT_CATEGORY, new AssetEntry("CATEGORY", "category", "folder", true, false, false)); - addEntry(LLAssetType::AT_LSL_TEXT, new AssetEntry("LSL_TEXT", "lsltext", "lsl2 script", false, false, false)); - addEntry(LLAssetType::AT_LSL_BYTECODE, new AssetEntry("LSL_BYTECODE", "lslbyte", "lsl bytecode", false, false, false)); - addEntry(LLAssetType::AT_TEXTURE_TGA, new AssetEntry("TEXTURE_TGA", "txtr_tga", "tga texture", false, false, false)); + addEntry(LLAssetType::AT_LSL_TEXT, new AssetEntry("LSL_TEXT", "lsltext", "lsl2 script", true, false, false)); + addEntry(LLAssetType::AT_LSL_BYTECODE, new AssetEntry("LSL_BYTECODE", "lslbyte", "lsl bytecode", true, false, false)); + addEntry(LLAssetType::AT_TEXTURE_TGA, new AssetEntry("TEXTURE_TGA", "txtr_tga", "tga texture", true, false, false)); addEntry(LLAssetType::AT_BODYPART, new AssetEntry("BODYPART", "bodypart", "body part", true, true, true)); - addEntry(LLAssetType::AT_SOUND_WAV, new AssetEntry("SOUND_WAV", "snd_wav", "sound", false, false, false)); - addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", false, false, false)); - addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", false, false, false)); - addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", false, true, true)); + addEntry(LLAssetType::AT_SOUND_WAV, new AssetEntry("SOUND_WAV", "snd_wav", "sound", true, false, false)); + addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", true, false, false)); + addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", true, false, false)); + addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", true, true, true)); addEntry(LLAssetType::AT_GESTURE, new AssetEntry("GESTURE", "gesture", "gesture", true, true, true)); addEntry(LLAssetType::AT_SIMSTATE, new AssetEntry("SIMSTATE", "simstate", "simstate", false, false, false)); diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 0874f574c5..aa7c8c789a 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -1338,7 +1338,7 @@ LLImageFormatted::LLImageFormatted(S8 codec) mCodec(codec), mDecoding(0), mDecoded(0), - mDiscardLevel(0) + mDiscardLevel(-1) { mMemType = LLMemType::MTYPE_IMAGEFORMATTED; } diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp index 4ef5df0b28..c050f20a9d 100644 --- a/indra/llinventory/llinventorytype.cpp +++ b/indra/llinventory/llinventorytype.cpp @@ -181,6 +181,10 @@ bool LLInventoryType::cannotRestrictPermissions(LLInventoryType::EType type) bool inventory_and_asset_types_match(LLInventoryType::EType inventory_type, LLAssetType::EType asset_type) { + // Links can be of any inventory type. + if (LLAssetType::lookupIsLinkType(asset_type)) + return true; + const InventoryEntry *entry = LLInventoryDictionary::getInstance()->lookup(inventory_type); if (!entry) return false; diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index e09b511a6e..0c9b325b68 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -160,7 +160,7 @@ void LLPluginClassMedia::idle(void) mPlugin->idle(); } - if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL)) + if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL) || (mPlugin->isBlocked())) { // Can't process a size change at this time } @@ -437,6 +437,12 @@ void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int { if(type == MOUSE_EVENT_MOVE) { + if(!mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked()) + { + // Don't queue up mouse move events that can't be delivered. + return; + } + if((x == mLastMouseX) && (y == mLastMouseY)) { // Don't spam unnecessary mouse move events. diff --git a/indra/llplugin/llpluginmessagepipe.cpp b/indra/llplugin/llpluginmessagepipe.cpp index 1d7ddc5592..e524c88cf8 100644 --- a/indra/llplugin/llpluginmessagepipe.cpp +++ b/indra/llplugin/llpluginmessagepipe.cpp @@ -299,26 +299,23 @@ bool LLPluginMessagePipe::pump(F64 timeout) void LLPluginMessagePipe::processInput(void) { // Look for input delimiter(s) in the input buffer. - int start = 0; int delim; - while((delim = mInput.find(MESSAGE_DELIMITER, start)) != std::string::npos) + while((delim = mInput.find(MESSAGE_DELIMITER)) != std::string::npos) { // Let the owner process this message if (mOwner) { - mOwner->receiveMessageRaw(mInput.substr(start, delim - start)); + // Pull the message out of the input buffer before calling receiveMessageRaw. + // It's now possible for this function to get called recursively (in the case where the plugin makes a blocking request) + // and this guarantees that the messages will get dequeued correctly. + std::string message(mInput, 0, delim); + mInput.erase(0, delim + 1); + mOwner->receiveMessageRaw(message); } else { LL_WARNS("Plugin") << "!mOwner" << LL_ENDL; } - - start = delim + 1; } - - // Remove delivered messages from the input buffer. - if(start != 0) - mInput = mInput.substr(start); - } diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp index ccaf95b36d..2d078cd6ed 100644 --- a/indra/llplugin/llpluginprocesschild.cpp +++ b/indra/llplugin/llpluginprocesschild.cpp @@ -48,6 +48,8 @@ LLPluginProcessChild::LLPluginProcessChild() mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); mSleepTime = PLUGIN_IDLE_SECONDS; // default: send idle messages at 100Hz mCPUElapsed = 0.0f; + mBlockingRequest = false; + mBlockingResponseReceived = false; } LLPluginProcessChild::~LLPluginProcessChild() @@ -226,6 +228,7 @@ void LLPluginProcessChild::idle(void) void LLPluginProcessChild::sleep(F64 seconds) { + deliverQueuedMessages(); if(mMessagePipe) { mMessagePipe->pump(seconds); @@ -238,6 +241,7 @@ void LLPluginProcessChild::sleep(F64 seconds) void LLPluginProcessChild::pump(void) { + deliverQueuedMessages(); if(mMessagePipe) { mMessagePipe->pump(0.0f); @@ -309,15 +313,32 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message) LL_DEBUGS("Plugin") << "Received from parent: " << message << LL_ENDL; + // Decode this message + LLPluginMessage parsed; + parsed.parse(message); + + if(mBlockingRequest) + { + // We're blocking the plugin waiting for a response. + + if(parsed.hasValue("blocking_response")) + { + // This is the message we've been waiting for -- fall through and send it immediately. + mBlockingResponseReceived = true; + } + else + { + // Still waiting. Queue this message and don't process it yet. + mMessageQueue.push(message); + return; + } + } + bool passMessage = true; // FIXME: how should we handle queueing here? { - // Decode this message - LLPluginMessage parsed; - parsed.parse(message); - std::string message_class = parsed.getClass(); if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL) { @@ -425,7 +446,13 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message) void LLPluginProcessChild::receivePluginMessage(const std::string &message) { LL_DEBUGS("Plugin") << "Received from plugin: " << message << LL_ENDL; - + + if(mBlockingRequest) + { + // + LL_ERRS("Plugin") << "Can't send a message while already waiting on a blocking request -- aborting!" << LL_ENDL; + } + // Incoming message from the plugin instance bool passMessage = true; @@ -436,6 +463,12 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message) // Decode this message LLPluginMessage parsed; parsed.parse(message); + + if(parsed.hasValue("blocking_request")) + { + mBlockingRequest = true; + } + std::string message_class = parsed.getClass(); if(message_class == "base") { @@ -494,6 +527,19 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message) LL_DEBUGS("Plugin") << "Passing through to parent: " << message << LL_ENDL; writeMessageRaw(message); } + + while(mBlockingRequest) + { + // The plugin wants to block and wait for a response to this message. + sleep(mSleepTime); // this will pump the message pipe and process messages + + if(mBlockingResponseReceived || mSocketError != APR_SUCCESS || (mMessagePipe == NULL)) + { + // Response has been received, or we've hit an error state. Stop waiting. + mBlockingRequest = false; + mBlockingResponseReceived = false; + } + } } @@ -502,3 +548,15 @@ void LLPluginProcessChild::setState(EState state) LL_DEBUGS("Plugin") << "setting state to " << state << LL_ENDL; mState = state; }; + +void LLPluginProcessChild::deliverQueuedMessages() +{ + if(!mBlockingRequest) + { + while(!mMessageQueue.empty()) + { + receiveMessageRaw(mMessageQueue.front()); + mMessageQueue.pop(); + } + } +} diff --git a/indra/llplugin/llpluginprocesschild.h b/indra/llplugin/llpluginprocesschild.h index 0e5e85406a..1430ad7a5d 100644 --- a/indra/llplugin/llpluginprocesschild.h +++ b/indra/llplugin/llpluginprocesschild.h @@ -106,6 +106,11 @@ private: LLTimer mHeartbeat; F64 mSleepTime; F64 mCPUElapsed; + bool mBlockingRequest; + bool mBlockingResponseReceived; + std::queue<std::string> mMessageQueue; + + void deliverQueuedMessages(); }; diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index 895c858979..e273410a1d 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -54,6 +54,7 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner) mCPUUsage = 0.0; mDisableTimeout = false; mDebug = false; + mBlocked = false; mPluginLaunchTimeout = 60.0f; mPluginLockupTimeout = 15.0f; @@ -479,6 +480,13 @@ void LLPluginProcessParent::setSleepTime(F64 sleep_time, bool force_send) void LLPluginProcessParent::sendMessage(const LLPluginMessage &message) { + if(message.hasValue("blocking_response")) + { + mBlocked = false; + + // reset the heartbeat timer, since there will have been no heartbeats while the plugin was blocked. + mHeartbeat.setTimerExpirySec(mPluginLockupTimeout); + } std::string buffer = message.generate(); LL_DEBUGS("Plugin") << "Sending: " << buffer << LL_ENDL; @@ -501,6 +509,11 @@ void LLPluginProcessParent::receiveMessageRaw(const std::string &message) void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message) { + if(message.hasValue("blocking_request")) + { + mBlocked = true; + } + std::string message_class = message.getClass(); if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL) { @@ -689,18 +702,15 @@ bool LLPluginProcessParent::pluginLockedUpOrQuit() { bool result = false; - if(!mDisableTimeout && !mDebug) + if(!mProcess.isRunning()) { - if(!mProcess.isRunning()) - { - LL_WARNS("Plugin") << "child exited" << llendl; - result = true; - } - else if(pluginLockedUp()) - { - LL_WARNS("Plugin") << "timeout" << llendl; - result = true; - } + LL_WARNS("Plugin") << "child exited" << llendl; + result = true; + } + else if(pluginLockedUp()) + { + LL_WARNS("Plugin") << "timeout" << llendl; + result = true; } return result; @@ -708,6 +718,12 @@ bool LLPluginProcessParent::pluginLockedUpOrQuit() bool LLPluginProcessParent::pluginLockedUp() { + if(mDisableTimeout || mDebug || mBlocked) + { + // Never time out a plugin process in these cases. + return false; + } + // If the timer is running and has expired, the plugin has locked up. return (mHeartbeat.getStarted() && mHeartbeat.hasExpired()); } diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h index cc6c513615..31f125bfb3 100644 --- a/indra/llplugin/llpluginprocessparent.h +++ b/indra/llplugin/llpluginprocessparent.h @@ -74,6 +74,9 @@ public: // returns true if the process has exited or we've had a fatal error bool isDone(void); + // returns true if the process is currently waiting on a blocking request + bool isBlocked(void) { return mBlocked; }; + void killSockets(void); // Go to the proper error state @@ -160,6 +163,7 @@ private: bool mDisableTimeout; bool mDebug; + bool mBlocked; LLProcessLauncher mDebugger; diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index e0b2244654..ec247b25c3 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -1147,12 +1147,17 @@ LLFlatListViewEx::LLFlatListViewEx(const Params& p) } -void LLFlatListViewEx::updateNoItemsMessage(bool items_filtered) +void LLFlatListViewEx::updateNoItemsMessage(const std::string& filter_string) { + bool items_filtered = !filter_string.empty(); if (items_filtered) { // items were filtered - setNoItemsCommentText(mNoFilteredItemsMsg); + LLStringUtil::format_map_t args; + args["[SEARCH_TERM]"] = LLURI::escape(filter_string); + std::string text = mNoFilteredItemsMsg; + LLStringUtil::format(text, args); + setNoItemsCommentText(text); } else { diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index f7d094f7e7..4f718ab0dc 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -470,10 +470,10 @@ protected: /** * Applies a message for empty list depend on passed argument. * - * @param items_filtered - if true message for filtered items will be set, otherwise for - * completely empty list. + * @param filter_string - if is not empty, message for filtered items will be set, otherwise for + * completely empty list. Value of filter string will be passed as search_term in SLURL. */ - void updateNoItemsMessage(bool items_filtered); + void updateNoItemsMessage(const std::string& filter_string); private: std::string mNoFilteredItemsMsg; diff --git a/indra/llui/llloadingindicator.cpp b/indra/llui/llloadingindicator.cpp index 8dec6ea9df..f8b029e19c 100644 --- a/indra/llui/llloadingindicator.cpp +++ b/indra/llui/llloadingindicator.cpp @@ -78,10 +78,8 @@ void LLLoadingIndicator::Data::initSingleton() LLPointer<LLUIImage> LLLoadingIndicator::Data::getNextImage(S8& idx) const { - // Actually selects previous image because - // current images seem to be in wrong order; - // performs array bounds checking. - idx = idx > 0 ? llmin(NIMAGES-1, idx-1) : NIMAGES-1; + // Calculate next index, performing array bounds checking. + idx = (idx >= NIMAGES || idx < 0) ? 0 : (idx + 1) % NIMAGES; return mImages[idx]; } diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 8a880e5ace..b5fde0baca 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1974,7 +1974,11 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra msg->nextBlockFast(_PREHASH_ObjectData ); msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID()); msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner()); +#if ENABLE_MULTIATTACHMENTS + msg->addU8Fast(_PREHASH_AttachmentPt, 0 | ATTACHMENT_ADD ); +#else msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point +#endif pack_permissions_slam(msg, item->getFlags(), item->getPermissions()); msg->addStringFast(_PREHASH_Name, item->getName()); msg->addStringFast(_PREHASH_Description, item->getDescription()); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 5586b3cd4d..e93e29ecde 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1092,7 +1092,8 @@ void LLAppearanceMgr::updateAppearanceFromCOF() } //preparing the list of wearables in the correct order for LLAgentWearables - std::sort(wear_items.begin(), wear_items.end(), sort_by_description); + sortItemsByActualDescription(wear_items); + LLWearableHoldingPattern* holder = new LLWearableHoldingPattern; @@ -1910,6 +1911,13 @@ bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_b return result; } +//static +void LLAppearanceMgr::sortItemsByActualDescription(LLInventoryModel::item_array_t& items) +{ + if (items.size() < 2) return; + + std::sort(items.begin(), items.end(), sort_by_description); +} //#define DUMP_CAT_VERBOSE diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index a308a3efa9..516dada39d 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -48,6 +48,8 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr> friend class LLSingleton<LLAppearanceMgr>; public: + typedef std::vector<LLInventoryModel::item_array_t> wearables_by_type_t; + void updateAppearanceFromCOF(); bool needToSaveCOF(); void updateCOF(const LLUUID& category, bool append = false); @@ -143,17 +145,17 @@ public: bool moveWearable(LLViewerInventoryItem* item, bool closer_to_body); + static void sortItemsByActualDescription(LLInventoryModel::item_array_t& items); + + //Divvy items into arrays by wearable type + static void divvyWearablesByType(const LLInventoryModel::item_array_t& items, wearables_by_type_t& items_by_type); + protected: LLAppearanceMgr(); ~LLAppearanceMgr(); private: - typedef std::vector<LLInventoryModel::item_array_t> wearables_by_type_t; - - //Divvy items into arrays by wearable type - static void divvyWearablesByType(const LLInventoryModel::item_array_t& items, wearables_by_type_t& items_by_type); - //Check ordering information on wearables stored in links' descriptions and update if it is invalid void updateClothingOrderingInfo(); diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index fd0b20281b..dfb213716c 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -177,13 +177,15 @@ void LLAvatarList::clear() void LLAvatarList::setNameFilter(const std::string& filter) { - if (mNameFilter != filter) + std::string filter_upper = filter; + LLStringUtil::toUpper(filter_upper); + if (mNameFilter != filter_upper) { - mNameFilter = filter; + mNameFilter = filter_upper; // update message for empty state here instead of refresh() to avoid blinking when switch // between tabs. - updateNoItemsMessage(!mNameFilter.empty()); + updateNoItemsMessage(filter); setDirty(); } } diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index f0442ee3f6..e21644e119 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -94,47 +94,139 @@ void LLCOFWearables::refresh() clear(); LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; + LLInventoryModel::item_array_t cof_items; + + gInventory.collectDescendents(LLAppearanceMgr::getInstance()->getCOF(), cats, cof_items, LLInventoryModel::EXCLUDE_TRASH); + + populateAttachmentsAndBodypartsLists(cof_items); + + + LLAppearanceMgr::wearables_by_type_t clothing_by_type(WT_COUNT); + LLAppearanceMgr::getInstance()->divvyWearablesByType(cof_items, clothing_by_type); - gInventory.collectDescendents(LLAppearanceMgr::getInstance()->getCOF(), cats, items, LLInventoryModel::EXCLUDE_TRASH); - if (items.empty()) return; + populateClothingList(clothing_by_type); +} + - for (U32 i = 0; i < items.size(); ++i) +void LLCOFWearables::populateAttachmentsAndBodypartsLists(const LLInventoryModel::item_array_t& cof_items) +{ + for (U32 i = 0; i < cof_items.size(); ++i) { - LLViewerInventoryItem* item = items.get(i); + LLViewerInventoryItem* item = cof_items.get(i); if (!item) continue; + const LLAssetType::EType item_type = item->getType(); + if (item_type == LLAssetType::AT_CLOTHING) continue; + LLPanelInventoryListItem* item_panel = LLPanelInventoryListItem::createItemPanel(item); if (!item_panel) continue; - switch (item->getType()) + if (item_type == LLAssetType::AT_OBJECT) { - case LLAssetType::AT_OBJECT: - mAttachments->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false); - break; + mAttachments->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false); + } + else if (item_type == LLAssetType::AT_BODYPART) + { + mBodyParts->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false); + addWearableTypeSeparator(mBodyParts); + } + } + + if (mAttachments->size()) + { + mAttachments->sort(); //*TODO by Name + mAttachments->notify(REARRANGE); //notifying the parent about the list's size change (cause items were added with rearrange=false) + } - case LLAssetType::AT_BODYPART: - mBodyParts->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false); - break; + if (mBodyParts->size()) + { + mBodyParts->sort(); //*TODO by name + } + + addListButtonBar(mBodyParts, "panel_bodyparts_list_button_bar.xml"); + mBodyParts->notify(REARRANGE); +} + + +void LLCOFWearables::populateClothingList(LLAppearanceMgr::wearables_by_type_t& clothing_by_type) +{ + llassert(clothing_by_type.size() == WT_COUNT); + + addListButtonBar(mClothing, "panel_clothing_list_button_bar.xml"); + + for (U32 type = WT_SHIRT; type < WT_COUNT; ++type) + { + U32 size = clothing_by_type[type].size(); + if (!size) continue; + + LLAppearanceMgr::sortItemsByActualDescription(clothing_by_type[type]); + + for (U32 i = 0; i < size; i++) + { + LLViewerInventoryItem* item = clothing_by_type[type][i]; - case LLAssetType::AT_CLOTHING: - mClothing->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false); - break; + LLPanelInventoryListItem* item_panel = LLPanelInventoryListItem::createItemPanel(item); + if (!item_panel) continue; - default: break; + mClothing->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false); } + + addWearableTypeSeparator(mClothing); } - mAttachments->sort(); //*TODO by Name - mAttachments->notify(REARRANGE); //notifying the parent about the list's size change (cause items were added with rearrange=false) - - mClothing->sort(); //*TODO by actual inventory item description + addClothingTypesDummies(clothing_by_type); + mClothing->notify(REARRANGE); +} + +void LLCOFWearables::addListButtonBar(LLFlatListView* list, std::string xml_filename) +{ + llassert(list); + llassert(xml_filename.length()); - mBodyParts->sort(); //*TODO by name - mBodyParts->notify(REARRANGE); + LLPanel::Params params; + LLPanel* button_bar = LLUICtrlFactory::create<LLPanel>(params); + LLUICtrlFactory::instance().buildPanel(button_bar, xml_filename); + + LLRect rc = button_bar->getRect(); + button_bar->reshape(list->getItemsRect().getWidth(), rc.getHeight()); + + list->addItem(button_bar, LLUUID::null, ADD_TOP, false); } +//adding dummy items for missing wearable types +void LLCOFWearables::addClothingTypesDummies(const LLAppearanceMgr::wearables_by_type_t& clothing_by_type) +{ + llassert(clothing_by_type.size() == WT_COUNT); + + for (U32 type = WT_SHIRT; type < WT_COUNT; type++) + { + U32 size = clothing_by_type[type].size(); + if (size) continue; + + //*TODO create dummy item panel + + //*TODO add dummy item panel -> mClothing->addItem(dummy_item_panel, item->getUUID(), ADD_BOTTOM, false); + + addWearableTypeSeparator(mClothing); + } +} + +void LLCOFWearables::addWearableTypeSeparator(LLFlatListView* list) +{ + llassert(list); + + static LLXMLNodePtr separator_xml_node = getXMLNode("panel_wearable_type_separator.xml"); + if (separator_xml_node->isNull()) return; + + LLPanel* separator = LLUICtrlFactory::defaultBuilder<LLPanel>(separator_xml_node, NULL, NULL); + + LLRect rc = separator->getRect(); + rc.setOriginAndSize(0, 0, list->getItemsRect().getWidth(), rc.getHeight()); + separator->setRect(rc); + + list->addItem(separator, LLUUID::null, ADD_BOTTOM, false); +} LLUUID LLCOFWearables::getSelectedUUID() { @@ -150,4 +242,17 @@ void LLCOFWearables::clear() mBodyParts->clear(); } +LLXMLNodePtr LLCOFWearables::getXMLNode(std::string xml_filename) +{ + LLXMLNodePtr xmlNode = NULL; + bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, xmlNode); + if (!success) + { + llwarning("Failed to read xml", 0); + return NULL; + } + + return xmlNode; +} + //EOF diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h index 58d67ed32f..fec6d34db2 100644 --- a/indra/newview/llcofwearables.h +++ b/indra/newview/llcofwearables.h @@ -34,6 +34,8 @@ #define LL_LLCOFWEARABLES_H #include "llpanel.h" +#include "llinventorymodel.h" +#include "llappearancemgr.h" class LLFlatListView; @@ -52,8 +54,16 @@ public: protected: + void populateAttachmentsAndBodypartsLists(const LLInventoryModel::item_array_t& cof_items); + void populateClothingList(LLAppearanceMgr::wearables_by_type_t& clothing_by_type); + + void addListButtonBar(LLFlatListView* list, std::string xml_filename); + void addClothingTypesDummies(const LLAppearanceMgr::wearables_by_type_t& clothing_by_type); + void addWearableTypeSeparator(LLFlatListView* list); void onSelectionChange(LLFlatListView* selected_list); + LLXMLNodePtr getXMLNode(std::string xml_filename); + LLFlatListView* mAttachments; LLFlatListView* mClothing; LLFlatListView* mBodyParts; diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index c492bfcef1..eba4cdfa31 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -946,7 +946,9 @@ void LLFolderView::draw() } else { - mStatusText = LLTrans::getString(getFilter()->getEmptyLookupMessage()); + LLStringUtil::format_map_t args; + args["[SEARCH_TERM]"] = LLURI::escape(getFilter()->getFilterSubStringOrig()); + mStatusText = LLTrans::getString(getFilter()->getEmptyLookupMessage(), args); //font->renderUTF8(mStatusText, 0, 2, 1, sSearchStatusColor, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE ); } mStatusTextBox->setValue(mStatusText); diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index f21b6e1085..252c34cf9c 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -131,9 +131,15 @@ BOOL LLGroupList::handleRightMouseDown(S32 x, S32 y, MASK mask) void LLGroupList::setNameFilter(const std::string& filter) { - if (mNameFilter != filter) + std::string filter_upper = filter; + LLStringUtil::toUpper(filter_upper); + if (mNameFilter != filter_upper) { - mNameFilter = filter; + mNameFilter = filter_upper; + + // set no items message depend on filter state + updateNoItemsMessage(filter); + setDirty(); } } @@ -151,9 +157,6 @@ void LLGroupList::refresh() LLUUID id; bool have_filter = !mNameFilter.empty(); - // set no items message depend on filter state & total count of groups - updateNoItemsMessage(have_filter); - clear(); for(S32 i = 0; i < count; ++i) diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index f03026715d..15dbc03f70 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -257,9 +257,8 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction) { - std::string you = LLTrans::getString("You"); - std::string started_call = LLTrans::getString("started_call"); - std::string joined_call = LLTrans::getString("joined_call"); + std::string you_joined_call = LLTrans::getString("you_joined_call"); + std::string you_started_call = LLTrans::getString("you_started_call"); std::string other_avatar_name = ""; std::string message; @@ -277,13 +276,15 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES switch(new_state) { case LLVoiceChannel::STATE_CALL_STARTED : - message = other_avatar_name + " " + started_call; - LLIMModel::getInstance()->addMessage(mSessionID, SYSTEM_FROM, LLUUID::null, message); - - break; + { + LLStringUtil::format_map_t string_args; + string_args["[NAME]"] = other_avatar_name; + message = LLTrans::getString("name_started_call", string_args); + LLIMModel::getInstance()->addMessage(mSessionID, SYSTEM_FROM, LLUUID::null, message); + break; + } case LLVoiceChannel::STATE_CONNECTED : - message = you + " " + joined_call; - LLIMModel::getInstance()->addMessage(mSessionID, SYSTEM_FROM, LLUUID::null, message); + LLIMModel::getInstance()->addMessage(mSessionID, SYSTEM_FROM, LLUUID::null, you_joined_call); default: break; } @@ -293,8 +294,7 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES switch(new_state) { case LLVoiceChannel::STATE_CALL_STARTED : - message = you + " " + started_call; - LLIMModel::getInstance()->addMessage(mSessionID, SYSTEM_FROM, LLUUID::null, message); + LLIMModel::getInstance()->addMessage(mSessionID, SYSTEM_FROM, LLUUID::null, you_started_call); break; case LLVoiceChannel::STATE_CONNECTED : message = LLTrans::getString("answered_call"); @@ -312,8 +312,7 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES switch(new_state) { case LLVoiceChannel::STATE_CONNECTED : - message = you + " " + joined_call; - LLIMModel::getInstance()->addMessage(mSessionID, SYSTEM_FROM, LLUUID::null, message); + LLIMModel::getInstance()->addMessage(mSessionID, SYSTEM_FROM, LLUUID::null, you_joined_call); default: break; } @@ -323,8 +322,7 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES switch(new_state) { case LLVoiceChannel::STATE_CALL_STARTED : - message = you + " " + started_call; - LLIMModel::getInstance()->addMessage(mSessionID, SYSTEM_FROM, LLUUID::null, message); + LLIMModel::getInstance()->addMessage(mSessionID, SYSTEM_FROM, LLUUID::null, you_started_call); break; default: break; @@ -2069,8 +2067,9 @@ void LLIncomingCallDialog::processCallResponse(S32 response) // send notification message to the corresponding chat if (mPayload["notify_box_type"].asString() == "VoiceInviteGroup" || mPayload["notify_box_type"].asString() == "VoiceInviteAdHoc") { - std::string started_call = LLTrans::getString("started_call"); - std::string message = mPayload["caller_name"].asString() + " " + started_call; + LLStringUtil::format_map_t string_args; + string_args["[NAME]"] = mPayload["caller_name"].asString(); + std::string message = LLTrans::getString("name_started_call", string_args); LLIMModel::getInstance()->addMessageSilently(session_id, SYSTEM_FROM, LLUUID::null, message); } } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index b4a1bf2758..c6f806178c 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -211,10 +211,14 @@ BOOL LLInvFVBridge::isItemRemovable() const return FALSE; } - // Disable delete from COF folder; have users explicitly choose "detach/take off". + // Disable delete from COF folder; have users explicitly choose "detach/take off", + // unless the item is not worn but in the COF (i.e. is bugged). if (LLAppearanceMgr::instance().getIsProtectedCOFItem(mUUID)) { - return FALSE; + if (get_is_item_worn(mUUID)) + { + return FALSE; + } } const LLInventoryObject *obj = model->getItem(mUUID); @@ -494,7 +498,7 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const } } const LLViewerInventoryCategory *cat = model->getCategory(objects.get(i)); - if (cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType())) + if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType())) { return FALSE; } @@ -641,13 +645,10 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, disabled_items.push_back(std::string("Paste")); } - if (gAgent.isGodlike()) + items.push_back(std::string("Paste As Link")); + if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0) { - items.push_back(std::string("Paste As Link")); - if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0) - { - disabled_items.push_back(std::string("Paste As Link")); - } + disabled_items.push_back(std::string("Paste As Link")); } items.push_back(std::string("Paste Separator")); @@ -677,7 +678,8 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { disabled_items.push_back(std::string("Share")); } - items.push_back(std::string("Open")); + + addOpenRightClickMenuOption(items); items.push_back(std::string("Properties")); getClipboardEntries(true, items, disabled_items, flags); @@ -712,7 +714,7 @@ void LLInvFVBridge::addDeleteContextMenuOptions(menuentry_vec_t &items, const LLInventoryObject *obj = getInventoryObject(); // Don't allow delete as a direct option from COF folder. - if (obj && obj->getIsLinkType() && isCOFFolder()) + if (obj && obj->getIsLinkType() && isCOFFolder() && get_is_item_worn(mUUID)) { return; } @@ -733,6 +735,17 @@ void LLInvFVBridge::addDeleteContextMenuOptions(menuentry_vec_t &items, } } +void LLInvFVBridge::addOpenRightClickMenuOption(menuentry_vec_t &items) +{ + const LLInventoryObject *obj = getInventoryObject(); + const BOOL is_link = (obj && obj->getIsLinkType()); + + if (is_link) + items.push_back(std::string("Open Original")); + else + items.push_back(std::string("Open")); +} + // *TODO: remove this BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const { @@ -1099,7 +1112,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action) gotoItem(); } - if ("open" == action) + if ("open" == action || "open_original" == action) { openItem(); return; @@ -1445,17 +1458,11 @@ BOOL LLItemBridge::isItemCopyable() const return FALSE; } - if (gAgent.isGodlike()) - { - // All items can be copied in god mode since you can - // at least paste-as-link the item, though you - // still may not be able paste the item. - return TRUE; - } - else - { - return (item->getPermissions().allowCopyBy(gAgent.getID())); - } + // All items can be copied in god mode since you can + // at least paste-as-link the item, though you + // still may not be able paste the item. + return TRUE; + // return (item->getPermissions().allowCopyBy(gAgent.getID())); } return FALSE; } @@ -1596,7 +1603,8 @@ BOOL LLFolderBridge::isUpToDate() const BOOL LLFolderBridge::isItemCopyable() const { - return FALSE; + // Can copy folders to paste-as-link, but not for straight paste. + return TRUE; } BOOL LLFolderBridge::copyToClipboard() const @@ -1827,11 +1835,13 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, else { LLPointer<LLInventoryCallback> cb = NULL; + const std::string empty_description = ""; link_inventory_item( gAgent.getID(), inv_cat->getUUID(), mUUID, inv_cat->getName(), + empty_description, LLAssetType::AT_LINK_FOLDER, cb); } @@ -2500,30 +2510,29 @@ void LLFolderBridge::pasteLinkFromClipboard() ++iter) { const LLUUID &object_id = (*iter); -#if SUPPORT_ENSEMBLES if (LLInventoryCategory *cat = model->getCategory(object_id)) { + const std::string empty_description = ""; link_inventory_item( gAgent.getID(), cat->getUUID(), parent_id, cat->getName(), + empty_description, LLAssetType::AT_LINK_FOLDER, LLPointer<LLInventoryCallback>(NULL)); } - else -#endif - if (LLInventoryItem *item = model->getItem(object_id)) - { - link_inventory_item( - gAgent.getID(), - item->getLinkedUUID(), - parent_id, - item->getName(), - item->getDescription(), - LLAssetType::AT_LINK, - LLPointer<LLInventoryCallback>(NULL)); - } + else if (LLInventoryItem *item = model->getItem(object_id)) + { + link_inventory_item( + gAgent.getID(), + item->getLinkedUUID(), + parent_id, + item->getName(), + item->getDescription(), + LLAssetType::AT_LINK, + LLPointer<LLInventoryCallback>(NULL)); + } } } } @@ -3333,7 +3342,7 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) disabled_items.push_back(std::string("Share")); } - items.push_back(std::string("Open")); + addOpenRightClickMenuOption(items); items.push_back(std::string("Properties")); getClipboardEntries(true, items, disabled_items, flags); @@ -3699,7 +3708,7 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { disabled_items.push_back(std::string("Share")); } - items.push_back(std::string("Open")); + addOpenRightClickMenuOption(items); items.push_back(std::string("Properties")); getClipboardEntries(true, items, disabled_items, flags); @@ -3978,7 +3987,7 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if (!is_sidepanel) { - items.push_back(std::string("Open")); + addOpenRightClickMenuOption(items); items.push_back(std::string("Properties")); } @@ -4716,7 +4725,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if (can_open && !is_sidepanel) { - items.push_back(std::string("Open")); + addOpenRightClickMenuOption(items); } if (!is_sidepanel) @@ -5177,9 +5186,13 @@ const LLUUID &LLLinkFolderBridge::getFolderID() const // static void LLInvFVBridgeAction::doAction(LLAssetType::EType asset_type, - const LLUUID& uuid,LLInventoryModel* model) + const LLUUID& uuid, + LLInventoryModel* model) { - LLInvFVBridgeAction* action = createAction(asset_type,uuid,model); + // Perform indirection in case of link. + const LLUUID& linked_uuid = gInventory.getLinkedItemID(uuid); + + LLInvFVBridgeAction* action = createAction(asset_type,linked_uuid,model); if(action) { action->doIt(); @@ -5292,7 +5305,8 @@ protected: }; -class LLNotecardBridgeAction: public LLInvFVBridgeAction +class LLNotecardBridgeAction +: public LLInvFVBridgeAction { friend class LLInvFVBridgeAction; public: diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index f378d219f6..de63bdd76b 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -135,7 +135,7 @@ protected: menuentry_vec_t &disabled_items); virtual void addDeleteContextMenuOptions(menuentry_vec_t &items, menuentry_vec_t &disabled_items); - + virtual void addOpenRightClickMenuOption(menuentry_vec_t &items); protected: LLInvFVBridge(LLInventoryPanel* inventory, LLFolderView* root, const LLUUID& uuid); diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 1a488175ac..901a570487 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -329,9 +329,10 @@ void LLInventoryFilter::setFilterSubString(const std::string& string) // appending new characters const BOOL more_restrictive = mFilterSubString.size() < string.size() && !string.substr(0, mFilterSubString.size()).compare(mFilterSubString); - mFilterSubString = string; + mFilterSubStringOrig = string; + LLStringUtil::trimHead(mFilterSubStringOrig); + mFilterSubString = mFilterSubStringOrig; LLStringUtil::toUpper(mFilterSubString); - LLStringUtil::trimHead(mFilterSubString); if (less_restrictive) { setModified(FILTER_LESS_RESTRICTIVE); diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index b01554edc8..2376ba5d22 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -84,6 +84,7 @@ public: void setFilterSubString(const std::string& string); const std::string& getFilterSubString(BOOL trim = FALSE) const; + const std::string& getFilterSubStringOrig() const { return mFilterSubStringOrig; } BOOL hasFilterString() const; void setFilterPermissions(PermissionMask perms); @@ -181,6 +182,7 @@ private: std::string::size_type mSubStringMatchOffset; std::string mFilterSubString; + std::string mFilterSubStringOrig; const std::string mName; S32 mFilterGeneration; diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index da74295f9e..3c112b8b5e 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -51,6 +51,12 @@ #include "llagentwearables.h" #include "llscrollingpanelparam.h" +#include "llcolorswatch.h" +#include "lltexturectrl.h" +#include "lltextureentry.h" +#include "llviewercontrol.h" // gSavedSettings +#include "llviewertexturelist.h" + // register panel with appropriate XML static LLRegisterPanelClassWrapper<LLPanelEditWearable> t_edit_wearable("panel_edit_wearable"); @@ -88,6 +94,8 @@ enum ESubpart { SUBPART_TATTOO }; +using namespace LLVOAvatarDefines; + typedef std::vector<ESubpart> subpart_vec_t; // Locally defined classes @@ -110,14 +118,17 @@ public: WearableEntry(EWearableType type, const std::string &title, const std::string &desc_title, - U8 num_subparts, ... ); // number of subparts followed by a list of ESubparts + U8 num_color_swatches, // number of 'color_swatches' + U8 num_texture_pickers, // number of 'texture_pickers' + U8 num_subparts, ... ); // number of subparts followed by a list of ETextureIndex and ESubparts const EWearableType mWearableType; const std::string mTitle; const std::string mDescTitle; subpart_vec_t mSubparts; - + texture_vec_t mColorSwatchCtrls; + texture_vec_t mTextureCtrls; }; struct Wearables : public LLDictionary<EWearableType, WearableEntry> @@ -158,6 +169,35 @@ public: } mSubparts; const SubpartEntry* getSubpart(ESubpart subpart) const { return mSubparts.lookup(subpart); } + + //-------------------------------------------------------------------- + // Picker Control Entries + //-------------------------------------------------------------------- +public: + struct PickerControlEntry : public LLDictionaryEntry + { + PickerControlEntry(ETextureIndex tex_index, + const std::string name, + const LLUUID default_image_id = LLUUID::null, + const bool allow_no_texture = false); + ETextureIndex mTextureIndex; + const std::string mControlName; + const LLUUID mDefaultImageId; + const bool mAllowNoTexture; + }; + + struct ColorSwatchCtrls : public LLDictionary<ETextureIndex, PickerControlEntry> + { + ColorSwatchCtrls(); + } mColorSwatchCtrls; + + struct TextureCtrls : public LLDictionary<ETextureIndex, PickerControlEntry> + { + TextureCtrls(); + } mTextureCtrls; + + const PickerControlEntry* getTexturePicker(ETextureIndex index) const { return mTextureCtrls.lookup(index); } + const PickerControlEntry* getColorSwatch(ETextureIndex index) const { return mColorSwatchCtrls.lookup(index); } }; LLEditWearableDictionary::LLEditWearableDictionary() @@ -172,26 +212,28 @@ LLEditWearableDictionary::~LLEditWearableDictionary() LLEditWearableDictionary::Wearables::Wearables() { - addEntry(WT_SHAPE, new WearableEntry(WT_SHAPE,"edit_shape_title","shape_desc_text",9, SUBPART_SHAPE_HEAD, SUBPART_SHAPE_EYES, SUBPART_SHAPE_EARS, SUBPART_SHAPE_NOSE, SUBPART_SHAPE_MOUTH, SUBPART_SHAPE_CHIN, SUBPART_SHAPE_TORSO, SUBPART_SHAPE_LEGS, SUBPART_SHAPE_WHOLE)); - addEntry(WT_SKIN, new WearableEntry(WT_SKIN,"edit_skin_title","skin_desc_text",4, SUBPART_SKIN_COLOR, SUBPART_SKIN_FACEDETAIL, SUBPART_SKIN_MAKEUP, SUBPART_SKIN_BODYDETAIL)); - addEntry(WT_HAIR, new WearableEntry(WT_HAIR,"edit_hair_title","hair_desc_text",4, SUBPART_HAIR_COLOR, SUBPART_HAIR_STYLE, SUBPART_HAIR_EYEBROWS, SUBPART_HAIR_FACIAL)); - addEntry(WT_EYES, new WearableEntry(WT_EYES,"edit_eyes_title","eyes_desc_text",1, SUBPART_EYES)); - addEntry(WT_SHIRT, new WearableEntry(WT_SHIRT,"edit_shirt_title","shirt_desc_text",1, SUBPART_SHIRT)); - addEntry(WT_PANTS, new WearableEntry(WT_PANTS,"edit_pants_title","pants_desc_text",1, SUBPART_PANTS)); - addEntry(WT_SHOES, new WearableEntry(WT_SHOES,"edit_shoes_title","shoes_desc_text",1, SUBPART_SHOES)); - addEntry(WT_SOCKS, new WearableEntry(WT_SOCKS,"edit_socks_title","socks_desc_text",1, SUBPART_SOCKS)); - addEntry(WT_JACKET, new WearableEntry(WT_JACKET,"edit_jacket_title","jacket_desc_text",1, SUBPART_JACKET)); - addEntry(WT_GLOVES, new WearableEntry(WT_GLOVES,"edit_gloves_title","gloves_desc_text",1, SUBPART_GLOVES)); - addEntry(WT_UNDERSHIRT, new WearableEntry(WT_UNDERSHIRT,"edit_undershirt_title","undershirt_desc_text",1, SUBPART_UNDERSHIRT)); - addEntry(WT_UNDERPANTS, new WearableEntry(WT_UNDERPANTS,"edit_underpants_title","underpants_desc_text",1, SUBPART_UNDERPANTS)); - addEntry(WT_SKIRT, new WearableEntry(WT_SKIRT,"edit_skirt_title","skirt_desc_text",1, SUBPART_SKIRT)); - addEntry(WT_ALPHA, new WearableEntry(WT_ALPHA,"edit_alpha_title","alpha_desc_text",1, SUBPART_ALPHA)); - addEntry(WT_TATTOO, new WearableEntry(WT_TATTOO,"edit_tattoo_title","tattoo_desc_text",1, SUBPART_TATTOO)); + addEntry(WT_SHAPE, new WearableEntry(WT_SHAPE,"edit_shape_title","shape_desc_text",0,0,9, SUBPART_SHAPE_HEAD, SUBPART_SHAPE_EYES, SUBPART_SHAPE_EARS, SUBPART_SHAPE_NOSE, SUBPART_SHAPE_MOUTH, SUBPART_SHAPE_CHIN, SUBPART_SHAPE_TORSO, SUBPART_SHAPE_LEGS, SUBPART_SHAPE_WHOLE)); + addEntry(WT_SKIN, new WearableEntry(WT_SKIN,"edit_skin_title","skin_desc_text",0,3,4, TEX_HEAD_BODYPAINT, TEX_UPPER_BODYPAINT, TEX_LOWER_BODYPAINT, SUBPART_SKIN_COLOR, SUBPART_SKIN_FACEDETAIL, SUBPART_SKIN_MAKEUP, SUBPART_SKIN_BODYDETAIL)); + addEntry(WT_HAIR, new WearableEntry(WT_HAIR,"edit_hair_title","hair_desc_text",0,1,4, TEX_HAIR, SUBPART_HAIR_COLOR, SUBPART_HAIR_STYLE, SUBPART_HAIR_EYEBROWS, SUBPART_HAIR_FACIAL)); + addEntry(WT_EYES, new WearableEntry(WT_EYES,"edit_eyes_title","eyes_desc_text",0,1,1, TEX_EYES_IRIS, SUBPART_EYES)); + addEntry(WT_SHIRT, new WearableEntry(WT_SHIRT,"edit_shirt_title","shirt_desc_text",1,1,1, TEX_UPPER_SHIRT, TEX_UPPER_SHIRT, SUBPART_SHIRT)); + addEntry(WT_PANTS, new WearableEntry(WT_PANTS,"edit_pants_title","pants_desc_text",1,1,1, TEX_LOWER_PANTS, TEX_LOWER_PANTS, SUBPART_PANTS)); + addEntry(WT_SHOES, new WearableEntry(WT_SHOES,"edit_shoes_title","shoes_desc_text",1,1,1, TEX_LOWER_SHOES, TEX_LOWER_SHOES, SUBPART_SHOES)); + addEntry(WT_SOCKS, new WearableEntry(WT_SOCKS,"edit_socks_title","socks_desc_text",1,1,1, TEX_LOWER_SOCKS, TEX_LOWER_SOCKS, SUBPART_SOCKS)); + addEntry(WT_JACKET, new WearableEntry(WT_JACKET,"edit_jacket_title","jacket_desc_text",1,2,1, TEX_UPPER_JACKET, TEX_UPPER_JACKET, TEX_LOWER_JACKET, SUBPART_JACKET)); + addEntry(WT_GLOVES, new WearableEntry(WT_GLOVES,"edit_gloves_title","gloves_desc_text",1,1,1, TEX_UPPER_GLOVES, TEX_UPPER_GLOVES, SUBPART_GLOVES)); + addEntry(WT_UNDERSHIRT, new WearableEntry(WT_UNDERSHIRT,"edit_undershirt_title","undershirt_desc_text",1,1,1, TEX_UPPER_UNDERSHIRT, TEX_UPPER_UNDERSHIRT, SUBPART_UNDERSHIRT)); + addEntry(WT_UNDERPANTS, new WearableEntry(WT_UNDERPANTS,"edit_underpants_title","underpants_desc_text",1,1,1, TEX_LOWER_UNDERPANTS, TEX_LOWER_UNDERPANTS, SUBPART_UNDERPANTS)); + addEntry(WT_SKIRT, new WearableEntry(WT_SKIRT,"edit_skirt_title","skirt_desc_text",1,1,1, TEX_SKIRT, TEX_SKIRT, SUBPART_SKIRT)); + addEntry(WT_ALPHA, new WearableEntry(WT_ALPHA,"edit_alpha_title","alpha_desc_text",0,5,1, TEX_LOWER_ALPHA, TEX_UPPER_ALPHA, TEX_HEAD_ALPHA, TEX_EYES_ALPHA, TEX_HAIR_ALPHA, SUBPART_ALPHA)); + addEntry(WT_TATTOO, new WearableEntry(WT_TATTOO,"edit_tattoo_title","tattoo_desc_text",0,3,1, TEX_LOWER_TATTOO, TEX_UPPER_TATTOO, TEX_HEAD_TATTOO, SUBPART_TATTOO)); } LLEditWearableDictionary::WearableEntry::WearableEntry(EWearableType type, const std::string &title, const std::string &desc_title, + U8 num_color_swatches, + U8 num_texture_pickers, U8 num_subparts, ... ) : LLDictionaryEntry(title), mWearableType(type), @@ -201,6 +243,18 @@ LLEditWearableDictionary::WearableEntry::WearableEntry(EWearableType type, va_list argp; va_start(argp, num_subparts); + for (U8 i = 0; i < num_color_swatches; ++i) + { + ETextureIndex index = (ETextureIndex)va_arg(argp,int); + mColorSwatchCtrls.push_back(index); + } + + for (U8 i = 0; i < num_texture_pickers; ++i) + { + ETextureIndex index = (ETextureIndex)va_arg(argp,int); + mTextureCtrls.push_back(index); + } + for (U8 i = 0; i < num_subparts; ++i) { ESubpart part = (ESubpart)va_arg(argp,int); @@ -265,6 +319,268 @@ LLEditWearableDictionary::SubpartEntry::SubpartEntry(ESubpart part, { } +LLEditWearableDictionary::ColorSwatchCtrls::ColorSwatchCtrls() +{ + addEntry ( TEX_UPPER_SHIRT, new PickerControlEntry (TEX_UPPER_SHIRT, "Color/Tint" )); + addEntry ( TEX_LOWER_PANTS, new PickerControlEntry (TEX_LOWER_PANTS, "Color/Tint" )); + addEntry ( TEX_LOWER_SHOES, new PickerControlEntry (TEX_LOWER_SHOES, "Color/Tint" )); + addEntry ( TEX_LOWER_SOCKS, new PickerControlEntry (TEX_LOWER_SOCKS, "Color/Tint" )); + addEntry ( TEX_UPPER_JACKET, new PickerControlEntry (TEX_UPPER_JACKET, "Color/Tint" )); + addEntry ( TEX_SKIRT, new PickerControlEntry (TEX_SKIRT, "Color/Tint" )); + addEntry ( TEX_UPPER_GLOVES, new PickerControlEntry (TEX_UPPER_GLOVES, "Color/Tint" )); + addEntry ( TEX_UPPER_UNDERSHIRT, new PickerControlEntry (TEX_UPPER_UNDERSHIRT, "Color/Tint" )); + addEntry ( TEX_LOWER_UNDERPANTS, new PickerControlEntry (TEX_LOWER_UNDERPANTS, "Color/Tint" )); +} + +LLEditWearableDictionary::TextureCtrls::TextureCtrls() +{ + addEntry ( TEX_HEAD_BODYPAINT, new PickerControlEntry (TEX_HEAD_BODYPAINT, "Head Tattoos", LLUUID::null, TRUE )); + addEntry ( TEX_UPPER_BODYPAINT, new PickerControlEntry (TEX_UPPER_BODYPAINT, "Upper Tattoos", LLUUID::null, TRUE )); + addEntry ( TEX_LOWER_BODYPAINT, new PickerControlEntry (TEX_LOWER_BODYPAINT, "Lower Tattoos", LLUUID::null, TRUE )); + addEntry ( TEX_HAIR, new PickerControlEntry (TEX_HAIR, "Texture", LLUUID( gSavedSettings.getString( "UIImgDefaultHairUUID" ) ), FALSE )); + addEntry ( TEX_EYES_IRIS, new PickerControlEntry (TEX_EYES_IRIS, "Iris", LLUUID( gSavedSettings.getString( "UIImgDefaultEyesUUID" ) ), FALSE )); + addEntry ( TEX_UPPER_SHIRT, new PickerControlEntry (TEX_UPPER_SHIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultShirtUUID" ) ), FALSE )); + addEntry ( TEX_LOWER_PANTS, new PickerControlEntry (TEX_LOWER_PANTS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultPantsUUID" ) ), FALSE )); + addEntry ( TEX_LOWER_SHOES, new PickerControlEntry (TEX_LOWER_SHOES, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultShoesUUID" ) ), FALSE )); + addEntry ( TEX_LOWER_SOCKS, new PickerControlEntry (TEX_LOWER_SOCKS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultSocksUUID" ) ), FALSE )); + addEntry ( TEX_UPPER_JACKET, new PickerControlEntry (TEX_UPPER_JACKET, "Upper Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultJacketUUID" ) ), FALSE )); + addEntry ( TEX_LOWER_JACKET, new PickerControlEntry (TEX_LOWER_JACKET, "Lower Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultJacketUUID" ) ), FALSE )); + addEntry ( TEX_SKIRT, new PickerControlEntry (TEX_SKIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultSkirtUUID" ) ), FALSE )); + addEntry ( TEX_UPPER_GLOVES, new PickerControlEntry (TEX_UPPER_GLOVES, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultGlovesUUID" ) ), FALSE )); + addEntry ( TEX_UPPER_UNDERSHIRT, new PickerControlEntry (TEX_UPPER_UNDERSHIRT, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultUnderwearUUID" ) ), FALSE )); + addEntry ( TEX_LOWER_UNDERPANTS, new PickerControlEntry (TEX_LOWER_UNDERPANTS, "Fabric", LLUUID( gSavedSettings.getString( "UIImgDefaultUnderwearUUID" ) ), FALSE )); + addEntry ( TEX_LOWER_ALPHA, new PickerControlEntry (TEX_LOWER_ALPHA, "Lower Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE )); + addEntry ( TEX_UPPER_ALPHA, new PickerControlEntry (TEX_UPPER_ALPHA, "Upper Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE )); + addEntry ( TEX_HEAD_ALPHA, new PickerControlEntry (TEX_HEAD_ALPHA, "Head Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE )); + addEntry ( TEX_EYES_ALPHA, new PickerControlEntry (TEX_EYES_ALPHA, "Eye Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE )); + addEntry ( TEX_HAIR_ALPHA, new PickerControlEntry (TEX_HAIR_ALPHA, "Hair Alpha", LLUUID( gSavedSettings.getString( "UIImgDefaultAlphaUUID" ) ), TRUE )); + addEntry ( TEX_LOWER_TATTOO, new PickerControlEntry (TEX_LOWER_TATTOO, "Lower Tattoo", LLUUID::null, TRUE )); + addEntry ( TEX_UPPER_TATTOO, new PickerControlEntry (TEX_UPPER_TATTOO, "Upper Tattoo", LLUUID::null, TRUE )); + addEntry ( TEX_HEAD_TATTOO, new PickerControlEntry (TEX_HEAD_TATTOO, "Head Tattoo", LLUUID::null, TRUE )); +} + +LLEditWearableDictionary::PickerControlEntry::PickerControlEntry(ETextureIndex tex_index, + const std::string name, + const LLUUID default_image_id, + const bool allow_no_texture) : + LLDictionaryEntry(name), + mTextureIndex(tex_index), + mControlName(name), + mDefaultImageId(default_image_id), + mAllowNoTexture(allow_no_texture) +{ +} + +// Helper functions. +static const texture_vec_t null_texture_vec; + +// Specializations of this template function return a vector of texture indexes of particular control type +// (i.e. LLColorSwatchCtrl or LLTextureCtrl) which are contained in given WearableEntry. +template <typename T> +const texture_vec_t& +get_pickers_indexes(const LLEditWearableDictionary::WearableEntry *wearable_entry) { return null_texture_vec; } + +// Specializations of this template function return picker control entry for particular control type. +template <typename T> +const LLEditWearableDictionary::PickerControlEntry* +get_picker_entry (const ETextureIndex index) { return NULL; } + +typedef boost::function<void(LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry*)> function_t; + +typedef struct PickerControlEntryNamePredicate +{ + PickerControlEntryNamePredicate(const std::string name) : mName (name) {}; + bool operator()(const LLEditWearableDictionary::PickerControlEntry* entry) const + { + return (entry && entry->mName == mName); + } +private: + const std::string mName; +} PickerControlEntryNamePredicate; + +// A full specialization of get_pickers_indexes for LLColorSwatchCtrl +template <> +const texture_vec_t& +get_pickers_indexes<LLColorSwatchCtrl> (const LLEditWearableDictionary::WearableEntry *wearable_entry) +{ + if (!wearable_entry) + { + llwarns << "could not get LLColorSwatchCtrl indexes for null wearable entry." << llendl; + return null_texture_vec; + } + return wearable_entry->mColorSwatchCtrls; +} + +// A full specialization of get_pickers_indexes for LLTextureCtrl +template <> +const texture_vec_t& +get_pickers_indexes<LLTextureCtrl> (const LLEditWearableDictionary::WearableEntry *wearable_entry) +{ + if (!wearable_entry) + { + llwarns << "could not get LLTextureCtrl indexes for null wearable entry." << llendl; + return null_texture_vec; + } + return wearable_entry->mTextureCtrls; +} + +// A full specialization of get_picker_entry for LLColorSwatchCtrl +template <> +const LLEditWearableDictionary::PickerControlEntry* +get_picker_entry<LLColorSwatchCtrl> (const ETextureIndex index) +{ + return LLEditWearableDictionary::getInstance()->getColorSwatch(index); +} + +// A full specialization of get_picker_entry for LLTextureCtrl +template <> +const LLEditWearableDictionary::PickerControlEntry* +get_picker_entry<LLTextureCtrl> (const ETextureIndex index) +{ + return LLEditWearableDictionary::getInstance()->getTexturePicker(index); +} + +template <typename CtrlType, class Predicate> +const LLEditWearableDictionary::PickerControlEntry* +find_picker_ctrl_entry_if(EWearableType type, const Predicate pred) +{ + const LLEditWearableDictionary::WearableEntry *wearable_entry + = LLEditWearableDictionary::getInstance()->getWearable(type); + if (!wearable_entry) + { + llwarns << "could not get wearable dictionary entry for wearable of type: " << type << llendl; + return NULL; + } + const texture_vec_t& indexes = get_pickers_indexes<CtrlType>(wearable_entry); + for (texture_vec_t::const_iterator + iter = indexes.begin(), + iter_end = indexes.end(); + iter != iter_end; ++iter) + { + const ETextureIndex te = *iter; + const LLEditWearableDictionary::PickerControlEntry* entry + = get_picker_entry<CtrlType>(te); + if (!entry) + { + llwarns << "could not get picker dictionary entry (" << te << ") for wearable of type: " << type << llendl; + continue; + } + if (pred(entry)) + { + return entry; + } + } + return NULL; +} + +template <typename CtrlType> +void +for_each_picker_ctrl_entry(LLPanel* panel, EWearableType type, function_t fun) +{ + if (!panel) + { + llwarns << "the panel wasn't passed for wearable of type: " << type << llendl; + return; + } + const LLEditWearableDictionary::WearableEntry *wearable_entry + = LLEditWearableDictionary::getInstance()->getWearable(type); + if (!wearable_entry) + { + llwarns << "could not get wearable dictionary entry for wearable of type: " << type << llendl; + return; + } + const texture_vec_t& indexes = get_pickers_indexes<CtrlType>(wearable_entry); + for (texture_vec_t::const_iterator + iter = indexes.begin(), + iter_end = indexes.end(); + iter != iter_end; ++iter) + { + const ETextureIndex te = *iter; + const LLEditWearableDictionary::PickerControlEntry* entry + = get_picker_entry<CtrlType>(te); + if (!entry) + { + llwarns << "could not get picker dictionary entry (" << te << ") for wearable of type: " << type << llendl; + continue; + } + fun (panel, entry); + } +} + +// The helper functions for pickers management +static void init_color_swatch_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry) +{ + LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild<LLColorSwatchCtrl>(entry->mControlName); + if (color_swatch_ctrl) + { + color_swatch_ctrl->setOriginal(self->getWearable()->getClothesColor(entry->mTextureIndex)); + } +} + +static void init_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry) +{ + LLTextureCtrl* texture_ctrl = panel->getChild<LLTextureCtrl>(entry->mControlName); + if (texture_ctrl) + { + texture_ctrl->setDefaultImageAssetID(entry->mDefaultImageId); + texture_ctrl->setAllowNoTexture(entry->mAllowNoTexture); + // Don't allow (no copy) or (notransfer) textures to be selected. + texture_ctrl->setImmediateFilterPermMask(PERM_NONE); + texture_ctrl->setNonImmediateFilterPermMask(PERM_NONE); + } +} + +static void update_color_swatch_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry) +{ + LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild<LLColorSwatchCtrl>(entry->mControlName); + if (color_swatch_ctrl) + { + color_swatch_ctrl->set(self->getWearable()->getClothesColor(entry->mTextureIndex)); + } +} + +static void update_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry) +{ + LLTextureCtrl* texture_ctrl = panel->getChild<LLTextureCtrl>(entry->mControlName); + if (texture_ctrl) + { + LLUUID new_id; + LLLocalTextureObject *lto = self->getWearable()->getLocalTextureObject(entry->mTextureIndex); + if( lto && (lto->getID() != IMG_DEFAULT_AVATAR) ) + { + new_id = lto->getID(); + } + else + { + new_id = LLUUID::null; + } + LLUUID old_id = texture_ctrl->getImageAssetID(); + if (old_id != new_id) + { + // texture has changed, close the floater to avoid DEV-22461 + texture_ctrl->closeDependentFloater(); + } + texture_ctrl->setImageAssetID(new_id); + } +} + +static void set_enabled_color_swatch_ctrl(bool enabled, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry) +{ + LLColorSwatchCtrl* color_swatch_ctrl = panel->getChild<LLColorSwatchCtrl>(entry->mControlName); + if (color_swatch_ctrl) + { + color_swatch_ctrl->setEnabled(enabled); + } +} + +static void set_enabled_texture_ctrl(bool enabled, LLPanel* panel, const LLEditWearableDictionary::PickerControlEntry* entry) +{ + LLTextureCtrl* texture_ctrl = panel->getChild<LLTextureCtrl>(entry->mControlName); + if (texture_ctrl) + { + texture_ctrl->setEnabled(enabled); + } +} // LLPanelEditWearable @@ -273,6 +589,8 @@ LLPanelEditWearable::LLPanelEditWearable() , mWearablePtr(NULL) , mWearableItem(NULL) { + mCommitCallbackRegistrar.add("ColorSwatch.Commit", boost::bind(&LLPanelEditWearable::onColorSwatchCommit, this, _1)); + mCommitCallbackRegistrar.add("TexturePicker.Commit", boost::bind(&LLPanelEditWearable::onTexturePickerCommit, this, _1)); } //virtual @@ -341,6 +659,10 @@ BOOL LLPanelEditWearable::isDirty() const void LLPanelEditWearable::draw() { updateVerbs(); + if (getWearable()) + { + updatePanelPickerControls(getWearable()->getType()); + } LLPanel::draw(); } @@ -361,6 +683,102 @@ void LLPanelEditWearable::onRevertButtonClicked(void* userdata) panel->revertChanges(); } +void LLPanelEditWearable::onTexturePickerCommit(const LLUICtrl* ctrl) +{ + const LLTextureCtrl* texture_ctrl = dynamic_cast<const LLTextureCtrl*>(ctrl); + if (!texture_ctrl) + { + llwarns << "got commit signal from not LLTextureCtrl." << llendl; + return; + } + + if (getWearable()) + { + EWearableType type = getWearable()->getType(); + const PickerControlEntryNamePredicate name_pred(texture_ctrl->getName()); + const LLEditWearableDictionary::PickerControlEntry* entry + = find_picker_ctrl_entry_if<LLTextureCtrl, PickerControlEntryNamePredicate>(type, name_pred); + if (entry) + { + // Set the new version + LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_ctrl->getImageAssetID()); + if( image->getID().isNull() ) + { + image = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR); + } + if (getWearable()) + { + U32 index = gAgentWearables.getWearableIndex(getWearable()); + gAgentAvatarp->setLocalTexture(entry->mTextureIndex, image, FALSE, index); + LLVisualParamHint::requestHintUpdates(); + gAgentAvatarp->wearableUpdated(type, FALSE); + } + } + else + { + llwarns << "could not get texture picker dictionary entry for wearable of type: " << type << llendl; + } + } +} + +void LLPanelEditWearable::onColorSwatchCommit(const LLUICtrl* ctrl) +{ + if (getWearable()) + { + EWearableType type = getWearable()->getType(); + const PickerControlEntryNamePredicate name_pred(ctrl->getName()); + const LLEditWearableDictionary::PickerControlEntry* entry + = find_picker_ctrl_entry_if<LLColorSwatchCtrl, PickerControlEntryNamePredicate>(type, name_pred); + if (entry) + { + const LLColor4& old_color = getWearable()->getClothesColor(entry->mTextureIndex); + const LLColor4& new_color = LLColor4(ctrl->getValue()); + if( old_color != new_color ) + { + getWearable()->setClothesColor(entry->mTextureIndex, new_color, TRUE); + LLVisualParamHint::requestHintUpdates(); + gAgentAvatarp->wearableUpdated(getWearable()->getType(), FALSE); + } + } + else + { + llwarns << "could not get color swatch dictionary entry for wearable of type: " << type << llendl; + } + } +} + +void LLPanelEditWearable::updatePanelPickerControls(EWearableType type) +{ + LLPanel* panel = getPanel(type); + if (!panel) + return; + + bool is_modifiable = false; + bool is_complete = false; + bool is_copyable = false; + + if(mWearableItem) + { + const LLPermissions& perm = mWearableItem->getPermissions(); + is_modifiable = perm.allowModifyBy(gAgent.getID(), gAgent.getGroupID()); + is_copyable = perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID()); + is_complete = mWearableItem->isFinished(); + } + + if (is_modifiable && is_complete) + { + // Update picker controls + for_each_picker_ctrl_entry <LLColorSwatchCtrl> (panel, type, boost::bind(update_color_swatch_ctrl, this, _1, _2)); + for_each_picker_ctrl_entry <LLTextureCtrl> (panel, type, boost::bind(update_texture_ctrl, this, _1, _2)); + } + + if (!is_modifiable || !is_complete || !is_copyable) + { + // Disable controls + for_each_picker_ctrl_entry <LLColorSwatchCtrl> (panel, type, boost::bind(set_enabled_color_swatch_ctrl, false, _1, _2)); + for_each_picker_ctrl_entry <LLTextureCtrl> (panel, type, boost::bind(set_enabled_texture_ctrl, false, _1, _2)); + } +} void LLPanelEditWearable::saveChanges() { @@ -428,6 +846,9 @@ void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show) mDescTitle->setText(description_title); } + // Update picker controls state + for_each_picker_ctrl_entry <LLColorSwatchCtrl> (targetPanel, type, boost::bind(set_enabled_color_swatch_ctrl, show, _1, _2)); + for_each_picker_ctrl_entry <LLTextureCtrl> (targetPanel, type, boost::bind(set_enabled_texture_ctrl, show, _1, _2)); } void LLPanelEditWearable::initializePanel() @@ -493,6 +914,11 @@ void LLPanelEditWearable::initializePanel() updateScrollingPanelUI(); } + + // initialize texture and color picker controls + for_each_picker_ctrl_entry <LLColorSwatchCtrl> (getPanel(type), type, boost::bind(init_color_swatch_ctrl, this, _1, _2)); + for_each_picker_ctrl_entry <LLTextureCtrl> (getPanel(type), type, boost::bind(init_texture_ctrl, this, _1, _2)); + updateVerbs(); } diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h index 8b63685177..76b0ddb3cc 100644 --- a/indra/newview/llpaneleditwearable.h +++ b/indra/newview/llpaneleditwearable.h @@ -77,6 +77,10 @@ private: // update bottom bar buttons ("Save", "Revert", etc) void updateVerbs(); + void onColorSwatchCommit(const LLUICtrl*); + void onTexturePickerCommit(const LLUICtrl*); + void updatePanelPickerControls(EWearableType type); + // the pointer to the wearable we're editing. NULL means we're not editing a wearable. LLWearable *mWearablePtr; LLViewerInventoryItem* mWearableItem; @@ -112,7 +116,6 @@ private: LLPanel *mPanelSkirt; LLPanel *mPanelAlpha; LLPanel *mPanelTattoo; - }; #endif diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 67d40a39b1..0a978d1b26 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -583,6 +583,7 @@ void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list if (!inventory_list->getFilter()) return; + inventory_list->getFilter()->setEmptyLookupMessage("PlacesNoMatchingItems"); inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK); inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2)); diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index f60951ca66..f2c0f92f9b 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -443,6 +443,7 @@ public: LLPanelPeople::LLPanelPeople() : LLPanel(), mFilterSubString(LLStringUtil::null), + mFilterSubStringOrig(LLStringUtil::null), mFilterEditor(NULL), mTabContainer(NULL), mOnlineFriendList(NULL), @@ -658,7 +659,9 @@ void LLPanelPeople::updateFriendListHelpText() { //update help text for empty lists std::string message_name = mFilterSubString.empty() ? "no_friends_msg" : "no_filtered_friends_msg"; - no_friends_text->setText(getString(message_name)); + LLStringUtil::format_map_t args; + args["[SEARCH_TERM]"] = LLURI::escape(mFilterSubStringOrig); + no_friends_text->setText(getString(message_name, args)); } } @@ -981,10 +984,11 @@ bool LLPanelPeople::isRealGroup() void LLPanelPeople::onFilterEdit(const std::string& search_string) { - std::string search_upper = search_string; + mFilterSubStringOrig = search_string; + LLStringUtil::trimHead(mFilterSubStringOrig); // Searches are case-insensitive + std::string search_upper = mFilterSubStringOrig; LLStringUtil::toUpper(search_upper); - LLStringUtil::trimHead(search_upper); if (mFilterSubString == search_upper) return; @@ -999,11 +1003,11 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string) // Apply new filter. - mNearbyList->setNameFilter(mFilterSubString); - mOnlineFriendList->setNameFilter(mFilterSubString); - mAllFriendList->setNameFilter(mFilterSubString); - mRecentList->setNameFilter(mFilterSubString); - mGroupList->setNameFilter(mFilterSubString); + mNearbyList->setNameFilter(mFilterSubStringOrig); + mOnlineFriendList->setNameFilter(mFilterSubStringOrig); + mAllFriendList->setNameFilter(mFilterSubStringOrig); + mRecentList->setNameFilter(mFilterSubStringOrig); + mGroupList->setNameFilter(mFilterSubStringOrig); setAccordionCollapsedByUser("tab_online", false); setAccordionCollapsedByUser("tab_all", false); diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index 1bd3ea471c..17c45a034b 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -169,6 +169,7 @@ private: Updater* mRecentListUpdater; std::string mFilterSubString; + std::string mFilterSubStringOrig; }; #endif //LL_LLPANELPEOPLE_H diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 89293d0e50..51a11e97e4 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -528,8 +528,7 @@ void LLPanelPlaces::onFilterEdit(const std::string& search_string, bool force_fi std::string string = search_string; // Searches are case-insensitive - LLStringUtil::toUpper(string); - LLStringUtil::trimHead(string); + // but we don't convert the typed string to upper-case so that it can be fed to the web search as-is. mActivePanel->onSearchEdit(string); } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index d03a492cd1..2c26bada20 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -3624,14 +3624,14 @@ void LLSelectMgr::sendAttach(U8 attachment_point) return; } -#if ENABLE_MULTIATTACHMENTS - attachment_point |= ATTACHMENT_ADD; -#endif BOOL build_mode = LLToolMgr::getInstance()->inEdit(); // Special case: Attach to default location for this object. if (0 == attachment_point || get_if_there(gAgentAvatarp->mAttachmentPoints, (S32)attachment_point, (LLViewerJointAttachment*)NULL)) { +#if ENABLE_MULTIATTACHMENTS + attachment_point |= ATTACHMENT_ADD; +#endif sendListToRegions( "ObjectAttach", packAgentIDAndSessionAndAttachment, diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 87494daaa9..f38df19de0 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -197,8 +197,7 @@ void LLSidepanelAppearance::onFilterEdit(const std::string& search_string) mFilterSubString = search_string; // Searches are case-insensitive - LLStringUtil::toUpper(mFilterSubString); - LLStringUtil::trimHead(mFilterSubString); + // but we don't convert the typed string to upper-case so that it can be fed to the web search as-is. mPanelOutfitsInventory->onSearchEdit(mFilterSubString); } diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index e64696b120..3d447dd411 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -167,8 +167,6 @@ public: } protected: - LLTextureFetchWorker(LLTextureFetch* fetcher, const LLUUID& id, const LLHost& host, - F32 priority, S32 discard, S32 size); LLTextureFetchWorker(LLTextureFetch* fetcher, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, S32 discard, S32 size); @@ -215,8 +213,15 @@ private: QUEUED = 1, SENT_SIM = 2 }; + enum e_write_to_cache_state //mWriteToCacheState + { + NOT_WRITE = 0, + CAN_WRITE = 1, + SHOULD_WRITE = 2 + }; static const char* sStateDescs[]; e_state mState; + e_write_to_cache_state mWriteToCacheState; LLTextureFetch* mFetcher; LLPointer<LLImageFormatted> mFormattedImage; LLPointer<LLImageRaw> mRawImage; @@ -377,6 +382,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, S32 size) // Desired size : LLWorkerClass(fetcher, "TextureFetch"), mState(INIT), + mWriteToCacheState(NOT_WRITE), mFetcher(fetcher), mID(id), mHost(host), @@ -595,7 +601,7 @@ bool LLTextureFetchWorker::doWork(S32 param) } if (mState == INIT) - { + { mRawImage = NULL ; mRequestedDiscard = -1; mLoadedDiscard = -1; @@ -636,17 +642,18 @@ bool LLTextureFetchWorker::doWork(S32 param) mFileSize = 0; mLoaded = FALSE; setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it - - CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage); + if (mUrl.compare(0, 7, "file://") == 0) { // read file from local disk std::string filename = mUrl.substr(7, std::string::npos); + CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage); mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority, offset, size, responder); } else if (mUrl.empty()) { + CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage); mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority, offset, size, responder); } @@ -659,8 +666,6 @@ bool LLTextureFetchWorker::doWork(S32 param) } setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); mState = SEND_HTTP_REQ; - delete responder; - responder = NULL; } } @@ -694,6 +699,7 @@ bool LLTextureFetchWorker::doWork(S32 param) llassert_always(mFormattedImage->getDataSize() > 0); mLoadedDiscard = mDesiredDiscard; mState = DECODE_IMAGE; + mWriteToCacheState = NOT_WRITE ; LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize() << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight()) << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; @@ -735,6 +741,7 @@ bool LLTextureFetchWorker::doWork(S32 param) if (!http_url.empty()) { mUrl = http_url + "/?texture_id=" + mID.asString().c_str(); + mWriteToCacheState = CAN_WRITE ; //because this texture has a fixed texture id. } } else @@ -747,12 +754,17 @@ bool LLTextureFetchWorker::doWork(S32 param) { mState = LLTextureFetchWorker::SEND_HTTP_REQ; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); + if(mWriteToCacheState != NOT_WRITE) + { + mWriteToCacheState = CAN_WRITE ; + } // don't return, fall through to next state } else if (mSentRequest == UNSENT) { // Add this to the network queue and sit here. // LLTextureFetch::update() will send off a request which will change our state + mWriteToCacheState = CAN_WRITE ; mRequestedSize = mDesiredSize; mRequestedDiscard = mDesiredDiscard; mSentRequest = QUEUED; @@ -789,6 +801,7 @@ bool LLTextureFetchWorker::doWork(S32 param) } setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); mState = DECODE_IMAGE; + mWriteToCacheState = SHOULD_WRITE ; } else { @@ -850,7 +863,6 @@ bool LLTextureFetchWorker::doWork(S32 param) mState = WAIT_HTTP_REQ; mFetcher->addToHTTPQueue(mID); - mSentRequest = QUEUED; // Will call callbackHttpGet when curl request completes std::vector<std::string> headers; headers.push_back("Accept: image/x-j2c"); @@ -933,15 +945,15 @@ bool LLTextureFetchWorker::doWork(S32 param) } llassert_always(mBufferSize == cur_size + mRequestedSize); - if (mHaveAllData) + if (mHaveAllData && mRequestedDiscard == 0) //the image file is fully loaded. { mFileSize = mBufferSize; } - else //the file size is unknown + else //the file size is unknown. { - mFileSize = S32_MAX ; //flag the file is not fully loaded. + mFileSize = mBufferSize + 1 ; //flag the file is not fully loaded. } - + U8* buffer = new U8[mBufferSize]; if (cur_size > 0) { @@ -956,6 +968,10 @@ bool LLTextureFetchWorker::doWork(S32 param) mBufferSize = 0; mLoadedDiscard = mRequestedDiscard; mState = DECODE_IMAGE; + if(mWriteToCacheState != NOT_WRITE) + { + mWriteToCacheState = SHOULD_WRITE ; + } setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); return false; } @@ -1055,7 +1071,7 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mState == WRITE_TO_CACHE) { - if (mInLocalCache || mSentRequest == UNSENT || mFormattedImage.isNull()) + if (mWriteToCacheState != SHOULD_WRITE || mFormattedImage.isNull()) { // If we're in a local cache or we didn't actually receive any new data, // or we failed to load anything, skip @@ -1063,6 +1079,17 @@ bool LLTextureFetchWorker::doWork(S32 param) return false; } S32 datasize = mFormattedImage->getDataSize(); + if(mFileSize < datasize)//This could happen when http fetching and sim fetching mixed. + { + if(mHaveAllData) + { + mFileSize = datasize ; + } + else + { + mFileSize = datasize + 1 ; //flag not fully loaded. + } + } llassert_always(datasize); setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it U32 cache_priority = mWorkPriority; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 3d042a8d8c..5dd9623955 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1091,7 +1091,7 @@ void open_inventory_offer(const uuid_vec_t& items, const std::string& from_name) //////////////////////////////////////////////////////////////////////////////// // Special handling for various types. - const LLAssetType::EType asset_type = item->getType(); + const LLAssetType::EType asset_type = item->getActualType(); if (check_offer_throttle(from_name, false)) // If we are throttled, don't display { LL_DEBUGS("Messaging") << "Highlighting inventory item: " << item->getUUID() << LL_ENDL; diff --git a/indra/newview/skins/default/textures/icons/Progress_1.png b/indra/newview/skins/default/textures/icons/Progress_1.png Binary files differindex 58b56003c4..5d6efbfa2a 100644 --- a/indra/newview/skins/default/textures/icons/Progress_1.png +++ b/indra/newview/skins/default/textures/icons/Progress_1.png diff --git a/indra/newview/skins/default/textures/icons/Progress_10.png b/indra/newview/skins/default/textures/icons/Progress_10.png Binary files differindex 07fe0be8a3..28203324f1 100644 --- a/indra/newview/skins/default/textures/icons/Progress_10.png +++ b/indra/newview/skins/default/textures/icons/Progress_10.png diff --git a/indra/newview/skins/default/textures/icons/Progress_11.png b/indra/newview/skins/default/textures/icons/Progress_11.png Binary files differindex 215d68cc46..6b87be0c3f 100644 --- a/indra/newview/skins/default/textures/icons/Progress_11.png +++ b/indra/newview/skins/default/textures/icons/Progress_11.png diff --git a/indra/newview/skins/default/textures/icons/Progress_12.png b/indra/newview/skins/default/textures/icons/Progress_12.png Binary files differindex d755588621..089d58b090 100644 --- a/indra/newview/skins/default/textures/icons/Progress_12.png +++ b/indra/newview/skins/default/textures/icons/Progress_12.png diff --git a/indra/newview/skins/default/textures/icons/Progress_2.png b/indra/newview/skins/default/textures/icons/Progress_2.png Binary files differindex 6640ee227b..94cb73b1f7 100644 --- a/indra/newview/skins/default/textures/icons/Progress_2.png +++ b/indra/newview/skins/default/textures/icons/Progress_2.png diff --git a/indra/newview/skins/default/textures/icons/Progress_3.png b/indra/newview/skins/default/textures/icons/Progress_3.png Binary files differindex 5decbe977e..a04a5b5263 100644 --- a/indra/newview/skins/default/textures/icons/Progress_3.png +++ b/indra/newview/skins/default/textures/icons/Progress_3.png diff --git a/indra/newview/skins/default/textures/icons/Progress_4.png b/indra/newview/skins/default/textures/icons/Progress_4.png Binary files differindex 56e81c17aa..a467098d82 100644 --- a/indra/newview/skins/default/textures/icons/Progress_4.png +++ b/indra/newview/skins/default/textures/icons/Progress_4.png diff --git a/indra/newview/skins/default/textures/icons/Progress_5.png b/indra/newview/skins/default/textures/icons/Progress_5.png Binary files differindex a89bf2ac62..ea64f1d907 100644 --- a/indra/newview/skins/default/textures/icons/Progress_5.png +++ b/indra/newview/skins/default/textures/icons/Progress_5.png diff --git a/indra/newview/skins/default/textures/icons/Progress_6.png b/indra/newview/skins/default/textures/icons/Progress_6.png Binary files differindex 233c479540..fe4447935f 100644 --- a/indra/newview/skins/default/textures/icons/Progress_6.png +++ b/indra/newview/skins/default/textures/icons/Progress_6.png diff --git a/indra/newview/skins/default/textures/icons/Progress_7.png b/indra/newview/skins/default/textures/icons/Progress_7.png Binary files differindex 631d7a6819..64fa294771 100644 --- a/indra/newview/skins/default/textures/icons/Progress_7.png +++ b/indra/newview/skins/default/textures/icons/Progress_7.png diff --git a/indra/newview/skins/default/textures/icons/Progress_8.png b/indra/newview/skins/default/textures/icons/Progress_8.png Binary files differindex ac0e3f13f7..a1c9a7f2eb 100644 --- a/indra/newview/skins/default/textures/icons/Progress_8.png +++ b/indra/newview/skins/default/textures/icons/Progress_8.png diff --git a/indra/newview/skins/default/textures/icons/Progress_9.png b/indra/newview/skins/default/textures/icons/Progress_9.png Binary files differindex 17fb4a0335..f3e9723184 100644 --- a/indra/newview/skins/default/textures/icons/Progress_9.png +++ b/indra/newview/skins/default/textures/icons/Progress_9.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 1080ff347c..bbb82d86b1 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -580,17 +580,17 @@ with the same filename but different name <texture name="default_profile_picture.j2c" /> <texture name="locked_image.j2c" /> - <texture name="Progress_1" file_name="icons/Progress_1.png" preload="false" /> - <texture name="Progress_2" file_name="icons/Progress_2.png" preload="false" /> - <texture name="Progress_3" file_name="icons/Progress_3.png" preload="false" /> - <texture name="Progress_4" file_name="icons/Progress_4.png" preload="false" /> - <texture name="Progress_5" file_name="icons/Progress_5.png" preload="false" /> - <texture name="Progress_6" file_name="icons/Progress_6.png" preload="false" /> - <texture name="Progress_7" file_name="icons/Progress_7.png" preload="false" /> - <texture name="Progress_8" file_name="icons/Progress_8.png" preload="false" /> - <texture name="Progress_9" file_name="icons/Progress_9.png" preload="false" /> - <texture name="Progress_10" file_name="icons/Progress_10.png" preload="false" /> - <texture name="Progress_11" file_name="icons/Progress_11.png" preload="false" /> - <texture name="Progress_12" file_name="icons/Progress_12.png" preload="false" /> + <texture name="Progress_1" file_name="icons/Progress_1.png" preload="true" /> + <texture name="Progress_2" file_name="icons/Progress_2.png" preload="true" /> + <texture name="Progress_3" file_name="icons/Progress_3.png" preload="true" /> + <texture name="Progress_4" file_name="icons/Progress_4.png" preload="true" /> + <texture name="Progress_5" file_name="icons/Progress_5.png" preload="true" /> + <texture name="Progress_6" file_name="icons/Progress_6.png" preload="true" /> + <texture name="Progress_7" file_name="icons/Progress_7.png" preload="true" /> + <texture name="Progress_8" file_name="icons/Progress_8.png" preload="true" /> + <texture name="Progress_9" file_name="icons/Progress_9.png" preload="true" /> + <texture name="Progress_10" file_name="icons/Progress_10.png" preload="true" /> + <texture name="Progress_11" file_name="icons/Progress_11.png" preload="true" /> + <texture name="Progress_12" file_name="icons/Progress_12.png" preload="true" /> </textures> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 5e1f6b58e8..11459ad0e6 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -410,6 +410,14 @@ parameter="open" /> </menu_item_call> <menu_item_call + label="Open Original" + layout="topleft" + name="Open Original"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="open_original" /> + </menu_item_call> + <menu_item_call label="Properties" layout="topleft" name="Properties"> diff --git a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml index b3150bb98b..5fcc9b012b 100644 --- a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml +++ b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <!-- *NOTE: mantipov: this xml is intended to be used inside panel_outfits_list.xml for each outfit folder--> <!-- All accordion tabs in the My Appearance/My Outfits panel will be created from this one at runtime--> +<!-- Non of string values of controls below are visible to user. They are not need to be translated. --> <accordion_tab display_children="false" follows="all" @@ -8,11 +9,13 @@ layout="topleft" name="Mockup Tab" title="Mockup Tab" + translate="false" width="0"> <wearable_items_list allow_select="true" follows="all" keep_one_selected="true" name="wearable_items_list" + translate="false" /> </accordion_tab> diff --git a/indra/newview/skins/default/xui/en/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/en/panel_bodyparts_list_button_bar.xml new file mode 100644 index 0000000000..9d19b89a61 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_bodyparts_list_button_bar.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> + +<panel + follows="left|right|top" + height="35" + layout="topleft" + left="0" + name="clothing_list_button_bar_panel" + top="0" + visible="true" + width="300"> + <button + follows="top|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + label="Switch" + layout="topleft" + left="5" + name="switch_btn" + top="5" + width="45" /> + <button + follows="top|right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + label="Shop >" + layout="topleft" + right="-5" + name="bodyparts_shop_btn" + top="5" + width="61" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/en/panel_clothing_list_button_bar.xml new file mode 100644 index 0000000000..2359719c2a --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_clothing_list_button_bar.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> + +<panel + follows="left|right|top" + height="35" + layout="topleft" + left="0" + name="clothing_list_button_bar_panel" + top="0" + visible="true" + width="500"> + <button + follows="top|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + is_toggle="true" + label="Add +" + layout="topleft" + left="5" + name="add_btn" + top="5" + width="45" /> + <button + follows="top|right" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + label="Shop >" + layout="topleft" + right="-5" + name="clothing_shop_btn" + top="5" + width="61" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml index 01c7ae61d2..d8a8dbbea4 100644 --- a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml +++ b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml @@ -14,6 +14,7 @@ height="373" layout="topleft" left="3" + single_expansion="true" top="0" name="cof_wearables_accordion" background_visible="true" diff --git a/indra/newview/skins/default/xui/en/panel_edit_alpha.xml b/indra/newview/skins/default/xui/en/panel_edit_alpha.xml index 1d0c0a02b0..cfcdc25f81 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_alpha.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_alpha.xml @@ -32,7 +32,10 @@ name="Lower Alpha" tool_tip="Click to choose a picture" top="10" - width="94" /> + width="94" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <check_box control_name="LowerAlphaTextureInvisible" follows="left" @@ -53,7 +56,10 @@ name="Upper Alpha" tool_tip="Click to choose a picture" top="10" - width="94" /> + width="94"> + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <check_box control_name="UpperAlphaTextureInvisible" follows="left" @@ -74,7 +80,10 @@ name="Head Alpha" tool_tip="Click to choose a picture" top="120" - width="94" /> + width="94" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <check_box control_name="HeadAlphaTextureInvisible" follows="left" @@ -95,7 +104,10 @@ name="Eye Alpha" tool_tip="Click to choose a picture" top="120" - width="94" /> + width="94" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <check_box control_name="Eye AlphaTextureInvisible" follows="left" @@ -116,7 +128,10 @@ name="Hair Alpha" tool_tip="Click to choose a picture" top="230" - width="94" /> + width="94" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <check_box control_name="HairAlphaTextureInvisible" follows="left" diff --git a/indra/newview/skins/default/xui/en/panel_edit_eyes.xml b/indra/newview/skins/default/xui/en/panel_edit_eyes.xml index f11ef43c76..4149a0b06f 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_eyes.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_eyes.xml @@ -32,8 +32,11 @@ name="Iris" tool_tip="Click to choose a picture" top="10" - width="64" /> - </panel> + width="64" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + </panel> <panel border="false" bg_alpha_color="DkGray2" diff --git a/indra/newview/skins/default/xui/en/panel_edit_gloves.xml b/indra/newview/skins/default/xui/en/panel_edit_gloves.xml index 7d8eed5085..94fd2f9080 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_gloves.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_gloves.xml @@ -32,7 +32,10 @@ name="Fabric" tool_tip="Click to choose a picture" top="10" - width="64" /> + width="64" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <color_swatch can_apply_immediately="true" follows="left|top" @@ -43,9 +46,12 @@ name="Color/Tint" tool_tip="Click to open color picker" top="10" - width="64" /> - </panel> - <panel + width="64" > + <color_swatch.commit_callback + function="ColorSwatch.Commit" /> + </color_swatch> + </panel> + <panel border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" diff --git a/indra/newview/skins/default/xui/en/panel_edit_hair.xml b/indra/newview/skins/default/xui/en/panel_edit_hair.xml index cd81aa2c4f..9b60e83387 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_hair.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_hair.xml @@ -32,8 +32,11 @@ name="Texture" tool_tip="Click to choose a picture" top="10" - width="64" /> - </panel> + width="64" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + </panel> <panel border="false" bg_alpha_color="DkGray2" diff --git a/indra/newview/skins/default/xui/en/panel_edit_jacket.xml b/indra/newview/skins/default/xui/en/panel_edit_jacket.xml index ba03865937..248ae9fe04 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_jacket.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_jacket.xml @@ -32,7 +32,10 @@ name="Upper Fabric" tool_tip="Click to choose a picture" top="10" - width="74" /> + width="74" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <texture_picker can_apply_immediately="true" default_image_name="Default" @@ -44,7 +47,10 @@ name="Lower Fabric" tool_tip="Click to choose a picture" top="10" - width="74" /> + width="74" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <color_swatch can_apply_immediately="true" follows="left|top" @@ -55,7 +61,10 @@ name="Color/Tint" tool_tip="Click to open color picker" top="10" - width="74" /> + width="74" > + <color_swatch.commit_callback + function="ColorSwatch.Commit" /> + </color_swatch> </panel> <panel border="false" diff --git a/indra/newview/skins/default/xui/en/panel_edit_pants.xml b/indra/newview/skins/default/xui/en/panel_edit_pants.xml index 5b02d1f968..3ed1df2399 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_pants.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_pants.xml @@ -32,7 +32,10 @@ name="Fabric" tool_tip="Click to choose a picture" top="10" - width="64" /> + width="64" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <color_swatch can_apply_immediately="true" follows="left|top" @@ -43,7 +46,10 @@ name="Color/Tint" tool_tip="Click to open color picker" top="10" - width="64" /> + width="64" > + <color_swatch.commit_callback + function="ColorSwatch.Commit" /> + </color_swatch> </panel> <panel border="false" diff --git a/indra/newview/skins/default/xui/en/panel_edit_shirt.xml b/indra/newview/skins/default/xui/en/panel_edit_shirt.xml index 7da8de4c0b..e088aa05ac 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_shirt.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_shirt.xml @@ -32,7 +32,10 @@ name="Fabric" tool_tip="Click to choose a picture" top="10" - width="64" /> + width="64" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <color_swatch can_apply_immediately="true" follows="left|top" @@ -43,7 +46,10 @@ name="Color/Tint" tool_tip="Click to open color picker" top="10" - width="64" /> + width="64" > + <color_swatch.commit_callback + function="ColorSwatch.Commit" /> + </color_swatch> </panel> <panel border="false" diff --git a/indra/newview/skins/default/xui/en/panel_edit_shoes.xml b/indra/newview/skins/default/xui/en/panel_edit_shoes.xml index 84fe26f7f6..e079047a86 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_shoes.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_shoes.xml @@ -32,7 +32,10 @@ name="Fabric" tool_tip="Click to choose a picture" top="10" - width="64" /> + width="64" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <color_swatch can_apply_immediately="true" follows="left|top" @@ -43,7 +46,10 @@ name="Color/Tint" tool_tip="Click to open color picker" top="10" - width="64" /> + width="64" > + <color_swatch.commit_callback + function="ColorSwatch.Commit" /> + </color_swatch> </panel> <panel border="false" diff --git a/indra/newview/skins/default/xui/en/panel_edit_skin.xml b/indra/newview/skins/default/xui/en/panel_edit_skin.xml index b5c8c95473..9158685c40 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_skin.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_skin.xml @@ -33,7 +33,10 @@ name="Head Tattoos" tool_tip="Click to choose a picture" top="10" - width="74" /> + width="74" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <texture_picker allow_no_texture="true" can_apply_immediately="true" @@ -46,7 +49,10 @@ name="Upper Tattoos" tool_tip="Click to choose a picture" top="10" - width="74" /> + width="74" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <texture_picker allow_no_texture="true" can_apply_immediately="true" @@ -59,8 +65,11 @@ name="Lower Tattoos" tool_tip="Click to choose a picture" top="10" - width="74" /> - </panel> + width="74" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + </panel> <panel border="false" bg_alpha_color="DkGray2" diff --git a/indra/newview/skins/default/xui/en/panel_edit_skirt.xml b/indra/newview/skins/default/xui/en/panel_edit_skirt.xml index 16f6950bd5..87f3270b31 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_skirt.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_skirt.xml @@ -32,7 +32,10 @@ name="Fabric" tool_tip="Click to choose a picture" top="10" - width="64" /> + width="64" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <color_swatch can_apply_immediately="true" follows="left|top" @@ -43,7 +46,10 @@ name="Color/Tint" tool_tip="Click to open color picker" top="10" - width="64" /> + width="64" > + <color_swatch.commit_callback + function="ColorSwatch.Commit" /> + </color_swatch> </panel> <panel border="false" diff --git a/indra/newview/skins/default/xui/en/panel_edit_socks.xml b/indra/newview/skins/default/xui/en/panel_edit_socks.xml index e4f916703b..5bd99969a2 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_socks.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_socks.xml @@ -32,7 +32,10 @@ name="Fabric" tool_tip="Click to choose a picture" top="10" - width="64" /> + width="64" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <color_swatch can_apply_immediately="true" follows="left|top" @@ -43,7 +46,10 @@ name="Color/Tint" tool_tip="Click to open color picker" top="10" - width="64" /> + width="64" > + <color_swatch.commit_callback + function="ColorSwatch.Commit" /> + </color_swatch> </panel> <panel border="false" diff --git a/indra/newview/skins/default/xui/en/panel_edit_underpants.xml b/indra/newview/skins/default/xui/en/panel_edit_underpants.xml index d43497c943..bbe5230341 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_underpants.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_underpants.xml @@ -32,7 +32,10 @@ name="Fabric" tool_tip="Click to choose a picture" top="10" - width="64" /> + width="64" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <color_swatch can_apply_immediately="true" follows="left|top" @@ -43,7 +46,10 @@ name="Color/Tint" tool_tip="Click to open color picker" top="10" - width="64" /> + width="64" > + <color_swatch.commit_callback + function="ColorSwatch.Commit" /> + </color_swatch> </panel> <panel border="false" diff --git a/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml index 45c6ef4526..a79c1b9eaa 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml @@ -32,7 +32,10 @@ name="Fabric" tool_tip="Click to choose a picture" top="10" - width="64" /> + width="64" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> <color_swatch can_apply_immediately="true" follows="left|top" @@ -43,7 +46,10 @@ name="Color/Tint" tool_tip="Click to open Color Picker" top="10" - width="64" /> + width="64" > + <color_swatch.commit_callback + function="ColorSwatch.Commit" /> + </color_swatch> </panel> <panel border="false" diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml index 27d66945d9..46625144e1 100644 --- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml @@ -3,7 +3,7 @@ background_visible="true" default_tab_group="1" follows="all" - height="408" + height="423" label="Things" layout="topleft" min_height="350" @@ -48,7 +48,7 @@ left="10" max_length="300" name="inventory search editor" - top="3" + top="18" width="303" /> <tab_container bg_alpha_color="DkGray" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index fa4213667b..066ea3be6e 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -16,13 +16,13 @@ value="No recent people. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]." /> <string name="no_filtered_recent_people" - value="Didn't find what you're looking for? Try [secondlife:///app/search/people Search]." /> + value="Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]." /> <string name="no_one_near" value="No one nearby. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]." /> <string name="no_one_filtered_near" - value="Didn't find what you're looking for? Try [secondlife:///app/search/people Search]." /> + value="Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]." /> <string name="no_friends_online" value="No friends online" /> @@ -36,7 +36,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M </string> <string name="no_filtered_friends_msg"> - Didn't find what you're looking for? Try [secondlife:///app/search/people Search]. + Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]. </string> <string name="people_filter_label" @@ -50,7 +50,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M --> <string name="no_filtered_groups_msg" - value="Didn't find what you're looking for? Try [secondlife:///app/search/groups Search]." /> + value="Didn't find what you're looking for? Try [secondlife:///app/search/groups/[SEARCH_TERM] Search]." /> <string name="no_groups_msg" value="Looking for Groups to join? Try [secondlife:///app/search/groups Search]." /> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index bf30e89a59..3cba76cbfa 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -1842,7 +1842,8 @@ Clears (deletes) the media and all params from the given face. <string name="LeaveMouselook">Press ESC to return to World View</string> <!-- inventory --> - <string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all Search].</string> + <string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].</string> + <string name="PlacesNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search].</string> <string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string> <string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string> <!-- use value="" because they have preceding spaces --> @@ -2950,8 +2951,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <!-- voice calls --> <string name="answered_call">Your call has been answered</string> - <string name="started_call">Started a voice call</string> - <string name="joined_call">Joined the voice call</string> + <string name="you_started_call">You started a voice call</string> + <string name="you_joined_call">You joined the voice call</string> + <string name="name_started_call">[NAME] started a voice call</string> <string name="ringing-im"> Joining voice call... diff --git a/indra/newview/skins/default/xui/it/menu_participant_list.xml b/indra/newview/skins/default/xui/it/menu_participant_list.xml index e641d38508..0da1d116b4 100644 --- a/indra/newview/skins/default/xui/it/menu_participant_list.xml +++ b/indra/newview/skins/default/xui/it/menu_participant_list.xml @@ -15,6 +15,6 @@ <menu_item_call label="Disattiva audio di questo participante" name="ModerateVoiceMuteSelected"/> <menu_item_call label="Disattiva audio di tutti gli altri" name="ModerateVoiceMuteOthers"/> <menu_item_call label="Riattiva audio di questo participante" name="ModerateVoiceUnMuteSelected"/> - <menu_item_call label="Disattiva audio di tutti gli altri" name="ModerateVoiceUnMuteOthers"/> + <menu_item_call label="Riattiva audio di tutti gli altri" name="ModerateVoiceUnMuteOthers"/> </context_menu> </context_menu> diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml index 6736c6a6f1..f1b87bc002 100644 --- a/indra/newview/skins/default/xui/it/notifications.xml +++ b/indra/newview/skins/default/xui/it/notifications.xml @@ -898,7 +898,7 @@ Unisci il terreno? In genere si tratta di un problema temporaneo. Attendi alcuni minuti per modificare e salvare nuovamente gli elementi indossabili. </notification> <notification name="YouHaveBeenLoggedOut"> - Accidenti. Sei stato scollegato da [SECOND_LIFE] + Sei stato scollegato da [SECOND_LIFE]. [MESSAGE] <usetemplate name="okcancelbuttons" notext="Esci" yestext="Vedi IM & Chat"/> </notification> diff --git a/indra/newview/skins/default/xui/it/panel_edit_pick.xml b/indra/newview/skins/default/xui/it/panel_edit_pick.xml index d2d97cfc71..f93b953eac 100644 --- a/indra/newview/skins/default/xui/it/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/it/panel_edit_pick.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Modifica scelta" name="panel_edit_pick"> +<panel label="Modifica preferito" name="panel_edit_pick"> <panel.string name="location_notice"> (si aggiornerà dopo il salvataggio) </panel.string> <text name="title"> - Modifica scelta + Modifica preferito </text> <scroll_container name="profile_scroll"> <panel name="scroll_content_panel"> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml index c24d3f656a..1d05f28d46 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml @@ -13,10 +13,10 @@ </text> <check_box label="Costruire/Modificare" name="edit_camera_movement" tool_tip="Utilizza il posizionamento automatico della fotocamera entrando o uscendo dalla modalità modifica"/> <check_box label="Aspetto fisico" name="appearance_camera_movement" tool_tip="Utilizza il posizionamento automatico della camera in modalità modifica"/> - <check_box label="Mostra in modalità Mouselook" name="first_person_avatar_visible"/> + <check_box label="Visualizzami in modalità soggettiva" name="first_person_avatar_visible"/> <check_box label="Le frecce di direzione mi fanno sempre spostare" name="arrow_keys_move_avatar_check"/> <check_box label="Doppio click e tieni premuto per correre" name="tap_tap_hold_to_run"/> - <check_box label="Consente il movimento delle labbra dell'avatar quando parla" name="enable_lip_sync"/> + <check_box label="Movimento delle labbra dell'avatar quando parla" name="enable_lip_sync"/> <check_box label="Chat a bolla" name="bubble_text_chat"/> <slider label="Opacità" name="bubble_chat_opacity"/> <color_swatch name="background" tool_tip="Scegli il colore delle vignette della chat"/> diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index a1b570d716..de9c5ba45b 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -886,13 +886,13 @@ Alto </string> <string name="LeaveMouselook"> - Premi ESC per tornare in visulizzazione normale + Premi ESC per tornare in visualizzazione normale </string> <string name="InventoryNoMatchingItems"> Nessun oggetto corrispondente trovato in inventario. Prova [secondlife:///app/search/groups "Cerca"]. </string> <string name="FavoritesNoMatchingItems"> - Trascina qui un punto di riferimento per aggiungerlo ai tuoi preferiti. + Trascina qui un punto di riferimento per aggiungerlo ai Preferiti. </string> <string name="InventoryNoTexture"> Non hai una copia di questa texture nel tuo inventario @@ -1566,7 +1566,7 @@ (si aggiornerà dopo la pubblicazione) </string> <string name="NoPicksClassifiedsText"> - Non hai creato luoghi preferiti né inserzioni. Clicca il pulsante più qui sotto per creare un luogo preferito o un'inserzione. + Non hai creato luoghi preferiti né inserzioni. Clicca il pulsante + qui sotto per creare un luogo preferito o un'inserzione. </string> <string name="NoAvatarPicksClassifiedsText"> L'utente non ha luoghi preferiti né inserzioni diff --git a/indra/newview/skins/default/xui/it/teleport_strings.xml b/indra/newview/skins/default/xui/it/teleport_strings.xml index c11d41f6b9..7a1046abd3 100644 --- a/indra/newview/skins/default/xui/it/teleport_strings.xml +++ b/indra/newview/skins/default/xui/it/teleport_strings.xml @@ -66,7 +66,7 @@ Se si continua a visualizzare questo messaggio, consulta la pagina [SUPPORT_SITE Elaborazione della destinazione in corso... </message> <message name="contacting"> - Contattando la nuova regione. + Contatto in corso con la nuova regione. </message> <message name="arriving"> In arrivo a destinazione... |