diff options
215 files changed, 2954 insertions, 4433 deletions
@@ -537,3 +537,4 @@ ad0e15543836d64d6399d28b32852510435e344a 5.1.0-release 7c00e5b6cb3d95712e9d8e29277c805bca2bda90 5.1.3-release 7b6b020fd5ad9a8dc3670c5c92d1ca92e55fc485 5.1.4-release 2ea47f358b171178eb9a95503a1670d519c2886f 5.1.5-release +04538b8157c1f5cdacd9403f0a395452d4a93689 5.1.6-release diff --git a/autobuild.xml b/autobuild.xml index 0d3c6d3a53..a1dc500c14 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3326,9 +3326,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>4aefe12a3825d1b4b8370986d84792a2</string> + <string>86f6708f393c162cd4f92426b0a3cde7</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15295/98583/viewer_manager-1.0.513540-darwin64-513540.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15341/99062/viewer_manager-1.0.513570-darwin64-513570.tar.bz2</string> </map> <key>name</key> <string>darwin64</string> @@ -3350,9 +3350,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>db96bc8a83e6577d31657586100bfc35</string> + <string>c4dec51062ad78c09b11f7432aff4d1d</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15298/98589/viewer_manager-1.0.513540-windows-513540.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/17857/121832/viewer_manager-1.0.515286-windows-515286.tar.bz2</string> </map> <key>name</key> <string>windows</string> @@ -3363,7 +3363,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>source_type</key> <string>hg</string> <key>version</key> - <string>1.0.513540</string> + <string>1.0.515286</string> </map> <key>vlc-bin</key> <map> diff --git a/doc/contributions.txt b/doc/contributions.txt index 90bbb1c2c6..039d00cbbf 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -220,6 +220,7 @@ Ansariel Hiller STORM-2151 MAINT-6917 MAINT-8085 + STORM-2122 Aralara Rajal Arare Chantilly CHUIBUG-191 diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index 63069adcc8..6079913a8e 100644 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -184,7 +184,7 @@ void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp) { LLTexLayerSet *layer_set = NULL; const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te); - if (texture_dict->mIsUsedByBakedTexture) + if (texture_dict && texture_dict->mIsUsedByBakedTexture) { const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; @@ -197,7 +197,7 @@ void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp) } else { - LL_ERRS() << "could not find layerset for LTO in wearable!" << LL_ENDL; + LL_WARNS() << "could not find layerset for LTO in wearable!" << LL_ENDL; } } @@ -437,7 +437,13 @@ LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, LL_WARNS() << "Bad Wearable asset: bad texture, #" << i << LL_ENDL; return LLWearable::FAILURE; } - + + if (te >= ETextureIndex::TEX_NUM_INDICES) //createLayers() converts to ETextureIndex + { + LL_WARNS() << "Bad Wearable asset: bad texture index: " << te << LL_ENDL; + return LLWearable::FAILURE; + } + if( !LLUUID::validate( uuid_buffer ) ) { LL_WARNS() << "Bad Wearable asset: bad texture uuid: " diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 8aa41035b9..fc203f78e1 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -258,7 +258,7 @@ int LLFile::remove(const std::string& filename, int supress_error) return warnif("remove", filename, rc, supress_error); } -int LLFile::rename(const std::string& filename, const std::string& newname) +int LLFile::rename(const std::string& filename, const std::string& newname, int supress_error) { #if LL_WINDOWS std::string utf8filename = filename; @@ -269,7 +269,7 @@ int LLFile::rename(const std::string& filename, const std::string& newname) #else int rc = ::rename(filename.c_str(),newname.c_str()); #endif - return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc); + return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc, supress_error); } bool LLFile::copy(const std::string from, const std::string to) diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index ba935b8714..398938b729 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -74,7 +74,7 @@ public: static int rmdir(const std::string& filename); static int remove(const std::string& filename, int supress_error = 0); - static int rename(const std::string& filename,const std::string& newname); + static int rename(const std::string& filename,const std::string& newname, int supress_error = 0); static bool copy(const std::string from, const std::string to); static int stat(const std::string& filename,llstat* file_status); diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp index 8836230640..745e3a168c 100644 --- a/indra/llcommon/tests/llsdserialize_test.cpp +++ b/indra/llcommon/tests/llsdserialize_test.cpp @@ -513,19 +513,20 @@ namespace tut const std::string& msg, const std::string& in, const LLSD& expected_value, - S32 expected_count) + S32 expected_count, + S32 depth_limit = -1) { std::stringstream input; input.str(in); LLSD parsed_result; mParser->reset(); // reset() call is needed since test code re-uses mParser - S32 parsed_count = mParser->parse(input, parsed_result, in.size()); + S32 parsed_count = mParser->parse(input, parsed_result, in.size(), depth_limit); ensure_equals(msg.c_str(), parsed_result, expected_value); // This count check is really only useful for expected // parse failures, since the ensures equal will already - // require eqality. + // require equality. std::string count_msg(msg); count_msg += " (count)"; ensure_equals(count_msg, parsed_count, expected_count); @@ -714,6 +715,43 @@ namespace tut expected, 1); } + + template<> template<> + void TestLLSDXMLParsingObject::test<5>() + { + // test deeper nested levels + LLSD level_5 = LLSD::emptyMap(); level_5["level_5"] = 42.f; + LLSD level_4 = LLSD::emptyMap(); level_4["level_4"] = level_5; + LLSD level_3 = LLSD::emptyMap(); level_3["level_3"] = level_4; + LLSD level_2 = LLSD::emptyMap(); level_2["level_2"] = level_3; + LLSD level_1 = LLSD::emptyMap(); level_1["level_1"] = level_2; + LLSD level_0 = LLSD::emptyMap(); level_0["level_0"] = level_1; + + LLSD v; + v["deep"] = level_0; + + ensureParse( + "deep llsd xml map", + "<llsd><map>" + "<key>deep</key><map>" + "<key>level_0</key><map>" + "<key>level_1</key><map>" + "<key>level_2</key><map>" + "<key>level_3</key><map>" + "<key>level_4</key><map>" + "<key>level_5</key><real>42.0</real>" + "</map>" + "</map>" + "</map>" + "</map>" + "</map>" + "</map>" + "</map></llsd>", + v, + 8); + } + + /* TODO: test XML parsing @@ -975,6 +1013,146 @@ namespace tut LLSDParser::PARSE_FAILURE); } + template<> template<> + void TestLLSDNotationParsingObject::test<18>() + { + LLSD level_1 = LLSD::emptyMap(); level_1["level_2"] = 99; + LLSD level_0 = LLSD::emptyMap(); level_0["level_1"] = level_1; + + LLSD deep = LLSD::emptyMap(); + deep["level_0"] = level_0; + + LLSD root = LLSD::emptyMap(); + root["deep"] = deep; + + ensureParse( + "nested notation 3 deep", + "{'deep' : {'level_0':{'level_1':{'level_2': i99} } } }", + root, + 5, + 5); // 4 '{' plus i99 also counts as llsd, so real depth is 5 + } + + template<> template<> + void TestLLSDNotationParsingObject::test<19>() + { + LLSD level_9 = LLSD::emptyMap(); level_9["level_9"] = (S32)99; + LLSD level_8 = LLSD::emptyMap(); level_8["level_8"] = level_9; + LLSD level_7 = LLSD::emptyMap(); level_7["level_7"] = level_8; + LLSD level_6 = LLSD::emptyMap(); level_6["level_6"] = level_7; + LLSD level_5 = LLSD::emptyMap(); level_5["level_5"] = level_6; + LLSD level_4 = LLSD::emptyMap(); level_4["level_4"] = level_5; + LLSD level_3 = LLSD::emptyMap(); level_3["level_3"] = level_4; + LLSD level_2 = LLSD::emptyMap(); level_2["level_2"] = level_3; + LLSD level_1 = LLSD::emptyMap(); level_1["level_1"] = level_2; + LLSD level_0 = LLSD::emptyMap(); level_0["level_0"] = level_1; + + LLSD deep = LLSD::emptyMap(); + deep["deep"] = level_0; + + ensureParse( + "nested notation 10 deep", + "{'deep' : {'level_0':{'level_1':{'level_2':{'level_3':{'level_4':{'level_5':{'level_6':{'level_7':{'level_8':{'level_9':i99}" + "} } } } } } } } } }", + deep, + 12, + 15); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<20>() + { + LLSD end = LLSD::emptyMap(); end["end"] = (S32)99; + + LLSD level_49 = LLSD::emptyMap(); level_49["level_49"] = end; + LLSD level_48 = LLSD::emptyMap(); level_48["level_48"] = level_49; + LLSD level_47 = LLSD::emptyMap(); level_47["level_47"] = level_48; + LLSD level_46 = LLSD::emptyMap(); level_46["level_46"] = level_47; + LLSD level_45 = LLSD::emptyMap(); level_45["level_45"] = level_46; + LLSD level_44 = LLSD::emptyMap(); level_44["level_44"] = level_45; + LLSD level_43 = LLSD::emptyMap(); level_43["level_43"] = level_44; + LLSD level_42 = LLSD::emptyMap(); level_42["level_42"] = level_43; + LLSD level_41 = LLSD::emptyMap(); level_41["level_41"] = level_42; + LLSD level_40 = LLSD::emptyMap(); level_40["level_40"] = level_41; + + LLSD level_39 = LLSD::emptyMap(); level_39["level_39"] = level_40; + LLSD level_38 = LLSD::emptyMap(); level_38["level_38"] = level_39; + LLSD level_37 = LLSD::emptyMap(); level_37["level_37"] = level_38; + LLSD level_36 = LLSD::emptyMap(); level_36["level_36"] = level_37; + LLSD level_35 = LLSD::emptyMap(); level_35["level_35"] = level_36; + LLSD level_34 = LLSD::emptyMap(); level_34["level_34"] = level_35; + LLSD level_33 = LLSD::emptyMap(); level_33["level_33"] = level_34; + LLSD level_32 = LLSD::emptyMap(); level_32["level_32"] = level_33; + LLSD level_31 = LLSD::emptyMap(); level_31["level_31"] = level_32; + LLSD level_30 = LLSD::emptyMap(); level_30["level_30"] = level_31; + + LLSD level_29 = LLSD::emptyMap(); level_29["level_29"] = level_30; + LLSD level_28 = LLSD::emptyMap(); level_28["level_28"] = level_29; + LLSD level_27 = LLSD::emptyMap(); level_27["level_27"] = level_28; + LLSD level_26 = LLSD::emptyMap(); level_26["level_26"] = level_27; + LLSD level_25 = LLSD::emptyMap(); level_25["level_25"] = level_26; + LLSD level_24 = LLSD::emptyMap(); level_24["level_24"] = level_25; + LLSD level_23 = LLSD::emptyMap(); level_23["level_23"] = level_24; + LLSD level_22 = LLSD::emptyMap(); level_22["level_22"] = level_23; + LLSD level_21 = LLSD::emptyMap(); level_21["level_21"] = level_22; + LLSD level_20 = LLSD::emptyMap(); level_20["level_20"] = level_21; + + LLSD level_19 = LLSD::emptyMap(); level_19["level_19"] = level_20; + LLSD level_18 = LLSD::emptyMap(); level_18["level_18"] = level_19; + LLSD level_17 = LLSD::emptyMap(); level_17["level_17"] = level_18; + LLSD level_16 = LLSD::emptyMap(); level_16["level_16"] = level_17; + LLSD level_15 = LLSD::emptyMap(); level_15["level_15"] = level_16; + LLSD level_14 = LLSD::emptyMap(); level_14["level_14"] = level_15; + LLSD level_13 = LLSD::emptyMap(); level_13["level_13"] = level_14; + LLSD level_12 = LLSD::emptyMap(); level_12["level_12"] = level_13; + LLSD level_11 = LLSD::emptyMap(); level_11["level_11"] = level_12; + LLSD level_10 = LLSD::emptyMap(); level_10["level_10"] = level_11; + + LLSD level_9 = LLSD::emptyMap(); level_9["level_9"] = level_10; + LLSD level_8 = LLSD::emptyMap(); level_8["level_8"] = level_9; + LLSD level_7 = LLSD::emptyMap(); level_7["level_7"] = level_8; + LLSD level_6 = LLSD::emptyMap(); level_6["level_6"] = level_7; + LLSD level_5 = LLSD::emptyMap(); level_5["level_5"] = level_6; + LLSD level_4 = LLSD::emptyMap(); level_4["level_4"] = level_5; + LLSD level_3 = LLSD::emptyMap(); level_3["level_3"] = level_4; + LLSD level_2 = LLSD::emptyMap(); level_2["level_2"] = level_3; + LLSD level_1 = LLSD::emptyMap(); level_1["level_1"] = level_2; + LLSD level_0 = LLSD::emptyMap(); level_0["level_0"] = level_1; + + LLSD deep = LLSD::emptyMap(); + deep["deep"] = level_0; + + ensureParse( + "nested notation deep", + "{'deep':" + "{'level_0' :{'level_1' :{'level_2' :{'level_3' :{'level_4' :{'level_5' :{'level_6' :{'level_7' :{'level_8' :{'level_9' :" + "{'level_10':{'level_11':{'level_12':{'level_13':{'level_14':{'level_15':{'level_16':{'level_17':{'level_18':{'level_19':" + "{'level_20':{'level_21':{'level_22':{'level_23':{'level_24':{'level_25':{'level_26':{'level_27':{'level_28':{'level_29':" + "{'level_30':{'level_31':{'level_32':{'level_33':{'level_34':{'level_35':{'level_36':{'level_37':{'level_38':{'level_39':" + "{'level_40':{'level_41':{'level_42':{'level_43':{'level_44':{'level_45':{'level_46':{'level_47':{'level_48':{'level_49':" + "{'end':i99}" + "} } } } } } } } } }" + "} } } } } } } } } }" + "} } } } } } } } } }" + "} } } } } } } } } }" + "} } } } } } } } } }" + "}", + deep, + 53); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<21>() + { + ensureParse( + "nested notation 10 deep", + "{'deep' : {'level_0':{'level_1':{'level_2':{'level_3':{'level_4':{'level_5':{'level_6':{'level_7':{'level_8':{'level_9':i99}" + "} } } } } } } } } }", + LLSD(), + LLSDParser::PARSE_FAILURE, + 9); + } + /** * @class TestLLSDBinaryParsing * @brief Concrete instance of a parse tester. diff --git a/indra/llmessage/llinstantmessage.cpp b/indra/llmessage/llinstantmessage.cpp index b7f3e6e4f7..dd5a655d7e 100644 --- a/indra/llmessage/llinstantmessage.cpp +++ b/indra/llmessage/llinstantmessage.cpp @@ -51,98 +51,6 @@ const std::string INTERACTIVE_SYSTEM_FROM("F387446C-37C4-45f2-A438-D99CBDBB563B" const S32 IM_TTL = 1; -/** - * LLIMInfo - */ -LLIMInfo::LLIMInfo() : - mFromGroup(FALSE), - mParentEstateID(0), - mOffline(0), - mViewerThinksToIsOnline(false), - mIMType(IM_NOTHING_SPECIAL), - mTimeStamp(0), - mTTL(IM_TTL) -{ -} - -LLIMInfo::LLIMInfo( - const LLUUID& from_id, - BOOL from_group, - const LLUUID& to_id, - EInstantMessage im_type, - const std::string& name, - const std::string& message, - const LLUUID& id, - U32 parent_estate_id, - const LLUUID& region_id, - const LLVector3& position, - LLSD data, - U8 offline, - U32 timestamp, - S32 ttl) : - mFromID(from_id), - mFromGroup(from_group), - mToID(to_id), - mParentEstateID(0), - mRegionID(region_id), - mPosition(position), - mOffline(offline), - mViewerThinksToIsOnline(false), - mIMType(im_type), - mID(id), - mTimeStamp(timestamp), - mName(name), - mMessage(message), - mData(data), - mTTL(ttl) -{ -} - -LLIMInfo::LLIMInfo(LLMessageSystem* msg, S32 ttl) : - mViewerThinksToIsOnline(false), - mTTL(ttl) -{ - unpackMessageBlock(msg); -} - -LLIMInfo::~LLIMInfo() -{ -} - -void LLIMInfo::packInstantMessage(LLMessageSystem* msg) const -{ - LL_DEBUGS() << "LLIMInfo::packInstantMessage()" << LL_ENDL; - msg->newMessageFast(_PREHASH_ImprovedInstantMessage); - packMessageBlock(msg); -} - -void LLIMInfo::packMessageBlock(LLMessageSystem* msg) const -{ - // Construct binary bucket - std::vector<U8> bucket; - if (mData.has("binary_bucket")) - { - bucket = mData["binary_bucket"].asBinary(); - } - pack_instant_message_block( - msg, - mFromID, - mFromGroup, - LLUUID::null, - mToID, - mName, - mMessage, - mOffline, - mIMType, - mID, - mParentEstateID, - mRegionID, - mPosition, - mTimeStamp, - &bucket[0], - bucket.size()); -} - void pack_instant_message( LLMessageSystem* msg, const LLUUID& from_id, @@ -253,120 +161,4 @@ void pack_instant_message_block( msg->addBinaryDataFast(_PREHASH_BinaryBucket, bb, binary_bucket_size); } -void LLIMInfo::unpackMessageBlock(LLMessageSystem* msg) -{ - msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, mFromID); - msg->getBOOLFast(_PREHASH_MessageBlock, _PREHASH_FromGroup, mFromGroup); - msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ToAgentID, mToID); - msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_ParentEstateID, mParentEstateID); - msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_RegionID, mRegionID); - msg->getVector3Fast(_PREHASH_MessageBlock, _PREHASH_Position, mPosition); - msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Offline, mOffline); - U8 dialog; - msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Dialog, dialog); - mIMType = (EInstantMessage) dialog; - msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, mID); - msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_Timestamp, mTimeStamp); - msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, mName); - - msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, mMessage); - - S32 binary_bucket_size = llmin( - MTUBYTES, - msg->getSizeFast( - _PREHASH_MessageBlock, - _PREHASH_BinaryBucket)); - if(binary_bucket_size > 0) - { - std::vector<U8> bucket; - bucket.resize(binary_bucket_size); - - msg->getBinaryDataFast( - _PREHASH_MessageBlock, - _PREHASH_BinaryBucket, - &bucket[0], - 0, - 0, - binary_bucket_size); - mData["binary_bucket"] = bucket; - } - else - { - mData.clear(); - } -} - -LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info) -{ - LLSD param_version; - param_version["version"] = 1; - LLSD param_message; - param_message["from_id"] = im_info->mFromID; - param_message["from_group"] = im_info->mFromGroup; - param_message["to_id"] = im_info->mToID; - param_message["from_name"] = im_info->mName; - param_message["message"] = im_info->mMessage; - param_message["type"] = (S32)im_info->mIMType; - param_message["id"] = im_info->mID; - param_message["timestamp"] = (S32)im_info->mTimeStamp; - param_message["offline"] = (S32)im_info->mOffline; - param_message["parent_estate_id"] = (S32)im_info->mParentEstateID; - param_message["region_id"] = im_info->mRegionID; - param_message["position"] = ll_sd_from_vector3(im_info->mPosition); - param_message["data"] = im_info->mData; - param_message["ttl"] = im_info->mTTL; - - LLSD param_agent; - param_agent["agent_id"] = im_info->mFromID; - - LLSD params; - params["version_params"] = param_version; - params["message_params"] = param_message; - params["agent_params"] = param_agent; - - return params; -} - -LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd) -{ - LLSD param_message = im_info_sd["message_params"]; - LLSD param_agent = im_info_sd["agent_params"]; - - LLPointer<LLIMInfo> im_info = new LLIMInfo( - param_message["from_id"].asUUID(), - param_message["from_group"].asBoolean(), - param_message["to_id"].asUUID(), - (EInstantMessage) param_message["type"].asInteger(), - param_message["from_name"].asString(), - param_message["message"].asString(), - param_message["id"].asUUID(), - (U32) param_message["parent_estate_id"].asInteger(), - param_message["region_id"].asUUID(), - ll_vector3_from_sd(param_message["position"]), - param_message["data"], - (U8) param_message["offline"].asInteger(), - (U32) param_message["timestamp"].asInteger(), - param_message["ttl"].asInteger()); - - return im_info; -} - -LLPointer<LLIMInfo> LLIMInfo::clone() -{ - return new LLIMInfo( - mFromID, - mFromGroup, - mToID, - mIMType, - mName, - mMessage, - mID, - mParentEstateID, - mRegionID, - mPosition, - mData, - mOffline, - mTimeStamp, - mTTL); -} diff --git a/indra/llmessage/llinstantmessage.h b/indra/llmessage/llinstantmessage.h index f7118f8ccf..55cda15405 100644 --- a/indra/llmessage/llinstantmessage.h +++ b/indra/llmessage/llinstantmessage.h @@ -177,59 +177,6 @@ extern const std::string INTERACTIVE_SYSTEM_FROM; // Number of retry attempts on sending the im. extern const S32 IM_TTL; - -class LLIMInfo : public LLRefCount -{ -protected: - LLIMInfo(); - ~LLIMInfo(); - -public: - LLIMInfo(LLMessageSystem* msg, - S32 ttl = IM_TTL); - - LLIMInfo( - const LLUUID& from_id, - BOOL from_group, - const LLUUID& to_id, - EInstantMessage im_type, - const std::string& name, - const std::string& message, - const LLUUID& id, - U32 parent_estate_id, - const LLUUID& region_id, - const LLVector3& position, - LLSD data, - U8 offline, - U32 timestamp, - S32 ttl = IM_TTL); - - void packInstantMessage(LLMessageSystem* msg) const; - void packMessageBlock(LLMessageSystem* msg) const; - void unpackMessageBlock(LLMessageSystem* msg); - LLPointer<LLIMInfo> clone(); -public: - LLUUID mFromID; - BOOL mFromGroup; - LLUUID mToID; - U32 mParentEstateID; - LLUUID mRegionID; - LLVector3 mPosition; - U8 mOffline; - bool mViewerThinksToIsOnline; - EInstantMessage mIMType; - LLUUID mID; - U32 mTimeStamp; - std::string mName; - std::string mMessage; - LLSD mData; - - S32 mTTL; -}; - -LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd); -LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info); - void pack_instant_message( LLMessageSystem* msgsystem, const LLUUID& from_id, diff --git a/indra/llmessage/llxfer.cpp b/indra/llmessage/llxfer.cpp index e0590dfdff..c8b9d5d19f 100644 --- a/indra/llmessage/llxfer.cpp +++ b/indra/llmessage/llxfer.cpp @@ -63,7 +63,6 @@ void LLXfer::init (S32 chunk_size) mXferSize = 0; mStatus = e_LL_XFER_UNINITIALIZED; - mNext = NULL; mWaitingForACK = FALSE; mCallback = NULL; @@ -99,7 +98,22 @@ void LLXfer::cleanup () S32 LLXfer::startSend (U64 xfer_id, const LLHost &remote_host) { - LL_WARNS() << "undifferentiated LLXfer::startSend for " << getFileName() << LL_ENDL; + LL_WARNS("Xfer") << "unexpected call to base class LLXfer::startSend for " << getFileName() << LL_ENDL; + return (-1); +} + +/////////////////////////////////////////////////////////// + +void LLXfer::closeFileHandle() +{ + LL_WARNS("Xfer") << "unexpected call to base class LLXfer::closeFileHandle for " << getFileName() << LL_ENDL; +} + +/////////////////////////////////////////////////////////// + +S32 LLXfer::reopenFileHandle() +{ + LL_WARNS("Xfer") << "unexpected call to base class LLXfer::reopenFileHandle for " << getFileName() << LL_ENDL; return (-1); } @@ -115,7 +129,7 @@ void LLXfer::setXferSize (S32 xfer_size) S32 LLXfer::startDownload() { - LL_WARNS() << "undifferentiated LLXfer::startDownload for " << getFileName() + LL_WARNS("Xfer") << "undifferentiated LLXfer::startDownload for " << getFileName() << LL_ENDL; return (-1); } @@ -127,20 +141,20 @@ S32 LLXfer::receiveData (char *datap, S32 data_size) S32 retval = 0; if (((S32) mBufferLength + data_size) > getMaxBufferSize()) - { + { // Write existing data to disk if it's larger than the buffer size retval = flush(); } if (!retval) { if (datap != NULL) - { + { // Append new data to mBuffer memcpy(&mBuffer[mBufferLength],datap,data_size); /*Flawfinder: ignore*/ mBufferLength += data_size; } else { - LL_ERRS() << "NULL data passed in receiveData" << LL_ENDL; + LL_ERRS("Xfer") << "NULL data passed in receiveData" << LL_ENDL; } } @@ -163,7 +177,7 @@ S32 LLXfer::flush() S32 LLXfer::suck(S32 start_position) { - LL_WARNS() << "Attempted to send a packet outside the buffer bounds in LLXfer::suck()" << LL_ENDL; + LL_WARNS("Xfer") << "Attempted to send a packet outside the buffer bounds in LLXfer::suck()" << LL_ENDL; return (-1); } @@ -196,7 +210,7 @@ void LLXfer::sendPacket(S32 packet_num) if (fdata_size < 0) { - LL_WARNS() << "negative data size in xfer send, aborting" << LL_ENDL; + LL_WARNS("Xfer") << "negative data size in xfer send, aborting" << LL_ENDL; abort(LL_ERR_EOF); return; } @@ -248,7 +262,12 @@ void LLXfer::sendPacket(S32 packet_num) gMessageSystem->nextBlockFast(_PREHASH_DataPacket); gMessageSystem->addBinaryDataFast(_PREHASH_Data, &fdata_buf,fdata_size); - gMessageSystem->sendMessage(mRemoteHost); + S32 sent_something = gMessageSystem->sendMessage(mRemoteHost); + if (sent_something == 0) + { + abort(LL_ERR_CIRCUIT_GONE); + return; + } ACKTimer.reset(); mWaitingForACK = TRUE; @@ -289,12 +308,12 @@ S32 LLXfer::processEOF() if (LL_ERR_NOERR == mCallbackResult) { - LL_INFOS() << "xfer from " << mRemoteHost << " complete: " << getFileName() + LL_INFOS("Xfer") << "xfer from " << mRemoteHost << " complete: " << getFileName() << LL_ENDL; } else { - LL_INFOS() << "xfer from " << mRemoteHost << " failed or aborted, code " + LL_INFOS("Xfer") << "xfer from " << mRemoteHost << " failed, code " << mCallbackResult << ": " << getFileName() << LL_ENDL; } @@ -323,15 +342,18 @@ void LLXfer::abort (S32 result_code) { mCallbackResult = result_code; - LL_INFOS() << "Aborting xfer from " << mRemoteHost << " named " << getFileName() + LL_INFOS("Xfer") << "Aborting xfer from " << mRemoteHost << " named " << getFileName() << " - error: " << result_code << LL_ENDL; - gMessageSystem->newMessageFast(_PREHASH_AbortXfer); - gMessageSystem->nextBlockFast(_PREHASH_XferID); - gMessageSystem->addU64Fast(_PREHASH_ID, mID); - gMessageSystem->addS32Fast(_PREHASH_Result, result_code); - - gMessageSystem->sendMessage(mRemoteHost); + if (result_code != LL_ERR_CIRCUIT_GONE) + { + gMessageSystem->newMessageFast(_PREHASH_AbortXfer); + gMessageSystem->nextBlockFast(_PREHASH_XferID); + gMessageSystem->addU64Fast(_PREHASH_ID, mID); + gMessageSystem->addS32Fast(_PREHASH_Result, result_code); + + gMessageSystem->sendMessage(mRemoteHost); + } mStatus = e_LL_XFER_ABORTED; } diff --git a/indra/llmessage/llxfer.h b/indra/llmessage/llxfer.h index edf5eeb82d..a906674dec 100644 --- a/indra/llmessage/llxfer.h +++ b/indra/llmessage/llxfer.h @@ -54,7 +54,6 @@ class LLXfer S32 mChunkSize; public: - LLXfer *mNext; U64 mID; S32 mPacketNum; @@ -62,7 +61,7 @@ class LLXfer S32 mXferSize; char *mBuffer; - U32 mBufferLength; + U32 mBufferLength; // Size of valid data, not actual allocated buffer size U32 mBufferStartOffset; BOOL mBufferContainsEOF; @@ -90,7 +89,9 @@ class LLXfer void init(S32 chunk_size); virtual void cleanup(); - virtual S32 startSend (U64 xfer_id, const LLHost &remote_host); + virtual S32 startSend(U64 xfer_id, const LLHost &remote_host); + virtual void closeFileHandle(); + virtual S32 reopenFileHandle(); virtual void sendPacket(S32 packet_num); virtual void sendNextPacket(); virtual void resendLastPacket(); diff --git a/indra/llmessage/llxfer_file.cpp b/indra/llmessage/llxfer_file.cpp index 8e2ed890e7..7fd4222fb7 100644 --- a/indra/llmessage/llxfer_file.cpp +++ b/indra/llmessage/llxfer_file.cpp @@ -102,12 +102,12 @@ void LLXfer_File::cleanup () if (mDeleteLocalOnCompletion) { - LL_DEBUGS() << "Removing file: " << mLocalFilename << LL_ENDL; + LL_DEBUGS("Xfer") << "Removing file: " << mLocalFilename << LL_ENDL; LLFile::remove(mLocalFilename, ENOENT); } else { - LL_DEBUGS() << "Keeping local file: " << mLocalFilename << LL_ENDL; + LL_DEBUGS("Xfer") << "Keeping local file: " << mLocalFilename << LL_ENDL; } LLXfer::cleanup(); @@ -139,7 +139,7 @@ S32 LLXfer_File::initializeRequest(U64 xfer_id, mCallbackDataHandle = user_data; mCallbackResult = LL_ERR_NOERR; - LL_INFOS() << "Requesting xfer from " << remote_host << " for file: " << mLocalFilename << LL_ENDL; + LL_INFOS("Xfer") << "Requesting xfer from " << remote_host << " for file: " << mLocalFilename << LL_ENDL; if (mBuffer) { @@ -167,6 +167,7 @@ S32 LLXfer_File::startDownload() fclose(mFp); mFp = NULL; + // tbd - is it premature to send this message if the queue is backed up? gMessageSystem->newMessageFast(_PREHASH_RequestXfer); gMessageSystem->nextBlockFast(_PREHASH_XferID); gMessageSystem->addU64Fast(_PREHASH_ID, mID); @@ -182,7 +183,7 @@ S32 LLXfer_File::startDownload() } else { - LL_WARNS() << "Couldn't create file to be received!" << LL_ENDL; + LL_WARNS("Xfer") << "Couldn't create file to be received!" << LL_ENDL; retval = -1; } @@ -206,7 +207,8 @@ S32 LLXfer_File::startSend (U64 xfer_id, const LLHost &remote_host) mBufferLength = 0; mBufferStartOffset = 0; - + + // We leave the file open, assuming we'll start reading and sending soon mFp = LLFile::fopen(mLocalFilename,"rb"); /* Flawfinder : ignore */ if (mFp) { @@ -223,7 +225,7 @@ S32 LLXfer_File::startSend (U64 xfer_id, const LLHost &remote_host) } else { - LL_INFOS() << "Warning: " << mLocalFilename << " not found." << LL_ENDL; + LL_INFOS("Xfer") << "Warning: " << mLocalFilename << " not found." << LL_ENDL; return (LL_ERR_FILE_NOT_FOUND); } @@ -233,6 +235,36 @@ S32 LLXfer_File::startSend (U64 xfer_id, const LLHost &remote_host) } /////////////////////////////////////////////////////////// +void LLXfer_File::closeFileHandle() +{ + if (mFp) + { + fclose(mFp); + mFp = NULL; + } +} + +/////////////////////////////////////////////////////////// + +S32 LLXfer_File::reopenFileHandle() +{ + S32 retval = LL_ERR_NOERR; // presume success + + if (mFp == NULL) + { + mFp = LLFile::fopen(mLocalFilename,"rb"); /* Flawfinder : ignore */ + if (mFp == NULL) + { + LL_INFOS("Xfer") << "Warning: " << mLocalFilename << " not found when re-opening file" << LL_ENDL; + retval = LL_ERR_FILE_NOT_FOUND; + } + } + + return retval; +} + + +/////////////////////////////////////////////////////////// S32 LLXfer_File::getMaxBufferSize () { @@ -279,18 +311,21 @@ S32 LLXfer_File::flush() { if (mFp) { - LL_ERRS() << "Overwriting open file pointer!" << LL_ENDL; + LL_ERRS("Xfer") << "Overwriting open file pointer!" << LL_ENDL; } mFp = LLFile::fopen(mTempFilename,"a+b"); /* Flawfinder : ignore */ if (mFp) { - if (fwrite(mBuffer,1,mBufferLength,mFp) != mBufferLength) + S32 write_size = fwrite(mBuffer,1,mBufferLength,mFp); + if (write_size != mBufferLength) { - LL_WARNS() << "Short write" << LL_ENDL; + LL_WARNS("Xfer") << "Non-matching write size, requested " << mBufferLength + << " but wrote " << write_size + << LL_ENDL; } -// LL_INFOS() << "******* wrote " << mBufferLength << " bytes of file xfer" << LL_ENDL; +// LL_INFOS("Xfer") << "******* wrote " << mBufferLength << " bytes of file xfer" << LL_ENDL; fclose(mFp); mFp = NULL; @@ -298,7 +333,7 @@ S32 LLXfer_File::flush() } else { - LL_WARNS() << "LLXfer_File::flush() unable to open " << mTempFilename << " for writing!" << LL_ENDL; + LL_WARNS("Xfer") << "LLXfer_File::flush() unable to open " << mTempFilename << " for writing!" << LL_ENDL; retval = LL_ERR_CANNOT_OPEN_FILE; } } @@ -329,18 +364,18 @@ S32 LLXfer_File::processEOF() { #if !LL_WINDOWS S32 error_number = errno; - LL_INFOS() << "Rename failure (" << error_number << ") - " + LL_INFOS("Xfer") << "Rename failure (" << error_number << ") - " << mTempFilename << " to " << mLocalFilename << LL_ENDL; if(EXDEV == error_number) { if(copy_file(mTempFilename, mLocalFilename) == 0) { - LL_INFOS() << "Rename across mounts; copying+unlinking the file instead." << LL_ENDL; + LL_INFOS("Xfer") << "Rename across mounts; copying+unlinking the file instead." << LL_ENDL; unlink(mTempFilename.c_str()); } else { - LL_WARNS() << "Copy failure - " << mTempFilename << " to " + LL_WARNS("Xfer") << "Copy failure - " << mTempFilename << " to " << mLocalFilename << LL_ENDL; } } @@ -354,11 +389,11 @@ S32 LLXfer_File::processEOF() //LL_WARNS() << "File " << mLocalFilename << " does " // << (!fp ? "not" : "" ) << " exit." << LL_ENDL; //if(fp) fclose(fp); - LL_WARNS() << "Rename fatally failed, can only handle EXDEV (" + LL_WARNS("Xfer") << "Rename fatally failed, can only handle EXDEV (" << EXDEV << ")" << LL_ENDL; } #else - LL_WARNS() << "Rename failure - " << mTempFilename << " to " + LL_WARNS("Xfer") << "Rename failure - " << mTempFilename << " to " << mLocalFilename << LL_ENDL; #endif } @@ -437,3 +472,4 @@ S32 copy_file(const std::string& from, const std::string& to) return rv; } #endif + diff --git a/indra/llmessage/llxfer_file.h b/indra/llmessage/llxfer_file.h index a37dda6732..ab9374549e 100644 --- a/indra/llmessage/llxfer_file.h +++ b/indra/llmessage/llxfer_file.h @@ -61,8 +61,10 @@ class LLXfer_File : public LLXfer virtual S32 startDownload(); virtual S32 processEOF(); - - virtual S32 startSend (U64 xfer_id, const LLHost &remote_host); + + virtual S32 startSend(U64 xfer_id, const LLHost &remote_host); + virtual void closeFileHandle(); + virtual S32 reopenFileHandle(); virtual S32 suck(S32 start_position); virtual S32 flush(); diff --git a/indra/llmessage/llxfer_mem.cpp b/indra/llmessage/llxfer_mem.cpp index 3bea08f2e5..78a3e4f558 100644 --- a/indra/llmessage/llxfer_mem.cpp +++ b/indra/llmessage/llxfer_mem.cpp @@ -80,28 +80,6 @@ void LLXfer_Mem::setXferSize (S32 xfer_size) /////////////////////////////////////////////////////////// -U64 LLXfer_Mem::registerXfer(U64 xfer_id, const void *datap, const S32 length) -{ - mID = xfer_id; - - if (datap) - { - setXferSize(length); - if (mBuffer) - { - memcpy(mBuffer,datap,length); /* Flawfinder : ignore */ - mBufferLength = length; - } - else - { - xfer_id = 0; - } - } - - mStatus = e_LL_XFER_REGISTERED; - return (xfer_id); -} - S32 LLXfer_Mem::startSend (U64 xfer_id, const LLHost &remote_host) { S32 retval = LL_ERR_NOERR; // presume success diff --git a/indra/llmessage/llxfer_mem.h b/indra/llmessage/llxfer_mem.h index b5adf837df..d07779de87 100644 --- a/indra/llmessage/llxfer_mem.h +++ b/indra/llmessage/llxfer_mem.h @@ -53,7 +53,6 @@ class LLXfer_Mem : public LLXfer virtual void cleanup(); virtual S32 startSend (U64 xfer_id, const LLHost &remote_host); - virtual U64 registerXfer(U64 xfer_id, const void *datap, const S32 length); virtual void setXferSize (S32 data_size); virtual S32 initializeRequest(U64 xfer_id, diff --git a/indra/llmessage/llxfer_vfile.cpp b/indra/llmessage/llxfer_vfile.cpp index 4a378d1d34..ddc24342f6 100644 --- a/indra/llmessage/llxfer_vfile.cpp +++ b/indra/llmessage/llxfer_vfile.cpp @@ -79,8 +79,20 @@ void LLXfer_VFile::init (LLVFS *vfs, const LLUUID &local_id, LLAssetType::EType void LLXfer_VFile::cleanup () { - LLVFile file(mVFS, mTempID, mType, LLVFile::WRITE); - file.remove(); + if (mTempID.notNull() && + mDeleteTempFile) + { + if (mVFS->getExists(mTempID, mType)) + { + LLVFile file(mVFS, mTempID, mType, LLVFile::WRITE); + file.remove(); + } + else + { + LL_WARNS("Xfer") << "LLXfer_VFile::cleanup() can't open to delete VFS file " << mTempID << "." << LLAssetType::lookup(mType) + << ", mRemoteID is " << mRemoteID << LL_ENDL; + } + } delete mVFile; mVFile = NULL; @@ -118,7 +130,7 @@ S32 LLXfer_VFile::initializeRequest(U64 xfer_id, mName = llformat("VFile %s:%s", id_string.c_str(), LLAssetType::lookup(mType)); - LL_INFOS() << "Requesting " << mName << LL_ENDL; + LL_INFOS("Xfer") << "Requesting " << mName << LL_ENDL; if (mBuffer) { @@ -131,6 +143,7 @@ S32 LLXfer_VFile::initializeRequest(U64 xfer_id, mBufferLength = 0; mPacketNum = 0; mTempID.generate(); + mDeleteTempFile = TRUE; mStatus = e_LL_XFER_PENDING; return retval; } @@ -140,7 +153,8 @@ S32 LLXfer_VFile::initializeRequest(U64 xfer_id, S32 LLXfer_VFile::startDownload() { S32 retval = 0; // presume success - LLVFile file(mVFS, mTempID, mType, LLVFile::APPEND); + + // Don't need to create the file here, it will happen when data arrives gMessageSystem->newMessageFast(_PREHASH_RequestXfer); gMessageSystem->nextBlockFast(_PREHASH_XferID); @@ -184,6 +198,8 @@ S32 LLXfer_VFile::startSend (U64 xfer_id, const LLHost &remote_host) if (mVFile->getSize() <= 0) { + LL_WARNS("Xfer") << "LLXfer_VFile::startSend() VFS file " << mLocalID << "." << LLAssetType::lookup(mType) + << " has unexpected file size of " << mVFile->getSize() << LL_ENDL; delete mVFile; mVFile = NULL; @@ -198,6 +214,7 @@ S32 LLXfer_VFile::startSend (U64 xfer_id, const LLHost &remote_host) } else { + LL_WARNS("Xfer") << "LLXfer_VFile::startSend() can't read VFS file " << mLocalID << "." << LLAssetType::lookup(mType) << LL_ENDL; retval = LL_ERR_FILE_NOT_FOUND; } @@ -205,6 +222,41 @@ S32 LLXfer_VFile::startSend (U64 xfer_id, const LLHost &remote_host) } /////////////////////////////////////////////////////////// + +void LLXfer_VFile::closeFileHandle() +{ + if (mVFile) + { + delete mVFile; + mVFile = NULL; + } +} + +/////////////////////////////////////////////////////////// + +S32 LLXfer_VFile::reopenFileHandle() +{ + S32 retval = LL_ERR_NOERR; // presume success + + if (mVFile == NULL) + { + if (mVFS->getExists(mLocalID, mType)) + { + mVFile = new LLVFile(mVFS, mLocalID, mType, LLVFile::READ); + } + else + { + LL_WARNS("Xfer") << "LLXfer_VFile::reopenFileHandle() can't read VFS file " << mLocalID << "." << LLAssetType::lookup(mType) << LL_ENDL; + retval = LL_ERR_FILE_NOT_FOUND; + } + } + + return retval; +} + + +/////////////////////////////////////////////////////////// + void LLXfer_VFile::setXferSize (S32 xfer_size) { LLXfer::setXferSize(xfer_size); @@ -236,8 +288,8 @@ S32 LLXfer_VFile::suck(S32 start_position) // grab a buffer from the right place in the file if (! mVFile->seek(start_position, 0)) { - LL_WARNS() << "VFile Xfer Can't seek to position " << start_position << ", file length " << mVFile->getSize() << LL_ENDL; - LL_WARNS() << "While sending file " << mLocalID << LL_ENDL; + LL_WARNS("Xfer") << "VFile Xfer Can't seek to position " << start_position << ", file length " << mVFile->getSize() << LL_ENDL; + LL_WARNS("Xfer") << "While sending file " << mLocalID << LL_ENDL; return -1; } @@ -288,12 +340,31 @@ S32 LLXfer_VFile::processEOF() if (!mCallbackResult) { - LLVFile file(mVFS, mTempID, mType, LLVFile::WRITE); - if (! file.rename(mLocalID, mType)) + if (mVFS->getExists(mTempID, mType)) { - LL_INFOS() << "copy from temp file failed: unable to rename to " << mLocalID << LL_ENDL; + LLVFile file(mVFS, mTempID, mType, LLVFile::WRITE); + if (!file.rename(mLocalID, mType)) + { + LL_WARNS("Xfer") << "VFS rename of temp file failed: unable to rename " << mTempID << " to " << mLocalID << LL_ENDL; + } + else + { + #ifdef VFS_SPAM + // Debugging spam + LL_INFOS("Xfer") << "VFS rename of temp file done: renamed " << mTempID << " to " << mLocalID + << " LLVFile size is " << file.getSize() + << LL_ENDL; + #endif + + // Rename worked: the original file is gone. Clear mDeleteTempFile + // so we don't attempt to delete the file in cleanup() + mDeleteTempFile = FALSE; + } + } + else + { + LL_WARNS("Xfer") << "LLXfer_VFile::processEOF() can't open for renaming VFS file " << mTempID << "." << LLAssetType::lookup(mType) << LL_ENDL; } - } if (mVFile) @@ -336,3 +407,4 @@ U32 LLXfer_VFile::getXferTypeTag() { return LLXfer::XFER_VFILE; } + diff --git a/indra/llmessage/llxfer_vfile.h b/indra/llmessage/llxfer_vfile.h index 048bf49dcc..5bf9a5cfba 100644 --- a/indra/llmessage/llxfer_vfile.h +++ b/indra/llmessage/llxfer_vfile.h @@ -47,6 +47,8 @@ class LLXfer_VFile : public LLXfer std::string mName; + BOOL mDeleteTempFile; + public: LLXfer_VFile (); LLXfer_VFile (LLVFS *vfs, const LLUUID &local_id, LLAssetType::EType type); @@ -66,8 +68,10 @@ class LLXfer_VFile : public LLXfer virtual S32 startDownload(); virtual S32 processEOF(); - - virtual S32 startSend (U64 xfer_id, const LLHost &remote_host); + + virtual S32 startSend(U64 xfer_id, const LLHost &remote_host); + virtual void closeFileHandle(); + virtual S32 reopenFileHandle(); virtual S32 suck(S32 start_position); virtual S32 flush(); diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp index 2ceb64ce8f..4cea886c8a 100644 --- a/indra/llmessage/llxfermanager.cpp +++ b/indra/llmessage/llxfermanager.cpp @@ -44,9 +44,15 @@ const S32 LL_PACKET_RETRY_LIMIT = 10; // packet retransmission limit const S32 LL_DEFAULT_MAX_SIMULTANEOUS_XFERS = 10; const S32 LL_DEFAULT_MAX_REQUEST_FIFO_XFERS = 1000; -#define LL_XFER_PROGRESS_MESSAGES 0 -#define LL_XFER_TEST_REXMIT 0 +// Kills the connection if a viewer download queue hits this many requests backed up +// Also set in simulator.xml at "hard_limit_outgoing_xfers_per_circuit" +const S32 LL_DEFAULT_MAX_HARD_LIMIT_SIMULTANEOUS_XFERS = 500; +// Use this to show sending some ConfirmXferPacket messages +//#define LL_XFER_PROGRESS_MESSAGES 1 + +// Use this for lots of diagnostic spam +//#define LL_XFER_DIAGNOISTIC_LOGGING 1 /////////////////////////////////////////////////////////// @@ -66,10 +72,10 @@ LLXferManager::~LLXferManager () void LLXferManager::init (LLVFS *vfs) { - mSendList = NULL; - mReceiveList = NULL; + cleanup(); setMaxOutgoingXfersPerCircuit(LL_DEFAULT_MAX_SIMULTANEOUS_XFERS); + setHardLimitOutgoingXfersPerCircuit(LL_DEFAULT_MAX_HARD_LIMIT_SIMULTANEOUS_XFERS); setMaxIncomingXfers(LL_DEFAULT_MAX_REQUEST_FIFO_XFERS); mVFS = vfs; @@ -83,29 +89,14 @@ void LLXferManager::init (LLVFS *vfs) void LLXferManager::cleanup () { - LLXfer *xferp; - LLXfer *delp; - for_each(mOutgoingHosts.begin(), mOutgoingHosts.end(), DeletePointer()); mOutgoingHosts.clear(); - delp = mSendList; - while (delp) - { - xferp = delp->mNext; - delete delp; - delp = xferp; - } - mSendList = NULL; + for_each(mSendList.begin(), mSendList.end(), DeletePointer()); + mSendList.clear(); - delp = mReceiveList; - while (delp) - { - xferp = delp->mNext; - delete delp; - delp = xferp; - } - mReceiveList = NULL; + for_each(mReceiveList.begin(), mReceiveList.end(), DeletePointer()); + mReceiveList.clear(); } /////////////////////////////////////////////////////////// @@ -122,6 +113,11 @@ void LLXferManager::setMaxOutgoingXfersPerCircuit(S32 max_num) mMaxOutgoingXfersPerCircuit = max_num; } +void LLXferManager::setHardLimitOutgoingXfersPerCircuit(S32 max_num) +{ + mHardLimitOutgoingXfersPerCircuit = max_num; +} + void LLXferManager::setUseAckThrottling(const BOOL use) { mUseAckThrottling = use; @@ -140,6 +136,11 @@ void LLXferManager::setAckThrottleBPS(const F32 bps) F32 actual_rate = llmax(min_bps*1.1f, bps); LL_DEBUGS("AppInit") << "LLXferManager ack throttle min rate: " << min_bps << LL_ENDL; LL_DEBUGS("AppInit") << "LLXferManager ack throttle actual rate: " << actual_rate << LL_ENDL; + #ifdef LL_XFER_DIAGNOISTIC_LOGGING + LL_INFOS("Xfer") << "LLXferManager ack throttle min rate: " << min_bps << LL_ENDL; + LL_INFOS("Xfer") << "LLXferManager ack throttle actual rate: " << actual_rate << LL_ENDL; + #endif // LL_XFER_DIAGNOISTIC_LOGGING + mAckThrottle.setRate(actual_rate); } @@ -148,45 +149,71 @@ void LLXferManager::setAckThrottleBPS(const F32 bps) void LLXferManager::updateHostStatus() { - LLXfer *xferp; - LLHostStatus *host_statusp = NULL; - + // Clear the outgoing host list for_each(mOutgoingHosts.begin(), mOutgoingHosts.end(), DeletePointer()); mOutgoingHosts.clear(); - - for (xferp = mSendList; xferp; xferp = xferp->mNext) + + // Loop through all outgoing xfers and re-build mOutgoingHosts + for (xfer_list_t::iterator send_iter = mSendList.begin(); + send_iter != mSendList.end(); ++send_iter) { + LLHostStatus *host_statusp = NULL; for (status_list_t::iterator iter = mOutgoingHosts.begin(); iter != mOutgoingHosts.end(); ++iter) { - host_statusp = *iter; - if (host_statusp->mHost == xferp->mRemoteHost) - { + if ((*iter)->mHost == (*send_iter)->mRemoteHost) + { // Already have this host + host_statusp = *iter; break; } } if (!host_statusp) - { + { // Don't have this host, so add it host_statusp = new LLHostStatus(); if (host_statusp) { - host_statusp->mHost = xferp->mRemoteHost; + host_statusp->mHost = (*send_iter)->mRemoteHost; mOutgoingHosts.push_front(host_statusp); } } if (host_statusp) - { - if (xferp->mStatus == e_LL_XFER_PENDING) + { // Do the accounting + if ((*send_iter)->mStatus == e_LL_XFER_PENDING) { host_statusp->mNumPending++; } - else if (xferp->mStatus == e_LL_XFER_IN_PROGRESS) + else if ((*send_iter)->mStatus == e_LL_XFER_IN_PROGRESS) { host_statusp->mNumActive++; } } - } + +#ifdef LL_XFER_DIAGNOISTIC_LOGGING + for (xfer_list_t::iterator send_iter = mSendList.begin(); + send_iter != mSendList.end(); ++send_iter) + { + LLXfer * xferp = *send_iter; + LL_INFOS("Xfer") << "xfer to host " << xferp->mRemoteHost + << " is " << xferp->mXferSize << " bytes" + << ", status " << (S32)(xferp->mStatus) + << ", waiting for ACK: " << (S32)(xferp->mWaitingForACK) + << " in frame " << (S32) LLFrameTimer::getFrameCount() + << LL_ENDL; + } + + for (status_list_t::iterator iter = mOutgoingHosts.begin(); + iter != mOutgoingHosts.end(); ++iter) + { + LL_INFOS("Xfer") << "LLXfer host " << (*iter)->mHost.getIPandPort() + << " has " << (*iter)->mNumActive + << " active, " << (*iter)->mNumPending + << " pending" + << " in frame " << (S32) LLFrameTimer::getFrameCount() + << LL_ENDL; + } +#endif // LL_XFER_DIAGNOISTIC_LOGGING + } /////////////////////////////////////////////////////////// @@ -196,27 +223,28 @@ void LLXferManager::printHostStatus() LLHostStatus *host_statusp = NULL; if (!mOutgoingHosts.empty()) { - LL_INFOS() << "Outgoing Xfers:" << LL_ENDL; + LL_INFOS("Xfer") << "Outgoing Xfers:" << LL_ENDL; for (status_list_t::iterator iter = mOutgoingHosts.begin(); iter != mOutgoingHosts.end(); ++iter) { host_statusp = *iter; - LL_INFOS() << " " << host_statusp->mHost << " active: " << host_statusp->mNumActive << " pending: " << host_statusp->mNumPending << LL_ENDL; + LL_INFOS("Xfer") << " " << host_statusp->mHost << " active: " << host_statusp->mNumActive << " pending: " << host_statusp->mNumPending << LL_ENDL; } } } /////////////////////////////////////////////////////////// -LLXfer *LLXferManager::findXfer (U64 id, LLXfer *list_head) +LLXfer * LLXferManager::findXferByID(U64 id, xfer_list_t & xfer_list) { - LLXfer *xferp; - for (xferp = list_head; xferp; xferp = xferp->mNext) + for (xfer_list_t::iterator iter = xfer_list.begin(); + iter != xfer_list.end(); + ++iter) { - if (xferp->mID == id) + if ((*iter)->mID == id) { - return(xferp); + return(*iter); } } return(NULL); @@ -225,29 +253,34 @@ LLXfer *LLXferManager::findXfer (U64 id, LLXfer *list_head) /////////////////////////////////////////////////////////// -void LLXferManager::removeXfer (LLXfer *delp, LLXfer **list_head) +// WARNING: this invalidates iterators from xfer_list +void LLXferManager::removeXfer(LLXfer *delp, xfer_list_t & xfer_list) { - // This function assumes that delp will only occur in the list - // zero or one times. if (delp) - { - if (*list_head == delp) + { + std::string direction = "send"; + if (&xfer_list == &mReceiveList) { - *list_head = delp->mNext; - delete (delp); + direction = "receive"; } - else + + // This assumes that delp will occur in the list once at most + // Find the pointer in the list + for (xfer_list_t::iterator iter = xfer_list.begin(); + iter != xfer_list.end(); + ++iter) { - LLXfer *xferp = *list_head; - while (xferp->mNext) + if ((*iter) == delp) { - if (xferp->mNext == delp) - { - xferp->mNext = delp->mNext; - delete (delp); - break; - } - xferp = xferp->mNext; + LL_DEBUGS("Xfer") << "Deleting xfer to host " << (*iter)->mRemoteHost + << " of " << (*iter)->mXferSize << " bytes" + << ", status " << (S32)((*iter)->mStatus) + << " from the " << direction << " list" + << LL_ENDL; + + xfer_list.erase(iter); + delete (delp); + break; } } } @@ -255,35 +288,30 @@ void LLXferManager::removeXfer (LLXfer *delp, LLXfer **list_head) /////////////////////////////////////////////////////////// -U32 LLXferManager::numActiveListEntries(LLXfer *list_head) +LLHostStatus * LLXferManager::findHostStatus(const LLHost &host) { - U32 num_entries = 0; + LLHostStatus *host_statusp = NULL; - while (list_head) + for (status_list_t::iterator iter = mOutgoingHosts.begin(); + iter != mOutgoingHosts.end(); ++iter) { - if (list_head->mStatus == e_LL_XFER_IN_PROGRESS) + host_statusp = *iter; + if (host_statusp->mHost == host) { - num_entries++; + return (host_statusp); } - list_head = list_head->mNext; } - return(num_entries); + return 0; } /////////////////////////////////////////////////////////// - + S32 LLXferManager::numPendingXfers(const LLHost &host) { - LLHostStatus *host_statusp = NULL; - - for (status_list_t::iterator iter = mOutgoingHosts.begin(); - iter != mOutgoingHosts.end(); ++iter) + LLHostStatus *host_statusp = findHostStatus(host); + if (host_statusp) { - host_statusp = *iter; - if (host_statusp->mHost == host) - { - return (host_statusp->mNumPending); - } + return host_statusp->mNumPending; } return 0; } @@ -292,16 +320,10 @@ S32 LLXferManager::numPendingXfers(const LLHost &host) S32 LLXferManager::numActiveXfers(const LLHost &host) { - LLHostStatus *host_statusp = NULL; - - for (status_list_t::iterator iter = mOutgoingHosts.begin(); - iter != mOutgoingHosts.end(); ++iter) + LLHostStatus *host_statusp = findHostStatus(host); + if (host_statusp) { - host_statusp = *iter; - if (host_statusp->mHost == host) - { - return (host_statusp->mNumActive); - } + return host_statusp->mNumActive; } return 0; } @@ -372,35 +394,6 @@ BOOL LLXferManager::isLastPacket(S32 packet_num) /////////////////////////////////////////////////////////// -U64 LLXferManager::registerXfer(const void *datap, const S32 length) -{ - LLXfer *xferp; - U64 xfer_id = getNextID(); - - xferp = (LLXfer *) new LLXfer_Mem(); - if (xferp) - { - xferp->mNext = mSendList; - mSendList = xferp; - - xfer_id = ((LLXfer_Mem *)xferp)->registerXfer(xfer_id, datap,length); - - if (!xfer_id) - { - removeXfer(xferp,&mSendList); - } - } - else - { - LL_ERRS() << "Xfer allocation error" << LL_ENDL; - xfer_id = 0; - } - - return(xfer_id); -} - -/////////////////////////////////////////////////////////// - U64 LLXferManager::requestFile(const std::string& local_filename, const std::string& remote_filename, ELLPath remote_path, @@ -411,43 +404,46 @@ U64 LLXferManager::requestFile(const std::string& local_filename, BOOL is_priority, BOOL use_big_packets) { - LLXfer *xferp; + LLXfer_File* file_xfer_p = NULL; - for (xferp = mReceiveList; xferp ; xferp = xferp->mNext) + // First check to see if it's already requested + for (xfer_list_t::iterator iter = mReceiveList.begin(); + iter != mReceiveList.end(); ++iter) { - if (xferp->getXferTypeTag() == LLXfer::XFER_FILE - && (((LLXfer_File*)xferp)->matchesLocalFilename(local_filename)) - && (((LLXfer_File*)xferp)->matchesRemoteFilename(remote_filename, remote_path)) - && (remote_host == xferp->mRemoteHost) - && (callback == xferp->mCallback) - && (user_data == xferp->mCallbackDataHandle)) - + if ((*iter)->getXferTypeTag() == LLXfer::XFER_FILE) { - // cout << "requested a xfer already in progress" << endl; - return xferp->mID; + file_xfer_p = (LLXfer_File*)(*iter); + if (file_xfer_p->matchesLocalFilename(local_filename) + && file_xfer_p->matchesRemoteFilename(remote_filename, remote_path) + && (remote_host == file_xfer_p->mRemoteHost) + && (callback == file_xfer_p->mCallback) + && (user_data == file_xfer_p->mCallbackDataHandle)) + { + // Already have the request (already in progress) + return (*iter)->mID; + } } } U64 xfer_id = 0; S32 chunk_size = use_big_packets ? LL_XFER_LARGE_PAYLOAD : -1; - xferp = (LLXfer *) new LLXfer_File(chunk_size); - if (xferp) + file_xfer_p = new LLXfer_File(chunk_size); + if (file_xfer_p) { - addToList(xferp, mReceiveList, is_priority); + addToList(file_xfer_p, mReceiveList, is_priority); // Remove any file by the same name that happens to be lying // around. // Note: according to AaronB, this is here to deal with locks on files that were // in transit during a crash, - if( delete_remote_on_completion - && (remote_filename.substr(remote_filename.length()-4) == ".tmp") - && gDirUtilp->fileExists(local_filename)) + if(delete_remote_on_completion && + (remote_filename.substr(remote_filename.length()-4) == ".tmp")) { LLFile::remove(local_filename, ENOENT); } xfer_id = getNextID(); - ((LLXfer_File *)xferp)->initializeRequest( + file_xfer_p->initializeRequest( xfer_id, local_filename, remote_filename, @@ -459,39 +455,11 @@ U64 LLXferManager::requestFile(const std::string& local_filename, } else { - LL_ERRS() << "Xfer allocation error" << LL_ENDL; + LL_ERRS("Xfer") << "Xfer allocation error" << LL_ENDL; } return xfer_id; } -void LLXferManager::requestFile(const std::string& remote_filename, - ELLPath remote_path, - const LLHost& remote_host, - BOOL delete_remote_on_completion, - void (*callback)(void*,S32,void**,S32,LLExtStat), - void** user_data, - BOOL is_priority) -{ - LLXfer *xferp; - - xferp = (LLXfer *) new LLXfer_Mem(); - if (xferp) - { - addToList(xferp, mReceiveList, is_priority); - ((LLXfer_Mem *)xferp)->initializeRequest(getNextID(), - remote_filename, - remote_path, - remote_host, - delete_remote_on_completion, - callback, user_data); - startPendingDownloads(); - } - else - { - LL_ERRS() << "Xfer allocation error" << LL_ENDL; - } -} - void LLXferManager::requestVFile(const LLUUID& local_id, const LLUUID& remote_id, LLAssetType::EType type, LLVFS* vfs, @@ -500,28 +468,46 @@ void LLXferManager::requestVFile(const LLUUID& local_id, void** user_data, BOOL is_priority) { - LLXfer *xferp; - - for (xferp = mReceiveList; xferp ; xferp = xferp->mNext) - { - if (xferp->getXferTypeTag() == LLXfer::XFER_VFILE - && (((LLXfer_VFile*)xferp)->matchesLocalFile(local_id, type)) - && (((LLXfer_VFile*)xferp)->matchesRemoteFile(remote_id, type)) - && (remote_host == xferp->mRemoteHost) - && (callback == xferp->mCallback) - && (user_data == xferp->mCallbackDataHandle)) + LLXfer_VFile * xfer_p = NULL; + for (xfer_list_t::iterator iter = mReceiveList.begin(); + iter != mReceiveList.end(); ++iter) + { // Find any matching existing requests + if ((*iter)->getXferTypeTag() == LLXfer::XFER_VFILE) { - // cout << "requested a xfer already in progress" << endl; - return; + xfer_p = (LLXfer_VFile*) (*iter); + if (xfer_p->matchesLocalFile(local_id, type) + && xfer_p->matchesRemoteFile(remote_id, type) + && (remote_host == xfer_p->mRemoteHost) + && (callback == xfer_p->mCallback) + && (user_data == xfer_p->mCallbackDataHandle)) + + { // Have match, don't add a duplicate + #ifdef LL_XFER_DIAGNOISTIC_LOGGING + LL_INFOS("Xfer") << "Dropping duplicate xfer request for " << remote_id + << " on " << remote_host.getIPandPort() + << " local id " << local_id + << LL_ENDL; + #endif // LL_XFER_DIAGNOISTIC_LOGGING + + return; + } } } - xferp = (LLXfer *) new LLXfer_VFile(); - if (xferp) + xfer_p = new LLXfer_VFile(); + if (xfer_p) { - addToList(xferp, mReceiveList, is_priority); - ((LLXfer_VFile *)xferp)->initializeRequest(getNextID(), + #ifdef LL_XFER_DIAGNOISTIC_LOGGING + LL_INFOS("Xfer") << "Starting file xfer for " << remote_id + << " type " << LLAssetType::lookupHumanReadable(type) + << " from " << xfer_p->mRemoteHost.getIPandPort() + << ", local id " << local_id + << LL_ENDL; + #endif // LL_XFER_DIAGNOISTIC_LOGGING + + addToList(xfer_p, mReceiveList, is_priority); + ((LLXfer_VFile *)xfer_p)->initializeRequest(getNextID(), vfs, local_id, remote_id, @@ -533,78 +519,18 @@ void LLXferManager::requestVFile(const LLUUID& local_id, } else { - LL_ERRS() << "Xfer allocation error" << LL_ENDL; - } - -} - -/* -void LLXferManager::requestXfer( - const std::string& local_filename, - BOOL delete_remote_on_completion, - U64 xfer_id, - const LLHost &remote_host, - void (*callback)(void **,S32), - void **user_data) -{ - LLXfer *xferp; - - for (xferp = mReceiveList; xferp ; xferp = xferp->mNext) - { - if (xferp->getXferTypeTag() == LLXfer::XFER_FILE - && (((LLXfer_File*)xferp)->matchesLocalFilename(local_filename)) - && (xfer_id == xferp->mID) - && (remote_host == xferp->mRemoteHost) - && (callback == xferp->mCallback) - && (user_data == xferp->mCallbackDataHandle)) - - { - // cout << "requested a xfer already in progress" << endl; - return; - } + LL_ERRS("Xfer") << "Xfer allocation error" << LL_ENDL; } - xferp = (LLXfer *) new LLXfer_File(); - if (xferp) - { - xferp->mNext = mReceiveList; - mReceiveList = xferp; - - ((LLXfer_File *)xferp)->initializeRequest(xfer_id,local_filename,"",LL_PATH_NONE,remote_host,delete_remote_on_completion,callback,user_data); - startPendingDownloads(); - } - else - { - LL_ERRS() << "Xfer allcoation error" << LL_ENDL; - } } -void LLXferManager::requestXfer(U64 xfer_id, const LLHost &remote_host, BOOL delete_remote_on_completion, void (*callback)(void *,S32,void **,S32),void **user_data) -{ - LLXfer *xferp; - - xferp = (LLXfer *) new LLXfer_Mem(); - if (xferp) - { - xferp->mNext = mReceiveList; - mReceiveList = xferp; - - ((LLXfer_Mem *)xferp)->initializeRequest(xfer_id,"",LL_PATH_NONE,remote_host,delete_remote_on_completion,callback,user_data); - startPendingDownloads(); - } - else - { - LL_ERRS() << "Xfer allcoation error" << LL_ENDL; - } -} -*/ /////////////////////////////////////////////////////////// void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user_data*/) { // there's sometimes an extra 4 bytes added to an xfer payload const S32 BUF_SIZE = LL_XFER_LARGE_PAYLOAD + 4; - char fdata_buf[LL_XFER_LARGE_PAYLOAD + 4]; /* Flawfinder : ignore */ + char fdata_buf[BUF_SIZE]; /* Flawfinder : ignore */ S32 fdata_size; U64 id; S32 packetnum; @@ -614,14 +540,24 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user mesgsys->getS32Fast(_PREHASH_XferID, _PREHASH_Packet, packetnum); fdata_size = mesgsys->getSizeFast(_PREHASH_DataPacket,_PREHASH_Data); - mesgsys->getBinaryDataFast(_PREHASH_DataPacket, _PREHASH_Data, fdata_buf, 0, 0, BUF_SIZE); - - xferp = findXfer(id, mReceiveList); + if (fdata_size < 0 || + fdata_size > BUF_SIZE) + { + char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ + LL_WARNS("Xfer") << "Received invalid xfer data size of " << fdata_size + << " in packet number " << packetnum + << " from " << mesgsys->getSender() + << " for xfer id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) + << LL_ENDL; + return; + } + mesgsys->getBinaryDataFast(_PREHASH_DataPacket, _PREHASH_Data, fdata_buf, fdata_size, 0, BUF_SIZE); - if (!xferp) + xferp = findXferByID(id, mReceiveList); + if (!xferp) { char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ - LL_INFOS() << "received xfer data from " << mesgsys->getSender() + LL_WARNS("Xfer") << "received xfer data from " << mesgsys->getSender() << " for non-existent xfer id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << LL_ENDL; return; @@ -634,11 +570,11 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user // confirm it if it was a resend of the last one, since the confirmation might have gotten dropped if (decodePacketNum(packetnum) == (xferp->mPacketNum - 1)) { - LL_INFOS() << "Reconfirming xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet " << packetnum << LL_ENDL; sendConfirmPacket(mesgsys, id, decodePacketNum(packetnum), mesgsys->getSender()); + LL_INFOS("Xfer") << "Reconfirming xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet " << packetnum << LL_ENDL; sendConfirmPacket(mesgsys, id, decodePacketNum(packetnum), mesgsys->getSender()); } else { - LL_INFOS() << "Ignoring xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " recv'd packet " << packetnum << "; expecting " << xferp->mPacketNum << LL_ENDL; + LL_INFOS("Xfer") << "Ignoring xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " recv'd packet " << packetnum << "; expecting " << xferp->mPacketNum << LL_ENDL; } return; } @@ -663,7 +599,7 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user if (result == LL_ERR_CANNOT_OPEN_FILE) { xferp->abort(LL_ERR_CANNOT_OPEN_FILE); - removeXfer(xferp,&mReceiveList); + removeXfer(xferp,mReceiveList); startPendingDownloads(); return; } @@ -688,7 +624,7 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user if (isLastPacket(packetnum)) { xferp->processEOF(); - removeXfer(xferp,&mReceiveList); + removeXfer(xferp,mReceiveList); startPendingDownloads(); } } @@ -697,7 +633,7 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user void LLXferManager::sendConfirmPacket (LLMessageSystem *mesgsys, U64 id, S32 packetnum, const LLHost &remote_host) { -#if LL_XFER_PROGRESS_MESSAGES +#ifdef LL_XFER_PROGRESS_MESSAGES if (!(packetnum % 50)) { cout << "confirming xfer packet #" << packetnum << endl; @@ -708,6 +644,7 @@ void LLXferManager::sendConfirmPacket (LLMessageSystem *mesgsys, U64 id, S32 pac mesgsys->addU64Fast(_PREHASH_ID, id); mesgsys->addU32Fast(_PREHASH_Packet, packetnum); + // Ignore a circuit failure here, we'll catch it with another message mesgsys->sendMessage(remote_host); } @@ -746,6 +683,28 @@ bool LLXferManager::validateFileForTransfer(const std::string& filename) return find_and_remove(mExpectedTransfers, filename); } +/* Present in fireengine, not used by viewer +void LLXferManager::expectVFileForRequest(const std::string& filename) +{ + mExpectedVFileRequests.insert(filename); +} + +bool LLXferManager::validateVFileForRequest(const std::string& filename) +{ + return find_and_remove(mExpectedVFileRequests, filename); +} + +void LLXferManager::expectVFileForTransfer(const std::string& filename) +{ + mExpectedVFileTransfers.insert(filename); +} + +bool LLXferManager::validateVFileForTransfer(const std::string& filename) +{ + return find_and_remove(mExpectedVFileTransfers, filename); +} +*/ + static bool remove_prefix(std::string& filename, const std::string& prefix) { if (std::equal(prefix.begin(), prefix.end(), filename.begin())) @@ -807,7 +766,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id); char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ - LL_INFOS() << "xfer request id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) + LL_INFOS("Xfer") << "xfer request id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << " to " << mesgsys->getSender() << LL_ENDL; mesgsys->getStringFast(_PREHASH_XferID, _PREHASH_Filename, local_filename); @@ -825,36 +784,45 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user LLXfer *xferp; if (uuid != LLUUID::null) - { + { // Request for an asset - use a VFS file if(NULL == LLAssetType::lookup(type)) { - LL_WARNS() << "Invalid type for xfer request: " << uuid << ":" + LL_WARNS("Xfer") << "Invalid type for xfer request: " << uuid << ":" << type_s16 << " to " << mesgsys->getSender() << LL_ENDL; return; } - LL_INFOS() << "starting vfile transfer: " << uuid << "," << LLAssetType::lookup(type) << " to " << mesgsys->getSender() << LL_ENDL; - if (! mVFS) { - LL_WARNS() << "Attempt to send VFile w/o available VFS" << LL_ENDL; + LL_WARNS("Xfer") << "Attempt to send VFile w/o available VFS" << LL_ENDL; return; } + /* Present in fireengine, not used by viewer + if (!validateVFileForTransfer(uuid.asString())) + { + // it is up to the app sending the file to mark it for expected + // transfer before the request arrives or it will be dropped + LL_WARNS("Xfer") << "SECURITY: Unapproved VFile '" << uuid << "'" << LL_ENDL; + return; + } + */ + + LL_INFOS("Xfer") << "starting vfile transfer: " << uuid << "," << LLAssetType::lookup(type) << " to " << mesgsys->getSender() << LL_ENDL; + xferp = (LLXfer *)new LLXfer_VFile(mVFS, uuid, type); if (xferp) { - xferp->mNext = mSendList; - mSendList = xferp; + mSendList.push_front(xferp); result = xferp->startSend(id,mesgsys->getSender()); } else { - LL_ERRS() << "Xfer allcoation error" << LL_ENDL; + LL_ERRS("Xfer") << "Xfer allcoation error" << LL_ENDL; } } else if (!local_filename.empty()) - { + { // Was given a file name to send // See DEV-21775 for detailed security issues if (local_path == LL_PATH_NONE) @@ -873,7 +841,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user case LL_PATH_NONE: if(!validateFileForTransfer(local_filename)) { - LL_WARNS() << "SECURITY: Unapproved filename '" << local_filename << LL_ENDL; + LL_WARNS("Xfer") << "SECURITY: Unapproved filename '" << local_filename << LL_ENDL; return; } break; @@ -881,13 +849,13 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user case LL_PATH_CACHE: if(!verify_cache_filename(local_filename)) { - LL_WARNS() << "SECURITY: Illegal cache filename '" << local_filename << LL_ENDL; + LL_WARNS("Xfer") << "SECURITY: Illegal cache filename '" << local_filename << LL_ENDL; return; } break; default: - LL_WARNS() << "SECURITY: Restricted file dir enum: " << (U32)local_path << LL_ENDL; + LL_WARNS("Xfer") << "SECURITY: Restricted file dir enum: " << (U32)local_path << LL_ENDL; return; } @@ -902,7 +870,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user { expanded_filename = local_filename; } - LL_INFOS() << "starting file transfer: " << expanded_filename << " to " << mesgsys->getSender() << LL_ENDL; + LL_INFOS("Xfer") << "starting file transfer: " << expanded_filename << " to " << mesgsys->getSender() << LL_ENDL; BOOL delete_local_on_completion = FALSE; mesgsys->getBOOL("XferID", "DeleteOnCompletion", delete_local_on_completion); @@ -912,23 +880,22 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user if (xferp) { - xferp->mNext = mSendList; - mSendList = xferp; + mSendList.push_front(xferp); result = xferp->startSend(id,mesgsys->getSender()); } else { - LL_ERRS() << "Xfer allcoation error" << LL_ENDL; + LL_ERRS("Xfer") << "Xfer allcoation error" << LL_ENDL; } } else - { + { // no uuid or filename - use the ID sent char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ - LL_INFOS() << "starting memory transfer: " + LL_INFOS("Xfer") << "starting memory transfer: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << " to " << mesgsys->getSender() << LL_ENDL; - xferp = findXfer(id, mSendList); + xferp = findXferByID(id, mSendList); if (xferp) { @@ -936,7 +903,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user } else { - LL_INFOS() << "Warning: " << U64_BUF << " not found." << LL_ENDL; + LL_INFOS("Xfer") << "Warning: xfer ID " << U64_BUF << " not found." << LL_ENDL; result = LL_ERR_FILE_NOT_FOUND; } } @@ -946,11 +913,11 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user if (xferp) { xferp->abort(result); - removeXfer(xferp,&mSendList); + removeXfer(xferp, mSendList); } else // can happen with a memory transfer not found { - LL_INFOS() << "Aborting xfer to " << mesgsys->getSender() << " with error: " << result << LL_ENDL; + LL_INFOS("Xfer") << "Aborting xfer to " << mesgsys->getSender() << " with error: " << result << LL_ENDL; mesgsys->newMessageFast(_PREHASH_AbortXfer); mesgsys->nextBlockFast(_PREHASH_XferID); @@ -960,24 +927,86 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user mesgsys->sendMessage(mesgsys->getSender()); } } - else if(xferp && (numActiveXfers(xferp->mRemoteHost) < mMaxOutgoingXfersPerCircuit)) + else if(xferp) { - xferp->sendNextPacket(); - changeNumActiveXfers(xferp->mRemoteHost,1); -// LL_INFOS() << "***STARTING XFER IMMEDIATELY***" << LL_ENDL; - } - else - { - if(xferp) + // Figure out how many transfers the host has requested + LLHostStatus *host_statusp = findHostStatus(xferp->mRemoteHost); + if (host_statusp) { - LL_INFOS() << " queueing xfer request, " << numPendingXfers(xferp->mRemoteHost) << " ahead of this one" << LL_ENDL; + if (host_statusp->mNumActive < mMaxOutgoingXfersPerCircuit) + { // Not many transfers in progress already, so start immediately + xferp->sendNextPacket(); + changeNumActiveXfers(xferp->mRemoteHost,1); + LL_DEBUGS("Xfer") << "Starting xfer ID " << U64_to_str(id) << " immediately" << LL_ENDL; + } + else if (mHardLimitOutgoingXfersPerCircuit == 0 || + (host_statusp->mNumActive + host_statusp->mNumPending) < mHardLimitOutgoingXfersPerCircuit) + { // Must close the file handle and wait for earlier ones to complete + LL_INFOS("Xfer") << " queueing xfer request id " << U64_to_str(id) << ", " + << host_statusp->mNumActive << " active and " + << host_statusp->mNumPending << " pending ahead of this one" + << LL_ENDL; + xferp->closeFileHandle(); // Close the file handle until we're ready to send again + } + else if (mHardLimitOutgoingXfersPerCircuit > 0) + { // Way too many requested ... it's time to stop being nice and kill the circuit + xferp->closeFileHandle(); // Close the file handle in any case + LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(xferp->mRemoteHost); + if (cdp) + { + if (cdp->getTrusted()) + { // Trusted internal circuit - don't kill it + LL_WARNS("Xfer") << "Trusted circuit to " << xferp->mRemoteHost << " has too many xfer requests in the queue " + << host_statusp->mNumActive << " active and " + << host_statusp->mNumPending << " pending ahead of this one" + << LL_ENDL; + } + else + { // Untrusted circuit - time to stop messing around and kill it + LL_WARNS("Xfer") << "Killing circuit to " << xferp->mRemoteHost << " for having too many xfer requests in the queue " + << host_statusp->mNumActive << " active and " + << host_statusp->mNumPending << " pending ahead of this one" + << LL_ENDL; + gMessageSystem->disableCircuit(xferp->mRemoteHost); + } + } + else + { // WTF? Why can't we find a circuit? Try to kill it off + LL_WARNS("Xfer") << "Backlog with circuit to " << xferp->mRemoteHost << " with too many xfer requests in the queue " + << host_statusp->mNumActive << " active and " + << host_statusp->mNumPending << " pending ahead of this one" + << " but no LLCircuitData found???" + << LL_ENDL; + gMessageSystem->disableCircuit(xferp->mRemoteHost); + } + } } else { - LL_WARNS() << "LLXferManager::processFileRequest() - no xfer found!" - << LL_ENDL; + LL_WARNS("Xfer") << "LLXferManager::processFileRequest() - no LLHostStatus found for id " << U64_to_str(id) + << " host " << xferp->mRemoteHost << LL_ENDL; } } + else + { + LL_WARNS("Xfer") << "LLXferManager::processFileRequest() - no xfer found for id " << U64_to_str(id) << LL_ENDL; + } +} + +/////////////////////////////////////////////////////////// + +// Return true if host is in a transfer-flood sitation. Same check for both internal and external hosts +bool LLXferManager::isHostFlooded(const LLHost & host) +{ + bool flooded = false; + LLHostStatus *host_statusp = findHostStatus(host); + if (host_statusp) + { + flooded = (mHardLimitOutgoingXfersPerCircuit > 0 && + (host_statusp->mNumActive + host_statusp->mNumPending) >= (S32)(mHardLimitOutgoingXfersPerCircuit * 0.8f)); + } + + return flooded; } @@ -991,7 +1020,7 @@ void LLXferManager::processConfirmation (LLMessageSystem *mesgsys, void ** /*use mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id); mesgsys->getS32Fast(_PREHASH_XferID, _PREHASH_Packet, packetNum); - LLXfer* xferp = findXfer(id, mSendList); + LLXfer* xferp = findXferByID(id, mSendList); if (xferp) { // cout << "confirmed packet #" << packetNum << " ping: "<< xferp->ACKTimer.getElapsedTimeF32() << endl; @@ -1002,91 +1031,105 @@ void LLXferManager::processConfirmation (LLMessageSystem *mesgsys, void ** /*use } else { - removeXfer(xferp, &mSendList); + removeXfer(xferp, mSendList); } } } /////////////////////////////////////////////////////////// -void LLXferManager::retransmitUnackedPackets () +// Called from LLMessageSystem::processAcks() +void LLXferManager::retransmitUnackedPackets() { LLXfer *xferp; - LLXfer *delp; - xferp = mReceiveList; - while(xferp) + + xfer_list_t::iterator iter = mReceiveList.begin(); + while (iter != mReceiveList.end()) { + xferp = (*iter); if (xferp->mStatus == e_LL_XFER_IN_PROGRESS) { // if the circuit dies, abort if (! gMessageSystem->mCircuitInfo.isCircuitAlive( xferp->mRemoteHost )) { - LL_INFOS() << "Xfer found in progress on dead circuit, aborting" << LL_ENDL; + LL_WARNS("Xfer") << "Xfer found in progress on dead circuit, aborting transfer to " + << xferp->mRemoteHost.getIPandPort() + << LL_ENDL; xferp->mCallbackResult = LL_ERR_CIRCUIT_GONE; xferp->processEOF(); - delp = xferp; - xferp = xferp->mNext; - removeXfer(delp,&mReceiveList); + + iter = mReceiveList.erase(iter); // iter is set to next one after the deletion point + delete (xferp); continue; } } - xferp = xferp->mNext; + ++iter; } - xferp = mSendList; + // Re-build mOutgoingHosts data updateHostStatus(); + F32 et; - while (xferp) + iter = mSendList.begin(); + while (iter != mSendList.end()) { + xferp = (*iter); if (xferp->mWaitingForACK && ( (et = xferp->ACKTimer.getElapsedTimeF32()) > LL_PACKET_TIMEOUT)) { if (xferp->mRetries > LL_PACKET_RETRY_LIMIT) { - LL_INFOS() << "dropping xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet retransmit limit exceeded, xfer dropped" << LL_ENDL; + LL_INFOS("Xfer") << "dropping xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet retransmit limit exceeded, xfer dropped" << LL_ENDL; xferp->abort(LL_ERR_TCP_TIMEOUT); - delp = xferp; - xferp = xferp->mNext; - removeXfer(delp,&mSendList); + iter = mSendList.erase(iter); + delete xferp; + continue; } else { - LL_INFOS() << "resending xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet unconfirmed after: "<< et << " sec, packet " << xferp->mPacketNum << LL_ENDL; + LL_INFOS("Xfer") << "resending xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet unconfirmed after: "<< et << " sec, packet " << xferp->mPacketNum << LL_ENDL; xferp->resendLastPacket(); - xferp = xferp->mNext; } } else if ((xferp->mStatus == e_LL_XFER_REGISTERED) && ( (et = xferp->ACKTimer.getElapsedTimeF32()) > LL_XFER_REGISTRATION_TIMEOUT)) { - LL_INFOS() << "registered xfer never requested, xfer dropped" << LL_ENDL; + LL_INFOS("Xfer") << "registered xfer never requested, xfer dropped" << LL_ENDL; xferp->abort(LL_ERR_TCP_TIMEOUT); - delp = xferp; - xferp = xferp->mNext; - removeXfer(delp,&mSendList); + iter = mSendList.erase(iter); + delete xferp; + continue; } else if (xferp->mStatus == e_LL_XFER_ABORTED) { - LL_WARNS() << "Removing aborted xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << LL_ENDL; - delp = xferp; - xferp = xferp->mNext; - removeXfer(delp,&mSendList); + LL_WARNS("Xfer") << "Removing aborted xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << LL_ENDL; + iter = mSendList.erase(iter); + delete xferp; + continue; } else if (xferp->mStatus == e_LL_XFER_PENDING) { -// LL_INFOS() << "*** numActiveXfers = " << numActiveXfers(xferp->mRemoteHost) << " mMaxOutgoingXfersPerCircuit = " << mMaxOutgoingXfersPerCircuit << LL_ENDL; +// LL_INFOS("Xfer") << "*** numActiveXfers = " << numActiveXfers(xferp->mRemoteHost) << " mMaxOutgoingXfersPerCircuit = " << mMaxOutgoingXfersPerCircuit << LL_ENDL; if (numActiveXfers(xferp->mRemoteHost) < mMaxOutgoingXfersPerCircuit) { -// LL_INFOS() << "bumping pending xfer to active" << LL_ENDL; - xferp->sendNextPacket(); - changeNumActiveXfers(xferp->mRemoteHost,1); - } - xferp = xferp->mNext; - } - else - { - xferp = xferp->mNext; + if (xferp->reopenFileHandle()) + { + LL_WARNS("Xfer") << "Error re-opening file handle for xfer ID " << U64_to_str(xferp->mID) + << " to host " << xferp->mRemoteHost << LL_ENDL; + xferp->abort(LL_ERR_CANNOT_OPEN_FILE); + iter = mSendList.erase(iter); + delete xferp; + continue; + } + else + { // No error re-opening the file, send the first packet + LL_DEBUGS("Xfer") << "Moving pending xfer ID " << U64_to_str(xferp->mID) << " to active" << LL_ENDL; + xferp->sendNextPacket(); + changeNumActiveXfers(xferp->mRemoteHost,1); + } + } } - } + ++iter; + } // end while() loop // // HACK - if we're using xfer confirm throttling, throttle our xfer confirms here @@ -1099,10 +1142,10 @@ void LLXferManager::retransmitUnackedPackets () { break; } - //LL_INFOS() << "Confirm packet queue length:" << mXferAckQueue.size() << LL_ENDL; + //LL_INFOS("Xfer") << "Confirm packet queue length:" << mXferAckQueue.size() << LL_ENDL; LLXferAckInfo ack_info = mXferAckQueue.front(); mXferAckQueue.pop_front(); - //LL_INFOS() << "Sending confirm packet" << LL_ENDL; + //LL_INFOS("Xfer") << "Sending confirm packet" << LL_ENDL; sendConfirmPacket(gMessageSystem, ack_info.mID, ack_info.mPacketNum, ack_info.mRemoteHost); mAckThrottle.throttleOverflow(1000.f*8.f); // Assume 1000 bytes/packet } @@ -1112,7 +1155,7 @@ void LLXferManager::retransmitUnackedPackets () void LLXferManager::abortRequestById(U64 xfer_id, S32 result_code) { - LLXfer * xferp = findXfer(xfer_id, mReceiveList); + LLXfer * xferp = findXferByID(xfer_id, mReceiveList); if (xferp) { if (xferp->mStatus == e_LL_XFER_IN_PROGRESS) @@ -1124,7 +1167,7 @@ void LLXferManager::abortRequestById(U64 xfer_id, S32 result_code) { xferp->mCallbackResult = result_code; xferp->processEOF(); //should notify requester - removeXfer(xferp, &mReceiveList); + removeXfer(xferp, mReceiveList); } // Since already removed or marked as aborted no need // to wait for processAbort() to start new download @@ -1143,12 +1186,12 @@ void LLXferManager::processAbort (LLMessageSystem *mesgsys, void ** /*user_data* mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id); mesgsys->getS32Fast(_PREHASH_XferID, _PREHASH_Result, result_code); - xferp = findXfer(id, mReceiveList); + xferp = findXferByID(id, mReceiveList); if (xferp) { xferp->mCallbackResult = result_code; xferp->processEOF(); - removeXfer(xferp, &mReceiveList); + removeXfer(xferp, mReceiveList); startPendingDownloads(); } } @@ -1164,27 +1207,29 @@ void LLXferManager::startPendingDownloads() // requests get pushed toward the back. Thus, if we didn't do a // stateful iteration, it would be possible for old requests to // never start. - LLXfer* xferp = mReceiveList; + LLXfer* xferp; std::list<LLXfer*> pending_downloads; S32 download_count = 0; S32 pending_count = 0; - while(xferp) + for (xfer_list_t::iterator iter = mReceiveList.begin(); + iter != mReceiveList.end(); + ++iter) { + xferp = (*iter); if(xferp->mStatus == e_LL_XFER_PENDING) - { + { // Count and accumulate pending downloads ++pending_count; pending_downloads.push_front(xferp); } else if(xferp->mStatus == e_LL_XFER_IN_PROGRESS) - { + { // Count downloads in progress ++download_count; } - xferp = xferp->mNext; } S32 start_count = mMaxIncomingXfers - download_count; - LL_DEBUGS() << "LLXferManager::startPendingDownloads() - XFER_IN_PROGRESS: " + LL_DEBUGS("Xfer") << "LLXferManager::startPendingDownloads() - XFER_IN_PROGRESS: " << download_count << " XFER_PENDING: " << pending_count << " startring " << llmin(start_count, pending_count) << LL_ENDL; @@ -1209,29 +1254,15 @@ void LLXferManager::startPendingDownloads() /////////////////////////////////////////////////////////// -void LLXferManager::addToList(LLXfer* xferp, LLXfer*& head, BOOL is_priority) +void LLXferManager::addToList(LLXfer* xferp, xfer_list_t & xfer_list, BOOL is_priority) { if(is_priority) { - xferp->mNext = NULL; - LLXfer* next = head; - if(next) - { - while(next->mNext) - { - next = next->mNext; - } - next->mNext = xferp; - } - else - { - head = xferp; - } + xfer_list.push_back(xferp); } else { - xferp->mNext = head; - head = xferp; + xfer_list.push_front(xferp); } } diff --git a/indra/llmessage/llxfermanager.h b/indra/llmessage/llxfermanager.h index d258f0a5ce..45ae2ffdd3 100644 --- a/indra/llmessage/llxfermanager.h +++ b/indra/llmessage/llxfermanager.h @@ -77,6 +77,7 @@ class LLXferManager protected: S32 mMaxOutgoingXfersPerCircuit; + S32 mHardLimitOutgoingXfersPerCircuit; // At this limit, kill off the connection S32 mMaxIncomingXfers; BOOL mUseAckThrottling; // Use ack throttling to cap file xfer bandwidth @@ -92,19 +93,22 @@ class LLXferManager HIGH_PRIORITY = TRUE, }; - LLXfer *mSendList; - LLXfer *mReceiveList; + // Linked FIFO list, add to the front and pull from back + typedef std::deque<LLXfer *> xfer_list_t; + xfer_list_t mSendList; + xfer_list_t mReceiveList; typedef std::list<LLHostStatus*> status_list_t; status_list_t mOutgoingHosts; - private: protected: // implementation methods virtual void startPendingDownloads(); - virtual void addToList(LLXfer* xferp, LLXfer*& head, BOOL is_priority); + virtual void addToList(LLXfer* xferp, xfer_list_t & xfer_list, BOOL is_priority); std::multiset<std::string> mExpectedTransfers; // files that are authorized to transfer out std::multiset<std::string> mExpectedRequests; // files that are authorized to be downloaded on top of + std::multiset<std::string> mExpectedVFileTransfers; // files that are authorized to transfer out + std::multiset<std::string> mExpectedVFileRequests; // files that are authorized to be downloaded on top of public: LLXferManager(LLVFS *vfs); @@ -117,14 +121,17 @@ class LLXferManager void setAckThrottleBPS(const F32 bps); // list management routines - virtual LLXfer *findXfer(U64 id, LLXfer *list_head); - virtual void removeXfer (LLXfer *delp, LLXfer **list_head); - virtual U32 numActiveListEntries(LLXfer *list_head); + virtual LLXfer *findXferByID(U64 id, xfer_list_t & xfer_list); + virtual void removeXfer (LLXfer *delp, xfer_list_t & xfer_list); + + LLHostStatus * findHostStatus(const LLHost &host); virtual S32 numActiveXfers(const LLHost &host); virtual S32 numPendingXfers(const LLHost &host); + virtual void changeNumActiveXfers(const LLHost &host, S32 delta); virtual void setMaxOutgoingXfersPerCircuit (S32 max_num); + virtual void setHardLimitOutgoingXfersPerCircuit(S32 max_num); virtual void setMaxIncomingXfers(S32 max_num); virtual void updateHostStatus(); virtual void printHostStatus(); @@ -136,8 +143,6 @@ class LLXferManager virtual S32 decodePacketNum(S32 packet_num); virtual BOOL isLastPacket(S32 packet_num); - virtual U64 registerXfer(const void *datap, const S32 length); - // file requesting routines // .. to file virtual U64 requestFile(const std::string& local_filename, @@ -148,7 +153,7 @@ class LLXferManager void (*callback)(void**,S32,LLExtStat), void** user_data, BOOL is_priority = FALSE, BOOL use_big_packets = FALSE); - + /* // .. to memory virtual void requestFile(const std::string& remote_filename, ELLPath remote_path, @@ -157,7 +162,7 @@ class LLXferManager void (*callback)(void*, S32, void**, S32, LLExtStat), void** user_data, BOOL is_priority = FALSE); - + */ // vfile requesting // .. to vfile virtual void requestVFile(const LLUUID &local_id, const LLUUID& remote_id, @@ -180,18 +185,15 @@ class LLXferManager virtual void expectFileForRequest(const std::string& filename); virtual bool validateFileForRequest(const std::string& filename); -/* -// xfer request (may be memory or file) -// .. to file - virtual void requestXfer(const char *local_filename, U64 xfer_id, - BOOL delete_remote_on_completion, - const LLHost &remote_host, void (*callback)(void **,S32),void **user_data); -// .. to memory - virtual void requestXfer(U64 xfer_id, - const LLHost &remote_host, - BOOL delete_remote_on_completion, - void (*callback)(void *, S32, void **, S32),void **user_data); -*/ + /** + Same idea but for VFiles, kept separate to avoid namespace overlap + */ + /* Present in fireengine, not used by viewer + virtual void expectVFileForTransfer(const std::string& filename); + virtual bool validateVFileForTransfer(const std::string& filename); + virtual void expectVFileForRequest(const std::string& filename); + virtual bool validateVFileForRequest(const std::string& filename); + */ virtual void processReceiveData (LLMessageSystem *mesgsys, void **user_data); virtual void sendConfirmPacket (LLMessageSystem *mesgsys, U64 id, S32 packetnum, const LLHost &remote_host); @@ -204,6 +206,8 @@ class LLXferManager // error handling void abortRequestById(U64 xfer_id, S32 result_code); virtual void processAbort (LLMessageSystem *mesgsys, void **user_data); + + virtual bool isHostFlooded(const LLHost & host); }; extern LLXferManager* gXferManager; diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index 3b3075c6bd..4f52afb317 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -317,6 +317,8 @@ public: // "init_history" message void initializeUrlHistory(const LLSD& url_history); + boost::shared_ptr<LLPluginClassMedia> getSharedPrt() { return boost::dynamic_pointer_cast<LLPluginClassMedia>(shared_from_this()); } // due to enable_shared_from_this + protected: LLPluginClassMediaOwner *mOwner; diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 559895da1a..00a933a0bb 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -845,6 +845,14 @@ void LLComboBox::setTextEntry(const LLStringExplicit& text) } } +void LLComboBox::setKeystrokeOnEsc(BOOL enable) +{ + if (mTextEntry) + { + mTextEntry->setKeystrokeOnEsc(enable); + } +} + void LLComboBox::onTextEntry(LLLineEditor* line_editor) { if (mTextEntryCallback != NULL) diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index c9b1212b70..7d38c051a5 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -126,6 +126,7 @@ public: virtual LLSD getValue() const; void setTextEntry(const LLStringExplicit& text); + void setKeystrokeOnEsc(BOOL enable); LLScrollListItem* add(const std::string& name, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); // add item "name" to menu LLScrollListItem* add(const std::string& name, const LLUUID& id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index bd6b00d38b..cfab6b7fc8 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -125,6 +125,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mTextLeftEdge(0), // computed in updateTextPadding() below mTextRightEdge(0), // computed in updateTextPadding() below mCommitOnFocusLost( p.commit_on_focus_lost ), + mKeystrokeOnEsc(FALSE), mRevertOnEsc( p.revert_on_esc ), mKeystrokeCallback( p.keystroke_callback() ), mIsSelecting( FALSE ), @@ -1494,6 +1495,10 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) { setText(mPrevText); // Note, don't set handled, still want to loose focus (won't commit becase text is now unchanged) + if (mKeystrokeOnEsc) + { + onKeystroke(); + } } break; diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 88468503df..287837a15c 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -214,6 +214,7 @@ public: void setCommitOnFocusLost( BOOL b ) { mCommitOnFocusLost = b; } void setRevertOnEsc( BOOL b ) { mRevertOnEsc = b; } + void setKeystrokeOnEsc(BOOL b) { mKeystrokeOnEsc = b; } void setCursorColor(const LLColor4& c) { mCursorColor = c; } const LLColor4& getCursorColor() const { return mCursorColor.get(); } @@ -338,6 +339,7 @@ protected: BOOL mCommitOnFocusLost; BOOL mRevertOnEsc; + BOOL mKeystrokeOnEsc; keystroke_callback_t mKeystrokeCallback; diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 1a49b94c23..134b76c720 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -2493,11 +2493,11 @@ void LLTextEditor::updateLinkSegments() } } } - + // if the link's label (what the user can edit) is a valid Url, // then update the link's HREF to be the same as the label text. // This lets users edit Urls in-place. - if (LLUrlRegistry::instance().hasUrl(url_label)) + if (acceptsTextInput() && LLUrlRegistry::instance().hasUrl(url_label)) { std::string new_url = wstring_to_utf8str(url_label); LLStringUtil::trim(new_url); diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index a4dc5bcde1..cd9b52d164 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -298,7 +298,7 @@ std::string LLUrlEntryHTTPLabel::getUrl(const std::string &string) const LLUrlEntryInvalidSLURL::LLUrlEntryInvalidSLURL() : LLUrlEntryBase() { - mPattern = boost::regex("(http://(maps.secondlife.com|slurl.com)/secondlife/|secondlife://(/app/(worldmap|teleport)/)?)[^ /]+(/-?[0-9]+){1,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?", + mPattern = boost::regex("(https?://(maps.secondlife.com|slurl.com)/secondlife/|secondlife://(/app/(worldmap|teleport)/)?)[^ /]+(/-?[0-9]+){1,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?", boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_http.xml"; mTooltip = LLTrans::getString("TooltipHttpUrl"); @@ -385,8 +385,9 @@ bool LLUrlEntryInvalidSLURL::isSLURLvalid(const std::string &url) const LLUrlEntrySLURL::LLUrlEntrySLURL() { // see http://slurl.com/about.php for details on the SLURL format - mPattern = boost::regex("http://(maps.secondlife.com|slurl.com)/secondlife/[^ /]+(/\\d+){0,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?", + mPattern = boost::regex("https?://(maps.secondlife.com|slurl.com)/secondlife/[^ /]+(/\\d+){0,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?", boost::regex::perl|boost::regex::icase); + mIcon = "Hand"; mMenuName = "menu_url_slurl.xml"; mTooltip = LLTrans::getString("TooltipSLURL"); } diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 28e9931718..78c149d9fd 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -175,6 +175,7 @@ class LLUrlEntrySLURL : public LLUrlEntryBase { public: LLUrlEntrySLURL(); + /*virtual*/ bool isTrusted() const { return true; } /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); /*virtual*/ std::string getLocation(const std::string &url) const; }; diff --git a/indra/llui/llviewereventrecorder.cpp b/indra/llui/llviewereventrecorder.cpp index 9fe6a542b4..8754cfebbb 100644 --- a/indra/llui/llviewereventrecorder.cpp +++ b/indra/llui/llviewereventrecorder.cpp @@ -34,11 +34,11 @@ LLViewerEventRecorder::LLViewerEventRecorder() { logEvents = false; // Remove any previous event log file std::string old_log_ui_events_to_llsd_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.old"); - LLFile::remove(old_log_ui_events_to_llsd_file); + LLFile::remove(old_log_ui_events_to_llsd_file, ENOENT); mLogFilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.llsd"); - LLFile::rename(mLogFilename, old_log_ui_events_to_llsd_file); + LLFile::rename(mLogFilename, old_log_ui_events_to_llsd_file, ENOENT); } diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 5f35a0f0f9..843294c239 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1515,6 +1515,7 @@ void LLWindowMacOSX::updateCursor() case UI_CURSOR_NOLOCKED: case UI_CURSOR_ARROWLOCKED: case UI_CURSOR_GRABLOCKED: + case UI_CURSOR_PIPETTE: case UI_CURSOR_TOOLTRANSLATE: case UI_CURSOR_TOOLROTATE: case UI_CURSOR_TOOLSCALE: @@ -1565,6 +1566,7 @@ void LLWindowMacOSX::initCursors() initPixmapCursor(UI_CURSOR_NOLOCKED, 8, 8); initPixmapCursor(UI_CURSOR_ARROWLOCKED, 1, 1); initPixmapCursor(UI_CURSOR_GRABLOCKED, 2, 14); + initPixmapCursor(UI_CURSOR_PIPETTE, 3, 29); initPixmapCursor(UI_CURSOR_TOOLTRANSLATE, 1, 1); initPixmapCursor(UI_CURSOR_TOOLROTATE, 1, 1); initPixmapCursor(UI_CURSOR_TOOLSCALE, 1, 1); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 6e3aba51cf..f98c2423e5 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -2708,6 +2708,14 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ } } break; + default: + { + if (gDebugWindowProc) + { + LL_INFOS("Window") << "Unhandled windows message code: " << U32(u_msg) << LL_ENDL; + } + } + break; } window_imp->mCallbacks->handlePauseWatchdog(window_imp); diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 2ac43accc5..2bd5526a86 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -810,8 +810,9 @@ void MediaPluginCEF::keyEvent(dullahan::EKeyEvent key_event, LLSD native_key_dat bool event_isrepeat = native_key_data["event_isrepeat"].asBoolean(); // adding new code below in unicodeInput means we don't send ascii chars - // here too or we get double key presses on a mac. - if (((unsigned char)event_chars < 0x10 || (unsigned char)event_chars >= 0x7f )) + // here too or we get double key presses on a mac. + bool esc_key = (event_umodchars == 27); + if (esc_key || ((unsigned char)event_chars < 0x10 || (unsigned char)event_chars >= 0x7f )) { mCEFLib->nativeKeyboardEventOSX(key_event, event_modifiers, event_keycode, event_chars, diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 696f603a13..d399f7d858 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -200,7 +200,6 @@ set(viewer_SOURCE_FILES llflickrconnect.cpp llfloaterabout.cpp llfloaterbvhpreview.cpp - llfloaterauction.cpp llfloaterautoreplacesettings.cpp llfloateravatar.cpp llfloateravatarpicker.cpp @@ -820,7 +819,6 @@ set(viewer_HEADER_FILES llflickrconnect.h llfloaterabout.h llfloaterbvhpreview.h - llfloaterauction.h llfloaterautoreplacesettings.h llfloateravatar.h llfloateravatarpicker.h diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 8710cfdff2..cbad66a094 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -5.1.6 +5.1.7 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 8649484d2f..c058d33e52 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4809,7 +4809,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>0</integer> + <integer>1</integer> </map> <key>InventoryOutboxDisplayBoth</key> <map> @@ -12372,7 +12372,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>500.0</real> + <real>3000.0</real> </map> <key>UpdaterMaximumBandwidth</key> <map> diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 92e61d2e86..3d4bd659f1 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -392,5 +392,27 @@ <key>Value</key> <string></string> </map> + <key>SnapshotBaseDir</key> + <map> + <key>Comment</key> + <string>Path to last snapshot save location</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string></string> + </map> + <key>SnapshotBaseName</key> + <map> + <key>Comment</key> + <string>Pattern for naming snapshots</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>Snapshot</string> + </map> </map> </llsd> diff --git a/indra/newview/cursors_mac/UI_CURSOR_PIPETTE.tif b/indra/newview/cursors_mac/UI_CURSOR_PIPETTE.tif Binary files differnew file mode 100644 index 0000000000..b4780967f9 --- /dev/null +++ b/indra/newview/cursors_mac/UI_CURSOR_PIPETTE.tif diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 4e41d6d083..14c8dba39f 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -282,7 +282,6 @@ StrCpy $INSTSHORTCUT "${SHORTCUT}" Call CheckIfAdministrator # Make sure the user can install/uninstall
Call CloseSecondLife # Make sure Second Life not currently running
-Call CheckNetworkConnection # Ping secondlife.com
Call CheckWillUninstallV2 # Check if Second Life is already installed
StrCmp $DO_UNINSTALL_V2 "" PRESERVE_DONE
@@ -347,16 +346,17 @@ WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\I # Write URL registry info
WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "(default)" "URL:Second Life"
WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "URL Protocol" ""
-WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}\DefaultIcon" "" '"$INSTDIR\$INSTEXE"'
+WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}\DefaultIcon" "" '"$INSTDIR\$VIEWER_EXE"'
# URL param must be last item passed to viewer, it ignores subsequent params to avoid parameter injection attacks.
-WriteRegExpandStr HKEY_CLASSES_ROOT "${URLNAME}\shell\open\command" "" '"$INSTDIR\$INSTEXE" -url "%1"'
-WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info"(default)" "URL:Second Life"
+# MAINT-8305: On SLURL click, directly invoke the viewer, not the launcher.
+WriteRegExpandStr HKEY_CLASSES_ROOT "${URLNAME}\shell\open\command" "" '"$INSTDIR\$VIEWER_EXE" -url "%1"'
+WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info" "(default)" "URL:Second Life"
WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info" "URL Protocol" ""
-WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\DefaultIcon" "" '"$INSTDIR\$INSTEXE"'
+WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\DefaultIcon" "" '"$INSTDIR\$VIEWER_EXE"'
# URL param must be last item passed to viewer, it ignores subsequent params to avoid parameter injection attacks.
-WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$INSTEXE" -url "%1"'
+WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$VIEWER_EXE" -url "%1"'
# Only allow Launcher to be the icon
WriteRegStr HKEY_CLASSES_ROOT "Applications\$INSTEXE" "IsHostApp" ""
@@ -531,41 +531,6 @@ Function un.CloseSecondLife FunctionEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Test our connection to secondlife.com
-;; Also allows us to count attempted installs by examining web logs.
-;; *TODO: Return current SL version info and have installer check
-;; if it is up to date.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-Function CheckNetworkConnection
- Push $0
- Push $1
- Push $2 # Option value for GetOptions
- DetailPrint $(CheckNetworkConnectionDP)
-# Look for a tag value from the stub installer, used for statistics to correlate installs.
-# Default to "" if not found on command line.
- StrCpy $2 ""
- ${GetOptions} $COMMANDLINE "/STUBTAG=" $2
- GetTempFileName $0
- !define HTTP_TIMEOUT 5000 # Milliseconds
-# Don't show secondary progress bar, this will be quick.
- NSISdl::download_quiet \
- /TIMEOUT=${HTTP_TIMEOUT} \
- "http://install.secondlife.com/check/?stubtag=$2&version=${VERSION_LONG}" \
- $0
- Pop $1 # Return value, either "success", "cancel" or an error message
- ; MessageBox MB_OK "Download result: $1"
- ; Result ignored for now
- ; StrCmp $1 "success" +2
- ; DetailPrint "Connection failed: $1"
- Delete $0 # Temporary file
- Pop $2
- Pop $1
- Pop $0
- Return
-
-FunctionEnd
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Delete files on install if previous install exists to prevent undesired behavior
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function RemoveProgFilesOnInst
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index b413c21033..4ce5e09254 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -1593,6 +1593,8 @@ void LLAgent::setAutoPilotTargetGlobal(const LLVector3d &target_global) LLViewerObject *obj; LLWorld::getInstance()->resolveStepHeightGlobal(NULL, target_global, traceEndPt, targetOnGround, groundNorm, &obj); + // Note: this might malfunction for sitting agent, since pelvis stays same, but agent's position becomes lower + // But for autopilot to work we assume that agent is standing and ready to go. F64 target_height = llmax((F64)gAgentAvatarp->getPelvisToFoot(), target_global.mdV[VZ] - targetOnGround.mdV[VZ]); // clamp z value of target to minimum height above ground diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index b927a52e77..7d7340fde2 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llappviewer.cpp * @brief The LLAppViewer class definitions * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2012, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -197,7 +197,7 @@ #include "llfolderview.h" #include "llagentpilot.h" #include "llvovolume.h" -#include "llflexibleobject.h" +#include "llflexibleobject.h" #include "llvosurfacepatch.h" #include "llviewerfloaterreg.h" #include "llcommandlineparser.h" @@ -237,9 +237,9 @@ #include "llviewereventrecorder.h" // *FIX: These extern globals should be cleaned up. -// The globals either represent state/config/resource-storage of either -// this app, or another 'component' of the viewer. App globals should be -// moved into the app class, where as the other globals should be +// The globals either represent state/config/resource-storage of either +// this app, or another 'component' of the viewer. App globals should be +// moved into the app class, where as the other globals should be // moved out of here. // If a global symbol reference seems valid, it will be included // via header files above. @@ -284,9 +284,9 @@ BOOL gShowObjectUpdates = FALSE; BOOL gUseQuickTime = TRUE; eLastExecEvent gLastExecEvent = LAST_EXEC_NORMAL; -S32 gLastExecDuration = -1; // (<0 indicates unknown) +S32 gLastExecDuration = -1; // (<0 indicates unknown) -#if LL_WINDOWS +#if LL_WINDOWS # define LL_PLATFORM_KEY "win" #elif LL_DARWIN # define LL_PLATFORM_KEY "mac" @@ -544,7 +544,7 @@ bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base) params.bottom_pad = 2; base->appendWidget(params," ",false); - + return true; } @@ -560,7 +560,7 @@ static void settings_to_globals() MENU_BAR_WIDTH = gSavedSettings.getS32("MenuBarWidth"); LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize")); - + LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLCoreProfile"); LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport"); LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); @@ -583,7 +583,7 @@ static void settings_to_globals() gAgentPilot.setNumRuns(gSavedSettings.getS32("StatsNumRuns")); gAgentPilot.setQuitAfterRuns(gSavedSettings.getBOOL("StatsQuitAfterRuns")); gAgent.setHideGroupTitle(gSavedSettings.getBOOL("RenderHideGroupTitle")); - + gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc"); gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale"); @@ -614,7 +614,7 @@ public: void run() { llofstream os(mFile.c_str()); - + while (!LLAppViewer::instance()->isQuitting()) { LLTrace::BlockTimer::writeLog(os); @@ -646,16 +646,16 @@ bool LLAppViewer::sendURLToOtherInstance(const std::string& url) // Static members. // The single viewer app. LLAppViewer* LLAppViewer::sInstance = NULL; -LLTextureCache* LLAppViewer::sTextureCache = NULL; -LLImageDecodeThread* LLAppViewer::sImageDecodeThread = NULL; -LLTextureFetch* LLAppViewer::sTextureFetch = NULL; +LLTextureCache* LLAppViewer::sTextureCache = NULL; +LLImageDecodeThread* LLAppViewer::sImageDecodeThread = NULL; +LLTextureFetch* LLAppViewer::sTextureFetch = NULL; std::string getRuntime() { return llformat("%.4f", (F32)LLTimer::getElapsedSeconds().value()); } -LLAppViewer::LLAppViewer() +LLAppViewer::LLAppViewer() : mMarkerFile(), mLogoutMarkerFile(), mReportedCrash(false), @@ -698,12 +698,12 @@ LLAppViewer::LLAppViewer() gLoggedInTime.stop(); initLoggingAndGetLastDuration(); - + processMarkerFiles(); // // OK to write stuff to logs now, we've now crash reported if necessary // - + LLLoginInstance::instance().setPlatformInfo(gPlatform, LLOSInfo::instance().getOSVersionString(), LLOSInfo::instance().getOSStringSimple()); } @@ -712,7 +712,7 @@ LLAppViewer::~LLAppViewer() delete mSettingsLocationList; destroyMainloopTimeout(); - + // If we got to this destructor somehow, the app didn't hang. removeMarkerFiles(); } @@ -739,7 +739,7 @@ void fast_exit(int rc) bool LLAppViewer::init() -{ +{ setupErrorHandling(mSecondInstance); // @@ -763,12 +763,12 @@ bool LLAppViewer::init() gDirUtilp->setSkinFolder("default", "en"); // initLoggingAndGetLastDuration(); - + // // OK to write stuff to logs now, we've now crash reported if necessary // init_default_trans_args(); - + if (!initConfiguration()) return false; @@ -806,11 +806,11 @@ bool LLAppViewer::init() // Initialize the non-LLCurl libcurl library. Should be called // before consumers (LLTextureFetch). mAppCoreHttp.init(); - + LL_INFOS("InitInfo") << "LLCore::Http initialized." << LL_ENDL ; LLMachineID::init(); - + { if (gSavedSettings.getBOOL("QAModeMetrics")) { @@ -885,7 +885,7 @@ bool LLAppViewer::init() LLKeyboard::setStringTranslatorFunc( LLTrans::getKeyboardString ); LLWeb::initClass(); // do this after LLUI - + // Provide the text fields with callbacks for opening Urls LLUrlAction::setOpenURLCallback(boost::bind(&LLWeb::loadURL, _1, LLStringUtil::null, LLStringUtil::null)); LLUrlAction::setOpenURLInternalCallback(boost::bind(&LLWeb::loadURLInternal, _1, LLStringUtil::null, LLStringUtil::null, false)); @@ -901,11 +901,11 @@ bool LLAppViewer::init() LLFloater::initClass(); ///////////////////////////////////////////////// - + LLToolMgr::getInstance(); // Initialize tool manager if not already instantiated - + LLViewerFloaterReg::registerFloaters(); - + ///////////////////////////////////////////////// // // Load settings files @@ -924,7 +924,7 @@ bool LLAppViewer::init() #else mime_types_name = "mime_types.xml"; #endif - LLMIMETypes::parseMIMETypes( mime_types_name ); + LLMIMETypes::parseMIMETypes( mime_types_name ); // Copy settings to globals. *TODO: Remove or move to appropriage class initializers settings_to_globals(); @@ -985,7 +985,7 @@ bool LLAppViewer::init() LLInitClassList::instance().fireCallbacks(); LLFolderViewItem::initClass(); // SJB: Needs to happen after initWindow(), not sure why but related to fonts - + gGLManager.getGLInfo(gDebugInfo); gGLManager.printGLInfoString(); @@ -1008,7 +1008,7 @@ bool LLAppViewer::init() // If we don't have the right GL requirements, exit. if (!gGLManager.mHasRequirements) - { + { // can't use an alert here since we're exiting and // all hell breaks lose. OSMessageBox( @@ -1020,7 +1020,7 @@ bool LLAppViewer::init() // Without SSE2 support we will crash almost immediately, warn here. if (!gSysCPU.hasSSE2()) - { + { // can't use an alert here since we're exiting and // all hell breaks lose. OSMessageBox( @@ -1036,7 +1036,7 @@ bool LLAppViewer::init() bool unsupported = false; LLSD args; std::string minSpecs; - + // get cpu data from xml std::stringstream minCPUString(LLNotifications::instance().getGlobalString("UnsupportedCPUAmount")); S32 minCPU = 0; @@ -1069,11 +1069,11 @@ bool LLAppViewer::init() if (LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_UNKNOWN) { LLNotificationsUtil::add("UnknownGPU"); - } - + } + if(unsupported) { - if(!gSavedSettings.controlExists("WarnUnsupportedHardware") + if(!gSavedSettings.controlExists("WarnUnsupportedHardware") || gSavedSettings.getBOOL("WarnUnsupportedHardware")) { args["MINSPECS"] = minSpecs; @@ -1083,20 +1083,22 @@ bool LLAppViewer::init() } } -#if LL_RELEASE_FOR_DOWNLOAD - char* PARENT = getenv("PARENT"); - if (! (PARENT && std::string(PARENT) == "SL_Launcher")) + // MAINT-8305: If we're processing a SLURL, skip the launcher check. + if (gSavedSettings.getString("CmdLineLoginLocation").empty()) { - // Don't directly run this executable. Please run the launcher, which - // will run the viewer itself. - // Naturally we do not consider this bulletproof. The point is to - // gently remind a user who *inadvertently* finds him/herself in this - // situation to do things the Right Way. Anyone who intentionally - // bypasses this mechanism needs no reminder that s/he's shooting - // him/herself in the foot. - LLNotificationsUtil::add("RunLauncher"); + const char* PARENT = getenv("PARENT"); + if (! (PARENT && std::string(PARENT) == "SL_Launcher")) + { + // Don't directly run this executable. Please run the launcher, which + // will run the viewer itself. + // Naturally we do not consider this bulletproof. The point is to + // gently remind a user who *inadvertently* finds him/herself in this + // situation to do things the Right Way. Anyone who intentionally + // bypasses this mechanism needs no reminder that s/he's shooting + // him/herself in the foot. + LLNotificationsUtil::add("RunLauncher"); + } } -#endif #if LL_WINDOWS if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion()) @@ -1181,7 +1183,7 @@ bool LLAppViewer::init() LLTextUtil::TextHelpers::iconCallbackCreationFunction = create_text_segment_icon_from_url_match; - //EXT-7013 - On windows for some locale (Japanese) standard + //EXT-7013 - On windows for some locale (Japanese) standard //datetime formatting functions didn't support some parameters such as "weekday". //Names for days and months localized in xml are also useful for Polish locale(STORM-107). std::string language = gSavedSettings.getString("Language"); @@ -1275,8 +1277,8 @@ void LLAppViewer::checkMemory() bool is_low = LLMemory::isMemoryPoolLow() ; - LLPipeline::throttleNewMemoryAllocation(is_low) ; - + LLPipeline::throttleNewMemoryAllocation(is_low) ; + if(is_low) { LLMemory::logMemoryInfo() ; @@ -1418,7 +1420,7 @@ bool LLAppViewer::doFrame() // Update state based on messages, user input, object idle. { pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! - + LL_RECORD_BLOCK_TIME(FTM_IDLE); idle(); @@ -1471,7 +1473,7 @@ bool LLAppViewer::doFrame() // Sleep and run background threads { LL_RECORD_BLOCK_TIME(FTM_SLEEP); - + // yield some time to the os based on command line option static LLCachedControl<S32> yield_time(gSavedSettings, "YieldTime", -1); if(yield_time >= 0) @@ -1497,7 +1499,7 @@ bool LLAppViewer::doFrame() LLAppViewer::getImageDecodeThread()->pause(); } } - + if (mRandomizeFramerate) { ms_sleep(rand() % 200); @@ -1511,7 +1513,7 @@ bool LLAppViewer::doFrame() } S32 total_work_pending = 0; - S32 total_io_pending = 0; + S32 total_io_pending = 0; { S32 work_pending = 0; S32 io_pending = 0; @@ -1538,18 +1540,18 @@ bool LLAppViewer::doFrame() } gMeshRepo.update() ; - + if(!total_work_pending) //pause texture fetching threads if nothing to process. { LLAppViewer::getTextureCache()->pause(); LLAppViewer::getImageDecodeThread()->pause(); - LLAppViewer::getTextureFetch()->pause(); + LLAppViewer::getTextureFetch()->pause(); } if(!total_io_pending) //pause file threads if nothing to process. { - LLVFSThread::sLocal->pause(); - LLLFSThread::sLocal->pause(); - } + LLVFSThread::sLocal->pause(); + LLLFSThread::sLocal->pause(); + } //texture fetching debugger if(LLTextureFetchDebugger::isEnabled()) @@ -1558,7 +1560,7 @@ bool LLAppViewer::doFrame() LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger"); if(tex_fetch_debugger_instance) { - tex_fetch_debugger_instance->idle() ; + tex_fetch_debugger_instance->idle() ; } } @@ -1686,7 +1688,7 @@ bool LLAppViewer::cleanup() LL_INFOS() << "Viewer disconnected" << LL_ENDL; - display_cleanup(); + display_cleanup(); release_start_screen(); // just in case @@ -1711,7 +1713,7 @@ bool LLAppViewer::cleanup() } LLKeyframeDataCache::clear(); - + // End TransferManager before deleting systems it depends on (Audio, VFS, AssetStorage) #if 0 // this seems to get us stuck in an infinite loop... gTransferManager.cleanup(); @@ -1790,24 +1792,24 @@ bool LLAppViewer::cleanup() gViewerWindow->shutdownViews(); LL_INFOS() << "Cleaning up Inventory" << LL_ENDL; - + // Cleanup Inventory after the UI since it will delete any remaining observers // (Deleted observers should have already removed themselves) gInventory.cleanupInventory(); LL_INFOS() << "Cleaning up Selections" << LL_ENDL; - + // Clean up selection managers after UI is destroyed, as UI may be observing them. // Clean up before GL is shut down because we might be holding on to objects with texture references LLSelectMgr::cleanupGlobals(); - + LL_INFOS() << "Shutting down OpenGL" << LL_ENDL; // Shut down OpenGL if( gViewerWindow) { gViewerWindow->shutdownGL(); - + // Destroy window, and make sure we're not fullscreen // This may generate window reshape and activation events. // Therefore must do this before destroying the message system. @@ -1817,26 +1819,26 @@ bool LLAppViewer::cleanup() } LL_INFOS() << "Cleaning up Keyboard & Joystick" << LL_ENDL; - + // viewer UI relies on keyboard so keep it aound until viewer UI isa gone delete gKeyboard; gKeyboard = NULL; // Turn off Space Navigator and similar devices LLViewerJoystick::getInstance()->terminate(); - + LL_INFOS() << "Cleaning up Objects" << LL_ENDL; - + LLViewerObject::cleanupVOClasses(); SUBSYSTEM_CLEANUP(LLAvatarAppearance); - + SUBSYSTEM_CLEANUP(LLAvatarAppearance); - + SUBSYSTEM_CLEANUP(LLPostProcess); LLTracker::cleanupInstance(); - + // *FIX: This is handled in LLAppViewerWin32::cleanup(). // I'm keeping the comment to remember its order in cleanup, // in case of unforseen dependency. @@ -1851,8 +1853,8 @@ bool LLAppViewer::cleanup() } LLPrimitive::cleanupVolumeManager(); - LL_INFOS() << "Additional Cleanup..." << LL_ENDL; - + LL_INFOS() << "Additional Cleanup..." << LL_ENDL; + LLViewerParcelMgr::cleanupGlobals(); // *Note: this is where gViewerStats used to be deleted. @@ -1865,7 +1867,7 @@ bool LLAppViewer::cleanup() SUBSYSTEM_CLEANUP(LLWorldMapView); SUBSYSTEM_CLEANUP(LLFolderViewItem); SUBSYSTEM_CLEANUP(LLUI); - + // // Shut down the VFS's AFTER the decode manager cleans up (since it cleans up vfiles). // Also after viewerwindow is deleted, since it may have image pointers (which have vfiles) @@ -1876,18 +1878,18 @@ bool LLAppViewer::cleanup() SUBSYSTEM_CLEANUP(LLVFile); LL_INFOS() << "Saving Data" << LL_ENDL; - + // Store the time of our current logoff gSavedPerAccountSettings.setU32("LastLogoff", time_corrected()); // Must do this after all panels have been deleted because panels that have persistent rects // save their rects on delete. gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE); - + LLUIColorTable::instance().saveUserSettings(); // PerAccountSettingsFile should be empty if no user has been logged on. - // *FIX:Mani This should get really saved in a "logoff" mode. + // *FIX:Mani This should get really saved in a "logoff" mode. if (gSavedSettings.getString("PerAccountSettingsFile").empty()) { LL_INFOS() << "Not saving per-account settings; don't know the account name yet." << LL_ENDL; @@ -1928,13 +1930,13 @@ bool LLAppViewer::cleanup() LL_INFOS() << "Purging all cache files on exit" << LL_ENDL; gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*"); } - + writeDebugInfo(); LLLocationHistory::getInstance()->save(); LLAvatarIconIDCache::getInstance()->save(); - + // Stop the plugin read thread if it's running. LLPluginProcessParent::setUseReadThread(false); @@ -1968,9 +1970,9 @@ bool LLAppViewer::cleanup() // shotdown all worker threads before deleting them in case of co-dependencies mAppCoreHttp.requestStop(); sTextureFetch->shutdown(); - sTextureCache->shutdown(); + sTextureCache->shutdown(); sImageDecodeThread->shutdown(); - + sTextureFetch->shutDownTextureCacheThread() ; sTextureFetch->shutDownImageDecodeThread() ; @@ -1995,16 +1997,16 @@ bool LLAppViewer::cleanup() if (LLFastTimerView::sAnalyzePerformance) { LL_INFOS() << "Analyzing performance" << LL_ENDL; - + std::string baseline_name = LLTrace::BlockTimer::sLogName + "_baseline.slp"; - std::string current_name = LLTrace::BlockTimer::sLogName + ".slp"; + std::string current_name = LLTrace::BlockTimer::sLogName + ".slp"; std::string report_name = LLTrace::BlockTimer::sLogName + "_report.csv"; LLFastTimerView::doAnalysis( gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baseline_name), gDirUtilp->getExpandedFilename(LL_PATH_LOGS, current_name), gDirUtilp->getExpandedFilename(LL_PATH_LOGS, report_name)); - } + } SUBSYSTEM_CLEANUP(LLMetricPerformanceTesterBasic) ; @@ -2017,7 +2019,7 @@ bool LLAppViewer::cleanup() SUBSYSTEM_CLEANUP(LLViewerParcelMedia); gTextureList.shutdown(); // shutdown again in case a callback added something LLUIImageList::getInstance()->cleanUp(); - + // This should eventually be done in LLAppViewer SUBSYSTEM_CLEANUP(LLImage); SUBSYSTEM_CLEANUP(LLVFSThread); @@ -2032,21 +2034,21 @@ bool LLAppViewer::cleanup() #endif LL_INFOS() << "Misc Cleanup" << LL_ENDL; - + // For safety, the LLVFS has to be deleted *after* LLVFSThread. This should be cleaned up. // (LLVFS doesn't know about LLVFSThread so can't kill pending requests) -Steve delete gStaticVFS; gStaticVFS = NULL; delete gVFS; gVFS = NULL; - + gSavedSettings.cleanup(); LLUIColorTable::instance().clear(); LLWatchdog::getInstance()->cleanup(); LLViewerAssetStatsFF::cleanup(); - + // If we're exiting to launch an URL, do that here so the screen // is at the right resolution before we launch IE. if (!gLaunchFileOnQuit.empty()) @@ -2083,7 +2085,7 @@ bool LLAppViewer::cleanup() // all cleanup will get subsumed into the generic calls. So the calls you // still see above are calls that MUST happen before the generic cleanup // kicks in. - + // This calls every remaining LLSingleton's cleanupSingleton() method. // This method should perform any cleanup that might take significant // realtime, or might throw an exception. @@ -2138,7 +2140,7 @@ bool LLAppViewer::initThreads() LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), sImageDecodeThread, enable_threads && true, - app_metrics_qa_mode); + app_metrics_qa_mode); if (LLTrace::BlockTimer::sLog || LLTrace::BlockTimer::sMetricLog) { @@ -2164,7 +2166,7 @@ void errorCallback(const std::string &error_string) //Set the ErrorActivated global so we know to create a marker file gLLErrorActivated = true; - + LLError::crashAndLoop(error_string); } @@ -2220,7 +2222,7 @@ void LLAppViewer::initLoggingAndGetLastDuration() gLastExecDuration = -1; // unknown } std::string duration_log_msg(duration_log_stream.str()); - + // Create a new start marker file for comparison with log file time for the next run LLAPRFile start_marker_file ; start_marker_file.open(start_marker_file_name, LL_APR_WB); @@ -2243,7 +2245,7 @@ void LLAppViewer::initLoggingAndGetLastDuration() bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, bool set_defaults) -{ +{ if (!mSettingsLocationList) { LL_ERRS() << "Invalid settings location list" << LL_ENDL; @@ -2275,7 +2277,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, std::string full_settings_path; - if (file.file_name_setting.isProvided() + if (file.file_name_setting.isProvided() && gSavedSettings.controlExists(file.file_name_setting)) { // try to find filename stored in file_name_setting control @@ -2362,7 +2364,7 @@ namespace } // anonymous namespace bool LLAppViewer::initConfiguration() -{ +{ //Load settings files list std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml"); LLXMLNodePtr root; @@ -2381,17 +2383,17 @@ bool LLAppViewer::initConfiguration() { LL_ERRS() << "Invalid settings file list " << settings_file_list << LL_ENDL; } - + // The settings and command line parsing have a fragile // order-of-operation: // - load defaults from app_settings // - set procedural settings values // - read command line settings // - selectively apply settings needed to load user settings. - // - load overrides from user_settings + // - load overrides from user_settings // - apply command line settings (to override the overrides) // - load per account settings (happens in llstartup - + // - load defaults bool set_defaults = true; if(!loadSettingsFromDirectory("Default", set_defaults)) @@ -2405,7 +2407,7 @@ bool LLAppViewer::initConfiguration() initStrings(); // setup paths for LLTrans based on settings files only // - set procedural settings // Note: can't use LL_PATH_PER_SL_ACCOUNT for any of these since we haven't logged in yet - gSavedSettings.setString("ClientSettingsFile", + gSavedSettings.setString("ClientSettingsFile", gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Global"))); #ifndef LL_RELEASE_FOR_DOWNLOAD @@ -2425,7 +2427,7 @@ bool LLAppViewer::initConfiguration() gSavedSettings.setBOOL("QAMode", TRUE ); gSavedSettings.setS32("WatchdogEnabled", 0); #endif - + // These are warnings that appear on the first experience of that condition. // They are already set in the settings_default.xml file, but still need to be added to LLFirstUse // for disable/reset ability @@ -2447,7 +2449,7 @@ bool LLAppViewer::initConfiguration() // LLFirstUse::addConfigVariable("FirstSculptedPrim"); // LLFirstUse::addConfigVariable("FirstVoice"); // LLFirstUse::addConfigVariable("FirstMedia"); - + // - read command line settings. LLControlGroupCLP clp; std::string cmd_line_config = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, @@ -2460,27 +2462,27 @@ bool LLAppViewer::initConfiguration() handleCommandLineError(clp); return false; } - - // - selectively apply settings + + // - selectively apply settings // If the user has specified a alternate settings file name. // Load it now before loading the user_settings/settings.xml if(clp.hasOption("settings")) { - std::string user_settings_filename = - gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, - clp.getOption("settings")[0]); + std::string user_settings_filename = + gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, + clp.getOption("settings")[0]); gSavedSettings.setString("ClientSettingsFile", user_settings_filename); - LL_INFOS("Settings") << "Using command line specified settings filename: " + LL_INFOS("Settings") << "Using command line specified settings filename: " << user_settings_filename << LL_ENDL; } - // - load overrides from user_settings + // - load overrides from user_settings loadSettingsFromDirectory("User"); if (gSavedSettings.getBOOL("FirstRunThisInstall")) { - // Set firstrun flag to indicate that some further init actiona should be taken + // Set firstrun flag to indicate that some further init actiona should be taken // like determining screen DPI value and so on mIsFirstRun = true; @@ -2489,24 +2491,24 @@ bool LLAppViewer::initConfiguration() if (clp.hasOption("sessionsettings")) { - std::string session_settings_filename = clp.getOption("sessionsettings")[0]; + std::string session_settings_filename = clp.getOption("sessionsettings")[0]; gSavedSettings.setString("SessionSettingsFile", session_settings_filename); - LL_INFOS("Settings") << "Using session settings filename: " + LL_INFOS("Settings") << "Using session settings filename: " << session_settings_filename << LL_ENDL; } loadSettingsFromDirectory("Session"); if (clp.hasOption("usersessionsettings")) { - std::string user_session_settings_filename = clp.getOption("usersessionsettings")[0]; + std::string user_session_settings_filename = clp.getOption("usersessionsettings")[0]; gSavedSettings.setString("UserSessionSettingsFile", user_session_settings_filename); - LL_INFOS("Settings") << "Using user session settings filename: " + LL_INFOS("Settings") << "Using user session settings filename: " << user_session_settings_filename << LL_ENDL; } loadSettingsFromDirectory("UserSession"); - // - apply command line settings + // - apply command line settings if (! clp.notify()) { handleCommandLineError(clp); @@ -2605,9 +2607,9 @@ bool LLAppViewer::initConfiguration() if (gSavedSettings.getBOOL("LogPerformance")) { LLTrace::BlockTimer::sLog = true; - LLTrace::BlockTimer::sLogName = std::string("performance"); + LLTrace::BlockTimer::sLogName = std::string("performance"); } - + std::string test_name(gSavedSettings.getString("LogMetrics")); if (! test_name.empty()) { @@ -2648,20 +2650,20 @@ bool LLAppViewer::initConfiguration() // Handle slurl use. NOTE: Don't let SL-55321 reappear. - // *FIX: This init code should be made more robust to prevent - // the issue SL-55321 from returning. One thought is to allow - // only select options to be set from command line when a slurl - // is specified. More work on the settings system is needed to + // *FIX: This init code should be made more robust to prevent + // the issue SL-55321 from returning. One thought is to allow + // only select options to be set from command line when a slurl + // is specified. More work on the settings system is needed to // achieve this. For now... - // *NOTE:Mani The command line parser parses tokens and is - // setup to bail after parsing the '--url' option or the + // *NOTE:Mani The command line parser parses tokens and is + // setup to bail after parsing the '--url' option or the // first option specified without a '--option' flag (or - // any other option that uses the 'last_option' setting - + // any other option that uses the 'last_option' setting - // see LLControlGroupCLP::configure()) - // What can happen is that someone can use IE (or potentially - // other browsers) and do the rough equivalent of command + // What can happen is that someone can use IE (or potentially + // other browsers) and do the rough equivalent of command // injection and steal passwords. Phoenix. SL-55321 std::string starting_location; @@ -2685,8 +2687,8 @@ bool LLAppViewer::initConfiguration() { start_slurl = starting_location; LLStartUp::setStartSLURL(start_slurl); - if(start_slurl.getType() == LLSLURL::LOCATION) - { + if(start_slurl.getType() == LLSLURL::LOCATION) + { LLGridManager::getInstance()->setGridChoice(start_slurl.getGrid()); } } @@ -2700,7 +2702,7 @@ bool LLAppViewer::initConfiguration() (gSavedSettings.getBOOL("SLURLPassToOtherInstance"))) { if (sendURLToOtherInstance(start_slurl.getSLURLString())) - { + { // successfully handed off URL to existing instance, exit return false; } @@ -2708,7 +2710,7 @@ bool LLAppViewer::initConfiguration() const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent"); if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString()) - { + { // Examining "Language" may not suffice -- see LLUI::getLanguage() // logic. Unfortunately LLUI::getLanguage() doesn't yet do us much // good because we haven't yet called LLUI::initClass(). @@ -2947,8 +2949,8 @@ bool LLAppViewer::initWindow() LL_INFOS("AppInit") << "watchdog setting is done." << LL_ENDL; LLNotificationsUI::LLNotificationManager::getInstance(); - - + + #ifdef LL_DARWIN //Satisfy both MAINT-3135 (OSX 10.6 and earlier) MAINT-3288 (OSX 10.7 and later) LLOSInfo& os_info = LLOSInfo::instance(); @@ -2958,7 +2960,7 @@ bool LLAppViewer::initWindow() gViewerWindow->getWindow()->setOldResize(true); } #endif - + if (gSavedSettings.getBOOL("WindowMaximized")) { gViewerWindow->getWindow()->maximize(); @@ -2973,7 +2975,7 @@ bool LLAppViewer::initWindow() LLFeatureManager::getInstance()->setGraphicsLevel(*mForceGraphicsLevel, false); gSavedSettings.setU32("RenderQualityPerformance", *mForceGraphicsLevel); } - + // Set this flag in case we crash while initializing GL gSavedSettings.setBOOL("RenderInitError", TRUE); gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); @@ -3031,14 +3033,14 @@ void LLAppViewer::writeDebugInfo(bool isStatic) debug_filename = ( isStatic ? getStaticDebugFile() : getDynamicDebugFile() ); - + LL_INFOS() << "Opening debug file " << *debug_filename << LL_ENDL; llofstream out_file(debug_filename->c_str()); - + isStatic ? LLSDSerialize::toPrettyXML(gDebugInfo, out_file) : LLSDSerialize::toPrettyXML(gDebugInfo["Dynamic"], out_file); - - + + out_file.close(); } @@ -3152,7 +3154,7 @@ LLSD LLAppViewer::getViewerInfo() const version_string << version.serverType << " " << version.serverVersion << std::endl; info["VOICE_VERSION"] = version_string.str(); } - else + else { info["VOICE_VERSION"] = LLTrans::getString("NotConnected"); } @@ -3307,9 +3309,9 @@ void LLAppViewer::cleanupSavedSettings() gSavedSettings.setBOOL("UseEnergy", TRUE); // force toggle to turn off, since sends message to simulator gSavedSettings.setBOOL("DebugWindowProc", gDebugWindowProc); - + gSavedSettings.setBOOL("ShowObjectUpdates", gShowObjectUpdates); - + if (gDebugView) { gSavedSettings.setBOOL("ShowDebugConsole", gDebugView->mDebugConsolep->getVisible()); @@ -3323,7 +3325,7 @@ void LLAppViewer::cleanupSavedSettings() if (!maximized) { LLCoordScreen window_pos; - + if (gViewerWindow->getWindow()->getPosition(&window_pos)) { gSavedSettings.setS32("WindowX", window_pos.mX); @@ -3348,10 +3350,10 @@ void LLAppViewer::removeCacheFiles(const std::string& file_mask) void LLAppViewer::writeSystemInfo() { - + if (! gDebugInfo.has("Dynamic") ) gDebugInfo["Dynamic"] = LLSD::emptyMap(); - + #if LL_WINDOWS gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log"); #else @@ -3374,13 +3376,13 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["CPUInfo"]["CPUAltivec"] = gSysCPU.hasAltivec(); gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE(); gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2(); - + gDebugInfo["RAMInfo"]["Physical"] = (LLSD::Integer)(gSysMemory.getPhysicalMemoryKB().value()); gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer)(gMemoryAllocated.valueInUnits<LLUnits::Kilobytes>()); gDebugInfo["OSInfo"] = LLOSInfo::instance().getOSStringSimple(); // The user is not logged on yet, but record the current grid choice login url - // which may have been the intended grid. + // which may have been the intended grid. gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridId(); // *FIX:Mani - move this down in llappviewerwin32 @@ -3397,14 +3399,14 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)true; // Insert crash host url (url to post crash log to) if configured. This insures - // that the crash report will go to the proper location in the case of a + // that the crash report will go to the proper location in the case of a // prior freeze. std::string crashHostUrl = gSavedSettings.get<std::string>("CrashHostUrl"); if(crashHostUrl != "") { gDebugInfo["CrashHostUrl"] = crashHostUrl; } - + // Dump some debugging info LL_INFOS("SystemInfo") << "Application: " << LLTrans::getString("APP_NAME") << LL_ENDL; LL_INFOS("SystemInfo") << "Version: " << LLVersionInfo::getChannelAndVersion() << LL_ENDL; @@ -3428,16 +3430,16 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin(); gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall"); gDebugInfo["StartupState"] = LLStartUp::getStartupStateString(); - + writeDebugInfo(); // Save out debug_info.log early, in case of crash. } #ifdef LL_WINDOWS -//For whatever reason, in Windows when using OOP server for breakpad, the callback to get the -//name of the dump file is not getting triggered by the breakpad library. Unfortunately they +//For whatever reason, in Windows when using OOP server for breakpad, the callback to get the +//name of the dump file is not getting triggered by the breakpad library. Unfortunately they //also didn't see fit to provide a simple query request across the pipe to get this name either. //Since we are putting our output in a runtime generated directory and we know the header data in -//the dump format, we can however use the following hack to identify our file. +//the dump format, we can however use the following hack to identify our file. // TODO make this a member function. void getFileList() { @@ -3501,19 +3503,19 @@ void LLAppViewer::handleViewerCrash() return; } pApp->mReportedCrash = TRUE; - + // Insert crash host url (url to post crash log to) if configured. std::string crashHostUrl = gSavedSettings.get<std::string>("CrashHostUrl"); if(crashHostUrl != "") { gDebugInfo["Dynamic"]["CrashHostUrl"] = crashHostUrl; } - + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if ( parcel && parcel->getMusicURL()[0]) { gDebugInfo["Dynamic"]["ParcelMusicURL"] = parcel->getMusicURL(); - } + } if ( parcel && parcel->getMediaURL()[0]) { gDebugInfo["Dynamic"]["ParcelMediaURL"] = parcel->getMediaURL(); @@ -3535,7 +3537,7 @@ void LLAppViewer::handleViewerCrash() { gDebugInfo["Dynamic"]["CurrentSimHost"] = gAgent.getRegionHost().getHostName(); gDebugInfo["Dynamic"]["CurrentRegion"] = gAgent.getRegion()->getName(); - + const LLVector3& loc = gAgent.getPositionAgent(); gDebugInfo["Dynamic"]["CurrentLocationX"] = loc.mV[0]; gDebugInfo["Dynamic"]["CurrentLocationY"] = loc.mV[1]; @@ -3546,14 +3548,14 @@ void LLAppViewer::handleViewerCrash() { gDebugInfo["Dynamic"]["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); } - + // The crash is being handled here so set this value to false. // Otherwise the crash logger will think this crash was a freeze. gDebugInfo["Dynamic"]["CrashNotHandled"] = (LLSD::Boolean)false; - + //Write out the crash status file //Use marker file style setup, as that's the simplest, especially since - //we're already in a crash situation + //we're already in a crash situation if (gDirUtilp) { std::string crash_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, @@ -3575,11 +3577,11 @@ void LLAppViewer::handleViewerCrash() else { LL_WARNS("MarkerFile") << "No gDirUtilp with which to create error marker file name" << LL_ENDL; - } - + } + #ifdef LL_WINDOWS Sleep(200); -#endif +#endif char *minidump_file = pApp->getMiniDumpFilename(); LL_DEBUGS("CRASHREPORT") << "minidump file name " << minidump_file << LL_ENDL; @@ -3593,10 +3595,10 @@ void LLAppViewer::handleViewerCrash() getFileList(); #else LL_WARNS("CRASHREPORT") << "no minidump file?" << LL_ENDL; -#endif +#endif } gDebugInfo["Dynamic"]["CrashType"]="crash"; - + if (gMessageSystem && gDirUtilp) { std::string filename; @@ -3611,7 +3613,7 @@ void LLAppViewer::handleViewerCrash() else { LL_WARNS("CRASHREPORT") << "problem recording stats" << LL_ENDL; - } + } } if (gMessageSystem) @@ -3627,8 +3629,8 @@ void LLAppViewer::handleViewerCrash() } // static -void LLAppViewer::recordMarkerVersion(LLAPRFile& marker_file) -{ +void LLAppViewer::recordMarkerVersion(LLAPRFile& marker_file) +{ std::string marker_version(LLVersionInfo::getChannelAndVersion()); if ( marker_version.length() > MAX_MARKER_LENGTH ) { @@ -3691,7 +3693,7 @@ void LLAppViewer::processMarkerFiles() // now test to see if this file is locked by a running process (try to open for write) LL_DEBUGS("MarkerFile") << "Checking exec marker file for lock..." << LL_ENDL; mMarkerFile.open(mMarkerFileName, LL_APR_WB); - apr_file_t* fMarker = mMarkerFile.getFileHandle() ; + apr_file_t* fMarker = mMarkerFile.getFileHandle() ; if (!fMarker) { LL_INFOS("MarkerFile") << "Exec marker file open failed - assume it is locked." << LL_ENDL; @@ -3707,7 +3709,7 @@ void LLAppViewer::processMarkerFiles() } else { - // No other instances; we've locked this file now, so record our version; delete on quit. + // No other instances; we've locked this file now, so record our version; delete on quit. recordMarkerVersion(mMarkerFile); LL_DEBUGS("MarkerFile") << "Exec marker file existed but was not locked; rewritten." << LL_ENDL; } @@ -3722,7 +3724,7 @@ void LLAppViewer::processMarkerFiles() // the file existed, is ours, and matched our version, so we can report on what it says LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec FROZE" << LL_ENDL; gLastExecEvent = LAST_EXEC_FROZE; - + } else { @@ -3733,12 +3735,12 @@ void LLAppViewer::processMarkerFiles() { // Create the marker file for this execution & lock it; it will be deleted on a clean exit apr_status_t s; - s = mMarkerFile.open(mMarkerFileName, LL_APR_WB, TRUE); + s = mMarkerFile.open(mMarkerFileName, LL_APR_WB, TRUE); if (s == APR_SUCCESS && mMarkerFile.getFileHandle()) { LL_DEBUGS("MarkerFile") << "Exec marker file '"<< mMarkerFileName << "' created." << LL_ENDL; - if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE)) + if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE)) { recordMarkerVersion(mMarkerFile); LL_DEBUGS("MarkerFile") << "Exec marker file locked." << LL_ENDL; @@ -3823,7 +3825,7 @@ void LLAppViewer::processMarkerFiles() void LLAppViewer::removeMarkerFiles() { if (!mSecondInstance) - { + { if (mMarkerFile.getFileHandle()) { mMarkerFile.close() ; @@ -3861,8 +3863,8 @@ void LLAppViewer::removeDumpDir() } void LLAppViewer::forceQuit() -{ - LLApp::setQuitting(); +{ + LLApp::setQuitting(); } //TODO: remove @@ -3876,10 +3878,10 @@ void LLAppViewer::fastQuit(S32 error_code) end_messaging_system(); // figure out the error code S32 final_error_code = error_code ? error_code : (S32)isError(); - // this isn't a crash + // this isn't a crash removeMarkerFiles(); // get outta here - _exit(final_error_code); + _exit(final_error_code); } void LLAppViewer::requestQuit() @@ -3887,7 +3889,7 @@ void LLAppViewer::requestQuit() LL_INFOS() << "requestQuit" << LL_ENDL; LLViewerRegion* region = gAgent.getRegion(); - + if( (LLStartUp::getStartupState() < STATE_STARTED) || !region ) { // If we have a region, make some attempt to send a logout request first. @@ -3896,7 +3898,7 @@ void LLAppViewer::requestQuit() { sendLogoutRequest(); } - + // Quit immediately forceQuit(); return; @@ -3910,13 +3912,13 @@ void LLAppViewer::requestQuit() { gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent. } - + // Try to send last batch of avatar rez metrics. if (!gDisconnected && isAgentAvatarValid()) { gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent. } - + LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); effectp->setPositionGlobal(gAgent.getPositionGlobal()); effectp->setColor(LLColor4U(gAgent.getEffectColor())); @@ -4075,7 +4077,7 @@ void dumpVFSCaches() gStaticVFS->dumpFiles(); SetCurrentDirectory(w_str); #endif - + LL_INFOS() << "========= Dynamic VFS ====" << LL_ENDL; gVFS->listFiles(); #if LL_WINDOWS @@ -4092,7 +4094,7 @@ void dumpVFSCaches() } //static -U32 LLAppViewer::getTextureCacheVersion() +U32 LLAppViewer::getTextureCacheVersion() { //viewer texture cache version, change if the texture cache format changes. const U32 TEXTURE_CACHE_VERSION = 8; @@ -4101,7 +4103,7 @@ U32 LLAppViewer::getTextureCacheVersion() } //static -U32 LLAppViewer::getObjectCacheVersion() +U32 LLAppViewer::getObjectCacheVersion() { // Viewer object cache version, change if object update // format changes. JC @@ -4118,10 +4120,10 @@ bool LLAppViewer::initCache() LLVOCache::getInstance()->setReadOnly(read_only); bool texture_cache_mismatch = false; - if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion()) + if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion()) { texture_cache_mismatch = true; - if(!read_only) + if(!read_only) { gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion()); } @@ -4139,10 +4141,10 @@ bool LLAppViewer::initCache() // STORM-1141 force purgeAllTextures to get called to prevent a crash here. -brad texture_cache_mismatch = true; } - + // We have moved the location of the cache directory over time. migrateCacheDirectory(); - + // Setup and verify the cache location std::string cache_location = gSavedSettings.getString("CacheLocation"); std::string new_cache_location = gSavedSettings.getString("NewCacheLocation"); @@ -4162,7 +4164,7 @@ bool LLAppViewer::initCache() gSavedSettings.setString("CacheLocation", ""); gSavedSettings.setString("CacheLocationTopFolder", ""); } - + if (mPurgeCache && !read_only) { LLSplashScreen::update(LLTrans::getString("StartupClearingCache")); @@ -4170,9 +4172,9 @@ bool LLAppViewer::initCache() } LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache")); - + // Init the texture cache - // Allocate 80% of the cache size for textures + // Allocate 80% of the cache size for textures const S32 MB = 1024 * 1024; const S64 MIN_CACHE_SIZE = 256 * MB; const S64 MAX_CACHE_SIZE = 9984ll * MB; @@ -4190,7 +4192,7 @@ bool LLAppViewer::initCache() LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion()) ; LLSplashScreen::update(LLTrans::getString("StartupInitializingVFS")); - + // Init the VFS vfs_size = llmin(vfs_size + extra, MAX_VFS_SIZE); vfs_size = (vfs_size / MB) * MB; // make sure it is MB aligned @@ -4202,7 +4204,7 @@ bool LLAppViewer::initCache() gSavedSettings.setU32("VFSOldSize", vfs_size_u32 / MB); } LL_INFOS("AppCache") << "VFS CACHE SIZE: " << vfs_size / (1024*1024) << " MB" << LL_ENDL; - + // This has to happen BEFORE starting the vfs // time_t ltime; srand(time(NULL)); // Flawfinder: ignore @@ -4268,7 +4270,7 @@ bool LLAppViewer::initCache() LL_WARNS("AppCache") << "Removing old vfs data file " << old_vfs_data_file << LL_ENDL; LLFile::remove(old_vfs_data_file); LLFile::remove(old_vfs_index_file); - + // Just in case, nuke any other old cache files in the directory. std::string dir; dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""); @@ -4294,7 +4296,7 @@ bool LLAppViewer::initCache() if (resize_vfs) { LL_DEBUGS("AppCache") << "Removing old vfs and re-sizing" << LL_ENDL; - + LLFile::remove(old_vfs_data_file); LLFile::remove(old_vfs_index_file); } @@ -4338,7 +4340,7 @@ bool LLAppViewer::initCache() dumpVFSCaches(); } #endif - + return true; } } @@ -4375,12 +4377,12 @@ std::string LLAppViewer::getSecondLifeTitle() const return LLTrans::getString("APP_NAME"); } -std::string LLAppViewer::getWindowTitle() const +std::string LLAppViewer::getWindowTitle() const { return gWindowTitle; } -// Callback from a dialog indicating user was logged out. +// Callback from a dialog indicating user was logged out. bool finish_disconnect(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); @@ -4408,7 +4410,7 @@ void LLAppViewer::forceDisconnect(const std::string& mesg) // do this again. return; } - + // *TODO: Translate the message if possible std::string big_reason = LLAgent::sTeleportErrorMessages[mesg]; if ( big_reason.size() == 0 ) @@ -4454,7 +4456,7 @@ void LLAppViewer::badNetworkHandler() "If the problem continues, see the Tech Support FAQ at: \n" "www.secondlife.com/support"; forceDisconnect(message.str()); - + LLApp::instance()->writeMiniDump(); } @@ -4519,7 +4521,7 @@ void LLAppViewer::saveNameCache() { LLAvatarNameCache::exportFile(name_cache_stream); } - + // real names cache if (gCacheName) { @@ -4537,7 +4539,7 @@ void LLAppViewer::saveNameCache() /*! @brief This class is an LLFrameTimer that can be created with an elapsed time that starts counting up from the given value rather than 0.0. - + Otherwise it behaves the same way as LLFrameTimer. */ class LLFrameStatsTimer : public LLFrameTimer @@ -4574,7 +4576,7 @@ static LLTrace::BlockTimerStatHandle FTM_HUD_EFFECTS("HUD Effects"); void LLAppViewer::idle() { pingMainloopTimeout("Main:Idle"); - + // Update frame timers static LLTimer idle_timer; @@ -4632,7 +4634,7 @@ void LLAppViewer::idle() gGLActive = FALSE; } - + F32 yaw = 0.f; // radians if (!gDisconnected) @@ -4640,8 +4642,8 @@ void LLAppViewer::idle() LL_RECORD_BLOCK_TIME(FTM_NETWORK); // Update spaceserver timeinfo LLWorld::getInstance()->setSpaceTimeUSec(LLWorld::getInstance()->getSpaceTimeUSec() + LLUnits::Seconds::fromValue(dt_raw)); - - + + ////////////////////////////////////// // // Update simulator agent state @@ -4720,7 +4722,7 @@ void LLAppViewer::idle() if (!gDisconnected) { LL_RECORD_BLOCK_TIME(FTM_NETWORK); - + //////////////////////////////////////////////// // // Network processing @@ -4730,7 +4732,7 @@ void LLAppViewer::idle() // idleNameCache(); idleNetwork(); - + // Check for away from keyboard, kick idle agents. idle_afk_check(); @@ -4744,7 +4746,7 @@ void LLAppViewer::idle() // Handle the regular UI idle callbacks as well as // hover callbacks // - + #ifdef LL_DARWIN if (!mQuitRequested) //MAINT-4243 #endif @@ -4753,12 +4755,12 @@ void LLAppViewer::idle() // Do event notifications if necessary. Yes, we may want to move this elsewhere. gEventNotifier.update(); - + gIdleCallbacks.callFunctions(); gInventory.idleNotifyObservers(); LLAvatarTracker::instance().idleNotifyObservers(); } - + // Metrics logging (LLViewerAssetStats, etc.) { static LLTimer report_interval; @@ -4804,14 +4806,14 @@ void LLAppViewer::idle() } { - LL_RECORD_BLOCK_TIME(FTM_OBJECTLIST_UPDATE); - + LL_RECORD_BLOCK_TIME(FTM_OBJECTLIST_UPDATE); + if (!(logoutRequestSent() && hasSavedFinalSnapshot())) { gObjectList.update(gAgent); } } - + ////////////////////////////////////// // // Deletes objects... @@ -4829,7 +4831,7 @@ void LLAppViewer::idle() LLDrawable::cleanupDeadDrawables(); } } - + // // After this point, in theory we should never see a dead object // in the various object/drawable lists. @@ -4859,7 +4861,7 @@ void LLAppViewer::idle() LL_RECORD_BLOCK_TIME(FTM_NETWORK); gVLManager.unpackData(); } - + ///////////////////////// // // Update surfaces, and surface textures as well. @@ -4871,24 +4873,24 @@ void LLAppViewer::idle() LL_RECORD_BLOCK_TIME(FTM_REGION_UPDATE); LLWorld::getInstance()->updateRegions(max_region_update_time); } - + ///////////////////////// // // Update weather effects // - // Update wind vector + // Update wind vector LLVector3 wind_position_region; static LLVector3 average_wind; LLViewerRegion *regionp; - regionp = LLWorld::getInstance()->resolveRegionGlobal(wind_position_region, gAgent.getPositionGlobal()); // puts agent's local coords into wind_position + regionp = LLWorld::getInstance()->resolveRegionGlobal(wind_position_region, gAgent.getPositionGlobal()); // puts agent's local coords into wind_position if (regionp) { gWindVec = regionp->mWind.getVelocity(wind_position_region); // Compute average wind and use to drive motion of water - + average_wind = regionp->mWind.getAverage(); gSky.setWind(average_wind); //LLVOWater::setWind(average_wind); @@ -4897,13 +4899,13 @@ void LLAppViewer::idle() { gWindVec.setVec(0.0f, 0.0f, 0.0f); } - + ////////////////////////////////////// // // Sort and cull in the new renderer are moved to pipeline.cpp // Here, particles are updated and drawables are moved. // - + LL_RECORD_BLOCK_TIME(FTM_WORLD_UPDATE); gPipeline.updateMove(); @@ -4914,7 +4916,7 @@ void LLAppViewer::idle() gAgentPilot.moveCamera(); } else if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { + { LLViewerJoystick::getInstance()->moveFlycam(); } else @@ -4929,7 +4931,7 @@ void LLAppViewer::idle() // update media focus LLViewerMediaFocus::getInstance()->update(); - + // Update marketplace LLMarketplaceInventoryImporter::update(); LLMarketplaceInventoryNotifications::update(); @@ -4945,7 +4947,7 @@ void LLAppViewer::idle() { LL_RECORD_BLOCK_TIME(FTM_AUDIO_UPDATE); - + if (gAudiop) { audio_update_volume(false); @@ -4960,8 +4962,8 @@ void LLAppViewer::idle() // Execute deferred tasks. LLDeferredTaskList::instance().run(); - - // Handle shutdown process, for example, + + // Handle shutdown process, for example, // wait for floaters to close, send quit message, // forcibly quit if it has taken too long if (mQuitRequested) @@ -4984,7 +4986,7 @@ void LLAppViewer::idleShutdown() { gIMMgr->disconnectAllSessions(); } - + // Wait for all floaters to get resolved if (gFloaterView && !gFloaterView->allChildrenClosed()) @@ -4994,7 +4996,7 @@ void LLAppViewer::idleShutdown() - + // ProductEngine: Try moving this code to where we shut down sTextureCache in cleanup() // *TODO: ugly static bool saved_teleport_history = false; @@ -5052,7 +5054,7 @@ void LLAppViewer::idleShutdown() } // Make sure that we quit if we haven't received a reply from the server. - if( logoutRequestSent() + if( logoutRequestSent() && gLogoutTimer.getElapsedTimeF32() > gLogoutMaxTime ) { forceQuit(); @@ -5069,7 +5071,7 @@ void LLAppViewer::sendLogoutRequest() if (!mSecondInstance) { mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME); - + mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB); if (mLogoutMarkerFile.getFileHandle()) { @@ -5079,13 +5081,13 @@ void LLAppViewer::sendLogoutRequest() else { LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL; - } + } } else { LL_INFOS("MarkerFile") << "Did not logout marker file because this is a second instance" << LL_ENDL; } - + LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_LogoutRequest); msg->nextBlockFast(_PREHASH_AgentData); @@ -5096,7 +5098,7 @@ void LLAppViewer::sendLogoutRequest() gLogoutTimer.reset(); gLogoutMaxTime = LOGOUT_REQUEST_TIME; mLogoutRequestSent = TRUE; - + if(LLVoiceClient::instanceExists()) { LLVoiceClient::getInstance()->leaveChannel(); @@ -5179,20 +5181,20 @@ static LLTrace::BlockTimerStatHandle FTM_CHECK_REGION_CIRCUIT("Check Region Circ void LLAppViewer::idleNetwork() { pingMainloopTimeout("idleNetwork"); - + gObjectList.mNumNewObjects = 0; S32 total_decoded = 0; if (!gSavedSettings.getBOOL("SpeedTest")) { LL_RECORD_BLOCK_TIME(FTM_IDLE_NETWORK); // decode - + LLTimer check_message_timer; - // Read all available packets from network + // Read all available packets from network const S64 frame_count = gFrameCount; // U32->S64 F32 total_time = 0.0f; - while (gMessageSystem->checkAllMessages(frame_count, gServicePump)) + while (gMessageSystem->checkAllMessages(frame_count, gServicePump)) { if (gDoDisconnect) { @@ -5201,7 +5203,7 @@ void LLAppViewer::idleNetwork() // server going down, so this is OK. break; } - + total_decoded++; gPacketsIn++; @@ -5236,12 +5238,12 @@ void LLAppViewer::idleNetwork() CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; } #endif - + // we want to clear the control after sending out all necessary agent updates gAgent.resetControlFlags(); - + // Decode enqueued messages... S32 remaining_possible_decodes = MESSAGE_MAX_PER_FRAME - total_decoded; @@ -5288,7 +5290,7 @@ void LLAppViewer::disconnectViewer() } // // Cleanup after quitting. - // + // // Save snapshot for next time, if we made it through initialization LL_INFOS() << "Disconnecting viewer!" << LL_ENDL; @@ -5387,7 +5389,7 @@ void LLAppViewer::forceErrorBadMemoryAccess() { LL_WARNS() << "Forcing a deliberate bad memory access" << LL_ENDL; S32* crash = NULL; - *crash = 0xDEADBEEF; + *crash = 0xDEADBEEF; return; } @@ -5400,7 +5402,7 @@ void LLAppViewer::forceErrorInfiniteLoop() } return; } - + void LLAppViewer::forceErrorSoftwareException() { LL_WARNS() << "Forcing a deliberate exception" << LL_ENDL; @@ -5439,7 +5441,7 @@ void LLAppViewer::resumeMainloopTimeout(const std::string& state, F32 secs) { secs = gSavedSettings.getF32("MainloopTimeoutDefault"); } - + mMainloopTimeout->setTimeout(secs); mMainloopTimeout->start(state); } @@ -5459,7 +5461,7 @@ void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs) // { // LL_WARNS() << "!!!!!!!!!!!!! Its an error trap!!!!" << state << LL_ENDL; // } - + if(mMainloopTimeout) { if(secs < 0.0f) @@ -5489,12 +5491,12 @@ void LLAppViewer::handleLoginComplete() if ( parcel && parcel->getMusicURL()[0]) { gDebugInfo["ParcelMusicURL"] = parcel->getMusicURL(); - } + } if ( parcel && parcel->getMediaURL()[0]) { gDebugInfo["ParcelMediaURL"] = parcel->getMediaURL(); } - + gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile"); gDebugInfo["CAFilename"] = gDirUtilp->getCAFile(); gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index 7413dbed20..7c7f55f68c 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -286,6 +286,9 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio && regionp->getRenderInfoReportTimer().hasExpired() // Time to make request) ) { + // make sure we won't re-report, coro will update timer with correct time later + regionp->getRenderInfoReportTimer().resetWithExpiry(SECS_BETWEEN_REGION_REPORTS); + std::string coroname = LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro", boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle())); @@ -306,6 +309,9 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi << " from " << url << LL_ENDL; + // make sure we won't re-request, coro will update timer with correct time later + regionp->getRenderInfoRequestTimer().resetWithExpiry(SECS_BETWEEN_REGION_REQUEST); + // First send a request to get the latest data std::string coroname = LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro", diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index a9e8e77a0b..97a71a8802 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -53,6 +53,7 @@ #include "llstylemap.h" #include "llslurl.h" #include "lllayoutstack.h" +#include "llnotifications.h" #include "llnotificationsutil.h" #include "lltoastnotifypanel.h" #include "lltooltip.h" @@ -1315,44 +1316,52 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL // notify processing if (chat.mNotifId.notNull()) { - bool create_toast = true; - for (LLToastNotifyPanel::instance_iter ti(LLToastNotifyPanel::beginInstances()) - , tend(LLToastNotifyPanel::endInstances()); ti != tend; ++ti) - { - LLToastNotifyPanel& panel = *ti; - LLIMToastNotifyPanel * imtoastp = dynamic_cast<LLIMToastNotifyPanel *>(&panel); - const std::string& notification_name = panel.getNotificationName(); - if (notification_name == "OfferFriendship" && panel.isControlPanelEnabled() && imtoastp) - { - create_toast = false; - break; - } - } - - if (create_toast) - { LLNotificationPtr notification = LLNotificationsUtil::find(chat.mNotifId); if (notification != NULL) { - LLIMToastNotifyPanel* notify_box = new LLIMToastNotifyPanel( - notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history, mEditor); - - //Prepare the rect for the view - LLRect target_rect = mEditor->getDocumentView()->getRect(); - // squeeze down the widget by subtracting padding off left and right - target_rect.mLeft += mLeftWidgetPad + mEditor->getHPad(); - target_rect.mRight -= mRightWidgetPad; - notify_box->reshape(target_rect.getWidth(), notify_box->getRect().getHeight()); - notify_box->setOrigin(target_rect.mLeft, notify_box->getRect().mBottom); + bool create_toast = true; + if (notification->getName() == "OfferFriendship") + { + // We don't want multiple friendship offers to appear, this code checks if there are previous offers + // by iterating though all panels. + // Note: it might be better to simply add a "pending offer" flag somewhere + for (LLToastNotifyPanel::instance_iter ti(LLToastNotifyPanel::beginInstances()) + , tend(LLToastNotifyPanel::endInstances()); ti != tend; ++ti) + { + LLToastNotifyPanel& panel = *ti; + LLIMToastNotifyPanel * imtoastp = dynamic_cast<LLIMToastNotifyPanel *>(&panel); + const std::string& notification_name = panel.getNotificationName(); + if (notification_name == "OfferFriendship" + && panel.isControlPanelEnabled() + && imtoastp) + { + create_toast = false; + break; + } + } + } - LLInlineViewSegment::Params params; - params.view = notify_box; - params.left_pad = mLeftWidgetPad; - params.right_pad = mRightWidgetPad; - mEditor->appendWidget(params, "\n", false); + if (create_toast) + { + LLIMToastNotifyPanel* notify_box = new LLIMToastNotifyPanel( + notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history, mEditor); + + //Prepare the rect for the view + LLRect target_rect = mEditor->getDocumentView()->getRect(); + // squeeze down the widget by subtracting padding off left and right + target_rect.mLeft += mLeftWidgetPad + mEditor->getHPad(); + target_rect.mRight -= mRightWidgetPad; + notify_box->reshape(target_rect.getWidth(), notify_box->getRect().getHeight()); + notify_box->setOrigin(target_rect.mLeft, notify_box->getRect().mBottom); + + LLInlineViewSegment::Params params; + params.view = notify_box; + params.left_pad = mLeftWidgetPad; + params.right_pad = mRightWidgetPad; + mEditor->appendWidget(params, "\n", false); + } } } - } // usual messages showing else diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 32630237ce..b0d48abb14 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -325,6 +325,9 @@ void LLDrawPoolAlpha::render(S32 pass) pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); pushBatches(LLRenderPass::PASS_ALPHA_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + gGL.diffuseColor4f(0, 0, 1, 1); + pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + if(shaders) { gHighlightProgram.unbind(); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 1acb1650cd..14b13c1f5f 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1223,6 +1223,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { LL_RECORD_BLOCK_TIME(FTM_FACE_GET_GEOM); llassert(verify()); + + if (volume.getNumVolumeFaces() <= f) { + LL_WARNS() << "Attempt get volume face out of range! Total Faces: " << volume.getNumVolumeFaces() << " Attempt get access to: " << f << LL_ENDL; + return FALSE; + } + const LLVolumeFace &vf = volume.getVolumeFace(f); S32 num_vertices = (S32)vf.mNumVertices; S32 num_indices = (S32) vf.mNumIndices; diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 125a823e58..0f22b6200f 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -283,7 +283,7 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) return success; } -BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter) +BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking) { if( mLocked ) { @@ -310,9 +310,13 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter) setupFilter(filter); reset(); - - // Modal, so pause agent - send_agent_pause(); + + if (blocking) + { + // Modal, so pause agent + send_agent_pause(); + } + // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! success = GetOpenFileName(&mOFN); // pauses until ok or cancel. if( success ) @@ -345,14 +349,18 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter) } } } - send_agent_resume(); + + if (blocking) + { + send_agent_resume(); + } // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); return success; } -BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) +BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, bool blocking) { if( mLocked ) { @@ -540,8 +548,12 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) reset(); - // Modal, so pause agent - send_agent_pause(); + if (blocking) + { + // Modal, so pause agent + send_agent_pause(); + } + { // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! try @@ -559,7 +571,11 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) } gKeyboard->resetKeys(); } - send_agent_resume(); + + if (blocking) + { + send_agent_resume(); + } // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); @@ -809,7 +825,7 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) mPickOptions |= F_NAV_SUPPORT; } - if (blocking) + if (blocking) // always true for linux/mac { // Modal, so pause agent send_agent_pause(); @@ -834,7 +850,7 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) return success; } -BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter) +BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking) { if( mLocked ) return FALSE; @@ -852,13 +868,20 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter) mPickOptions |= F_FILE; mPickOptions |= F_MULTIPLE; - // Modal, so pause agent - send_agent_pause(); - + + if (blocking) // always true for linux/mac + { + // Modal, so pause agent + send_agent_pause(); + } + success = doNavChooseDialog(filter); - - send_agent_resume(); - + + if (blocking) + { + send_agent_resume(); + } + if (success) { if (!getFileCount()) @@ -872,7 +895,7 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter) return success; } -BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) +BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, bool blocking) { if( mLocked ) @@ -889,8 +912,11 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) mPickOptions &= ~F_MULTIPLE; - // Modal, so pause agent - send_agent_pause(); + if (blocking) + { + // Modal, so pause agent + send_agent_pause(); + } success = doNavSaveDialog(filter, filename); @@ -900,7 +926,10 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) success = false; } - send_agent_resume(); + if (blocking) + { + send_agent_resume(); + } // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); @@ -1354,7 +1383,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) return rtn; } -BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter ) +BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking) { BOOL rtn = FALSE; @@ -1438,7 +1467,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) return TRUE; } -BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter ) +BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking) { // if local file browsing is turned off, return without opening dialog // (Even though this is a stub, I think we still should not return anything at all) @@ -1467,7 +1496,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter ) return FALSE; } -BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter ) +BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking) { reset(); return FALSE; diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index b6e67375cd..2fc496a144 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -113,9 +113,9 @@ public: }; // open the dialog. This is a modal operation - BOOL getSaveFile( ESaveFilter filter = FFSAVE_ALL, const std::string& filename = LLStringUtil::null ); + BOOL getSaveFile( ESaveFilter filter = FFSAVE_ALL, const std::string& filename = LLStringUtil::null, bool blocking = true); BOOL getOpenFile( ELoadFilter filter = FFLOAD_ALL, bool blocking = true ); - BOOL getMultipleOpenFiles( ELoadFilter filter = FFLOAD_ALL ); + BOOL getMultipleOpenFiles( ELoadFilter filter = FFLOAD_ALL, bool blocking = true ); // Get the filename(s) found. getFirstFile() sets the pointer to // the start of the structure and allows the start of iteration. @@ -198,6 +198,4 @@ public: ~LLFilePicker(); }; -const std::string upload_pick(void* data); - #endif diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp deleted file mode 100644 index 56619e818a..0000000000 --- a/indra/newview/llfloaterauction.cpp +++ /dev/null @@ -1,552 +0,0 @@ -/** - * @file llfloaterauction.cpp - * @author James Cook, Ian Wilkes - * @brief Implementation of the auction floater. - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" -#include "llfloaterauction.h" - -#include "llgl.h" -#include "llimagej2c.h" -#include "llimagetga.h" -#include "llparcel.h" -#include "llvfile.h" -#include "llvfs.h" -#include "llwindow.h" -#include "message.h" - -#include "llagent.h" -#include "llassetstorage.h" -#include "llcombobox.h" -#include "llestateinfomodel.h" -#include "llmimetypes.h" -#include "llnotifications.h" -#include "llnotificationsutil.h" -#include "llsavedsettingsglue.h" -#include "llviewertexturelist.h" -#include "llviewerparcelmgr.h" -#include "llviewerregion.h" -#include "lluictrlfactory.h" -#include "llviewerwindow.h" -#include "llviewerdisplay.h" -#include "llviewercontrol.h" -#include "llui.h" -#include "llrender.h" -#include "llsdutil.h" -#include "llsdutil_math.h" -#include "lltrans.h" -#include "llcorehttputil.h" - -///---------------------------------------------------------------------------- -/// Local function declarations, constants, enums, and typedefs -///---------------------------------------------------------------------------- - -void auction_j2c_upload_done(const LLUUID& asset_id, - void* user_data, S32 status, LLExtStat ext_status); -void auction_tga_upload_done(const LLUUID& asset_id, - void* user_data, S32 status, LLExtStat ext_status); - -///---------------------------------------------------------------------------- -/// Class llfloaterauction -///---------------------------------------------------------------------------- - -// Default constructor -LLFloaterAuction::LLFloaterAuction(const LLSD& key) - : LLFloater(key), - mParcelID(-1) -{ - mCommitCallbackRegistrar.add("ClickSnapshot", boost::bind(&LLFloaterAuction::onClickSnapshot, this)); - mCommitCallbackRegistrar.add("ClickSellToAnyone", boost::bind(&LLFloaterAuction::onClickSellToAnyone, this)); - mCommitCallbackRegistrar.add("ClickStartAuction", boost::bind(&LLFloaterAuction::onClickStartAuction, this)); - mCommitCallbackRegistrar.add("ClickResetParcel", boost::bind(&LLFloaterAuction::onClickResetParcel, this)); -} - -// Destroys the object -LLFloaterAuction::~LLFloaterAuction() -{ -} - -BOOL LLFloaterAuction::postBuild() -{ - return TRUE; -} - -void LLFloaterAuction::onOpen(const LLSD& key) -{ - initialize(); -} - -void LLFloaterAuction::initialize() -{ - mParcelUpdateCapUrl.clear(); - - mParcelp = LLViewerParcelMgr::getInstance()->getParcelSelection(); - LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); - LLParcel* parcelp = mParcelp->getParcel(); - if(parcelp && region && !parcelp->getForSale()) - { - mParcelHost = region->getHost(); - mParcelID = parcelp->getLocalID(); - mParcelUpdateCapUrl = region->getCapability("ParcelPropertiesUpdate"); - - getChild<LLUICtrl>("parcel_text")->setValue(parcelp->getName()); - getChildView("snapshot_btn")->setEnabled(TRUE); - getChildView("reset_parcel_btn")->setEnabled(TRUE); - getChildView("start_auction_btn")->setEnabled(TRUE); - - U32 estate_id = LLEstateInfoModel::instance().getID(); - // Only enable "Sell to Anyone" on Teen grid or if we don't know the ID yet - getChildView("sell_to_anyone_btn")->setEnabled(estate_id == ESTATE_TEEN || estate_id == 0); - } - else - { - mParcelHost.invalidate(); - if(parcelp && parcelp->getForSale()) - { - getChild<LLUICtrl>("parcel_text")->setValue(getString("already for sale")); - } - else - { - getChild<LLUICtrl>("parcel_text")->setValue(LLStringUtil::null); - } - mParcelID = -1; - getChildView("snapshot_btn")->setEnabled(false); - getChildView("reset_parcel_btn")->setEnabled(false); - getChildView("sell_to_anyone_btn")->setEnabled(false); - getChildView("start_auction_btn")->setEnabled(false); - } - - mImageID.setNull(); - mImage = NULL; -} - -void LLFloaterAuction::draw() -{ - LLFloater::draw(); - - if(!isMinimized() && mImage.notNull()) - { - LLView* snapshot_icon = findChildView("snapshot_icon"); - if (snapshot_icon) - { - LLRect rect = snapshot_icon->getRect(); - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gl_rect_2d(rect, LLColor4(0.f, 0.f, 0.f, 1.f)); - rect.stretch(-1); - } - { - LLGLSUIDefault gls_ui; - gGL.color3f(1.f, 1.f, 1.f); - gl_draw_scaled_image(rect.mLeft, - rect.mBottom, - rect.getWidth(), - rect.getHeight(), - mImage); - } - } - } -} - - -// static -void LLFloaterAuction::onClickSnapshot(void* data) -{ - LLFloaterAuction* self = (LLFloaterAuction*)(data); - - LLPointer<LLImageRaw> raw = new LLImageRaw; - - gForceRenderLandFence = self->getChild<LLUICtrl>("fence_check")->getValue().asBoolean(); - BOOL success = gViewerWindow->rawSnapshot(raw, - gViewerWindow->getWindowWidthScaled(), - gViewerWindow->getWindowHeightScaled(), - TRUE, FALSE, - FALSE, FALSE); - gForceRenderLandFence = FALSE; - - if (success) - { - self->mTransactionID.generate(); - self->mImageID = self->mTransactionID.makeAssetID(gAgent.getSecureSessionID()); - - if(!gSavedSettings.getBOOL("QuietSnapshotsToDisk")) - { - gViewerWindow->playSnapshotAnimAndSound(); - } - LL_INFOS() << "Writing TGA..." << LL_ENDL; - - LLPointer<LLImageTGA> tga = new LLImageTGA; - tga->encode(raw); - LLVFile::writeFile(tga->getData(), tga->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_IMAGE_TGA); - - raw->biasedScaleToPowerOfTwo(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT); - - LL_INFOS() << "Writing J2C..." << LL_ENDL; - - LLPointer<LLImageJ2C> j2c = new LLImageJ2C; - j2c->encode(raw, 0.0f); - LLVFile::writeFile(j2c->getData(), j2c->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_TEXTURE); - - self->mImage = LLViewerTextureManager::getLocalTexture((LLImageRaw*)raw, FALSE); - gGL.getTexUnit(0)->bind(self->mImage); - self->mImage->setAddressMode(LLTexUnit::TAM_CLAMP); - } - else - { - LL_WARNS() << "Unable to take snapshot" << LL_ENDL; - } -} - -// static -void LLFloaterAuction::onClickStartAuction(void* data) -{ - LLFloaterAuction* self = (LLFloaterAuction*)(data); - - if(self->mImageID.notNull()) - { - LLSD parcel_name = self->getChild<LLUICtrl>("parcel_text")->getValue(); - - // create the asset - std::string* name = new std::string(parcel_name.asString()); - gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_IMAGE_TGA, - &auction_tga_upload_done, - (void*)name, - FALSE); - self->getWindow()->incBusyCount(); - - std::string* j2c_name = new std::string(parcel_name.asString()); - gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_TEXTURE, - &auction_j2c_upload_done, - (void*)j2c_name, - FALSE); - self->getWindow()->incBusyCount(); - - LLNotificationsUtil::add("UploadingAuctionSnapshot"); - - } - LLMessageSystem* msg = gMessageSystem; - - msg->newMessage("ViewerStartAuction"); - - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); - msg->nextBlock("ParcelData"); - msg->addS32("LocalID", self->mParcelID); - msg->addUUID("SnapshotID", self->mImageID); - msg->sendReliable(self->mParcelHost); - - // clean up floater, and get out - self->cleanupAndClose(); -} - - -void LLFloaterAuction::cleanupAndClose() -{ - mImageID.setNull(); - mImage = NULL; - mParcelID = -1; - mParcelHost.invalidate(); - closeFloater(); -} - - - -// static glue -void LLFloaterAuction::onClickResetParcel(void* data) -{ - LLFloaterAuction* self = (LLFloaterAuction*)(data); - if (self) - { - self->doResetParcel(); - } -} - - -// Reset all the values for the parcel in preparation for a sale -void LLFloaterAuction::doResetParcel() -{ - LLParcel* parcelp = mParcelp->getParcel(); - LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); - - if (parcelp - && region - && !mParcelUpdateCapUrl.empty()) - { - LLSD body; - std::string empty; - - // request new properties update from simulator - U32 message_flags = 0x01; - body["flags"] = ll_sd_from_U32(message_flags); - - // Set all the default parcel properties for auction - body["local_id"] = parcelp->getLocalID(); - - U32 parcel_flags = PF_ALLOW_LANDMARK | - PF_ALLOW_FLY | - PF_CREATE_GROUP_OBJECTS | - PF_ALLOW_ALL_OBJECT_ENTRY | - PF_ALLOW_GROUP_OBJECT_ENTRY | - PF_ALLOW_GROUP_SCRIPTS | - PF_RESTRICT_PUSHOBJECT | - PF_SOUND_LOCAL | - PF_ALLOW_VOICE_CHAT | - PF_USE_ESTATE_VOICE_CHAN; - - body["parcel_flags"] = ll_sd_from_U32(parcel_flags); - - // Build a parcel name like "Ahern (128,128) PG 4032m" - std::ostringstream parcel_name; - LLVector3 center_point( parcelp->getCenterpoint() ); - center_point.snap(0); // Get rid of fractions - parcel_name << region->getName() - << " (" - << (S32) center_point.mV[VX] - << "," - << (S32) center_point.mV[VY] - << ") " - << region->getSimAccessString() - << " " - << parcelp->getArea() - << "m"; - - std::string new_name(parcel_name.str().c_str()); - body["name"] = new_name; - getChild<LLUICtrl>("parcel_text")->setValue(new_name); // Set name in dialog as well, since it won't get updated otherwise - - body["sale_price"] = (S32) 0; - body["description"] = empty; - body["music_url"] = empty; - body["media_url"] = empty; - body["media_desc"] = empty; - body["media_type"] = LLMIMETypes::getDefaultMimeType(); - body["media_width"] = (S32) 0; - body["media_height"] = (S32) 0; - body["auto_scale"] = (S32) 0; - body["media_loop"] = (S32) 0; - body["obscure_media"] = (S32) 0; // OBSOLETE - no longer used - body["obscure_music"] = (S32) 0; // OBSOLETE - no longer used - body["media_id"] = LLUUID::null; - body["group_id"] = MAINTENANCE_GROUP_ID; // Use maintenance group - body["pass_price"] = (S32) 10; // Defaults to $10 - body["pass_hours"] = 0.0f; - body["category"] = (U8) LLParcel::C_NONE; - body["auth_buyer_id"] = LLUUID::null; - body["snapshot_id"] = LLUUID::null; - body["user_location"] = ll_sd_from_vector3( LLVector3::zero ); - body["user_look_at"] = ll_sd_from_vector3( LLVector3::zero ); - body["landing_type"] = (U8) LLParcel::L_DIRECT; - - LL_INFOS() << "Sending parcel update to reset for auction via capability to: " - << mParcelUpdateCapUrl << LL_ENDL; - - LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(mParcelUpdateCapUrl, body, - "Parcel reset for auction", - "Parcel not set for auction."); - - // Send a message to clear the object return time - LLMessageSystem *msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ParcelSetOtherCleanTime); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_ParcelData); - msg->addS32Fast(_PREHASH_LocalID, parcelp->getLocalID()); - msg->addS32Fast(_PREHASH_OtherCleanTime, 5); // 5 minute object auto-return - - msg->sendReliable(region->getHost()); - - // Clear the access lists - clearParcelAccessList(parcelp, region, AL_ACCESS); - clearParcelAccessList(parcelp, region, AL_BAN); - clearParcelAccessList(parcelp, region, AL_ALLOW_EXPERIENCE); - clearParcelAccessList(parcelp, region, AL_BLOCK_EXPERIENCE); - } -} - - - -void LLFloaterAuction::clearParcelAccessList(LLParcel* parcel, LLViewerRegion* region, U32 list) -{ - if (!region || !parcel) return; - - LLUUID transactionUUID; - transactionUUID.generate(); - - LLMessageSystem* msg = gMessageSystem; - - msg->newMessageFast(_PREHASH_ParcelAccessListUpdate); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); - msg->nextBlockFast(_PREHASH_Data); - msg->addU32Fast(_PREHASH_Flags, list); - msg->addS32(_PREHASH_LocalID, parcel->getLocalID() ); - msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID); - msg->addS32Fast(_PREHASH_SequenceID, 1); // sequence_id - msg->addS32Fast(_PREHASH_Sections, 0); // num_sections - - // pack an empty block since there will be no data - msg->nextBlockFast(_PREHASH_List); - msg->addUUIDFast(_PREHASH_ID, LLUUID::null ); - msg->addS32Fast(_PREHASH_Time, 0 ); - msg->addU32Fast(_PREHASH_Flags, 0 ); - - msg->sendReliable( region->getHost() ); -} - - - -// static - 'Sell to Anyone' clicked, throw up a confirmation dialog -void LLFloaterAuction::onClickSellToAnyone(void* data) -{ - LLFloaterAuction* self = (LLFloaterAuction*)(data); - if (self) - { - LLParcel* parcelp = self->mParcelp->getParcel(); - - // Do a confirmation - S32 sale_price = parcelp->getArea(); // Selling for L$1 per meter - S32 area = parcelp->getArea(); - - LLSD args; - args["LAND_SIZE"] = llformat("%d", area); - args["SALE_PRICE"] = llformat("%d", sale_price); - args["NAME"] = LLTrans::getString("Anyone"); - - LLNotification::Params params("ConfirmLandSaleChange"); // Re-use existing dialog - params.substitutions(args) - .functor.function(boost::bind(&LLFloaterAuction::onSellToAnyoneConfirmed, self, _1, _2)); - - params.name("ConfirmLandSaleToAnyoneChange"); - - // ask away - LLNotifications::instance().add(params); - } -} - - -// Sell confirmation clicked -bool LLFloaterAuction::onSellToAnyoneConfirmed(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option == 0) - { - doSellToAnyone(); - } - - return false; -} - - - -// Reset all the values for the parcel in preparation for a sale -void LLFloaterAuction::doSellToAnyone() -{ - LLParcel* parcelp = mParcelp->getParcel(); - LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); - - if (parcelp - && region - && !mParcelUpdateCapUrl.empty()) - { - LLSD body; - std::string empty; - - // request new properties update from simulator - U32 message_flags = 0x01; - body["flags"] = ll_sd_from_U32(message_flags); - - // Set all the default parcel properties for auction - body["local_id"] = parcelp->getLocalID(); - - // Set 'for sale' flag - U32 parcel_flags = parcelp->getParcelFlags() | PF_FOR_SALE; - // Ensure objects not included - parcel_flags &= ~PF_FOR_SALE_OBJECTS; - body["parcel_flags"] = ll_sd_from_U32(parcel_flags); - - body["sale_price"] = parcelp->getArea(); // Sell for L$1 per square meter - body["auth_buyer_id"] = LLUUID::null; // To anyone - - LL_INFOS() << "Sending parcel update to sell to anyone for L$1 via capability to: " - << mParcelUpdateCapUrl << LL_ENDL; - - LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(mParcelUpdateCapUrl, body, - "Parcel set as sell to everyone.", - "Parcel sell to everyone failed."); - - // clean up floater, and get out - cleanupAndClose(); - } -} - - -///---------------------------------------------------------------------------- -/// Local function definitions -///---------------------------------------------------------------------------- - -void auction_tga_upload_done(const LLUUID& asset_id, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed) -{ - std::string* name = (std::string*)(user_data); - LL_INFOS() << "Upload of asset '" << *name << "' " << asset_id - << " returned " << status << LL_ENDL; - delete name; - - gViewerWindow->getWindow()->decBusyCount(); - - if (0 == status) - { - LLNotificationsUtil::add("UploadWebSnapshotDone"); - } - else - { - LLSD args; - args["REASON"] = std::string(LLAssetStorage::getErrorString(status)); - LLNotificationsUtil::add("UploadAuctionSnapshotFail", args); - } -} - -void auction_j2c_upload_done(const LLUUID& asset_id, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed) -{ - std::string* name = (std::string*)(user_data); - LL_INFOS() << "Upload of asset '" << *name << "' " << asset_id - << " returned " << status << LL_ENDL; - delete name; - - gViewerWindow->getWindow()->decBusyCount(); - - if (0 == status) - { - LLNotificationsUtil::add("UploadSnapshotDone"); - } - else - { - LLSD args; - args["REASON"] = std::string(LLAssetStorage::getErrorString(status)); - LLNotificationsUtil::add("UploadAuctionSnapshotFail", args); - } -} diff --git a/indra/newview/llfloaterauction.h b/indra/newview/llfloaterauction.h deleted file mode 100644 index c83a11ba8b..0000000000 --- a/indra/newview/llfloaterauction.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * @file llfloaterauction.h - * @author James Cook, Ian Wilkes - * @brief llfloaterauction class header file - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLFLOATERAUCTION_H -#define LL_LLFLOATERAUCTION_H - -#include "llfloater.h" -#include "lluuid.h" -#include "llpointer.h" -#include "llviewertexture.h" - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFloaterAuction -// -// Class which holds the functionality to start auctions. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLParcelSelection; -class LLParcel; -class LLViewerRegion; - -class LLFloaterAuction : public LLFloater -{ - friend class LLFloaterReg; -public: - // LLFloater interface - /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void draw(); - -private: - - LLFloaterAuction(const LLSD& key); - ~LLFloaterAuction(); - - void initialize(); - - static void onClickSnapshot(void* data); - static void onClickResetParcel(void* data); - static void onClickSellToAnyone(void* data); // Sell to anyone clicked - bool onSellToAnyoneConfirmed(const LLSD& notification, const LLSD& response); // Sell confirmation clicked - static void onClickStartAuction(void* data); - - /*virtual*/ BOOL postBuild(); - - void doResetParcel(); - void doSellToAnyone(); - void clearParcelAccessList( LLParcel* parcel, LLViewerRegion* region, U32 list); - void cleanupAndClose(); - -private: - - LLTransactionID mTransactionID; - LLAssetID mImageID; - LLPointer<LLViewerTexture> mImage; - LLSafeHandle<LLParcelSelection> mParcelp; - S32 mParcelID; - LLHost mParcelHost; - - std::string mParcelUpdateCapUrl; // "ParcelPropertiesUpdate" capability -}; - - -#endif // LL_LLFLOATERAUCTION_H diff --git a/indra/newview/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp index 5830f2f711..ec05ba924c 100644 --- a/indra/newview/llfloaterautoreplacesettings.cpp +++ b/indra/newview/llfloaterautoreplacesettings.cpp @@ -54,6 +54,7 @@ #include "llhost.h" #include "llassetstorage.h" #include "roles_constants.h" +#include "llviewermenufile.h" // LLFilePickerReplyThread #include "llviewertexteditor.h" #include <boost/tokenizer.hpp> @@ -349,62 +350,58 @@ void LLFloaterAutoReplaceSettings::onDeleteEntry() // called when the Import List button is pressed void LLFloaterAutoReplaceSettings::onImportList() { - LLFilePicker& picker = LLFilePicker::instance(); - if( picker.getOpenFile( LLFilePicker::FFLOAD_XML) ) + (new LLFilePickerReplyThread(boost::bind(&LLFloaterAutoReplaceSettings::loadListFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile(); +} + +void LLFloaterAutoReplaceSettings::loadListFromFile(const std::vector<std::string>& filenames) +{ + llifstream file; + file.open(filenames[0].c_str()); + LLSD newList; + if (file.is_open()) { - llifstream file; - file.open(picker.getFirstFile().c_str()); - LLSD newList; - if (file.is_open()) - { - LLSDSerialize::fromXMLDocument(newList, file); - } - file.close(); + LLSDSerialize::fromXMLDocument(newList, file); + } + file.close(); - switch ( mSettings.addList(newList) ) - { - case LLAutoReplaceSettings::AddListOk: - mSelectedListName = LLAutoReplaceSettings::getListName(newList); + switch ( mSettings.addList(newList) ) + { + case LLAutoReplaceSettings::AddListOk: + mSelectedListName = LLAutoReplaceSettings::getListName(newList); - updateListNames(); - updateListNamesControls(); - updateReplacementsList(); - break; + updateListNames(); + updateListNamesControls(); + updateReplacementsList(); + break; - case LLAutoReplaceSettings::AddListDuplicateName: - { - std::string newName = LLAutoReplaceSettings::getListName(newList); - LL_WARNS("AutoReplace")<<"name '"<<newName<<"' is in use; prompting for new name"<<LL_ENDL; - LLSD newPayload; - newPayload["list"] = newList; - LLSD args; - args["DUPNAME"] = newName; + case LLAutoReplaceSettings::AddListDuplicateName: + { + std::string newName = LLAutoReplaceSettings::getListName(newList); + LL_WARNS("AutoReplace")<<"name '"<<newName<<"' is in use; prompting for new name"<<LL_ENDL; + LLSD newPayload; + newPayload["list"] = newList; + LLSD args; + args["DUPNAME"] = newName; - LLNotificationsUtil::add("RenameAutoReplaceList", args, newPayload, + LLNotificationsUtil::add("RenameAutoReplaceList", args, newPayload, boost::bind(&LLFloaterAutoReplaceSettings::callbackListNameConflict, this, _1, _2)); - } - break; + } + break; - case LLAutoReplaceSettings::AddListInvalidList: - LLNotificationsUtil::add("InvalidAutoReplaceList"); - LL_WARNS("AutoReplace") << "imported list was invalid" << LL_ENDL; + case LLAutoReplaceSettings::AddListInvalidList: + LLNotificationsUtil::add("InvalidAutoReplaceList"); + LL_WARNS("AutoReplace") << "imported list was invalid" << LL_ENDL; - mSelectedListName.clear(); - updateListNames(); - updateListNamesControls(); - updateReplacementsList(); - break; + mSelectedListName.clear(); + updateListNames(); + updateListNamesControls(); + updateReplacementsList(); + break; - default: - LL_ERRS("AutoReplace") << "invalid AddListResult" << LL_ENDL; + default: + LL_ERRS("AutoReplace") << "invalid AddListResult" << LL_ENDL; - } - - } - else - { - LL_DEBUGS("AutoReplace") << "file selection failed for import list" << LL_ENDL; - } + } } void LLFloaterAutoReplaceSettings::onNewList() @@ -539,16 +536,17 @@ void LLFloaterAutoReplaceSettings::onDeleteList() void LLFloaterAutoReplaceSettings::onExportList() { std::string listName=mListNames->getFirstSelected()->getColumn(0)->getValue().asString(); - const LLSD* list = mSettings.exportList(listName); std::string listFileName = listName + ".xml"; - LLFilePicker& picker = LLFilePicker::instance(); - if( picker.getSaveFile( LLFilePicker::FFSAVE_XML, listFileName) ) - { - llofstream file; - file.open(picker.getFirstFile().c_str()); - LLSDSerialize::toPrettyXML(*list, file); - file.close(); - } + (new LLFilePickerReplyThread(boost::bind(&LLFloaterAutoReplaceSettings::saveListToFile, this, _1, listName), LLFilePicker::FFSAVE_XML, listFileName))->getFile(); +} + +void LLFloaterAutoReplaceSettings::saveListToFile(const std::vector<std::string>& filenames, std::string listName) +{ + llofstream file; + const LLSD* list = mSettings.exportList(listName); + file.open(filenames[0].c_str()); + LLSDSerialize::toPrettyXML(*list, file); + file.close(); } void LLFloaterAutoReplaceSettings::onAddEntry() diff --git a/indra/newview/llfloaterautoreplacesettings.h b/indra/newview/llfloaterautoreplacesettings.h index 629aea3e3c..2109aa7026 100644 --- a/indra/newview/llfloaterautoreplacesettings.h +++ b/indra/newview/llfloaterautoreplacesettings.h @@ -112,6 +112,9 @@ private: bool selectedListIsLast(); void cleanUp(); + + void loadListFromFile(const std::vector<std::string>& filenames); + void saveListToFile(const std::vector<std::string>& filenames, std::string listName); }; #endif // LLFLOATERAUTOREPLACESETTINGS_H diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp index 78807a8e99..8e654a53c4 100644 --- a/indra/newview/llfloateravatartextures.cpp +++ b/indra/newview/llfloateravatartextures.cpp @@ -78,7 +78,7 @@ static void update_texture_ctrl(LLVOAvatar* avatarp, { LLUUID id = IMG_DEFAULT_AVATAR; const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture(te); - if (tex_entry->mIsLocalTexture) + if (tex_entry && tex_entry->mIsLocalTexture) { if (avatarp->isSelf()) { @@ -96,7 +96,7 @@ static void update_texture_ctrl(LLVOAvatar* avatarp, } else { - id = avatarp->getTE(te)->getID(); + id = tex_entry ? avatarp->getTE(te)->getID() : IMG_DEFAULT_AVATAR; } //id = avatarp->getTE(te)->getID(); if (id == IMG_DEFAULT_AVATAR) diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 6623ce0f80..a4ab1af9a8 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -82,8 +82,7 @@ LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id) mPositioned(false), mSessionInitialized(false), mMeTypingTimer(), - mOtherTypingTimer(), - mImInfo() + mOtherTypingTimer() { mIsNearbyChat = false; @@ -125,7 +124,7 @@ void LLFloaterIMSession::refresh() if (mOtherTyping && mOtherTypingTimer.getElapsedTimeF32() > OTHER_TYPING_TIMEOUT) { LL_DEBUGS("TypingMsgs") << "Received: is typing cleared due to timeout" << LL_ENDL; - removeTypingIndicator(mImInfo); + removeTypingIndicator(mImFromId); mOtherTyping = false; } @@ -1006,19 +1005,19 @@ void LLFloaterIMSession::setTyping(bool typing) } } -void LLFloaterIMSession::processIMTyping(const LLIMInfo* im_info, BOOL typing) +void LLFloaterIMSession::processIMTyping(const LLUUID& from_id, BOOL typing) { LL_DEBUGS("TypingMsgs") << "typing=" << typing << LL_ENDL; if ( typing ) { // other user started typing - addTypingIndicator(im_info); + addTypingIndicator(from_id); mOtherTypingTimer.reset(); } else { // other user stopped typing - removeTypingIndicator(im_info); + removeTypingIndicator(from_id); } } @@ -1218,7 +1217,7 @@ BOOL LLFloaterIMSession::inviteToSession(const uuid_vec_t& ids) return is_region_exist; } -void LLFloaterIMSession::addTypingIndicator(const LLIMInfo* im_info) +void LLFloaterIMSession::addTypingIndicator(const LLUUID& from_id) { /* Operation of "<name> is typing" state machine: Not Typing state: @@ -1248,35 +1247,35 @@ Note: OTHER_TYPING_TIMEOUT must be > ME_TYPING_TIMEOUT for proper operation of t */ // We may have lost a "stop-typing" packet, don't add it twice - if (im_info && !mOtherTyping) + if (from_id.notNull() && !mOtherTyping) { mOtherTyping = true; mOtherTypingTimer.reset(); // Save im_info so that removeTypingIndicator can be properly called because a timeout has occurred - mImInfo = im_info; + mImFromId = from_id; // Update speaker LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); if ( speaker_mgr ) { - speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE); + speaker_mgr->setSpeakerTyping(from_id, TRUE); } } } -void LLFloaterIMSession::removeTypingIndicator(const LLIMInfo* im_info) +void LLFloaterIMSession::removeTypingIndicator(const LLUUID& from_id) { if (mOtherTyping) { mOtherTyping = false; - if (im_info) + if (from_id.notNull()) { // Update speaker LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); if (speaker_mgr) { - speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE); + speaker_mgr->setSpeakerTyping(from_id, FALSE); } } } diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h index 0f7164a585..28464fc14b 100644 --- a/indra/newview/llfloaterimsession.h +++ b/indra/newview/llfloaterimsession.h @@ -122,7 +122,7 @@ public: const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state); - void processIMTyping(const LLIMInfo* im_info, BOOL typing); + void processIMTyping(const LLUUID& from_id, BOOL typing); void processAgentListUpdates(const LLSD& body); void processSessionUpdate(const LLSD& session_update); @@ -165,10 +165,10 @@ private: void boundVoiceChannel(); // Add the "User is typing..." indicator. - void addTypingIndicator(const LLIMInfo* im_info); + void addTypingIndicator(const LLUUID& from_id); // Remove the "User is typing..." indicator. - void removeTypingIndicator(const LLIMInfo* im_info = NULL); + void removeTypingIndicator(const LLUUID& from_id = LLUUID::null); static void closeHiddenIMToasts(); @@ -199,7 +199,7 @@ private: // connection to voice channel state change signal boost::signals2::connection mVoiceChannelStateChangeConnection; - const LLIMInfo* mImInfo; + LLUUID mImFromId; }; #endif // LL_FLOATERIMSESSION_H diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index ac47253444..fcf836f4a0 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -45,7 +45,6 @@ #include "llcombobox.h" #include "llfloaterreg.h" #include "llfloateravatarpicker.h" -#include "llfloaterauction.h" #include "llfloatergroups.h" #include "llfloaterscriptlimits.h" #include "llavataractions.h" @@ -80,6 +79,7 @@ #include "llpanelexperiencepicker.h" #include "llpanelenvironment.h" #include "llexperiencecache.h" +#include "llweb.h" #include "llgroupactions.h" #include "llenvironment.h" @@ -574,7 +574,6 @@ void LLPanelLandGeneral::refresh() mBtnDeedToGroup->setEnabled(FALSE); mBtnSetGroup->setEnabled(FALSE); - mBtnStartAuction->setEnabled(FALSE); mCheckDeedToGroup ->set(FALSE); mCheckDeedToGroup ->setEnabled(FALSE); @@ -672,7 +671,6 @@ void LLPanelLandGeneral::refresh() mTextClaimDate->setEnabled(FALSE); mTextGroup->setText(getString("none_text")); mTextGroup->setEnabled(FALSE); - mBtnStartAuction->setEnabled(FALSE); } else { @@ -724,11 +722,6 @@ void LLPanelLandGeneral::refresh() LLStringUtil::format (claim_date_str, substitution); mTextClaimDate->setText(claim_date_str); mTextClaimDate->setEnabled(is_leased); - - BOOL enable_auction = (gAgent.getGodLevel() >= GOD_LIAISON) - && (owner_id == GOVERNOR_LINDEN_ID) - && (parcel->getAuctionID() == 0); - mBtnStartAuction->setEnabled(enable_auction); } // Display options @@ -1056,20 +1049,8 @@ void LLPanelLandGeneral::onClickBuyPass(void* data) // static void LLPanelLandGeneral::onClickStartAuction(void* data) { - LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data; - LLParcel* parcelp = panelp->mParcel->getParcel(); - if(parcelp) - { - if(parcelp->getForSale()) - { - LLNotificationsUtil::add("CannotStartAuctionAlreadyForSale"); - } - else - { - //LLFloaterAuction::showInstance(); - LLFloaterReg::showInstance("auction"); - } - } + std::string auction_url = "https://places.[GRID]/auctions/"; + LLWeb::loadURLExternal(LLWeb::expandURLSubstitutions(auction_url, LLSD())); } // static diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index da84a6b8f8..7a2ab37a0d 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -218,9 +218,17 @@ LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod) mLOD = lod; } -void LLMeshFilePicker::notify(const std::string& filename) +void LLMeshFilePicker::notify(const std::vector<std::string>& filenames) { - mMP->loadModel(mFile, mLOD); + if (filenames.size() > 0) + { + mMP->loadModel(filenames[0], mLOD); + } + else + { + //closes floater + mMP->loadModel(std::string(), mLOD); + } } void FindModel(LLModelLoader::scene& scene, const std::string& name_to_match, LLModel*& baseModelOut, LLMatrix4& matOut) diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 0b2b7db2b6..53b03c6069 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -219,7 +219,7 @@ class LLMeshFilePicker : public LLFilePickerThread { public: LLMeshFilePicker(LLModelPreview* mp, S32 lod); - virtual void notify(const std::string& filename); + virtual void notify(const std::vector<std::string>& filenames); private: LLModelPreview* mMP; diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 5de7ca5289..9d723bdd9d 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1249,6 +1249,8 @@ void LLFloaterPreference::refreshEnabledState() // Cannot have floater active until caps have been received getChild<LLButton>("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() < STATE_STARTED ? false : true); + + getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess()); } void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() @@ -1383,8 +1385,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() // now turn off any features that are unavailable disableUnavailableSettings(); - - getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess()); } // static @@ -2563,18 +2563,6 @@ BOOL LLPanelPreferenceGraphics::postBuild() LLFloaterReg::showInstance("prefs_graphics_advanced"); LLFloaterReg::hideInstance("prefs_graphics_advanced"); -// Don't do this on Mac as their braindead GL versioning -// sets this when 8x and 16x are indeed available -// -#if !LL_DARWIN - if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f) - { //remove FSAA settings above "4x" - LLComboBox* combo = getChild<LLComboBox>("fsaa"); - combo->remove("8x"); - combo->remove("16x"); - } -#endif - resetDirtyChilds(); setPresetText(); @@ -2749,6 +2737,23 @@ LLFloaterPreferenceProxy::LLFloaterPreferenceProxy(const LLSD& key) mCommitCallbackRegistrar.add("Proxy.Change", boost::bind(&LLFloaterPreferenceProxy::onChangeSocksSettings, this)); } +BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild() +{ + // Don't do this on Mac as their braindead GL versioning + // sets this when 8x and 16x are indeed available + // +#if !LL_DARWIN + if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f) + { //remove FSAA settings above "4x" + LLComboBox* combo = getChild<LLComboBox>("fsaa"); + combo->remove("8x"); + combo->remove("16x"); + } +#endif + + return TRUE; +} + void LLFloaterPreferenceGraphicsAdvanced::onOpen(const LLSD& key) { refresh(); diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 444ad5a928..0cd7bac20f 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -276,6 +276,7 @@ class LLFloaterPreferenceGraphicsAdvanced : public LLFloater public: LLFloaterPreferenceGraphicsAdvanced(const LLSD& key); ~LLFloaterPreferenceGraphicsAdvanced(); + /*virtual*/ BOOL postBuild(); void onOpen(const LLSD& key); void onClickCloseBtn(bool app_quitting); void disableUnavailableSettings(); diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp index 1310a60638..fbb7432f71 100644 --- a/indra/newview/llfloaterproperties.cpp +++ b/indra/newview/llfloaterproperties.cpp @@ -490,7 +490,6 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) if (is_obj_modify && can_agent_sell && gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE)) { - getChildView("SaleLabel")->setEnabled(is_complete); getChildView("CheckPurchase")->setEnabled(is_complete); getChildView("NextOwnerLabel")->setEnabled(TRUE); @@ -498,13 +497,11 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) getChildView("CheckNextOwnerCopy")->setEnabled((base_mask & PERM_COPY) && !cannot_restrict_permissions); getChildView("CheckNextOwnerTransfer")->setEnabled((next_owner_mask & PERM_COPY) && !cannot_restrict_permissions); - getChildView("TextPrice")->setEnabled(is_complete && is_for_sale); combo_sale_type->setEnabled(is_complete && is_for_sale); edit_cost->setEnabled(is_complete && is_for_sale); } else { - getChildView("SaleLabel")->setEnabled(FALSE); getChildView("CheckPurchase")->setEnabled(FALSE); getChildView("NextOwnerLabel")->setEnabled(FALSE); @@ -512,7 +509,6 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) getChildView("CheckNextOwnerCopy")->setEnabled(FALSE); getChildView("CheckNextOwnerTransfer")->setEnabled(FALSE); - getChildView("TextPrice")->setEnabled(FALSE); combo_sale_type->setEnabled(FALSE); edit_cost->setEnabled(FALSE); } diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index a320bcc6fc..d94bf3f651 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -214,10 +214,30 @@ BOOL LLFloaterReporter::postBuild() std::string reporter = LLSLURL("agent", gAgent.getID(), "inspect").getSLURLString(); getChild<LLUICtrl>("reporter_field")->setValue(reporter); + // request categories + if (gAgent.getRegion() + && gAgent.getRegion()->capabilitiesReceived()) + { + std::string cap_url = gAgent.getRegionCapability("AbuseCategories"); + + if (!cap_url.empty()) + { + std::string lang = gSavedSettings.getString("Language"); + if (lang != "default" && !lang.empty()) + { + cap_url += "?lc="; + cap_url += lang; + } + LLCoros::instance().launch("LLFloaterReporter::requestAbuseCategoriesCoro", + boost::bind(LLFloaterReporter::requestAbuseCategoriesCoro, cap_url, this->getHandle())); + } + } + center(); return TRUE; } + // virtual LLFloaterReporter::~LLFloaterReporter() { @@ -402,6 +422,65 @@ void LLFloaterReporter::onAvatarNameCache(const LLUUID& avatar_id, const LLAvata } } +void LLFloaterReporter::requestAbuseCategoriesCoro(std::string url, LLHandle<LLFloater> handle) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestAbuseCategoriesCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, url); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status || !result.has("categories")) // success = httpResults["success"].asBoolean(); + { + LL_WARNS() << "Error requesting Abuse Categories from capability: " << url << LL_ENDL; + return; + } + + if (handle.isDead()) + { + // nothing to do + return; + } + + LLFloater* floater = handle.get(); + LLComboBox* combo = floater->getChild<LLComboBox>("category_combo"); + if (!combo) + { + LL_WARNS() << "categories category_combo not found!" << LL_ENDL; + return; + } + + //get selection (in case capability took a while) + S32 selection = combo->getCurrentIndex(); + + // Combobox should have a "Select category" element; + // This is a bit of workaround since there is no proper and simple way to save array of + // localizable strings in xml along with data (value). For now combobox is initialized along + // with placeholders, and first element is "Select category" which we want to keep, so remove + // everything but first element. + // Todo: once sim with capability fully releases, just remove this string and all unnecessary + // items from combobox since they will be obsolete (or depending on situation remake this to + // something better, for example move "Select category" to separate string) + while (combo->remove(1)); + + LLSD contents = result["categories"]; + + LLSD::array_iterator i = contents.beginArray(); + LLSD::array_iterator iEnd = contents.endArray(); + for (; i != iEnd; ++i) + { + const LLSD &message_data(*i); + std::string label = message_data["description_localized"]; + combo->add(label, message_data["category"]); + } + + //restore selection + combo->selectNthItem(selection); +} // static void LLFloaterReporter::onClickSend(void *userdata) diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index d9ecb9f4ea..c678df7155 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -129,6 +129,7 @@ private: void setFromAvatarID(const LLUUID& avatar_id); void onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name); + static void requestAbuseCategoriesCoro(std::string url, LLHandle<LLFloater> handle); static void finishedARPost(const LLSD &); private: diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 25e3d74ebc..156b2ba7b1 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -1100,6 +1100,7 @@ void LLFloaterSnapshot::onOpen(const LLSD& key) if(preview) { LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL; + preview->setAllowFullScreenPreview(TRUE); preview->updateSnapshot(TRUE); } focusFirstItem(FALSE); @@ -1129,6 +1130,7 @@ void LLFloaterSnapshotBase::onClose(bool app_quitting) LLSnapshotLivePreview* previewp = getPreviewView(); if (previewp) { + previewp->setAllowFullScreenPreview(FALSE); previewp->setVisible(FALSE); previewp->setEnabled(FALSE); } diff --git a/indra/newview/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp index 5124dae147..b87044ef5a 100644 --- a/indra/newview/llfloaterspellchecksettings.cpp +++ b/indra/newview/llfloaterspellchecksettings.cpp @@ -30,12 +30,13 @@ #include "llfilepicker.h" #include "llfloaterreg.h" #include "llfloaterspellchecksettings.h" +#include "llnotificationsutil.h" #include "llscrolllistctrl.h" #include "llsdserialize.h" #include "llspellcheck.h" #include "lltrans.h" #include "llviewercontrol.h" -#include "llnotificationsutil.h" +#include "llviewermenufile.h" // LLFilePickerReplyThread #include <boost/algorithm/string.hpp> @@ -258,13 +259,12 @@ BOOL LLFloaterSpellCheckerImport::postBuild(void) void LLFloaterSpellCheckerImport::onBtnBrowse() { - LLFilePicker& file_picker = LLFilePicker::instance(); - if (!file_picker.getOpenFile(LLFilePicker::FFLOAD_DICTIONARY)) - { - return; - } + (new LLFilePickerReplyThread(boost::bind(&LLFloaterSpellCheckerImport::importSelectedDictionary, this, _1), LLFilePicker::FFLOAD_DICTIONARY, false))->getFile(); +} - std::string filepath = file_picker.getFirstFile(); +void LLFloaterSpellCheckerImport::importSelectedDictionary(const std::vector<std::string>& filenames) +{ + std::string filepath = filenames[0]; const std::string extension = gDirUtilp->getExtension(filepath); if ("xcu" == extension) @@ -277,7 +277,7 @@ void LLFloaterSpellCheckerImport::onBtnBrowse() } getChild<LLUICtrl>("dictionary_path")->setValue(filepath); - + mDictionaryDir = gDirUtilp->getDirName(filepath); mDictionaryBasename = gDirUtilp->getBaseFileName(filepath, true); getChild<LLUICtrl>("dictionary_name")->setValue(mDictionaryBasename); diff --git a/indra/newview/llfloaterspellchecksettings.h b/indra/newview/llfloaterspellchecksettings.h index de59d83f24..f9bbefafb7 100644 --- a/indra/newview/llfloaterspellchecksettings.h +++ b/indra/newview/llfloaterspellchecksettings.h @@ -58,6 +58,7 @@ protected: void onBtnBrowse(); void onBtnCancel(); void onBtnOK(); + void importSelectedDictionary(const std::vector<std::string>& filenames); std::string parseXcuFile(const std::string& file_path) const; std::string mDictionaryDir; diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index c9d664c7c4..7fc60ddaac 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -253,7 +253,6 @@ BOOL LLFloaterTools::postBuild() mCheckStretchTexture = getChild<LLCheckBoxCtrl>("checkbox stretch textures"); getChild<LLUICtrl>("checkbox stretch textures")->setValue((BOOL)gSavedSettings.getBOOL("ScaleStretchTextures")); mComboGridMode = getChild<LLComboBox>("combobox grid mode"); - mCheckStretchUniformLabel = getChild<LLTextBox>("checkbox uniform label"); // // Create Buttons @@ -1214,7 +1213,7 @@ void LLFloaterTools::getMediaState() &&first_object->permModify() )) { - getChildView("Add_Media")->setEnabled(FALSE); + getChildView("add_media")->setEnabled(FALSE); media_info->clear(); clearMediaSettings(); return; @@ -1225,7 +1224,7 @@ void LLFloaterTools::getMediaState() if(!has_media_capability) { - getChildView("Add_Media")->setEnabled(FALSE); + getChildView("add_media")->setEnabled(FALSE); LL_WARNS("LLFloaterTools: media") << "Media not enabled (no capability) in this region!" << LL_ENDL; clearMediaSettings(); return; @@ -1320,7 +1319,7 @@ void LLFloaterTools::getMediaState() // update UI depending on whether "object" (prim or face) has media // and whether or not you are allowed to edit it. - getChildView("Add_Media")->setEnabled(editable); + getChildView("add_media")->setEnabled(editable); // IF all the faces have media (or all dont have media) if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo ) { @@ -1342,10 +1341,7 @@ void LLFloaterTools::getMediaState() media_title = multi_media_info_str; } - getChildView("media_tex")->setEnabled(bool_has_media && editable); - getChildView("edit_media")->setEnabled(bool_has_media && LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo && editable ); getChildView("delete_media")->setEnabled(bool_has_media && editable ); - getChildView("add_media")->setEnabled(editable); // TODO: display a list of all media on the face - use 'identical' flag } else // not all face has media but at least one does. @@ -1367,10 +1363,7 @@ void LLFloaterTools::getMediaState() } } - getChildView("media_tex")->setEnabled(TRUE); - getChildView("edit_media")->setEnabled(LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo); getChildView("delete_media")->setEnabled(TRUE); - getChildView("add_media")->setEnabled(editable); } navigateToTitleMedia(media_title); diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp index 8a8d92d459..3b17368445 100644 --- a/indra/newview/llfloaterwebcontent.cpp +++ b/indra/newview/llfloaterwebcontent.cpp @@ -105,6 +105,7 @@ BOOL LLFloaterWebContent::postBuild() // these buttons are always enabled mBtnReload->setEnabled( true ); + mBtnReload->setVisible( false ); getChildView("popexternal")->setEnabled( true ); // cache image for secure browsing diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index db1bc56fc5..491671c46f 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -593,45 +593,13 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, case IM_TYPING_START: { - std::vector<U8> bucket(binary_bucket[0], binary_bucket_size); - LLSD data; - data["binary_bucket"] = bucket; - LLPointer<LLIMInfo> im_info = new LLIMInfo(from_id, - from_group, - to_id, - dialog, - agentName, - message, - session_id, - parent_estate_id, - region_id, - position, - data, - offline, - timestamp); - gIMMgr->processIMTypingStart(im_info); + gIMMgr->processIMTypingStart(from_id, dialog); } break; case IM_TYPING_STOP: { - std::vector<U8> bucket(binary_bucket[0], binary_bucket_size); - LLSD data; - data["binary_bucket"] = bucket; - LLPointer<LLIMInfo> im_info = new LLIMInfo(from_id, - from_group, - to_id, - dialog, - agentName, - message, - session_id, - parent_estate_id, - region_id, - position, - data, - offline, - timestamp); - gIMMgr->processIMTypingStop(im_info); + gIMMgr->processIMTypingStop(from_id, dialog); } break; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index d62b6300cb..0f5d514660 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -3432,23 +3432,23 @@ void LLIMMgr::noteMutedUsers(const LLUUID& session_id, } } -void LLIMMgr::processIMTypingStart(const LLIMInfo* im_info) +void LLIMMgr::processIMTypingStart(const LLUUID& from_id, const EInstantMessage im_type) { - processIMTypingCore(im_info, TRUE); + processIMTypingCore(from_id, im_type, TRUE); } -void LLIMMgr::processIMTypingStop(const LLIMInfo* im_info) +void LLIMMgr::processIMTypingStop(const LLUUID& from_id, const EInstantMessage im_type) { - processIMTypingCore(im_info, FALSE); + processIMTypingCore(from_id, im_type, FALSE); } -void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing) +void LLIMMgr::processIMTypingCore(const LLUUID& from_id, const EInstantMessage im_type, BOOL typing) { - LLUUID session_id = computeSessionID(im_info->mIMType, im_info->mFromID); + LLUUID session_id = computeSessionID(im_type, from_id); LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id); if ( im_floater ) { - im_floater->processIMTyping(im_info, typing); + im_floater->processIMTyping(from_id, typing); } } diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index e3851a56e0..81d3ffa1a6 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -391,8 +391,8 @@ public: const std::string& session_handle = LLStringUtil::null, const std::string& session_uri = LLStringUtil::null); - void processIMTypingStart(const LLIMInfo* im_info); - void processIMTypingStop(const LLIMInfo* im_info); + void processIMTypingStart(const LLUUID& from_id, const EInstantMessage im_type); + void processIMTypingStop(const LLUUID& from_id, const EInstantMessage im_type); // automatically start a call once the session has initialized void autoStartCallOnStartup(const LLUUID& session_id); @@ -471,7 +471,7 @@ private: void noteOfflineUsers(const LLUUID& session_id, const std::vector<LLUUID>& ids); void noteMutedUsers(const LLUUID& session_id, const std::vector<LLUUID>& ids); - void processIMTypingCore(const LLIMInfo* im_info, BOOL typing); + void processIMTypingCore(const LLUUID& from_id, const EInstantMessage im_type, BOOL typing); static void onInviteNameLookup(LLSD payload, const LLUUID& id, const LLAvatarName& name); diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 1e15dc832c..88e7ad1b71 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -215,7 +215,9 @@ void LLInspectAvatar::onOpen(const LLSD& data) } // Generate link to avatar profile. - getChild<LLUICtrl>("avatar_profile_link")->setTextArg("[LINK]", LLSLURL("agent", mAvatarID, "about").getSLURLString()); + LLTextBase* avatar_profile_link = getChild<LLTextBase>("avatar_profile_link"); + avatar_profile_link->setTextArg("[LINK]", LLSLURL("agent", mAvatarID, "about").getSLURLString()); + avatar_profile_link->setIsFriendCallback(LLAvatarActions::isFriend); // can't call from constructor as widgets are not built yet requestUpdate(); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index b7b5185672..44a9d0bff4 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -783,6 +783,14 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, if (obj) { + + items.push_back(std::string("Copy Separator")); + items.push_back(std::string("Copy")); + if (!isItemCopyable()) + { + disabled_items.push_back(std::string("Copy")); + } + if (obj->getIsLinkType()) { items.push_back(std::string("Find Original")); @@ -825,13 +833,6 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, disabled_items.push_back(std::string("Copy Asset UUID")); } } - items.push_back(std::string("Copy Separator")); - - items.push_back(std::string("Copy")); - if (!isItemCopyable()) - { - disabled_items.push_back(std::string("Copy")); - } items.push_back(std::string("Cut")); if (!isItemMovable() || !isItemRemovable()) @@ -2116,12 +2117,6 @@ BOOL LLItemBridge::isItemCopyable() const return FALSE; } - // You can never copy a link. - if (item->getIsLinkType()) - { - return FALSE; - } - return item->getPermissions().allowCopyBy(gAgent.getID()) || gSavedSettings.getBOOL("InventoryLinking"); } return FALSE; @@ -3824,6 +3819,11 @@ void LLFolderBridge::perform_pasteFromClipboard() break; } } + else if (item->getIsLinkType()) + { + link_inventory_object(parent_id, item_id, + LLPointer<LLInventoryCallback>(NULL)); + } else { copy_inventory_item( diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index e056ccebee..030c967019 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -398,57 +398,66 @@ void copy_inventory_category(LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& parent_id, const LLUUID& root_copy_id, - bool move_no_copy_items ) + bool move_no_copy_items ) { // Create the initial folder - LLUUID new_cat_uuid = gInventory.createNewCategory(parent_id, LLFolderType::FT_NONE, cat->getName()); + inventory_func_type func = boost::bind(©_inventory_category_content, _1, model, cat, root_copy_id, move_no_copy_items); + gInventory.createNewCategory(parent_id, LLFolderType::FT_NONE, cat->getName(), func); +} + +void copy_inventory_category_content(const LLUUID& new_cat_uuid, LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& root_copy_id, bool move_no_copy_items) +{ model->notifyObservers(); - + // We need to exclude the initial root of the copy to avoid recursively copying the copy, etc... LLUUID root_id = (root_copy_id.isNull() ? new_cat_uuid : root_copy_id); // Get the content of the folder LLInventoryModel::cat_array_t* cat_array; LLInventoryModel::item_array_t* item_array; - gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array); - - // If root_copy_id is null, tell the marketplace model we'll be waiting for new items to be copied over for this folder - if (root_copy_id.isNull()) - { - LLMarketplaceData::instance().setValidationWaiting(root_id,count_descendants_items(cat->getUUID())); - } + gInventory.getDirectDescendentsOf(cat->getUUID(), cat_array, item_array); + + // If root_copy_id is null, tell the marketplace model we'll be waiting for new items to be copied over for this folder + if (root_copy_id.isNull()) + { + LLMarketplaceData::instance().setValidationWaiting(root_id, count_descendants_items(cat->getUUID())); + } // Copy all the items LLInventoryModel::item_array_t item_array_copy = *item_array; for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++) { LLInventoryItem* item = *iter; - LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(update_folder_cb, new_cat_uuid)); + LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(update_folder_cb, new_cat_uuid)); - if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) - { - // If the item is nocopy, we do nothing or, optionally, move it - if (move_no_copy_items) - { - // Reparent the item - LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) item; - gInventory.changeItemParent(viewer_inv_item, new_cat_uuid, true); - } - // Decrement the count in root_id since that one item won't be copied over - LLMarketplaceData::instance().decrementValidationWaiting(root_id); - } - else - { - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - new_cat_uuid, - std::string(), - cb); - } + if (item->getIsLinkType()) + { + link_inventory_object(new_cat_uuid, item->getLinkedUUID(), cb); + } + else if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + // If the item is nocopy, we do nothing or, optionally, move it + if (move_no_copy_items) + { + // Reparent the item + LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *)item; + gInventory.changeItemParent(viewer_inv_item, new_cat_uuid, true); + } + // Decrement the count in root_id since that one item won't be copied over + LLMarketplaceData::instance().decrementValidationWaiting(root_id); + } + else + { + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + new_cat_uuid, + std::string(), + cb); + } } - + // Copy all the folders LLInventoryModel::cat_array_t cat_array_copy = *cat_array; for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index d454d7e00b..fd106bc2d8 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -72,6 +72,8 @@ void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::s void copy_inventory_category(LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& parent_id, const LLUUID& root_copy_id = LLUUID::null, bool move_no_copy_items = false); +void copy_inventory_category_content(const LLUUID& new_cat_uuid, LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& root_copy_id, bool move_no_copy_items); + // Generates a string containing the path to the item specified by item_id. void append_path(const LLUUID& id, std::string& path); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 678fdbef35..cef6528724 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -925,7 +925,20 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask) new_item = old_item; LLUUID old_parent_id = old_item->getParentUUID(); LLUUID new_parent_id = item->getParentUUID(); - + bool update_parent_on_server = false; + + if (new_parent_id.isNull()) + { + // item with null parent will end in random location and then in Lost&Found, + // either move to default folder as if it is new item or don't move at all + LL_WARNS(LOG_INV) << "Update attempts to reparent item " << item->getUUID() + << " to null folder. Moving to Lost&Found. Old item name: " << old_item->getName() + << ". New name: " << item->getName() + << "." << LL_ENDL; + new_parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); + update_parent_on_server = true; + } + if(old_parent_id != new_parent_id) { // need to update the parent-child tree @@ -938,6 +951,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask) item_array = get_ptr_in_map(mParentChildItemTree, new_parent_id); if(item_array) { + if (update_parent_on_server) + { + LLInventoryModel::LLCategoryUpdate update(new_parent_id, 1); + gInventory.accountForUpdate(update); + } item_array->push_back(old_item); } mask |= LLInventoryObserver::STRUCTURE; @@ -947,6 +965,12 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask) mask |= LLInventoryObserver::LABEL; } old_item->copyViewerItem(item); + if (update_parent_on_server) + { + // Parent id at server is null, so update server even if item already is in the same folder + old_item->setParent(new_parent_id); + new_item->updateParentOnServer(FALSE); + } mask |= LLInventoryObserver::INTERNAL; } else @@ -2820,7 +2844,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32 item_array_t items; update_map_t update; S32 count = msg->getNumberOfBlocksFast(_PREHASH_InventoryData); - LLUUID folder_id; // Does this loop ever execute more than once? for(S32 i = 0; i < count; ++i) { @@ -2847,10 +2870,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32 { ++update[titem->getParentUUID()]; } - if (folder_id.isNull()) - { - folder_id = titem->getParentUUID(); - } } if(account) { diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 2464e650e1..46ae200a1c 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -1453,14 +1453,16 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open) //static void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const LLUUID& obj_id, BOOL main_panel, BOOL take_keyboard_focus, BOOL reset_filter) { - LLInventoryPanel *active_panel; + LLSidepanelInventory* sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); + sidepanel_inventory->showInventoryPanel(); + bool in_inbox = (gInventory.isObjectDescendentOf(obj_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX))); if (main_panel && !in_inbox) { - LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory")->selectAllItemsPanel(); + sidepanel_inventory->selectAllItemsPanel(); } - active_panel = LLInventoryPanel::getActiveInventoryPanel(auto_open); + LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(auto_open); if (active_panel) { @@ -1473,7 +1475,7 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L if (in_inbox) { - LLSidepanelInventory * sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); + LLInventoryPanel * inventory_panel = NULL; sidepanel_inventory->openInbox(); inventory_panel = sidepanel_inventory->getInboxPanel(); diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp index bd8f464acd..bc45eb6d3a 100644 --- a/indra/newview/llmediadataclient.cpp +++ b/indra/newview/llmediadataclient.cpp @@ -27,6 +27,7 @@ #include "llviewerprecompiledheaders.h" #include "llmediadataclient.h" +#include "llviewercontrol.h" #if LL_MSVC // disable boost::lexical_cast warning @@ -718,6 +719,13 @@ bool LLObjectMediaDataClient::compareRequestScores(const Request::ptr_t &o1, con void LLObjectMediaDataClient::enqueue(Request::ptr_t request) { + static LLCachedControl<bool> audio_streaming_enabled(gSavedSettings, "AudioStreamingMedia", true); + if (!audio_streaming_enabled) + { + LL_DEBUGS("LLMediaDataClient") << "not queueing request when Media is disabled " << *request << LL_ENDL; + return; + } + if(request->isDead()) { LL_DEBUGS("LLMediaDataClient") << "not queueing dead request " << *request << LL_ENDL; @@ -978,6 +986,13 @@ const char *LLObjectMediaNavigateClient::getCapabilityName() const void LLObjectMediaNavigateClient::enqueue(Request::ptr_t request) { + static LLCachedControl<bool> audio_streaming_enabled(gSavedSettings, "AudioStreamingMedia", true); + if (!audio_streaming_enabled) + { + LL_DEBUGS("LLMediaDataClient") << "not queueing request when Media is disabled " << *request << LL_ENDL; + return; + } + if(request->isDead()) { LL_DEBUGS("LLMediaDataClient") << "not queuing dead request " << *request << LL_ENDL; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 0af6cfc6f9..d0ef9dd326 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -353,6 +353,9 @@ const U32 LARGE_MESH_FETCH_THRESHOLD = 1U << 21; // Size at which requests goes const long SMALL_MESH_XFER_TIMEOUT = 120L; // Seconds to complete xfer, small mesh downloads const long LARGE_MESH_XFER_TIMEOUT = 600L; // Seconds to complete xfer, large downloads +const U32 DOWNLOAD_RETRY_LIMIT = 8; +const F32 DOWNLOAD_RETRY_DELAY = 0.5f; // seconds + // Would normally like to retry on uploads as some // retryable failures would be recoverable. Unfortunately, // the mesh service is using 500 (retryable) rather than @@ -516,6 +519,24 @@ void get_vertex_buffer_from_mesh(LLCDMeshData& mesh, LLModel::PhysicsMesh& res, } } +void RequestStats::updateTime() +{ + U32 modifier = 1 << mRetries; // before ++ + mRetries++; + mTimer.reset(); + mTimer.setTimerExpirySec(DOWNLOAD_RETRY_DELAY * (F32)modifier); // up to 32s, 64 total wait +} + +bool RequestStats::canRetry() const +{ + return mRetries < DOWNLOAD_RETRY_LIMIT; +} + +bool RequestStats::isDelayed() const +{ + return mTimer.getStarted() && !mTimer.hasExpired(); +} + LLViewerFetchedTexture* LLMeshUploadThread::FindViewerTexture(const LLImportMaterial& material) { LLPointer< LLViewerFetchedTexture > * ppTex = static_cast< LLPointer< LLViewerFetchedTexture > * >(material.mOpaqueData); @@ -890,141 +911,225 @@ void LLMeshRepoThread::run() sRequestWaterLevel = mHttpRequestSet.size(); // Stats data update // NOTE: order of queue processing intentionally favors LOD requests over header requests + // Todo: we are processing mLODReqQ, mHeaderReqQ, mSkinRequests, mDecompositionRequests and mPhysicsShapeRequests + // in relatively similar manners, remake code to simplify/unify the process, + // like processRequests(&requestQ, fetchFunction); which does same thing for each element - while (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater) - { - if (! mMutex) - { - break; - } - mMutex->lock(); - LODRequest req = mLODReqQ.front(); - mLODReqQ.pop(); - LLMeshRepository::sLODProcessing--; - mMutex->unlock(); - - if (!fetchMeshLOD(req.mMeshParams, req.mLOD)) // failed, resubmit - { - mMutex->lock(); - mLODReqQ.push(req); - ++LLMeshRepository::sLODProcessing; - mMutex->unlock(); - } - } - - while (!mHeaderReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater) - { - if (! mMutex) - { - break; - } - mMutex->lock(); - HeaderRequest req = mHeaderReqQ.front(); - mHeaderReqQ.pop(); - mMutex->unlock(); - if (!fetchMeshHeader(req.mMeshParams))//failed, resubmit - { - mMutex->lock(); - mHeaderReqQ.push(req) ; - mMutex->unlock(); - } - } - - // For the final three request lists, similar goal to above but - // slightly different queue structures. Stay off the mutex when - // performing long-duration actions. - - if (mHttpRequestSet.size() < sRequestHighWater - && (! mSkinRequests.empty() - || ! mDecompositionRequests.empty() - || ! mPhysicsShapeRequests.empty())) - { - // Something to do probably, lock and double-check. We don't want - // to hold the lock long here. That will stall main thread activities - // so we bounce it. - - mMutex->lock(); - if (! mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) - { - std::set<LLUUID> incomplete; - std::set<LLUUID>::iterator iter(mSkinRequests.begin()); - while (iter != mSkinRequests.end() && mHttpRequestSet.size() < sRequestHighWater) - { - LLUUID mesh_id = *iter; - mSkinRequests.erase(iter); - mMutex->unlock(); - - if (! fetchMeshSkinInfo(mesh_id)) - { - incomplete.insert(mesh_id); - } + if (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater) + { + std::list<LODRequest> incomplete; + while (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater) + { + if (!mMutex) + { + break; + } + + mMutex->lock(); + LODRequest req = mLODReqQ.front(); + mLODReqQ.pop(); + LLMeshRepository::sLODProcessing--; + mMutex->unlock(); + if (req.isDelayed()) + { + // failed to load before, wait a bit + incomplete.push_front(req); + } + else if (!fetchMeshLOD(req.mMeshParams, req.mLOD, req.canRetry())) + { + if (req.canRetry()) + { + // failed, resubmit + req.updateTime(); + incomplete.push_front(req); + } + else + { + // too many fails + mUnavailableQ.push(req); + LL_WARNS() << "Failed to load " << req.mMeshParams << " , skip" << LL_ENDL; + } + } + } - mMutex->lock(); - iter = mSkinRequests.begin(); - } + if (!incomplete.empty()) + { + LLMutexLock locker(mMutex); + for (std::list<LODRequest>::iterator iter = incomplete.begin(); iter != incomplete.end(); iter++) + { + mLODReqQ.push(*iter); + ++LLMeshRepository::sLODProcessing; + } + } + } - if (! incomplete.empty()) - { - mSkinRequests.insert(incomplete.begin(), incomplete.end()); - } - } + if (!mHeaderReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater) + { + std::list<HeaderRequest> incomplete; + while (!mHeaderReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater) + { + if (!mMutex) + { + break; + } + + mMutex->lock(); + HeaderRequest req = mHeaderReqQ.front(); + mHeaderReqQ.pop(); + mMutex->unlock(); + if (req.isDelayed()) + { + // failed to load before, wait a bit + incomplete.push_front(req); + } + else if (!fetchMeshHeader(req.mMeshParams, req.canRetry())) + { + if (req.canRetry()) + { + //failed, resubmit + req.updateTime(); + incomplete.push_front(req); + } + else + { + LL_DEBUGS() << "mHeaderReqQ failed: " << req.mMeshParams << LL_ENDL; + } + } + } - // holding lock, try next list - // *TODO: For UI/debug-oriented lists, we might drop the fine- - // grained locking as there's a lowered expectation of smoothness - // in these cases. - if (! mDecompositionRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) - { - std::set<LLUUID> incomplete; - std::set<LLUUID>::iterator iter(mDecompositionRequests.begin()); - while (iter != mDecompositionRequests.end() && mHttpRequestSet.size() < sRequestHighWater) - { - LLUUID mesh_id = *iter; - mDecompositionRequests.erase(iter); - mMutex->unlock(); - - if (! fetchMeshDecomposition(mesh_id)) - { - incomplete.insert(mesh_id); - } + if (!incomplete.empty()) + { + LLMutexLock locker(mMutex); + for (std::list<HeaderRequest>::iterator iter = incomplete.begin(); iter != incomplete.end(); iter++) + { + mHeaderReqQ.push(*iter); + } + } + } - mMutex->lock(); - iter = mDecompositionRequests.begin(); - } + // For the final three request lists, similar goal to above but + // slightly different queue structures. Stay off the mutex when + // performing long-duration actions. - if (! incomplete.empty()) - { - mDecompositionRequests.insert(incomplete.begin(), incomplete.end()); - } - } + if (mHttpRequestSet.size() < sRequestHighWater + && (!mSkinRequests.empty() + || !mDecompositionRequests.empty() + || !mPhysicsShapeRequests.empty())) + { + // Something to do probably, lock and double-check. We don't want + // to hold the lock long here. That will stall main thread activities + // so we bounce it. - // holding lock, final list - if (! mPhysicsShapeRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) - { - std::set<LLUUID> incomplete; - std::set<LLUUID>::iterator iter(mPhysicsShapeRequests.begin()); - while (iter != mPhysicsShapeRequests.end() && mHttpRequestSet.size() < sRequestHighWater) - { - LLUUID mesh_id = *iter; - mPhysicsShapeRequests.erase(iter); - mMutex->unlock(); - - if (! fetchMeshPhysicsShape(mesh_id)) - { - incomplete.insert(mesh_id); - } + if (!mSkinRequests.empty()) + { + std::set<UUIDBasedRequest> incomplete; + while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) + { + mMutex->lock(); + std::set<UUIDBasedRequest>::iterator iter = mSkinRequests.begin(); + UUIDBasedRequest req = *iter; + mSkinRequests.erase(iter); + mMutex->unlock(); + if (req.isDelayed()) + { + incomplete.insert(req); + } + else if (!fetchMeshSkinInfo(req.mId)) + { + if (req.canRetry()) + { + req.updateTime(); + incomplete.insert(req); + } + else + { + LL_DEBUGS() << "mSkinRequests failed: " << req.mId << LL_ENDL; + } + } + } + + if (!incomplete.empty()) + { + LLMutexLock locker(mMutex); + mSkinRequests.insert(incomplete.begin(), incomplete.end()); + } + } - mMutex->lock(); - iter = mPhysicsShapeRequests.begin(); - } + // holding lock, try next list + // *TODO: For UI/debug-oriented lists, we might drop the fine- + // grained locking as there's a lowered expectation of smoothness + // in these cases. + if (!mDecompositionRequests.empty()) + { + std::set<UUIDBasedRequest> incomplete; + while (!mDecompositionRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) + { + mMutex->lock(); + std::set<UUIDBasedRequest>::iterator iter = mDecompositionRequests.begin(); + UUIDBasedRequest req = *iter; + mDecompositionRequests.erase(iter); + mMutex->unlock(); + if (req.isDelayed()) + { + incomplete.insert(req); + } + else if (!fetchMeshDecomposition(req.mId)) + { + if (req.canRetry()) + { + req.updateTime(); + incomplete.insert(req); + } + else + { + LL_DEBUGS() << "mDecompositionRequests failed: " << req.mId << LL_ENDL; + } + } + } + + if (!incomplete.empty()) + { + LLMutexLock locker(mMutex); + mDecompositionRequests.insert(incomplete.begin(), incomplete.end()); + } + } - if (! incomplete.empty()) - { - mPhysicsShapeRequests.insert(incomplete.begin(), incomplete.end()); - } - } - mMutex->unlock(); - } + // holding lock, final list + if (!mPhysicsShapeRequests.empty()) + { + std::set<UUIDBasedRequest> incomplete; + while (!mPhysicsShapeRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) + { + mMutex->lock(); + std::set<UUIDBasedRequest>::iterator iter = mPhysicsShapeRequests.begin(); + UUIDBasedRequest req = *iter; + mPhysicsShapeRequests.erase(iter); + mMutex->unlock(); + if (req.isDelayed()) + { + incomplete.insert(req); + } + else if (!fetchMeshPhysicsShape(req.mId)) + { + if (req.canRetry()) + { + req.updateTime(); + incomplete.insert(req); + } + else + { + LL_DEBUGS() << "mPhysicsShapeRequests failed: " << req.mId << LL_ENDL; + } + } + } + + if (!incomplete.empty()) + { + LLMutexLock locker(mMutex); + mPhysicsShapeRequests.insert(incomplete.begin(), incomplete.end()); + } + } + } // For dev purposes only. A dynamic change could make this false // and that shouldn't assert. @@ -1046,19 +1151,19 @@ void LLMeshRepoThread::run() // Mutex: LLMeshRepoThread::mMutex must be held on entry void LLMeshRepoThread::loadMeshSkinInfo(const LLUUID& mesh_id) { - mSkinRequests.insert(mesh_id); + mSkinRequests.insert(UUIDBasedRequest(mesh_id)); } // Mutex: LLMeshRepoThread::mMutex must be held on entry void LLMeshRepoThread::loadMeshDecomposition(const LLUUID& mesh_id) { - mDecompositionRequests.insert(mesh_id); + mDecompositionRequests.insert(UUIDBasedRequest(mesh_id)); } // Mutex: LLMeshRepoThread::mMutex must be held on entry void LLMeshRepoThread::loadMeshPhysicsShape(const LLUUID& mesh_id) { - mPhysicsShapeRequests.insert(mesh_id); + mPhysicsShapeRequests.insert(UUIDBasedRequest(mesh_id)); } void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) @@ -1234,16 +1339,16 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) //check VFS for mesh skin info LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); if (file.getSize() >= offset+size) - { - LLMeshRepository::sCacheBytesRead += size; - ++LLMeshRepository::sCacheReads; - file.seek(offset); + { U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS(LOG_MESH) << "Failed to allocate memory for skin info" << LL_ENDL; + LL_WARNS_ONCE(LOG_MESH) << "Failed to allocate memory for skin info, size: " << size << LL_ENDL; return false; } + LLMeshRepository::sCacheBytesRead += size; + ++LLMeshRepository::sCacheReads; + file.seek(offset); file.read(buffer, size); //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) @@ -1331,16 +1436,16 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); if (file.getSize() >= offset+size) { - LLMeshRepository::sCacheBytesRead += size; - ++LLMeshRepository::sCacheReads; - - file.seek(offset); U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS(LOG_MESH) << "Failed to allocate memory for mesh decomposition" << LL_ENDL; + LL_WARNS_ONCE(LOG_MESH) << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL; return false; } + LLMeshRepository::sCacheBytesRead += size; + ++LLMeshRepository::sCacheReads; + + file.seek(offset); file.read(buffer, size); //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) @@ -1434,7 +1539,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS(LOG_MESH) << "Failed to allocate memory for physics shape" << LL_ENDL; + LL_WARNS_ONCE(LOG_MESH) << "Failed to allocate memory for physics shape, size: " << size << LL_ENDL; return false; } file.read(buffer, size); @@ -1524,7 +1629,7 @@ void LLMeshRepoThread::decActiveHeaderRequests() } //return false if failed to get header -bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params) +bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, bool can_retry) { ++LLMeshRepository::sMeshRequestCount; @@ -1571,7 +1676,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params) << LL_ENDL; retval = false; } - else + else if (can_retry) { handler->mHttpHandle = handle; mHttpRequestSet.insert(handler); @@ -1582,7 +1687,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params) } //return false if failed to get mesh lod. -bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) +bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, bool can_retry) { if (!mHeaderMutex) { @@ -1612,15 +1717,17 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); if (file.getSize() >= offset+size) { - LLMeshRepository::sCacheBytesRead += size; - ++LLMeshRepository::sCacheReads; - file.seek(offset); U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS(LOG_MESH) << "Can't allocate memory for mesh LOD" << LL_ENDL; + LL_WARNS_ONCE(LOG_MESH) << "Can't allocate memory for mesh " << mesh_id << " LOD " << lod << ", size: " << size << LL_ENDL; + // todo: for now it will result in indefinite constant retries, should result in timeout + // or in retry-count and disabling mesh. (but usually viewer is beyond saving at this point) return false; } + LLMeshRepository::sCacheBytesRead += size; + ++LLMeshRepository::sCacheReads; + file.seek(offset); file.read(buffer, size); //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) @@ -1658,12 +1765,16 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) << LL_ENDL; retval = false; } - else + else if (can_retry) { handler->mHttpHandle = handle; mHttpRequestSet.insert(handler); // *NOTE: Allowing a re-request, not marking as unavailable. Is that correct? } + else + { + mUnavailableQ.push(LODRequest(mesh_params, lod)); + } } else { diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index e07a00bf03..22215c784a 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -177,6 +177,21 @@ public: }; +class RequestStats +{ +public: + RequestStats() : mRetries(0) {}; + + void updateTime(); + bool canRetry() const; + bool isDelayed() const; + U32 getRetries() { return mRetries; } + +private: + U32 mRetries; + LLFrameTimer mTimer; +}; + class LLMeshRepoThread : public LLThread { public: @@ -197,14 +212,14 @@ public: mesh_header_map mMeshHeader; std::map<LLUUID, U32> mMeshHeaderSize; - - class HeaderRequest + + class HeaderRequest : public RequestStats { public: const LLVolumeParams mMeshParams; HeaderRequest(const LLVolumeParams& mesh_params) - : mMeshParams(mesh_params) + : RequestStats(), mMeshParams(mesh_params) { } @@ -214,7 +229,7 @@ public: } }; - class LODRequest + class LODRequest : public RequestStats { public: LLVolumeParams mMeshParams; @@ -222,7 +237,7 @@ public: F32 mScore; LODRequest(const LLVolumeParams& mesh_params, S32 lod) - : mMeshParams(mesh_params), mLOD(lod), mScore(0.f) + : RequestStats(), mMeshParams(mesh_params), mLOD(lod), mScore(0.f) { } }; @@ -234,7 +249,22 @@ public: return lhs.mScore > rhs.mScore; // greatest = first } }; - + + class UUIDBasedRequest : public RequestStats + { + public: + LLUUID mId; + + UUIDBasedRequest(const LLUUID& id) + : RequestStats(), mId(id) + { + } + + bool operator<(const UUIDBasedRequest& rhs) const + { + return mId < rhs.mId; + } + }; class LoadedMesh { @@ -251,16 +281,16 @@ public: }; //set of requested skin info - std::set<LLUUID> mSkinRequests; + std::set<UUIDBasedRequest> mSkinRequests; // list of completed skin info requests std::list<LLMeshSkinInfo> mSkinInfoQ; //set of requested decompositions - std::set<LLUUID> mDecompositionRequests; + std::set<UUIDBasedRequest> mDecompositionRequests; //set of requested physics shapes - std::set<LLUUID> mPhysicsShapeRequests; + std::set<UUIDBasedRequest> mPhysicsShapeRequests; // list of completed Decomposition info requests std::list<LLModel::Decomposition*> mDecompositionQ; @@ -304,8 +334,8 @@ public: void lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod); void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod); - bool fetchMeshHeader(const LLVolumeParams& mesh_params); - bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod); + bool fetchMeshHeader(const LLVolumeParams& mesh_params, bool can_retry = true); + bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, bool can_retry = true); bool headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size); EMeshProcessingResult lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size); bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size); diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index c03080beb8..301487b994 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -716,9 +716,9 @@ void LLPanelStandStopFlying::updatePosition() left_tb_width = toolbar_left->getRect().getWidth(); } - if (!mStateManagementButtons.get()) + if (!mStateManagementButtons.get()) // Obsolete?!! { - LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("state_management_buttons_container"); + LLPanel* panel_ssf_container = gToolBarView->getChild<LLPanel>("state_management_buttons_container"); if (panel_ssf_container) { mStateManagementButtons = panel_ssf_container->getHandle(); diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 84a2cd8be1..cfe2e6bf6a 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -443,6 +443,7 @@ void LLNavigationBar::onLocationSelection() { gAgent.teleportViaLandmark( LLUUID(value["AssetUUID"].asString())); + mSaveToLocationHistory = true; return; } else @@ -453,6 +454,7 @@ void LLNavigationBar::onLocationSelection() if (!landmark_items.empty()) { gAgent.teleportViaLandmark( landmark_items[0]->getAssetUUID()); + mSaveToLocationHistory = true; return; } } diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp index cbcf9cac9c..f2de8e54a0 100644 --- a/indra/newview/llnotificationlistitem.cpp +++ b/indra/newview/llnotificationlistitem.cpp @@ -288,9 +288,7 @@ BOOL LLGroupInviteNotificationListItem::postBuild() //invitation with any non-default group role, doesn't have newline characters at the end unlike simple invitations std::string invitation_desc = mNoticeTextExp->getValue().asString(); - boost::regex pattern = boost::regex("\n\n$", boost::regex::perl|boost::regex::icase); - boost::match_results<std::string::const_iterator> matches; - if(!boost::regex_search(invitation_desc, matches, pattern)) + if (invitation_desc.substr(invitation_desc.size() - 2) != "\n\n") { invitation_desc += "\n\n"; mNoticeTextExp->setValue(invitation_desc); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 7e75dca908..01ce4470f0 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1165,16 +1165,6 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) getChild<LLUICtrl>("combobox texgen")->setTentative(!identical); getChildView("tex gen")->setEnabled(editable); - if (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR) - { - // EXP-1507 (change label based on the mapping mode) - getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per meter")); - } - else - if (selected_texgen == LLTextureEntry::TEX_GEN_DEFAULT) - { - getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per face")); - } } { @@ -1390,8 +1380,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) mColorSwatch->setValid(FALSE); } getChildView("color trans")->setEnabled(FALSE); - getChildView("rpt")->setEnabled(FALSE); - getChildView("tex offset")->setEnabled(FALSE); + getChildView("rptctrl")->setEnabled(FALSE); getChildView("tex gen")->setEnabled(FALSE); getChildView("label shininess")->setEnabled(FALSE); getChildView("label bumpiness")->setEnabled(FALSE); diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 342b57ba4a..e41211ddbd 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -159,9 +159,6 @@ BOOL LLPanelGroup::postBuild() button = getChild<LLButton>("btn_chat"); button->setClickedCallback(onBtnGroupChatClicked, this); - button = getChild<LLButton>("btn_cancel"); - button->setVisible(false); button->setEnabled(true); - button = getChild<LLButton>("btn_refresh"); button->setClickedCallback(onBtnRefresh, this); @@ -170,8 +167,6 @@ BOOL LLPanelGroup::postBuild() childSetCommitCallback("back",boost::bind(&LLPanelGroup::onBackBtnClick,this),NULL); childSetCommitCallback("btn_create",boost::bind(&LLPanelGroup::onBtnCreate,this),NULL); - - childSetCommitCallback("btn_cancel",boost::bind(&LLPanelGroup::onBtnCancel,this),NULL); LLPanelGroupTab* panel_general = findChild<LLPanelGroupTab>("group_general_tab_panel"); LLPanelGroupTab* panel_roles = findChild<LLPanelGroupTab>("group_roles_tab_panel"); @@ -299,11 +294,6 @@ void LLPanelGroup::onBtnJoin() LLGroupActions::join(mID); } -void LLPanelGroup::onBtnCancel() -{ - onBackBtnClick(); -} - void LLPanelGroup::changed(LLGroupChange gc) { for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it) diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index 05be4b5aee..0b40c8b5d3 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -95,7 +95,6 @@ protected: void onBtnCreate(); void onBackBtnClick(); void onBtnJoin(); - void onBtnCancel(); static void onBtnApply(void*); static void onBtnRefresh(void*); diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index d17f5494a0..f85a2ffbc1 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -194,6 +194,7 @@ void LLPanelGroupGeneral::setupCtrls(LLPanel* panel_group) if (mInsignia) { mInsignia->setCommitCallback(onCommitAny, this); + mInsignia->setAllowLocalTexture(FALSE); } mFounderName = getChild<LLTextBox>("founder_name"); diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 8cd8079c11..46603bf4d4 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -576,6 +576,7 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg) mNoticesList->setNeedsSort(save_sort); mNoticesList->updateSort(); + mNoticesList->selectFirstItem(); } void LLPanelGroupNotices::onSelectNotice(LLUICtrl* ctrl, void* data) diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 66a0a1d4ad..087e0a0759 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -465,12 +465,12 @@ BOOL LLPanelGroupSubTab::postBuild() { // Hook up the search widgets. bool recurse = true; - mSearchEditor = getChild<LLFilterEditor>("filter_input", recurse); - if (!mSearchEditor) - return FALSE; - - mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::setSearchFilter, this, _2)); + mSearchEditor = findChild<LLFilterEditor>("filter_input", recurse); + if (mSearchEditor) // SubTab doesn't implement this, only some of derived classes + { + mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::setSearchFilter, this, _2)); + } return LLPanelGroupTab::postBuild(); } @@ -815,14 +815,18 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root) // Look recursively from the parent to find all our widgets. bool recurse = true; - mHeader = parent->getChild<LLPanel>("members_header", recurse); - mFooter = parent->getChild<LLPanel>("members_footer", recurse); + mHeader = parent->findChild<LLPanel>("members_header", recurse); + mFooter = parent->findChild<LLPanel>("members_footer", recurse); mMembersList = parent->getChild<LLNameListCtrl>("member_list", recurse); mAssignedRolesList = parent->getChild<LLScrollListCtrl>("member_assigned_roles", recurse); mAllowedActionsList = parent->getChild<LLScrollListCtrl>("member_allowed_actions", recurse); + mActionDescription = parent->getChild<LLTextEditor>("member_action_description", recurse); - if (!mMembersList || !mAssignedRolesList || !mAllowedActionsList) return FALSE; + if (!mMembersList || !mAssignedRolesList || !mAllowedActionsList || !mActionDescription) return FALSE; + + mAllowedActionsList->setCommitOnSelectionChange(TRUE); + mAllowedActionsList->setCommitCallback(boost::bind(&LLPanelGroupMembersSubTab::updateActionDescription, this)); // We want to be notified whenever a member is selected. mMembersList->setCommitOnSelectionChange(TRUE); @@ -889,6 +893,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() mAssignedRolesList->deleteAllItems(); mAllowedActionsList->deleteAllItems(); + mActionDescription->clear(); LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); if (!gdatap) @@ -1386,6 +1391,7 @@ void LLPanelGroupMembersSubTab::activate() update(GC_MEMBER_DATA); } } + mActionDescription->clear(); } void LLPanelGroupMembersSubTab::deactivate() @@ -1894,6 +1900,23 @@ bool LLPanelGroupMembersSubTab::handleBanCallback(const LLSD& notification, cons return false; } +void LLPanelGroupMembersSubTab::updateActionDescription() +{ + mActionDescription->setText(std::string()); + LLScrollListItem* action_item = mAllowedActionsList->getFirstSelected(); + if (!action_item || !mAllowedActionsList->getCanSelect()) + { + return; + } + + LLRoleAction* rap = (LLRoleAction*)action_item->getUserdata(); + if (rap) + { + std::string desc = rap->mLongDescription.empty() ? rap->mDescription : rap->mLongDescription; + mActionDescription->setText(desc); + } +} + void LLPanelGroupMembersSubTab::handleBanMember() { LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); @@ -1957,13 +1980,14 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root) // Look recursively from the parent to find all our widgets. bool recurse = true; - mHeader = parent->getChild<LLPanel>("roles_header", recurse); - mFooter = parent->getChild<LLPanel>("roles_footer", recurse); + mHeader = parent->findChild<LLPanel>("roles_header", recurse); + mFooter = parent->findChild<LLPanel>("roles_footer", recurse); mRolesList = parent->getChild<LLScrollListCtrl>("role_list", recurse); mAssignedMembersList = parent->getChild<LLNameListCtrl>("role_assigned_members", recurse); mAllowedActionsList = parent->getChild<LLScrollListCtrl>("role_allowed_actions", recurse); + mActionDescription = parent->getChild<LLTextEditor>("role_action_description", recurse); mRoleName = parent->getChild<LLLineEditor>("role_name", recurse); mRoleTitle = parent->getChild<LLLineEditor>("role_title", recurse); @@ -1971,7 +1995,7 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root) mMemberVisibleCheck = parent->getChild<LLCheckBoxCtrl>("role_visible_in_list", recurse); - if (!mRolesList || !mAssignedMembersList || !mAllowedActionsList + if (!mRolesList || !mAssignedMembersList || !mAllowedActionsList || !mActionDescription || !mRoleName || !mRoleTitle || !mRoleDescription || !mMemberVisibleCheck) { LL_WARNS() << "ARG! element not found." << LL_ENDL; @@ -2004,6 +2028,7 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root) mMemberVisibleCheck->setCommitCallback(onMemberVisibilityChange, this); mAllowedActionsList->setCommitOnSelectionChange(TRUE); + mAllowedActionsList->setCommitCallback(boost::bind(&LLPanelGroupRolesSubTab::updateActionDescription, this)); mRoleName->setCommitOnFocusLost(TRUE); mRoleName->setKeystrokeCallback(onPropertiesKey, this); @@ -2023,6 +2048,7 @@ void LLPanelGroupRolesSubTab::activate() { LLPanelGroupSubTab::activate(); + mActionDescription->clear(); mRolesList->deselectAllItems(); mAssignedMembersList->deleteAllItems(); mAllowedActionsList->deleteAllItems(); @@ -2707,6 +2733,23 @@ void LLPanelGroupRolesSubTab::saveRoleChanges(bool select_saved_role) } } +void LLPanelGroupRolesSubTab::updateActionDescription() +{ + mActionDescription->setText(std::string()); + LLScrollListItem* action_item = mAllowedActionsList->getFirstSelected(); + if (!action_item || !mAllowedActionsList->getCanSelect()) + { + return; + } + + LLRoleAction* rap = (LLRoleAction*)action_item->getUserdata(); + if (rap) + { + std::string desc = rap->mLongDescription.empty() ? rap->mDescription : rap->mLongDescription; + mActionDescription->setText(desc); + } +} + void LLPanelGroupRolesSubTab::setGroupID(const LLUUID& id) { if(mRolesList) mRolesList->deleteAllItems(); @@ -2746,8 +2789,8 @@ BOOL LLPanelGroupActionsSubTab::postBuildSubTab(LLView* root) // Look recursively from the parent to find all our widgets. bool recurse = true; - mHeader = parent->getChild<LLPanel>("actions_header", recurse); - mFooter = parent->getChild<LLPanel>("actions_footer", recurse); + mHeader = parent->findChild<LLPanel>("actions_header", recurse); + mFooter = parent->findChild<LLPanel>("actions_footer", recurse); mActionDescription = parent->getChild<LLTextEditor>("action_description", recurse); @@ -2953,10 +2996,10 @@ BOOL LLPanelGroupBanListSubTab::postBuildSubTab(LLView* root) // Look recursively from the parent to find all our widgets. bool recurse = true; - - mHeader = parent->getChild<LLPanel>("banlist_header", recurse); - mFooter = parent->getChild<LLPanel>("banlist_footer", recurse); - + + mHeader = parent->findChild<LLPanel>("banlist_header", recurse); + mFooter = parent->findChild<LLPanel>("banlist_footer", recurse); + mBanList = parent->getChild<LLNameListCtrl>("ban_list", recurse); mCreateBanButton = parent->getChild<LLButton>("ban_create", recurse); diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index 1d1d69e0ae..aafbd242cb 100644 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -132,7 +132,7 @@ protected: BOOL is_owner_role); protected: - LLPanel* mHeader; + LLPanel* mHeader; // Might not be present in xui of derived class (NULL) LLPanel* mFooter; LLFilterEditor* mSearchEditor; @@ -182,6 +182,7 @@ public: bool handleBanCallback(const LLSD& notification, const LLSD& response); void confirmBanMembers(); + void updateActionDescription(); void applyMemberChanges(); bool addOwnerCB(const LLSD& notification, const LLSD& response); @@ -222,6 +223,8 @@ protected: BOOL mPendingMemberUpdate; BOOL mHasMatch; + LLTextEditor* mActionDescription; + member_role_changes_map_t mMemberRoleChangeData; U32 mNumOwnerAdditions; @@ -269,6 +272,8 @@ public: static void onDeleteRole(void*); void handleDeleteRole(); + void updateActionDescription(); + void saveRoleChanges(bool select_saved_role); virtual void setGroupID(const LLUUID& id); @@ -282,6 +287,7 @@ protected: LLScrollListCtrl* mRolesList; LLNameListCtrl* mAssignedMembersList; LLScrollListCtrl* mAllowedActionsList; + LLTextEditor* mActionDescription; LLLineEditor* mRoleName; LLLineEditor* mRoleTitle; diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index c876c1c149..ef5ce155b1 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -271,9 +271,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, LLTextBox* forgot_password_text = getChild<LLTextBox>("forgot_password_text"); forgot_password_text->setClickedCallback(onClickForgotPassword, NULL); - LLTextBox* need_help_text = getChild<LLTextBox>("login_help"); - need_help_text->setClickedCallback(onClickHelp, NULL); - // get the web browser control LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html"); web_browser->addObserver(this); @@ -284,6 +281,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, username_combo->setTextChangedCallback(boost::bind(&LLPanelLogin::addFavoritesToStartLocation, this)); // STEAM-14: When user presses Enter with this field in focus, initiate login username_combo->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, this)); + username_combo->setKeystrokeOnEsc(TRUE); } void LLPanelLogin::addFavoritesToStartLocation() @@ -923,16 +921,6 @@ void LLPanelLogin::onClickForgotPassword(void*) } } -//static -void LLPanelLogin::onClickHelp(void*) -{ - if (sInstance) - { - LLViewerHelp* vhelp = LLViewerHelp::getInstance(); - vhelp->showTopic(vhelp->preLoginTopic()); - } -} - // static void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data) { diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index 82ef048493..852195b304 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -99,7 +99,6 @@ private: static void onClickNewAccount(void*); static void onClickVersion(void*); static void onClickForgotPassword(void*); - static void onClickHelp(void*); static void onPassKey(LLLineEditor* caller, void* user_data); static void updateServerCombo(); diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index d0dea5d044..25cfb598e7 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -448,20 +448,6 @@ void LLPanelObject::getState( ) S32 roots_selected = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount(); BOOL editable = root_objectp->permModify(); - // Select Single Message - getChildView("select_single")->setVisible( FALSE); - getChildView("edit_object")->setVisible( FALSE); - if (!editable || single_volume || selected_count <= 1) - { - getChildView("edit_object")->setVisible( TRUE); - getChildView("edit_object")->setEnabled(TRUE); - } - else - { - getChildView("select_single")->setVisible( TRUE); - getChildView("select_single")->setEnabled(TRUE); - } - BOOL is_flexible = volobjp && volobjp->isFlexible(); BOOL is_permanent = root_objectp->flagObjectPermanent(); BOOL is_permanent_enforced = root_objectp->isPermanentEnforced(); @@ -1893,10 +1879,6 @@ void LLPanelObject::clearCtrls() mLabelTaper ->setEnabled( FALSE ); mLabelRadiusOffset->setEnabled( FALSE ); mLabelRevolutions->setEnabled( FALSE ); - - getChildView("select_single")->setVisible( FALSE); - getChildView("edit_object")->setVisible( TRUE); - getChildView("edit_object")->setEnabled(FALSE); getChildView("scale_hole")->setEnabled(FALSE); getChildView("scale_taper")->setEnabled(FALSE); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 096679d786..35c5407e6c 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -101,9 +101,7 @@ public: static LLTaskInvFVBridge* createObjectBridge(LLPanelObjectInventory* panel, LLInventoryObject* object); void showProperties(); - void buyItem(); S32 getPrice(); - static bool commitBuyItem(const LLSD& notification, const LLSD& response); // LLFolderViewModelItemInventory functionality virtual const std::string& getName() const; @@ -201,75 +199,6 @@ void LLTaskInvFVBridge::showProperties() show_task_item_profile(mUUID, mPanel->getTaskUUID()); } -struct LLBuyInvItemData -{ - LLUUID mTaskID; - LLUUID mItemID; - LLAssetType::EType mType; - - LLBuyInvItemData(const LLUUID& task, - const LLUUID& item, - LLAssetType::EType type) : - mTaskID(task), mItemID(item), mType(type) - {} -}; - -void LLTaskInvFVBridge::buyItem() -{ - LL_INFOS() << "LLTaskInvFVBridge::buyItem()" << LL_ENDL; - LLInventoryItem* item = findItem(); - if(!item || !item->getSaleInfo().isForSale()) return; - LLBuyInvItemData* inv = new LLBuyInvItemData(mPanel->getTaskUUID(), - mUUID, - item->getType()); - - const LLSaleInfo& sale_info = item->getSaleInfo(); - const LLPermissions& perm = item->getPermissions(); - const std::string owner_name; // no owner name currently... FIXME? - - LLViewerObject* obj; - if( ( obj = gObjectList.findObject( mPanel->getTaskUUID() ) ) && obj->isAttachment() ) - { - LLNotificationsUtil::add("Cannot_Purchase_an_Attachment"); - LL_INFOS() << "Attempt to purchase an attachment" << LL_ENDL; - delete inv; - } - else - { - LLSD args; - args["PRICE"] = llformat("%d",sale_info.getSalePrice()); - args["OWNER"] = owner_name; - if (sale_info.getSaleType() != LLSaleInfo::FS_CONTENTS) - { - U32 next_owner_mask = perm.getMaskNextOwner(); - args["MODIFYPERM"] = LLTrans::getString((next_owner_mask & PERM_MODIFY) ? "PermYes" : "PermNo"); - args["COPYPERM"] = LLTrans::getString((next_owner_mask & PERM_COPY) ? "PermYes" : "PermNo"); - args["RESELLPERM"] = LLTrans::getString((next_owner_mask & PERM_TRANSFER) ? "PermYes" : "PermNo"); - } - - std::string alertdesc; - switch(sale_info.getSaleType()) - { - case LLSaleInfo::FS_ORIGINAL: - alertdesc = owner_name.empty() ? "BuyOriginalNoOwner" : "BuyOriginal"; - break; - case LLSaleInfo::FS_CONTENTS: - alertdesc = owner_name.empty() ? "BuyContentsNoOwner" : "BuyContents"; - break; - case LLSaleInfo::FS_COPY: - default: - alertdesc = owner_name.empty() ? "BuyCopyNoOwner" : "BuyCopy"; - break; - } - - LLSD payload; - payload["task_id"] = inv->mTaskID; - payload["item_id"] = inv->mItemID; - payload["type"] = inv->mType; - LLNotificationsUtil::add(alertdesc, args, payload, LLTaskInvFVBridge::commitBuyItem); - } -} - S32 LLTaskInvFVBridge::getPrice() { LLInventoryItem* item = findItem(); @@ -283,31 +212,6 @@ S32 LLTaskInvFVBridge::getPrice() } } -// static -bool LLTaskInvFVBridge::commitBuyItem(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if(0 == option) - { - LLViewerObject* object = gObjectList.findObject(notification["payload"]["task_id"].asUUID()); - if(!object || !object->getRegion()) return false; - - - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_BuyObjectInventory); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_Data); - msg->addUUIDFast(_PREHASH_ObjectID, notification["payload"]["task_id"].asUUID()); - msg->addUUIDFast(_PREHASH_ItemID, notification["payload"]["item_id"].asUUID()); - msg->addUUIDFast(_PREHASH_FolderID, - gInventory.findCategoryUUIDForType((LLFolderType::EType)notification["payload"]["type"].asInteger())); - msg->sendReliable(object->getRegion()->getHost()); - } - return false; -} - const std::string& LLTaskInvFVBridge::getName() const { return mName; @@ -616,29 +520,7 @@ BOOL LLTaskInvFVBridge::dragOrDrop(MASK mask, BOOL drop, // virtual void LLTaskInvFVBridge::performAction(LLInventoryModel* model, std::string action) { - if (action == "task_buy") - { - // Check the price of the item. - S32 price = getPrice(); - if (-1 == price) - { - LL_WARNS() << "label_buy_task_bridged_item: Invalid price" << LL_ENDL; - } - else - { - if (price > 0 && price > gStatusBar->getBalance()) - { - LLStringUtil::format_map_t args; - args["AMOUNT"] = llformat("%d", price); - LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("this_costs", args), price ); - } - else - { - buyItem(); - } - } - } - else if (action == "task_open") + if (action == "task_open") { openItem(); } @@ -660,39 +542,7 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) return; } - if(!gAgent.allowOperation(PERM_OWNER, item->getPermissions(), - GP_OBJECT_MANIPULATE) - && item->getSaleInfo().isForSale()) - { - items.push_back(std::string("Task Buy")); - - std::string label= LLTrans::getString("Buy"); - // Check the price of the item. - S32 price = getPrice(); - if (-1 == price) - { - LL_WARNS() << "label_buy_task_bridged_item: Invalid price" << LL_ENDL; - } - else - { - std::ostringstream info; - info << LLTrans::getString("BuyforL$") << price; - label.assign(info.str()); - } - - const LLView::child_list_t *list = menu.getChildList(); - LLView::child_list_t::const_iterator itor; - for (itor = list->begin(); itor != list->end(); ++itor) - { - std::string name = (*itor)->getName(); - LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor); - if (name == "Task Buy" && menu_itemp) - { - menu_itemp->setLabel(label); - } - } - } - else if (canOpenItem()) + if (canOpenItem()) { items.push_back(std::string("Task Open")); } @@ -980,42 +830,15 @@ void LLTaskSoundBridge::performAction(LLInventoryModel* model, std::string actio void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { LLInventoryItem* item = findItem(); - if(!item) return; std::vector<std::string> items; std::vector<std::string> disabled_items; - - if(item->getPermissions().getOwner() != gAgent.getID() - && item->getSaleInfo().isForSale()) + if (!item) { - items.push_back(std::string("Task Buy")); - - std::string label= LLTrans::getString("Buy"); - // Check the price of the item. - S32 price = getPrice(); - if (-1 == price) - { - LL_WARNS() << "label_buy_task_bridged_item: Invalid price" << LL_ENDL; - } - else - { - std::ostringstream info; - info << LLTrans::getString("BuyforL$") << price; - label.assign(info.str()); - } - - const LLView::child_list_t *list = menu.getChildList(); - LLView::child_list_t::const_iterator itor; - for (itor = list->begin(); itor != list->end(); ++itor) - { - std::string name = (*itor)->getName(); - LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor); - if (name == "Task Buy" && menu_itemp) - { - menu_itemp->setLabel(label); - } - } + hide_context_entries(menu, items, disabled_items); + return; } - else if (canOpenItem()) + + if (canOpenItem()) { if (!isItemCopyable()) { @@ -1354,49 +1177,20 @@ void LLTaskMeshBridge::performAction(LLInventoryModel* model, std::string action void LLTaskMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { LLInventoryItem* item = findItem(); - if(!item) return; std::vector<std::string> items; std::vector<std::string> disabled_items; - - if(item->getPermissions().getOwner() != gAgent.getID() - && item->getSaleInfo().isForSale()) + if(!item) { - items.push_back(std::string("Task Buy")); - - std::string label= LLTrans::getString("Buy"); - // Check the price of the item. - S32 price = getPrice(); - if (-1 == price) - { - LL_WARNS() << "label_buy_task_bridged_item: Invalid price" << LL_ENDL; - } - else - { - std::ostringstream info; - info << LLTrans::getString("BuyforL$") << price; - label.assign(info.str()); - } - - const LLView::child_list_t *list = menu.getChildList(); - LLView::child_list_t::const_iterator itor; - for (itor = list->begin(); itor != list->end(); ++itor) - { - std::string name = (*itor)->getName(); - LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor); - if (name == "Task Buy" && menu_itemp) - { - menu_itemp->setLabel(label); - } - } + hide_context_entries(menu, items, disabled_items); + return; } - else + + items.push_back(std::string("Task Open")); + if (!isItemCopyable()) { - items.push_back(std::string("Task Open")); - if (!isItemCopyable()) - { - disabled_items.push_back(std::string("Task Open")); - } + disabled_items.push_back(std::string("Task Open")); } + items.push_back(std::string("Task Properties")); if ((flags & FIRST_SELECTED_ITEM) == 0) { diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 5973b08183..c5bae9c52e 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -531,11 +531,6 @@ BOOL LLPanelOutfitEdit::postBuild() mPlusBtn = getChild<LLButton>("plus_btn"); mPlusBtn->setClickedCallback(boost::bind(&LLPanelOutfitEdit::onPlusBtnClicked, this)); - - mEditWearableBtn = getChild<LLButton>("edit_wearable_btn"); - mEditWearableBtn->setEnabled(FALSE); - mEditWearableBtn->setVisible(FALSE); - mEditWearableBtn->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onEditWearableClicked, this)); childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance())); diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 30870daf40..2cc8b65001 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -214,7 +214,6 @@ private: LLFilterEditor* mSearchFilter; LLSaveFolderState* mSavedFolderState; std::string mSearchString; - LLButton* mEditWearableBtn; LLButton* mFolderViewBtn; LLButton* mListViewBtn; LLButton* mPlusBtn; diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index eb2a297a35..30fef9f5f0 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -586,7 +586,6 @@ BOOL LLPanelPeople::postBuild() getChild<LLFilterEditor>("friends_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); getChild<LLFilterEditor>("groups_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); getChild<LLFilterEditor>("recent_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); - getChild<LLFilterEditor>("fbc_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); if(gMaxAgentGroups <= BASE_MAX_AGENT_GROUPS) { diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 29ca172f60..a7c53a7050 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -171,6 +171,8 @@ BOOL LLPanelPermissions::postBuild() childSetCommitCallback("search_check",LLPanelPermissions::onCommitIncludeInSearch,this); mLabelGroupName = getChild<LLNameBox>("Group Name Proxy"); + mLabelOwnerName = getChild<LLTextBox>("Owner Name"); + mLabelCreatorName = getChild<LLTextBox>("Creator Name"); return TRUE; } @@ -178,6 +180,14 @@ BOOL LLPanelPermissions::postBuild() LLPanelPermissions::~LLPanelPermissions() { + if (mOwnerCacheConnection.connected()) + { + mOwnerCacheConnection.disconnect(); + } + if (mCreatorCacheConnection.connected()) + { + mCreatorCacheConnection.disconnect(); + } // base class will take care of everything } @@ -192,14 +202,14 @@ void LLPanelPermissions::disableAll() getChildView("Creator:")->setEnabled(FALSE); getChild<LLUICtrl>("Creator Icon")->setVisible(FALSE); - getChild<LLUICtrl>("Creator Name")->setValue(LLStringUtil::null); - getChildView("Creator Name")->setEnabled(FALSE); + mLabelCreatorName->setValue(LLStringUtil::null); + mLabelCreatorName->setEnabled(FALSE); getChildView("Owner:")->setEnabled(FALSE); getChild<LLUICtrl>("Owner Icon")->setVisible(FALSE); getChild<LLUICtrl>("Owner Group Icon")->setVisible(FALSE); - getChild<LLUICtrl>("Owner Name")->setValue(LLStringUtil::null); - getChildView("Owner Name")->setEnabled(FALSE); + mLabelOwnerName->setValue(LLStringUtil::null); + mLabelOwnerName->setEnabled(FALSE); getChildView("Group:")->setEnabled(FALSE); getChild<LLUICtrl>("Group Name Proxy")->setValue(LLStringUtil::null); @@ -214,8 +224,6 @@ void LLPanelPermissions::disableAll() getChildView("Description:")->setEnabled(FALSE); getChild<LLUICtrl>("Object Description")->setValue(LLStringUtil::null); getChildView("Object Description")->setEnabled(FALSE); - - getChildView("Permissions:")->setEnabled(FALSE); getChild<LLUICtrl>("checkbox share with group")->setValue(FALSE); getChildView("checkbox share with group")->setEnabled(FALSE); @@ -369,8 +377,6 @@ void LLPanelPermissions::refresh() getChildView("pathfinding_attributes_value")->setEnabled(TRUE); getChild<LLUICtrl>("pathfinding_attributes_value")->setValue(LLTrans::getString(pfAttrName)); - - getChildView("Permissions:")->setEnabled(TRUE); // Update creator text field getChildView("Creator:")->setEnabled(TRUE); @@ -383,22 +389,29 @@ void LLPanelPermissions::refresh() style_params.color = link_color; style_params.readonly_color = link_color; style_params.is_link = true; // link will be added later - const LLFontGL* fontp = getChild<LLTextBox>("Creator Name")->getFont(); + const LLFontGL* fontp = mLabelCreatorName->getFont(); style_params.font.name = LLFontGL::nameFromFont(fontp); style_params.font.size = LLFontGL::sizeFromFont(fontp); style_params.font.style = "UNDERLINE"; LLAvatarName av_name; + style_params.link_href = creator_app_link; if (LLAvatarNameCache::get(mCreatorID, &av_name)) { - // If name isn't present, this will 'request' it and trigger refresh() again - LLTextBox* text_box = getChild<LLTextBox>("Creator Name"); - style_params.link_href = creator_app_link; - text_box->setText(av_name.getCompleteName(), style_params); + updateCreatorName(mCreatorID, av_name, style_params); + } + else + { + if (mCreatorCacheConnection.connected()) + { + mCreatorCacheConnection.disconnect(); + } + mLabelCreatorName->setText(LLTrans::getString("None")); + mCreatorCacheConnection = LLAvatarNameCache::get(mCreatorID, boost::bind(&LLPanelPermissions::updateCreatorName, this, _1, _2, style_params)); } getChild<LLAvatarIconCtrl>("Creator Icon")->setValue(mCreatorID); getChild<LLAvatarIconCtrl>("Creator Icon")->setVisible(TRUE); - getChildView("Creator Name")->setEnabled(TRUE); + mLabelCreatorName->setEnabled(TRUE); // Update owner text field getChildView("Owner:")->setEnabled(TRUE); @@ -413,9 +426,8 @@ void LLPanelPermissions::refresh() LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mOwnerID); if (group_data && group_data->isGroupPropertiesDataComplete()) { - LLTextBox* text_box = getChild<LLTextBox>("Owner Name"); style_params.link_href = owner_app_link; - text_box->setText(group_data->mName, style_params); + mLabelOwnerName->setText(group_data->mName, style_params); getChild<LLGroupIconCtrl>("Owner Group Icon")->setIconId(group_data->mInsigniaID); getChild<LLGroupIconCtrl>("Owner Group Icon")->setVisible(TRUE); getChild<LLUICtrl>("Owner Icon")->setVisible(FALSE); @@ -444,18 +456,27 @@ void LLPanelPermissions::refresh() } owner_id = mLastOwnerID; } + + style_params.link_href = owner_app_link; if (LLAvatarNameCache::get(owner_id, &av_name)) { - // If name isn't present, this will 'request' it and trigger refresh() again - LLTextBox* text_box = getChild<LLTextBox>("Owner Name"); - style_params.link_href = owner_app_link; - text_box->setText(av_name.getCompleteName(), style_params); + updateOwnerName(owner_id, av_name, style_params); + } + else + { + if (mOwnerCacheConnection.connected()) + { + mOwnerCacheConnection.disconnect(); + } + mLabelOwnerName->setText(LLTrans::getString("None")); + mOwnerCacheConnection = LLAvatarNameCache::get(owner_id, boost::bind(&LLPanelPermissions::updateOwnerName, this, _1, _2, style_params)); } + getChild<LLAvatarIconCtrl>("Owner Icon")->setValue(owner_id); getChild<LLAvatarIconCtrl>("Owner Icon")->setVisible(TRUE); getChild<LLUICtrl>("Owner Group Icon")->setVisible(FALSE); } - getChildView("Owner Name")->setEnabled(TRUE); + mLabelOwnerName->setEnabled(TRUE); // update group text field getChildView("Group:")->setEnabled(TRUE); @@ -785,7 +806,7 @@ void LLPanelPermissions::refresh() else { getChild<LLUICtrl>("checkbox share with group")->setValue(TRUE); - getChild<LLUICtrl>("checkbox share with group")->setTentative( TRUE); + getChild<LLUICtrl>("checkbox share with group")->setTentative(!has_change_perm_ability); getChildView("button deed")->setEnabled(gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (group_mask_on & PERM_MOVE) && (owner_mask_on & PERM_TRANSFER) && !group_owned && can_transfer); } } @@ -944,6 +965,23 @@ void LLPanelPermissions::refresh() getChildView("clickaction")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume); } +void LLPanelPermissions::updateOwnerName(const LLUUID& owner_id, const LLAvatarName& owner_name, const LLStyle::Params& style_params) +{ + if (mOwnerCacheConnection.connected()) + { + mOwnerCacheConnection.disconnect(); + } + mLabelOwnerName->setText(owner_name.getCompleteName(), style_params); +} + +void LLPanelPermissions::updateCreatorName(const LLUUID& creator_id, const LLAvatarName& creator_name, const LLStyle::Params& style_params) +{ + if (mCreatorCacheConnection.connected()) + { + mCreatorCacheConnection.disconnect(); + } + mLabelCreatorName->setText(creator_name.getCompleteName(), style_params); +} // static void LLPanelPermissions::onClickClaim(void*) diff --git a/indra/newview/llpanelpermissions.h b/indra/newview/llpanelpermissions.h index 2d15954baa..e657f8f8b7 100644 --- a/indra/newview/llpanelpermissions.h +++ b/indra/newview/llpanelpermissions.h @@ -28,6 +28,7 @@ #define LL_LLPANELPERMISSIONS_H #include "llpanel.h" +#include "llstyle.h" #include "lluuid.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -36,6 +37,8 @@ // Panel for permissions of an object. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLAvatarName; +class LLTextBox; class LLNameBox; class LLViewerInventoryItem; @@ -46,7 +49,8 @@ public: virtual ~LLPanelPermissions(); /*virtual*/ BOOL postBuild(); - + void updateOwnerName(const LLUUID& owner_id, const LLAvatarName& owner_name, const LLStyle::Params& style_params); + void updateCreatorName(const LLUUID& creator_id, const LLAvatarName& creator_name, const LLStyle::Params& style_params); void refresh(); // refresh all labels as needed protected: @@ -85,10 +89,14 @@ protected: private: LLNameBox* mLabelGroupName; // group name - + LLTextBox* mLabelOwnerName; + LLTextBox* mLabelCreatorName; LLUUID mCreatorID; LLUUID mOwnerID; LLUUID mLastOwnerID; + + boost::signals2::connection mOwnerCacheConnection; + boost::signals2::connection mCreatorCacheConnection; }; diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index b1895bfc9b..1c4384ff08 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -282,7 +282,6 @@ void LLPanelVolume::getState( ) if (is_light && editable && single_volume) { - getChildView("label color")->setEnabled(true); //mLabelColor ->setEnabled( TRUE ); LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch"); if(LightColorSwatch) @@ -325,7 +324,6 @@ void LLPanelVolume::getState( ) getChild<LLSpinCtrl>("Light Radius", true)->clear(); getChild<LLSpinCtrl>("Light Falloff", true)->clear(); - getChildView("label color")->setEnabled(false); LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch"); if(LightColorSwatch) { @@ -526,7 +524,6 @@ void LLPanelVolume::refresh() BOOL visible = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE; - getChildView("label texture")->setVisible( visible); getChildView("Light FOV")->setVisible( visible); getChildView("Light Focus")->setVisible( visible); getChildView("Light Ambiance")->setVisible( visible); @@ -567,9 +564,7 @@ void LLPanelVolume::clearCtrls() getChildView("select_single")->setVisible(true); getChildView("edit_object")->setEnabled(false); getChildView("edit_object")->setVisible(false); - getChildView("Light Checkbox Ctrl")->setEnabled(false); - getChildView("label color")->setEnabled(false); - getChildView("label color")->setEnabled(false); + getChildView("Light Checkbox Ctrl")->setEnabled(false);; LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch"); if(LightColorSwatch) { diff --git a/indra/newview/llpanelvolumepulldown.cpp b/indra/newview/llpanelvolumepulldown.cpp index 6595da235c..6792137350 100644 --- a/indra/newview/llpanelvolumepulldown.cpp +++ b/indra/newview/llpanelvolumepulldown.cpp @@ -35,6 +35,7 @@ // Linden libs #include "llbutton.h" +#include "llcheckboxctrl.h" #include "lltabcontainer.h" #include "llfloaterreg.h" #include "llfloaterpreference.h" @@ -52,17 +53,15 @@ LLPanelVolumePulldown::LLPanelVolumePulldown() { mHoverTimer.stop(); - mCommitCallbackRegistrar.add("Vol.setControlFalse", boost::bind(&LLPanelVolumePulldown::setControlFalse, this, _2)); + mCommitCallbackRegistrar.add("Vol.setControlFalse", boost::bind(&LLPanelVolumePulldown::setControlFalse, this, _2)); + mCommitCallbackRegistrar.add("Vol.SetSounds", boost::bind(&LLPanelVolumePulldown::onClickSetSounds, this)); + mCommitCallbackRegistrar.add("Vol.updateMediaAutoPlayCheckbox", boost::bind(&LLPanelVolumePulldown::updateMediaAutoPlayCheckbox, this, _1)); mCommitCallbackRegistrar.add("Vol.GoAudioPrefs", boost::bind(&LLPanelVolumePulldown::onAdvancedButtonClick, this, _2)); buildFromFile( "panel_volume_pulldown.xml"); } BOOL LLPanelVolumePulldown::postBuild() { - // set the initial volume-slider's position to reflect reality - LLSliderCtrl* volslider = getChild<LLSliderCtrl>( "mastervolume" ); - volslider->setValue(gSavedSettings.getF32("AudioLevelMaster")); - return LLPanel::postBuild(); } @@ -130,6 +129,28 @@ void LLPanelVolumePulldown::setControlFalse(const LLSD& user_data) control->set(LLSD(FALSE)); } +void LLPanelVolumePulldown::updateMediaAutoPlayCheckbox(LLUICtrl* ctrl) +{ + std::string name = ctrl->getName(); + + // Disable "Allow Media to auto play" only when both + // "Streaming Music" and "Media" are unchecked. STORM-513. + if ((name == "enable_music") || (name == "enable_media")) + { + bool music_enabled = getChild<LLCheckBoxCtrl>("enable_music")->get(); + bool media_enabled = getChild<LLCheckBoxCtrl>("enable_media")->get(); + + getChild<LLCheckBoxCtrl>("media_auto_play_btn")->setEnabled(music_enabled || media_enabled); + } +} + +void LLPanelVolumePulldown::onClickSetSounds() +{ + // Disable Enable gesture sounds checkbox if the master sound is disabled + // or if sound effects are disabled. + getChild<LLCheckBoxCtrl>("gesture_audio_play_btn")->setEnabled(!gSavedSettings.getBOOL("MuteSounds")); +} + //virtual void LLPanelVolumePulldown::draw() { diff --git a/indra/newview/llpanelvolumepulldown.h b/indra/newview/llpanelvolumepulldown.h index b843fab756..4f23112f50 100644 --- a/indra/newview/llpanelvolumepulldown.h +++ b/indra/newview/llpanelvolumepulldown.h @@ -47,6 +47,10 @@ class LLPanelVolumePulldown : public LLPanel private: void setControlFalse(const LLSD& user_data); + void onClickSetSounds(); + // Disables "Allow Media to auto play" check box only when both + // "Streaming Music" and "Media" are unchecked. Otherwise enables it. + void updateMediaAutoPlayCheckbox(LLUICtrl* ctrl); void onAdvancedButtonClick(const LLSD& user_data); LLFrameTimer mHoverTimer; diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 54a47f6e6e..b85e48ec77 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -60,6 +60,7 @@ #include "llselectmgr.h" #include "llviewerinventory.h" #include "llviewermenu.h" +#include "llviewermenufile.h" // LLFilePickerReplyThread #include "llviewerobject.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" @@ -1201,17 +1202,12 @@ BOOL LLScriptEdCore::handleKeyHere(KEY key, MASK mask) void LLScriptEdCore::onBtnLoadFromFile( void* data ) { - LLScriptEdCore* self = (LLScriptEdCore*) data; - - // TODO Maybe add a dialogue warning here if the current file has unsaved changes. - LLFilePicker& file_picker = LLFilePicker::instance(); - if( !file_picker.getOpenFile( LLFilePicker::FFLOAD_SCRIPT ) ) - { - //File picking cancelled by user, so nothing to do. - return; - } + (new LLFilePickerReplyThread(boost::bind(&LLScriptEdCore::loadScriptFromFile, _1, data), LLFilePicker::FFLOAD_SCRIPT, false))->getFile(); +} - std::string filename = file_picker.getFirstFile(); +void LLScriptEdCore::loadScriptFromFile(const std::vector<std::string>& filenames, void* data) +{ + std::string filename = filenames[0]; llifstream fin(filename.c_str()); @@ -1219,8 +1215,8 @@ void LLScriptEdCore::onBtnLoadFromFile( void* data ) std::string text; std::string linetotal; while (!fin.eof()) - { - getline(fin,line); + { + getline(fin, line); text += line; if (!fin.eof()) { @@ -1230,7 +1226,8 @@ void LLScriptEdCore::onBtnLoadFromFile( void* data ) fin.close(); // Only replace the script if there is something to replace with. - if (text.length() > 0) + LLScriptEdCore* self = (LLScriptEdCore*)data; + if (self && (text.length() > 0)) { self->mEditor->selectAll(); LLWString script(utf8str_to_wstring(text)); @@ -1246,16 +1243,21 @@ void LLScriptEdCore::onBtnSaveToFile( void* userdata ) if( self->mSaveCallback ) { - LLFilePicker& file_picker = LLFilePicker::instance(); - if( file_picker.getSaveFile( LLFilePicker::FFSAVE_SCRIPT, self->mScriptName ) ) - { - std::string filename = file_picker.getFirstFile(); - std::string scriptText=self->mEditor->getText(); - llofstream fout(filename.c_str()); - fout<<(scriptText); - fout.close(); - self->mSaveCallback( self->mUserdata, FALSE ); - } + (new LLFilePickerReplyThread(boost::bind(&LLScriptEdCore::saveScriptToFile, _1, userdata), LLFilePicker::FFSAVE_SCRIPT, self->mScriptName))->getFile(); + } +} + +void LLScriptEdCore::saveScriptToFile(const std::vector<std::string>& filenames, void* data) +{ + LLScriptEdCore* self = (LLScriptEdCore*)data; + if (self) + { + std::string filename = filenames[0]; + std::string scriptText = self->mEditor->getText(); + llofstream fout(filename.c_str()); + fout << (scriptText); + fout.close(); + self->mSaveCallback(self->mUserdata, FALSE); } } diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index a185d85889..69cf9d9158 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -109,7 +109,10 @@ public: static void onBtnInsertSample(void*); static void onBtnInsertFunction(LLUICtrl*, void*); static void onBtnLoadFromFile(void*); - static void onBtnSaveToFile(void*); + static void onBtnSaveToFile(void*); + + static void loadScriptFromFile(const std::vector<std::string>& filenames, void* data); + static void saveScriptToFile(const std::vector<std::string>& filenames, void* data); static bool enableSaveToFileMenu(void* userdata); static bool enableLoadFromFileMenu(void* userdata); diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index 12bcd89cb0..9d8be4b2fe 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -46,6 +46,7 @@ #include "lltextureview.h" #include "llui.h" #include "llviewerinventory.h" +#include "llviewermenufile.h" // LLFilePickerReplyThread #include "llviewertexture.h" #include "llviewertexturelist.h" #include "lluictrlfactory.h" @@ -293,27 +294,27 @@ void LLPreviewTexture::saveAs() if( mLoadingFullImage ) return; - LLFilePicker& file_picker = LLFilePicker::instance(); - const LLInventoryItem* item = getItem() ; - if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_TGAPNG, item ? LLDir::getScrubbedFileName(item->getName()) : LLStringUtil::null) ) - { - // User canceled or we failed to acquire save file. - return; - } - if(mPreviewToSave) + std::string filename = getItem() ? LLDir::getScrubbedFileName(getItem()->getName()) : LLStringUtil::null; + (new LLFilePickerReplyThread(boost::bind(&LLPreviewTexture::saveTextureToFile, this, _1), LLFilePicker::FFSAVE_TGAPNG, filename))->getFile(); +} + +void LLPreviewTexture::saveTextureToFile(const std::vector<std::string>& filenames) +{ + const LLInventoryItem* item = getItem(); + if (item && mPreviewToSave) { mPreviewToSave = FALSE; LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", item->getUUID()); } // remember the user-approved/edited file name. - mSaveFileName = file_picker.getFirstFile(); + mSaveFileName = filenames[0]; mLoadingFullImage = TRUE; getWindow()->incBusyCount(); - mImage->forceToSaveRawImage(0) ;//re-fetch the raw image if the old one is removed. - mImage->setLoadedCallback( LLPreviewTexture::onFileLoadedForSave, - 0, TRUE, FALSE, new LLUUID( mItemUUID ), &mCallbackTextureList ); + mImage->forceToSaveRawImage(0);//re-fetch the raw image if the old one is removed. + mImage->setLoadedCallback(LLPreviewTexture::onFileLoadedForSave, + 0, TRUE, FALSE, new LLUUID(mItemUUID), &mCallbackTextureList); } // virtual diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h index c156c48d0c..ad77d9e118 100644 --- a/indra/newview/llpreviewtexture.h +++ b/indra/newview/llpreviewtexture.h @@ -61,6 +61,8 @@ public: BOOL final, void* userdata ); void openToSave(); + + void saveTextureToFile(const std::vector<std::string>& filenames); static void onSaveAsBtn(void* data); diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index d6bf2164a0..4ebcffa554 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -102,10 +102,6 @@ BOOL LLSidepanelAppearance::postBuild() childSetAction("edit_outfit_btn", boost::bind(&LLSidepanelAppearance::showOutfitEditPanel, this)); - mNewOutfitBtn = getChild<LLButton>("newlook_btn"); - mNewOutfitBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onNewOutfitButtonClicked, this)); - mNewOutfitBtn->setEnabled(false); - mFilterEditor = getChild<LLFilterEditor>("Filter"); if (mFilterEditor) { @@ -285,14 +281,6 @@ void LLSidepanelAppearance::onEditAppearanceButtonClicked() } } -void LLSidepanelAppearance::onNewOutfitButtonClicked() -{ - if (!mOutfitEdit->getVisible()) - { - mPanelOutfitsInventory->onSave(); - } -} - void LLSidepanelAppearance::showOutfitsInventoryPanel() { toggleWearableEditPanel(FALSE); @@ -347,7 +335,6 @@ void LLSidepanelAppearance::toggleMyOutfitsPanel(BOOL visible) // *TODO: Move these controls to panel_outfits_inventory.xml // so that we don't need to toggle them explicitly. mFilterEditor->setVisible(visible); - mNewOutfitBtn->setVisible(visible); mCurrOutfitPanel->setVisible(visible); if (visible) @@ -473,8 +460,6 @@ void LLSidepanelAppearance::editWearable(LLViewerWearable *wearable, LLView *dat // fetched. Alternatively, we could stuff this logic into llagentwearables::makeNewOutfitLinks. void LLSidepanelAppearance::fetchInventory() { - - mNewOutfitBtn->setEnabled(false); uuid_vec_t ids; LLUUID item_id; for(S32 type = (S32)LLWearableType::WT_SHAPE; type < (S32)LLWearableType::WT_COUNT; ++type) @@ -525,7 +510,6 @@ void LLSidepanelAppearance::fetchInventory() void LLSidepanelAppearance::inventoryFetched() { - mNewOutfitBtn->setEnabled(true); } void LLSidepanelAppearance::setWearablesLoading(bool val) diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h index 440fce07bb..7817fd317c 100644 --- a/indra/newview/llsidepanelappearance.h +++ b/indra/newview/llsidepanelappearance.h @@ -55,7 +55,6 @@ public: void fetchInventory(); void inventoryFetched(); - void onNewOutfitButtonClicked(); void showOutfitsInventoryPanel(); void showOutfitEditPanel(); @@ -84,7 +83,6 @@ private: LLButton* mOpenOutfitBtn; LLButton* mEditAppearanceBtn; - LLButton* mNewOutfitBtn; LLPanel* mCurrOutfitPanel; LLTextBox* mCurrentLookName; diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index e25cac8c17..689734e36a 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -177,9 +177,6 @@ BOOL LLSidepanelInventory::postBuild() mTeleportBtn = mInventoryPanel->getChild<LLButton>("teleport_btn"); mTeleportBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onTeleportButtonClicked, this)); - mOverflowBtn = mInventoryPanel->getChild<LLButton>("overflow_btn"); - mOverflowBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onOverflowButtonClicked, this)); - mPanelMainInventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory"); mPanelMainInventory->setSelectCallback(boost::bind(&LLSidepanelInventory::onSelectionChange, this, _1, _2)); LLTabContainer* tabs = mPanelMainInventory->getChild<LLTabContainer>("inventory filter tabs"); @@ -515,10 +512,6 @@ void LLSidepanelInventory::onTeleportButtonClicked() performActionOnSelection("teleport"); } -void LLSidepanelInventory::onOverflowButtonClicked() -{ -} - void LLSidepanelInventory::onBackButtonClicked() { showInventoryPanel(); diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index 3b8cdb98ab..a3cd20a2c6 100644 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -114,7 +114,6 @@ protected: void onWearButtonClicked(); void onPlayButtonClicked(); void onTeleportButtonClicked(); - void onOverflowButtonClicked(); void onBackButtonClicked(); private: @@ -123,7 +122,6 @@ private: LLButton* mWearBtn; LLButton* mPlayBtn; LLButton* mTeleportBtn; - LLButton* mOverflowBtn; LLButton* mShopBtn; bool mInboxEnabled; diff --git a/indra/newview/llsidepanelinventorysubpanel.cpp b/indra/newview/llsidepanelinventorysubpanel.cpp index 2918bb388a..3b73b6b7dd 100644 --- a/indra/newview/llsidepanelinventorysubpanel.cpp +++ b/indra/newview/llsidepanelinventorysubpanel.cpp @@ -50,8 +50,7 @@ LLSidepanelInventorySubpanel::LLSidepanelInventorySubpanel(const LLPanel::Params : LLPanel(p), mIsDirty(TRUE), mIsEditing(FALSE), - mCancelBtn(NULL), - mSaveBtn(NULL) + mCancelBtn(NULL) { } @@ -63,11 +62,12 @@ LLSidepanelInventorySubpanel::~LLSidepanelInventorySubpanel() // virtual BOOL LLSidepanelInventorySubpanel::postBuild() { - mSaveBtn = getChild<LLButton>("save_btn"); - mSaveBtn->setClickedCallback(boost::bind(&LLSidepanelInventorySubpanel::onSaveButtonClicked, this)); - mCancelBtn = getChild<LLButton>("cancel_btn"); - mCancelBtn->setClickedCallback(boost::bind(&LLSidepanelInventorySubpanel::onCancelButtonClicked, this)); + mCancelBtn = findChild<LLButton>("cancel_btn"); + if (mCancelBtn) + { + mCancelBtn->setClickedCallback(boost::bind(&LLSidepanelInventorySubpanel::onCancelButtonClicked, this)); + } return TRUE; } @@ -118,8 +118,10 @@ void LLSidepanelInventorySubpanel::dirty() void LLSidepanelInventorySubpanel::updateVerbs() { - mSaveBtn->setVisible(mIsEditing); - mCancelBtn->setVisible(mIsEditing); + if (mCancelBtn) + { + mCancelBtn->setVisible(mIsEditing); + } } void LLSidepanelInventorySubpanel::onEditButtonClicked() @@ -129,14 +131,6 @@ void LLSidepanelInventorySubpanel::onEditButtonClicked() updateVerbs(); } -void LLSidepanelInventorySubpanel::onSaveButtonClicked() -{ - save(); - setIsEditing(FALSE); - refresh(); - updateVerbs(); -} - void LLSidepanelInventorySubpanel::onCancelButtonClicked() { setIsEditing(FALSE); diff --git a/indra/newview/llsidepanelinventorysubpanel.h b/indra/newview/llsidepanelinventorysubpanel.h index b5cf3aaf17..0d18943cbf 100644 --- a/indra/newview/llsidepanelinventorysubpanel.h +++ b/indra/newview/llsidepanelinventorysubpanel.h @@ -62,9 +62,7 @@ protected: // protected: void onEditButtonClicked(); - void onSaveButtonClicked(); void onCancelButtonClicked(); - LLButton* mSaveBtn; LLButton* mCancelBtn; private: diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp index 43e7e57814..a486a29aa2 100644 --- a/indra/newview/llsidepaneliteminfo.cpp +++ b/indra/newview/llsidepaneliteminfo.cpp @@ -441,7 +441,6 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) const std::string perm_and_sale_items[]={ "perms_inv", - "OwnerLabel", "perm_modify", "CheckOwnerModify", "CheckOwnerCopy", @@ -455,10 +454,8 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) "CheckNextOwnerCopy", "CheckNextOwnerTransfer", "CheckPurchase", - "SaleLabel", "ComboBoxSaleType", - "Edit Cost", - "TextPrice" + "Edit Cost" }; const std::string debug_items[]={ @@ -495,14 +492,6 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) /////////////////////// // OWNER PERMISSIONS // /////////////////////// - if(can_agent_manipulate) - { - getChild<LLUICtrl>("OwnerLabel")->setValue(getString("you_can")); - } - else - { - getChild<LLUICtrl>("OwnerLabel")->setValue(getString("owner_can")); - } U32 base_mask = perm.getMaskBase(); U32 owner_mask = perm.getMaskOwner(); @@ -510,7 +499,6 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) U32 everyone_mask = perm.getMaskEveryone(); U32 next_owner_mask = perm.getMaskNextOwner(); - getChildView("OwnerLabel")->setEnabled(TRUE); getChildView("CheckOwnerModify")->setEnabled(FALSE); getChild<LLUICtrl>("CheckOwnerModify")->setValue(LLSD((BOOL)(owner_mask & PERM_MODIFY))); getChildView("CheckOwnerCopy")->setEnabled(FALSE); @@ -645,7 +633,6 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) if (is_obj_modify && can_agent_sell && gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE)) { - getChildView("SaleLabel")->setEnabled(is_complete); getChildView("CheckPurchase")->setEnabled(is_complete); getChildView("NextOwnerLabel")->setEnabled(TRUE); @@ -653,13 +640,11 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) getChildView("CheckNextOwnerCopy")->setEnabled((base_mask & PERM_COPY) && !cannot_restrict_permissions); getChildView("CheckNextOwnerTransfer")->setEnabled((next_owner_mask & PERM_COPY) && !cannot_restrict_permissions); - getChildView("TextPrice")->setEnabled(is_complete && is_for_sale); combo_sale_type->setEnabled(is_complete && is_for_sale); edit_cost->setEnabled(is_complete && is_for_sale); } else { - getChildView("SaleLabel")->setEnabled(FALSE); getChildView("CheckPurchase")->setEnabled(FALSE); getChildView("NextOwnerLabel")->setEnabled(FALSE); @@ -667,7 +652,6 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) getChildView("CheckNextOwnerCopy")->setEnabled(FALSE); getChildView("CheckNextOwnerTransfer")->setEnabled(FALSE); - getChildView("TextPrice")->setEnabled(FALSE); combo_sale_type->setEnabled(FALSE); edit_cost->setEnabled(FALSE); } diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index 403ca7bcbf..f73722521a 100644 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -124,30 +124,24 @@ BOOL LLSidepanelTaskInfo::postBuild() childSetCommitCallback("search_check", &LLSidepanelTaskInfo::onCommitIncludeInSearch,this); mDAPermModify = getChild<LLUICtrl>("perm_modify"); - mDACreator = getChildView("Creator:"); mDACreatorName = getChild<LLUICtrl>("Creator Name"); mDAOwner = getChildView("Owner:"); mDAOwnerName = getChild<LLUICtrl>("Owner Name"); - mDAGroup = getChildView("Group:"); - mDAGroupName = getChild<LLUICtrl>("Group Name"); mDAButtonSetGroup = getChildView("button set group"); mDAObjectName = getChild<LLUICtrl>("Object Name"); mDAName = getChildView("Name:"); mDADescription = getChildView("Description:"); mDAObjectDescription = getChild<LLUICtrl>("Object Description"); - mDAPermissions = getChildView("Permissions:"); mDACheckboxShareWithGroup = getChild<LLUICtrl>("checkbox share with group"); mDAButtonDeed = getChildView("button deed"); mDACheckboxAllowEveryoneMove = getChild<LLUICtrl>("checkbox allow everyone move"); mDACheckboxAllowEveryoneCopy = getChild<LLUICtrl>("checkbox allow everyone copy"); - mDANextOwnerCan = getChildView("Next owner can:"); mDACheckboxNextOwnerCanModify = getChild<LLUICtrl>("checkbox next owner can modify"); mDACheckboxNextOwnerCanCopy = getChild<LLUICtrl>("checkbox next owner can copy"); mDACheckboxNextOwnerCanTransfer = getChild<LLUICtrl>("checkbox next owner can transfer"); mDACheckboxForSale = getChild<LLUICtrl>("checkbox for sale"); mDASearchCheck = getChild<LLUICtrl>("search_check"); mDAComboSaleType = getChild<LLComboBox>("sale type"); - mDACost = getChild<LLUICtrl>("Cost"); mDAEditCost = getChild<LLUICtrl>("Edit Cost"); mDALabelClickAction = getChildView("label click action"); mDAComboClickAction = getChild<LLComboBox>("clickaction"); @@ -183,7 +177,6 @@ void LLSidepanelTaskInfo::disableAll() mDAPermModify->setEnabled(FALSE); mDAPermModify->setValue(LLStringUtil::null); - mDACreator->setEnabled(FALSE); mDACreatorName->setValue(LLStringUtil::null); mDACreatorName->setEnabled(FALSE); @@ -191,21 +184,14 @@ void LLSidepanelTaskInfo::disableAll() mDAOwnerName->setValue(LLStringUtil::null); mDAOwnerName->setEnabled(FALSE); - mDAGroup->setEnabled(FALSE); - mDAGroupName->setValue(LLStringUtil::null); - mDAGroupName->setEnabled(FALSE); mDAButtonSetGroup->setEnabled(FALSE); mDAObjectName->setValue(LLStringUtil::null); mDAObjectName->setEnabled(FALSE); mDAName->setEnabled(FALSE); - mDAGroupName->setValue(LLStringUtil::null); - mDAGroupName->setEnabled(FALSE); mDADescription->setEnabled(FALSE); mDAObjectDescription->setValue(LLStringUtil::null); mDAObjectDescription->setEnabled(FALSE); - - mDAPermissions->setEnabled(FALSE); mDACheckboxShareWithGroup->setValue(FALSE); mDACheckboxShareWithGroup->setEnabled(FALSE); @@ -217,7 +203,6 @@ void LLSidepanelTaskInfo::disableAll() mDACheckboxAllowEveryoneCopy->setEnabled(FALSE); //Next owner can: - mDANextOwnerCan->setEnabled(FALSE); mDACheckboxNextOwnerCanModify->setValue(FALSE); mDACheckboxNextOwnerCanModify->setEnabled(FALSE); mDACheckboxNextOwnerCanCopy->setValue(FALSE); @@ -235,9 +220,7 @@ void LLSidepanelTaskInfo::disableAll() mDAComboSaleType->setValue(LLSaleInfo::FS_COPY); mDAComboSaleType->setEnabled(FALSE); - - mDACost->setEnabled(FALSE); - mDACost->setValue(getString("Cost Default")); + mDAEditCost->setValue(LLStringUtil::null); mDAEditCost->setEnabled(FALSE); @@ -365,8 +348,6 @@ void LLSidepanelTaskInfo::refresh() mDAPathfindingAttributes->setEnabled(TRUE); mDAPathfindingAttributes->setValue(LLTrans::getString(pfAttrName)); - - getChildView("Permissions:")->setEnabled(TRUE); // Update creator text field getChildView("Creator:")->setEnabled(TRUE); @@ -698,7 +679,6 @@ void LLSidepanelTaskInfo::refresh() getChild<LLUICtrl>("checkbox for sale")->setTentative( is_for_sale_mixed); getChildView("sale type")->setEnabled(num_for_sale && can_transfer && !is_sale_price_mixed); - getChildView("Next owner can:")->setEnabled(TRUE); getChildView("checkbox next owner can modify")->setEnabled(base_mask_on & PERM_MODIFY); getChildView("checkbox next owner can copy")->setEnabled(base_mask_on & PERM_COPY); getChildView("checkbox next owner can transfer")->setEnabled(next_owner_mask_on & PERM_COPY); @@ -708,7 +688,6 @@ void LLSidepanelTaskInfo::refresh() getChildView("checkbox for sale")->setEnabled(FALSE); getChildView("sale type")->setEnabled(FALSE); - getChildView("Next owner can:")->setEnabled(FALSE); getChildView("checkbox next owner can modify")->setEnabled(FALSE); getChildView("checkbox next owner can copy")->setEnabled(FALSE); getChildView("checkbox next owner can transfer")->setEnabled(FALSE); diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h index a1479ef0e7..cbfb07874b 100644 --- a/indra/newview/llsidepaneltaskinfo.h +++ b/indra/newview/llsidepaneltaskinfo.h @@ -125,30 +125,24 @@ private: private: // Pointers cached here to speed up the "disableAll" function which gets called on idle LLUICtrl* mDAPermModify; - LLView* mDACreator; LLUICtrl* mDACreatorName; LLView* mDAOwner; LLUICtrl* mDAOwnerName; - LLView* mDAGroup; - LLUICtrl* mDAGroupName; LLView* mDAButtonSetGroup; LLUICtrl* mDAObjectName; LLView* mDAName; LLView* mDADescription; LLUICtrl* mDAObjectDescription; - LLView* mDAPermissions; LLUICtrl* mDACheckboxShareWithGroup; LLView* mDAButtonDeed; LLUICtrl* mDACheckboxAllowEveryoneMove; LLUICtrl* mDACheckboxAllowEveryoneCopy; - LLView* mDANextOwnerCan; LLUICtrl* mDACheckboxNextOwnerCanModify; LLUICtrl* mDACheckboxNextOwnerCanCopy; LLUICtrl* mDACheckboxNextOwnerCanTransfer; LLUICtrl* mDACheckboxForSale; LLUICtrl* mDASearchCheck; LLComboBox* mDAComboSaleType; - LLUICtrl* mDACost; LLUICtrl* mDAEditCost; LLView* mDALabelClickAction; LLComboBox* mDAComboClickAction; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index b190635fe0..4666a1e053 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -750,7 +750,6 @@ bool idle_startup() if (gLoginMenuBarView == NULL) { LL_DEBUGS("AppInit") << "initializing menu bar" << LL_ENDL; - initialize_edit_menu(); initialize_spellcheck_menu(); init_menus(); } diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 72c5c961aa..43c0fbd53a 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -108,7 +108,6 @@ LLStatusBar::LLStatusBar(const LLRect& rect) mTextTime(NULL), mSGBandwidth(NULL), mSGPacketLoss(NULL), - mBtnStats(NULL), mBtnVolume(NULL), mBoxBalance(NULL), mBalance(0), @@ -168,8 +167,6 @@ BOOL LLStatusBar::postBuild() mBoxBalance = getChild<LLTextBox>("balance"); mBoxBalance->setClickedCallback( &LLStatusBar::onClickBalance, this ); - - mBtnStats = getChildView("stat_btn"); mIconPresets = getChild<LLIconCtrl>( "presets_icon" ); mIconPresets->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresets, this)); @@ -242,8 +239,6 @@ BOOL LLStatusBar::postBuild() mPanelNearByMedia->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT); mPanelNearByMedia->setVisible(FALSE); - mScriptOut = getChildView("scriptout"); - return TRUE; } @@ -297,7 +292,6 @@ void LLStatusBar::refresh() mSGBandwidth->setVisible(net_stats_visible); mSGPacketLoss->setVisible(net_stats_visible); - mBtnStats->setEnabled(net_stats_visible); // update the master volume button state bool mute_audio = LLAppViewer::instance()->getMasterSystemAudioMute(); diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h index 277f039f20..a3326e752a 100644 --- a/indra/newview/llstatusbar.h +++ b/indra/newview/llstatusbar.h @@ -105,12 +105,10 @@ private: LLStatGraph *mSGBandwidth; LLStatGraph *mSGPacketLoss; - LLView *mBtnStats; LLIconCtrl *mIconPresets; LLButton *mBtnVolume; LLTextBox *mBoxBalance; LLButton *mMediaToggle; - LLView *mScriptOut; LLFrameTimer mClockUpdateTimer; S32 mBalance; diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index c7adaa908f..a5a2eec246 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -990,6 +990,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p) mOnSelectCallback(NULL), mBorderColor( p.border_color() ), mAllowNoTexture( FALSE ), + mAllowLocalTexture( TRUE ), mImmediateFilterPermMask( PERM_NONE ), mNonImmediateFilterPermMask( PERM_NONE ), mCanApplyImmediately( FALSE ), @@ -1198,6 +1199,12 @@ void LLTextureCtrl::showPicker(BOOL take_focus) floaterp->openFloater(); } + LLFloaterTexturePicker* picker_floater = dynamic_cast<LLFloaterTexturePicker*>(floaterp); + if (picker_floater) + { + picker_floater->setLocalTextureEnabled(mAllowLocalTexture); + } + if (take_focus) { floaterp->setFocus(TRUE); diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 840feddfaf..6bcf9c3a75 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -142,6 +142,9 @@ public: void setAllowNoTexture( BOOL b ) { mAllowNoTexture = b; } bool getAllowNoTexture() const { return mAllowNoTexture; } + void setAllowLocalTexture(BOOL b) { mAllowLocalTexture = b; } + BOOL getAllowLocalTexture() const { return mAllowLocalTexture; } + const LLUUID& getImageItemID() { return mImageItemID; } virtual void setImageAssetName(const std::string& name); @@ -222,6 +225,7 @@ private: LLTextBox* mCaption; std::string mLabel; BOOL mAllowNoTexture; // If true, the user can select "none" as an option + BOOL mAllowLocalTexture; PermissionMask mImmediateFilterPermMask; PermissionMask mDnDFilterPermMask; PermissionMask mNonImmediateFilterPermMask; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 6fd90e4935..1f69939c46 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -3082,7 +3082,7 @@ void LLTextureFetch::commonUpdate() //virtual S32 LLTextureFetch::update(F32 max_time_ms) { - static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS", 500.0); + static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS", 3000.0); { mNetworkQueueMutex.lock(); // +Mfnq diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index edde7c8076..b9b05966bc 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -34,6 +34,7 @@ #include "llviewercontrol.h" using namespace LLNotificationsUI; +std::list<LLToast*> LLToast::sModalToastsList; //-------------------------------------------------------------------------- LLToastLifeTimer::LLToastLifeTimer(LLToast* toast, F32 period) @@ -143,6 +144,11 @@ LLToast::LLToast(const LLToast::Params& p) { mOnDeleteToastSignal.connect(p.on_delete_toast()); } + + if (isModal()) + { + sModalToastsList.push_front(this); + } } void LLToast::reshape(S32 width, S32 height, BOOL called_from_parent) @@ -187,6 +193,15 @@ LLToast::~LLToast() { mOnToastDestroyedSignal(this); } + + if (isModal()) + { + std::list<LLToast*>::iterator iter = std::find(sModalToastsList.begin(), sModalToastsList.end(), this); + if (iter != sModalToastsList.end()) + { + sModalToastsList.erase(iter); + } + } } //-------------------------------------------------------------------------- diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h index cd92189012..69074b1670 100644 --- a/indra/newview/lltoast.h +++ b/indra/newview/lltoast.h @@ -108,6 +108,8 @@ public: static void updateClass(); static void cleanupToasts(); + static BOOL isAlertToastShown() { return sModalToastsList.size() > 0; } + LLToast(const LLToast::Params& p); virtual ~LLToast(); BOOL postBuild(); @@ -245,6 +247,8 @@ private: commit_signal_t mToastMouseEnterSignal; commit_signal_t mToastMouseLeaveSignal; + + static std::list<LLToast*> sModalToastsList; }; } diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp index 39adfb3431..c4c4b13a2f 100644 --- a/indra/newview/lltoastimpanel.cpp +++ b/indra/newview/lltoastimpanel.cpp @@ -65,14 +65,9 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(p.session_id); mIsGroupMsg = (im_session && im_session->mSessionType == LLIMModel::LLIMSession::GROUP_SESSION); - if(mIsGroupMsg) - { - mAvatarName->setValue(im_session->mName); - LLAvatarName avatar_name; - LLAvatarNameCache::get(p.avatar_id, &avatar_name); - p.message = "[From " + avatar_name.getDisplayName() + "]\n" + p.message; - } - + std::string title = mIsGroupMsg ? im_session->mName : p.from; + mAvatarName->setValue(title); + //Handle IRC styled /me messages. std::string prefix = p.message.substr(0, 4); if (prefix == "/me " || prefix == "/me'") @@ -88,14 +83,16 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif } else { + if (mIsGroupMsg) + { + LLAvatarName avatar_name; + LLAvatarNameCache::get(p.avatar_id, &avatar_name); + p.message = "[From " + avatar_name.getDisplayName() + "]\n" + p.message; + } style_params.font.style = "NORMAL"; mMessage->setText(p.message, style_params); } - if(!mIsGroupMsg) - { - mAvatarName->setValue(p.from); - } mTime->setValue(p.time); mSessionID = p.session_id; mAvatarID = p.avatar_id; diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp index caa055e5e0..596951fdfb 100644 --- a/indra/newview/lltoolfocus.cpp +++ b/indra/newview/lltoolfocus.cpp @@ -222,8 +222,10 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info) gAgentCamera.setFocusGlobal(pick_info); } + BOOL zoom_tool = gCameraBtnZoom && (LLToolMgr::getInstance()->getBaseTool() == LLToolCamera::getInstance()); if (!(pick_info.mKeyMask & MASK_ALT) && !LLFloaterCamera::inFreeCameraMode() && + !zoom_tool && gAgentCamera.cameraThirdPerson() && gViewerWindow->getLeftMouseDown() && !gSavedSettings.getBOOL("FreezeTime") && diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp index 1fcc9a0711..c22eb48eef 100644 --- a/indra/newview/lltoolselect.cpp +++ b/indra/newview/lltoolselect.cpp @@ -52,6 +52,7 @@ //extern BOOL gAllowSelectAvatar; const F32 SELECTION_ROTATION_TRESHOLD = 0.1f; +const F32 SELECTION_SITTING_ROTATION_TRESHOLD = 3.2f; //radian LLToolSelect::LLToolSelect( LLToolComposite* composite ) : LLTool( std::string("Select"), composite ), @@ -194,7 +195,13 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi { LLQuaternion target_rot; target_rot.shortestArc(LLVector3::x_axis, selection_dir); - gAgent.startAutoPilotGlobal(gAgent.getPositionGlobal(), "", &target_rot, NULL, NULL, 1.f, SELECTION_ROTATION_TRESHOLD); + gAgent.startAutoPilotGlobal(gAgent.getPositionGlobal(), + "", + &target_rot, + NULL, + NULL, + MAX_FAR_CLIP /*stop_distance, don't care since we are looking, not moving*/, + gAgentAvatarp->isSitting() ? SELECTION_SITTING_ROTATION_TRESHOLD : SELECTION_ROTATION_TRESHOLD); } } diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index a91bf04bfa..555768615a 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -766,14 +766,7 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti // Show the preview panel for textures and sounds to let // user know that the image (or snapshot) arrived intact. LLInventoryPanel* panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); - if (panel) - { - panel->setSelection(serverInventoryItem, TAKE_FOCUS_NO); - } - else - { - LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, serverInventoryItem, TRUE, TAKE_FOCUS_NO, TRUE); - } + LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, serverInventoryItem, TRUE, TAKE_FOCUS_NO, (panel == NULL)); // restore keyboard focus gFocusMgr.setKeyboardFocus(focus); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 2d1f3510d5..7c5ccb1087 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -34,7 +34,6 @@ #include "llcompilequeue.h" #include "llfasttimerview.h" #include "llfloaterabout.h" -#include "llfloaterauction.h" #include "llfloaterautoreplacesettings.h" #include "llfloateravatar.h" #include "llfloateravatarpicker.h" @@ -192,7 +191,6 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("about_land", "floater_about_land.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLand>); LLFloaterReg::add("appearance", "floater_my_appearance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>); LLFloaterReg::add("associate_listing", "floater_associate_listing.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAssociateListing>); - LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>); LLFloaterReg::add("avatar", "floater_avatar.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatar>); LLFloaterReg::add("avatar_picker", "floater_avatar_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarPicker>); LLFloaterReg::add("avatar_render_settings", "floater_avatar_render_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarRenderSettings>); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 75108b3ef0..4334cbfda3 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -55,6 +55,7 @@ #include "llversioninfo.h" #include "llviewermediafocus.h" #include "llviewercontrol.h" +#include "llviewermenufile.h" // LLFilePickerThread #include "llviewernetwork.h" #include "llviewerparcelmedia.h" #include "llviewerparcelmgr.h" @@ -82,6 +83,43 @@ /*static*/ const char* LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING = "MediaShowOutsideParcel"; +class LLMediaFilePicker : public LLFilePickerThread // deletes itself when done +{ +public: + LLMediaFilePicker(LLPluginClassMedia* plugin, LLFilePicker::ELoadFilter filter, bool get_multiple) + : LLFilePickerThread(filter, get_multiple), + mPlugin(plugin->getSharedPrt()) + { + } + + LLMediaFilePicker(LLPluginClassMedia* plugin, LLFilePicker::ESaveFilter filter, const std::string &proposed_name) + : LLFilePickerThread(filter, proposed_name), + mPlugin(plugin->getSharedPrt()) + { + } + + virtual void notify(const std::vector<std::string>& filenames) + { + mPlugin->sendPickFileResponse(mResponses); + mPlugin = NULL; + } + +private: + boost::shared_ptr<LLPluginClassMedia> mPlugin; +}; + +void init_threaded_picker_load_dialog(LLPluginClassMedia* plugin, LLFilePicker::ELoadFilter filter, bool get_multiple) +{ + (new LLMediaFilePicker(plugin, filter, get_multiple))->getFile(); // will delete itself +} + +void init_threaded_picker_save_dialog(LLPluginClassMedia* plugin, LLFilePicker::ESaveFilter filter, std::string &proposed_name) +{ + (new LLMediaFilePicker(plugin, filter, proposed_name))->getFile(); // will delete itself +} + +/////////////////////////////////////////////////////////////////////////////// + // Move this to its own file. LLViewerMediaEventEmitter::~LLViewerMediaEventEmitter() @@ -1647,8 +1685,7 @@ void LLViewerMediaImpl::destroyMediaSource() if(mMediaSource) { mMediaSource->setDeleteOK(true) ; - delete mMediaSource; - mMediaSource = NULL; + mMediaSource = NULL; // shared pointer } } @@ -1840,7 +1877,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type) media_source->clear_cache(); } - mMediaSource = media_source; + mMediaSource.reset(media_source); mMediaSource->setDeleteOK(false) ; updateVolume(); @@ -3274,37 +3311,9 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla case LLViewerMediaObserver::MEDIA_EVENT_PICK_FILE_REQUEST: { - LLFilePicker& picker = LLFilePicker::instance(); - std::vector<std::string> responses; - - bool pick_multiple_files = plugin->getIsMultipleFilePick(); - if (pick_multiple_files == false) - { - picker.getOpenFile(LLFilePicker::FFLOAD_ALL); - - std::string filename = picker.getFirstFile(); - responses.push_back(filename); - } - else - { - if (picker.getMultipleOpenFiles()) - { - std::string filename = picker.getFirstFile(); - - responses.push_back(filename); - - while (!filename.empty()) - { - filename = picker.getNextFile(); + LL_DEBUGS("Media") << "Media event - file pick requested." << LL_ENDL; - if (!filename.empty()) - { - responses.push_back(filename); - } - } - } - } - plugin->sendPickFileResponse(responses); + init_threaded_picker_load_dialog(plugin, LLFilePicker::FFLOAD_ALL, plugin->getIsMultipleFilePick()); } break; diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 6e18c4fecb..c52960dfcf 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -202,7 +202,7 @@ public: bool initializeMedia(const std::string& mime_type); bool initializePlugin(const std::string& media_type); void loadURI(); - LLPluginClassMedia* getMediaPlugin() { return mMediaSource; } + LLPluginClassMedia* getMediaPlugin() { return mMediaSource.get(); } void setSize(int width, int height); void showNotification(LLNotificationPtr notify); @@ -417,7 +417,7 @@ private: private: // a single media url with some data and an impl. - LLPluginClassMedia* mMediaSource; + boost::shared_ptr<LLPluginClassMedia> mMediaSource; F64 mZoomFactor; LLUUID mTextureId; bool mMovieImageHasMips; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index e45ffb38ad..ce6cb78909 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7973,6 +7973,23 @@ void handle_web_browser_test(const LLSD& param) LLWeb::loadURLInternal(url); } +bool callback_clear_cache_immediately(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if ( option == 0 ) // YES + { + //clear cache + LLAppViewer::instance()->purgeCacheImmediate(); + } + + return false; +} + +void handle_cache_clear_immediately() +{ + LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache_immediately); +} + void handle_web_content_test(const LLSD& param) { std::string url = param.asString(); @@ -8982,6 +8999,8 @@ void initialize_menus() //Develop (Texture Fetch Debug Console) view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger"); + //Develop (clear cache immediately) + commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) ); // Admin >Object view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy"); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 482de8a722..d6ef008488 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -46,6 +46,7 @@ #include "llimagetga.h" #include "llinventorymodel.h" // gInventory #include "llresourcedata.h" +#include "lltoast.h" #include "llfloaterperms.h" #include "llstatusbar.h" #include "llviewercontrol.h" // gSavedSettings @@ -134,18 +135,35 @@ void LLFilePickerThread::getFile() //virtual void LLFilePickerThread::run() { - LLFilePicker picker; #if LL_WINDOWS - if (picker.getOpenFile(mFilter, false)) + bool blocking = false; +#else + bool blocking = true; // modal +#endif + + LLFilePicker picker; + + if (mIsSaveDialog) { - mFile = picker.getFirstFile(); + if (picker.getSaveFile(mSaveFilter, mProposedName, blocking)) + { + mResponses.push_back(picker.getFirstFile()); + } } -#else - if (picker.getOpenFile(mFilter, true)) + else { - mFile = picker.getFirstFile(); + bool result = mIsGetMultiple ? picker.getMultipleOpenFiles(mLoadFilter, blocking) : picker.getOpenFile(mLoadFilter, blocking); + if (result) + { + std::string filename = picker.getFirstFile(); // consider copying mFiles directly + do + { + mResponses.push_back(filename); + filename = picker.getNextFile(); + } + while (mIsGetMultiple && !filename.empty()); + } } -#endif { LLMutexLock lock(sMutex); @@ -178,13 +196,47 @@ void LLFilePickerThread::clearDead() while (!sDeadQ.empty()) { LLFilePickerThread* thread = sDeadQ.front(); - thread->notify(thread->mFile); + thread->notify(thread->mResponses); delete thread; sDeadQ.pop(); } } } +LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple) + : LLFilePickerThread(filter, get_multiple), + mLoadFilter(filter), + mSaveFilter(LLFilePicker::FFSAVE_ALL), + mFilePickedSignal(NULL) +{ + mFilePickedSignal = new file_picked_signal_t(); + mFilePickedSignal->connect(cb); +} + +LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name) + : LLFilePickerThread(filter, proposed_name), + mLoadFilter(LLFilePicker::FFLOAD_ALL), + mSaveFilter(filter), + mFilePickedSignal(NULL) +{ + mFilePickedSignal = new file_picked_signal_t(); + mFilePickedSignal->connect(cb); +} + +LLFilePickerReplyThread::~LLFilePickerReplyThread() +{ + delete mFilePickedSignal; +} + +void LLFilePickerReplyThread::notify(const std::vector<std::string>& filenames) +{ + if (filenames.empty()) return; + + if (mFilePickedSignal) + { + (*mFilePickedSignal)(filenames, mLoadFilter, mSaveFilter); + } +} //============================================================================ @@ -231,54 +283,21 @@ std::string build_extensions_string(LLFilePicker::ELoadFilter filter) } } -/** - char* upload_pick(void* data) - If applicable, brings up a file chooser in which the user selects a file - to upload for a particular task. If the file is valid for the given action, - returns the string to the full path filename, else returns NULL. - Data is the load filter for the type of file as defined in LLFilePicker. -**/ -const std::string upload_pick(void* data) +const bool check_file_extension(const std::string& filename, LLFilePicker::ELoadFilter type) { - if( gAgentCamera.cameraMouselook() ) - { - gAgentCamera.changeCameraToDefault(); - // This doesn't seem necessary. JC - // display(); - } - - LLFilePicker::ELoadFilter type; - if(data) - { - type = (LLFilePicker::ELoadFilter)((intptr_t)data); - } - else - { - type = LLFilePicker::FFLOAD_ALL; - } - - LLFilePicker& picker = LLFilePicker::instance(); - if (!picker.getOpenFile(type)) - { - LL_INFOS() << "Couldn't import objects from file" << LL_ENDL; - return std::string(); - } - - - const std::string& filename = picker.getFirstFile(); std::string ext = gDirUtilp->getExtension(filename); //strincmp doesn't like NULL pointers if (ext.empty()) { std::string short_name = gDirUtilp->getBaseFileName(filename); - + // No extension LLSD args; args["FILE"] = short_name; LLNotificationsUtil::add("NoFileExtension", args); - return std::string(); + return false; } else { @@ -290,7 +309,7 @@ const std::string upload_pick(void* data) std::string valid_extensions = build_extensions_string(type); BOOL ext_valid = FALSE; - + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; boost::char_separator<char> sep(" "); tokenizer tokens(valid_extensions, sep); @@ -299,9 +318,9 @@ const std::string upload_pick(void* data) //now loop over all valid file extensions //and compare them to the extension of the file //to be uploaded - for( token_iter = tokens.begin(); - token_iter != tokens.end() && ext_valid != TRUE; - ++token_iter) + for (token_iter = tokens.begin(); + token_iter != tokens.end() && ext_valid != TRUE; + ++token_iter) { const std::string& cur_token = *token_iter; @@ -321,42 +340,103 @@ const std::string upload_pick(void* data) args["EXTENSION"] = ext; args["VALIDS"] = valid_extensions; LLNotificationsUtil::add("InvalidFileExtension", args); - return std::string(); + return false; } }//end else (non-null extension) + return true; +} - //valid file extension +const void upload_single_file(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type) +{ + std::string filename = filenames[0]; + if (!check_file_extension(filename, type)) return; - //now we check to see - //if the file is actually a valid image/sound/etc. - if (type == LLFilePicker::FFLOAD_WAV) + if (!filename.empty()) { - // pre-qualify wavs to make sure the format is acceptable - std::string error_msg; - if (check_for_invalid_wav_formats(filename,error_msg)) + if (type == LLFilePicker::FFLOAD_WAV) { - LL_INFOS() << error_msg << ": " << filename << LL_ENDL; - LLSD args; - args["FILE"] = filename; - LLNotificationsUtil::add( error_msg, args ); - return std::string(); + // pre-qualify wavs to make sure the format is acceptable + std::string error_msg; + if (check_for_invalid_wav_formats(filename, error_msg)) + { + LL_INFOS() << error_msg << ": " << filename << LL_ENDL; + LLSD args; + args["FILE"] = filename; + LLNotificationsUtil::add(error_msg, args); + return; + } + else + { + LLFloaterReg::showInstance("upload_sound", LLSD(filename)); + } + } + if (type == LLFilePicker::FFLOAD_IMAGE) + { + LLFloaterReg::showInstance("upload_image", LLSD(filename)); } - }//end if a wave/sound file + if (type == LLFilePicker::FFLOAD_ANIM) + { + if (filename.rfind(".anim") != std::string::npos) + { + LLFloaterReg::showInstance("upload_anim_anim", LLSD(filename)); + } + else + { + LLFloaterReg::showInstance("upload_anim_bvh", LLSD(filename)); + } + } + } + return; +} - - return filename; + +const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type) +{ + // TODO: + // Check user balance for entire cost + // Charge user entire cost + // Loop, uploading + // If an upload fails, refund the user for that one + // + // Also fix single upload to charge first, then refund + + S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); + for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter) + { + std::string filename = (*in_iter); + if (!check_file_extension(filename, type)) continue; + + std::string name = gDirUtilp->getBaseFileName(filename, true); + std::string asset_name = name; + LLStringUtil::replaceNonstandardASCII(asset_name, '?'); + LLStringUtil::replaceChar(asset_name, '|', '?'); + LLStringUtil::stripNonprintable(asset_name); + LLStringUtil::trim(asset_name); + + LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo( + filename, + asset_name, + asset_name, 0, + LLFolderType::FT_NONE, LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms("Uploads"), + LLFloaterPerms::getGroupPerms("Uploads"), + LLFloaterPerms::getEveryonePerms("Uploads"), + expected_upload_cost)); + + upload_new_resource(uploadInfo, NULL, NULL); + } } class LLFileUploadImage : public view_listener_t { bool handleEvent(const LLSD& userdata) { - std::string filename = upload_pick((void *)LLFilePicker::FFLOAD_IMAGE); - if (!filename.empty()) + if (gAgentCamera.cameraMouselook()) { - LLFloaterReg::showInstance("upload_image", LLSD(filename)); + gAgentCamera.changeCameraToDefault(); } - return TRUE; + (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_IMAGE, false))->getFile(); + return true; } }; @@ -378,11 +458,11 @@ class LLFileUploadSound : public view_listener_t { bool handleEvent(const LLSD& userdata) { - std::string filename = upload_pick((void*)LLFilePicker::FFLOAD_WAV); - if (!filename.empty()) + if (gAgentCamera.cameraMouselook()) { - LLFloaterReg::showInstance("upload_sound", LLSD(filename)); + gAgentCamera.changeCameraToDefault(); } + (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_WAV, false))->getFile(); return true; } }; @@ -391,18 +471,11 @@ class LLFileUploadAnim : public view_listener_t { bool handleEvent(const LLSD& userdata) { - const std::string filename = upload_pick((void*)LLFilePicker::FFLOAD_ANIM); - if (!filename.empty()) + if (gAgentCamera.cameraMouselook()) { - if (filename.rfind(".anim") != std::string::npos) - { - LLFloaterReg::showInstance("upload_anim_anim", LLSD(filename)); - } - else - { - LLFloaterReg::showInstance("upload_anim_bvh", LLSD(filename)); - } + gAgentCamera.changeCameraToDefault(); } + (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_ANIM, false))->getFile(); return true; } }; @@ -411,55 +484,11 @@ class LLFileUploadBulk : public view_listener_t { bool handleEvent(const LLSD& userdata) { - if( gAgentCamera.cameraMouselook() ) + if (gAgentCamera.cameraMouselook()) { gAgentCamera.changeCameraToDefault(); } - - // TODO: - // Check extensions for uploadability, cost - // Check user balance for entire cost - // Charge user entire cost - // Loop, uploading - // If an upload fails, refund the user for that one - // - // Also fix single upload to charge first, then refund - - LLFilePicker& picker = LLFilePicker::instance(); - if (picker.getMultipleOpenFiles()) - { - std::string filename = picker.getFirstFile(); - S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); - - while (!filename.empty()) - { - std::string name = gDirUtilp->getBaseFileName(filename, true); - - std::string asset_name = name; - LLStringUtil::replaceNonstandardASCII( asset_name, '?' ); - LLStringUtil::replaceChar(asset_name, '|', '?'); - LLStringUtil::stripNonprintable(asset_name); - LLStringUtil::trim(asset_name); - - LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared<LLNewFileResourceUploadInfo>( - filename, - asset_name, - asset_name, 0, - LLFolderType::FT_NONE, LLInventoryType::IT_NONE, - LLFloaterPerms::getNextOwnerPerms("Uploads"), - LLFloaterPerms::getGroupPerms("Uploads"), - LLFloaterPerms::getEveryonePerms("Uploads"), - expected_upload_cost)); - - upload_new_resource(uploadInfo); - - filename = picker.getNextFile(); - } - } - else - { - LL_INFOS() << "Couldn't import objects from file" << LL_ENDL; - } + (new LLFilePickerReplyThread(boost::bind(&upload_bulk, _1, _2), LLFilePicker::FFLOAD_ALL, true))->getFile(); return true; } }; @@ -482,7 +511,7 @@ class LLFileEnableCloseWindow : public view_listener_t bool frontmost_fl_exists = (NULL != gFloaterView->getFrontmostClosableFloater()); bool frontmost_snapshot_fl_exists = (NULL != gSnapshotFloaterView->getFrontmostClosableFloater()); - return frontmost_fl_exists || frontmost_snapshot_fl_exists; + return !LLNotificationsUI::LLToast::isAlertToastShown() && (frontmost_fl_exists || frontmost_snapshot_fl_exists); } }; @@ -519,7 +548,7 @@ class LLFileEnableCloseAllWindows : public view_listener_t bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain()) || (floater_outfit_snapshot && floater_outfit_snapshot->isInVisibleChain()); bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened; - return !open_children; + return !open_children && !LLNotificationsUI::LLToast::isAlertToastShown(); } }; diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index 973739d7ac..c6f3eec1ce 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -81,21 +81,48 @@ public: static void cleanupClass(); static void clearDead(); - std::string mFile; + std::vector<std::string> mResponses; + std::string mProposedName; - LLFilePicker::ELoadFilter mFilter; + LLFilePicker::ELoadFilter mLoadFilter; + LLFilePicker::ESaveFilter mSaveFilter; + bool mIsSaveDialog; + bool mIsGetMultiple; - LLFilePickerThread(LLFilePicker::ELoadFilter filter) - : LLThread("file picker"), mFilter(filter) + LLFilePickerThread(LLFilePicker::ELoadFilter filter, bool get_multiple = false) + : LLThread("file picker"), mLoadFilter(filter), mIsSaveDialog(false), mIsGetMultiple(get_multiple) { + } + LLFilePickerThread(LLFilePicker::ESaveFilter filter, const std::string &proposed_name) + : LLThread("file picker"), mSaveFilter(filter), mIsSaveDialog(true), mProposedName(proposed_name) + { } void getFile(); virtual void run(); - virtual void notify(const std::string& filename) = 0; + virtual void notify(const std::vector<std::string>& filenames) = 0; +}; + + +class LLFilePickerReplyThread : public LLFilePickerThread +{ +public: + + typedef boost::signals2::signal<void(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter)> file_picked_signal_t; + + LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple); + LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name); + ~LLFilePickerReplyThread(); + + virtual void notify(const std::vector<std::string>& filenames); + +private: + LLFilePicker::ELoadFilter mLoadFilter; + LLFilePicker::ESaveFilter mSaveFilter; + file_picked_signal_t* mFilePickedSignal; }; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 239e357cdd..955cc79283 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -134,6 +134,7 @@ std::map<std::string, U32> LLViewerObject::sObjectDataMap; // JC 3/18/2003 const F32 PHYSICS_TIMESTEP = 1.f / 45.f; +const U32 MAX_INV_FILE_READ_FAILS = 25; static LLTrace::BlockTimerStatHandle FTM_CREATE_OBJECT("Create Object"); @@ -3063,6 +3064,7 @@ BOOL LLViewerObject::loadTaskInvFile(const std::string& filename) llifstream ifs(filename_and_local_path.c_str()); if(ifs.good()) { + U32 fail_count = 0; char buffer[MAX_STRING]; /* Flawfinder: ignore */ // *NOTE: This buffer size is hard coded into scanf() below. char keyword[MAX_STRING]; /* Flawfinder: ignore */ @@ -3077,8 +3079,14 @@ BOOL LLViewerObject::loadTaskInvFile(const std::string& filename) while(ifs.good()) { ifs.getline(buffer, MAX_STRING); - sscanf(buffer, " %254s", keyword); /* Flawfinder: ignore */ - if(0 == strcmp("inv_item", keyword)) + if (sscanf(buffer, " %254s", keyword) == EOF) /* Flawfinder: ignore */ + { + // Blank file? + LL_WARNS() << "Issue reading from file '" + << filename << "'" << LL_ENDL; + break; + } + else if(0 == strcmp("inv_item", keyword)) { LLPointer<LLInventoryObject> inv = new LLViewerInventoryItem; inv->importLegacyStream(ifs); @@ -3091,9 +3099,17 @@ BOOL LLViewerObject::loadTaskInvFile(const std::string& filename) inv->rename("Contents"); mInventory->push_front(inv); } + else if (fail_count >= MAX_INV_FILE_READ_FAILS) + { + LL_WARNS() << "Encountered too many unknowns while reading from file: '" + << filename << "'" << LL_ENDL; + break; + } else { - LL_WARNS() << "Unknown token in inventory file '" + // Is there really a point to continue processing? We already failing to display full inventory + fail_count++; + LL_WARNS_ONCE() << "Unknown token while reading from inventory file. Token: '" << keyword << "'" << LL_ENDL; } } diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index dc54346d59..23a51b99f6 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1046,9 +1046,11 @@ void LLViewerObjectList::fetchObjectCostsCoro(std::string url) mPendingObjectCost.begin(), mPendingObjectCost.end(), std::inserter(diff, diff.begin())); + mStaleObjectCost.clear(); + if (diff.empty()) { - LL_INFOS() << "No outstanding object IDs to request." << LL_ENDL; + LL_INFOS() << "No outstanding object IDs to request. Pending count: " << mPendingObjectCost.size() << LL_ENDL; return; } @@ -1057,7 +1059,6 @@ void LLViewerObjectList::fetchObjectCostsCoro(std::string url) for (uuid_set_t::iterator it = diff.begin(); it != diff.end(); ++it) { idList.append(*it); - mStaleObjectCost.erase(*it); } mPendingObjectCost.insert(diff.begin(), diff.end()); @@ -1094,9 +1095,7 @@ void LLViewerObjectList::fetchObjectCostsCoro(std::string url) { LLUUID objectId = it->asUUID(); - // If the object was added to the StaleObjectCost set after it had been - // added to mPendingObjectCost it would still be in the StaleObjectCost - // set when we got the response back. + // Object could have been added to the mStaleObjectCost after request started mStaleObjectCost.erase(objectId); mPendingObjectCost.erase(objectId); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 8e8d1ff024..0e47d0e8ad 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1878,7 +1878,7 @@ void LLViewerRegion::updateNetStats() mLastPacketsLost = mPacketsLost; mPacketsIn = cdp->getPacketsIn(); - mBitsIn = 8 * cdp->getBytesIn(); + mBitsIn = cdp->getBytesIn(); mPacketsOut = cdp->getPacketsOut(); mPacketsLost = cdp->getPacketsLost(); mPingDelay = cdp->getPingDelay(); @@ -2817,6 +2817,7 @@ void LLViewerRegion::unpackRegionHandshake() void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) { + capabilityNames.append("AbuseCategories"); capabilityNames.append("AgentPreferences"); capabilityNames.append("AgentState"); capabilityNames.append("AttachmentResources"); diff --git a/indra/newview/llviewerthrottle.cpp b/indra/newview/llviewerthrottle.cpp index 22de7e150b..2729253d18 100644 --- a/indra/newview/llviewerthrottle.cpp +++ b/indra/newview/llviewerthrottle.cpp @@ -46,7 +46,7 @@ const F32 MAX_FRACTIONAL = 1.5f; const F32 MIN_FRACTIONAL = 0.2f; const F32 MIN_BANDWIDTH = 50.f; -const F32 MAX_BANDWIDTH = 3000.f; +const F32 MAX_BANDWIDTH = 6000.f; const F32 STEP_FRACTIONAL = 0.1f; const LLUnit<F32, LLUnits::Percent> TIGHTEN_THROTTLE_THRESHOLD(3.0f); // packet loss % per s const LLUnit<F32, LLUnits::Percent> EASE_THROTTLE_THRESHOLD(0.5f); // packet loss % per s diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp index ae9ce37a28..2d7a0f920f 100644 --- a/indra/newview/llviewerwearable.cpp +++ b/indra/newview/llviewerwearable.cpp @@ -301,7 +301,7 @@ void LLViewerWearable::setTexturesToDefaults() LLUUID LLViewerWearable::getDefaultTextureImageID(ETextureIndex index) const { const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index); - const std::string &default_image_name = texture_dict->mDefaultImageName; + const std::string &default_image_name = texture_dict ? texture_dict->mDefaultImageName : ""; if (default_image_name == "") { return IMG_DEFAULT_AVATAR; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 1ad71ce93e..3c1b1590fa 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -261,10 +261,8 @@ static const F32 MIN_UI_SCALE = 0.75f; static const F32 MAX_UI_SCALE = 7.0f; static const F32 MIN_DISPLAY_SCALE = 0.75f; -std::string LLViewerWindow::sSnapshotBaseName; -std::string LLViewerWindow::sSnapshotDir; - -std::string LLViewerWindow::sMovieBaseName; +static LLCachedControl<std::string> sSnapshotBaseName(LLCachedControl<std::string>(gSavedPerAccountSettings, "SnapshotBaseName", "Snapshot")); +static LLCachedControl<std::string> sSnapshotDir(LLCachedControl<std::string>(gSavedPerAccountSettings, "SnapshotBaseDir", "")); LLTrace::SampleStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity"); @@ -393,14 +391,12 @@ public: } } -#if LL_WINDOWS if (gSavedSettings.getBOOL("DebugShowMemory")) { addText(xpos, ypos, STRINGIZE("Memory: " << (LLMemory::getCurrentRSS() / 1024) << " (KB)")); ypos += y_inc; } -#endif if (gDisplayCameraPos) { @@ -1694,11 +1690,6 @@ LLViewerWindow::LLViewerWindow(const Params& p) LL_INFOS() << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << LL_ENDL; } - // Default to application directory. - LLViewerWindow::sSnapshotBaseName = "Snapshot"; - LLViewerWindow::sMovieBaseName = "SLmovie"; - resetSnapshotLoc(); - /* LLWindowCallbacks* callbacks, @@ -1877,6 +1868,11 @@ void LLViewerWindow::showSystemUIScaleFactorChanged() LLNotificationsUtil::add("SystemUIScaleFactorChanged", LLSD(), LLSD(), onSystemUIScaleFactorChanged); } +std::string LLViewerWindow::getLastSnapshotDir() +{ + return sSnapshotDir; +} + //static bool LLViewerWindow::onSystemUIScaleFactorChanged(const LLSD& notification, const LLSD& response) { @@ -1946,6 +1942,10 @@ void LLViewerWindow::initBase() // Create global views + // Login screen and main_view.xml need edit menus for preferences and browser + LL_DEBUGS("AppInit") << "initializing edit menu" << LL_ENDL; + initialize_edit_menu(); + // Create the floater view at the start so that other views can add children to it. // (But wait to add it as a child of the root view so that it will be in front of the // other views.) @@ -2156,6 +2156,15 @@ void LLViewerWindow::shutdownViews() RecordToChatConsole::getInstance()->stopRecorder(); LL_INFOS() << "Warning logger is cleaned." << LL_ENDL ; + gFocusMgr.unlockFocus(); + gFocusMgr.setMouseCapture(NULL); + gFocusMgr.setKeyboardFocus(NULL); + gFocusMgr.setTopCtrl(NULL); + if (mWindow) + { + mWindow->allowLanguageTextInput(NULL, FALSE); + } + delete mDebugText; mDebugText = NULL; @@ -2188,7 +2197,11 @@ void LLViewerWindow::shutdownViews() view_listener_t::cleanup(); LL_INFOS() << "view listeners destroyed." << LL_ENDL ; - + + // Clean up pointers that are going to be invalid. (todo: check sMenuContainer) + mProgressView = NULL; + mPopupView = NULL; + // Delete all child views. delete mRootView; mRootView = NULL; @@ -4397,20 +4410,21 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picke // Copy the directory + file name std::string filepath = picker.getFirstFile(); - LLViewerWindow::sSnapshotBaseName = gDirUtilp->getBaseFileName(filepath, true); - LLViewerWindow::sSnapshotDir = gDirUtilp->getDirName(filepath); + gSavedPerAccountSettings.setString("SnapshotBaseName", gDirUtilp->getBaseFileName(filepath, true)); + gSavedPerAccountSettings.setString("SnapshotBaseDir", gDirUtilp->getDirName(filepath)); } - if(LLViewerWindow::sSnapshotDir.empty()) + std::string snapshot_dir = sSnapshotDir; + if(snapshot_dir.empty()) { return FALSE; } // Check if there is enough free space to save snapshot #ifdef LL_WINDOWS - boost::filesystem::space_info b_space = boost::filesystem::space(utf8str_to_utf16str(sSnapshotDir)); + boost::filesystem::space_info b_space = boost::filesystem::space(utf8str_to_utf16str(snapshot_dir)); #else - boost::filesystem::space_info b_space = boost::filesystem::space(sSnapshotDir); + boost::filesystem::space_info b_space = boost::filesystem::space(snapshot_dir); #endif if (b_space.free < image->getDataSize()) { @@ -4448,7 +4462,7 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picke void LLViewerWindow::resetSnapshotLoc() { - sSnapshotDir.clear(); + gSavedPerAccountSettings.setString("SnapshotBaseDir", std::string()); } // static @@ -4502,6 +4516,17 @@ void LLViewerWindow::playSnapshotAnimAndSound() send_sound_trigger(LLUUID(gSavedSettings.getString("UISndSnapshot")), 1.0f); } +BOOL LLViewerWindow::isSnapshotLocSet() const +{ + std::string snapshot_dir = sSnapshotDir; + return !snapshot_dir.empty(); +} + +void LLViewerWindow::resetSnapshotLoc() const +{ + gSavedPerAccountSettings.setString("SnapshotBaseDir", std::string()); +} + BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type) { return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, do_rebuild, type); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 38178fa910..c01921641c 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -350,8 +350,8 @@ public: BOOL rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE); BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type); - BOOL isSnapshotLocSet() const { return ! sSnapshotDir.empty(); } - void resetSnapshotLoc() const { sSnapshotDir.clear(); } + BOOL isSnapshotLocSet() const; + void resetSnapshotLoc() const; BOOL saveImageNumbered(LLImageFormatted *image, BOOL force_picker, BOOL& insufficient_memory); // Reset the directory where snapshots are saved. @@ -419,7 +419,7 @@ public: bool getSystemUIScaleFactorChanged() { return mSystemUIScaleFactorChanged; } static void showSystemUIScaleFactorChanged(); - static std::string getLastSnapshotDir() { return sSnapshotDir; } + static std::string getLastSnapshotDir(); private: bool shouldShowToolTipFor(LLMouseHandler *mh); @@ -504,11 +504,6 @@ private: boost::scoped_ptr<LLWindowListener> mWindowListener; boost::scoped_ptr<LLViewerWindowListener> mViewerWindowListener; - static std::string sSnapshotBaseName; - static std::string sSnapshotDir; - - static std::string sMovieBaseName; - // Object temporarily hovered over while dragging LLPointer<LLViewerObject> mDragHoveredObject; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index d7a24c6823..b221dc7c35 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1007,7 +1007,7 @@ void LLVOAvatar::dumpBakedStatus() const ETextureIndex index = baked_dict->mTextureIndex; if (!inst->isTextureDefined(index)) { - LL_CONT << " " << LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mName; + LL_CONT << " " << (LLAvatarAppearanceDictionary::getInstance()->getTexture(index) ? LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mName : ""); } } LL_CONT << " ) " << inst->getUnbakedPixelAreaRank(); @@ -4715,7 +4715,7 @@ void LLVOAvatar::collectLocalTextureUUIDs(std::set<LLUUID>& ids) const if (imagep) { const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)texture_index); - if (texture_dict->mIsLocalTexture) + if (texture_dict && texture_dict->mIsLocalTexture) { ids.insert(imagep->getID()); } @@ -4872,8 +4872,8 @@ void LLVOAvatar::updateTextures() if (imagep) { const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)texture_index); - const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; - if (texture_dict->mIsLocalTexture) + const EBakedTextureIndex baked_index = texture_dict ? texture_dict->mBakedTextureIndex : EBakedTextureIndex::BAKED_NUM_INDICES; + if (texture_dict && texture_dict->mIsLocalTexture) { addLocalTextureStats((ETextureIndex)texture_index, imagep, texel_area_ratio, render_avatar, mBakedTextureDatas[baked_index].mIsUsed); } @@ -5322,6 +5322,11 @@ LLUUID LLVOAvatar::remapMotionID(const LLUUID& id) if (use_new_walk_run) result = ANIM_AGENT_RUN_NEW; } + // keeps in sync with setSex() related code (viewer controls sit's sex) + else if (id == ANIM_AGENT_SIT_FEMALE) + { + result = ANIM_AGENT_SIT; + } } @@ -6093,7 +6098,26 @@ void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints) //----------------------------------------------------------------------------- void LLVOAvatar::updateVisualParams() { - setSex( (getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE ); + ESex avatar_sex = (getVisualParamWeight("male") > 0.5f) ? SEX_MALE : SEX_FEMALE; + if (getSex() != avatar_sex) + { + if (mIsSitting && findMotion(avatar_sex == SEX_MALE ? ANIM_AGENT_SIT_FEMALE : ANIM_AGENT_SIT) != NULL) + { + // In some cases of gender change server changes sit motion with motion message, + // but in case of some avatars (legacy?) there is no update from server side, + // likely because server doesn't know about difference between motions + // (female and male sit ids are same server side, so it is likely unaware that it + // need to send update) + // Make sure motion is up to date + stopMotion(ANIM_AGENT_SIT); + setSex(avatar_sex); + startMotion(ANIM_AGENT_SIT); + } + else + { + setSex(avatar_sex); + } + } LLCharacter::updateVisualParams(); @@ -8515,6 +8539,8 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara apr_file_printf( file, "<linden_genepool version=\"1.0\">\n" ); apr_file_printf( file, "\n\t<archetype name=\"???\">\n" ); + bool agent_is_godlike = gAgent.isGodlikeWithoutAdminMenuFakery(); + if (group_by_wearables) { for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++) @@ -8540,8 +8566,11 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); if( te_image ) { - std::string uuid_str; - te_image->getID().toString( uuid_str ); + std::string uuid_str = LLUUID().asString(); + if (agent_is_godlike) + { + te_image->getID().toString(uuid_str); + } apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str()); } } @@ -8563,8 +8592,11 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); if( te_image ) { - std::string uuid_str; - te_image->getID().toString( uuid_str ); + std::string uuid_str = LLUUID().asString(); + if (agent_is_godlike) + { + te_image->getID().toString(uuid_str); + } apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str()); } } diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 10af524ee7..b2954f4de2 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -2606,6 +2606,8 @@ void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index ) if( mUpperBodyLayerSet ) mUpperBodyLayerSet->requestUpdate(); */ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index); + if (!texture_dict) + return; if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture) return; const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; @@ -2622,7 +2624,7 @@ LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const case TEX_HEAD_BODYPAINT: return mHeadLayerSet; */ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index); - if (texture_dict->mIsUsedByBakedTexture) + if (texture_dict && texture_dict->mIsUsedByBakedTexture) { const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; return getLayerSet(baked_index); @@ -2758,7 +2760,7 @@ void LLVOAvatarSelf::sendHoverHeight() const // class responder if nothing else gets added. // (comment from removed Responder) LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, update, - "Hover hight sent to sim", "Hover hight not sent to sim"); + "Hover height sent to sim", "Hover height not sent to sim"); mLastHoverOffsetSent = hover_offset; } } diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 838de48308..da4b6a5008 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -3997,13 +3997,13 @@ void LLVivoxVoiceClient::sessionNotificationEvent(std::string &sessionHandle, st { // Other end started typing // TODO: The proper way to add a typing notification seems to be LLIMMgr::processIMTypingStart(). - // It requires an LLIMInfo for the message, which we don't have here. + // It requires some info for the message, which we don't have here. } else if (!stricmp(notificationType.c_str(), "NotTyping")) { // Other end stopped typing // TODO: The proper way to remove a typing notification seems to be LLIMMgr::processIMTypingStop(). - // It requires an LLIMInfo for the message, which we don't have here. + // It requires some info for the message, which we don't have here. } else { diff --git a/indra/newview/skins/default/xui/de/floater_preferences.xml b/indra/newview/skins/default/xui/de/floater_preferences.xml index a4f6df515d..159f65be30 100644 --- a/indra/newview/skins/default/xui/de/floater_preferences.xml +++ b/indra/newview/skins/default/xui/de/floater_preferences.xml @@ -1,5 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Preferences" title="EINSTELLUNGEN"> + <floater.string name="email_unverified_tooltip"> + Bitte bestätigen Sie Ihre E-Mail-Adresse unter https://accounts.secondlife.com/change_email/ zur Aktivierung der E-Mail-Funktion des IM. + </floater.string> <button label="OK" label_selected="OK" name="OK"/> <button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/> <tab_container name="pref core"> diff --git a/indra/newview/skins/default/xui/de/floater_tos.xml b/indra/newview/skins/default/xui/de/floater_tos.xml index 47551d2a82..918b1a9be3 100644 --- a/indra/newview/skins/default/xui/de/floater_tos.xml +++ b/indra/newview/skins/default/xui/de/floater_tos.xml @@ -12,9 +12,10 @@ <text name="external_tos_required"> Sie müssen sich unter https://my.secondlife.com anmelden und die Servicebedingungen akzeptieren, bevor Sie fortfahren können. Vielen Dank! </text> + <check_box label="" name="agree_chk"/> <text name="agree_list"> - Ich habe die Allgemeinen Geschäftsbedingungen, die Datenschutzrichtlinie sowie die Servicebedingungen inklusive der Anforderungen zur Streitschlichtung gelesen und akzeptiere diese. - </text> - <button label="Weiter" label_selected="Weiter" name="Continue" top_delta="45"/> + Ich habe die Allgemeinen Geschäftsbedingungen, die Datenschutzrichtlinie sowie die Servicebedingungen inklusive der Anforderungen zur Streitschlichtung gelesen und akzeptiere diese. + </text> + <button label="Weiter" label_selected="Weiter" name="Continue"/> <button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/de/mime_types.xml b/indra/newview/skins/default/xui/de/mime_types.xml index 8728a57737..f8b4ae00c9 100644 --- a/indra/newview/skins/default/xui/de/mime_types.xml +++ b/indra/newview/skins/default/xui/de/mime_types.xml @@ -57,6 +57,11 @@ Echtzeit-Streaming </label> </scheme> + <scheme name="example"> + <label name="example_label"> + Beispiel-Plugin-Schema auslösen + </label> + </scheme> <scheme name="libvlc"> <label name="libvlc_label"> Von LibVLC unterstützte Medien diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index aefe30813c..8ff3ac770b 100644 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -692,6 +692,9 @@ Weitere Informationen finden Sie auf [_URL]. </url> <usetemplate ignoretext="Meine Hardware wird nicht unterstützt" name="okcancelignore" notext="Nein" yestext="Ja"/> </notification> + <notification name="RunLauncher"> + Bitte starten Sie die ausführbare Viewer-Datei nicht direkt. Aktualisieren Sie alle bestehenden Verknüpfungen, um stattdessen den LS_Launcher zu starten. + </notification> <notification name="OldGPUDriver"> Wahrscheinlich gibt es einen neueren Treiber für Ihren Grafikchip. Durch Aktualisieren der Grafiktreiber lässt sich die Leistung u. U. beträchtlich verbessern. @@ -1595,154 +1598,14 @@ Geben Sie das Objekt zum Verkauf frei und versuchen Sie es erneut. Raw-Terrain-Datei wurde heruntergeladen nach: [DOWNLOAD_PATH]. </notification> - <notification name="DownloadWindowsMandatory"> - Eine neue Version von [SUPPORT_SITE] ist verfügbar. -[MESSAGE] -Sie müssen das Update herunterladen, um [APP_NAME] weiter verwenden zu können. - <usetemplate name="okcancelbuttons" notext="Beenden" yestext="Herunterladen"/> - </notification> - <notification name="DownloadWindows"> - Eine neue Version von [APP_NAME] ist verfügbar. -[MESSAGE] -Dieses Update ist nicht erforderlich, für bessere Leistung und Stabilität sollte es jedoch installiert werden. - <usetemplate name="okcancelbuttons" notext="Weiter" yestext="Herunterladen"/> - </notification> - <notification name="DownloadWindowsReleaseForDownload"> - Eine neue Version von [APP_NAME] ist verfügbar. -[MESSAGE] -Dieses Update ist nicht erforderlich, für bessere Leistung und Stabilität sollte es jedoch installiert werden. - <usetemplate name="okcancelbuttons" notext="Weiter" yestext="Herunterladen"/> - </notification> - <notification name="DownloadLinuxMandatory"> - Eine neue Version von [SUPPORT_SITE] ist verfügbar. -[MESSAGE] -Sie müssen das Update herunterladen, um [APP_NAME] weiter verwenden zu können. - <usetemplate name="okcancelbuttons" notext="Beenden" yestext="Herunterladen"/> - </notification> - <notification name="DownloadLinux"> - Eine neue Version von [APP_NAME] ist verfügbar. -[MESSAGE] -Dieses Update ist nicht erforderlich, für bessere Leistung und Stabilität sollte es jedoch installiert werden. - <usetemplate name="okcancelbuttons" notext="Weiter" yestext="Herunterladen"/> - </notification> - <notification name="DownloadLinuxReleaseForDownload"> - Eine neue Version von [APP_NAME] ist verfügbar. -[MESSAGE] -Dieses Update ist nicht erforderlich, für bessere Leistung und Stabilität sollte es jedoch installiert werden. - <usetemplate name="okcancelbuttons" notext="Weiter" yestext="Herunterladen"/> - </notification> - <notification name="DownloadMacMandatory"> - Eine neue Version von [SUPPORT_SITE] ist verfügbar. -[MESSAGE] -Sie müssen das Update herunterladen, um [APP_NAME] weiter verwenden zu können. - -In Ihren Anwendungsordner herunterladen? - <usetemplate name="okcancelbuttons" notext="Beenden" yestext="Herunterladen"/> - </notification> - <notification name="DownloadMac"> - Eine neue Version von [APP_NAME] ist verfügbar. -[MESSAGE] -Dieses Update ist nicht erforderlich, für bessere Leistung und Stabilität sollte es jedoch installiert werden. - -In Ihren Anwendungsordner herunterladen? - <usetemplate name="okcancelbuttons" notext="Weiter" yestext="Herunterladen"/> - </notification> - <notification name="DownloadMacReleaseForDownload"> - Eine neue Version von [APP_NAME] ist verfügbar. -[MESSAGE] -Dieses Update ist nicht erforderlich, für bessere Leistung und Stabilität sollte es jedoch installiert werden. - -In Ihren Anwendungsordner herunterladen? - <usetemplate name="okcancelbuttons" notext="Weiter" yestext="Herunterladen"/> - </notification> - <notification name="FailedUpdateInstall"> - Beim Installieren des Viewer-Updates ist ein Fehler aufgetreten. -Laden Sie den neuesten Viewer von http://secondlife.com/download herunter und installieren Sie ihn. + <notification name="RequiredUpdate"> + Für die Anmeldung ist Version [VERSION] erforderlich. Diese sollte für Sie aktualisiert worden sein, was offenbar nicht geschehen ist. Bitte laden Sie die Datei unter https://secondlife.com/support/downloads/ herunter. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="FailedRequiredUpdateInstall"> - Ein erforderliches Update konnte nicht installiert werden. -Sie können sich erst anmelden, wenn [APP_NAME] aktualisiert wurde. - -Laden Sie den neuesten Viewer von http://secondlife.com/download herunter und installieren Sie ihn. + <notification name="LoginFailedUnknown"> + Die Anmeldung ist aus nicht bekannten Gründen leider fehlgeschlagen. Falls diese Meldung weiterhin angezeigt wird, besuchen Sie bitte die [SUPPORT_SITE]. <usetemplate name="okbutton" yestext="Beenden"/> </notification> - <notification name="UpdaterServiceNotRunning"> - Für Ihre SecondLife-Installation ist ein Update erforderlich. - -Sie können dieses Update von http://www.secondlife.com/downloads herunterladen oder jetzt installieren. - <usetemplate name="okcancelbuttons" notext="Second Life beenden" yestext="Jetzt herunterladen und installieren"/> - </notification> - <notification name="DownloadBackgroundTip"> - Für Ihre [APP_NAME]-Installation wurde ein Update heruntergeladen. -Version [VERSION] [[RELEASE_NOTES_FULL_URL] Informationen zu diesem Update] - <usetemplate name="okcancelbuttons" notext="Später..." yestext="Jetzt installieren und [APP_NAME] neu starten"/> - </notification> - <notification name="DownloadBackgroundDialog"> - Für Ihre [APP_NAME]-Installation wurde ein Update heruntergeladen. -Version [VERSION] [[RELEASE_NOTES_FULL_URL] Informationen zu diesem Update] - <usetemplate name="okcancelbuttons" notext="Später..." yestext="Jetzt installieren und [APP_NAME] neu starten"/> - </notification> - <notification name="RequiredUpdateDownloadedVerboseDialog"> - Ein erforderliches Softwareupdate wurde heruntergeladen. -Version [VERSION] [[INFO_URL] Infos zu diesem Update] - -Zur Installation des Updates muss [APP_NAME] neu gestartet werden. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="RequiredUpdateDownloadedDialog"> - Zur Installation des Updates muss [APP_NAME] neu gestartet werden. -[[INFO_URL] Infos zu diesem Update] - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="OtherChannelDownloadBackgroundTip"> - Für Ihre [APP_NAME]-Installation wurde ein Update heruntergeladen. -Version [VERSION] -Dieser experimentelle Viewer wurde durch einen [NEW_CHANNEL] Viewer ersetzt; -weitere Details zu diesem Update finden Sie [[INFO_URL] hier]. - <usetemplate name="okcancelbuttons" notext="Später..." yestext="Jetzt installieren und [APP_NAME] neu starten"/> - </notification> - <notification name="OtherChannelDownloadBackgroundDialog"> - Für Ihre [APP_NAME]-Installation wurde ein Update heruntergeladen. -Version [VERSION] -Dieser experimentelle Viewer wurde durch einen [NEW_CHANNEL] Viewer ersetzt; -weitere Infos zu diesem Update finden Sie [[INFO_URL] hier]. - <usetemplate name="okcancelbuttons" notext="Später..." yestext="Jetzt installieren und [APP_NAME] neu starten"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog"> - Ein erforderliches Softwareupdate wurde heruntergeladen. -Version [VERSION] -Dieser experimentelle Viewer wurde durch einen [NEW_CHANNEL] Viewer ersetzt; -weitere Infos zu diesem Update finden Sie [[INFO_URL] hier]. - -Zur Installation des Updates muss [APP_NAME] neu gestartet werden. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedDialog"> - Zur Installation des Updates muss [APP_NAME] neu gestartet werden. -Dieser experimentelle Viewer wurde durch einen [NEW_CHANNEL] Viewer ersetzt; -weitere Infos zu diesem Update finden Sie [[INFO_URL] hier]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateDownloadInProgress"> - Ein Update ist verfügbar. -Es wird im Hintergrund heruntergeladen. Wenn der Download fertig ist, werden Sie aufgefordert, den Viewer neu zu starten, damit die Installation abgeschlossen werden kann. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateDownloadComplete"> - Ein Update wurde heruntergeladen. Es wird beim Neustart installiert. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateCheckError"> - Beim Suchen nach einem Update ist ein Fehler aufgetreten. -Versuchen Sie es später erneut. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateViewerUpToDate"> - Ihr Viewer ist auf dem neuesten Stand. -Wenn Sie die neuesten Features und Fixes ausprobieren möchten, gehen Sie zur Seite „Alternate Viewers“. http://wiki.secondlife.com/wiki/Linden_Lab_Official:Alternate_Viewers. - <usetemplate name="okbutton" yestext="OK"/> - </notification> <notification name="DeedObjectToGroup"> Bei Übertragung dieses Objekts erhält die Gruppe: * An das Objekt bezahlte L$ @@ -3525,6 +3388,10 @@ Deaktivieren Sie alle SIP-ALG-Funktionen in Ihrem Router. Sprachkommunikation ist nicht möglich. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="NoVoiceConnect-GIAB"> + Es gibt Probleme mit der Verbindung zu Ihrem Voice-Server. Voice-Kommunikation ist leider nicht verfügbar. Überprüfen Sie Ihre Netzwerk- und Firewall-Konfiguration. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="AvatarRezLeftNotification"> (Seit [EXISTENCE] Sekunden inworld ) Avatar '[NAME]' hat als vollständig gerezzter Avatar die Welt verlassen. diff --git a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml index 4414bbfae7..3e596de55c 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml @@ -26,8 +26,9 @@ Softwareupdates: </text> <combo_box name="updater_service_combobox"> - <combo_box.item label="Automatisch installieren" name="Install_automatically"/> - <combo_box.item label="Ich werde Updates manuell herunterladen und installieren" name="Install_manual"/> + <combo_box.item label="Alle Updates automatisch installieren" name="Install_automatically"/> + <combo_box.item label="Mich fragen, wenn ein optionales Update bereit zur Installation ist" name="Install_ask"/> + <combo_box.item label="Nur zwingend erforderliche Updates installieren" name="Install_manual"/> </combo_box> <check_box label="Bereit, Release-Kandidaten zu verwenden" name="update_willing_to_test"/> <check_box label="Versionshinweise nach der Aktualisierung anzeigen" name="update_show_release_notes"/> diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 7ddcab9d34..3e66007627 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -38,8 +38,7 @@ Grafikinitialisierung fehlgeschlagen. Bitte aktualisieren Sie Ihren Grafiktreiber. </string> <string name="AboutHeader"> - [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) ([CHANNEL]) -[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] + [CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]Bit) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> <string name="BuildConfig"> Build-Konfiguration [BUILD_CONFIG] @@ -79,7 +78,7 @@ Erstellungszeit VFS (Cache): [VFS_TIME] <string name="AboutLibs"> J2C-Decoderversion: [J2C_VERSION] Audiotreiberversion: [AUDIO_DRIVER_VERSION] -CEF-Version: [LIBCEF_VERSION] +[LIBCEF_VERSION] LibVLC-Version: [LIBVLC_VERSION] Voice-Server-Version: [VOICE_VERSION] </string> @@ -1445,6 +1444,9 @@ besuchen Sie bitte http://secondlife.com/support <string name="InventoryNoMatchingItems"> Sie haben nicht das Richtige gefunden? Versuchen Sie es mit der [secondlife:///app/search/all/[SEARCH_TERM] Suche]. </string> + <string name="InventoryNoMatchingRecentItems"> + Sie haben nicht das Richtige gefunden? Versuchen Sie [secondlife:///app/inventory/filters Show filters]. + </string> <string name="PlacesNoMatchingItems"> Sie haben nicht das Richtige gefunden? Versuchen Sie es mit der [secondlife:///app/search/places/[SEARCH_TERM] Suche]. </string> diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index 334de8e3db..ef05fc3b39 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -502,7 +502,7 @@ name="Buy Land..." width="130" /> <button - enabled="false" + enabled="true" follows="left|top" height="23" label="Linden Sale" diff --git a/indra/newview/skins/default/xui/en/floater_auction.xml b/indra/newview/skins/default/xui/en/floater_auction.xml deleted file mode 100644 index 9c6d114c4c..0000000000 --- a/indra/newview/skins/default/xui/en/floater_auction.xml +++ /dev/null @@ -1,96 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - can_resize="true" - height="412" - layout="topleft" - min_height="412" - min_width="420" - name="floater_auction" - help_topic="floater_auction" - title="START LINDEN LAND SALE" - width="420"> - <floater.string - name="already for sale"> - You cannot auction parcels which are already for sale. - </floater.string> - <icon - bottom="280" - follows="left|right|top|bottom" - layout="topleft" - left="4" - name="snapshot_icon" - right="-4" - top="24" /> - <text - follows="left|right|bottom" - height="16" - layout="topleft" - left_delta="0" - name="parcel_text" - top_pad="12" - width="400" /> - <check_box - control_name="AuctionShowFence" - follows="left|bottom" - height="16" - initial_value="true" - label="Include yellow selection fence" - layout="topleft" - left_delta="0" - name="fence_check" - top_pad="12" - width="199" /> - <button - follows="left|bottom" - height="20" - label="Snapshot" - label_selected="Snapshot" - layout="topleft" - left_delta="0" - name="snapshot_btn" - top_pad="4" - width="150"> - <button.commit_callback - function="ClickSnapshot" /> - </button> - <button - follows="left|bottom" - height="20" - label="Sell to Anyone" - label_selected="Sell to Anyone" - layout="topleft" - left_delta="0" - name="sell_to_anyone_btn" - top_pad="4" - width="150"> - <button.commit_callback - function="ClickSellToAnyone" /> - </button> - <button - follows="left|bottom" - height="20" - label="Clear Settings" - label_selected="Clear Settings" - layout="topleft" - left_delta="0" - name="reset_parcel_btn" - top_pad="4" - width="150"> - <button.commit_callback - function="ClickResetParcel" /> - </button> - <button - follows="left|bottom" - height="20" - label="Start Auction" - label_selected="Start Auction" - layout="topleft" - left_pad="4" - name="start_auction_btn" - top_delta="0" - width="150"> - <button.commit_callback - function="ClickStartAuction" /> - </button> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml index 6667238232..45e16c59ae 100644 --- a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml +++ b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml @@ -418,30 +418,5 @@ width="90"> N: </text--> - <!--text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="10" - name="SaleLabel" - top_pad="5" - width="330"> - Mark Item: - </text--> - - <!--text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left="10" - name="TextPrice" - top_pad="5" - width="78"> - Price: L$ - </text--> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index c6b91a8b2f..c2500951a6 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -253,7 +253,7 @@ follows="left|top" height="16" layout="topleft" - name="ShadersText" + name="HardwareText" top_delta="20" left="10" width="128"> @@ -426,7 +426,7 @@ follows="left|top" height="16" layout="topleft" - name="AvatarText" + name="MeshText" top_delta="20" left="400" top="21" @@ -509,6 +509,7 @@ label_width="185" layout="topleft" left="420" + min_val="1" max_val="2" name="ObjectMeshDetail" show_text="false" @@ -916,7 +917,7 @@ are saved in a preset file. --> label="RenderAvatarMaxComplexity" layout="topleft" left="0" - name="RenderAvatarMaxNonImpostors" + name="RenderAvatarMaxComplexity" top_delta="0" width="0"> </check_box> diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml index 225266af86..8fa5b49573 100644 --- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml +++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml @@ -188,6 +188,7 @@ tool_tip="Category -- select the category that best describes this report" top_pad="5" width="313"> + <!-- Values can be populated from capability --> <combo_box.item label="Select category" name="Select_category" diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index edd1f42d92..6dea791dd9 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -88,14 +88,6 @@ function="Inventory.Share" /> </menu_item_call> <menu_item_call - label="Buy" - layout="topleft" - name="Task Buy"> - <menu_item_call.on_click - function="Inventory.DoToSelected" - parameter="task_buy" /> - </menu_item_call> - <menu_item_call label="Open" layout="topleft" name="Task Open"> diff --git a/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml index 01ca38f51a..5e16707340 100644 --- a/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml @@ -53,7 +53,7 @@ <menu_item_check label="Block Particles" layout="topleft" - name="MuteText"> + name="MuteParticles"> <on_check function="Block.Check" parameter="block_particles" /> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 90fc06aeb6..3cac835961 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1457,7 +1457,8 @@ </menu_item_call> <menu_item_call label="Set UI Size to Default" - name="Set UI Size to Default"> + name="Set UI Size to Default" + shortcut="control|alt|shift|R"> <menu_item_call.on_click function="View.DefaultUISize" /> </menu_item_call> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 756b711c4c..f69c3d261f 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -10414,14 +10414,6 @@ Not enough script resources available to attach object! </notification> <notification - icon="alertmodal.tga" - name="IllegalAttachment" - type="notify"> - <tag>fail</tag> - The attachment has requested a nonexistent point on the avatar. It has been attached to the chest instead. - </notification> - - <notification icon="alertmodal.tga" name="CantDropItemTrialUser" type="notify"> @@ -11031,7 +11023,7 @@ An internal error prevented us from properly updating your viewer. The L$ balan name="LargePrimAgentIntersect" type="notify"> <tag>fail</tag> -Cannot create large prims that intersect other players. Please re-try when other players have moved. +Cannot create large prims that intersect other residents. Please re-try when other residents have moved. </notification> <notification diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml index 574e5f3cbc..c324e24a86 100644 --- a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml @@ -109,6 +109,7 @@ layout="topleft" left="3" name="blocked" + keep_one_selected="false" tool_tip="List of currently blocked Residents" top_pad="4" right="-1"/> diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml index c8ce5cdebf..47aceb2c2e 100644 --- a/indra/newview/skins/default/xui/en/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml @@ -180,13 +180,20 @@ Maximum 200 per group daily <line_editor follows="left|top|right" enabled="false" - height="19" + height="20" layout="topleft" max_length_bytes="90" mouse_opaque="false" name="create_inventory_name" top_pad="2" width="285" /> + <icon + height="16" + layout="topleft" + left_delta="5" + name="create_inv_icon" + top_delta="2" + width="16" /> <text text_color="EmphasisColor" follows="left|top" @@ -350,6 +357,13 @@ Maximum 200 per group daily name="view_inventory_name" top_pad="8" width="250"/> + <icon + height="16" + layout="topleft" + left_delta="5" + name="view_inv_icon" + top_delta="2" + width="16" /> <button follows="left|top" height="23" diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml index dac4371a38..714d4166c0 100644 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel - height="680" + height="750" label="Members & Roles" layout="topleft" left="0" @@ -284,8 +284,7 @@ clicking on their names. width="20" /> <scroll_list.columns label="" - name="action" - width="270" /> + name="action" /> </scroll_list> </panel> <panel @@ -451,7 +450,39 @@ clicking on their names. </scroll_list> </panel> <panel - height="550" + height="90" + background_visible="false" + bg_alpha_color="FloaterUnfocusBorderColor" + layout="topleft" + follows="top|left|right" + left="0" + right="-1" + width="313" + mouse_opaque="false" + name="members_header" + top_pad="3" + visible="false"> + <text_editor + bg_readonly_color="Transparent" + text_readonly_color="EmphasisColor" + font="SansSerifSmall" + type="string" + enabled="false" + halign="left" + layout="topleft" + top_pad="0" + follows="left|top|right" + left="0" + right="-1" + height="90" + max_length="512" + name="member_action_description" + word_wrap="true"> + This Ability is 'Eject Members from this Group'. Only an Owner can eject another Owner. + </text_editor> + </panel> + <panel + height="460" background_visible="false" bg_alpha_color="FloaterUnfocusBorderColor" layout="topleft" @@ -599,11 +630,42 @@ clicking on their names. width="20" /> <scroll_list.columns label="" - name="action" - width="270" /> + name="action" /> </scroll_list> </panel> <panel + height="90" + background_visible="false" + bg_alpha_color="FloaterUnfocusBorderColor" + layout="topleft" + follows="top|left|right" + left="0" + right="-1" + width="313" + mouse_opaque="false" + name="roles_header" + top_pad="3" + visible="false"> + <text_editor + bg_readonly_color="Transparent" + text_readonly_color="EmphasisColor" + font="SansSerifSmall" + type="string" + enabled="false" + halign="left" + layout="topleft" + top_pad="0" + follows="left|top|right" + left="0" + right="-1" + height="90" + max_length="512" + name="role_action_description" + word_wrap="true"> + This Ability is 'Eject Members from this Group'. Only an Owner can eject another Owner. + </text_editor> + </panel> + <panel height="424" background_visible="false" bg_alpha_color="FloaterUnfocusBorderColor" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 2cb06d6877..8fc0f6f642 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -345,6 +345,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M left="0" multi_select="true" name="avatars_online" + keep_one_selected="false" show_permissions_granted="true" top="0" width="307" /> @@ -362,6 +363,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M left="0" multi_select="true" name="avatars_all" + keep_one_selected="false" show_permissions_granted="true" top="0" width="307" /> @@ -517,6 +519,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M height="388" layout="topleft" left="3" + keep_one_selected="false" name="group_list" right="-2" top_pad="4" /> @@ -631,6 +634,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M multi_select="true" name="avatar_list" show_last_interaction_time="true" + keep_one_selected="false" right="-2" top_pad="4" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml b/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml index 343c2db2f1..67eff2b762 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml @@ -104,7 +104,7 @@ height="12" layout="topleft" left="37" - name="title_animation" + name="title_model" top_pad="7" width="100"> Models diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index ffdbc5d227..8c769d87de 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -11,14 +11,6 @@ name="Texture" top="0" width="295"> - <panel.string - name="string repeats per meter"> - Repeats Per Meter - </panel.string> - <panel.string - name="string repeats per face"> - Repeats Per Face - </panel.string> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml index 6adede0362..2034409111 100644 --- a/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml +++ b/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml @@ -29,7 +29,7 @@ top="10" volume="true"> <slider.commit_callback - function="Pref.setControlFalse" + function="Vol.setControlFalse" parameter="MuteAudio" /> </slider> <button @@ -61,7 +61,7 @@ top_pad="4" volume="true"> <slider.commit_callback - function="Pref.setControlFalse" + function="Vol.setControlFalse" parameter="MuteUI" /> </slider> <button @@ -94,7 +94,7 @@ top_pad="4" volume="true"> <slider.commit_callback - function="Pref.setControlFalse" + function="Vol.setControlFalse" parameter="MuteAmbient" /> </slider> <button @@ -127,7 +127,7 @@ top_pad="4" volume="true"> <slider.commit_callback - function="Pref.setControlFalse" + function="Vol.setControlFalse" parameter="MuteSounds" /> </slider> <button @@ -144,7 +144,7 @@ tab_stop="false" width="16"> <button.commit_callback - function="Pref.SetSounds"/> + function="Vol.SetSounds"/> </button> <check_box name="gesture_audio_play_btn" @@ -173,7 +173,7 @@ top_pad="4" volume="true"> <slider.commit_callback - function="Pref.setControlFalse" + function="Vol.setControlFalse" parameter="MuteMusic" /> </slider> <button @@ -199,7 +199,7 @@ top_delta="2" width="350"> <check_box.commit_callback - function="Pref.updateMediaAutoPlayCheckbox"/> + function="Vol.updateMediaAutoPlayCheckbox"/> </check_box> <slider control_name="AudioLevelMedia" @@ -218,7 +218,7 @@ top_pad="4" volume="true"> <slider.commit_callback - function="Pref.setControlFalse" + function="Vol.setControlFalse" parameter="MuteMedia" /> </slider> <button @@ -246,7 +246,7 @@ name="enable_media" width="110"> <check_box.commit_callback - function="Pref.updateMediaAutoPlayCheckbox"/> + function="Vol.updateMediaAutoPlayCheckbox"/> </check_box> <slider control_name="AudioLevelVoice" @@ -265,7 +265,7 @@ show_text="false" volume="true"> <slider.commit_callback - function="Pref.setControlFalse" + function="Vol.setControlFalse" parameter="MuteVoice" /> </slider> <button diff --git a/indra/newview/skins/default/xui/en/role_actions.xml b/indra/newview/skins/default/xui/en/role_actions.xml index 8d058b0b53..f79d752fdb 100644 --- a/indra/newview/skins/default/xui/en/role_actions.xml +++ b/indra/newview/skins/default/xui/en/role_actions.xml @@ -4,10 +4,10 @@ description="These Abilities include powers to add and remove group Members, and allow new Members to join without an invitation." name="Membership"> <action description="Invite People to this Group" - longdescription="Invite People to this Group using the 'Invite' button in the Roles section > Members tab." + longdescription="Invite People to this Group using the 'Invite' button in the Roles & Members section > Members tab." name="member invite" value="1" /> - <action description="Eject Members from this Group" - longdescription="Eject Members from this Group using the 'Eject' button in the Roles section > Members tab. An Owner can eject anyone except another Owner. If you're not an Owner, a Member can be ejected from a group if, and only if, they're only in the Everyone Role, and NO other Roles. To remove Members from Roles, you need to have the 'Remove Members from Roles' Ability." + <action description="Eject Members belonging to the 'Everyone' role from this Group" + longdescription="Eject Members from this Group using the 'Eject' button in the Roles & Members section > Members tab. An Owner can eject anyone except another Owner. If you're not an Owner, a Member can be ejected from a group if, and only if, they're only in the Everyone Role, and NO other Roles. To remove Members from Roles, you need to have the 'Remove Members from Roles' Ability." name="member eject" value="2" /> <action description="Manage ban list" longdescription="Allows the group member to ban / un-ban Residents from this group." @@ -21,25 +21,25 @@ description="These Abilities include powers to add, remove, and change group Roles, add and remove Members in Roles, and assign Abilities to Roles." name="Roles"> <action description="Create new Roles" - longdescription="Create new Roles in the Roles section > Roles tab." + longdescription="Create new Roles in the Roles & Members section > Roles tab." name="role create" value="4" /> <action description="Delete Roles" - longdescription="Delete Roles in the Roles section > Roles tab." + longdescription="Delete Roles in the Roles & Members section > Roles tab." name="role delete" value="5" /> <action description="Change Role names, titles, descriptions, and whether Role members are publicly revealed" - longdescription="Change Role names, titles, descriptions, and whether Role members are publicly revealed. This is done at the bottom of the the Roles section > Roles tab after selecting a Role." + longdescription="Change Role names, titles, descriptions, and whether Role members are publicly revealed. This is done at the bottom of the the Roles & Members section > Roles tab after selecting a Role." name="role properties" value="6" /> <action description="Assign Members to Assigner's Roles" - longdescription="Assign Members to Roles in the list of Assigned Roles (Roles section > Members tab). A Member with this Ability can only add Members to a Role that the assigner is already in." + longdescription="Assign Members to Roles in the list of Assigned Roles (Roles & Members section > Members tab). A Member with this Ability can only add Members to a Role that the assigner is already in." name="role assign member limited" value="7" /> <action description="Assign Members to Any Role" - longdescription="Assign Members to Any Role in the list of Assigned Roles (Roles section > Members tab). *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you're doing before assigning this Ability." + longdescription="Assign Members to Any Role in the list of Assigned Roles (Roles & Members section > Members tab). *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you're doing before assigning this Ability." name="role assign member" value="8" /> <action description="Remove Members from Roles" - longdescription="Remove Members from Roles in the list of Assigned Roles (Roles section > Members tab). Owners can't be removed." + longdescription="Remove Members from Roles in the list of Assigned Roles (Roles & Members section > Members tab). Owners can't be removed." name="role remove member" value="9" /> <action description="Assign and Remove Abilities in Roles" - longdescription="Assign and Remove Abilities for each Role in the list of Allowed Abilities (Roles section > Roles tab). *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--all Abilities, potentially elevating themselves to near-Owner power. Be sure you know what you're doing before assigning this Ability." + longdescription="Assign and Remove Abilities for each Role in the list of Allowed Abilities (Roles & Members section > Roles tab). *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--all Abilities, potentially elevating themselves to near-Owner power. Be sure you know what you're doing before assigning this Ability." name="role change actions" value="10" /> </action_set> <action_set diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml index 1d98a84e25..2a1eb425ed 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml @@ -131,15 +131,6 @@ width="333"> tab_group="1" top_pad="6" follows="all" /> - <!-- <button - follows="bottom|left" - height="23" - label="New outfit" - layout="topleft" - left_pad="5" - right="-10" - name="newlook_btn" - width="100" />--> <panel class="panel_outfit_edit" filename="panel_outfit_edit.xml" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 7b6c580e7f..a40b94a542 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -4204,8 +4204,7 @@ Try enclosing path to the editor with double quotes. <string name="ExperiencePermissionShort10">Control Camera</string> <string name="ExperiencePermissionShort11">Teleport</string> <string name="ExperiencePermissionShort12">Permission</string> - <string name="ExperiencePermissionShortUnknown">Unknown: [Permission]</string> - + <!-- Conversation log messages --> <string name="logging_calls_disabled_log_empty"> Conversations are not being logged. To begin keeping a log, choose "Save: Log only" or "Save: Log and transcripts" under Preferences > Chat. diff --git a/indra/newview/skins/default/xui/es/floater_preferences.xml b/indra/newview/skins/default/xui/es/floater_preferences.xml index cb2a1dde14..edd0824e57 100644 --- a/indra/newview/skins/default/xui/es/floater_preferences.xml +++ b/indra/newview/skins/default/xui/es/floater_preferences.xml @@ -1,5 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Preferences" title="PREFERENCIAS"> + <floater.string name="email_unverified_tooltip"> + Por favor ingresa al link siguiente y verifica tu dirección de correo electrónico para permitir que IM te envíe un email: https://accounts.secondlife.com/change_email/ + </floater.string> <button label="OK" label_selected="OK" name="OK"/> <button label="Cancelar" label_selected="Cancelar" name="Cancel"/> <tab_container name="pref core"> diff --git a/indra/newview/skins/default/xui/es/floater_tos.xml b/indra/newview/skins/default/xui/es/floater_tos.xml index 8d83eb5b24..10c77a695e 100644 --- a/indra/newview/skins/default/xui/es/floater_tos.xml +++ b/indra/newview/skins/default/xui/es/floater_tos.xml @@ -12,9 +12,10 @@ <text name="external_tos_required"> Para poder proseguir, debes iniciar sesión en https://my.secondlife.com y aceptar las Condiciones del servicio. Gracias. </text> + <check_box label="" name="agree_chk"/> <text name="agree_list"> - He leído y acepto los Términos y Condiciones, la Política de privacidad y las Condiciones del servicio de Second Life, incluyendo los requerimientos para resolver disputas. - </text> + Leí los Términos y Condiciones, la Política de privacidad y las Condiciones del servicio de Second Life, incluyendo los requerimientos para resolver disputas. + </text> <button label="Continuar" label_selected="Continuar" name="Continue"/> <button label="Cancelar" label_selected="Cancelar" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/es/mime_types.xml b/indra/newview/skins/default/xui/es/mime_types.xml index 74e447c707..fad1cab56f 100644 --- a/indra/newview/skins/default/xui/es/mime_types.xml +++ b/indra/newview/skins/default/xui/es/mime_types.xml @@ -57,6 +57,11 @@ Real Time Streaming </label> </scheme> + <scheme name="example"> + <label name="example_label"> + Plugin Ejemplo desencadenador de esquema + </label> + </scheme> <scheme name="libvlc"> <label name="libvlc_label"> Medios compatibles con LibVLC diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml index 151886875b..fdf9003321 100644 --- a/indra/newview/skins/default/xui/es/notifications.xml +++ b/indra/newview/skins/default/xui/es/notifications.xml @@ -680,6 +680,9 @@ El objeto debe de haber sido borrado o estar fuera de rango ('out of range& </url> <usetemplate ignoretext="El hardware de mi ordenador no está admitido" name="okcancelignore" notext="No" yestext="Sí"/> </notification> + <notification name="RunLauncher"> + Por favor no inicies directamente el visualizador ejecutable. Actualiza los atajos existentes para utilizar SL_Launcher en vez. + </notification> <notification name="OldGPUDriver"> Probablemente ya existe un controlador más reciente para tu procesador de gráficos. La actualización del controlador de gráficos puede mejorar sustancialmente el rendimiento. @@ -1585,157 +1588,14 @@ Por favor, pon en venta el objeto y vuelve a intentarlo. Acabada la descarga del archivo raw de terreno en: [DOWNLOAD_PATH]. </notification> - <notification name="DownloadWindowsMandatory"> - Hay una versión nueva de [SECOND_LIFE] disponible. -[MESSAGE] -Debes descargar esta actualización para usar [SECOND_LIFE]. - <usetemplate name="okcancelbuttons" notext="Salir" yestext="Descargarla"/> - </notification> - <notification name="DownloadWindows"> - Hay una versión actualizada de [SECOND_LIFE] disponible. -[MESSAGE] -Esta actualización no es obligatoria, pero te sugerimos instalarla para mejorar el rendimiento y la estabilidad. - <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Descargarla"/> - </notification> - <notification name="DownloadWindowsReleaseForDownload"> - Hay una versión actualizada de [SECOND_LIFE] disponible. -[MESSAGE] -Esta actualización no es obligatoria, pero te sugerimos instalarla para mejorar el rendimiento y la estabilidad. - <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Descargarla"/> - </notification> - <notification name="DownloadLinuxMandatory"> - Hay una versión nueva de [SECOND_LIFE] disponible. -[MESSAGE] -Debes descargar esta actualización para usar [SECOND_LIFE]. - <usetemplate name="okcancelbuttons" notext="Salir" yestext="Descargar"/> - </notification> - <notification name="DownloadLinux"> - Hay una versión actualizada de [SECOND_LIFE] disponible. -[MESSAGE] -Esta actualización no es obligatoria, pero te sugerimos instalarla para mejorar el rendimiento y la estabilidad. - <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Descargar"/> - </notification> - <notification name="DownloadLinuxReleaseForDownload"> - Hay una versión actualizada de [SECOND_LIFE] disponible. -[MESSAGE] -Esta actualización no es obligatoria, pero te sugerimos instalarla para mejorar el rendimiento y la estabilidad. - <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Descargar"/> - </notification> - <notification name="DownloadMacMandatory"> - Hay una versión nueva de [SECOND_LIFE] disponible. -[MESSAGE] -Debes descargar esta actualización para usar [SECOND_LIFE]. - -¿Descargarla a tu carpeta de Programas? - <usetemplate name="okcancelbuttons" notext="Salir" yestext="Descargarla"/> - </notification> - <notification name="DownloadMac"> - Hay una versión actualizada de [SECOND_LIFE] disponible. -[MESSAGE] -Esta actualización no es obligatoria, pero te sugerimos instalarla para mejorar el rendimiento y la estabilidad. - -¿Descargarla a tu carpeta de Programas? - <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Descargarla"/> - </notification> - <notification name="DownloadMacReleaseForDownload"> - Hay una versión actualizada de [SECOND_LIFE] disponible. -[MESSAGE] -Esta actualización no es obligatoria, pero te sugerimos instalarla para mejorar el rendimiento y la estabilidad. - -¿Descargarla a tu carpeta de Programas? - <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Descargarla"/> - </notification> - <notification name="FailedUpdateInstall"> - Se ha producido un error al instalar la actualización del visor. -Descarga e instala el último visor a través de -http://secondlife.com/download. - <usetemplate name="okbutton" yestext="OK"/> + <notification name="RequiredUpdate"> + La versión [VERSION] es necesaria para iniciar sesión. Esto debería haber sido actualizado, pero parece que no fue así. Por favor, descarga desde https://secondlife.com/support/downloads/ + <usetemplate name="okbutton" yestext="Aceptar"/> </notification> - <notification name="FailedRequiredUpdateInstall"> - No hemos podido instalar una actualización necesaria. -No podrás iniciar sesión hasta que [APP_NAME] se haya actualizado. - -Descarga e instala el último visor a través de -http://secondlife.com/download. + <notification name="LoginFailedUnknown"> + Lo sentimos, error en el inicio de sesión, motivo desconocido. Si sigues recibiendo este mensaje, por favor, acude al [SUPPORT_SITE]. <usetemplate name="okbutton" yestext="Salir"/> </notification> - <notification name="UpdaterServiceNotRunning"> - Hay una actualización necesaria para la instalación de Second Life. - -Puedes descargar esta actualización de http://www.secondlife.com/downloads -o instalarla ahora. - <usetemplate name="okcancelbuttons" notext="Salir de Second Life" yestext="Descargar e instalar ahora"/> - </notification> - <notification name="DownloadBackgroundTip"> - Hemos descargado una actualización para la instalación de [APP_NAME]. -Versión [VERSION] [[RELEASE_NOTES_FULL_URL]; información acerca de esta actualización] - <usetemplate name="okcancelbuttons" notext="Más tarde..." yestext="Instalar ahora y reiniciar [NOMBRE_APL]"/> - </notification> - <notification name="DownloadBackgroundDialog"> - Hemos descargado una actualización para la instalación de [APP_NAME]. -Versión [VERSION] [[RELEASE_NOTES_FULL_URL]; información acerca de esta actualización] - <usetemplate name="okcancelbuttons" notext="Más tarde..." yestext="Instalar ahora y reiniciar [APP_NAME]"/> - </notification> - <notification name="RequiredUpdateDownloadedVerboseDialog"> - Hemos descargado una actualización de software necesaria. -Versión [VERSION] [[INFO_URL] Información sobre esta actualización] - -Para instalar la actualización, hay que reiniciar [APP_NAME]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="RequiredUpdateDownloadedDialog"> - Para instalar la actualización, hay que reiniciar [APP_NAME]. -[[INFO_URL] Información sobre esta actualización] - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="OtherChannelDownloadBackgroundTip"> - Hemos descargado una actualización aplicable a tu instalación de [APP_NAME]. -Versión [VERSION] -Este visor experimental se ha sustituido por un visor de [NEW_CHANNEL]. -Consulta [[INFO_URL] para informarte sobre esta actualización.] - <usetemplate name="okcancelbuttons" notext="Más tarde..." yestext="Instalar ahora y reiniciar [APP_NAME]"/> - </notification> - <notification name="OtherChannelDownloadBackgroundDialog"> - Hemos descargado una actualización aplicable a tu instalación de [APP_NAME]. -Versión [VERSION] -Este visor experimental se ha sustituido por un visor de [NEW_CHANNEL]. -Consulta [[INFO_URL] Información sobre esta actualización]. - <usetemplate name="okcancelbuttons" notext="Más tarde..." yestext="Instalar ahora y reiniciar [APP_NAME]"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog"> - Hemos descargado una actualización de software necesaria. -Versión [VERSION] -Este visor experimental se ha sustituido por un visor de [NEW_CHANNEL]. -Consulta [[INFO_URL] Información sobre esta actualización]. - -Para instalar la actualización, hay que reiniciar [APP_NAME]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedDialog"> - Para instalar la actualización, hay que reiniciar [APP_NAME]. -Este visor experimental se ha sustituido por un visor de [NEW_CHANNEL]. -Consulta [[INFO_URL] Información sobre esta actualización]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateDownloadInProgress"> - Está disponible una actualización. -Se está descargando en segundo plano y, en cuanto esté lista, te pediremos que reinicies el visor para terminar de instalarla. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateDownloadComplete"> - Se ha descargado una actualización. Se instalará durante el reinicio. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateCheckError"> - Ha ocurrido un error al buscar actualizaciones. -Repite la operación más adelante. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateViewerUpToDate"> - El visor está actualizado. -Si estás impaciente por probar las nuevas funciones y correcciones, lee la página sobre los visores alternativos. http://wiki.secondlife.com/wiki/Linden_Lab_Official:Alternate_Viewers. - <usetemplate name="okbutton" yestext="OK"/> - </notification> <notification name="DeedObjectToGroup"> Transferir este objeto al grupo hará que: * Reciba los L$ pagados en el objeto @@ -3511,6 +3371,10 @@ Desactiva las funciones SIP ALG de tu router. No podrás establecer comunicaciones de voz. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="NoVoiceConnect-GIAB"> + Tenemos problemas de conexión con tu servidor de voz: No podrás establecer comunicaciones de voz. Comprueba la configuración de la red y del servidor de seguridad. + <usetemplate name="okbutton" yestext="Aceptar"/> + </notification> <notification name="AvatarRezLeftNotification"> ( [EXISTENCE] segundos vivo) El avatar '[NAME]' ya estaba totalmente cargado al salir. diff --git a/indra/newview/skins/default/xui/es/panel_preferences_setup.xml b/indra/newview/skins/default/xui/es/panel_preferences_setup.xml index 0b3ca03bcc..34947ca478 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_setup.xml @@ -26,8 +26,9 @@ Actualizaciones de software: </text> <combo_box name="updater_service_combobox"> - <combo_box.item label="Instalar automáticamente" name="Install_automatically"/> - <combo_box.item label="Descargaré e instalaré manualmente las actualizaciones" name="Install_manual"/> + <combo_box.item label="Instalar cada actualización automáticamente" name="Install_automatically"/> + <combo_box.item label="Preguntarme cuando una actualización opcional está disponible para instalar" name="Install_ask"/> + <combo_box.item label="Instalar sólo actualizaciones obligatorias" name="Install_manual"/> </combo_box> <check_box label="Admitir candidatos a la versión comercial a la hora de realizar actualizaciones" name="update_willing_to_test"/> <check_box label="Mostrar las notas de la versión después de la actualización" name="update_show_release_notes"/> diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index c4744a8222..341c6d2fe8 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -29,7 +29,7 @@ Error de inicialización de gráficos. Actualiza tu controlador de gráficos. </string> <string name="AboutHeader"> - [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) ([CHANNEL]) + [CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> <string name="BuildConfig"> @@ -68,11 +68,11 @@ Memoria de textura: [TEXTURE_MEMORY]MB Tiempo de creación de VFS (caché): [VFS_TIME] </string> <string name="AboutLibs"> - Versión de J2C Decoder: [J2C_VERSION] -Versión de Audio Driver: [AUDIO_DRIVER_VERSION] -Versión de CEF: [LIBCEF_VERSION] -Versión de LibVLC: [LIBVLC_VERSION] -Versión de Voice Server: [VOICE_VERSION] + Versión de descodificador J2C: [J2C_VERSION] +Versión del controlador audio: [AUDIO_DRIVER_VERSION] +[LIBCEF_VERSION] +Versión LibVLC: [LIBVLC_VERSION] +Versión del servidor de voz: [VOICE_VERSION] </string> <string name="AboutTraffic"> Paquetes perdidos: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) @@ -1427,6 +1427,9 @@ http://secondlife.com/support para obtener ayuda sobre cómo solucionar este pro <string name="InventoryNoMatchingItems"> ¿No encuentras lo que buscas? Prueba con [secondlife:///app/search/all/[SEARCH_TERM] Buscar]. </string> + <string name="InventoryNoMatchingRecentItems"> + ¿No encuentras lo que buscas? Intenta [secondlife:///app/inventory/filters Show filters]. + </string> <string name="PlacesNoMatchingItems"> ¿No encuentras lo que buscas? Prueba con [secondlife:///app/search/places/[SEARCH_TERM] Buscar]. </string> diff --git a/indra/newview/skins/default/xui/fr/floater_preferences.xml b/indra/newview/skins/default/xui/fr/floater_preferences.xml index 25887bb5f7..1730202031 100644 --- a/indra/newview/skins/default/xui/fr/floater_preferences.xml +++ b/indra/newview/skins/default/xui/fr/floater_preferences.xml @@ -1,5 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Preferences" title="PRÉFÉRENCES"> + <floater.string name="email_unverified_tooltip"> + Veuillez vérifier votre adresse électronique pour autoriser les IM par courriel en vous rendant à l'adresse https://accounts.secondlife.com/change_email/ + </floater.string> <button label="OK" label_selected="OK" name="OK"/> <button label="Annuler" label_selected="Annuler" name="Cancel"/> <tab_container name="pref core"> diff --git a/indra/newview/skins/default/xui/fr/floater_tos.xml b/indra/newview/skins/default/xui/fr/floater_tos.xml index 4e359e6482..ca6800e835 100644 --- a/indra/newview/skins/default/xui/fr/floater_tos.xml +++ b/indra/newview/skins/default/xui/fr/floater_tos.xml @@ -12,8 +12,9 @@ <text name="external_tos_required"> Vous devez vous rendre sur https://my.secondlife.com et vous connecter pour accepter les Conditions d’utilisation avant de pouvoir continuer. Merci ! </text> + <check_box label="" name="agree_chk"/> <text name="agree_list"> - J'ai lu et j'accepte les termes et conditions; la Politique de confidentialité et les Conditions d'utilisation de Second Life, y compris ls exigences de résolution des différends. + J'ai lu et j'accepte les termes et les conditions, la Politique de confidentialité et les Conditions d'utilisation du service, y compris les conditions de résolution des différends. </text> <button label="Continuer" label_selected="Continuer" name="Continue"/> <button label="Annuler" label_selected="Annuler" name="Cancel"/> diff --git a/indra/newview/skins/default/xui/fr/mime_types.xml b/indra/newview/skins/default/xui/fr/mime_types.xml index 15b1dc5a23..243752eb9d 100644 --- a/indra/newview/skins/default/xui/fr/mime_types.xml +++ b/indra/newview/skins/default/xui/fr/mime_types.xml @@ -57,6 +57,11 @@ Flux en temps réel </label> </scheme> + <scheme name="example"> + <label name="example_label"> + Exemple de programme de déclenchement du Plugin + </label> + </scheme> <scheme name="libvlc"> <label name="libvlc_label"> Médias pris en charge par LibVLC diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index faa744d8da..6225eba119 100644 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -684,6 +684,9 @@ Consulter [_URL] pour en savoir plus ? </url> <usetemplate ignoretext="Mon matériel n'est pas pris en charge" name="okcancelignore" notext="Non" yestext="Oui"/> </notification> + <notification name="RunLauncher"> + Veuillez ne pas exécuter la visionneuse directement. Actualiser tout raccourci existant pour lancer SL_Launcher + </notification> <notification name="OldGPUDriver"> Il existe probablement un pilote plus récent pour votre puce graphique. La mise à jour des pilotes graphiques est susceptible d’améliorer considérablement les performances. @@ -1578,157 +1581,14 @@ Veuillez choisir un objet à vendre et réessayer. Téléchargement du fichier de terrain raw effectué vers : [DOWNLOAD_PATH]. </notification> - <notification name="DownloadWindowsMandatory"> - Une nouvelle version de [APP_NAME] est disponible. -[MESSAGE] -Pour utiliser [APP_NAME], vous devez télécharger cette mise à jour. - <usetemplate name="okcancelbuttons" notext="Quitter" yestext="Télécharger"/> - </notification> - <notification name="DownloadWindows"> - Une mise à jour de [APP_NAME] est disponible. -[MESSAGE] -Cette mise à jour n'est pas requise mais si vous voulez une meilleure performance et plus de stabilité, nous vous recommandons de l'installer. - <usetemplate name="okcancelbuttons" notext="Continuer" yestext="Télécharger"/> - </notification> - <notification name="DownloadWindowsReleaseForDownload"> - Une mise à jour de [APP_NAME] est disponible. -[MESSAGE] -Cette mise à jour n'est pas requise mais si vous voulez une meilleure performance et plus de stabilité, nous vous recommandons de l'installer. - <usetemplate name="okcancelbuttons" notext="Continuer" yestext="Télécharger"/> - </notification> - <notification name="DownloadLinuxMandatory"> - Une nouvelle version de [APP_NAME] est disponible. -[MESSAGE] -Pour utiliser [APP_NAME], vous devez télécharger cette mise à jour. - <usetemplate name="okcancelbuttons" notext="Quitter" yestext="Télécharger"/> - </notification> - <notification name="DownloadLinux"> - Une mise à jour de [APP_NAME] est disponible. -[MESSAGE] -Cette mise à jour n'est pas requise mais si vous voulez une meilleure performance et plus de stabilité, nous vous recommandons de l'installer. - <usetemplate name="okcancelbuttons" notext="Continuer" yestext="Télécharger"/> - </notification> - <notification name="DownloadLinuxReleaseForDownload"> - Une mise à jour de [APP_NAME] est disponible. -[MESSAGE] -Cette mise à jour n'est pas requise mais si vous voulez une meilleure performance et plus de stabilité, nous vous recommandons de l'installer. - <usetemplate name="okcancelbuttons" notext="Continuer" yestext="Télécharger"/> - </notification> - <notification name="DownloadMacMandatory"> - Une nouvelle version de [APP_NAME] est disponible. -[MESSAGE] -Pour utiliser [APP_NAME], vous devez télécharger cette mise à jour. - -Télécharger vers le dossier Applications ? - <usetemplate name="okcancelbuttons" notext="Quitter" yestext="Télécharger"/> - </notification> - <notification name="DownloadMac"> - Une mise à jour de [APP_NAME] est disponible. -[MESSAGE] -Cette mise à jour n'est pas requise mais si vous voulez une meilleure performance et plus de stabilité, nous vous recommandons de l'installer. - -Télécharger vers le dossier Applications ? - <usetemplate name="okcancelbuttons" notext="Continuer" yestext="Télécharger"/> - </notification> - <notification name="DownloadMacReleaseForDownload"> - Une mise à jour de [APP_NAME] est disponible. -[MESSAGE] -Cette mise à jour n'est pas requise mais si vous voulez une meilleure performance et plus de stabilité, nous vous recommandons de l'installer. - -Télécharger vers le dossier Applications ? - <usetemplate name="okcancelbuttons" notext="Continuer" yestext="Télécharger"/> - </notification> - <notification name="FailedUpdateInstall"> - Une erreur est survenue lors de l'installation de la mise à jour du client. -Veuillez télécharger et installer la dernière version du client à la page Web -http://secondlife.com/download. + <notification name="RequiredUpdate"> + La version [VERSION] est nécessaire pour vous connecter. Cette version aurait dû être mise à jour, mais visiblement, elle ne l'a pas été. Veuillez télécharger la dernière version sur https://secondlife.com/support/downloads/ <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="FailedRequiredUpdateInstall"> - Impossible d'installer une mise à jour requise. -Vous ne pourrez pas vous connecter tant que [APP_NAME] ne sera pas mis à jour. - -Veuillez télécharger et installer la dernière version du client à la page Web -http://secondlife.com/download. + <notification name="LoginFailedUnknown"> + Désolé, la connexion a échoué pour un raison non reconnue. Si ce message persiste, veuillez consulter la page [SUPPORT_SITE]. <usetemplate name="okbutton" yestext="Quitter"/> </notification> - <notification name="UpdaterServiceNotRunning"> - Une mise à jour requise pour votre installation Second Life existe. - -Pour la télécharger, accédez à http://www.secondlife.com/downloads. -Vous pouvez également l'installer dès maintenant. - <usetemplate name="okcancelbuttons" notext="Quitter Second Life" yestext="Télécharger et installer maintenant"/> - </notification> - <notification name="DownloadBackgroundTip"> - Nous avons téléchargé une mise à jour de votre installation [APP_NAME]. -Version [VERSION] [[RELEASE_NOTES_FULL_URL] Informations relatives à cette mise à jour] - <usetemplate name="okcancelbuttons" notext="Ultérieurement..." yestext="Installer maintenant et redémarrer [APP_NAME]"/> - </notification> - <notification name="DownloadBackgroundDialog"> - Nous avons téléchargé une mise à jour de votre installation [APP_NAME]. -Version [VERSION] [[RELEASE_NOTES_FULL_URL] Informations relatives à cette mise à jour] - <usetemplate name="okcancelbuttons" notext="Ultérieurement..." yestext="Installer maintenant et redémarrer [APP_NAME]"/> - </notification> - <notification name="RequiredUpdateDownloadedVerboseDialog"> - Nous avons téléchargé une mise à jour logicielle requise. -Version [VERSION] [Informations au sujet de cette mise à jour [INFO_URL]] - -[APP_NAME] doit être redémarré pour que la mise à jour soit installée. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="RequiredUpdateDownloadedDialog"> - [APP_NAME] doit être redémarré pour que la mise à jour soit installée. -[Informations au sujet de cette mise à jour [INFO_URL]] - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="OtherChannelDownloadBackgroundTip"> - Nous avons téléchargé une mise à jour de votre installation [APP_NAME]. -Version [VERSION] -Le client expérimental a été remplacé par un nouveau client [NEW_CHANNEL] ; -consultez [[INFO_URL] pour en savoir plus sur cette mise à jour] - <usetemplate name="okcancelbuttons" notext="Ultérieurement..." yestext="Installer maintenant et redémarrer [APP_NAME]"/> - </notification> - <notification name="OtherChannelDownloadBackgroundDialog"> - Nous avons téléchargé une mise à jour de votre installation [APP_NAME]. -Version [VERSION] -Le client expérimental a été remplacé par un nouveau client [NEW_CHANNEL] ; -consultez [Informations au sujet de cette mise à jour [INFO_URL]] - <usetemplate name="okcancelbuttons" notext="Ultérieurement..." yestext="Installer maintenant et redémarrer [APP_NAME]"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog"> - Nous avons téléchargé une mise à jour logicielle requise. -Version [VERSION] -Le client expérimental a été remplacé par un nouveau client [NEW_CHANNEL] ; -consultez [Informations au sujet de cette mise à jour [INFO_URL]] - -[APP_NAME] doit être redémarré pour que la mise à jour soit installée. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedDialog"> - [APP_NAME] doit être redémarré pour que la mise à jour soit installée. -Le client expérimental a été remplacé par un nouveau client [NEW_CHANNEL] ; -consultez [Informations au sujet de cette mise à jour [INFO_URL]] - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateDownloadInProgress"> - Une mise à jour est disponible. -Elle est en cours de téléchargement en arrière-plan et nous vous inviterons à redémarrer votre client pour terminer son installation dès qu’elle est prête. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateDownloadComplete"> - Une mise à jour a été téléchargée. Elle sera installée au redémarrage. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateCheckError"> - Une erreur est survenue lors de la recherche de mises à jour. -Veuillez réessayer ultérieurement. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateViewerUpToDate"> - Votre client est à jour. -Si vous êtes impatients de découvrir les dernières fonctionnalités et corrections, consultez la page Autres clients. http://wiki.secondlife.com/wiki/Linden_Lab_Official:Alternate_Viewers. - <usetemplate name="okbutton" yestext="OK"/> - </notification> <notification name="DeedObjectToGroup"> Si vous cédez cet objet, le groupe : * recevra les L$ versés pour l'objet ; @@ -3512,6 +3372,10 @@ Veuillez désactiver toute fonctionnalité SIP ALG dans votre routeur. Aucune communication vocale n'est disponible. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="NoVoiceConnect-GIAB"> + Nous rencontrons des difficultés pour vous connecter à votre serveur vocal. Aucune communication vocale n'est disponible. Veuillez vérifier la configuration de votre réseau et de votre pare-feu. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="AvatarRezLeftNotification"> ([EXISTENCE] secondes d'existence) Départ de l'avatar [NAME] entièrement chargé. diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml b/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml index 3b819b40c8..7ac84fb4bd 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml @@ -26,8 +26,9 @@ Mises à jour logicielles : </text> <combo_box name="updater_service_combobox"> - <combo_box.item label="Installation automatique" name="Install_automatically"/> - <combo_box.item label="Je téléchargerai et installerai les mises à jour manuellement" name="Install_manual"/> + <combo_box.item label="Installer chaque mise à jour automatiquement" name="Install_automatically"/> + <combo_box.item label="Toujours me demander lorsqu'une mise à jour facultative est prête à être installée" name="Install_ask"/> + <combo_box.item label="Installer uniquement les mises à jour obligatoires" name="Install_manual"/> </combo_box> <check_box label="Accepte de passer aux versions avant sortie officielle" name="update_willing_to_test"/> <check_box label="Afficher les notes de version après la mise à jour" name="update_show_release_notes"/> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index 599ef126da..d76beee93d 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -38,8 +38,8 @@ Échec d'initialisation des graphiques. Veuillez mettre votre pilote graphique à jour. </string> <string name="AboutHeader"> - [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) ([CHANNEL]) -[[VIEWER_RELEASE_NOTES_URL] [Notes de version]] + [CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) +[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> <string name="BuildConfig"> Configuration de la construction [BUILD_CONFIG] @@ -77,11 +77,11 @@ Mémoire textures : [TEXTURE_MEMORY] Mo Durée de création VFS (cache) : [VFS_TIME] </string> <string name="AboutLibs"> - Version J2C Decoder : [J2C_VERSION] -Version Audio Driver : [AUDIO_DRIVER_VERSION] -Version CEF : [LIBCEF_VERSION] -Version LibVLC : [LIBVLC_VERSION] -Version serveur vocal : [VOICE_VERSION] + J2C Decoder Version: [J2C_VERSION] +Audio Driver Version: [AUDIO_DRIVER_VERSION] +[LIBCEF_VERSION] +LibVLC Version: [LIBVLC_VERSION] +Voice Server Version: [VOICE_VERSION] </string> <string name="AboutTraffic"> Paquets perdus : [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) @@ -1445,6 +1445,9 @@ http://secondlife.com/support pour vous aider à résoudre ce problème. <string name="InventoryNoMatchingItems"> Vous n'avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/all/[SEARCH_TERM] Rechercher]. </string> + <string name="InventoryNoMatchingRecentItems"> + Avez-vous trouvé ce que vous cherchiez ? Essayez [secondlife:///app/inventory/filters Show filters]. + </string> <string name="PlacesNoMatchingItems"> Vous n'avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/places/[SEARCH_TERM] Rechercher]. </string> diff --git a/indra/newview/skins/default/xui/it/floater_preferences.xml b/indra/newview/skins/default/xui/it/floater_preferences.xml index 189ba195c5..895b6eef3c 100644 --- a/indra/newview/skins/default/xui/it/floater_preferences.xml +++ b/indra/newview/skins/default/xui/it/floater_preferences.xml @@ -1,5 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Preferences" title="PREFERENZE"> + <floater.string name="email_unverified_tooltip"> + Verifica la tua email per abilitare l’opzione “Invia IM all'e-mail” visitando il sito https://accounts.secondlife.com/change_email/ + </floater.string> <button label="OK" label_selected="OK" name="OK"/> <button label="Annulla" label_selected="Annulla" name="Cancel"/> <tab_container name="pref core" tab_width="100"> diff --git a/indra/newview/skins/default/xui/it/floater_tos.xml b/indra/newview/skins/default/xui/it/floater_tos.xml index 0016df1882..31314d1800 100644 --- a/indra/newview/skins/default/xui/it/floater_tos.xml +++ b/indra/newview/skins/default/xui/it/floater_tos.xml @@ -12,9 +12,10 @@ <text name="external_tos_required"> Per continuare, visita https://my.secondlife.com e accedi per accettare i Termini del servizio. Grazie. </text> + <check_box label="" name="agree_chk"/> <text name="agree_list"> - Ho letto e sono d’accordo con i Termini e le Condizioni di Second Life, le clausole di riservatezza, i Termini del Servizio, compresi i requisiti per la risoluzione delle dispute. - </text> + Ho letto e accettato i Termini e le Condizioni di Second Life, le clausole di riservatezza e i Termini del Servizio, compresi i requisiti per la risoluzione delle dispute. + </text> <button label="Continua" label_selected="Continua" name="Continue"/> <button label="Annulla" label_selected="Annulla" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/it/mime_types.xml b/indra/newview/skins/default/xui/it/mime_types.xml index 7e528b0688..1f6f9223fe 100644 --- a/indra/newview/skins/default/xui/it/mime_types.xml +++ b/indra/newview/skins/default/xui/it/mime_types.xml @@ -57,6 +57,11 @@ Streaming in tempo reale </label> </scheme> + <scheme name="example"> + <label name="example_label"> + Tasto di comando schema plugin di esempio + </label> + </scheme> <scheme name="libvlc"> <label name="libvlc_label"> Media supportati da LibVLC diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml index 8714fc9170..cf354b8f4f 100644 --- a/indra/newview/skins/default/xui/it/notifications.xml +++ b/indra/newview/skins/default/xui/it/notifications.xml @@ -682,6 +682,9 @@ Visitare [_URL] per ulteriori informazioni? </url> <usetemplate ignoretext="L'hardware di questo computer non è compatibile" name="okcancelignore" notext="No" yestext="Si"/> </notification> + <notification name="RunLauncher"> + Non avviare direttamente il viewer eseguibile. Aggiorna le scorciatoie attuali per avviare invece il Launcher_SL. + </notification> <notification name="OldGPUDriver"> È probabile che ci sia un driver aggiornato per il processore grafico. L'aggiornamento dei driver della grafica può migliorare le prestazioni in maniera significativa. @@ -1581,156 +1584,13 @@ Imposta l'oggetto per la vendita e riprova. Hai terminato di scaricare il file del terreno nella cartella: [DOWNLOAD_PATH]. </notification> - <notification name="DownloadWindowsMandatory"> - È disponibile una nuova versione di [APP_NAME]. -[MESSAGE] -Devi scaricare questo aggiornamento per utilizzare [APP_NAME]. - <usetemplate name="okcancelbuttons" notext="Esci" yestext="Scarica l'aggiornamento"/> - </notification> - <notification name="DownloadWindows"> - È disponibile una versione aggiornata di [APP_NAME]. -[MESSAGE] -Questo aggiornamento non è necessario, ma ti consigliamo di installarlo per migliorare il rendimento e la stabilità. - <usetemplate name="okcancelbuttons" notext="Continua" yestext="Scarica l'aggiornamento"/> - </notification> - <notification name="DownloadWindowsReleaseForDownload"> - È disponibile una versione aggiornata di [APP_NAME]. -[MESSAGE] -Questo aggiornamento non è necessario, ma ti consigliamo di installarlo per migliorare il rendimento e la stabilità. - <usetemplate name="okcancelbuttons" notext="Continua" yestext="Scarica l'aggiornamento"/> - </notification> - <notification name="DownloadLinuxMandatory"> - È disponibile una nuova versione di [APP_NAME]. -[MESSAGE] -Devi scaricare questo aggiornamento per utilizzare [APP_NAME]. - <usetemplate name="okcancelbuttons" notext="Esci" yestext="Scarica"/> - </notification> - <notification name="DownloadLinux"> - È disponibile una versione aggiornata di [APP_NAME]. -[MESSAGE] -Questo aggiornamento non è necessario, ma ti consigliamo di installarlo per migliorare il rendimento e la stabilità. - <usetemplate name="okcancelbuttons" notext="Continua" yestext="Scarica"/> - </notification> - <notification name="DownloadLinuxReleaseForDownload"> - È disponibile una versione aggiornata di [APP_NAME]. -[MESSAGE] -Questo aggiornamento non è necessario, ma ti consigliamo di installarlo per migliorare il rendimento e la stabilità. - <usetemplate name="okcancelbuttons" notext="Continua" yestext="Scarica"/> - </notification> - <notification name="DownloadMacMandatory"> - È disponibile una nuova versione di [APP_NAME]. -[MESSAGE] -Devi scaricare questo aggiornamento per utilizzare [APP_NAME]. - -Scaricare nella cartella Applicazioni? - <usetemplate name="okcancelbuttons" notext="Esci" yestext="Scarica l'aggiornamento"/> - </notification> - <notification name="DownloadMac"> - È disponibile una versione aggiornata di [APP_NAME]. -[MESSAGE] -Questo aggiornamento non è necessario, ma ti consigliamo di installarlo per migliorare il rendimento e la stabilità. - -Scaricare nella cartella Applicazioni? - <usetemplate name="okcancelbuttons" notext="Continua" yestext="Scarica l'aggiornamento"/> - </notification> - <notification name="DownloadMacReleaseForDownload"> - È disponibile una versione aggiornata di [APP_NAME]. -[MESSAGE] -Questo aggiornamento non è necessario, ma ti consigliamo di installarlo per migliorare il rendimento e la stabilità. - -Scaricare nella cartella Applicazioni? - <usetemplate name="okcancelbuttons" notext="Continua" yestext="Scarica l'aggiornamento"/> - </notification> - <notification name="FailedUpdateInstall"> - Si è verificato un errore durante l'aggiornamento del viewer. -Scarica e installa la versione più recente del viewer da -http://secondlife.com/download. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="FailedRequiredUpdateInstall"> - Non è stato possibile installare un aggiornamento richiesto. -Non potrai accedere fino a quando non verrà aggiornato [APP_NAME]. - -Scarica e installa la versione più recente del viewer da -http://secondlife.com/download. - <usetemplate name="okbutton" yestext="Esci"/> - </notification> - <notification name="UpdaterServiceNotRunning"> - È disponibile un aggiornamento obbligatorio per l'installazione di Second Life. - -Puoi scaricare questo aggiornamento da http://www.secondlife.com/downloads -oppure puoi installarlo adesso. - <usetemplate name="okcancelbuttons" notext="Esci da Second Life" yestext="Scarica e aggiorna adesso"/> - </notification> - <notification name="DownloadBackgroundTip"> - È stato scaricato un aggiornamento dell'installazione di [APP_NAME]. -Versione [VERSION] [[RELEASE_NOTES_FULL_URL] Informazioni su questo aggiornamento] - <usetemplate name="okcancelbuttons" notext="Più tardi..." yestext="Installa ora e riavvia [APP_NAME]"/> - </notification> - <notification name="DownloadBackgroundDialog"> - È stato scaricato un aggiornamento dell'installazione di [APP_NAME]. -Versione [VERSION] [[RELEASE_NOTES_FULL_URL] Informazioni su questo aggiornamento] - <usetemplate name="okcancelbuttons" notext="Più tardi..." yestext="Installa ora e riavvia [APP_NAME]"/> - </notification> - <notification name="RequiredUpdateDownloadedVerboseDialog"> - È stato scaricato un aggiornamento obbligatorio del software. -Versione [VERSION] [[INFO_URL] Informazioni su questo aggiornamento] - -Per installare l'aggiornamento è necessario riavviare [APP_NAME]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="RequiredUpdateDownloadedDialog"> - Per installare l'aggiornamento è necessario riavviare [APP_NAME]. -[[INFO_URL] Informazioni su questo aggiornamento] - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="OtherChannelDownloadBackgroundTip"> - È stato scaricato un aggiornamento dell'installazione di [APP_NAME]. -Versione [VERSION] -Questo viewer sperimentale è stato sostituito con un viewer [NEW_CHANNEL]; -vedi [[INFO_URL] per informazioni su queesto aggiornamento] - <usetemplate name="okcancelbuttons" notext="Più tardi..." yestext="Installa ora e riavvia [APP_NAME]"/> - </notification> - <notification name="OtherChannelDownloadBackgroundDialog"> - È stato scaricato un aggiornamento dell'installazione di [APP_NAME]. -Versione [VERSION] -Questo viewer sperimentale è stato sostituito con un viewer [NEW_CHANNEL]; -vedi [[INFO_URL] Informazioni su questo aggiornamento] - <usetemplate name="okcancelbuttons" notext="Più tardi..." yestext="Installa ora e riavvia [APP_NAME]"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog"> - È stato scaricato un aggiornamento obbligatorio del software. -Versione [VERSION] -Questo viewer sperimentale è stato sostituito con un viewer [NEW_CHANNEL]; -vedi [[INFO_URL] Informazioni su questo aggiornamento] - -Per installare l'aggiornamento è necessario riavviare [APP_NAME]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedDialog"> - Per installare l'aggiornamento è necessario riavviare [APP_NAME]. -Questo viewer sperimentale è stato sostituito con un viewer [NEW_CHANNEL]; -vedi [[INFO_URL] Informazioni su questo aggiornamento] - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateDownloadInProgress"> - È disponibile un aggiornamento. -È in fase di download. Al termine ti verrà chiesto di riavviare il computer per completare l'installazione. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateDownloadComplete"> - È stato scaricato un aggiornamento. Verrà installato durante il riavvio. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateCheckError"> - Si è verificato un errore durante la ricerca dell'aggiornamento. -Riprova più tardi. + <notification name="RequiredUpdate"> + É richiesta la versione [VERSION] per l’accesso. Sembra che dovresti avere la versione aggiornata, ma cosí non é. Scaricala da https://secondlife.com/support/downloads/ <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="UpdateViewerUpToDate"> - Il Viewer è aggiornato. -Per provare le funzioni e modifiche più recenti, visita la pagina Alternate Viewers. http://wiki.secondlife.com/wiki/Linden_Lab_Official:Alternate_Viewers. - <usetemplate name="okbutton" yestext="OK"/> + <notification name="LoginFailedUnknown"> + Spiacenti, accesso non riuscito per ragioni sconosciute. Se continui a visualizzare questo messaggio, visita il [SUPPORT_SITE]. + <usetemplate name="okbutton" yestext="Chiudi"/> </notification> <notification name="DeedObjectToGroup"> La cessione di questo oggetto farà in modo che il gruppo: @@ -3515,6 +3375,10 @@ Disabilita la funzione SIP ALG del router. La comunicazione voce non sará possibile. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="NoVoiceConnect-GIAB"> + Stiamo riscontrando dei problemi nel connetterci al tuo server di voce. La comunicazione voce non sará possibile. Controlla le tue impostazione di rete e della firewall. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="AvatarRezLeftNotification"> ( presente da [EXISTENCE] secondi ) Avatar '[NAME]' è partito completamente caricato. diff --git a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml index d34bb7c3a4..24375e0de1 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml @@ -26,8 +26,9 @@ Aggiornamenti software: </text> <combo_box name="updater_service_combobox"> - <combo_box.item label="Installa automaticamente" name="Install_automatically"/> - <combo_box.item label="Scarica e installa manualmente gli aggiornamenti" name="Install_manual"/> + <combo_box.item label="Installa gli aggiornamenti automaticamente" name="Install_automatically"/> + <combo_box.item label="Chiedimi quando è pronto un aggiornamento facoltativo" name="Install_ask"/> + <combo_box.item label="Installa solo gli aggiornamenti obbligatori" name="Install_manual"/> </combo_box> <check_box label="Disponibile agli aggiornamenti con versioni non rilasciate" name="update_willing_to_test"/> <check_box label="Mostra note di release dopo l'aggiornamento" name="update_show_release_notes"/> diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index 75bfb9119b..ad74e16170 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -35,7 +35,7 @@ Inizializzazione grafica non riuscita. Aggiorna il driver della scheda grafica! </string> <string name="AboutHeader"> - [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) ([CHANNEL]) + [CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> <string name="BuildConfig"> @@ -74,11 +74,10 @@ Memoria texture: [TEXTURE_MEMORY] MB Data/ora creazione VFS (cache): [VFS_TIME] </string> <string name="AboutLibs"> - Versione J2C Decoder: [J2C_VERSION] -Versione Driver audio: [AUDIO_DRIVER_VERSION] -Versione CEF: [LIBCEF_VERSION] -Versione LibVLC: [LIBVLC_VERSION] -Versione Server voice: [VOICE_VERSION] + J2C Versione decoder: [J2C_VERSION] +Versione del driver audio: [AUDIO_DRIVER_VERSION][LIBCEF_VERSION] +Versione LibVLC: [LIBVLC_VERSION] +Versione server voce: [VOICE_VERSION] </string> <string name="AboutTraffic"> Pacchetti perduti: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) @@ -1436,6 +1435,9 @@ http://secondlife.com/support per risolvere il problema. <string name="InventoryNoMatchingItems"> Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/all/[SEARCH_TERM] Cerca]. </string> + <string name="InventoryNoMatchingRecentItems"> + Non hai trovato ció che cercavi? Prova [secondlife:///app/inventory/filters Show filters]. + </string> <string name="PlacesNoMatchingItems"> Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/places/[SEARCH_TERM] Cerca]. </string> diff --git a/indra/newview/skins/default/xui/ja/floater_preferences.xml b/indra/newview/skins/default/xui/ja/floater_preferences.xml index fa337defe7..7482c4772a 100644 --- a/indra/newview/skins/default/xui/ja/floater_preferences.xml +++ b/indra/newview/skins/default/xui/ja/floater_preferences.xml @@ -1,5 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Preferences" title="環境設定"> + <floater.string name="email_unverified_tooltip"> + IM を有効にするには、https://accounts.secondlife.com/change_email/ からあなたのメールアドレスを確認してください + </floater.string> <button label="OK" label_selected="OK" name="OK"/> <button label="取り消し" label_selected="取り消し" name="Cancel"/> <tab_container name="pref core"> diff --git a/indra/newview/skins/default/xui/ja/floater_tos.xml b/indra/newview/skins/default/xui/ja/floater_tos.xml index 8045a1f1f7..8a6a6ff58a 100644 --- a/indra/newview/skins/default/xui/ja/floater_tos.xml +++ b/indra/newview/skins/default/xui/ja/floater_tos.xml @@ -12,9 +12,10 @@ <text name="external_tos_required"> 操作を続けるに、https://my.secondlife.com に移動し、利用規約に同意する必要があります。 </text> + <check_box label="" name="agree_chk"/> <text name="agree_list"> - 私は以下の内容を読み、同意します。Second Life の利用規約、プライバシーポリシー、およびサービス規約(紛争解決のための必要条件を含む)。 - </text> + 私は、Second Life の利用規約、プライバシーポリシー、およびサービス規約(紛争解決のための必要条件を含む)を読み、同意しました。 + </text> <button label="続行" label_selected="続行" name="Continue"/> <button label="取り消し" label_selected="取り消し" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/ja/mime_types.xml b/indra/newview/skins/default/xui/ja/mime_types.xml index 6de9244b40..3b29a622a4 100644 --- a/indra/newview/skins/default/xui/ja/mime_types.xml +++ b/indra/newview/skins/default/xui/ja/mime_types.xml @@ -57,6 +57,11 @@ リアルタイム・ストリーミング </label> </scheme> + <scheme name="example"> + <label name="example_label"> + 例 プラグイン スキーム トリガー + </label> + </scheme> <scheme name="libvlc"> <label name="libvlc_label"> LibVLC 対応メディア diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index f76ee9033b..67586efc9e 100644 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -702,6 +702,9 @@ L$ が不足しているのでこのグループに参加することができ </url> <usetemplate ignoretext="使用中のコンピューターのハードウェアがサポートされていないとき" name="okcancelignore" notext="いいえ" yestext="はい"/> </notification> + <notification name="RunLauncher"> + ビューワ実行ファイルを直接実行しないでください。代わりに、既存のショートカットの内のどれかをアップデートし、SL_Launcher を実行してください。 + </notification> <notification name="OldGPUDriver"> グラフィックスチップに最新のドライバがある可能性があります。グラフィックドライバを更新することにより、大幅にパフォーマンスが向上します。 @@ -1610,154 +1613,14 @@ SHA1 フィンガープリント: [MD5_DIGEST] 未加工の地形ファイルをダウンロードしました: [DOWNLOAD_PATH] </notification> - <notification name="DownloadWindowsMandatory"> - [APP_NAME] の最新バージョンがご利用可能です。 -[MESSAGE] -[APP_NAME] をご利用になるにはこのアップデートは必須です。 - <usetemplate name="okcancelbuttons" notext="終了" yestext="ダウンロード"/> - </notification> - <notification name="DownloadWindows"> - [APP_NAME] のアップデートバージョンがご利用可能です。 -[MESSAGE] -このアップデートは必須ではありませんが、パフォーマンス向上のためにインストールをおすすめします。 - <usetemplate name="okcancelbuttons" notext="続行" yestext="ダウンロード"/> - </notification> - <notification name="DownloadWindowsReleaseForDownload"> - [APP_NAME] のアップデートバージョンがご利用可能です。 -[MESSAGE] -このアップデートは必須ではありませんが、パフォーマンス向上のためにインストールをおすすめします。 - <usetemplate name="okcancelbuttons" notext="続行" yestext="ダウンロード"/> - </notification> - <notification name="DownloadLinuxMandatory"> - [APP_NAME] の最新バージョンがご利用可能です。 -[MESSAGE] -[APP_NAME] をご利用になるにはこのアップデートは必須です。 - <usetemplate name="okcancelbuttons" notext="終了" yestext="ダウンロード"/> - </notification> - <notification name="DownloadLinux"> - [APP_NAME] のアップデートバージョンがご利用可能です。 -[MESSAGE] -このアップデートは必須ではありませんが、パフォーマンス向上のためにインストールをおすすめします。 - <usetemplate name="okcancelbuttons" notext="続ける" yestext="ダウンロード"/> - </notification> - <notification name="DownloadLinuxReleaseForDownload"> - [APP_NAME] のアップデートバージョンがご利用可能です。 -[MESSAGE] -このアップデートは必須ではありませんが、パフォーマンス向上のためにインストールをおすすめします。 - <usetemplate name="okcancelbuttons" notext="続ける" yestext="ダウンロード"/> - </notification> - <notification name="DownloadMacMandatory"> - [APP_NAME] の最新バージョンがご利用可能です。 -[MESSAGE] -[APP_NAME] をご利用になるにはこのアップデートは必須です。 - -あなたのアプリケーションフォルダにダウンロードしますか? - <usetemplate name="okcancelbuttons" notext="終了" yestext="ダウンロード"/> - </notification> - <notification name="DownloadMac"> - [APP_NAME] のアップデートバージョンがご利用可能です。 -[MESSAGE] -このアップデートは必須ではありませんが、パフォーマンス向上のためにインストールをおすすめします。 - -あなたのアプリケーションフォルダにダウンロードしますか? - <usetemplate name="okcancelbuttons" notext="続行" yestext="ダウンロード"/> - </notification> - <notification name="DownloadMacReleaseForDownload"> - [APP_NAME] のアップデートバージョンがご利用可能です。 -[MESSAGE] -このアップデートは必須ではありませんが、パフォーマンス向上のためにインストールをおすすめします。 - -あなたのアプリケーションフォルダにダウンロードしますか? - <usetemplate name="okcancelbuttons" notext="続行" yestext="ダウンロード"/> - </notification> - <notification name="FailedUpdateInstall"> - ビューワのアップデートをインストール中にエラーが発生しました。 -http://secondlife.com/download から最新バージョンをダウンロードしてインストールしてください。 + <notification name="RequiredUpdate"> + ログインするには、バージョン [VERSION] が必要です。このアップデートは自動的に行われるものですが、まだ実行されてないようです。https://secondlife.com/support/downloads/ からダウンロードしてください。 <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="FailedRequiredUpdateInstall"> - 必要なアップデートをインストールできませんでした。 -[APP_NAME] がアップデートされるまでログインできません。 - -http://secondlife.com/download から最新バージョンをダウンロードしてインストールしてください。 + <notification name="LoginFailedUnknown"> + 申し訳ありませんが、不明な理由によってログインに失敗しました。このメッセージが何度も出る場合は、[SUPPORT_SITE] をご確認ください。 <usetemplate name="okbutton" yestext="終了"/> </notification> - <notification name="UpdaterServiceNotRunning"> - お使いの Second Life に必要なアップデートがインストールされていません。 - -このアップデートは、http://www.secondlife.com/downloads からダウンロードして、今すぐインストールできます。 - <usetemplate name="okcancelbuttons" notext="終了" yestext="今すぐダウンロードしてインストール"/> - </notification> - <notification name="DownloadBackgroundTip"> - お使いの [APP_NAME] に必要なアップデートをダウンロードしました。 -バージョン [VERSION] [[RELEASE_NOTES_FULL_URL] このアップデートに関する情報] - <usetemplate name="okcancelbuttons" notext="後で実行" yestext="今すぐインストールして [APP_NAME] を再起動"/> - </notification> - <notification name="DownloadBackgroundDialog"> - お使いの [APP_NAME] に必要なアップデートをダウンロードしました。 -バージョン [VERSION] [[RELEASE_NOTES_FULL_URL] このアップデートに関する情報] - <usetemplate name="okcancelbuttons" notext="後で実行" yestext="今すぐインストールして [APP_NAME] を再起動"/> - </notification> - <notification name="RequiredUpdateDownloadedVerboseDialog"> - 必要なソフトウェアのアップデートをダウンロードしました。 -バージョン [VERSION] [[INFO_URL] このアップデートに関する情報] - -アップデートをインストールするには [APP_NAME] を再起動する必要があります。 - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="RequiredUpdateDownloadedDialog"> - アップデートをインストールするには [APP_NAME] を再起動する必要があります。 -[[INFO_URL] このアップデートに関する情報] - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="OtherChannelDownloadBackgroundTip"> - お使いの [APP_NAME] に必要なアップデートをダウンロードしました。 -バージョン [VERSION] -この試験的なビューアが [NEW_CHANNEL] ビューアに置き換えられています; -このアップデートの詳細については、[[INFO_URL] を参照してください] - <usetemplate name="okcancelbuttons" notext="後で実行" yestext="今すぐインストールして [APP_NAME] を再起動"/> - </notification> - <notification name="OtherChannelDownloadBackgroundDialog"> - お使いの [APP_NAME] に必要なアップデートをダウンロードしました。 -バージョン [VERSION] -この試験的なビューアが [NEW_CHANNEL] ビューアに置き換えられています; -[[INFO_URL] このアップデートに関する情報] を参照 - <usetemplate name="okcancelbuttons" notext="後で実行" yestext="今すぐインストールして [APP_NAME] を再起動"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog"> - 必要なソフトウェアのアップデートをダウンロードしました。 -バージョン [VERSION] -この試験的なビューアが [NEW_CHANNEL] ビューアに置き換えられています; -[[INFO_URL] このアップデートに関する情報] を参照 - -アップデートをインストールするには [APP_NAME] を再起動する必要があります。 - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedDialog"> - アップデートをインストールするには [APP_NAME] を再起動する必要があります。 -この試験的なビューアが [NEW_CHANNEL] ビューアに置き換えられています; -[[INFO_URL] このアップデートに関する情報] を参照 - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateDownloadInProgress"> - アップデートを利用できます。 -バックグラウンドでアップデートをダウンロードしています。準備ができ次第、インストールを完了するために、ビューワを再起動するように求めるメッセージが表示されます。 - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateDownloadComplete"> - アップデートがダウンロードされました。再起動中にインストールされます。 - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateCheckError"> - アップデートの確認中にエラーが発生しました。 -あとでもう一度お試しください。 - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateViewerUpToDate"> - ご利用のビューワは最新です! -最新の機能と修正を今すぐ試したい場合は、代替ビューワページ (http://wiki.secondlife.com/wiki/Linden_Lab_Official:Alternate_Viewers) をチェックしてください。 - <usetemplate name="okbutton" yestext="OK"/> - </notification> <notification name="DeedObjectToGroup"> このオブジェクトを譲渡するとグループは以下のことが可能です: * オブジェクトに支払われた L$ を受領します。 @@ -3550,6 +3413,10 @@ M キーを押して変更します。 ボイスチャットによるコミュニケーションが利用できません。 <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="NoVoiceConnect-GIAB"> + ボイスサーバーに接続できません。ボイスチャットによるコミュニケーションが利用できません。お使いのネットワークやファイアウォールの設定を確認してください。 + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="AvatarRezLeftNotification"> ( [EXISTENCE] 秒) アバター「 NAME 」が完全に読み込まれました。 diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml b/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml index 4c40ba7f7b..ac5e43c4d4 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml @@ -26,8 +26,9 @@ ソフトウェアアップデート: </text> <combo_box name="updater_service_combobox"> - <combo_box.item label="自動的にインストール" name="Install_automatically"/> - <combo_box.item label="更新を手動でダウンロードしてインストールします" name="Install_manual"/> + <combo_box.item label="各アップデートを自動的にインストールする" name="Install_automatically"/> + <combo_box.item label="オプションのアップデートのインストール準備ができたら通知する" name="Install_ask"/> + <combo_box.item label="必須アップデートのみインストールする" name="Install_manual"/> </combo_box> <check_box label="release candidate にアップグレードします" name="update_willing_to_test"/> <check_box label="更新後にリリースノートを表示する" name="update_show_release_notes"/> diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index 5d3fb1787e..5ca7ddd92c 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -38,7 +38,7 @@ グラフィックを初期化できませんでした。グラフィックドライバを更新してください。 </string> <string name="AboutHeader"> - [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) ([CHANNEL]) + [CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> <string name="BuildConfig"> @@ -77,11 +77,10 @@ LOD 係数: [LOD_FACTOR] VFS(キャッシュ)作成時間: [VFS_TIME] </string> <string name="AboutLibs"> - J2C デコーダバージョン:[J2C_VERSION] -オーディオドライババージョン:[AUDIO_DRIVER_VERSION] -CEF バージョン: [LIBCEF_VERSION] -LibVLC バージョン: [LIBVLC_VERSION] -ボイスサーバーバージョン:[VOICE_VERSION] + J2C デコーダバージョン: [J2C_VERSION] +オーディオドライババージョン: [AUDIO_DRIVER_VERSION] +[LIBCEF_VERSION] LibVLC バージョン: [LIBVLC_VERSION] +ボイスサーバーバージョン: [VOICE_VERSION] </string> <string name="AboutTraffic"> パケットロス:[PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) @@ -1445,6 +1444,9 @@ support@secondlife.com にお問い合わせください。 <string name="InventoryNoMatchingItems"> お探しのものは見つかりましたか? [secondlife:///app/search/all/[SEARCH_TERM] 検索] をお試しください。 </string> + <string name="InventoryNoMatchingRecentItems"> + お探しのものは見つかりましたか?[secondlife:///app/inventory/filters Show filters] をお試しください。 + </string> <string name="PlacesNoMatchingItems"> お探しのものは見つかりましたか? [secondlife:///app/search/places/[SEARCH_TERM] 検索] をお試しください。 </string> diff --git a/indra/newview/skins/default/xui/pt/floater_preferences.xml b/indra/newview/skins/default/xui/pt/floater_preferences.xml index b3cd20b0e9..8a2ef83a3b 100644 --- a/indra/newview/skins/default/xui/pt/floater_preferences.xml +++ b/indra/newview/skins/default/xui/pt/floater_preferences.xml @@ -1,5 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Preferences" title="PREFERÊNCIAS"> + <floater.string name="email_unverified_tooltip"> + Vericiar seu e-mail para habilitar o IM para envio de e-mail pelo endereço https://accounts.secondlife.com/change_email/ + </floater.string> <button label="OK" label_selected="OK" name="OK"/> <button label="Cancelar" label_selected="Cancelar" name="Cancel"/> <tab_container name="pref core"> diff --git a/indra/newview/skins/default/xui/pt/floater_tos.xml b/indra/newview/skins/default/xui/pt/floater_tos.xml index 09a90bc76c..0581c95bc6 100644 --- a/indra/newview/skins/default/xui/pt/floater_tos.xml +++ b/indra/newview/skins/default/xui/pt/floater_tos.xml @@ -12,9 +12,10 @@ <text name="external_tos_required"> Antes de continuar, você precisará visitar https://my.secondlife.com e fazer login para aceitar os Termos de Serviço. Obrigado! </text> + <check_box label="" name="agree_chk"/> <text name="agree_list"> - Li e concordo os Termos e condições, Política de privacidade e Termos de serviço do Second Life, incluindo as exigências para resolver disputas. - </text> + Eu lie e concordo com os Termos e condições, Política de privacidade e Termos de serviço do Second Life, incluindo as exigências para resolver disputas. + </text> <button label="Continuar" label_selected="Continuar" name="Continue"/> <button label="Cancelar" label_selected="Cancelar" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/pt/mime_types.xml b/indra/newview/skins/default/xui/pt/mime_types.xml index 54902f165b..75307f0aaf 100644 --- a/indra/newview/skins/default/xui/pt/mime_types.xml +++ b/indra/newview/skins/default/xui/pt/mime_types.xml @@ -57,6 +57,11 @@ Transmissão em tempo real </label> </scheme> + <scheme name="example"> + <label name="example_label"> + Exemplo Plugin scheme trigger + </label> + </scheme> <scheme name="libvlc"> <label name="libvlc_label"> Mídia com suporte a LibVLC diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml index d22e0f7bb7..b66f65c682 100644 --- a/indra/newview/skins/default/xui/pt/notifications.xml +++ b/indra/newview/skins/default/xui/pt/notifications.xml @@ -678,6 +678,9 @@ Consultar [_URL] para mais informações? </url> <usetemplate ignoretext="O hardware do meu computador não é suportado" name="okcancelignore" notext="Não" yestext="Sim"/> </notification> + <notification name="RunLauncher"> + Não executar diretamente o visualizador executável. Atualizar quaisquer atalhos existentes para executar o SL_Launcher. + </notification> <notification name="OldGPUDriver"> Provavelmente, há um driver mais recente para o seu chip gráfico. A atualização dos drivers gráficos pode melhorar significativamente o desempenho. @@ -1572,157 +1575,14 @@ Por favor, ponha o objeto à venda e tente novamente. Download do arquivo de terreno RAW concluído em: [DOWNLOAD_PATH] </notification> - <notification name="DownloadWindowsMandatory"> - Existe uma nova versão do [APP_NAME] -[MESSAGE] -Baixe a atualização para usar o [APP_NAME]. - <usetemplate name="okcancelbuttons" notext="Sair" yestext="Atualizar"/> - </notification> - <notification name="DownloadWindows"> - Existe uma nova versão do [APP_NAME] -[MESSAGE] -Não é preciso passar para a nova versão, mas ela pode melhorar o desempenho e estabilidade do visualizador. - <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Atualizar"/> - </notification> - <notification name="DownloadWindowsReleaseForDownload"> - Existe uma nova versão do [APP_NAME] -[MESSAGE] -Não é preciso passar para a nova versão, mas ela pode melhorar o desempenho e estabilidade do visualizador. - <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Atualizar"/> - </notification> - <notification name="DownloadLinuxMandatory"> - Existe uma nova versão do [APP_NAME] -[MESSAGE] -Baixe a atualização para usar o [APP_NAME]. - <usetemplate name="okcancelbuttons" notext="Sair" yestext="Baixar"/> - </notification> - <notification name="DownloadLinux"> - Existe uma nova versão do [APP_NAME] -[MESSAGE] -Não é preciso passar para a nova versão, mas ela pode melhorar o desempenho e estabilidade. - <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Baixar"/> - </notification> - <notification name="DownloadLinuxReleaseForDownload"> - Existe uma nova versão do [APP_NAME] -[MESSAGE] -Não é preciso passar para a nova versão, mas ela pode melhorar o desempenho e estabilidade. - <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Baixar"/> - </notification> - <notification name="DownloadMacMandatory"> - Existe uma nova versão do [APP_NAME] -[MESSAGE] -Baixe a atualização para usar o [APP_NAME]. - -Salvar na pasta Aplicativos? - <usetemplate name="okcancelbuttons" notext="Sair" yestext="Atualizar"/> - </notification> - <notification name="DownloadMac"> - Existe uma nova versão do [APP_NAME] -[MESSAGE] -Não é preciso passar para a nova versão, mas ela pode melhorar o desempenho e estabilidade do visualizador. - -Salvar na pasta Aplicativos? - <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Atualizar"/> - </notification> - <notification name="DownloadMacReleaseForDownload"> - Existe uma nova versão do [APP_NAME] -[MESSAGE] -Não é preciso passar para a nova versão, mas ela pode melhorar o desempenho e estabilidade do visualizador. - -Salvar na pasta Aplicativos? - <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Atualizar"/> - </notification> - <notification name="FailedUpdateInstall"> - Ocorreu um erro de atualização do visualizador. -Baixe e instale a versão mais recente do visualizador em -http://secondlife.com/download. + <notification name="RequiredUpdate"> + Versão [VERSION] é obrigatório para efetuar login. Isto deveria ter sido atualizado por você, mas aparentemente não foi. Baixe a versão mais recente em https://secondlife.com/support/downloads/ <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="FailedRequiredUpdateInstall"> - Não foi possível instalar uma atualização necessária. -Não será possível acessar a sua conta até que você atualize o [APP_NAME]. - -Baixe e instale a versão mais recente do visualizador em -http://secondlife.com/download. + <notification name="LoginFailedUnknown"> + Desculpe, motivo de falha de login desconhecido. Se você continuar a receber esta mensagem, por favor consulte o [SUPPORT_SITE]. <usetemplate name="okbutton" yestext="Sair"/> </notification> - <notification name="UpdaterServiceNotRunning"> - A instalação do Second Life requer uma atualização. - -Baixe a atualização em http://www.secondlife.com/downloads -ou você pode instalar a instalação agora. - <usetemplate name="okcancelbuttons" notext="Sair do Second Life" yestext="Baixar e instalar agora"/> - </notification> - <notification name="DownloadBackgroundTip"> - Baixamos uma atualização para a instalação do [APP_NAME]. -Versão [VERSION] [[RELEASE_NOTES_FULL_URL] sobre esta atualização] - <usetemplate name="okcancelbuttons" notext="Depois..." yestext="Instalar agora e reiniciar o [APP_NAME]"/> - </notification> - <notification name="DownloadBackgroundDialog"> - Baixamos uma atualização para a instalação do [APP_NAME]. -Versão [VERSION] [[RELEASE_NOTES_FULL_URL] sobre esta atualização] - <usetemplate name="okcancelbuttons" notext="Depois..." yestext="Instalar agora e reiniciar o [APP_NAME]"/> - </notification> - <notification name="RequiredUpdateDownloadedVerboseDialog"> - O software requer uma atualização que já foi baixada. -Versão [VERSION] Informação [[INFO_URL] sobre essa atualização] - -Para instalar a atualização, será preciso reiniciar o [APP_NAME]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="RequiredUpdateDownloadedDialog"> - Para instalar a atualização, será preciso reiniciar o [APP_NAME]. -Informação [[INFO_URL] sobre essa atualização] - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="OtherChannelDownloadBackgroundTip"> - Baixamos uma atualização para a instalação do [APP_NAME]. -Versão [VERSION] -O visualizador experimental foi substituído por um visualizador [NEW_CHANNEL]; -consulte [[INFO_URL] para obter mais detalhes sobre essa atualização] - <usetemplate name="okcancelbuttons" notext="Depois..." yestext="Instalar agora e reiniciar o [APP_NAME]"/> - </notification> - <notification name="OtherChannelDownloadBackgroundDialog"> - Baixamos uma atualização para a instalação do [APP_NAME]. -Versão [VERSION] -O visualizador experimental foi substituído por um visualizador [NEW_CHANNEL]; -consulte a informação [[INFO_URL] sobre essa atualização] - <usetemplate name="okcancelbuttons" notext="Depois..." yestext="Instalar agora e reiniciar o [APP_NAME]"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog"> - O software requer uma atualização que já foi baixada. -Versão [VERSION] -O visualizador experimental foi substituído por um visualizador [NEW_CHANNEL]; -consulte a informação [[INFO_URL] sobre essa atualização] - -Para instalar a atualização, será preciso reiniciar o [APP_NAME]. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedDialog"> - Para instalar a atualização, será preciso reiniciar o [APP_NAME]. -O visualizador experimental foi substituído por um visualizador [NEW_CHANNEL]; -consulte a informação [[INFO_URL] sobre essa atualização] - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateDownloadInProgress"> - Uma atualização está disponível! -O download está ocorrendo em segundo plano e reiniciaremos seu visualizador automaticamente para terminar a instalação assim que ele estiver concluído. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateDownloadComplete"> - Uma atualização foi baixada. Ela será instalada durante a reinicialização. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateCheckError"> - Erro ao verificar atualizações. -Tente novamente mais tarde. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateViewerUpToDate"> - Seu visualizador está atualizado! -Se você estiver muito ansioso para experimentar os novos recursos e correções, consulte a página de visualizadores alternativos. http://wiki.secondlife.com/wiki/Linden_Lab_Official:Alternate_Viewers. - <usetemplate name="okbutton" yestext="OK"/> - </notification> <notification name="DeedObjectToGroup"> Delegar este objeto causará ao grupo: * Receber os L$ pagos ao objeto @@ -3500,6 +3360,10 @@ Desativar qualquer configuração SIP ALG em seu router. Talvez não seja possível se comunicar via voz. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="NoVoiceConnect-GIAB"> + Estamos tendo problemas de conexão com o seu servidor de voz: Talvez não seja possível se comunicar via voz. Verifique a configuração da sua rede e firewall. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="AvatarRezLeftNotification"> ( [EXISTENCE] segundos de vida ) Avatar '[NAME]' saiu totalmente carregado. diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml index c6f6bba320..ce356a6447 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml @@ -26,8 +26,9 @@ Atualizações de software: </text> <combo_box name="updater_service_combobox"> - <combo_box.item label="Instalar automaticamente" name="Install_automatically"/> - <combo_box.item label="Baixarei e instalarei as atualizações manualmente" name="Install_manual"/> + <combo_box.item label="Instalar cada atualização automaticamente" name="Install_automatically"/> + <combo_box.item label="Pergunte-me quando uma atualização opcional estiver pronta para ser instalada" name="Install_ask"/> + <combo_box.item label="Instalar somente as atualizações obrigatórias" name="Install_manual"/> </combo_box> <check_box label="Disposto a atualizar para candidatos da versão" name="update_willing_to_test"/> <check_box label="Mostrar notas de versão após atualização" name="update_show_release_notes"/> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index c1acab097d..ee048e28e3 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -29,7 +29,7 @@ Falha na inicialização dos gráficos. Atualize seu driver gráfico! </string> <string name="AboutHeader"> - [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) ([CHANNEL]) + [CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> <string name="BuildConfig"> @@ -68,10 +68,10 @@ Memória de textura: [TEXTURE_MEMORY]MB Tempo de criação de VFS (cache): [VFS_TIME] </string> <string name="AboutLibs"> - Versão do J2C Decoder: [J2C_VERSION] + Versão do J2C Decoder: [J2C_VERSION] Versão do driver de áudio: [AUDIO_DRIVER_VERSION] -Versão de CEF: [LIBCEF_VERSION] -Versão da LibVLC: [LIBVLC_VERSION] +[LIBCEF_VERSION] +Versão do LibVLC: [LIBVLC_VERSION] Versão do servidor de voz: [VOICE_VERSION] </string> <string name="AboutTraffic"> @@ -1395,6 +1395,9 @@ http://secondlife.com/support para ajuda ao resolver este problema. <string name="InventoryNoMatchingItems"> Não encontrou o que procura? Tente buscar no [secondlife:///app/search/people/[SEARCH_TERM] Search]. </string> + <string name="InventoryNoMatchingRecentItems"> + Não encontrou o que procura? Tente [secondlife:///app/inventory/filters Show filters]. + </string> <string name="PlacesNoMatchingItems"> Não encontrou o que procura? Tente buscar no [secondlife:///app/search/groups/[SEARCH_TERM] Search]. </string> diff --git a/indra/newview/skins/default/xui/ru/floater_preferences.xml b/indra/newview/skins/default/xui/ru/floater_preferences.xml index fa78eedd3a..1f04eabaf7 100644 --- a/indra/newview/skins/default/xui/ru/floater_preferences.xml +++ b/indra/newview/skins/default/xui/ru/floater_preferences.xml @@ -1,5 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Preferences" title="НАСТРОЙКИ"> + <floater.string name="email_unverified_tooltip"> + Проверьте свою электронную почту для отправки мгновенных сообщений через электронную почту на странице https://accounts.secondlife.com/change_email/ + </floater.string> <button label="ОК" label_selected="ОК" name="OK"/> <button label="Отмена" label_selected="Отмена" name="Cancel"/> <tab_container name="pref core"> diff --git a/indra/newview/skins/default/xui/ru/floater_tos.xml b/indra/newview/skins/default/xui/ru/floater_tos.xml index 4cfdf5af70..3f2b5747d5 100644 --- a/indra/newview/skins/default/xui/ru/floater_tos.xml +++ b/indra/newview/skins/default/xui/ru/floater_tos.xml @@ -12,9 +12,10 @@ <text name="external_tos_required"> Для продолжения перейдите на сайт https://my.secondlife.com, войдите и примите Условия обслуживания. Спасибо! </text> + <check_box label="" name="agree_chk"/> <text name="agree_list"> - Я прочитал и согласен с условиями и положениями по конфиденциальности Пользовательского соглашения, включая требования по разрешению разногласий. - </text> + Я прочитал и согласен с Условиями и положениями по конфиденциальности Пользовательского соглашения, включая требования по разрешению разногласий Second Life. + </text> <button label="Продолжить" label_selected="Продолжить" name="Continue"/> <button label="Отмена" label_selected="Отмена" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/ru/mime_types.xml b/indra/newview/skins/default/xui/ru/mime_types.xml index 9c3ce00c5e..cfb7208049 100644 --- a/indra/newview/skins/default/xui/ru/mime_types.xml +++ b/indra/newview/skins/default/xui/ru/mime_types.xml @@ -57,6 +57,11 @@ Поток RealTime </label> </scheme> + <scheme name="example"> + <label name="example_label"> + Пример триггера схемы плагина + </label> + </scheme> <scheme name="libvlc"> <label name="libvlc_label"> Медиа с поддержкой LibVLC diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml index 0996224932..483cebaac5 100644 --- a/indra/newview/skins/default/xui/ru/notifications.xml +++ b/indra/newview/skins/default/xui/ru/notifications.xml @@ -684,6 +684,9 @@ </url> <usetemplate ignoretext="Оборудование моего компьютера не поддерживается" name="okcancelignore" notext="Нет" yestext="Да"/> </notification> + <notification name="RunLauncher"> + Пожалуйста, не запускайте напрямую исполняемый файл просмотра. Обновите все имеющиеся ярлыки, чтобы вместо этого запускать SL_Launcher. + </notification> <notification name="OldGPUDriver"> Возможно, для вашей видеокарты имеется более новый драйвер. Обновление драйвера может существенно повысить быстродействие. @@ -1580,157 +1583,14 @@ Завершена загрузка файла ландшафта: [DOWNLOAD_PATH]. </notification> - <notification name="DownloadWindowsMandatory"> - Появилась новая версия [APP_NAME]. -[MESSAGE] -Это обновление необходимо загрузить для использования [APP_NAME]. - <usetemplate name="okcancelbuttons" notext="Выйти" yestext="Загрузить"/> - </notification> - <notification name="DownloadWindows"> - Появилось обновление для [APP_NAME]. -[MESSAGE] -Устанавливать это обновление не обязательно, но рекомендуется для повышения производительности и стабильности. - <usetemplate name="okcancelbuttons" notext="Продолжить" yestext="Загрузить"/> - </notification> - <notification name="DownloadWindowsReleaseForDownload"> - Появилось обновление для [APP_NAME]. -[MESSAGE] -Устанавливать это обновление не обязательно, но рекомендуется для повышения производительности и стабильности. - <usetemplate name="okcancelbuttons" notext="Продолжить" yestext="Загрузить"/> - </notification> - <notification name="DownloadLinuxMandatory"> - Появилась новая версия [APP_NAME]. -[MESSAGE] -Это обновление необходимо загрузить для использования [APP_NAME]. - <usetemplate name="okcancelbuttons" notext="Выйти" yestext="Загрузить"/> - </notification> - <notification name="DownloadLinux"> - Появилось обновление для [APP_NAME]. -[MESSAGE] -Устанавливать это обновление не обязательно, но рекомендуется для повышения производительности и стабильности. - <usetemplate name="okcancelbuttons" notext="Продолжить" yestext="Загрузить"/> - </notification> - <notification name="DownloadLinuxReleaseForDownload"> - Появилось обновление для [APP_NAME]. -[MESSAGE] -Устанавливать это обновление не обязательно, но рекомендуется для повышения производительности и стабильности. - <usetemplate name="okcancelbuttons" notext="Продолжить" yestext="Загрузить"/> - </notification> - <notification name="DownloadMacMandatory"> - Появилась новая версия [APP_NAME]. -[MESSAGE] -Это обновление необходимо загрузить для использования [APP_NAME]. - -Загрузить его в папку приложений? - <usetemplate name="okcancelbuttons" notext="Выйти" yestext="Загрузить"/> - </notification> - <notification name="DownloadMac"> - Появилось обновление для [APP_NAME]. -[MESSAGE] -Устанавливать это обновление не обязательно, но рекомендуется для повышения производительности и стабильности. - -Загрузить его в папку приложений? - <usetemplate name="okcancelbuttons" notext="Продолжить" yestext="Загрузить"/> - </notification> - <notification name="DownloadMacReleaseForDownload"> - Появилось обновление для [APP_NAME]. -[MESSAGE] -Устанавливать это обновление не обязательно, но рекомендуется для повышения производительности и стабильности. - -Загрузить его в папку приложений? - <usetemplate name="okcancelbuttons" notext="Продолжить" yestext="Загрузить"/> - </notification> - <notification name="FailedUpdateInstall"> - Произошла ошибка при установке обновления. -Загрузите новую версию программы на сайте -http://secondlife.com/download. + <notification name="RequiredUpdate"> + Для входа необходима версия \[VERSION]. Для вас обновление должно было произведено автоматически, но по какой-то причине этого не произошло. Скачайте обновление с веб-сайта https://secondlife.com/support/downloads/ <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="FailedRequiredUpdateInstall"> - Не удалось установить обязательное обновление. -Вы не сможете войти в [APP_NAME], пока обновление не будет установлено. - -Загрузите новую версию программы на сайте -http://secondlife.com/download. + <notification name="LoginFailedUnknown"> + Извините, ошибка входа по неустановленной причине. Если данное сообщение повторится, посетите веб-сайт [SUPPORT_SITE]. <usetemplate name="okbutton" yestext="Выйти"/> </notification> - <notification name="UpdaterServiceNotRunning"> - Появились обязательные обновления для вашей версии Second Life. - -Загрузите это обновление на сайте http://www.secondlife.com/downloads -или установите его сейчас. - <usetemplate name="okcancelbuttons" notext="Выйти из Second Life" yestext="Загрузить и установить сейчас"/> - </notification> - <notification name="DownloadBackgroundTip"> - Загружено обновление для вашей версии [APP_NAME]. -Версия [VERSION]. [[RELEASE_NOTES_FULL_URL] Сведения об этом обновлении] - <usetemplate name="okcancelbuttons" notext="Позже..." yestext="Установите обновление и перезапустите [APP_NAME]"/> - </notification> - <notification name="DownloadBackgroundDialog"> - Загружено обновление для вашей версии [APP_NAME]. -Версия [VERSION]. [[RELEASE_NOTES_FULL_URL] Сведения об этом обновлении] - <usetemplate name="okcancelbuttons" notext="Позже..." yestext="Установите обновление и перезапустите [APP_NAME]"/> - </notification> - <notification name="RequiredUpdateDownloadedVerboseDialog"> - Загружено обязательное обновление. -Версия [VERSION]. [[INFO_URL] Сведения об этом обновлении] - -Необходимо перезапустить [APP_NAME] для установки обновления. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="RequiredUpdateDownloadedDialog"> - Необходимо перезапустить [APP_NAME] для установки обновления. -[[INFO_URL] Сведения об этом обновлении] - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="OtherChannelDownloadBackgroundTip"> - Загружено обновление для вашей версии [APP_NAME]. -Версия [VERSION] -На замену этой экспериментальной версии клиента предлагается клиент [NEW_CHANNEL]; -см. [[INFO_URL] об этом обновлении] - <usetemplate name="okcancelbuttons" notext="Позже..." yestext="Установите обновление и перезапустите [APP_NAME]"/> - </notification> - <notification name="OtherChannelDownloadBackgroundDialog"> - Загружено обновление для вашей версии [APP_NAME]. -Версия [VERSION] -На замену этой экспериментальной версии клиента предлагается клиент [NEW_CHANNEL]; -см. [[INFO_URL] Сведения об этом обновлении] - <usetemplate name="okcancelbuttons" notext="Позже..." yestext="Установите обновление и перезапустите [APP_NAME]"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog"> - Загружено обязательное обновление. -Версия [VERSION] -На замену этой экспериментальной версии клиента предлагается клиент [NEW_CHANNEL]; -см. [[INFO_URL] Сведения об этом обновлении] - -Необходимо перезапустить [APP_NAME] для установки обновления. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedDialog"> - Необходимо перезапустить [APP_NAME] для установки обновления. -На замену этой экспериментальной версии клиента предлагается клиент [NEW_CHANNEL]; -см. [[INFO_URL] Сведения об этом обновлении] - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateDownloadInProgress"> - Появилось обновление! -Оно сейчас загружается в фоновом режиме и, как только будет готово, вам будет предложено перезапустить клиент для завершения установки. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateDownloadComplete"> - Обновление загружено. Оно будет установлено после перезапуска. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateCheckError"> - При поиске обновлений произошла ошибка. -Повторите попытку позже. - <usetemplate name="okbutton" yestext="OK"/> - </notification> - <notification name="UpdateViewerUpToDate"> - Ваш клиент уже обновлен! -Если вы хотите немедленно испробовать наши новейшие функции и исправления, обратитесь на страницу «Альтернативные клиенты»: http://wiki.secondlife.com/wiki/Linden_Lab_Official:Alternate_Viewers. - <usetemplate name="okbutton" yestext="OK"/> - </notification> <notification name="DeedObjectToGroup"> В результате передачи этого объекта группа: * Получит L$ в уплату за объект @@ -3511,6 +3371,10 @@ http://secondlife.com/download. Голосовое общение будет недоступно. <usetemplate name="okbutton" yestext="OK"/> </notification> + <notification name="NoVoiceConnect-GIAB"> + Проблемы соединения с речевым сервером: Голосовое общение будет недоступно. Проверьте настройки сети и брандмауэра. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="AvatarRezLeftNotification"> ( [EXISTENCE] сек. жизни ) Аватар «[NAME]» полностью загружен. diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml b/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml index e1b185e8ef..d19a35c8b5 100644 --- a/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml @@ -26,8 +26,9 @@ Обновления ПО: </text> <combo_box name="updater_service_combobox"> - <combo_box.item label="Устанавливать автоматически" name="Install_automatically"/> - <combo_box.item label="Я буду загружать и устанавливать обновления вручную" name="Install_manual"/> + <combo_box.item label="Автоматическая установка каждого обновления" name="Install_automatically"/> + <combo_box.item label="Когда необязательное обновление будет готово к установке, запросите меня" name="Install_ask"/> + <combo_box.item label="Установка только обязательных обновлений" name="Install_manual"/> </combo_box> <check_box label="Устанавливать бета-версии" name="update_willing_to_test"/> <check_box label="Показать заметки о выпуске после обновления" name="update_show_release_notes"/> diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml index b94c417ef0..95225da7d0 100644 --- a/indra/newview/skins/default/xui/ru/strings.xml +++ b/indra/newview/skins/default/xui/ru/strings.xml @@ -38,7 +38,7 @@ Ошибка инициализации графики. Обновите графический драйвер! </string> <string name="AboutHeader"> - [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) ([CHANNEL]) + [CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> <string name="BuildConfig"> @@ -77,11 +77,11 @@ SLURL: <nolink>[SLURL]</nolink> Время создания VFS (кэш): [VFS_TIME] </string> <string name="AboutLibs"> - Версия декодера J2C: [J2C_VERSION] -Версия драйвера звука: [AUDIO_DRIVER_VERSION] -Версия CEF: [LIBCEF_VERSION] -Версия LibVLC: [LIBVLC_VERSION] -Версия голосового сервера: [VOICE_VERSION] + Версия декодера J2C: [J2C_VERSION] +Версия аудиодрайвера: [AUDIO_DRIVER_VERSION] +[LIBCEF_VERSION] +Версия LibVLC: [LIBVLC_VERSION] +Версия речевого сервера: [VOICE_VERSION] </string> <string name="AboutTraffic"> Потеряно пакетов: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) @@ -1442,6 +1442,9 @@ support@secondlife.com. <string name="InventoryNoMatchingItems"> Не нашли того, что вам нужно? Воспользуйтесь [secondlife:///app/search/all/[SEARCH_TERM] поиском]. </string> + <string name="InventoryNoMatchingRecentItems"> + Не нашли то, что искали? Попробуйте на [secondlife:///app/inventory/filters Show filters]. + </string> <string name="PlacesNoMatchingItems"> Не нашли того, что вам нужно? Воспользуйтесь [secondlife:///app/search/places/[SEARCH_TERM] поиском]. </string> diff --git a/indra/newview/skins/default/xui/tr/floater_preferences.xml b/indra/newview/skins/default/xui/tr/floater_preferences.xml index 679b018247..c9d509c868 100644 --- a/indra/newview/skins/default/xui/tr/floater_preferences.xml +++ b/indra/newview/skins/default/xui/tr/floater_preferences.xml @@ -1,5 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Preferences" title="TERCİHLER"> + <floater.string name="email_unverified_tooltip"> + Lütfen Anlık Mesajlaşmayı etkinleştirmek için https://accounts.secondlife.com/change_email/ adresini ziyaret ederek e-postanızı doğrulayın + </floater.string> <button label="Tamam" label_selected="Tamam" name="OK"/> <button label="İptal" label_selected="İptal" name="Cancel"/> <tab_container name="pref core"> diff --git a/indra/newview/skins/default/xui/tr/floater_tos.xml b/indra/newview/skins/default/xui/tr/floater_tos.xml index 9c0249526a..091a641f03 100644 --- a/indra/newview/skins/default/xui/tr/floater_tos.xml +++ b/indra/newview/skins/default/xui/tr/floater_tos.xml @@ -12,8 +12,9 @@ <text name="external_tos_required"> Devam edebilmeniz için https://my.secondlife.com adresine gidip oturum açarak Hizmet Sözleşmesi'ni kabul etmeniz gerekir. Teşekkürler! </text> + <check_box label="" name="agree_chk"/> <text name="agree_list"> - Uyuşmazlıkların çözümü gerekliliklerini içeren Second Life Şartlar ve Koşulları, Gizlilik Politikası'nı ve Hizmet Koşulları'nı okudum ve kabul ediyorum. + Anlaşmazlıkların çözümü de dahil olmak üzere Second Life Şartlarını ve Koşullarını, Gizlilik Politikasını ve Hizmet Şartlarını okudum ve kabul ediyorum. </text> <button label="Devam Et" label_selected="Devam Et" name="Continue"/> <button label="İptal" label_selected="İptal" name="Cancel"/> diff --git a/indra/newview/skins/default/xui/tr/mime_types.xml b/indra/newview/skins/default/xui/tr/mime_types.xml index 5b13b0059a..6c049a5d07 100644 --- a/indra/newview/skins/default/xui/tr/mime_types.xml +++ b/indra/newview/skins/default/xui/tr/mime_types.xml @@ -57,6 +57,11 @@ Gerçek Zamanlı Akış </label> </scheme> + <scheme name="example"> + <label name="example_label"> + Örnek Eklenti şeması tetikleyici + </label> + </scheme> <scheme name="libvlc"> <label name="libvlc_label"> LibVLC destekli ortam diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml index 1deda01de8..d218eb1957 100644 --- a/indra/newview/skins/default/xui/tr/notifications.xml +++ b/indra/newview/skins/default/xui/tr/notifications.xml @@ -685,6 +685,9 @@ Daha fazla bilgi için [_URL] adresini ziyaret etmek ister misiniz? </url> <usetemplate ignoretext="Bilgisayar donanımım desteklenmiyor" name="okcancelignore" notext="Hayır" yestext="Evet"/> </notification> + <notification name="RunLauncher"> + Lütfen çalıştırılabilir görüntüleyiciyi doğrudan çalıştırmayın. SL_Launcher'ı çalıştırmak yerine tüm mevcut kısayolları güncelleyin. + </notification> <notification name="OldGPUDriver"> Grafik yonganız için muhtemelen daha yeni bir sürücü mevcut. Grafik sürücüleri güncellemek performansınızı kayda değer şekilde artırabilir. @@ -1581,157 +1584,14 @@ Nesneyi satılık olarak ayarlayıp tekrar deneyin. İşlenmemiş yüzey dosyasının şu konuma karşıdan yüklenmesi tamamlandı: [DOWNLOAD_PATH]. </notification> - <notification name="DownloadWindowsMandatory"> - [APP_NAME] uygulamasının yeni bir sürümü mevcut. -[MESSAGE] -[APP_NAME] uygulamasını kullanabilmek için bu güncellemeyi karşıdan yüklemelisiniz. - <usetemplate name="okcancelbuttons" notext="Çık" yestext="Karşıdan Yükle"/> - </notification> - <notification name="DownloadWindows"> - [APP_NAME] uygulamasının güncellenmiş bir sürümü mevcut. -[MESSAGE] -Bu güncelleme zorunlu değil, fakat performans ve kararlılığı iyileştirmek için güncellemeyi yüklemenizi öneririz. - <usetemplate name="okcancelbuttons" notext="Devam" yestext="Karşıdan Yükle"/> - </notification> - <notification name="DownloadWindowsReleaseForDownload"> - [APP_NAME] uygulamasının güncellenmiş bir sürümü mevcut. -[MESSAGE] -Bu güncelleme zorunlu değil, fakat performans ve kararlılığı iyileştirmek için güncellemeyi yüklemenizi öneririz. - <usetemplate name="okcancelbuttons" notext="Devam" yestext="Karşıdan Yükle"/> - </notification> - <notification name="DownloadLinuxMandatory"> - [APP_NAME] uygulamasının yeni bir sürümü mevcut. -[MESSAGE] -[APP_NAME] uygulamasını kullanabilmek için bu güncellemeyi karşıdan yüklemelisiniz. - <usetemplate name="okcancelbuttons" notext="Çık" yestext="Karşıdan Yükle"/> - </notification> - <notification name="DownloadLinux"> - [APP_NAME] uygulamasının güncellenmiş bir sürümü mevcut. -[MESSAGE] -Bu güncelleme zorunlu değil, fakat performans ve kararlılığı iyileştirmek için güncellemeyi yüklemenizi öneririz. - <usetemplate name="okcancelbuttons" notext="Devam" yestext="Karşıdan Yükle"/> - </notification> - <notification name="DownloadLinuxReleaseForDownload"> - [APP_NAME] uygulamasının güncellenmiş bir sürümü mevcut. -[MESSAGE] -Bu güncelleme zorunlu değil, fakat performans ve kararlılığı iyileştirmek için güncellemeyi yüklemenizi öneririz. - <usetemplate name="okcancelbuttons" notext="Devam" yestext="Karşıdan Yükle"/> - </notification> - <notification name="DownloadMacMandatory"> - [APP_NAME] uygulamasının yeni bir sürümü mevcut. -[MESSAGE] -[APP_NAME] uygulamasını kullanabilmek için bu güncellemeyi karşıdan yüklemelisiniz. - -Uygulamalar klasörünüze karşıdan yüklensin mi? - <usetemplate name="okcancelbuttons" notext="Çık" yestext="Karşıdan Yükle"/> - </notification> - <notification name="DownloadMac"> - [APP_NAME] uygulamasının güncellenmiş bir sürümü mevcut. -[MESSAGE] -Bu güncelleme zorunlu değil, fakat performans ve kararlılığı iyileştirmek için güncellemeyi yüklemenizi öneririz. - -Uygulamalar klasörünüze karşıdan yüklensin mi? - <usetemplate name="okcancelbuttons" notext="Devam" yestext="Karşıdan Yükle"/> - </notification> - <notification name="DownloadMacReleaseForDownload"> - [APP_NAME] uygulamasının güncellenmiş bir sürümü mevcut. -[MESSAGE] -Bu güncelleme zorunlu değil, fakat performans ve kararlılığı iyileştirmek için güncellemeyi yüklemenizi öneririz. - -Uygulamalar klasörünüze karşıdan yüklensin mi? - <usetemplate name="okcancelbuttons" notext="Devam" yestext="Karşıdan Yükle"/> - </notification> - <notification name="FailedUpdateInstall"> - Görüntüleyici güncellemesi yüklenirken bir hata oluştu. -Lütfen en son görüntüleyiciyi şu adresten karşıdan yükleyin ve kurun: -http://secondlife.com/download. + <notification name="RequiredUpdate"> + Oturum açma için [VERSION] sürümü gerekli. Bu sizin için güncellenmiş olmalıydı ancak görünüşe göre güncellenmemiş. Lütfen www.secondlife.com adresinden indirin. <usetemplate name="okbutton" yestext="Tamam"/> </notification> - <notification name="FailedRequiredUpdateInstall"> - Gerekli bir güncellemeyi yükleyemedik. -[APP_NAME] güncellenene kadar oturum açamayacaksınız. - -Lütfen en son görüntüleyiciyi şu adresten karşıdan yükleyin ve kurun: -http://secondlife.com/download. + <notification name="LoginFailedUnknown"> + Üzgünüz, oturum açma bilinmeyen bir nedenden dolayı başarısız oldu. Bu mesajı almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun. <usetemplate name="okbutton" yestext="Çık"/> </notification> - <notification name="UpdaterServiceNotRunning"> - Second Life kurulumunuz için gerekli bir güncelleme var. - -Bu güncellemeyi http://www.secondlife.com/downloads adresinden karşıdan yükleyebilir -veya şimdi kurabilirsiniz. - <usetemplate name="okcancelbuttons" notext="Second Life'tan çık" yestext="Karşıdan yükle ve şimdi kur"/> - </notification> - <notification name="DownloadBackgroundTip"> - [APP_NAME] kurulumunuz için bir güncellemeyi karşıdan yükledik. -Sürüm [VERSION] [[RELEASE_NOTES_FULL_URL] Bu güncelleme hakkında ayrıntılı bilgi] - <usetemplate name="okcancelbuttons" notext="Sonra..." yestext="Şimdi kur ve [APP_NAME] uygulamasını yeniden başlat"/> - </notification> - <notification name="DownloadBackgroundDialog"> - [APP_NAME] kurulumunuz için bir güncellemeyi karşıdan yükledik. -Sürüm [VERSION] [[RELEASE_NOTES_FULL_URL] Bu güncelleme hakkında ayrıntılı bilgi] - <usetemplate name="okcancelbuttons" notext="Sonra..." yestext="Şimdi kur ve [APP_NAME] uygulamasını yeniden başlat"/> - </notification> - <notification name="RequiredUpdateDownloadedVerboseDialog"> - Gerekli bir yazılım güncellemesi indirdik. -Sürüm [VERSION] [[INFO_URL] Bu güncelleme hakkında ayrıntılı bilgi] - -Güncellemeyi yüklemek için [APP_NAME] uygulamasını yeniden başlatmalısınız. - <usetemplate name="okbutton" yestext="Tamam"/> - </notification> - <notification name="RequiredUpdateDownloadedDialog"> - Güncellemeyi yüklemek için [APP_NAME] uygulamasını yeniden başlatmalısınız. -[[INFO_URL] Bu güncelleme hakkında bilgi] - <usetemplate name="okbutton" yestext="Tamam"/> - </notification> - <notification name="OtherChannelDownloadBackgroundTip"> - [APP_NAME] kurulumunuz için bir güncelleme indirdik. -Sürüm [VERSION] -Bu deneysel görüntüleyicinin yerini bir [NEW_CHANNEL] görüntüleyici aldı; -bkz. [bu güncelleme hakkında bilgi için [INFO_URL]] - <usetemplate name="okcancelbuttons" notext="Sonra..." yestext="Şimdi yükle ve [APP_NAME] uygulamasını yeniden başlat"/> - </notification> - <notification name="OtherChannelDownloadBackgroundDialog"> - [APP_NAME] kurulumunuz için bir güncelleme indirdik. -Sürüm [VERSION] -Bu deneysel görüntüleyicinin yerini bir [NEW_CHANNEL] görüntüleyici aldı; -bkz. [[INFO_URL] Bu güncelleme hakkında bilgi] - <usetemplate name="okcancelbuttons" notext="Sonra..." yestext="Şimdi yükle ve [APP_NAME] uygulamasını yeniden başlat"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog"> - Gerekli bir yazılım güncellemesi indirdik. -Sürüm [VERSION] -Bu deneysel görüntüleyicinin yerini bir [NEW_CHANNEL] görüntüleyici aldı; -bkz. [[INFO_URL] Bu güncelleme hakkında bilgi] - -Güncellemeyi yüklemek için [APP_NAME] uygulamasını yeniden başlatmalısınız. - <usetemplate name="okbutton" yestext="Tamam"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedDialog"> - Güncellemeyi yüklemek için [APP_NAME] uygulamasını yeniden başlatmalısınız. -Bu deneysel görüntüleyicinin yerini bir [NEW_CHANNEL] görüntüleyici aldı; -bkz. [[INFO_URL] Bu güncelleme hakkında bilgi] - <usetemplate name="okbutton" yestext="Tamam"/> - </notification> - <notification name="UpdateDownloadInProgress"> - Bir güncelleme mevcut. -Şu anda arkaplanda indiriliyor ve hazır olduğunda yüklemeyi bitirmek için görüntüleyicinizi yeniden başlatmanız için sizi uyaracağız. - <usetemplate name="okbutton" yestext="Tamam"/> - </notification> - <notification name="UpdateDownloadComplete"> - Bir güncelleme indirildi. Yeniden başlatma sırasında yüklenecek. - <usetemplate name="okbutton" yestext="Tamam"/> - </notification> - <notification name="UpdateCheckError"> - Güncelleme kontrolü yapılırken bir hata oluştu. -Lütfen daha sonra tekrar deneyin. - <usetemplate name="okbutton" yestext="Tamam"/> - </notification> - <notification name="UpdateViewerUpToDate"> - Görüntüleyiciniz güncel. -En yeni özellikleri ve düzeltmeleri görmek için sabırsızlanıyorsanız Alternatif Görüntüleyici sayfasına göz atın. http://wiki.secondlife.com/wiki/Linden_Lab_Official:Alternate_Viewers. - <usetemplate name="okbutton" yestext="Tamam"/> - </notification> <notification name="DeedObjectToGroup"> Bu nesnenin devredilmesi grubun şunu yapmasına sebep olacak: * Nesneye ödenen L$'nı almasına @@ -3511,6 +3371,10 @@ Yönlendiricinizdeki her SIP ALG özelliğini devre dışı bırakın. Sesli iletişim kullanılamayacak. <usetemplate name="okbutton" yestext="Tamam"/> </notification> + <notification name="NoVoiceConnect-GIAB"> + Ses sunucunuz ile bağlantı kurma konusunda sorun yaşıyoruz. Ses bağlantıları kullanılamayacak. Lütfen ağ ve güvenlik duvarı ayarlarınızı kontrol edin. + <usetemplate name="okbutton" yestext="Tamam"/> + </notification> <notification name="AvatarRezLeftNotification"> ( [EXISTENCE] saniyedir hayatta ) '[NAME]' adlı avatar tam olarak yüklenmiş bir şekilde ayrıldı. diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_setup.xml b/indra/newview/skins/default/xui/tr/panel_preferences_setup.xml index 39a7ce9973..91a7cb48b7 100644 --- a/indra/newview/skins/default/xui/tr/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/tr/panel_preferences_setup.xml @@ -26,8 +26,9 @@ Yazılım güncelleştirmeleri: </text> <combo_box name="updater_service_combobox"> - <combo_box.item label="Otomatik olarak kurulsun" name="Install_automatically"/> - <combo_box.item label="Güncellemeleri manuel olarak indirip yükleyeceğim" name="Install_manual"/> + <combo_box.item label="Her bir güncellemeyi otomatik olarak yükle" name="Install_automatically"/> + <combo_box.item label="İsteğe bağlı bir güncelleme yüklenmeye hazır olduğunda bana sor" name="Install_ask"/> + <combo_box.item label="Yalnızca zorunlu güncellemeleri yükle" name="Install_manual"/> </combo_box> <check_box label="Sürüm adaylarına güncelleme yapmaya gönüllü" name="update_willing_to_test"/> <check_box label="Güncellemeden sonra Sürüm Notlarını göster" name="update_show_release_notes"/> diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml index c2f7b7bdc6..6850c67df3 100644 --- a/indra/newview/skins/default/xui/tr/strings.xml +++ b/indra/newview/skins/default/xui/tr/strings.xml @@ -38,7 +38,7 @@ Grafik başlatma başarılamadı. Lütfen grafik sürücünüzü güncelleştirin! </string> <string name="AboutHeader"> - [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) ([CHANNEL]) + [CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> <string name="BuildConfig"> @@ -77,10 +77,10 @@ Doku belleği: [TEXTURE_MEMORY]MB VFS (önbellek) oluşturma zamanı: [VFS_TIME] </string> <string name="AboutLibs"> - J2C Kod Çözücü Sürümü: [J2C_VERSION] -Ses Sürücüsü Sürümü: [AUDIO_DRIVER_VERSION] -CEF Sürümü: [LIBCEF_VERSION] -LibVLC Sürümü: [LIBVLC_VERSION] + J2C Kod Çözücü Sürümü: [J2C_VERSION] +Ses Sürücüsü Sürümü: [AUDIO_DRIVER_VERSION] +[LIBCEF_VERSION] +LibVLC Sürümü: [LIBVLC_VERSION] Ses Sunucusu Sürümü: [VOICE_VERSION] </string> <string name="AboutTraffic"> @@ -1442,6 +1442,9 @@ http://secondlife.com/support adresini ziyaret edin. <string name="InventoryNoMatchingItems"> Aradığınızı bulamadınız mı? [secondlife:///app/search/all/[SEARCH_TERM] Arama] ile bulmayı deneyin. </string> + <string name="InventoryNoMatchingRecentItems"> + Aradığınızı bulamadınız mı? [secondlife:///app/inventory/filters Show filters] seçeneğini deneyin. + </string> <string name="PlacesNoMatchingItems"> Aradığınızı bulamadınız mı? [secondlife:///app/search/places/[SEARCH_TERM] Arama] ile bulmayı deneyin. </string> diff --git a/indra/newview/skins/default/xui/zh/floater_preferences.xml b/indra/newview/skins/default/xui/zh/floater_preferences.xml index c5b078f3c7..7f35f40b9e 100644 --- a/indra/newview/skins/default/xui/zh/floater_preferences.xml +++ b/indra/newview/skins/default/xui/zh/floater_preferences.xml @@ -1,5 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Preferences" title="偏好設定"> + <floater.string name="email_unverified_tooltip"> + 請至以下網址確認電郵,以便啓動即時通訊: +https://accounts.secondlife.com/change_email/ + </floater.string> <button label="確定" label_selected="確定" name="OK"/> <button label="取消" label_selected="取消" name="Cancel"/> <tab_container name="pref core"> diff --git a/indra/newview/skins/default/xui/zh/floater_tos.xml b/indra/newview/skins/default/xui/zh/floater_tos.xml index cde6445e34..4cac07cd21 100644 --- a/indra/newview/skins/default/xui/zh/floater_tos.xml +++ b/indra/newview/skins/default/xui/zh/floater_tos.xml @@ -12,9 +12,10 @@ <text name="external_tos_required"> 你需先登入 https://my.secondlife.com 同意服務條款,才可繼續。 謝謝你! </text> + <check_box label="" name="agree_chk"/> <text name="agree_list"> - 我已閱畢並同意 Second Life使用條款、隱私政策、服務條款,包括解決爭端的規定途徑。 - </text> + 我已閱畢並同意Second Life使用條款、隱私政策、服務條款,包括解決爭端的規定途徑。 + </text> <button label="繼續" label_selected="繼續" name="Continue"/> <button label="取消" label_selected="取消" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/mime_types.xml b/indra/newview/skins/default/xui/zh/mime_types.xml index f4b6822778..52f25d18d2 100644 --- a/indra/newview/skins/default/xui/zh/mime_types.xml +++ b/indra/newview/skins/default/xui/zh/mime_types.xml @@ -57,6 +57,11 @@ 即時串流 </label> </scheme> + <scheme name="example"> + <label name="example_label"> + 插件範例樣板觸發器 + </label> + </scheme> <scheme name="libvlc"> <label name="libvlc_label"> LibVLC支持的媒體 diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml index d25192d7ba..5949d068c3 100644 --- a/indra/newview/skins/default/xui/zh/notifications.xml +++ b/indra/newview/skins/default/xui/zh/notifications.xml @@ -685,6 +685,9 @@ </url> <usetemplate ignoretext="我的電腦硬體並不支援" name="okcancelignore" notext="否" yestext="是"/> </notification> + <notification name="RunLauncher"> + 請勿直接執行該瀏覽器可執行程式。 如果有SL_Launcher(SL啓動器)的捷徑,請更新,以便正常使用。 + </notification> <notification name="OldGPUDriver"> 你的顯示卡很可能有新版的驅動程式。 更新顯示驅動程式會大幅改善性能。 @@ -1574,153 +1577,16 @@ SHA1 指紋:[MD5_DIGEST] 原始地形檔案下載完成: [DOWNLOAD_PATH]。 </notification> - <notification name="DownloadWindowsMandatory"> - 有個新版本的 [APP_NAME] 可供使用。 -[MESSAGE] -你必須下載這個更新才可使用 [APP_NAME]。 - <usetemplate name="okcancelbuttons" notext="結束退出" yestext="下載"/> - </notification> - <notification name="DownloadWindows"> - 一個 [APP_NAME] 更新過的版本已經可用。 -[MESSAGE] -這個更新並非強制更新,但我們建議你安裝以增強效能及穩定性。 - <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> - </notification> - <notification name="DownloadWindowsReleaseForDownload"> - 一個 [APP_NAME] 更新過的版本已經可用。 -[MESSAGE] -這個更新並非強制更新,但我們建議你安裝以增強效能及穩定性。 - <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> - </notification> - <notification name="DownloadLinuxMandatory"> - 有個新版本的 [APP_NAME] 可供使用。 -[MESSAGE] -你必須下載這個更新才可使用 [APP_NAME]。 - <usetemplate name="okcancelbuttons" notext="結束退出" yestext="下載"/> - </notification> - <notification name="DownloadLinux"> - 一個 [APP_NAME] 更新過的版本已經可用。 -[MESSAGE] -這個更新並非強制更新,但我們建議你安裝以增強效能及穩定性。 - <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> - </notification> - <notification name="DownloadLinuxReleaseForDownload"> - 一個 [APP_NAME] 更新過的版本已經可用。 -[MESSAGE] -這個更新並非強制更新,但我們建議你安裝以增強效能及穩定性。 - <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> - </notification> - <notification name="DownloadMacMandatory"> - 有個新版本的 [APP_NAME] 可供使用。 -[MESSAGE] -你必須下載這個更新才可使用 [APP_NAME]。 - -下載到 Applications 資料夾? - <usetemplate name="okcancelbuttons" notext="結束退出" yestext="下載"/> - </notification> - <notification name="DownloadMac"> - 一個 [APP_NAME] 更新過的版本已經可用。 -[MESSAGE] -這個更新並非強制更新,但我們建議你安裝以增強效能及穩定性。 - -下載到 Applications 資料夾? - <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> - </notification> - <notification name="DownloadMacReleaseForDownload"> - 一個 [APP_NAME] 更新過的版本已經可用。 -[MESSAGE] -這個更新並非強制更新,但我們建議你安裝以增強效能及穩定性。 - -下載到 Applications 資料夾? - <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> - </notification> - <notification name="FailedUpdateInstall"> - 安裝更新版 Viewer 時出錯。 -請到 http://secondlife.com/download 下載並安裝最新版 Viewer。 - <usetemplate name="okbutton" yestext="確定"/> - </notification> - <notification name="FailedRequiredUpdateInstall"> - 無法安裝必要的更新。 -除非 [APP_NAME] 更新,你將無法登入。 - -請到 http://secondlife.com/download 下載並安裝最新版 Viewer。 - <usetemplate name="okbutton" yestext="結束退出"/> - </notification> - <notification name="UpdaterServiceNotRunning"> - 你已安裝的第二人生軟體現有一個必要的更新。 - -你可以到 http://www.secondlife.com/downloads 下載此更新,或者現在立即安裝。 - <usetemplate name="okcancelbuttons" notext="結束退出第二人生" yestext="立即下載及安裝"/> - </notification> - <notification name="DownloadBackgroundTip"> - 我們已為你的 [APP_NAME] 軟體下載了更新。 -[VERSION] 版本 [[RELEASE_NOTES_FULL_URL] 關於此更新的資訊] - <usetemplate name="okcancelbuttons" notext="稍候..." yestext="立即安裝及重新啟動 [APP_NAME]"/> - </notification> - <notification name="DownloadBackgroundDialog"> - 我們已為你的 [APP_NAME] 軟體下載了更新。 -[VERSION] 版本 [[RELEASE_NOTES_FULL_URL] 關於此更新的資訊] - <usetemplate name="okcancelbuttons" notext="稍候..." yestext="立即安裝及重新啟動 [APP_NAME]"/> - </notification> - <notification name="RequiredUpdateDownloadedVerboseDialog"> - 我們已下載了一個必要的軟體更新。 -[VERSION] 版本 [[INFO_URL] 關於此更新的資訊] - -我門必須重新啟動 [APP_NAME] 以安裝更新。 + <notification name="RequiredUpdate"> + 必須用[VERSION]版本登入。 +本來應該已經完成更新,但看來你的尚未更新。 +請到 http://secondlife.com/support/ 下載更新版 <usetemplate name="okbutton" yestext="確定"/> </notification> - <notification name="RequiredUpdateDownloadedDialog"> - 我門必須重新啟動 [APP_NAME] 以安裝更新。 -[[INFO_URL] 關於此更新的資訊] - <usetemplate name="okbutton" yestext="確定"/> - </notification> - <notification name="OtherChannelDownloadBackgroundTip"> - 我們已為你的 [APP_NAME] 軟體下載了更新。 -版本:[VERSION] -原本試驗性質的瀏覽器已被 [NEW_CHANNEL] 瀏覽器取代, -參見[[INFO_URL] 此更新版的詳情] - <usetemplate name="okcancelbuttons" notext="稍候..." yestext="立即安裝並重新啟動 [APP_NAME]"/> - </notification> - <notification name="OtherChannelDownloadBackgroundDialog"> - 我們已為你的 [APP_NAME] 軟體下載了更新。 -版本:[VERSION] -原本試驗性質的瀏覽器已被 [NEW_CHANNEL] 瀏覽器取代, -參見[[INFO_URL] 介紹此更新版的資訊] - <usetemplate name="okcancelbuttons" notext="稍候…" yestext="立即安裝並重新啟動 [APP_NAME]"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog"> - 我們已下載了一個必要的軟體更新。 -版本:[VERSION] -原本試驗性質的瀏覽器已被 [NEW_CHANNEL] 瀏覽器取代, -參見[[INFO_URL] 介紹此更新版的資訊] - -我們必須重新啟動 [APP_NAME] 以便安裝更新。 - <usetemplate name="okbutton" yestext="確定"/> - </notification> - <notification name="OtherChannelRequiredUpdateDownloadedDialog"> - 我們必須重新啟動 [APP_NAME] 以便安裝更新。 -原本試驗性質的瀏覽器已被 [NEW_CHANNEL] 瀏覽器取代, -參見[[INFO_URL] 介紹此更新版的資訊] - <usetemplate name="okbutton" yestext="確定"/> - </notification> - <notification name="UpdateDownloadInProgress"> - 有更新版本! -正在背景下載中,一完成下載我們會通知你重啟瀏覽器以便安裝。 - <usetemplate name="okbutton" yestext="確定"/> - </notification> - <notification name="UpdateDownloadComplete"> - 一個更新版本已經下載完畢。 重啟時將會安裝。 - <usetemplate name="okbutton" yestext="確定"/> - </notification> - <notification name="UpdateCheckError"> - 查詢是否有更新時出錯。 -請稍候再試一次。 - <usetemplate name="okbutton" yestext="確定"/> - </notification> - <notification name="UpdateViewerUpToDate"> - 你的瀏覽器已是最新版! -如果你急欲試用最新的功能和修補,請光臨「替代瀏覽器」網頁:http://wiki.secondlife.com/wiki/Linden_Lab_Official:Alternate_Viewers。 - <usetemplate name="okbutton" yestext="確定"/> + <notification name="LoginFailedUnknown"> + 抱歉,登入失敗,原因不明。 +如果你一直看到此訊息,請查閱 [SUPPORT_SITE]。 + <usetemplate name="okbutton" yestext="退出"/> </notification> <notification name="DeedObjectToGroup"> 讓渡此物件將可讓這個群組: @@ -3501,6 +3367,13 @@ SHA1 指紋:[MD5_DIGEST] 將無法用語音溝通。 <usetemplate name="okbutton" yestext="確定"/> </notification> + <notification name="NoVoiceConnect-GIAB"> + 試圖連接語音伺服器時出了問題。 + +將無法用語音溝通。 +請檢查你的網路和防火牆設定。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> <notification name="AvatarRezLeftNotification"> (存續 [EXISTENCE] 秒鐘) 化身 '[NAME]' 在完全載入狀況下離開。 diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml b/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml index bdf980218c..64c0fd062e 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml @@ -26,8 +26,9 @@ 軟體更新: </text> <combo_box name="updater_service_combobox"> - <combo_box.item label="自動安裝" name="Install_automatically"/> - <combo_box.item label="讓我自己手動下載並安裝" name="Install_manual"/> + <combo_box.item label="自動安裝每一次更新" name="Install_automatically"/> + <combo_box.item label="每當有可自由選擇的更新,讓我做決定" name="Install_ask"/> + <combo_box.item label="僅安裝強制必要的更新" name="Install_manual"/> </combo_box> <check_box label="願意在更新時搶先試用釋出候選版" name="update_willing_to_test"/> <check_box label="更新後顯示發行記事" name="update_show_release_notes"/> diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml index f36f56bd53..e4f9c5d433 100644 --- a/indra/newview/skins/default/xui/zh/strings.xml +++ b/indra/newview/skins/default/xui/zh/strings.xml @@ -38,7 +38,7 @@ 顯像初始化失敗。 請更新你的顯像卡驅動程式! </string> <string name="AboutHeader"> - [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) ([CHANNEL]) + [CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]位元) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> <string name="BuildConfig"> @@ -79,7 +79,7 @@ VFS(快取)建立時間:[VFS_TIME] <string name="AboutLibs"> J2C 解碼器版本: [J2C_VERSION] 音效驅動程式版本: [AUDIO_DRIVER_VERSION] -CEF版本:[LIBCEF_VERSION] +[LIBCEF_VERSION] LibVLC版本:[LIBVLC_VERSION]N] 語音伺服器版本: [VOICE_VERSION] </string> @@ -1438,6 +1438,9 @@ http://secondlife.com/support 求助解決問題。 <string name="InventoryNoMatchingItems"> 找不到你要找的嗎? 請試試 [secondlife:///app/search/places/ 搜尋]。 </string> + <string name="InventoryNoMatchingRecentItems"> + 找不到你要找的嗎? 請試試[secondlife:///app/inventory/filters 顯示過濾器]。 + </string> <string name="PlacesNoMatchingItems"> 找不到你要找的嗎? 請試試 [secondlife:///app/search/places/[SEARCH_TERM] 搜尋]。 </string> diff --git a/indra/newview/tests/llslurl_test.cpp b/indra/newview/tests/llslurl_test.cpp index d0f44dcda1..eabf922875 100644 --- a/indra/newview/tests/llslurl_test.cpp +++ b/indra/newview/tests/llslurl_test.cpp @@ -46,7 +46,7 @@ static const char * const TEST_FILENAME("llslurl_test.xml"); class LLTrans { public: - static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string); + static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string = false); }; std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string) diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp index 2aedb2eb4f..3dd327591e 100644 --- a/indra/newview/tests/llviewernetwork_test.cpp +++ b/indra/newview/tests/llviewernetwork_test.cpp @@ -45,7 +45,7 @@ static const char * const TEST_FILENAME("llviewernetwork_test.xml"); class LLTrans { public: - static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string=false); + static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string = false); }; std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string) |