summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/cmake/Copy3rdPartyLibs.cmake11
-rw-r--r--indra/cmake/Discord.cmake19
-rw-r--r--indra/llinventory/llinventory.cpp60
-rw-r--r--indra/llinventory/llinventory.h3
-rw-r--r--indra/llinventory/llpermissions.cpp104
-rw-r--r--indra/llinventory/llpermissions.h2
-rw-r--r--indra/llinventory/tests/inventorymisc_test.cpp2
-rw-r--r--indra/llmath/llvolume.cpp10
-rw-r--r--indra/llui/llfolderviewmodel.h67
-rw-r--r--indra/llui/lltextbase.cpp1
-rw-r--r--indra/llui/llurlaction.cpp28
-rw-r--r--indra/llui/llurlaction.h4
-rw-r--r--indra/llui/llurlentry.cpp18
-rw-r--r--indra/llui/llurlentry.h6
-rw-r--r--indra/llwebrtc/llwebrtc.cpp56
-rw-r--r--indra/llwebrtc/llwebrtc_impl.h7
-rw-r--r--indra/llwindow/llwindowwin32.cpp101
-rw-r--r--indra/llwindow/llwindowwin32.h7
-rw-r--r--indra/newview/CMakeLists.txt16
-rw-r--r--indra/newview/app_settings/settings.xml63
-rw-r--r--indra/newview/llagentwearables.cpp10
-rw-r--r--indra/newview/llappearancemgr.cpp2
-rw-r--r--indra/newview/llappviewer.cpp12
-rw-r--r--indra/newview/llappviewerwin32.cpp1
-rw-r--r--indra/newview/llconversationmodel.cpp20
-rw-r--r--indra/newview/llfloaterchatmentionpicker.cpp2
-rw-r--r--indra/newview/llfloaterimagepreview.cpp114
-rw-r--r--indra/newview/llfloaterimagepreview.h2
-rw-r--r--indra/newview/llfloaterimcontainer.cpp6
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp45
-rw-r--r--indra/newview/llfloatermediasettings.cpp9
-rw-r--r--indra/newview/llfloatermediasettings.h2
-rw-r--r--indra/newview/llfloatermodelpreview.cpp6
-rw-r--r--indra/newview/llfloatermodelpreview.h2
-rw-r--r--indra/newview/llfloaterpreference.cpp4
-rw-r--r--indra/newview/llfloatersettingsdebug.cpp5
-rw-r--r--indra/newview/llfloatersettingsdebug.h1
-rwxr-xr-xindra/newview/llfloaterworldmap.cpp46
-rw-r--r--indra/newview/llhudeffectlookat.cpp39
-rw-r--r--indra/newview/llhudeffectpointat.cpp14
-rw-r--r--indra/newview/llimprocessing.cpp4
-rw-r--r--indra/newview/llinventorybridge.cpp24
-rw-r--r--indra/newview/llinventorybridge.h1
-rw-r--r--indra/newview/llinventoryfunctions.cpp10
-rw-r--r--indra/newview/llinventorymodel.cpp172
-rw-r--r--indra/newview/lllogchat.cpp33
-rw-r--r--indra/newview/llmeshrepository.cpp10
-rw-r--r--indra/newview/llmutelist.cpp50
-rw-r--r--indra/newview/llmutelist.h14
-rw-r--r--indra/newview/lloutfitslist.cpp24
-rw-r--r--indra/newview/llpanelemojicomplete.cpp1
-rw-r--r--indra/newview/llpanelface.cpp17
-rw-r--r--indra/newview/llpanellogin.cpp103
-rw-r--r--indra/newview/llpanellogin.h1
-rw-r--r--indra/newview/llpanelpeople.cpp2
-rw-r--r--indra/newview/llpanelpeoplemenus.cpp6
-rw-r--r--indra/newview/llselectmgr.cpp22
-rw-r--r--indra/newview/llspeakers.cpp2
-rw-r--r--indra/newview/llstatusbar.cpp62
-rw-r--r--indra/newview/llstatusbar.h12
-rw-r--r--indra/newview/lltooldraganddrop.cpp13
-rw-r--r--indra/newview/llviewerinventory.cpp19
-rw-r--r--indra/newview/llviewerinventory.h2
-rw-r--r--indra/newview/llviewermedia_streamingaudio.cpp21
-rw-r--r--indra/newview/llviewermenufile.cpp161
-rw-r--r--indra/newview/llviewermessage.cpp16
-rw-r--r--indra/newview/llvoavatar.cpp76
-rw-r--r--indra/newview/llvoavatar.h5
-rw-r--r--indra/newview/llvoavatarself.cpp14
-rw-r--r--indra/newview/llvoavatarself.h2
-rw-r--r--indra/newview/llvoicewebrtc.cpp42
-rw-r--r--indra/newview/res/ll_icon_small.icobin0 -> 91010 bytes
-rw-r--r--indra/newview/res/resource.h1
-rwxr-xr-xindra/newview/res/viewerRes.rc1
-rw-r--r--indra/newview/skins/default/textures/textures.xml1
-rw-r--r--indra/newview/skins/default/textures/windows/first_login_image.jpgbin199811 -> 0 bytes
-rw-r--r--indra/newview/skins/default/xui/de/panel_login_first.xml39
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_slapp.xml10
-rw-r--r--indra/newview/skins/default/xui/en/menu_url_parcel.xml2
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml11
-rw-r--r--indra/newview/skins/default/xui/en/panel_login_first.xml262
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_advanced.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_privacy.xml33
-rw-r--r--indra/newview/skins/default/xui/en/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_login_first.xml39
-rw-r--r--indra/newview/skins/default/xui/fr/panel_login_first.xml39
-rw-r--r--indra/newview/skins/default/xui/it/panel_login_first.xml39
-rw-r--r--indra/newview/skins/default/xui/ja/panel_login_first.xml54
-rw-r--r--indra/newview/skins/default/xui/pl/panel_login_first.xml30
-rw-r--r--indra/newview/skins/default/xui/pt/panel_login_first.xml39
-rw-r--r--indra/newview/skins/default/xui/ru/panel_login_first.xml39
-rw-r--r--indra/newview/skins/default/xui/tr/panel_login_first.xml39
-rw-r--r--indra/newview/skins/default/xui/zh/panel_login_first.xml39
-rw-r--r--indra/newview/tests/llviewerassetstats_test.cpp5
-rwxr-xr-xindra/newview/viewer_manifest.py12
95 files changed, 1433 insertions, 1181 deletions
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 6ac00fd131..0153e69d5b 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -6,6 +6,9 @@
include(CMakeCopyIfDifferent)
include(Linking)
+if (USE_DISCORD)
+ include(Discord)
+endif ()
include(OPENAL)
# When we copy our dependent libraries, we almost always want to copy them to
@@ -75,6 +78,10 @@ if(WINDOWS)
endif(ADDRESS_SIZE EQUAL 32)
endif (USE_BUGSPLAT)
+ if (TARGET ll::discord_sdk)
+ list(APPEND release_files discord_partner_sdk.dll)
+ endif ()
+
if (TARGET ll::openal)
list(APPEND release_files openal32.dll alut.dll)
endif ()
@@ -180,6 +187,10 @@ elseif(DARWIN)
)
endif()
+ if (TARGET ll::discord_sdk)
+ list(APPEND release_files libdiscord_partner_sdk.dylib)
+ endif ()
+
if (TARGET ll::openal)
list(APPEND release_files libalut.dylib libopenal.dylib)
endif ()
diff --git a/indra/cmake/Discord.cmake b/indra/cmake/Discord.cmake
index 52c0765ae7..1896c12853 100644
--- a/indra/cmake/Discord.cmake
+++ b/indra/cmake/Discord.cmake
@@ -1,18 +1,23 @@
include(Prebuilt)
-add_library(ll::discord INTERFACE IMPORTED)
-target_compile_definitions(ll::discord INTERFACE LL_DISCORD=1)
+include_guard()
-if (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/discord_installed OR NOT ${discord_installed} EQUAL 0)
+add_library(ll::discord_sdk INTERFACE IMPORTED)
+target_compile_definitions(ll::discord_sdk INTERFACE LL_DISCORD=1)
+
+#use_prebuilt_binary(discord_sdk)
+
+if (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/discord_sdk_installed OR NOT ${discord_sdk_installed} EQUAL 0)
file(ARCHIVE_EXTRACT
INPUT $ENV{HOME}/Downloads/DiscordSocialSdk-1.4.9649.zip
DESTINATION ${CMAKE_BINARY_DIR}
)
+ file(MAKE_DIRECTORY ${LIBS_PREBUILT_DIR}/include/discord_sdk)
file(
COPY
${CMAKE_BINARY_DIR}/discord_social_sdk/include/cdiscord.h
${CMAKE_BINARY_DIR}/discord_social_sdk/include/discordpp.h
- DESTINATION ${LIBS_PREBUILT_DIR}/include
+ DESTINATION ${LIBS_PREBUILT_DIR}/include/discord_sdk
)
if (WINDOWS)
file(
@@ -38,8 +43,8 @@ if (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKIN
DESTINATION ${ARCH_PREBUILT_DIRS_RELEASE}
)
endif ()
- file(WRITE ${PREBUILD_TRACKING_DIR}/discord_installed "0")
+ file(WRITE ${PREBUILD_TRACKING_DIR}/discord_sdk_installed "0")
endif ()
-target_include_directories(ll::discord SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
-target_link_libraries(ll::discord INTERFACE discord_partner_sdk)
+target_include_directories(ll::discord_sdk SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/discord_sdk)
+target_link_libraries(ll::discord_sdk INTERFACE discord_partner_sdk)
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index fe60800700..3defad8f3b 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -995,6 +995,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
// TODO - figure out if this should be moved into the noclobber fields above
mThumbnailUUID.setNull();
mFavorite = false;
+ mPermissions.init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
// iterate as map to avoid making unnecessary temp copies of everything
LLSD::map_const_iterator i, end;
@@ -1053,7 +1054,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
if (i->first == INV_PERMISSIONS_LABEL)
{
- mPermissions = ll_permissions_from_sd(i->second);
+ mPermissions.importLLSD(i->second);
continue;
}
@@ -1522,53 +1523,68 @@ void LLInventoryCategory::exportLLSD(LLSD& cat_data) const
}
}
-bool LLInventoryCategory::importLLSD(const LLSD& cat_data)
+bool LLInventoryCategory::importLLSDMap(const LLSD& cat_data)
{
- if (cat_data.has(INV_FOLDER_ID_LABEL))
+ LLSD::map_const_iterator i, end;
+ end = cat_data.endMap();
+ for ( i = cat_data.beginMap(); i != end; ++i)
+ {
+ importLLSD(i->first, i->second);
+ }
+ return true;
+}
+
+bool LLInventoryCategory::importLLSD(const std::string& label, const LLSD& value)
+{
+ if (label == INV_FOLDER_ID_LABEL)
{
- setUUID(cat_data[INV_FOLDER_ID_LABEL].asUUID());
+ setUUID(value.asUUID());
+ return true;
}
- if (cat_data.has(INV_PARENT_ID_LABEL))
+ else if (label == INV_PARENT_ID_LABEL)
{
- setParent(cat_data[INV_PARENT_ID_LABEL].asUUID());
+ setParent(value.asUUID());
+ return true;
}
- if (cat_data.has(INV_ASSET_TYPE_LABEL))
+ else if (label == INV_ASSET_TYPE_LABEL)
{
- setType(LLAssetType::lookup(cat_data[INV_ASSET_TYPE_LABEL].asString()));
+ setType(LLAssetType::lookup(value.asString()));
+ return true;
}
- if (cat_data.has(INV_PREFERRED_TYPE_LABEL))
+ else if (label == INV_PREFERRED_TYPE_LABEL)
{
- setPreferredType(LLFolderType::lookup(cat_data[INV_PREFERRED_TYPE_LABEL].asString()));
+ setPreferredType(LLFolderType::lookup(value.asString()));
+ return true;
}
- if (cat_data.has(INV_THUMBNAIL_LABEL))
+ else if (label == INV_THUMBNAIL_LABEL)
{
LLUUID thumbnail_uuid;
- const LLSD &thumbnail_data = cat_data[INV_THUMBNAIL_LABEL];
- if (thumbnail_data.has(INV_ASSET_ID_LABEL))
+ if (value.has(INV_ASSET_ID_LABEL))
{
- thumbnail_uuid = thumbnail_data[INV_ASSET_ID_LABEL].asUUID();
+ thumbnail_uuid = value[INV_ASSET_ID_LABEL].asUUID();
}
setThumbnailUUID(thumbnail_uuid);
+ return true;
}
- if (cat_data.has(INV_FAVORITE_LABEL))
+ if (label == INV_FAVORITE_LABEL)
{
bool favorite = false;
- const LLSD& favorite_data = cat_data[INV_FAVORITE_LABEL];
- if (favorite_data.has(INV_TOGGLED_LABEL))
+ if (value.has(INV_TOGGLED_LABEL))
{
- favorite = favorite_data[INV_TOGGLED_LABEL].asBoolean();
+ favorite = value[INV_TOGGLED_LABEL].asBoolean();
}
setFavorite(favorite);
}
- if (cat_data.has(INV_NAME_LABEL))
+ else if (label == INV_NAME_LABEL)
{
- mName = cat_data[INV_NAME_LABEL].asString();
+ mName = value.asString();
LLStringUtil::replaceNonstandardASCII(mName, ' ');
LLStringUtil::replaceChar(mName, '|', ' ');
+ return true;
}
-
- return true;
+ return false;
}
+
///----------------------------------------------------------------------------
/// Local function definitions for testing purposes
///----------------------------------------------------------------------------
diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h
index 17670d2ea1..181c46226c 100644
--- a/indra/llinventory/llinventory.h
+++ b/indra/llinventory/llinventory.h
@@ -274,7 +274,8 @@ public:
virtual bool exportLegacyStream(std::ostream& output_stream, bool include_asset_key = true) const;
virtual void exportLLSD(LLSD& sd) const;
- bool importLLSD(const LLSD& cat_data);
+ bool importLLSDMap(const LLSD& cat_data);
+ virtual bool importLLSD(const std::string& label, const LLSD& value);
//--------------------------------------------------------------------
// Member Variables
//--------------------------------------------------------------------
diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp
index d800ca02c9..ebf7445c65 100644
--- a/indra/llinventory/llpermissions.cpp
+++ b/indra/llinventory/llpermissions.cpp
@@ -704,6 +704,79 @@ bool LLPermissions::exportLegacyStream(std::ostream& output_stream) const
return true;
}
+static const std::string PERM_CREATOR_ID_LABEL("creator_id");
+static const std::string PERM_OWNER_ID_LABEL("owner_id");
+static const std::string PERM_LAST_OWNER_ID_LABEL("last_owner_id");
+static const std::string PERM_GROUP_ID_LABEL("group_id");
+static const std::string PERM_IS_OWNER_GROUP_LABEL("is_owner_group");
+static const std::string PERM_BASE_MASK_LABEL("base_mask");
+static const std::string PERM_OWNER_MASK_LABEL("owner_mask");
+static const std::string PERM_GROUP_MASK_LABEL("group_mask");
+static const std::string PERM_EVERYONE_MASK_LABEL("everyone_mask");
+static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask");
+
+void LLPermissions::importLLSD(const LLSD& sd_perm)
+{
+ LLSD::map_const_iterator i, end;
+ end = sd_perm.endMap();
+ for (i = sd_perm.beginMap(); i != end; ++i)
+ {
+ const std::string& label = i->first;
+ if (label == PERM_CREATOR_ID_LABEL)
+ {
+ mCreator = i->second.asUUID();
+ continue;
+ }
+ if (label == PERM_OWNER_ID_LABEL)
+ {
+ mOwner = i->second.asUUID();
+ continue;
+ }
+ if (label == PERM_LAST_OWNER_ID_LABEL)
+ {
+ mLastOwner = i->second.asUUID();
+ continue;
+ }
+ if (label == PERM_GROUP_ID_LABEL)
+ {
+ mGroup = i->second.asUUID();
+ continue;
+ }
+ if (label == PERM_BASE_MASK_LABEL)
+ {
+ PermissionMask mask = i->second.asInteger();
+ mMaskBase = mask;
+ continue;
+ }
+ if (label == PERM_OWNER_MASK_LABEL)
+ {
+ PermissionMask mask = i->second.asInteger();
+ mMaskOwner = mask;
+ continue;
+ }
+ if (label == PERM_EVERYONE_MASK_LABEL)
+ {
+ PermissionMask mask = i->second.asInteger();
+ mMaskEveryone = mask;
+ continue;
+ }
+ if (label == PERM_GROUP_MASK_LABEL)
+ {
+ PermissionMask mask = i->second.asInteger();
+ mMaskGroup = mask;
+ continue;
+ }
+ if (label == PERM_NEXT_OWNER_MASK_LABEL)
+ {
+ PermissionMask mask = i->second.asInteger();
+ mMaskNextOwner = mask;
+ continue;
+ }
+ }
+
+ fix();
+}
+
bool LLPermissions::operator==(const LLPermissions &rhs) const
{
return
@@ -998,16 +1071,6 @@ std::string mask_to_string(U32 mask)
///----------------------------------------------------------------------------
/// exported functions
///----------------------------------------------------------------------------
-static const std::string PERM_CREATOR_ID_LABEL("creator_id");
-static const std::string PERM_OWNER_ID_LABEL("owner_id");
-static const std::string PERM_LAST_OWNER_ID_LABEL("last_owner_id");
-static const std::string PERM_GROUP_ID_LABEL("group_id");
-static const std::string PERM_IS_OWNER_GROUP_LABEL("is_owner_group");
-static const std::string PERM_BASE_MASK_LABEL("base_mask");
-static const std::string PERM_OWNER_MASK_LABEL("owner_mask");
-static const std::string PERM_GROUP_MASK_LABEL("group_mask");
-static const std::string PERM_EVERYONE_MASK_LABEL("everyone_mask");
-static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask");
LLSD ll_create_sd_from_permissions(const LLPermissions& perm)
{
@@ -1032,25 +1095,6 @@ void ll_fill_sd_from_permissions(LLSD& rv, const LLPermissions& perm)
LLPermissions ll_permissions_from_sd(const LLSD& sd_perm)
{
LLPermissions rv;
- rv.init(
- sd_perm[PERM_CREATOR_ID_LABEL].asUUID(),
- sd_perm[PERM_OWNER_ID_LABEL].asUUID(),
- sd_perm[PERM_LAST_OWNER_ID_LABEL].asUUID(),
- sd_perm[PERM_GROUP_ID_LABEL].asUUID());
-
- // We do a cast to U32 here since LLSD does not attempt to
- // represent unsigned ints.
- PermissionMask mask;
- mask = (U32)(sd_perm[PERM_BASE_MASK_LABEL].asInteger());
- rv.setMaskBase(mask);
- mask = (U32)(sd_perm[PERM_OWNER_MASK_LABEL].asInteger());
- rv.setMaskOwner(mask);
- mask = (U32)(sd_perm[PERM_EVERYONE_MASK_LABEL].asInteger());
- rv.setMaskEveryone(mask);
- mask = (U32)(sd_perm[PERM_GROUP_MASK_LABEL].asInteger());
- rv.setMaskGroup(mask);
- mask = (U32)(sd_perm[PERM_NEXT_OWNER_MASK_LABEL].asInteger());
- rv.setMaskNext(mask);
- rv.fix();
+ rv.importLLSD(sd_perm);
return rv;
}
diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h
index f3e10af25c..82cdc03727 100644
--- a/indra/llinventory/llpermissions.h
+++ b/indra/llinventory/llpermissions.h
@@ -299,6 +299,8 @@ public:
bool importLegacyStream(std::istream& input_stream);
bool exportLegacyStream(std::ostream& output_stream) const;
+ void importLLSD(const LLSD& sd_perm);
+
bool operator==(const LLPermissions &rhs) const;
bool operator!=(const LLPermissions &rhs) const;
diff --git a/indra/llinventory/tests/inventorymisc_test.cpp b/indra/llinventory/tests/inventorymisc_test.cpp
index e41500b4c5..f11a4c3bf7 100644
--- a/indra/llinventory/tests/inventorymisc_test.cpp
+++ b/indra/llinventory/tests/inventorymisc_test.cpp
@@ -518,7 +518,7 @@ namespace tut
file.close();
LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory();
- src2->importLLSD(s_item);
+ src2->importLLSDMap(s_item);
ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index d56891cab3..e5521e0ffc 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -5711,7 +5711,15 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
S32 vert_count = 0;
if (!data.p.empty())
{
- vert_count = static_cast<S32>(meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count));
+ try
+ {
+ vert_count = static_cast<S32>(meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count));
+ }
+ catch (std::bad_alloc&)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS("LLCoros") << "Failed to allocate memory for VertexRemap: " << (S32)data.p.size() << LL_ENDL;
+ }
}
if (vert_count < 65535 && vert_count != 0)
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index ba9d0b8de3..2865b789b9 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -224,6 +224,7 @@ public:
virtual S32 getSortVersion() = 0;
virtual void setSortVersion(S32 version) = 0;
virtual void setParent(LLFolderViewModelItem* parent) = 0;
+ virtual const LLFolderViewModelItem* getParent() = 0;
virtual bool hasParent() = 0;
protected:
@@ -254,14 +255,14 @@ public:
mChildren.clear();
}
- void requestSort() { mSortVersion = -1; }
- S32 getSortVersion() { return mSortVersion; }
- void setSortVersion(S32 version) { mSortVersion = version;}
+ void requestSort() override { mSortVersion = -1; }
+ S32 getSortVersion() override { return mSortVersion; }
+ void setSortVersion(S32 version) override { mSortVersion = version;}
- S32 getLastFilterGeneration() const { return mLastFilterGeneration; }
+ S32 getLastFilterGeneration() const override { return mLastFilterGeneration; }
S32 getLastFolderFilterGeneration() const { return mLastFolderFilterGeneration; }
- S32 getMarkedDirtyGeneration() const { return mMarkedDirtyGeneration; }
- void dirtyFilter()
+ S32 getMarkedDirtyGeneration() const override { return mMarkedDirtyGeneration; }
+ void dirtyFilter() override
{
if(mMarkedDirtyGeneration < 0)
{
@@ -276,7 +277,7 @@ public:
mParent->dirtyFilter();
}
}
- void dirtyDescendantsFilter()
+ void dirtyDescendantsFilter() override
{
mMostFilteredDescendantGeneration = -1;
if (mParent)
@@ -284,13 +285,13 @@ public:
mParent->dirtyDescendantsFilter();
}
}
- bool hasFilterStringMatch();
- std::string::size_type getFilterStringOffset();
- std::string::size_type getFilterStringSize();
+ bool hasFilterStringMatch() override;
+ std::string::size_type getFilterStringOffset() override;
+ std::string::size_type getFilterStringSize() override;
- typedef std::list<LLFolderViewModelItem*> child_list_t;
+ typedef std::list<LLPointer<LLFolderViewModelItem> > child_list_t;
- virtual void addChild(LLFolderViewModelItem* child)
+ virtual void addChild(LLFolderViewModelItem* child) override
{
mChildren.push_back(child);
child->setParent(this);
@@ -298,15 +299,15 @@ public:
requestSort();
}
- virtual void removeChild(LLFolderViewModelItem* child)
+ virtual void removeChild(LLFolderViewModelItem* child) override final
{
- mChildren.remove(child);
child->setParent(NULL);
+ mChildren.remove(child);
dirtyDescendantsFilter();
dirtyFilter();
}
- virtual void clearChildren()
+ virtual void clearChildren() override
{
// We are working with models that belong to views as LLPointers, clean the list, let poiters handle the rest
std::for_each(mChildren.begin(), mChildren.end(), [](LLFolderViewModelItem* c) {c->setParent(NULL); });
@@ -319,7 +320,7 @@ public:
child_list_t::const_iterator getChildrenEnd() const { return mChildren.end(); }
child_list_t::size_type getChildrenCount() const { return mChildren.size(); }
- void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0)
+ void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) override
{
mPassedFilter = passed;
mLastFilterGeneration = filter_generation;
@@ -328,20 +329,20 @@ public:
mMarkedDirtyGeneration = -1;
}
- void setPassedFolderFilter(bool passed, S32 filter_generation)
+ void setPassedFolderFilter(bool passed, S32 filter_generation) override
{
mPassedFolderFilter = passed;
mLastFolderFilterGeneration = filter_generation;
}
- virtual bool potentiallyVisible()
+ virtual bool potentiallyVisible() override
{
return passedFilter() // we've passed the filter
|| (getLastFilterGeneration() < mRootViewModel.getFilter().getFirstSuccessGeneration()) // or we don't know yet
|| descendantsPassedFilter();
}
- virtual bool passedFilter(S32 filter_generation = -1)
+ virtual bool passedFilter(S32 filter_generation = -1) override
{
if (filter_generation < 0)
{
@@ -352,7 +353,7 @@ public:
return passed_folder_filter && (passed_filter || descendantsPassedFilter(filter_generation));
}
- virtual bool descendantsPassedFilter(S32 filter_generation = -1)
+ virtual bool descendantsPassedFilter(S32 filter_generation = -1) override
{
if (filter_generation < 0)
{
@@ -361,10 +362,10 @@ public:
return mMostFilteredDescendantGeneration >= filter_generation;
}
-
protected:
- virtual void setParent(LLFolderViewModelItem* parent) { mParent = parent; }
- virtual bool hasParent() { return mParent != NULL; }
+ virtual void setParent(LLFolderViewModelItem* parent) override final { mParent = parent; }
+ virtual const LLFolderViewModelItem* getParent() override { return mParent; };
+ virtual bool hasParent() override { return mParent != NULL; }
S32 mSortVersion;
bool mPassedFilter;
@@ -381,7 +382,7 @@ protected:
LLFolderViewModelItem* mParent;
LLFolderViewModelInterface& mRootViewModel;
- void setFolderViewItem(LLFolderViewItem* folder_view_item) { mFolderViewItem = folder_view_item;}
+ void setFolderViewItem(LLFolderViewItem* folder_view_item) override { mFolderViewItem = folder_view_item;}
LLFolderViewItem* mFolderViewItem;
};
@@ -395,15 +396,15 @@ public:
mFolderView(NULL)
{}
- virtual void requestSortAll()
+ virtual void requestSortAll() override
{
// sort everything
mTargetSortVersion++;
}
- virtual std::string getStatusText(bool is_empty_folder = false);
- virtual void filter();
+ virtual std::string getStatusText(bool is_empty_folder = false) override;
+ virtual void filter() override;
- void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;}
+ void setFolderView(LLFolderView* folder_view) override { mFolderView = folder_view;}
protected:
bool needsSort(class LLFolderViewModelItem* item);
@@ -433,14 +434,14 @@ public:
virtual const SortType& getSorter() const { return *mSorter; }
virtual void setSorter(const SortType& sorter) { mSorter.reset(new SortType(sorter)); requestSortAll(); }
- virtual FilterType& getFilter() { return *mFilter; }
- virtual const FilterType& getFilter() const { return *mFilter; }
+ virtual FilterType& getFilter() override { return *mFilter; }
+ virtual const FilterType& getFilter() const override { return *mFilter; }
virtual void setFilter(const FilterType& filter) { mFilter.reset(new FilterType(filter)); }
// By default, we assume the content is available. If a network fetch mechanism is implemented for the model,
// this method needs to be overloaded and return the relevant fetch status.
- virtual bool contentsReady() { return true; }
- virtual bool isFolderComplete(LLFolderViewFolder* folder) { return true; }
+ virtual bool contentsReady() override { return true; }
+ virtual bool isFolderComplete(LLFolderViewFolder* folder) override { return true; }
struct ViewModelCompare
{
@@ -461,7 +462,7 @@ public:
const SortType& mSorter;
};
- void sort(LLFolderViewFolder* folder)
+ void sort(LLFolderViewFolder* folder) override
{
if (needsSort(folder->getViewModelItem()))
{
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 778b253c3c..7007049e1c 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -2228,6 +2228,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
registrar.add("Url.ReportAbuse", boost::bind(&LLUrlAction::reportAbuse, url));
registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url));
registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));
+ registrar.add("Url.ShowParcelOnMap", boost::bind(&LLUrlAction::showParcelOnMap, url));
registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url));
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index b6b450c2a1..fdae22cfa1 100644
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -30,6 +30,7 @@
#include "llview.h"
#include "llwindow.h"
#include "llurlregistry.h"
+#include "v3dmath.h"
// global state for the callback functions
@@ -128,6 +129,23 @@ void LLUrlAction::showLocationOnMap(std::string url)
}
}
+void LLUrlAction::showParcelOnMap(std::string url)
+{
+ LLSD path_array = LLURI(url).pathArray();
+ auto path_parts = path_array.size();
+
+ if (path_parts < 3) // no parcel id
+ {
+ LL_WARNS() << "Global coordinates are missing in url: [" << url << "]" << LL_ENDL;
+ return;
+ }
+
+ LLVector3d parcel_pos = LLUrlEntryParcel::getParcelPos(LLUUID(LLURI::unescape(path_array[2])));
+ std::ostringstream pos;
+ pos << parcel_pos.mdV[VX] << '/' << parcel_pos.mdV[VY] << '/' << parcel_pos.mdV[VZ];
+ executeSLURL("secondlife:///app/worldmap_global/" + pos.str());
+}
+
void LLUrlAction::copyURLToClipboard(std::string url)
{
LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(url));
@@ -142,6 +160,16 @@ void LLUrlAction::copyLabelToClipboard(std::string url)
}
}
+std::string LLUrlAction::getURLLabel(std::string url)
+{
+ LLUrlMatch match;
+ if (LLUrlRegistry::instance().findUrl(url, match))
+ {
+ return match.getLabel();
+ }
+ return "";
+}
+
void LLUrlAction::showProfile(std::string url)
{
// Get id from 'secondlife:///app/{cmd}/{id}/{action}'
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
index ac9741a7ad..8b7ab0e7c5 100644
--- a/indra/llui/llurlaction.h
+++ b/indra/llui/llurlaction.h
@@ -63,6 +63,8 @@ public:
/// if the Url specifies an SL location, show it on a map
static void showLocationOnMap(std::string url);
+ static void showParcelOnMap(std::string url);
+
/// perform the appropriate action for left-clicking on a Url
static void clickAction(std::string url, bool trusted_content);
@@ -72,6 +74,8 @@ public:
/// copy a Url to the clipboard
static void copyURLToClipboard(std::string url);
+ static std::string getURLLabel(std::string url);
+
/// if the Url specifies an SL command in the form like 'app/{cmd}/{id}/*', show its profile
static void showProfile(std::string url);
static std::string getUserID(std::string url);
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index bcd13b7f0b..95603d7ed5 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -41,8 +41,7 @@
#include "lluicolortable.h"
#include "message.h"
#include "llexperiencecache.h"
-
-#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))"
+#include "v3dmath.h"
// Utility functions
std::string localize_slapp_label(const std::string& url, const std::string& full_name);
@@ -1084,6 +1083,7 @@ LLUUID LLUrlEntryParcel::sSessionID(LLUUID::null);
LLHost LLUrlEntryParcel::sRegionHost;
bool LLUrlEntryParcel::sDisconnected(false);
std::set<LLUrlEntryParcel*> LLUrlEntryParcel::sParcelInfoObservers;
+std::map<LLUUID, LLVector3d> LLUrlEntryParcel::sParcelPos;
///
/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
@@ -1176,6 +1176,20 @@ void LLUrlEntryParcel::processParcelInfo(const LLParcelData& parcel_data)
url_entry->onParcelInfoReceived(parcel_data.parcel_id.asString(), label);
}
}
+ if (sParcelPos.find(parcel_data.parcel_id) == sParcelPos.end())
+ {
+ sParcelPos[parcel_data.parcel_id] = LLVector3d(parcel_data.global_x, parcel_data.global_y, parcel_data.global_z);
+ }
+}
+
+// static
+LLVector3d LLUrlEntryParcel::getParcelPos(const LLUUID& parcel_id)
+{
+ if (sParcelPos.find(parcel_id) != sParcelPos.end())
+ {
+ return sParcelPos[parcel_id];
+ }
+ return LLVector3d();
}
//
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 6e7d2fc80f..efb5081103 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -41,6 +41,9 @@
#include <map>
class LLAvatarName;
+class LLVector3d;
+
+#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))"
typedef boost::signals2::signal<void (const std::string& url,
const std::string& label,
@@ -434,6 +437,8 @@ public:
// Processes parcel label and triggers notifying observers.
static void processParcelInfo(const LLParcelData& parcel_data);
+ static LLVector3d getParcelPos(const LLUUID& parcel_id);
+
// Next setters are used to update agent and viewer connection information
// upon events like user login, viewer disconnect and user changing region host.
// These setters are made public to be accessible from newview and should not be
@@ -447,6 +452,7 @@ private:
static LLHost sRegionHost;
static bool sDisconnected;
static std::set<LLUrlEntryParcel*> sParcelInfoObservers;
+ static std::map<LLUUID, LLVector3d> sParcelPos;
};
///
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp
index 2ee6d912c1..b245774516 100644
--- a/indra/llwebrtc/llwebrtc.cpp
+++ b/indra/llwebrtc/llwebrtc.cpp
@@ -672,7 +672,10 @@ LLWebRTCPeerConnectionInterface *LLWebRTCImpl::newPeerConnection()
peerConnection->init(this);
mPeerConnections.emplace_back(peerConnection);
- peerConnection->enableSenderTracks(!mMute);
+ // Should it really start disabled?
+ // Seems like something doesn't get the memo and senders need to be reset later
+ // to remove the voice indicator from taskbar
+ peerConnection->enableSenderTracks(false);
if (mPeerConnections.empty())
{
setRecording(true);
@@ -706,7 +709,7 @@ void LLWebRTCImpl::freePeerConnection(LLWebRTCPeerConnectionInterface* peer_conn
LLWebRTCPeerConnectionImpl::LLWebRTCPeerConnectionImpl() :
mWebRTCImpl(nullptr),
mPeerConnection(nullptr),
- mMute(true),
+ mMute(MUTE_INITIAL),
mAnswerReceived(false)
{
}
@@ -741,6 +744,19 @@ void LLWebRTCPeerConnectionImpl::terminate()
}
}
+ // to remove 'Secondlife is recording' icon from taskbar
+ // if user was speaking
+ auto senders = mPeerConnection->GetSenders();
+ for (auto& sender : senders)
+ {
+ auto track = sender->track();
+ if (track)
+ {
+ track->set_enabled(false);
+ }
+ }
+ mPeerConnection->SetAudioRecording(false);
+
mPeerConnection->Close();
if (mLocalStream)
{
@@ -830,6 +846,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
audioOptions.auto_gain_control = true;
audioOptions.echo_cancellation = true;
audioOptions.noise_suppression = true;
+ audioOptions.init_recording_on_send = false;
mLocalStream = mPeerConnectionFactory->CreateLocalMediaStream("SLStream");
@@ -894,6 +911,7 @@ void LLWebRTCPeerConnectionImpl::enableSenderTracks(bool enable)
{
sender->track()->set_enabled(enable);
}
+ mPeerConnection->SetAudioRecording(enable);
}
}
@@ -934,9 +952,17 @@ void LLWebRTCPeerConnectionImpl::AnswerAvailable(const std::string &sdp)
void LLWebRTCPeerConnectionImpl::setMute(bool mute)
{
- mMute = mute;
+ EMicMuteState new_state = mute ? MUTE_MUTED : MUTE_UNMUTED;
+ if (new_state == mMute)
+ {
+ return; // no change
+ }
+ bool force_reset = mMute == MUTE_INITIAL && mute;
+ bool enable = !mute;
+ mMute = new_state;
+
mWebRTCImpl->PostSignalingTask(
- [this]()
+ [this, force_reset, enable]()
{
if (mPeerConnection)
{
@@ -948,16 +974,34 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute)
auto track = sender->track();
if (track)
{
- track->set_enabled(!mMute);
+ if (force_reset)
+ {
+ // Force notify observers
+ // Was it disabled too early?
+ // Without this microphone icon in Win's taskbar will stay
+ track->set_enabled(true);
+ }
+ track->set_enabled(enable);
}
}
+ mPeerConnection->SetAudioRecording(enable);
}
});
}
void LLWebRTCPeerConnectionImpl::resetMute()
{
- setMute(mMute);
+ switch(mMute)
+ {
+ case MUTE_MUTED:
+ setMute(true);
+ break;
+ case MUTE_UNMUTED:
+ setMute(false);
+ break;
+ default:
+ break;
+ }
}
void LLWebRTCPeerConnectionImpl::setReceiveVolume(float volume)
diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h
index 99accb2c20..dfdb19e9be 100644
--- a/indra/llwebrtc/llwebrtc_impl.h
+++ b/indra/llwebrtc/llwebrtc_impl.h
@@ -425,7 +425,12 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface,
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> mPeerConnectionFactory;
- bool mMute;
+ typedef enum {
+ MUTE_INITIAL,
+ MUTE_MUTED,
+ MUTE_UNMUTED,
+ } EMicMuteState;
+ EMicMuteState mMute;
// signaling
std::vector<LLWebRTCSignalingObserver *> mSignalingObserverList;
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 8960519bc2..2656f21def 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -76,6 +76,11 @@
#pragma comment(lib, "dxguid.lib") // needed for llurlentry test to build on some systems
#pragma comment(lib, "dinput8")
+#pragma comment(lib, "UxTheme.lib")
+#pragma comment(lib, "Dwmapi.lib")
+#include <Uxtheme.h>
+#include <dwmapi.h> // needed for DwmSetWindowAttribute to set window theme
+
const S32 MAX_MESSAGE_PER_UPDATE = 20;
const S32 BITS_PER_PIXEL = 32;
const S32 MAX_NUM_RESOLUTIONS = 32;
@@ -85,6 +90,10 @@ const F32 ICON_FLASH_TIME = 0.5f;
#define USER_DEFAULT_SCREEN_DPI 96 // Win7
#endif
+#ifndef WM_DWMCOLORIZATIONCOLORCHANGED
+#define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320
+#endif
+
// Claim a couple unused GetMessage() message IDs
const UINT WM_DUMMY_(WM_USER + 0x0017);
const UINT WM_POST_FUNCTION_(WM_USER + 0x0018);
@@ -104,6 +113,7 @@ static std::thread::id sMainThreadId;
LPWSTR gIconResource = IDI_APPLICATION;
+LPWSTR gIconSmallResource = IDI_APPLICATION;
LPDIRECTINPUT8 gDirectInput8;
LLW32MsgCallback gAsyncMsgCallback = NULL;
@@ -137,6 +147,17 @@ typedef HRESULT(STDAPICALLTYPE *GetDpiForMonitorType)(
_Out_ UINT *dpiX,
_Out_ UINT *dpiY);
+typedef enum PREFERRED_APP_MODE
+{
+ DEFAULT,
+ ALLOW_DARK,
+ FORCE_DARK,
+ FORCE_LIGHT,
+ MAX
+} PREFERRED_APP_MODE;
+
+typedef PREFERRED_APP_MODE(WINAPI* fnSetPreferredAppMode)(PREFERRED_APP_MODE mode);
+
//
// LLWindowWin32
//
@@ -512,6 +533,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
mFSAASamples = fsaa_samples;
mIconResource = gIconResource;
+ mIconSmallResource = gIconSmallResource;
mOverrideAspectRatio = 0.f;
mNativeAspectRatio = 0.f;
mInputProcessingPaused = false;
@@ -846,6 +868,8 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
// Initialize (boot strap) the Language text input management,
// based on the system's (or user's) default settings.
allowLanguageTextInput(NULL, false);
+ updateWindowTheme();
+ setCustomIcon();
}
@@ -3020,6 +3044,17 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
WINDOW_IMP_POST(window_imp->mMouseVanish = true);
}
}
+ // Check if theme-related settings changed
+ else if (l_param && (wcscmp((LPCWSTR)l_param, L"ImmersiveColorSet") == 0))
+ {
+ WINDOW_IMP_POST(window_imp->updateWindowTheme());
+ }
+ }
+ break;
+
+ case WM_DWMCOLORIZATIONCOLORCHANGED:
+ {
+ WINDOW_IMP_POST(window_imp->updateWindowTheme());
}
break;
@@ -4962,3 +4997,69 @@ void LLWindowWin32::updateWindowRect()
});
}
}
+
+bool LLWindowWin32::isSystemAppDarkMode()
+{
+ HKEY hKey;
+ DWORD dwValue = 1; // Default to light theme
+ DWORD dwSize = sizeof(DWORD);
+
+ // Check registry for system theme preference
+ LSTATUS ret_code =
+ RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_READ, &hKey);
+ if (ERROR_SUCCESS == ret_code)
+ {
+ if (RegQueryValueExW(hKey, L"AppsUseLightTheme", NULL, NULL, (LPBYTE)&dwValue, &dwSize) != ERROR_SUCCESS)
+ {
+ // If AppsUseLightTheme is not found, check SystemUsesLightTheme
+ dwSize = sizeof(DWORD);
+ RegQueryValueExW(hKey, L"SystemUsesLightTheme", NULL, NULL, (LPBYTE)&dwValue, &dwSize);
+ }
+ RegCloseKey(hKey);
+ }
+
+ // Return true if dark mode
+ return dwValue == 0;
+}
+
+void LLWindowWin32::updateWindowTheme()
+{
+ bool use_dark_mode = isSystemAppDarkMode();
+ if (use_dark_mode == mCurrentDarkMode)
+ {
+ return;
+ }
+ mCurrentDarkMode = use_dark_mode;
+
+ HMODULE hUxTheme = LoadLibraryExW(L"uxtheme.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ if (hUxTheme)
+ {
+ auto SetPreferredAppMode = (fnSetPreferredAppMode)GetProcAddress(hUxTheme, "SetPreferredAppMode");
+ if (SetPreferredAppMode)
+ {
+ SetPreferredAppMode(use_dark_mode ? ALLOW_DARK : FORCE_LIGHT);
+ }
+ FreeLibrary(hUxTheme);
+ }
+ BOOL dark_mode(use_dark_mode);
+ DwmSetWindowAttribute(mWindowHandle, DWMWA_USE_IMMERSIVE_DARK_MODE, &dark_mode, sizeof(dark_mode));
+
+ LL_INFOS("Window") << "Viewer window theme is set to " << (use_dark_mode ? "dark" : "light") << " mode" << LL_ENDL;
+}
+
+void LLWindowWin32::setCustomIcon()
+{
+ if (mWindowHandle)
+ {
+ HICON hDefaultIcon = LoadIcon(mhInstance, mIconResource);
+ HICON hSmallIcon = LoadIcon(mhInstance, mIconSmallResource);
+ mWindowThread->post([=]()
+ {
+ SendMessage(mWindowHandle, WM_SETICON, ICON_BIG, (LPARAM)hDefaultIcon);
+ SendMessage(mWindowHandle, WM_SETICON, ICON_SMALL, (LPARAM)hSmallIcon);
+
+ SetClassLongPtr(mWindowHandle, GCLP_HICON, (LONG_PTR)hDefaultIcon);
+ SetClassLongPtr(mWindowHandle, GCLP_HICONSM, (LONG_PTR)hSmallIcon);
+ });
+ }
+}
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 561f07d388..7196706f87 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -214,6 +214,7 @@ protected:
bool mCustomGammaSet;
LPWSTR mIconResource;
+ LPWSTR mIconSmallResource;
bool mInputProcessingPaused;
// The following variables are for Language Text Input control.
@@ -246,6 +247,11 @@ protected:
RECT mRect;
RECT mClientRect;
+ void updateWindowTheme();
+ bool isSystemAppDarkMode();
+ void setCustomIcon();
+ bool mCurrentDarkMode { false };
+
struct LLWindowWin32Thread;
LLWindowWin32Thread* mWindowThread = nullptr;
LLThreadSafeQueue<std::function<void()>> mFunctionQueue;
@@ -281,6 +287,7 @@ private:
extern LLW32MsgCallback gAsyncMsgCallback;
extern LPWSTR gIconResource;
+extern LPWSTR gIconSmallResource;
S32 OSMessageBoxWin32(const std::string& text, const std::string& caption, U32 type);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 019d656471..9b30902de9 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1605,6 +1605,7 @@ if (WINDOWS)
res-sdl/ll_icon.BMP
res/ll_icon.BMP
res/ll_icon.ico
+ res/ll_icon_small.ico
res/resource.h
res/toolpickobject.cur
res/toolpickobject2.cur
@@ -1913,6 +1914,12 @@ if (WINDOWS)
)
endif (ADDRESS_SIZE EQUAL 64)
+ if (TARGET ll::discord_sdk)
+ list(APPEND COPY_INPUT_DEPENDENCIES
+ ${SHARED_LIB_STAGING_DIR}/discord_partner_sdk.dll
+ )
+ endif ()
+
if (TARGET ll::openal)
list(APPEND COPY_INPUT_DEPENDENCIES
${SHARED_LIB_STAGING_DIR}/OpenAL32.dll
@@ -1929,6 +1936,7 @@ if (WINDOWS)
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
+ "--discord=${USE_DISCORD}"
"--openal=${USE_OPENAL}"
"--tracy=${USE_TRACY}"
--build=${CMAKE_CURRENT_BINARY_DIR}
@@ -1967,6 +1975,7 @@ if (WINDOWS)
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
+ "--discord=${USE_DISCORD}"
"--openal=${USE_OPENAL}"
"--tracy=${USE_TRACY}"
--build=${CMAKE_CURRENT_BINARY_DIR}
@@ -2044,6 +2053,7 @@ if (WINDOWS)
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
+ "--discord=${USE_DISCORD}"
"--openal=${USE_OPENAL}"
"--tracy=${USE_TRACY}"
--build=${CMAKE_CURRENT_BINARY_DIR}
@@ -2151,7 +2161,7 @@ if (ENABLE_MEDIA_PLUGINS)
endif ()
if (USE_DISCORD)
- target_link_libraries(${VIEWER_BINARY_NAME} ll::discord )
+ target_link_libraries(${VIEWER_BINARY_NAME} ll::discord_sdk )
endif ()
if( TARGET ll::intel_memops )
@@ -2269,6 +2279,7 @@ if (LINUX)
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
+ "--discord=${USE_DISCORD}"
"--openal=${USE_OPENAL}"
"--tracy=${USE_TRACY}"
--build=${CMAKE_CURRENT_BINARY_DIR}
@@ -2351,6 +2362,7 @@ if (LINUX)
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
+ "--discord=${USE_DISCORD}"
"--openal=${USE_OPENAL}"
"--tracy=${USE_TRACY}"
--build=${CMAKE_CURRENT_BINARY_DIR}
@@ -2453,6 +2465,7 @@ if (DARWIN)
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
+ "--discord=${USE_DISCORD}"
"--openal=${USE_OPENAL}"
"--tracy=${USE_TRACY}"
--build=${CMAKE_CURRENT_BINARY_DIR}
@@ -2507,6 +2520,7 @@ if (DARWIN)
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
+ "--discord=${USE_DISCORD}"
"--openal=${USE_OPENAL}"
"--tracy=${USE_TRACY}"
--build=${CMAKE_CURRENT_BINARY_DIR}
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index ff9f2b96a7..2b26eb105e 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1219,13 +1219,13 @@
<key>DiskCachePercentOfTotal</key>
<map>
<key>Comment</key>
- <string>The percent of total cache size (defined by CacheSize) to use for the disk cache</string>
+ <string>The percent of total cache size (defined by CacheSize) to use for the disk cache (ex: asset storage, excludes textures)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>40.0</real>
+ <real>35.0</real>
</map>
<key>DiskCacheDirName</key>
<map>
@@ -1269,7 +1269,7 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <integer>4096</integer>
+ <integer>6144</integer>
</map>
<key>CacheValidateCounter</key>
<map>
@@ -9716,6 +9716,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>ObscureBalanceInStatusBar</key>
+ <map>
+ <key>Comment</key>
+ <string>If true, balance will be shows as '*'</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderUIBuffer</key>
<map>
<key>Comment</key>
@@ -13940,7 +13951,7 @@
<key>FullScreen</key>
<map>
<key>Comment</key>
- <string>run a fullscreen session</string>
+ <string>Run a fullscreen session. MacOS not supported</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -16837,5 +16848,49 @@
<key>Value</key>
<integer>31</integer>
</map>
+ <key>EnableSelectionHints</key>
+ <map>
+ <key>Comment</key>
+ <string>Whether or not to send editing hints to animate the arm when editing an object.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>EnableLookAtTarget</key>
+ <map>
+ <key>Comment</key>
+ <string>Whether or not to animate the avatar head and send look at targets when moving the cursor or focusing on objects</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>LimitLookAtTarget</key>
+ <map>
+ <key>Comment</key>
+ <string>Whether or not to clamp the look at targets around the avatar head before sending</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>LimitLookAtTargetDistance</key>
+ <map>
+ <key>Comment</key>
+ <string>Distance to limit look at target to</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <integer>2</integer>
+ </map>
</map>
</llsd>
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 5211884bc2..93cc4941f1 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1094,12 +1094,12 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
{
gAgentAvatarp->setCompositeUpdatesEnabled(true);
- // If we have not yet declouded, we may want to use
+ // If we have not yet loaded core parts, we may want to use
// baked texture UUIDs sent from the first objectUpdate message
- // don't overwrite these. If we have already declouded, we've saved
- // these ids as the last known good textures and can invalidate without
- // re-clouding.
- if (!gAgentAvatarp->getIsCloud())
+ // don't overwrite these. If we have parts already, we've saved
+ // these texture ids as the last known good textures and can
+ // invalidate without having to recloud avatar.
+ if (!gAgentAvatarp->getHasMissingParts())
{
gAgentAvatarp->invalidateAll();
}
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 4050bda024..71dec10e01 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -856,7 +856,7 @@ void LLWearableHoldingPattern::checkMissingWearables()
// was requested but none was found, create a default asset as a replacement.
// In all other cases, don't do anything.
// For critical types (shape/hair/skin/eyes), this will keep the avatar as a cloud
- // due to logic in LLVOAvatarSelf::getIsCloud().
+ // due to logic in LLVOAvatarSelf::getHasMissingParts().
// For non-critical types (tatoo, socks, etc.) the wearable will just be missing.
(requested_by_type[type] > 0) &&
((type == LLWearableType::WT_PANTS) || (type == LLWearableType::WT_SHIRT) || (type == LLWearableType::WT_SKIRT)))
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 53a3978086..32f4421ce2 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3178,7 +3178,15 @@ bool LLAppViewer::initWindow()
.height(gSavedSettings.getU32("WindowHeight"))
.min_width(gSavedSettings.getU32("MinWindowWidth"))
.min_height(gSavedSettings.getU32("MinWindowHeight"))
+#ifdef LL_DARWIN
+ // Setting it to true causes black screen with no UI displayed.
+ // Given that it's a DEBUG settings and application goes fullscreen
+ // on mac simply by expanding it, it was decided to not support/use
+ // this setting on mac.
+ .fullscreen(false)
+#else // LL_DARWIN
.fullscreen(gSavedSettings.getBOOL("FullScreen"))
+#endif
.ignore_pixel_depth(ignorePixelDepth)
.first_run(mIsFirstRun);
@@ -4365,8 +4373,8 @@ bool LLAppViewer::initCache()
const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName");
const U32 MB = 1024 * 1024;
- const uintmax_t MIN_CACHE_SIZE = 256 * MB;
- const uintmax_t MAX_CACHE_SIZE = 9984ll * MB;
+ const uintmax_t MIN_CACHE_SIZE = 896 * MB;
+ const uintmax_t MAX_CACHE_SIZE = 32768ll * MB;
const uintmax_t setting_cache_total_size = uintmax_t(gSavedSettings.getU32("CacheSize")) * MB;
const uintmax_t cache_total_size = llclamp(setting_cache_total_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE);
const F64 disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal");
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index f3214e2a20..d5cce28a3d 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -460,6 +460,7 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
// *FIX: global
gIconResource = MAKEINTRESOURCE(IDI_LL_ICON);
#endif
+ gIconSmallResource = MAKEINTRESOURCE(IDI_LL_ICON_SMALL);
LLAppViewerWin32* viewer_app_ptr = new LLAppViewerWin32(ll_convert_wide_to_string(pCmdLine).c_str());
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index af5a46742c..774e8fd4c5 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -300,7 +300,7 @@ void LLConversationItemSession::updateName(LLConversationItemParticipant* partic
for (auto itemp : mChildren)
{
- LLConversationItem* current_participant = dynamic_cast<LLConversationItem*>(itemp);
+ LLConversationItem* current_participant = dynamic_cast<LLConversationItem*>(itemp.get());
// Add the avatar uuid to the list (except if it's the own agent uuid)
if (current_participant->getUUID() != gAgentID)
{
@@ -329,6 +329,7 @@ void LLConversationItemSession::updateName(LLConversationItemParticipant* partic
void LLConversationItemSession::removeParticipant(LLConversationItemParticipant* participant)
{
+ LLPointer<LLFolderViewModelItem> holder(participant);
removeChild(participant);
mNeedsRefresh = true;
updateName(participant);
@@ -360,15 +361,10 @@ void LLConversationItemSession::clearAndDeparentModels()
for (child_list_t::iterator it = mChildren.begin(); it != mChildren.end();)
{
LLFolderViewModelItem* child = *it;
- if (child->getNumRefs() == 0)
+ // Note that model might still be assigned to some view/widget
+ // and have a different parent
+ if (child->getParent() == this)
{
- // LLConversationItemParticipant can be created but not assigned to any view,
- // it was waiting for an "add_participant" event to be processed
- delete child;
- }
- else
- {
- // Model is still assigned to some view/widget
child->setParent(NULL);
}
it = mChildren.erase(it);
@@ -383,7 +379,7 @@ LLConversationItemParticipant* LLConversationItemSession::findParticipant(const
child_list_t::iterator iter;
for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
{
- participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+ participant = dynamic_cast<LLConversationItemParticipant*>((*iter).get());
if (participant && participant->hasSameValue(participant_id))
{
break;
@@ -493,7 +489,7 @@ const bool LLConversationItemSession::getTime(F64& time) const
child_list_t::const_iterator iter;
for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
{
- participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+ participant = dynamic_cast<LLConversationItemParticipant*>((*iter).get());
F64 participant_time;
if (participant && participant->getTime(participant_time))
{
@@ -517,7 +513,7 @@ void LLConversationItemSession::dumpDebugData(bool dump_children)
{
for (child_list_t::iterator iter = mChildren.begin(); iter != mChildren.end(); iter++)
{
- LLConversationItemParticipant* participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+ LLConversationItemParticipant* participant = dynamic_cast<LLConversationItemParticipant*>((*iter).get());
if (participant)
{
participant->dumpDebugData();
diff --git a/indra/newview/llfloaterchatmentionpicker.cpp b/indra/newview/llfloaterchatmentionpicker.cpp
index 1cfed122a9..a3eb286375 100644
--- a/indra/newview/llfloaterchatmentionpicker.cpp
+++ b/indra/newview/llfloaterchatmentionpicker.cpp
@@ -88,7 +88,7 @@ uuid_vec_t LLFloaterChatMentionPicker::getParticipantIds()
LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
while (current_participant_model != end_participant_model)
{
- LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
+ LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>((*current_participant_model).get());
if (participant_model)
{
avatar_ids.push_back(participant_model->getUUID());
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index f254fdafaf..42a5df5d17 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -32,6 +32,7 @@
#include "llimagetga.h"
#include "llimagejpeg.h"
#include "llimagepng.h"
+#include "llimagej2c.h"
#include "llagent.h"
#include "llagentbenefits.h"
@@ -43,6 +44,10 @@
#include "llrender.h"
#include "llface.h"
#include "llfocusmgr.h"
+#include "llfilesystem.h"
+#include "llfloaterperms.h"
+#include "llnotificationsutil.h"
+#include "llstatusbar.h" // can_afford_transaction()
#include "lltextbox.h"
#include "lltoolmgr.h"
#include "llui.h"
@@ -52,6 +57,7 @@
#include "llvoavatar.h"
#include "pipeline.h"
#include "lluictrlfactory.h"
+#include "llviewermenufile.h" // upload_new_resource()
#include "llviewershadermgr.h"
#include "llviewertexturelist.h"
#include "llstring.h"
@@ -140,7 +146,7 @@ bool LLFloaterImagePreview::postBuild()
}
}
- getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this));
+ getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterImagePreview::onBtnOK, this));
return true;
}
@@ -244,6 +250,59 @@ void LLFloaterImagePreview::clearAllPreviewTextures()
}
//-----------------------------------------------------------------------------
+// onBtnOK()
+//-----------------------------------------------------------------------------
+void LLFloaterImagePreview::onBtnOK()
+{
+ getChildView("ok_btn")->setEnabled(false); // don't allow inadvertent extra uploads
+
+ S32 expected_upload_cost = getExpectedUploadCost();
+ if (can_afford_transaction(expected_upload_cost))
+ {
+ LL_INFOS() << "saving texture: " << mRawImagep->getWidth() << "x" << mRawImagep->getHeight() << LL_ENDL;
+ // gen a new uuid for this asset
+ LLTransactionID tid;
+ tid.generate();
+ LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+
+ LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
+
+ if (formatted->encode(mRawImagep, 0.0f))
+ {
+ LLFileSystem fmt_file(new_asset_id, LLAssetType::AT_TEXTURE, LLFileSystem::WRITE);
+ fmt_file.write(formatted->getData(), formatted->getDataSize());
+
+ LLResourceUploadInfo::ptr_t assetUploadInfo(new LLResourceUploadInfo(
+ tid, LLAssetType::AT_TEXTURE,
+ getChild<LLUICtrl>("name_form")->getValue().asString(),
+ getChild<LLUICtrl>("description_form")->getValue().asString(),
+ 0,
+ LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
+ expected_upload_cost
+ ));
+
+ upload_new_resource(assetUploadInfo);
+ }
+ else
+ {
+ LLNotificationsUtil::add("ErrorEncodingImage");
+ LL_WARNS() << "Error encoding image" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LLSD args;
+ args["COST"] = llformat("%d", expected_upload_cost);
+ LLNotificationsUtil::add("ErrorCannotAffordUpload", args);
+ }
+
+ closeFloater(false);
+}
+
+//-----------------------------------------------------------------------------
// draw()
//-----------------------------------------------------------------------------
void LLFloaterImagePreview::draw()
@@ -364,19 +423,6 @@ bool LLFloaterImagePreview::loadImage(const std::string& src_filename)
return false;
}
- S32 max_width = gSavedSettings.getS32("max_texture_dimension_X");
- S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y");
-
- if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))
- {
- LLStringUtil::format_map_t args;
- args["WIDTH"] = llformat("%d", max_width);
- args["HEIGHT"] = llformat("%d", max_height);
-
- mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args);
- return false;
- }
-
// Load the image
LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
if (image.isNull())
@@ -399,6 +445,46 @@ bool LLFloaterImagePreview::loadImage(const std::string& src_filename)
image->setLastError("Image files with less than 3 or more than 4 components are not supported.");
return false;
}
+ // Downscale images to fit the max_texture_dimensions_*
+ S32 max_width = gSavedSettings.getS32("max_texture_dimension_X");
+ S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y");
+
+ S32 orig_width = raw_image->getWidth();
+ S32 orig_height = raw_image->getHeight();
+
+ if (orig_width > max_width || orig_height > max_height)
+ {
+ // Calculate scale factors
+ F32 width_scale = (F32)max_width / (F32)orig_width;
+ F32 height_scale = (F32)max_height / (F32)orig_height;
+ F32 scale = llmin(width_scale, height_scale);
+
+ // Calculate new dimensions, preserving aspect ratio
+ S32 new_width = LLImageRaw::contractDimToPowerOfTwo(
+ llclamp((S32)llroundf(orig_width * scale), 4, max_width)
+ );
+ S32 new_height = LLImageRaw::contractDimToPowerOfTwo(
+ llclamp((S32)llroundf(orig_height * scale), 4, max_height)
+ );
+
+ if (!raw_image->scale(new_width, new_height))
+ {
+ LL_WARNS() << "Failed to scale image from "
+ << orig_width << "x" << orig_height
+ << " to " << new_width << "x" << new_height << LL_ENDL;
+ return false;
+ }
+
+ // Inform the resident about the resized image
+ LLSD subs;
+ subs["[ORIGINAL_WIDTH]"] = orig_width;
+ subs["[ORIGINAL_HEIGHT]"] = orig_height;
+ subs["[NEW_WIDTH]"] = new_width;
+ subs["[NEW_HEIGHT]"] = new_height;
+ subs["[MAX_WIDTH]"] = max_width;
+ subs["[MAX_HEIGHT]"] = max_height;
+ LLNotificationsUtil::add("ImageUploadResized", subs);
+ }
raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
mRawImagep = raw_image;
diff --git a/indra/newview/llfloaterimagepreview.h b/indra/newview/llfloaterimagepreview.h
index 9bc57246cf..5e5f4932c2 100644
--- a/indra/newview/llfloaterimagepreview.h
+++ b/indra/newview/llfloaterimagepreview.h
@@ -126,6 +126,8 @@ public:
void clearAllPreviewTextures();
+ void onBtnOK();
+
protected:
static void onPreviewTypeCommit(LLUICtrl*,void*);
void draw() override;
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 59ae8a9a81..bff0457a7d 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -460,7 +460,7 @@ void LLFloaterIMContainer::processParticipantsStyleUpdate()
LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = session_model->getChildrenEnd();
while (current_participant_model != end_participant_model)
{
- LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+ LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>((*current_participant_model).get());
if (participant_model)
{
// Get the avatar name for this participant id from the cache and update the model
@@ -511,7 +511,7 @@ void LLFloaterIMContainer::idleUpdate()
bool can_ban = haveAbilityToBan();
while (current_participant_model != end_participant_model)
{
- LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+ LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>((*current_participant_model).get());
if (participant_model)
{
participant_model->setModeratorOptionsVisible(is_moderator);
@@ -1882,7 +1882,7 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID&
LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
while (current_participant_model != end_participant_model)
{
- LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
+ LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>((*current_participant_model).get());
LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
participant_view->addToFolder(widget);
current_participant_model++;
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 733e178de3..5160ac4d34 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -107,26 +107,6 @@ LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
delete mRefreshTimer;
LLIMMgr::instance().removeSessionObserver(this);
mEmojiCloseConn.disconnect();
-
- LLFloaterIMContainer* im_container = LLFloaterIMContainer::findInstance();
- if (im_container)
- {
- LLParticipantList* session = dynamic_cast<LLParticipantList*>(im_container->getSessionModel(mSessionID));
- if (session)
- {
- for (const conversations_widgets_map::value_type& widget_pair : mConversationsWidgets)
- {
- LLFolderViewItem* widget = widget_pair.second;
- LLFolderViewModelItem* item_vmi = widget->getViewModelItem();
- if (item_vmi && item_vmi->getNumRefs() == 1)
- {
- // This is the last pointer, remove participant from session
- // before participant gets deleted on destroyView.
- session->removeChild(item_vmi);
- }
- }
- }
- }
}
// static
@@ -731,7 +711,7 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant()
LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
while (current_participant_model != end_participant_model)
{
- LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
+ LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>((*current_participant_model).get());
if (participant_model)
{
addConversationViewParticipant(participant_model);
@@ -775,27 +755,6 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part
LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
if (widget)
{
- LLFolderViewModelItem* item_vmi = widget->getViewModelItem();
- if (item_vmi && item_vmi->getNumRefs() == 1)
- {
- // This is the last pointer, remove participant from session
- // before participant gets deleted on destroyView.
- //
- // Floater (widget) and participant's view can simultaneously
- // co-own the model, in which case view is responsible for
- // the deletion and floater is free to clear and recreate
- // the list, yet there are cases where only widget owns
- // the pointer so it should do the cleanup.
- // See "add_participant".
- //
- // Todo: If it keeps causing issues turn participants
- // into LLPointers in the session
- LLParticipantList* session = getParticipantList();
- if (session)
- {
- session->removeChild(item_vmi);
- }
- }
widget->destroyView();
}
mConversationsWidgets.erase(participant_id);
@@ -861,7 +820,7 @@ void LLFloaterIMSessionTab::refreshConversation()
LLIMSpeakerMgr *speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
while (current_participant_model != end_participant_model)
{
- LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+ LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>((*current_participant_model).get());
if (speaker_mgr && participant_model)
{
LLSpeaker *participant_speaker = speaker_mgr->findSpeaker(participant_model->getUUID());
diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp
index 2496887c9d..81eab52e6c 100644
--- a/indra/newview/llfloatermediasettings.cpp
+++ b/indra/newview/llfloatermediasettings.cpp
@@ -180,8 +180,15 @@ void LLFloaterMediaSettings::onClose(bool app_quitting)
////////////////////////////////////////////////////////////////////////////////
//static
-void LLFloaterMediaSettings::initValues( const LLSD& media_settings, bool editable )
+void LLFloaterMediaSettings::initValues( const LLSD& media_settings, bool editable, bool has_media_info, bool multiple_media, bool multiple_valid_media)
{
+ if (!sInstance)
+ {
+ return;
+ }
+ sInstance->mIdenticalHasMediaInfo = has_media_info;
+ sInstance->mMultipleMedia = multiple_media;
+ sInstance->mMultipleValidMedia = multiple_valid_media;
if (sInstance->hasFocus()) return;
// Clear values
diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h
index 38730ddc98..7ed7ab246f 100644
--- a/indra/newview/llfloatermediasettings.h
+++ b/indra/newview/llfloatermediasettings.h
@@ -48,7 +48,7 @@ public:
static LLFloaterMediaSettings* getInstance();
static bool instanceExists();
static void apply();
- static void initValues( const LLSD& media_settings , bool editable);
+ static void initValues( const LLSD& media_settings , bool editable, bool has_media_info, bool multiple_media, bool multiple_valid_media);
static void clearValues( bool editable);
LLPanelMediaSettingsSecurity* getPanelSecurity(){return mPanelMediaSettingsSecurity;};
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 234885eba7..6a6766fb3f 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -165,7 +165,7 @@ bool LLFloaterModelPreview::postBuild()
for (S32 lod = 0; lod <= LLModel::LOD_HIGH; ++lod)
{
LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[lod]);
- lod_source_combo->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLoDSourceCommit, this, lod, true));
+ lod_source_combo->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLoDSourceCommit, this, lod));
lod_source_combo->setCurrentByIndex(mLODMode[lod]);
getChild<LLButton>("lod_browse_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onBrowseLOD, this, lod));
@@ -766,7 +766,7 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[i]);
if (lod_source_combo->getCurrentIndex() == LLModelPreview::USE_LOD_ABOVE)
{
- onLoDSourceCommit(i, false);
+ onLoDSourceCommit(i);
}
else
{
@@ -1760,7 +1760,7 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
}
}
-void LLFloaterModelPreview::onLoDSourceCommit(S32 lod, bool refresh_ui)
+void LLFloaterModelPreview::onLoDSourceCommit(S32 lod)
{
mModelPreview->updateLodControls(lod);
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index f8f2cd7812..7b652a3613 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -206,7 +206,7 @@ private:
void onClickCalculateBtn();
void onJointListSelection();
- void onLoDSourceCommit(S32 lod, bool refresh_ui);
+ void onLoDSourceCommit(S32 lod);
void modelUpdated(bool calculate_visible);
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 36a68a7017..dc5346634e 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -528,6 +528,10 @@ bool LLFloaterPreference::postBuild()
getChild<LLComboBox>("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true);
}
+#ifndef LL_DISCORD
+ getChild<LLTabContainer>("privacy_tab_container")->childDisable("privacy_preferences_discord");
+#endif
+
return true;
}
diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp
index 8cc01f6dc6..01108b5cfa 100644
--- a/indra/newview/llfloatersettingsdebug.cpp
+++ b/indra/newview/llfloatersettingsdebug.cpp
@@ -207,14 +207,14 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp)
mSettingNameText->setToolTip(controlp->getName());
mComment->setVisible(true);
- std::string old_text = mComment->getText();
std::string new_text = controlp->getComment();
// Don't setText if not nessesary, it will reset scroll
// This is a debug UI that reads from xml, there might
// be use cases where comment changes, but not the name
- if (old_text != new_text)
+ if (mOldText != new_text)
{
mComment->setText(controlp->getComment());
+ mOldText = new_text;
}
mValSpinner1->setMaxValue(F32_MAX);
@@ -467,6 +467,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp)
}
default:
mComment->setText(std::string("unknown"));
+ mOldText = "unknown";
break;
}
}
diff --git a/indra/newview/llfloatersettingsdebug.h b/indra/newview/llfloatersettingsdebug.h
index b813cf4a74..8781cd3b67 100644
--- a/indra/newview/llfloatersettingsdebug.h
+++ b/indra/newview/llfloatersettingsdebug.h
@@ -82,6 +82,7 @@ protected:
LLColorSwatchCtrl* mColorSwatch = nullptr;
std::string mSearchFilter;
+ std::string mOldText;
};
#endif //LLFLOATERDEBUGSETTINGS_H
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 6e6eaa3a20..03979edbc1 100755
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -169,6 +169,52 @@ public:
};
LLWorldMapHandler gWorldMapHandler;
+// handle secondlife:///app/worldmap_global/{GLOBAL_COORDS} URLs
+class LLWorldMapGlobalHandler : public LLCommandHandler
+{
+public:
+ LLWorldMapGlobalHandler() : LLCommandHandler("worldmap_global", UNTRUSTED_THROTTLE)
+ {}
+
+ virtual bool canHandleUntrusted(
+ const LLSD& params,
+ const LLSD& query_map,
+ LLMediaCtrl* web,
+ const std::string& nav_type)
+ {
+ if (nav_type == NAV_TYPE_CLICKED
+ || nav_type == NAV_TYPE_EXTERNAL)
+ {
+ // NAV_TYPE_EXTERNAL will be throttled
+ return true;
+ }
+
+ return false;
+ }
+
+ bool handle(const LLSD& params,
+ const LLSD& query_map,
+ const std::string& grid,
+ LLMediaCtrl* web)
+ {
+ if (params.size() < 3)
+ {
+ LL_WARNS() << "Correct global coordinates are not provided." << LL_ENDL;
+ return true;
+ }
+
+ LLVector3d parcel_global_pos = LLVector3d(params[0].asInteger(), params[1].asInteger(), params[2].asInteger());
+ LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
+ if (!parcel_global_pos.isExactlyZero() && worldmap_instance)
+ {
+ worldmap_instance->trackLocation(parcel_global_pos);
+ LLFloaterReg::showInstance("world_map", "center");
+ }
+ return true;
+ }
+};
+LLWorldMapGlobalHandler gWorldMapGlobalHandler;
+
// SocialMap handler secondlife:///app/maptrackavatar/id
class LLMapTrackAvatarHandler : public LLCommandHandler
{
diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index d0d2ee191a..776d2dd31e 100644
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/indra/newview/llhudeffectlookat.cpp
@@ -37,6 +37,7 @@
#include "lldrawable.h"
#include "llviewerobjectlist.h"
#include "llviewercontrol.h"
+#include "llvoavatarself.h"
#include "llrendersphere.h"
#include "llselectmgr.h"
#include "llglheaders.h"
@@ -397,6 +398,21 @@ bool LLHUDEffectLookAt::setLookAt(ELookAtType target_type, LLViewerObject *objec
return false;
}
+ static LLCachedControl<bool> enable_lookat_hints(gSavedSettings, "EnableLookAtTarget", true);
+ if (!enable_lookat_hints)
+ {
+ // Clear the effect so it doesn't linger around if it gets disabled
+ if (mTargetType != LOOKAT_TARGET_IDLE)
+ {
+ mTargetObject = gAgentAvatarp;
+ mTargetType = LOOKAT_TARGET_IDLE;
+ mTargetOffsetGlobal.set(2.f, 0.f, 0.f);
+ setDuration(3.f);
+ setNeedsSendToSim(true);
+ }
+ return false;
+ }
+
if (target_type >= LOOKAT_NUM_TARGETS)
{
LL_WARNS() << "Bad target_type " << (int)target_type << " - ignoring." << LL_ENDL;
@@ -409,6 +425,29 @@ bool LLHUDEffectLookAt::setLookAt(ELookAtType target_type, LLViewerObject *objec
return false;
}
+ static LLCachedControl<bool> limit_lookat_hints(gSavedSettings, "LimitLookAtTarget", true);
+ // Don't affect the look at if object is gAgentAvatarp (cursor head follow)
+ if (limit_lookat_hints && object != gAgentAvatarp)
+ {
+ // If it is a object
+ if (object)
+ {
+ position += object->getRenderPosition();
+ object = NULL;
+ }
+
+ LLVector3 agentHeadPosition = gAgentAvatarp->mHeadp->getWorldPosition();
+ float dist = (float)dist_vec(agentHeadPosition, position);
+
+ static LLCachedControl<F32> limit_lookat_hints_distance(gSavedSettings, "LimitLookAtTargetDistance", 2.0f);
+ if (dist > limit_lookat_hints_distance)
+ {
+ LLVector3 headOffset = position - agentHeadPosition;
+ headOffset *= limit_lookat_hints_distance / dist;
+ position.setVec(agentHeadPosition + headOffset);
+ }
+ }
+
F32 current_time = mTimer.getElapsedTimeF32();
// type of lookat behavior or target object has changed
diff --git a/indra/newview/llhudeffectpointat.cpp b/indra/newview/llhudeffectpointat.cpp
index eeb38cd6aa..c600010f6b 100644
--- a/indra/newview/llhudeffectpointat.cpp
+++ b/indra/newview/llhudeffectpointat.cpp
@@ -34,6 +34,7 @@
#include "llagent.h"
#include "llagentcamera.h"
#include "lldrawable.h"
+#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
#include "llvoavatar.h"
#include "message.h"
@@ -226,6 +227,19 @@ bool LLHUDEffectPointAt::setPointAt(EPointAtType target_type, LLViewerObject *ob
return false;
}
+ static LLCachedControl<bool> enable_selection_hints(gSavedSettings, "EnableSelectionHints", true);
+ if (!enable_selection_hints)
+ {
+ // Clear the effect so it doesn't linger around if it gets disabled
+ if (mTargetType != POINTAT_TARGET_NONE)
+ {
+ clearPointAtTarget();
+ setDuration(1.f);
+ setNeedsSendToSim(true);
+ }
+ return false;
+ }
+
if (target_type >= POINTAT_NUM_TARGETS)
{
LL_WARNS() << "Bad target_type " << (int)target_type << " - ignoring." << LL_ENDL;
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index 4c02511268..7cd0171a37 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -1520,10 +1520,10 @@ void LLIMProcessing::requestOfflineMessages()
if (!requested
&& gMessageSystem
&& !gDisconnected
- && LLMuteList::getInstance()->isLoaded()
&& isAgentAvatarValid()
&& gAgent.getRegion()
- && gAgent.getRegion()->capabilitiesReceived())
+ && gAgent.getRegion()->capabilitiesReceived()
+ && (LLMuteList::getInstance()->isLoaded() || LLMuteList::getInstance()->getLoadFailed()))
{
std::string cap_url = gAgent.getRegionCapability("ReadOfflineMsgs");
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index edefb5d109..359a009fef 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -4555,6 +4555,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
items.push_back(std::string("Rename"));
items.push_back(std::string("thumbnail"));
+ addInventoryFavoritesMenuOptions(items);
addDeleteContextMenuOptions(items, disabled_items);
// EXT-4030: disallow deletion of currently worn outfit
const LLViewerInventoryItem* base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink();
@@ -4572,6 +4573,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
EMyOutfitsSubfolderType in_my_outfits = myoutfit_object_subfolder_type(model, mUUID, outfits_id);
if (in_my_outfits != MY_OUTFITS_NO)
{
+ // Either an outfit or a subfolder inside MY_OUTFITS
if (in_my_outfits == MY_OUTFITS_SUBFOLDER)
{
// Not inside an outfit, but inside 'my outfits'
@@ -4581,6 +4583,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
items.push_back(std::string("Rename"));
items.push_back(std::string("thumbnail"));
+ addInventoryFavoritesMenuOptions(items);
addDeleteContextMenuOptions(items, disabled_items);
}
else
@@ -4629,14 +4632,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
if (model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT) == mUUID)
{
items.push_back(std::string("Copy outfit list to clipboard"));
- if (isFavorite())
- {
- items.push_back(std::string("Remove from Favorites"));
- }
- else
- {
- items.push_back(std::string("Add to Favorites"));
- }
+ addInventoryFavoritesMenuOptions(items);
addOpenFolderMenuOptions(flags, items);
}
@@ -4898,6 +4894,18 @@ void LLFolderBridge::addOpenFolderMenuOptions(U32 flags, menuentry_vec_t& items)
}
}
+void LLFolderBridge::addInventoryFavoritesMenuOptions(menuentry_vec_t& items)
+{
+ if (isFavorite())
+ {
+ items.push_back(std::string("Remove from Favorites"));
+ }
+ else
+ {
+ items.push_back(std::string("Add to Favorites"));
+ }
+}
+
bool LLFolderBridge::hasChildren() const
{
LLInventoryModel* model = getInventoryModel();
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index ea80b6959a..d96adbd1d2 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -345,6 +345,7 @@ protected:
void buildContextMenuOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items);
void buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items);
void addOpenFolderMenuOptions(U32 flags, menuentry_vec_t& items);
+ void addInventoryFavoritesMenuOptions(menuentry_vec_t& items); // Inventory favorites, not toolbar favorites
//--------------------------------------------------------------------
// Menu callbacks
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index a3e4f6a65d..d1fd82a7f1 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -3998,15 +3998,17 @@ void LLInventoryAction::buildMarketplaceFolders(LLFolderView* root)
for (; set_iter != selected_items.end(); ++set_iter)
{
viewModel = dynamic_cast<LLFolderViewModelItemInventory *>((*set_iter)->getViewModelItem());
- if (!viewModel || !viewModel->getInventoryObject()) continue;
- if (gInventory.isObjectDescendentOf(viewModel->getInventoryObject()->getParentUUID(), marketplacelistings_id))
+ if (!viewModel) continue;
+ LLInventoryObject* inv_obj = viewModel->getInventoryObject();
+ if (!inv_obj) continue;
+ if (gInventory.isObjectDescendentOf(inv_obj->getParentUUID(), marketplacelistings_id))
{
- const LLUUID &parent_id = viewModel->getInventoryObject()->getParentUUID();
+ const LLUUID &parent_id = inv_obj->getParentUUID();
if (parent_id != marketplacelistings_id)
{
sMarketplaceFolders.push_back(parent_id);
}
- const LLUUID &curr_id = viewModel->getInventoryObject()->getUUID();
+ const LLUUID &curr_id = inv_obj->getUUID();
if (curr_id != marketplacelistings_id)
{
sMarketplaceFolders.push_back(curr_id);
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index d419f67d47..943f41b6a7 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -78,7 +78,7 @@
// Increment this if the inventory contents change in a non-backwards-compatible way.
// For viewer 2, the addition of link items makes a pre-viewer-2 cache incorrect.
-const S32 LLInventoryModel::sCurrentInvCacheVersion = 4;
+const S32 LLInventoryModel::sCurrentInvCacheVersion = 5;
bool LLInventoryModel::sFirstTimeInViewer2 = true;
S32 LLInventoryModel::sPendingSystemFolders = 0;
@@ -3384,7 +3384,7 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
}
LL_INFOS(LOG_INV) << "loading inventory from: (" << filename << ")" << LL_ENDL;
- llifstream file(filename.c_str());
+ llifstream file(filename.c_str(), std::ifstream::in | std::ifstream::binary);
if (!file.is_open())
{
@@ -3393,80 +3393,92 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
}
is_cache_obsolete = true; // Obsolete until proven current
-
- //U64 lines_count = 0U;
- std::string line;
- LLPointer<LLSDParser> parser = new LLSDNotationParser();
- while (std::getline(file, line))
+ U32 value_nbo = 0;
+ file.read((char*)&value_nbo, sizeof(U32));
+ if (file.fail())
+ {
+ LL_WARNS(LOG_INV) << "Failed to read cache version. Unable to load inventory from: " << filename << LL_ENDL;
+ }
+ else
{
- LLSD s_item;
- std::istringstream iss(line);
- if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
+ S32 version = (S32)ntohl(value_nbo);
+ if (version == sCurrentInvCacheVersion)
{
- LL_WARNS(LOG_INV)<< "Parsing inventory cache failed" << LL_ENDL;
- break;
+ // Cache is up to date
+ is_cache_obsolete = false;
}
-
- if (s_item.has("inv_cache_version"))
+ else
{
- S32 version = s_item["inv_cache_version"].asInteger();
- if (version == sCurrentInvCacheVersion)
- {
- // Cache is up to date
- is_cache_obsolete = false;
- continue;
- }
- else
- {
- LL_WARNS(LOG_INV)<< "Inventory cache is out of date" << LL_ENDL;
- break;
- }
+ LL_WARNS(LOG_INV) << "Inventory cache is out of date" << LL_ENDL;
}
- else if (s_item.has("cat_id"))
+ }
+
+ LLSD inventory;
+ if (!is_cache_obsolete)
+ {
+ LLPointer<LLSDParser> parser = new LLSDBinaryParser();
+
+ if (parser->parse(file, inventory, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE)
{
- if (is_cache_obsolete)
- break;
+ is_cache_obsolete = true;
+ LL_WARNS(LOG_INV) << "Parsing inventory cache failed" << LL_ENDL;
+ }
+ }
- LLPointer<LLViewerInventoryCategory> inv_cat = new LLViewerInventoryCategory(LLUUID::null);
- if(inv_cat->importLLSD(s_item))
+ if (!is_cache_obsolete)
+ {
+ const LLSD& llsd_cats = inventory["categories"];
+ if (llsd_cats.isArray())
+ {
+ LLSD::array_const_iterator iter = llsd_cats.beginArray();
+ LLSD::array_const_iterator end = llsd_cats.endArray();
+ for (; iter != end; ++iter)
{
- categories.push_back(inv_cat);
+ LLPointer<LLViewerInventoryCategory> inv_cat = new LLViewerInventoryCategory(LLUUID::null);
+ if (inv_cat->importLLSDMap(*iter))
+ {
+ categories.push_back(inv_cat);
+ }
}
}
- else if (s_item.has("item_id"))
- {
- if (is_cache_obsolete)
- break;
- LLPointer<LLViewerInventoryItem> inv_item = new LLViewerInventoryItem;
- if( inv_item->fromLLSD(s_item) )
+ const LLSD& llsd_items = inventory["items"];
+ if (llsd_items.isArray())
+ {
+ LLSD::array_const_iterator iter = llsd_items.beginArray();
+ LLSD::array_const_iterator end = llsd_items.endArray();
+ for (; iter != end; ++iter)
{
- if(inv_item->getUUID().isNull())
- {
- LL_DEBUGS(LOG_INV) << "Ignoring inventory with null item id: "
- << inv_item->getName() << LL_ENDL;
- }
- else
+ LLPointer<LLViewerInventoryItem> inv_item = new LLViewerInventoryItem;
+ if (inv_item->fromLLSD(*iter))
{
- if (inv_item->getType() == LLAssetType::AT_UNKNOWN)
+ if (inv_item->getUUID().isNull())
{
- cats_to_update.insert(inv_item->getParentUUID());
+ LL_DEBUGS(LOG_INV) << "Ignoring inventory with null item id: "
+ << inv_item->getName() << LL_ENDL;
}
else
{
- items.push_back(inv_item);
+ if (inv_item->getType() == LLAssetType::AT_UNKNOWN)
+ {
+ cats_to_update.insert(inv_item->getParentUUID());
+ }
+ else
+ {
+ items.push_back(inv_item);
+ }
}
}
+
+ // TODO(brad) - figure out how to reenable this without breaking everything else
+ // static constexpr U64 BATCH_SIZE = 512U;
+ // if ((++lines_count % BATCH_SIZE) == 0)
+ // {
+ // // SL-19968 - make sure message system code gets a chance to run every so often
+ // pump_idle_startup_network();
+ // }
}
}
-
-// TODO(brad) - figure out how to reenable this without breaking everything else
-// static constexpr U64 BATCH_SIZE = 512U;
-// if ((++lines_count % BATCH_SIZE) == 0)
-// {
-// // SL-19968 - make sure message system code gets a chance to run every so often
-// pump_idle_startup_network();
-// }
}
file.close();
@@ -3489,58 +3501,54 @@ bool LLInventoryModel::saveToFile(const std::string& filename,
try
{
- llofstream fileXML(filename.c_str());
- if (!fileXML.is_open())
+ llofstream fileSD(filename.c_str(), std::ios_base::out | std::ios_base::binary);
+ if (!fileSD.is_open())
{
LL_WARNS(LOG_INV) << "Failed to open file. Unable to save inventory to: " << filename << LL_ENDL;
return false;
}
-
- LLSD cache_ver;
- cache_ver["inv_cache_version"] = sCurrentInvCacheVersion;
-
- if (fileXML.fail())
+ U32 value_nbo = htonl(sCurrentInvCacheVersion);
+ fileSD.write((const char*)(&value_nbo), sizeof(U32));
+ if (fileSD.fail())
{
- LL_WARNS(LOG_INV) << "Failed to write cache version to file. Unable to save inventory to: " << filename << LL_ENDL;
+ LL_WARNS(LOG_INV) << "Failed to write cache. Unable to save inventory to: " << filename << LL_ENDL;
return false;
}
- fileXML << LLSDOStreamer<LLSDNotationFormatter>(cache_ver) << std::endl;
+ LLSD inventory;
+ inventory["categories"] = LLSD::emptyArray();
+ LLSD& cat_array = inventory["categories"];
S32 cat_count = 0;
for (auto& cat : categories)
{
if (cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN)
{
- LLSD sd = LLSD::emptyMap();
+ LLSD sd;
cat->exportLLSD(sd);
- fileXML << LLSDOStreamer<LLSDNotationFormatter>(sd) << std::endl;
+ cat_array.append(sd);
cat_count++;
}
-
- if (fileXML.fail())
- {
- LL_WARNS(LOG_INV) << "Failed to write a folder to file. Unable to save inventory to: " << filename << LL_ENDL;
- return false;
- }
}
+ inventory["items"] = LLSD::emptyArray();
+ LLSD& item_array = inventory["items"];
auto it_count = items.size();
for (auto& item : items)
{
- LLSD sd = LLSD::emptyMap();
+ LLSD sd;
item->asLLSD(sd);
- fileXML << LLSDOStreamer<LLSDNotationFormatter>(sd) << std::endl;
-
- if (fileXML.fail())
- {
- LL_WARNS(LOG_INV) << "Failed to write an item to file. Unable to save inventory to: " << filename << LL_ENDL;
- return false;
- }
+ item_array.append(sd);
+ }
+ fileSD << LLSDOStreamer<LLSDBinaryFormatter>(inventory) << std::endl;
+ if (fileSD.fail())
+ {
+ LL_WARNS(LOG_INV) << "Failed to write cache. Unable to save inventory to: " << filename << LL_ENDL;
+ return false;
}
- fileXML.flush();
+ fileSD.flush();
- fileXML.close();
+ fileSD.close();
LL_INFOS(LOG_INV) << "Inventory saved: " << (S32)cat_count << " categories, " << (S32)it_count << " items." << LL_ENDL;
}
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index e86599035e..9034678782 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -32,6 +32,8 @@
#include "lllogchat.h"
#include "llregex.h"
#include "lltrans.h"
+#include "llurlaction.h"
+#include "llurlentry.h"
#include "llviewercontrol.h"
#include "lldiriterator.h"
@@ -360,13 +362,29 @@ void LLLogChat::saveHistory(const std::string& filename,
return;
}
+ std::string altered_line = line;
+
+ // avoid costly regex calls
+ if (line.find("/mention") != std::string::npos)
+ {
+ static const boost::regex mention_regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/mention", boost::regex::perl | boost::regex::icase);
+
+ // replace mention URL with [@username](URL)
+ altered_line = boost::regex_replace(line, mention_regex, [](const boost::smatch& match) -> std::string
+ {
+ std::string url = match[0].str();
+ std::string username = LLUrlAction::getURLLabel(url);
+ return "[" + username + "](" + url + ")";
+ });
+ }
+
LLSD item;
if (gSavedPerAccountSettings.getBOOL("LogTimestamp"))
item["time"] = LLLogChat::timestamp2LogString(0, gSavedPerAccountSettings.getBOOL("LogTimestampDate"));
item["from_id"] = from_id;
- item["message"] = line;
+ item["message"] = altered_line;
//adding "Second Life:" for all system messages to make chat log history parsing more reliable
if (from.empty() && from_id.isNull())
@@ -472,6 +490,19 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
std::string line(remove_utf8_bom(buffer));
+
+ // fast heuristic test for a mention URL in a string
+ // this is used to avoid costly regex calls
+ if (line.find("/mention)") != std::string::npos)
+ {
+ // restore original mention URL from [@username](URL) format
+ static const boost::regex altered_mention_regex("\\[@([^\\]]+)\\]\\((" APP_HEADER_REGEX "/agent/[\\da-f-]+/mention)\\)",
+ boost::regex::perl | boost::regex::icase);
+
+ // $2 captures the URL part
+ line = boost::regex_replace(line, altered_mention_regex, "$2");
+ }
+
//updated 1.23 plain text log format requires a space added before subsequent lines in a multilined message
if (' ' == line[0])
{
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 57acf51e26..07d68fc3ec 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -2380,7 +2380,13 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p
LLPointer<LLVolume> volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod));
if (volume->unpackVolumeFaces(data, data_size))
{
- if (volume->getNumFaces() > 0)
+ // Use LLVolume::getNumVolumeFaces() here and not LLVolume::getNumFaces(),
+ // because setMeshAssetLoaded() has not yet been called for this volume
+ // (it is set later in LLMeshRepository::notifyMeshLoaded()), and
+ // getNumFaces() would return the number of faces in the LLProfile
+ // instead. HB
+ S32 num_faces = volume->getNumVolumeFaces();
+ if (num_faces > 0)
{
// if we have a valid SkinInfo, cache per-joint bounding boxes for this LOD
LLPointer<LLMeshSkinInfo> skin_info = nullptr;
@@ -2394,7 +2400,7 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p
}
if (skin_info.notNull() && isAgentAvatarValid())
{
- for (S32 i = 0; i < volume->getNumFaces(); ++i)
+ for (S32 i = 0; i < num_faces; ++i)
{
// NOTE: no need to lock gAgentAvatarp as the state being checked is not changed after initialization
LLVolumeFace& face = volume->getVolumeFace(i);
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 2d51acc063..f6d635f51f 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -154,7 +154,8 @@ std::string LLMute::getDisplayType() const
// LLMuteList()
//-----------------------------------------------------------------------------
LLMuteList::LLMuteList() :
- mIsLoaded(false)
+ mLoadState(ML_INITIAL),
+ mRequestStartTime(0.f)
{
gGenericDispatcher.addHandler("emptymutelist", &sDispatchEmptyMuteList);
@@ -209,6 +210,23 @@ bool LLMuteList::isLinden(const std::string& name)
return last_name == "linden";
}
+bool LLMuteList::getLoadFailed() const
+{
+ if (mLoadState == ML_FAILED)
+ {
+ return true;
+ }
+ if (mLoadState == ML_REQUESTED)
+ {
+ constexpr F64 WAIT_SECONDS = 30;
+ if (mRequestStartTime + WAIT_SECONDS < LLTimer::getTotalSeconds())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
static LLVOAvatar* find_avatar(const LLUUID& id)
{
LLViewerObject *obj = gObjectList.findObject(id);
@@ -371,11 +389,14 @@ void LLMuteList::updateAdd(const LLMute& mute)
msg->addU32("MuteFlags", mute.mFlags);
gAgent.sendReliableMessage();
- if (!mIsLoaded)
+ if (!isLoaded())
{
LL_WARNS() << "Added elements to non-initialized block list" << LL_ENDL;
}
- mIsLoaded = true; // why is this here? -MG
+ // Based of logs and testing, if file doesn't exist server side,
+ // viewer will not receive any callback and won't know to set
+ // ML_LOADED. As a workaround, set it regardless of current state.
+ mLoadState = ML_LOADED;
}
@@ -564,6 +585,7 @@ bool LLMuteList::loadFromFile(const std::string& filename)
if(!filename.size())
{
LL_WARNS() << "Mute List Filename is Empty!" << LL_ENDL;
+ mLoadState = ML_FAILED;
return false;
}
@@ -571,6 +593,7 @@ bool LLMuteList::loadFromFile(const std::string& filename)
if (!fp)
{
LL_WARNS() << "Couldn't open mute list " << filename << LL_ENDL;
+ mLoadState = ML_FAILED;
return false;
}
@@ -730,13 +753,17 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id)
if (gDisconnected)
{
LL_WARNS() << "Trying to request mute list when disconnected!" << LL_ENDL;
+ mLoadState = ML_FAILED;
return;
}
if (!gAgent.getRegion())
{
LL_WARNS() << "No region for agent yet, skipping mute list request!" << LL_ENDL;
+ mLoadState = ML_FAILED;
return;
}
+ mLoadState = ML_REQUESTED;
+ mRequestStartTime = LLTimer::getElapsedSeconds();
// Double amount of retries due to this request happening during busy stage
// Ideally this should be turned into a capability
gMessageSystem->sendReliable(gAgent.getRegionHost(), LL_DEFAULT_RELIABLE_RETRIES * 2, true, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL);
@@ -749,7 +776,7 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id)
void LLMuteList::cache(const LLUUID& agent_id)
{
// Write to disk even if empty.
- if(mIsLoaded)
+ if(isLoaded())
{
std::string agent_id_string;
std::string filename;
@@ -777,6 +804,13 @@ void LLMuteList::processMuteListUpdate(LLMessageSystem* msg, void**)
msg->getStringFast(_PREHASH_MuteData, _PREHASH_Filename, unclean_filename);
std::string filename = LLDir::getScrubbedFileName(unclean_filename);
+ LLMuteList* mute_list = getInstance();
+ mute_list->mLoadState = ML_REQUESTED;
+ mute_list->mRequestStartTime = LLTimer::getElapsedSeconds();
+
+ // Todo: Based of logs and testing, there is no callback
+ // from server if file doesn't exist server side.
+ // Once server side gets fixed make sure it gets handled right.
std::string *local_filename_and_path = new std::string(gDirUtilp->getExpandedFilename( LL_PATH_CACHE, filename ));
gXferManager->requestFile(*local_filename_and_path,
filename,
@@ -809,12 +843,16 @@ void LLMuteList::onFileMuteList(void** user_data, S32 error_code, LLExtStat ext_
LLMuteList::getInstance()->loadFromFile(*local_filename_and_path);
LLFile::remove(*local_filename_and_path);
}
+ else
+ {
+ LLMuteList::getInstance()->mLoadState = ML_FAILED;
+ }
delete local_filename_and_path;
}
void LLMuteList::onAccountNameChanged(const LLUUID& id, const std::string& username)
{
- if (mIsLoaded)
+ if (isLoaded())
{
LLMute mute(id, username, LLMute::AGENT);
mute_set_t::iterator mute_it = mMutes.find(mute);
@@ -866,7 +904,7 @@ void LLMuteList::removeObserver(LLMuteListObserver* observer)
void LLMuteList::setLoaded()
{
- mIsLoaded = true;
+ mLoadState = ML_LOADED;
notifyObservers();
}
diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h
index 13d579c61f..b65fd61fcc 100644
--- a/indra/newview/llmutelist.h
+++ b/indra/newview/llmutelist.h
@@ -74,6 +74,14 @@ class LLMuteList : public LLSingleton<LLMuteList>
LLSINGLETON(LLMuteList);
~LLMuteList();
/*virtual*/ void cleanupSingleton() override;
+
+ enum EMuteListState
+ {
+ ML_INITIAL,
+ ML_REQUESTED,
+ ML_LOADED,
+ ML_FAILED,
+ };
public:
// reasons for auto-unmuting a resident
enum EAutoReason
@@ -107,7 +115,8 @@ public:
static bool isLinden(const std::string& name);
- bool isLoaded() const { return mIsLoaded; }
+ bool isLoaded() const { return mLoadState == ML_LOADED; }
+ bool getLoadFailed() const;
std::vector<LLMute> getMutes() const;
@@ -167,7 +176,8 @@ private:
typedef std::set<LLMuteListObserver*> observer_set_t;
observer_set_t mObservers;
- bool mIsLoaded;
+ EMuteListState mLoadState;
+ F64 mRequestStartTime;
friend class LLDispatchEmptyMuteList;
};
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 2b2b5ea696..cb2a6191fa 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -34,11 +34,13 @@
#include "llaccordionctrl.h"
#include "llaccordionctrltab.h"
#include "llagentwearables.h"
+#include "llaisapi.h"
#include "llappearancemgr.h"
#include "llappviewer.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
#include "llinspecttexture.h"
+#include "llinventorymodelbackgroundfetch.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "llmenubutton.h"
@@ -247,12 +249,22 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id)
list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3));
- // Fetch the new outfit contents.
- cat->fetch();
-
- // Refresh the list of outfit items after fetch().
- // Further list updates will be triggered by the category observer.
- list->updateList(cat_id);
+ if (AISAPI::isAvailable() && LLInventoryModelBackgroundFetch::instance().folderFetchActive())
+ {
+ // for reliability just fetch it whole, linked items included
+ LLInventoryModelBackgroundFetch::instance().fetchFolderAndLinks(cat_id, [cat_id, list]
+ {
+ if (list) list->updateList(cat_id);
+ });
+ }
+ else
+ {
+ // Fetch the new outfit contents.
+ cat->fetch();
+ // Refresh the list of outfit items after fetch().
+ // Further list updates will be triggered by the category observer.
+ list->updateList(cat_id);
+ }
// If filter is currently applied we store the initial tab state.
if (!getFilterSubString().empty())
diff --git a/indra/newview/llpanelemojicomplete.cpp b/indra/newview/llpanelemojicomplete.cpp
index 3a6a6a5ec3..f0555408dd 100644
--- a/indra/newview/llpanelemojicomplete.cpp
+++ b/indra/newview/llpanelemojicomplete.cpp
@@ -463,6 +463,7 @@ void LLPanelEmojiComplete::updateConstraints()
{
mEmojiHeight = mRenderRect.getHeight();
mRenderRect.stretch((mRenderRect.getWidth() - static_cast<S32>(mVisibleEmojis) * mEmojiWidth) / -2, 0);
+ mRenderRect.translate(-mRenderRect.mLeft, 0); // Left align emojis to fix hitboxes
}
updateScrollPos();
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 4909c11bae..514d772340 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -2205,7 +2205,7 @@ void LLPanelFace::refreshMedia()
// check if all faces have media(or, all dont have media)
- LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue(&func, bool_has_media);
+ bool identical_has_media_info = selected_objects->getSelectedTEValue(&func, bool_has_media);
const LLMediaEntry default_media_data;
@@ -2227,7 +2227,8 @@ void LLPanelFace::refreshMedia()
} func_media_data(default_media_data);
LLMediaEntry media_data_get;
- LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue(&func_media_data, media_data_get));
+ bool multiple_media = !(selected_objects->getSelectedTEValue(&func_media_data, media_data_get));
+ bool multiple_valid_media = false;
std::string multi_media_info_str = LLTrans::getString("Multiple Media");
std::string media_title = "";
@@ -2236,12 +2237,12 @@ void LLPanelFace::refreshMedia()
mAddMedia->setEnabled(editable);
// IF all the faces have media (or all dont have media)
- if (LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo)
+ if (identical_has_media_info)
{
// TODO: get media title and set it.
mTitleMediaText->clear();
// if identical is set, all faces are same (whether all empty or has the same media)
- if (!(LLFloaterMediaSettings::getInstance()->mMultipleMedia))
+ if (!multiple_media)
{
// Media data is valid
if (media_data_get != default_media_data)
@@ -2262,9 +2263,9 @@ void LLPanelFace::refreshMedia()
else // not all face has media but at least one does.
{
// seleted faces have not identical value
- LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data);
+ multiple_valid_media = selected_objects->isMultipleTEValue(&func_media_data, default_media_data);
- if (LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)
+ if (multiple_valid_media)
{
media_title = multi_media_info_str;
}
@@ -2301,7 +2302,7 @@ void LLPanelFace::refreshMedia()
// load values for media settings
updateMediaSettings();
- LLFloaterMediaSettings::initValues(mMediaSettings, editable);
+ LLFloaterMediaSettings::initValues(mMediaSettings, editable, identical_has_media_info, multiple_media, multiple_valid_media);
}
void LLPanelFace::unloadMedia()
@@ -3374,6 +3375,7 @@ void LLPanelFace::onSelectNormalTexture(const LLSD& data)
// TODO: test if there is media on the item and only allow editing if present
void LLPanelFace::onClickBtnEditMedia()
{
+ LLFloaterMediaSettings::getInstance(); // make sure floater we are about to open exists before refreshMedia
refreshMedia();
LLFloaterReg::showInstance("media_settings");
}
@@ -3392,6 +3394,7 @@ void LLPanelFace::onClickBtnAddMedia()
// check if multiple faces are selected
if (LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
{
+ LLFloaterMediaSettings::getInstance(); // make sure floater we are about to open exists before refreshMedia
refreshMedia();
LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm);
}
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index ed80c8b732..59aa375457 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -184,7 +184,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
mCallback(callback),
mCallbackData(cb_data),
mListener(new LLPanelLoginListener(this)),
- mFirstLoginThisInstall(gSavedSettings.getBOOL("FirstLoginThisInstall")),
mUsernameLength(0),
mPasswordLength(0),
mLocationLength(0),
@@ -203,14 +202,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
login_holder->addChild(this);
}
- if (mFirstLoginThisInstall)
- {
- buildFromFile( "panel_login_first.xml");
- }
- else
- {
- buildFromFile( "panel_login.xml");
- }
+ buildFromFile("panel_login.xml");
reshape(rect.getWidth(), rect.getHeight());
@@ -224,38 +216,36 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
sendChildToBack(getChildView("sign_up_text"));
std::string current_grid = LLGridManager::getInstance()->getGrid();
- if (!mFirstLoginThisInstall)
- {
- LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo");
- updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
- favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, false));
- favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this));
- LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo");
- server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this));
+ LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo");
+ updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
+ favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, false));
+ favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this));
+
+ LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo");
+ server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this));
- // Load all of the grids, sorted, and then add a bar and the current grid at the top
- server_choice_combo->removeall();
+ // Load all of the grids, sorted, and then add a bar and the current grid at the top
+ server_choice_combo->removeall();
- std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
- for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin();
- grid_choice != known_grids.end();
- grid_choice++)
+ std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
+ for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin();
+ grid_choice != known_grids.end();
+ grid_choice++)
+ {
+ if (!grid_choice->first.empty() && current_grid != grid_choice->first)
{
- if (!grid_choice->first.empty() && current_grid != grid_choice->first)
- {
- LL_DEBUGS("AppInit") << "adding " << grid_choice->first << LL_ENDL;
- server_choice_combo->add(grid_choice->second, grid_choice->first);
- }
+ LL_DEBUGS("AppInit") << "adding " << grid_choice->first << LL_ENDL;
+ server_choice_combo->add(grid_choice->second, grid_choice->first);
}
- server_choice_combo->sortByName();
-
- LL_DEBUGS("AppInit") << "adding current " << current_grid << LL_ENDL;
- server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
- current_grid,
- ADD_TOP);
- server_choice_combo->selectFirstItem();
}
+ server_choice_combo->sortByName();
+
+ LL_DEBUGS("AppInit") << "adding current " << current_grid << LL_ENDL;
+ server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
+ current_grid,
+ ADD_TOP);
+ server_choice_combo->selectFirstItem();
LLSLURL start_slurl(LLStartUp::getStartSLURL());
// The StartSLURL might have been set either by an explicit command-line
@@ -331,15 +321,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
void LLPanelLogin::addFavoritesToStartLocation()
{
- if (mFirstLoginThisInstall)
- {
- // first login panel has no favorites, just update name length and buttons
- std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple();
- mUsernameLength = static_cast<unsigned int>(user_defined_name.length());
- updateLoginButtons();
- return;
- }
-
// Clear the combo.
LLComboBox* combo = getChild<LLComboBox>("start_location_combo");
if (!combo) return;
@@ -559,16 +540,9 @@ void LLPanelLogin::resetFields()
// function is used to reset list in case of changes by external sources
return;
}
- if (sInstance->mFirstLoginThisInstall)
- {
- // no list to populate
- LL_WARNS() << "Shouldn't happen, user should have no ability to modify list on first install" << LL_ENDL;
- }
- else
- {
- LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
- sInstance->populateUserList(cred);
- }
+
+ LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
+ sInstance->populateUserList(cred);
}
// static
@@ -586,7 +560,6 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential)
if(identifier.has("type") && (std::string)identifier["type"] == "agent")
{
- // not nessesary for panel_login.xml, needed for panel_login_first.xml
std::string firstname = identifier["first_name"].asString();
std::string lastname = identifier["last_name"].asString();
std::string login_id = firstname;
@@ -1081,8 +1054,7 @@ void LLPanelLogin::onRememberUserCheck(void*)
LLComboBox* user_combo(sInstance->getChild<LLComboBox>("username_combo"));
bool remember = remember_name->getValue().asBoolean();
- if (!sInstance->mFirstLoginThisInstall
- && user_combo->getCurrentIndex() != -1
+ if (user_combo->getCurrentIndex() != -1
&& !remember)
{
remember = true;
@@ -1197,17 +1169,14 @@ void LLPanelLogin::updateLoginButtons()
login_btn->setEnabled(mUsernameLength != 0 && mPasswordLength != 0);
- if (!mFirstLoginThisInstall)
+ LLComboBox* user_combo = getChild<LLComboBox>("username_combo");
+ LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name");
+ if (user_combo->getCurrentIndex() != -1)
{
- LLComboBox* user_combo = getChild<LLComboBox>("username_combo");
- LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name");
- if (user_combo->getCurrentIndex() != -1)
- {
- remember_name->setValue(true);
- LLCheckBoxCtrl* remember_pass = getChild<LLCheckBoxCtrl>("remember_password");
- remember_pass->setEnabled(true);
- } // Note: might be good idea to do "else remember_name->setValue(mRememberedState)" but it might behave 'weird' to user
- }
+ remember_name->setValue(true);
+ LLCheckBoxCtrl* remember_pass = getChild<LLCheckBoxCtrl>("remember_password");
+ remember_pass->setEnabled(true);
+ } // Note: might be good idea to do "else remember_name->setValue(mRememberedState)" but it might behave 'weird' to user
}
void LLPanelLogin::populateUserList(LLPointer<LLCredential> credential)
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index a1bf25fb05..1259bf26d6 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -119,7 +119,6 @@ private:
static LLPanelLogin* sInstance;
static bool sCapslockDidNotification;
- bool mFirstLoginThisInstall;
static bool sCredentialSet;
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 01541968de..42c40fe404 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -846,7 +846,7 @@ void LLPanelPeople::updateNearbyList()
mNearbyList->setDirty();
#ifdef LL_DISCORD
if (gSavedSettings.getBOOL("EnableDiscord"))
- LLAppViewer::updateDiscordPartyMaxSize(mNearbyList->getIDs().size());
+ LLAppViewer::updateDiscordPartyMaxSize((S32)mNearbyList->getIDs().size());
#endif
DISTANCE_COMPARATOR.updateAvatarsPositions(positions, mNearbyList->getIDs());
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index 6966cb38ab..794ae4ad44 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -155,11 +155,15 @@ void PeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
bool PeopleContextMenu::enableContextMenuItem(const LLSD& userdata)
{
+ std::string item = userdata.asString();
if(gAgent.getID() == mUUIDs.front())
{
+ if (item == std::string("can_zoom_in"))
+ {
+ return true;
+ }
return false;
}
- std::string item = userdata.asString();
// Note: can_block and can_delete is used only for one person selected menu
// so we don't need to go over all uuids.
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 1948bba4be..00c219fdda 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -2249,6 +2249,7 @@ void LLSelectMgr::selectionRevertGLTFMaterials()
{
// Restore base material
LLUUID asset_id = nodep->mSavedGLTFMaterialIds[te];
+ LLUUID old_asset_id = objectp->getRenderMaterialID(te);
// Update material locally
objectp->setRenderMaterialID(te, asset_id, false /*wait for LLGLTFMaterialList update*/);
@@ -2259,18 +2260,29 @@ void LLSelectMgr::selectionRevertGLTFMaterials()
objectp->setTEGLTFMaterialOverride(te, material);
}
- // Enqueue update to server
- if (asset_id.notNull() && material)
+ if (asset_id.isNull() || !material)
+ {
+ //blank override out
+ LLGLTFMaterialList::queueApply(objectp, te, asset_id);
+ }
+ if (old_asset_id != asset_id)
{
// Restore overrides and base material
+ // Note: might not work reliably if asset is already there, might
+ // have a server sided problem where servers applies override
+ // first then resets it by adding asset, in which case need
+ // to create a server ticket and chain asset then override
+ // application.
LLGLTFMaterialList::queueApply(objectp, te, asset_id, material);
}
else
{
- //blank override out
- LLGLTFMaterialList::queueApply(objectp, te, asset_id);
+ // Enqueue override update to server
+ // Note: this is suboptimal, better to send asset id as well
+ // but there seems to be a server problem with queueApply
+ // that ignores override in some cases
+ LLGLTFMaterialList::queueModify(objectp, te, material);
}
-
}
return true;
}
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 12a9d5e9b7..b49c0119ed 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -1028,7 +1028,7 @@ void LLLocalSpeakerMgr::updateSpeakerList()
LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), CHAT_NORMAL_RADIUS);
#ifdef LL_DISCORD
if (gSavedSettings.getBOOL("EnableDiscord"))
- LLAppViewer::updateDiscordPartyCurrentSize(avatar_ids.size());
+ LLAppViewer::updateDiscordPartyCurrentSize((S32)avatar_ids.size());
#endif
for(U32 i=0; i<avatar_ids.size(); i++)
{
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index bda75c16e7..bf4ec14487 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -115,6 +115,8 @@ LLStatusBar::LLStatusBar(const LLRect& rect)
mBtnVolume(NULL),
mBoxBalance(NULL),
mBalance(0),
+ mBalanceClicked(false),
+ mObscureBalance(false),
mHealth(100),
mSquareMetersCredit(0),
mSquareMetersCommitted(0),
@@ -126,8 +128,6 @@ LLStatusBar::LLStatusBar(const LLRect& rect)
// status bar can possible overlay menus?
setMouseOpaque(false);
- mBalanceTimer = new LLFrameTimer();
- mHealthTimer = new LLFrameTimer();
mFpsUpdateTimer = new LLFrameTimer();
buildFromFile("panel_status_bar.xml");
@@ -135,12 +135,6 @@ LLStatusBar::LLStatusBar(const LLRect& rect)
LLStatusBar::~LLStatusBar()
{
- delete mBalanceTimer;
- mBalanceTimer = NULL;
-
- delete mHealthTimer;
- mHealthTimer = NULL;
-
// LLView destructor cleans up children
}
@@ -176,7 +170,8 @@ bool LLStatusBar::postBuild()
getChild<LLUICtrl>("goShop")->setCommitCallback(boost::bind(&LLWeb::loadURL, gSavedSettings.getString("MarketplaceURL"), LLStringUtil::null, LLStringUtil::null));
mBoxBalance = getChild<LLTextBox>("balance");
- mBoxBalance->setClickedCallback( &LLStatusBar::onClickBalance, this );
+ mBoxBalance->setClickedCallback(&LLStatusBar::onClickRefreshBalance, this);
+ mBoxBalance->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onClickToggleBalance(); });
mIconPresetsCamera = getChild<LLIconCtrl>( "presets_icon_camera" );
mIconPresetsCamera->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresetsCamera, this));
@@ -196,12 +191,14 @@ bool LLStatusBar::postBuild()
gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&LLStatusBar::onVolumeChanged, this, _2));
gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&LLStatusBar::onVoiceChanged, this, _2));
+ gSavedSettings.getControl("ObscureBalanceInStatusBar")->getSignal()->connect(boost::bind(&LLStatusBar::onObscureBalanceChanged, this, _2));
if (!gSavedSettings.getBOOL("EnableVoiceChat") && LLAppViewer::instance()->isSecondInstance())
{
// Indicate that second instance started without sound
mBtnVolume->setImageUnselected(LLUI::getUIImage("VoiceMute_Off"));
}
+ mObscureBalance = gSavedSettings.getBOOL("ObscureBalanceInStatusBar");
// Adding Net Stat Graph
S32 x = getRect().getWidth() - 2;
@@ -334,6 +331,12 @@ void LLStatusBar::refresh()
mTextTime->setToolTip (dtStr);
}
+ if (mBalanceClicked && mBalanceClickTimer.getElapsedTimeF32() > 1.f)
+ {
+ mBalanceClicked = false;
+ sendMoneyBalanceRequest();
+ }
+
LLRect r;
const S32 MENU_RIGHT = gMenuBarView->getRightmostMenuEdge();
@@ -399,9 +402,17 @@ void LLStatusBar::setBalance(S32 balance)
std::string money_str = LLResMgr::getInstance()->getMonetaryString( balance );
LLStringUtil::format_map_t string_args;
- string_args["[AMT]"] = llformat("%s", money_str.c_str());
+ if (mObscureBalance)
+ {
+ string_args["[AMT]"] = "****";
+ }
+ else
+ {
+ string_args["[AMT]"] = llformat("%s", money_str.c_str());
+ }
std::string label_str = getString("buycurrencylabel", string_args);
mBoxBalance->setValue(label_str);
+ mBoxBalance->setToolTipArg(LLStringExplicit("[AMT]"), llformat("%s", money_str.c_str()));
updateBalancePanelPosition();
@@ -421,8 +432,6 @@ void LLStatusBar::setBalance(S32 balance)
if( balance != mBalance )
{
- mBalanceTimer->reset();
- mBalanceTimer->setTimerExpirySec( ICON_TIMER_EXPIRY );
mBalance = balance;
}
}
@@ -474,9 +483,6 @@ void LLStatusBar::setHealth(S32 health)
}
}
}
-
- mHealthTimer->reset();
- mHealthTimer->setTimerExpirySec( ICON_TIMER_EXPIRY );
}
mHealth = health;
@@ -636,13 +642,27 @@ static void onClickVolume(void* data)
}
//static
-void LLStatusBar::onClickBalance(void* )
+void LLStatusBar::onClickRefreshBalance(void* data)
{
- // Force a balance request message:
- LLStatusBar::sendMoneyBalanceRequest();
+ LLStatusBar* status_bar = (LLStatusBar*)data;
+
+ if (!status_bar->mBalanceClicked)
+ {
+ // Schedule a balance request message:
+ status_bar->mBalanceClicked = true;
+ status_bar->mBalanceClickTimer.reset();
+ }
// The refresh of the display (call to setBalance()) will be done by process_money_balance_reply()
}
+void LLStatusBar::onClickToggleBalance()
+{
+ mObscureBalance = !mObscureBalance;
+ gSavedSettings.setBOOL("ObscureBalanceInStatusBar", mObscureBalance);
+ setBalance(mBalance);
+ mBalanceClicked = false; // supress click
+}
+
//static
void LLStatusBar::onClickMediaToggle(void* data)
{
@@ -678,6 +698,12 @@ void LLStatusBar::onVoiceChanged(const LLSD& newvalue)
refresh();
}
+void LLStatusBar::onObscureBalanceChanged(const LLSD& newvalue)
+{
+ mObscureBalance = newvalue.asBoolean();
+ setBalance(mBalance);
+}
+
void LLStatusBar::onUpdateFilterTerm()
{
LLWString searchValue = utf8str_to_wstring( mFilterEdit->getValue() );
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index 86c1ccd051..f1225a22f8 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -72,7 +72,8 @@ public:
void debitBalance(S32 debit);
void creditBalance(S32 credit);
- // Request the latest currency balance from the server
+ // Request the latest currency balance from the server.
+ // Reply at process_money_balance_reply()
static void sendMoneyBalanceRequest();
void setHealth(S32 percent);
@@ -102,6 +103,7 @@ private:
void onClickBuyCurrency();
void onVolumeChanged(const LLSD& newvalue);
void onVoiceChanged(const LLSD& newvalue);
+ void onObscureBalanceChanged(const LLSD& newvalue);
void onMouseEnterPresetsCamera();
void onMouseEnterPresets();
@@ -109,7 +111,8 @@ private:
void onMouseEnterNearbyMedia();
static void onClickMediaToggle(void* data);
- static void onClickBalance(void* data);
+ static void onClickRefreshBalance(void* data);
+ void onClickToggleBalance();
static void onClickFps(void* data);
@@ -139,11 +142,12 @@ private:
LLFrameTimer *mFpsUpdateTimer;
S32 mBalance;
+ bool mBalanceClicked;
+ bool mObscureBalance;
+ LLTimer mBalanceClickTimer;
S32 mHealth;
S32 mSquareMetersCredit;
S32 mSquareMetersCommitted;
- LLFrameTimer* mBalanceTimer;
- LLFrameTimer* mHealthTimer;
LLPanelPresetsCameraPulldown* mPanelPresetsCameraPulldown;
LLPanelPresetsPulldown* mPanelPresetsPulldown;
LLPanelVolumePulldown* mPanelVolumePulldown;
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 3665ff5e87..b4a5955be3 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1125,28 +1125,33 @@ void set_texture_to_material(LLViewerObject* hit_obj,
case LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR:
default:
{
- material->setBaseColorId(asset_id);
+ material->setBaseColorId(asset_id, true);
}
break;
case LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS:
{
- material->setOcclusionRoughnessMetallicId(asset_id);
+ material->setOcclusionRoughnessMetallicId(asset_id, true);
}
break;
case LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE:
{
- material->setEmissiveId(asset_id);
+ material->setEmissiveId(asset_id, true);
}
break;
case LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL:
{
- material->setNormalId(asset_id);
+ material->setNormalId(asset_id, true);
}
break;
}
+ // Update viewer side, needed for updating mSavedGLTFOverrideMaterials.
+ // Also for parity, we are immediately setting textures and materials,
+ // so we should immediate set overrides to.
+ hit_obj->setTEGLTFMaterialOverride(hit_face, material);
+ // update server
LLGLTFMaterialList::queueModify(hit_obj, hit_face, material);
}
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 5f61aeaf13..6155058f14 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -761,18 +761,23 @@ void LLViewerInventoryCategory::exportLLSD(LLSD & cat_data) const
cat_data[INV_VERSION] = mVersion;
}
-bool LLViewerInventoryCategory::importLLSD(const LLSD& cat_data)
+bool LLViewerInventoryCategory::importLLSD(const std::string& label, const LLSD& value)
{
- LLInventoryCategory::importLLSD(cat_data);
- if (cat_data.has(INV_OWNER_ID))
+ if (LLInventoryCategory::importLLSD(label, value))
{
- mOwnerID = cat_data[INV_OWNER_ID].asUUID();
+ return true;
}
- if (cat_data.has(INV_VERSION))
+ else if (label == INV_OWNER_ID)
{
- setVersion(cat_data[INV_VERSION].asInteger());
+ mOwnerID = value.asUUID();
+ return true;
}
- return true;
+ else if (label == INV_VERSION)
+ {
+ setVersion(value.asInteger());
+ return true;
+ }
+ return false;
}
bool LLViewerInventoryCategory::acceptItem(LLInventoryItem* inv_item)
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 5cd31353f8..0dfbf0cced 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -233,7 +233,7 @@ public:
S32 getViewerDescendentCount() const;
virtual void exportLLSD(LLSD &sd) const;
- virtual bool importLLSD(const LLSD& cat_data);
+ virtual bool importLLSD(const std::string& label, const LLSD& value);
void determineFolderType();
void changeType(LLFolderType::EType new_folder_type);
diff --git a/indra/newview/llviewermedia_streamingaudio.cpp b/indra/newview/llviewermedia_streamingaudio.cpp
index 21f5ba64d7..959de38364 100644
--- a/indra/newview/llviewermedia_streamingaudio.cpp
+++ b/indra/newview/llviewermedia_streamingaudio.cpp
@@ -61,13 +61,26 @@ void LLStreamingAudio_MediaPlugins::start(const std::string& url)
if(!mMediaPlugin)
return;
- if (!url.empty()) {
+ if (!url.empty())
+ {
LL_INFOS() << "Starting internet stream: " << url << LL_ENDL;
- mURL = url;
- mMediaPlugin->loadURI ( url );
+
+ mURL = url; // keep original url here for comparison purposes
+ std::string snt_url = url;
+ LLStringUtil::trim(snt_url);
+ size_t pos = snt_url.find(' ');
+ if (pos != std::string::npos)
+ {
+ // fmod permited having names after the url and people were using it.
+ // People label their streams this way, ignore the 'label'.
+ snt_url = snt_url.substr(0, pos);
+ }
+ mMediaPlugin->loadURI(snt_url);
mMediaPlugin->start();
LL_INFOS() << "Playing stream..." << LL_ENDL;
- } else {
+ }
+ else
+ {
LL_INFOS() << "setting stream to NULL"<< LL_ENDL;
mURL.clear();
mMediaPlugin->stop();
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index d9d20611b4..3695478061 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -69,6 +69,7 @@
#include "llviewerassetupload.h"
// linden libraries
+#include "llfilesystem.h"
#include "llnotificationsutil.h"
#include "llsdserialize.h"
#include "llsdutil.h"
@@ -550,16 +551,9 @@ void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k)
if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec))
{
bool resource_upload = false;
- if (asset_type == LLAssetType::AT_TEXTURE && allow_2k)
+ if (asset_type == LLAssetType::AT_TEXTURE)
{
- LLPointer<LLImageFormatted> image_frmted = LLImageFormatted::createFromType(codec);
- if (gDirUtilp->fileExists(filename) && image_frmted && image_frmted->load(filename))
- {
- S32 biased_width = LLImageRaw::biasedDimToPowerOfTwo(image_frmted->getWidth(), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
- S32 biased_height = LLImageRaw::biasedDimToPowerOfTwo(image_frmted->getHeight(), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
- expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(biased_width, biased_height);
- resource_upload = true;
- }
+ resource_upload = true;
}
else if (LLAgentBenefitsMgr::current().findUploadCost(asset_type, expected_upload_cost))
{
@@ -568,23 +562,115 @@ void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k)
if (resource_upload)
{
- LLNewFileResourceUploadInfo* info_p = 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);
-
- if (!allow_2k)
+ if (asset_type == LLAssetType::AT_TEXTURE)
{
- info_p->setMaxImageSize(1024);
- }
- LLResourceUploadInfo::ptr_t uploadInfo(info_p);
+ std::string exten = gDirUtilp->getExtension(filename);
+ U32 codec = LLImageBase::getCodecFromExtension(exten);
+
+ // Load the image
+ LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
+ if (image.isNull())
+ {
+ LL_WARNS() << "Failed to create image container for " << filename << LL_ENDL;
+ continue;
+ }
+ if (!image->load(filename))
+ {
+ LL_WARNS() << "Failed to load image: " << filename << LL_ENDL;
+ continue;
+ }
+ // Decompress or expand it in a raw image structure
+ LLPointer<LLImageRaw> raw_image = new LLImageRaw;
+ if (!image->decode(raw_image, 0.0f))
+ {
+ LL_WARNS() << "Failed to decode image: " << filename << LL_ENDL;
+ continue;
+ }
+ // Check the image constraints
+ if ((image->getComponents() != 3) && (image->getComponents() != 4))
+ {
+ LL_WARNS() << "Attempted to upload a texture that has " << image->getComponents()
+ << " components, but only 3 (RGB) or 4 (RGBA) are allowed." << LL_ENDL;
+ continue;
+ }
+ // Downscale images to fit the max_texture_dimensions_*, or 1024 if allow_2k is false
+ S32 max_width = allow_2k ? gSavedSettings.getS32("max_texture_dimension_X") : 1024;
+ S32 max_height = allow_2k ? gSavedSettings.getS32("max_texture_dimension_Y") : 1024;
+
+ S32 orig_width = raw_image->getWidth();
+ S32 orig_height = raw_image->getHeight();
+
+ if (orig_width > max_width || orig_height > max_height)
+ {
+ // Calculate scale factors
+ F32 width_scale = (F32)max_width / (F32)orig_width;
+ F32 height_scale = (F32)max_height / (F32)orig_height;
+ F32 scale = llmin(width_scale, height_scale);
+
+ // Calculate new dimensions, preserving aspect ratio
+ S32 new_width = LLImageRaw::contractDimToPowerOfTwo(llclamp((S32)llroundf(orig_width * scale), 4, max_width));
+ S32 new_height = LLImageRaw::contractDimToPowerOfTwo(llclamp((S32)llroundf(orig_height * scale), 4, max_height));
+
+ if (!raw_image->scale(new_width, new_height))
+ {
+ LL_WARNS() << "Failed to scale image from " << orig_width << "x" << orig_height << " to " << new_width << "x"
+ << new_height << LL_ENDL;
+ continue;
+ }
+
+ // Inform the resident about the resized image
+ LLSD subs;
+ subs["[ORIGINAL_WIDTH]"] = orig_width;
+ subs["[ORIGINAL_HEIGHT]"] = orig_height;
+ subs["[NEW_WIDTH]"] = new_width;
+ subs["[NEW_HEIGHT]"] = new_height;
+ subs["[MAX_WIDTH]"] = max_width;
+ subs["[MAX_HEIGHT]"] = max_height;
+ LLNotificationsUtil::add("ImageUploadResized", subs);
+ }
+
+ raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
+
+ LLTransactionID tid;
+ tid.generate();
+ LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
- upload_new_resource(uploadInfo);
+ LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
+
+ if (formatted->encode(raw_image, 0.0f))
+ {
+ LLFileSystem fmt_file(new_asset_id, LLAssetType::AT_TEXTURE, LLFileSystem::WRITE);
+ fmt_file.write(formatted->getData(), formatted->getDataSize());
+
+ LLResourceUploadInfo::ptr_t assetUploadInfo(new LLResourceUploadInfo(
+ tid, LLAssetType::AT_TEXTURE,
+ asset_name,
+ asset_name, 0,
+ LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
+ LLAgentBenefitsMgr::current().getTextureUploadCost(raw_image->getWidth(), raw_image->getHeight())
+ ));
+
+ upload_new_resource(assetUploadInfo);
+ }
+ }
+ else
+ {
+ LLNewFileResourceUploadInfo* info_p = 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);
+ LLResourceUploadInfo::ptr_t uploadInfo(info_p);
+
+ upload_new_resource(uploadInfo);
+ }
}
}
@@ -653,8 +739,31 @@ bool get_bulk_upload_expected_cost(
LLPointer<LLImageFormatted> image_frmted = LLImageFormatted::createFromType(codec);
if (gDirUtilp->fileExists(filename) && image_frmted && image_frmted->load(filename))
{
- S32 biased_width = LLImageRaw::biasedDimToPowerOfTwo(image_frmted->getWidth(), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
- S32 biased_height = LLImageRaw::biasedDimToPowerOfTwo(image_frmted->getHeight(), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
+ S32 biased_width, biased_height;
+
+ S32 max_width = allow_2k ? gSavedSettings.getS32("max_texture_dimension_X") : 1024;
+ S32 max_height = allow_2k ? gSavedSettings.getS32("max_texture_dimension_Y") : 1024;
+
+ S32 orig_width = image_frmted->getWidth();
+ S32 orig_height = image_frmted->getHeight();
+
+ if (orig_width > max_width || orig_height > max_height)
+ {
+ // Calculate scale factors
+ F32 width_scale = (F32)max_width / (F32)orig_width;
+ F32 height_scale = (F32)max_height / (F32)orig_height;
+ F32 scale = llmin(width_scale, height_scale);
+
+ // Calculate new dimensions, preserving aspect ratio
+ biased_width = LLImageRaw::contractDimToPowerOfTwo(llclamp((S32)llroundf(orig_width * scale), 4, max_width));
+ biased_height = LLImageRaw::contractDimToPowerOfTwo(llclamp((S32)llroundf(orig_height * scale), 4, max_height));
+ }
+ else
+ {
+ biased_width = LLImageRaw::biasedDimToPowerOfTwo(orig_width, LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
+ biased_height = LLImageRaw::biasedDimToPowerOfTwo(orig_height, LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
+ }
+
total_cost += LLAgentBenefitsMgr::current().getTextureUploadCost(biased_width, biased_height);
S32 area = biased_width * biased_height;
if (area >= LLAgentBenefits::MIN_2K_TEXTURE_AREA)
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 86bd11d1eb..0cd4a739ee 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3214,6 +3214,7 @@ void send_agent_update(bool force_send, bool send_reliable)
static F64 last_send_time = 0.0;
static U32 last_control_flags = 0;
+ static bool control_flags_follow_up = false;
static U8 last_render_state = 0;
static U8 last_flags = AU_FLAGS_NONE;
static LLQuaternion last_body_rot,
@@ -3291,6 +3292,20 @@ void send_agent_update(bool force_send, bool send_reliable)
break;
}
+ // example:
+ // user taps crouch (control_flags 4128), viewer sends 4128 then immediately 0
+ // server starts crouching motion but does not stop it, only once viewer sends 0
+ // second time will server stop the motion. follow_up exists to make sure all
+ // states like 'crouch' motion are properly cleared server side.
+ //
+ // P.S. Server probably shouldn't require a reminder to stop a motion,
+ // but at the moment it does.
+ if (control_flags_follow_up)
+ {
+ send_update = true;
+ break;
+ }
+
// check translation
constexpr F32 TRANSLATE_THRESHOLD = 0.01f;
if ((last_camera_pos_agent - camera_pos_agent).magVec() > TRANSLATE_THRESHOLD)
@@ -3424,6 +3439,7 @@ void send_agent_update(bool force_send, bool send_reliable)
// remember last update data
last_send_time = now;
+ control_flags_follow_up = last_control_flags != control_flags;
last_control_flags = control_flags;
last_render_state = render_state;
last_flags = flags;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 80ede12b8a..e317ba262a 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -679,6 +679,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mVisuallyMuteSetting(AV_RENDER_NORMALLY),
mMutedAVColor(LLColor4::white /* used for "uninitialize" */),
mFirstFullyVisible(true),
+ mWaitingForMeshes(false),
mFirstDecloudTime(-1.f),
mFullyLoaded(false),
mPreviousFullyLoaded(false),
@@ -934,12 +935,12 @@ bool LLVOAvatar::isFullyTextured() const
bool LLVOAvatar::hasGray() const
{
- return !getIsCloud() && !isFullyTextured();
+ return !getHasMissingParts() && !isFullyTextured();
}
S32 LLVOAvatar::getRezzedStatus() const
{
- if (getIsCloud()) return 0;
+ if (getHasMissingParts()) return 0;
bool textured = isFullyTextured();
bool all_baked_loaded = allBakedTexturesCompletelyDownloaded();
if (textured && all_baked_loaded && getAttachmentCount() == mSimAttachments.size()) return 4;
@@ -986,30 +987,45 @@ bool LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars)
}
// static
-void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars)
+void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars, S32& pending_meshes, S32& control_avatars)
{
counts.clear();
counts.resize(5);
avg_cloud_time = 0;
cloud_avatars = 0;
+ pending_meshes = 0;
+ control_avatars = 0;
S32 count_avg = 0;
for (LLCharacter* character : LLCharacter::sInstances)
{
- if (LLVOAvatar* inst = (LLVOAvatar*)character)
+ LLVOAvatar* inst = (LLVOAvatar*)character;
+ if (inst && !inst->isUIAvatar() && !inst->isSelf())
{
- S32 rez_status = inst->getRezzedStatus();
- counts[rez_status]++;
- F32 time = inst->getFirstDecloudTime();
- if (time >= 0)
+ if (inst->isControlAvatar())
{
- avg_cloud_time+=time;
- count_avg++;
+ control_avatars++;
}
- if (!inst->isFullyLoaded() || time < 0)
+ else
{
- // still renders as cloud
- cloud_avatars++;
+ S32 rez_status = inst->getRezzedStatus();
+ counts[rez_status]++;
+ F32 time = inst->getFirstDecloudTime();
+ if (time >= 0)
+ {
+ avg_cloud_time += time;
+ count_avg++;
+ }
+ if (!inst->isFullyLoaded() || time < 0)
+ {
+ // still renders as cloud
+ cloud_avatars++;
+ if (rez_status >= 4
+ && inst->mWaitingForMeshes)
+ {
+ pending_meshes++;
+ }
+ }
}
}
}
@@ -1026,7 +1042,7 @@ std::string LLVOAvatar::rezStatusToString(S32 rez_status)
switch (rez_status)
{
case 0:
- return "cloud";
+ return "missing parts";
case 1:
return "gray";
case 2:
@@ -3505,7 +3521,7 @@ void LLVOAvatar::idleUpdateNameTagText(bool new_name)
is_muted = isInMuteList();
}
bool is_friend = isBuddy();
- bool is_cloud = getIsCloud();
+ bool is_cloud = getHasMissingParts();
if (is_appearance != mNameAppearance)
{
@@ -8255,7 +8271,7 @@ bool LLVOAvatar::isVisible() const
}
// Determine if we have enough avatar data to render
-bool LLVOAvatar::getIsCloud() const
+bool LLVOAvatar::getHasMissingParts() const
{
if (mIsDummy)
{
@@ -8462,8 +8478,12 @@ bool LLVOAvatar::updateIsFullyLoaded()
|| (mLoadedCallbackTextures < mCallbackTextureList.size() && mLastTexCallbackAddedTime.getElapsedTimeF32() < MAX_TEXTURE_WAIT_TIME_SEC)
|| !mPendingAttachment.empty()
|| (rez_status < 3 && !isFullyBaked())
- || hasPendingAttachedMeshes()
);
+ if (!loading)
+ {
+ mWaitingForMeshes = hasPendingAttachedMeshes();
+ loading = mWaitingForMeshes;
+ }
// compare amount of attachments to one reported by simulator
if (!isSelf() && mLastCloudAttachmentCount < mSimAttachments.size() && mSimAttachments.size() > 0)
@@ -11830,16 +11850,24 @@ void LLVOAvatar::readProfileQuery(S32 retries)
}
else
- { // wait until next frame
- LLUUID id = getID();
+ {
+ // wait until next frame
+ const LLUUID id = getID();
- LL::WorkQueue::getInstance("mainloop")->post([id, retries] {
- LLVOAvatar* avatar = (LLVOAvatar*) gObjectList.findObject(id);
- if(avatar)
+ LL::WorkQueue::getInstance("mainloop")->post([id, retries]
+ {
+ LLViewerObject* object = gObjectList.findObject(id);
+ if (object
+ && !object->isDead()
+ && object->isAvatar()) // probably excessive, pcode isn't supposed to change
{
- avatar->readProfileQuery(retries);
+ LLVOAvatar* avatar = (LLVOAvatar*)object;
+ if (avatar)
+ {
+ avatar->readProfileQuery(retries);
+ }
}
- });
+ });
}
}
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 8e5b95ef25..1e563c4869 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -401,7 +401,7 @@ public:
bool isTooComplex() const;
bool visualParamWeightsAreDefault();
- virtual bool getIsCloud() const;
+ virtual bool getHasMissingParts() const;
bool isFullyTextured() const;
bool hasGray() const;
S32 getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = textured, 3 = waiting for attachments, 4 = full.
@@ -427,6 +427,7 @@ protected:
private:
bool mFirstFullyVisible;
+ bool mWaitingForMeshes;
F32 mFirstDecloudTime;
LLFrameTimer mFirstAppearanceMessageTimer;
@@ -723,7 +724,7 @@ public:
bool isFullyBaked();
static bool areAllNearbyInstancesBaked(S32& grey_avatars);
- static void getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars);
+ static void getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars, S32& pending_meshes, S32& control_avatars);
static std::string rezStatusToString(S32 status);
//--------------------------------------------------------------------
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index ebba9ba291..653c7e82eb 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1927,7 +1927,7 @@ void LLVOAvatarSelf::dumpTotalLocalTextureByteCount()
LL_INFOS() << "Total Avatar LocTex GL:" << (gl_bytes/1024) << "KB" << LL_ENDL;
}
-bool LLVOAvatarSelf::getIsCloud() const
+bool LLVOAvatarSelf::getHasMissingParts() const
{
// Let people know why they're clouded without spamming them into oblivion.
bool do_warn = false;
@@ -2237,14 +2237,18 @@ void LLVOAvatarSelf::appearanceChangeMetricsCoro(std::string url)
std::vector<S32> rez_counts;
F32 avg_time;
S32 total_cloud_avatars;
- LLVOAvatar::getNearbyRezzedStats(rez_counts, avg_time, total_cloud_avatars);
+ S32 waiting_for_meshes;
+ S32 control_avatars;
+ LLVOAvatar::getNearbyRezzedStats(rez_counts, avg_time, total_cloud_avatars, waiting_for_meshes, control_avatars);
for (S32 rez_stat = 0; rez_stat < rez_counts.size(); ++rez_stat)
{
std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat);
msg["nearby"][rez_status_name] = rez_counts[rez_stat];
}
+ msg["nearby"]["waiting_for_meshes"] = waiting_for_meshes;
msg["nearby"]["avg_decloud_time"] = avg_time;
msg["nearby"]["cloud_total"] = total_cloud_avatars;
+ msg["nearby"]["animeshes"] = control_avatars;
// std::vector<std::string> bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake");
std::vector<std::string> by_fields;
@@ -2826,6 +2830,12 @@ void LLVOAvatarSelf::setHoverOffset(const LLVector3& hover_offset, bool send_upd
//------------------------------------------------------------------------
bool LLVOAvatarSelf::needsRenderBeam()
{
+ static LLCachedControl<bool> enable_selection_hints(gSavedSettings, "EnableSelectionHints", true);
+ if (!enable_selection_hints)
+ {
+ return false;
+ }
+
LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
bool is_touching_or_grabbing = (tool == LLToolGrab::getInstance() && LLToolGrab::getInstance()->isEditing());
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index f7cd974ab0..45985b2a80 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -129,7 +129,7 @@ public:
// Loading state
//--------------------------------------------------------------------
public:
- /*virtual*/ bool getIsCloud() const;
+ /*virtual*/ bool getHasMissingParts() const;
//--------------------------------------------------------------------
// Region state
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index facda1d876..e9c765f9de 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -336,35 +336,37 @@ void LLWebRTCVoiceClient::updateSettings()
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
setVoiceEnabled(LLVoiceClient::getInstance()->voiceEnabled());
- static LLCachedControl<S32> sVoiceEarLocation(gSavedSettings, "VoiceEarLocation");
- setEarLocation(sVoiceEarLocation);
-
- static LLCachedControl<std::string> sInputDevice(gSavedSettings, "VoiceInputAudioDevice");
- setCaptureDevice(sInputDevice);
+ if (mVoiceEnabled)
+ {
+ static LLCachedControl<S32> sVoiceEarLocation(gSavedSettings, "VoiceEarLocation");
+ setEarLocation(sVoiceEarLocation);
- static LLCachedControl<std::string> sOutputDevice(gSavedSettings, "VoiceOutputAudioDevice");
- setRenderDevice(sOutputDevice);
+ static LLCachedControl<std::string> sInputDevice(gSavedSettings, "VoiceInputAudioDevice");
+ setCaptureDevice(sInputDevice);
- LL_INFOS("Voice") << "Input device: " << std::quoted(sInputDevice()) << ", output device: " << std::quoted(sOutputDevice()) << LL_ENDL;
+ static LLCachedControl<std::string> sOutputDevice(gSavedSettings, "VoiceOutputAudioDevice");
+ setRenderDevice(sOutputDevice);
- static LLCachedControl<F32> sMicLevel(gSavedSettings, "AudioLevelMic");
- setMicGain(sMicLevel);
+ LL_INFOS("Voice") << "Input device: " << std::quoted(sInputDevice()) << ", output device: " << std::quoted(sOutputDevice()) << LL_ENDL;
- llwebrtc::LLWebRTCDeviceInterface::AudioConfig config;
+ static LLCachedControl<F32> sMicLevel(gSavedSettings, "AudioLevelMic");
+ setMicGain(sMicLevel);
- static LLCachedControl<bool> sEchoCancellation(gSavedSettings, "VoiceEchoCancellation", true);
- config.mEchoCancellation = sEchoCancellation;
+ llwebrtc::LLWebRTCDeviceInterface::AudioConfig config;
- static LLCachedControl<bool> sAGC(gSavedSettings, "VoiceAutomaticGainControl", true);
- config.mAGC = sAGC;
+ static LLCachedControl<bool> sEchoCancellation(gSavedSettings, "VoiceEchoCancellation", true);
+ config.mEchoCancellation = sEchoCancellation;
- static LLCachedControl<U32> sNoiseSuppressionLevel(gSavedSettings,
- "VoiceNoiseSuppressionLevel",
- llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel::NOISE_SUPPRESSION_LEVEL_VERY_HIGH);
- config.mNoiseSuppressionLevel = (llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel) (U32)sNoiseSuppressionLevel;
+ static LLCachedControl<bool> sAGC(gSavedSettings, "VoiceAutomaticGainControl", true);
+ config.mAGC = sAGC;
- mWebRTCDeviceInterface->setAudioConfig(config);
+ static LLCachedControl<U32> sNoiseSuppressionLevel(gSavedSettings,
+ "VoiceNoiseSuppressionLevel",
+ llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel::NOISE_SUPPRESSION_LEVEL_VERY_HIGH);
+ config.mNoiseSuppressionLevel = (llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel)(U32)sNoiseSuppressionLevel;
+ mWebRTCDeviceInterface->setAudioConfig(config);
+ }
}
// Observers
diff --git a/indra/newview/res/ll_icon_small.ico b/indra/newview/res/ll_icon_small.ico
new file mode 100644
index 0000000000..a3f6877935
--- /dev/null
+++ b/indra/newview/res/ll_icon_small.ico
Binary files differ
diff --git a/indra/newview/res/resource.h b/indra/newview/res/resource.h
index e904f4a1a8..1d3289d784 100644
--- a/indra/newview/res/resource.h
+++ b/indra/newview/res/resource.h
@@ -30,6 +30,7 @@
#define IDREMOVE 3
#define IDI_LL_ICON 103
#define IDC_GRABHAND 104
+#define IDI_LL_ICON_SMALL 105
#define IDC_CURSOR1 134
#define IDC_CURSOR2 136
#define IDC_CURSOR3 147
diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc
index b01f5e700d..08e381ebc5 100755
--- a/indra/newview/res/viewerRes.rc
+++ b/indra/newview/res/viewerRes.rc
@@ -56,6 +56,7 @@ END
// remains consistent on all systems.
IDI_LL_ICON ICON "ll_icon.ico"
IDI_LCD_LL_ICON ICON "icon1.ico"
+IDI_LL_ICON_SMALL ICON "ll_icon_small.ico"
/////////////////////////////////////////////////////////////////////////////
//
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 94c8119d4d..654810e210 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -659,7 +659,6 @@ with the same filename but different name
<texture name="login_mp_logo" file_name="windows/login_mp_logo.png" preload="true" />
<texture name="login_mp_logo_small" file_name="windows/login_mp_logo_small.png" preload="true" />
- <texture name="first_login_image" file_name="windows/first_login_image.jpg" preload="true" />
<texture name="Stepper_Down_Off" file_name="widgets/Stepper_Down_Off.png" preload="false" />
<texture name="Stepper_Down_Press" file_name="widgets/Stepper_Down_Press.png" preload="false" />
diff --git a/indra/newview/skins/default/textures/windows/first_login_image.jpg b/indra/newview/skins/default/textures/windows/first_login_image.jpg
deleted file mode 100644
index 58c417081a..0000000000
--- a/indra/newview/skins/default/textures/windows/first_login_image.jpg
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/xui/de/panel_login_first.xml b/indra/newview/skins/default/xui/de/panel_login_first.xml
deleted file mode 100644
index 038001157e..0000000000
--- a/indra/newview/skins/default/xui/de/panel_login_first.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<panel name="panel_login">
- <panel.string name="forgot_password_url">
- http://secondlife.com/account/request.php?lang=de
- </panel.string>
- <panel.string name="sign_up_url">
- https://join.secondlife.com/
- </panel.string>
- <layout_stack name="logo_stack">
- <layout_panel name="parent_panel2">
- <layout_stack name="widget_stack">
- <layout_panel name="widget_container">
- <combo_box label="Benutzername" name="username_combo" tool_tip="Bei der Registrierung gewählter Benutzername wie „berndschmidt12“ oder „Liebe Sonne“"/>
- <line_editor label="Kennwort" name="password_edit"/>
- <button label="Anmelden" name="connect_btn"/>
- <check_box label="Details speichern" name="remember_check"/>
- <text name="forgot_password_text">
- Kennwort vergessen
- </text>
- <text name="sign_up_text">
- Registrieren
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- <layout_panel name="parent_panel3">
- <layout_stack name="images_stack">
- <layout_panel name="images_container">
- <text name="image_caption_left">
- Ihr erster Schritt ist Learning Island. Suchen Sie die Pforte!
- </text>
- <text name="image_caption_right">
- Erkunden Sie dann Social Island und lernen Sie andere Einwohner kennen!
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/floater_test_slapp.xml b/indra/newview/skins/default/xui/en/floater_test_slapp.xml
index dd2720816a..5a13a0147e 100644
--- a/indra/newview/skins/default/xui/en/floater_test_slapp.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_slapp.xml
@@ -8,7 +8,7 @@
width="500">
<floater.string
name="remove_folder_slapp">
- secondlife://app/remove_folder/?folder_id=
+ secondlife:///app/remove_folder/?folder_id=
</floater.string>
<text
type="string"
@@ -42,7 +42,7 @@
width="450"
layout="topleft"
left="16">
- secondlife://app/wear_folder/?folder_name=Daisy
+ secondlife:///app/wear_folder/?folder_name=Daisy
</text>
<text
type="string"
@@ -63,7 +63,7 @@
width="450"
layout="topleft"
left="16">
- secondlife://app/add_folder/?folder_name=Cardboard%20Boxbot
+ secondlife:///app/add_folder/?folder_name=Cardboard%20Boxbot
</text>
<text
type="string"
@@ -73,7 +73,7 @@
height="16"
width="450"
layout="topleft">
- secondlife://app/add_folder/?folder_id=59219db2-c260-87d3-213d-bb3bc298a3d8
+ secondlife:///app/add_folder/?folder_id=59219db2-c260-87d3-213d-bb3bc298a3d8
</text>
<text
type="string"
@@ -118,6 +118,6 @@
name="remove_folder_txt"
layout="topleft"
left="16">
- secondlife://app/remove_folder/?folder_id=
+ secondlife:///app/remove_folder/?folder_id=
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_url_parcel.xml b/indra/newview/skins/default/xui/en/menu_url_parcel.xml
index e0f1fcf9c3..95752dab66 100644
--- a/indra/newview/skins/default/xui/en/menu_url_parcel.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_parcel.xml
@@ -16,7 +16,7 @@
layout="topleft"
name="show_on_map">
<menu_item_call.on_click
- function="Url.ShowOnMap" />
+ function="Url.ShowParcelOnMap" />
</menu_item_call>
<menu_item_separator
layout="topleft" />
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index a318093d7c..10c9efffd1 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -12674,4 +12674,15 @@ Select the "use as favorite folder" from a folder's menu to set it as the favori
Unable to apply material to the water exclusion surface.
<tag>fail</tag>
</notification>
+
+ <notification
+ icon="notify.tga"
+ name="ImageUploadResized"
+ type="alertmodal">
+ The texture you are uploading has been resized from [ORIGINAL_WIDTH]x[ORIGINAL_HEIGHT] to [NEW_WIDTH]x[NEW_HEIGHT] in order to to fit the maximum size of [MAX_WIDTH]x[MAX_HEIGHT] pixels.
+ <usetemplate
+ ignoretext="Image Upload Resized"
+ name="okignore"
+ yestext="OK"/>
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml
deleted file mode 100644
index 0a8ae48b02..0000000000
--- a/indra/newview/skins/default/xui/en/panel_login_first.xml
+++ /dev/null
@@ -1,262 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel
- follows="all"
- height="768"
- layout="topleft"
- name="panel_login"
- focus_root="true"
- background_visible="true"
- bg_opaque_color="0.0 0.0 0.0 1"
- background_opaque="true"
- width="1024">
- <panel.string
- name="forgot_password_url">
- http://secondlife.com/account/request.php
- </panel.string>
- <panel.string
- name="sign_up_url">
- https://join.secondlife.com/
- </panel.string>
- <layout_stack
- follows="left|right|top|bottom"
- width="1024"
- height="768"
- left="0"
- name="logo_stack"
- orientation="vertical"
- top="0">
- <layout_panel
- height="18"
- auto_resize="false"
- name="page_top"
- width="1024" />
- <!-- start of logo stack -->
- <layout_panel
- height="130"
- min_height="10"
- auto_resize="false"
- name="parent_panel"
- width="1024">
- <layout_stack
- follows="left|right|top|bottom"
- height="100"
- left="0"
- name="logo_stack"
- orientation="horizontal"
- top="0"
- width="1024">
- <layout_panel
- height="110"
- min_height="10"
- auto_resize="true"
- name="logo_left"
- width="300" />
- <layout_panel
- auto_resize="false"
- follows="left|right|top"
- name="logo_container"
- width="225"
- left="0"
- top="0"
- height="105">
- <icon
- height="94"
- image_name="login_mp_logo"
- left="0"
- name="sl_logo"
- top="0" />
- </layout_panel>
- <layout_panel
- height="100"
- name="logo_right"
- auto_resize="true"
- width="300" />
- </layout_stack>
- </layout_panel>
- <!-- end of logo stack -->
- <!-- start of widget stack -->
- <layout_panel
- height="100"
- min_height="10"
- auto_resize="false"
- name="parent_panel2"
- width="1024">
- <layout_stack
- follows="left|right|top|bottom"
- height="80"
- left="0"
- name="widget_stack"
- orientation="horizontal"
- top="0"
- width="1024">
- <layout_panel
- height="80"
- min_height="10"
- auto_resize="true"
- name="widget_left"
- width="200" />
- <layout_panel
- auto_resize="false"
- follows="left|right|top"
- name="widget_container"
- width="730"
- left="0"
- top="0"
- height="80">
- <combo_box
- allow_text_entry="true"
- follows="left|bottom"
- height="32"
- left="42"
- label="Username"
- combo_editor.font="SansSerifLarge"
- max_chars="128"
- top="0"
- combo_editor.prevalidator="ascii"
- tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine"
- name="username_combo"
- width="232">
- <combo_box.combo_editor
- text_pad_left="8" />
- <combo_box.combo_button
- visible ="false"/>
- <combo_box.drop_down_button
- visible ="false"/>
- </combo_box>
- <line_editor
- follows="left|top"
- width="200"
- height="32"
- left="262"
- max_length_chars="16"
- name="password_edit"
- label="Password"
- text_pad_left="8"
- font="SansSerifLarge"
- is_password="true"
- select_on_focus="true"
- commit_on_focus_lost="false"
- top="0" />
- <button
- follows="left|top"
- image_unselected="PushButton_Login"
- image_pressed="PushButton_Login_Pressed"
- image_hover_unselected="PushButton_Login_Over"
- label="Log In"
- label_color="White"
- font="SansSerifLarge"
- name="connect_btn"
- left_pad="15"
- width="120"
- height="32"
- top="0" />
- <text
- follows="left|top"
- font="SansSerifLarge"
- font.style="BOLD"
- text_color="EmphasisColor"
- height="34"
- name="sign_up_text"
- left_pad="10"
- top="0"
- width="200"
- valign="center">
- Sign up
- </text>
- <check_box
- follows="left|top"
- font="SansSerifLarge"
- left="42"
- top="32"
- height="24"
- label="Remember me"
- word_wrap="down"
- check_button.bottom="3"
- name="remember_name"
- tool_tip="Already remembered user can be forgotten from Me &gt; Preferences &gt; Advanced &gt; Remembered Usernames."
- width="198" />
- <check_box
- control_name="RememberPassword"
- follows="left|top"
- font="SansSerifLarge"
- height="24"
- left="262"
- bottom_delta="0"
- label="Remember password"
- word_wrap="down"
- check_button.bottom="3"
- name="remember_password"
- width="198" />
- <text
- follows="left|top"
- font="SansSerifLarge"
- text_color="EmphasisColor"
- height="16"
- name="forgot_password_text"
- left="492"
- top="34"
- width="200">
- Forgotten password
- </text>
- </layout_panel>
- <layout_panel
- height="100"
- name="widget_right"
- auto_resize="true"
- width="200" />
- </layout_stack>
- </layout_panel>
- <!-- end of widget stack -->
- <!-- start of images stack -->
- <layout_panel
- height="500"
- min_height="10"
- auto_resize="false"
- name="parent_panel3"
- width="1024">
- <layout_stack
- follows="left|right|top|bottom"
- height="500"
- left="0"
- name="images_stack"
- orientation="horizontal"
- top="0"
- width="1024">
- <layout_panel
- height="500"
- min_height="10"
- auto_resize="true"
- name="images_left"
- width="96" />
- <layout_panel
- auto_resize="false"
- follows="left|right|top"
- name="images_container"
- width="675"
- left="0"
- top="0"
- height="500">
- <icon
- height="450"
- width="675"
- image_name="first_login_image"
- left="0"
- name="image_left"
- top="0" />
- </layout_panel>
- <layout_panel
- height="100"
- name="images_right"
- auto_resize="true"
- width="96" />
- </layout_stack>
- </layout_panel>
- <!-- end of images stack -->
- <layout_panel
- height="400"
- min_height="10"
- auto_resize="true"
- name="page_bottom"
- width="1024" />
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index c38af9d4fa..54105a7d4e 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -32,15 +32,15 @@
height="23"
increment="64"
initial_value="1024"
- label="Cache size (256 - 9984MB)"
+ label="Cache size (896 - 32768MB)"
label_width="150"
layout="topleft"
left="80"
- max_val="9984"
- min_val="256"
+ max_val="32768"
+ min_val="896"
top_pad="10"
name="cachesizespinner"
- width="200" />
+ width="210" />
<text
type="string"
length="1"
@@ -59,7 +59,7 @@
label="Clear Cache"
label_selected="Clear Cache"
layout="topleft"
- left_pad="30"
+ left_pad="20"
name="clear_cache"
top_delta="0"
width="100">
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
index 809c001904..8ab7b48d19 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
@@ -90,7 +90,7 @@
name="online_visibility"
top_pad="15"
width="350" />
-
+
<check_box
enabled_control="EnableVoiceChat"
control_name="AutoDisengageMic"
@@ -101,6 +101,37 @@
name="auto_disengage_mic_check"
top_pad="10"
width="350" />
+ <check_box
+ control_name="EnableLookAtTarget"
+ height="16"
+ label="Enable LookAt"
+ tool_tip="Enable tracking cursor position with avatar head's rotation"
+ layout="topleft"
+ left="30"
+ name="enable_lookat_target"
+ top_pad="10"
+ width="350" />
+ <check_box
+ enabled_control="EnableLookAtTarget"
+ control_name="LimitLookAtTarget"
+ height="16"
+ label="Limit LookAt Distance"
+ tool_tip="Limit the look at target's distance by restricting it around the avatar's head"
+ layout="topleft"
+ left="50"
+ name="limit_lookat_distance"
+ top_pad="10"
+ width="350" />
+ <check_box
+ control_name="EnableSelectionHints"
+ height="16"
+ label="Enable Selection Hints"
+ tool_tip="Enable reporting and tracking current selection using 'beam' particles and character animations"
+ layout="topleft"
+ left="30"
+ name="enable_selection_hints"
+ top_pad="10"
+ width="350" />
<button
follows="left|top"
height="23"
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index 5e05eb2837..e53a25ff6b 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -86,7 +86,7 @@
height="18"
left="0"
name="balance"
- tool_tip="Click to refresh your L$ balance"
+ tool_tip="L$ [AMT]&#10;Click to refresh your L$ balance.&#10;Double-click to display or hide your L$ balance."
v_pad="4"
top="0"
wrap="false"
diff --git a/indra/newview/skins/default/xui/es/panel_login_first.xml b/indra/newview/skins/default/xui/es/panel_login_first.xml
deleted file mode 100644
index ccb6858351..0000000000
--- a/indra/newview/skins/default/xui/es/panel_login_first.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<panel name="panel_login">
- <panel.string name="forgot_password_url">
- http://secondlife.com/account/request.php?lang=es
- </panel.string>
- <panel.string name="sign_up_url">
- https://join.secondlife.com/
- </panel.string>
- <layout_stack name="logo_stack">
- <layout_panel name="parent_panel2">
- <layout_stack name="widget_stack">
- <layout_panel name="widget_container">
- <combo_box label="Nombre de usuario" name="username_combo" tool_tip="El nombre de usuario que elegiste al registrarte, como bobsmith12 o Steller Sunshine"/>
- <line_editor label="Contraseña" name="password_edit"/>
- <button label="Iniciar sesión" name="connect_btn"/>
- <check_box label="Recordarme" name="remember_check"/>
- <text name="forgot_password_text">
- Contraseña olvidada
- </text>
- <text name="sign_up_text">
- Regístrate
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- <layout_panel name="parent_panel3">
- <layout_stack name="images_stack">
- <layout_panel name="images_container">
- <text name="image_caption_left">
- Tu primer destino es la Isla de aprendizaje. ¡Encuentra el portal de salida!
- </text>
- <text name="image_caption_right">
- A continuación, puedes explorar la Isla social y hablar con otros residentes nuevos.
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_login_first.xml b/indra/newview/skins/default/xui/fr/panel_login_first.xml
deleted file mode 100644
index 8f40d0230c..0000000000
--- a/indra/newview/skins/default/xui/fr/panel_login_first.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<panel name="panel_login">
- <panel.string name="forgot_password_url">
- http://secondlife.com/account/request.php?lang=fr
- </panel.string>
- <panel.string name="sign_up_url">
- https://join.secondlife.com/
- </panel.string>
- <layout_stack name="logo_stack">
- <layout_panel name="parent_panel2">
- <layout_stack name="widget_stack">
- <layout_panel name="widget_container">
- <combo_box label="Nom d&apos;utilisateur" name="username_combo" tool_tip="Nom d&apos;utilisateur que vous avez choisi lors de votre inscription (par exemple, bobsmith12 ou Steller Sunshine)."/>
- <line_editor label="Mot de passe" name="password_edit"/>
- <button label="Connexion" name="connect_btn"/>
- <check_box font="SansSerifSmall" label="Mémoriser mes informations" name="remember_check"/>
- <text name="forgot_password_text">
- Mot de passe oublié
- </text>
- <text name="sign_up_text">
- S&apos;inscrire
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- <layout_panel name="parent_panel3">
- <layout_stack name="images_stack">
- <layout_panel name="images_container">
- <text name="image_caption_left">
- Votre première étape est Learning Island. Trouvez le portail de sortie.
- </text>
- <text name="image_caption_right">
- Puis explorez Social Island et faites la connaissance d&apos;autres résidents.
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_login_first.xml b/indra/newview/skins/default/xui/it/panel_login_first.xml
deleted file mode 100644
index 5b04fd411a..0000000000
--- a/indra/newview/skins/default/xui/it/panel_login_first.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<panel name="panel_login">
- <panel.string name="forgot_password_url">
- http://secondlife.com/account/request.php?lang=it
- </panel.string>
- <panel.string name="sign_up_url">
- http://join.secondlife.com/
- </panel.string>
- <layout_stack name="logo_stack">
- <layout_panel name="parent_panel2">
- <layout_stack name="widget_stack">
- <layout_panel name="widget_container">
- <combo_box label="Nome utente" name="username_combo" tool_tip="Il nome utente che hai scelto durante la registrazione, come roby12 o Stella Solare"/>
- <line_editor label="Password" name="password_edit"/>
- <button label="Accedi" name="connect_btn"/>
- <check_box label="Ricordami" name="remember_check"/>
- <text name="forgot_password_text">
- Password dimenticata
- </text>
- <text name="sign_up_text">
- Registrati
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- <layout_panel name="parent_panel3">
- <layout_stack name="images_stack">
- <layout_panel name="images_container">
- <text name="image_caption_left">
- Il primo passo è a Learning Island. Trova il portale di uscita!
- </text>
- <text name="image_caption_right">
- Quindi esplora Social Island e incontra altri nuovi residenti.
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_login_first.xml b/indra/newview/skins/default/xui/ja/panel_login_first.xml
deleted file mode 100644
index 0f987fc816..0000000000
--- a/indra/newview/skins/default/xui/ja/panel_login_first.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="panel_login">
- <panel.string name="forgot_password_url">
- https://secondlife.com/my/account/request.php?lang=ja-JP
- </panel.string>
- <panel.string name="sign_up_url">
- https://join.secondlife.com/?lang=ja
- </panel.string>
- <layout_stack name="logo_stack">
- <layout_panel name="page_top"/>
- <layout_panel name="parent_panel">
- <layout_stack name="logo_stack">
- <layout_panel name="logo_left"/>
- <layout_panel name="logo_container">
- <icon name="sl_logo"/>
- </layout_panel>
- <layout_panel auto_resize="true"/>
- </layout_stack>
- </layout_panel>
- <layout_panel name="parent_panel2">
- <layout_stack name="widget_stack">
- <layout_panel name="widget_left"/>
- <layout_panel name="widget_container">
- <combo_box label="ユーザ名" tool_tip="登録時に自分で選んだユーザー名(例:bobsmith12、Steller Sunshineなど)" name="username_combo">
- <combo_box.combo_editor/>
- <combo_box.combo_button/>
- <combo_box.drop_down_button/>
- </combo_box>
- <line_editor name="password_edit" label="パスワード"/>
- <button label="ログイン" name="connect_btn"/>
- <text name="sign_up_text" valign="center">
- サインアップ
- </text>
- <check_box label="ユーザ名を記憶" name="remember_name" tool_tip="すでに記憶されているユーザーは、「私」>「初期設定」>「詳細設定」>「記憶されたユーザー名」から削除できます。"/>
- <check_box label="パスワード記憶" name="remember_password"/>
- <text name="forgot_password_text">
- パスワードを忘れましたか?
- </text>
- </layout_panel>
- <layout_panel name="widget_right"/>
- </layout_stack>
- </layout_panel>
- <layout_panel name="parent_panel3">
- <layout_stack name="images_stack">
- <layout_panel name="images_left"/>
- <layout_panel name="images_container">
- <icon name="image_left"/>
- </layout_panel>
- <layout_panel name="images_right"/>
- </layout_stack>
- </layout_panel>
- <layout_panel name="page_bottom"/>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/pl/panel_login_first.xml b/indra/newview/skins/default/xui/pl/panel_login_first.xml
deleted file mode 100644
index 0604ecbcff..0000000000
--- a/indra/newview/skins/default/xui/pl/panel_login_first.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel name="panel_login">
- <layout_stack name="logo_stack">
- <layout_panel name="parent_panel2">
- <layout_stack name="widget_stack">
- <layout_panel name="widget_container">
- <combo_box label="Użytkownik" tool_tip="Nazwa użytkownika wybrana przy rejestracji, np. bobsmith12 lub Steller Sunshine" name="username_combo" />
- <line_editor name="password_edit" label="Hasło" />
- <button label="Zaloguj" name="connect_btn" />
- <check_box label="Zapamiętaj mnie" name="remember_check" />
- <text name="forgot_password_text">
- Zapomniałem/am hasła
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- <layout_panel name="parent_panel3">
- <layout_stack name="images_stack">
- <layout_panel name="images_container">
- <text name="image_caption_left">
- Wyspa Nauki to Twój pierwszy krok. Znajdź portal z wyjściem!
- </text>
- <text name="image_caption_right">
- Potem zwiedź Wyspę Towarzyską i poznaj innych nowych rezydentów!
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_login_first.xml b/indra/newview/skins/default/xui/pt/panel_login_first.xml
deleted file mode 100644
index 86c61163bc..0000000000
--- a/indra/newview/skins/default/xui/pt/panel_login_first.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<panel name="panel_login">
- <panel.string name="forgot_password_url">
- http://secondlife.com/account/request.php?lang=pt
- </panel.string>
- <panel.string name="sign_up_url">
- https://join.secondlife.com/
- </panel.string>
- <layout_stack name="logo_stack">
- <layout_panel name="parent_panel2">
- <layout_stack name="widget_stack">
- <layout_panel name="widget_container">
- <combo_box label="Nome de usuário" name="username_combo" tool_tip="O nome de usuário que você escolheu ao fazer seu cadastro, como zecazc12 ou Magia Solar"/>
- <line_editor label="Senha" name="password_edit"/>
- <button label="Login" name="connect_btn"/>
- <check_box label="Lembrar-me" name="remember_check"/>
- <text name="forgot_password_text">
- Senha esquecida
- </text>
- <text name="sign_up_text">
- Cadastre-se
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- <layout_panel name="parent_panel3">
- <layout_stack name="images_stack">
- <layout_panel name="images_container">
- <text name="image_caption_left">
- Sua primeira parada é a Ilha da Educação. Encontre o portal de saída!
- </text>
- <text name="image_caption_right">
- Em seguida, explore a Ilha Social e encontre novos residentes!
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_login_first.xml b/indra/newview/skins/default/xui/ru/panel_login_first.xml
deleted file mode 100644
index 5db81ea7ca..0000000000
--- a/indra/newview/skins/default/xui/ru/panel_login_first.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<panel name="panel_login">
- <panel.string name="forgot_password_url">
- http://secondlife.com/account/request.php
- </panel.string>
- <panel.string name="sign_up_url">
- https://join.secondlife.com/
- </panel.string>
- <layout_stack name="logo_stack">
- <layout_panel name="parent_panel2">
- <layout_stack name="widget_stack">
- <layout_panel name="widget_container">
- <combo_box label="Имя пользователя" name="username_combo" tool_tip="Имя пользователя, которое вы выбрали при регистрации, например, «bobsmith12» или «Steller Sunshine»"/>
- <line_editor label="Пароль" name="password_edit"/>
- <button label="Войти" name="connect_btn"/>
- <check_box label="Запомнить меня" name="remember_check"/>
- <text name="forgot_password_text">
- Забытый пароль
- </text>
- <text name="sign_up_text">
- Регистрация
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- <layout_panel name="parent_panel3">
- <layout_stack name="images_stack">
- <layout_panel name="images_container">
- <text name="image_caption_left">
- Ваш первый шаг – Учебный остров. Найдите портал выхода!
- </text>
- <text name="image_caption_right">
- Затем исследуйте Социальный остров и познакомьтесь с другими новичками!
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_login_first.xml b/indra/newview/skins/default/xui/tr/panel_login_first.xml
deleted file mode 100644
index 1fc80c2b97..0000000000
--- a/indra/newview/skins/default/xui/tr/panel_login_first.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<panel name="panel_login">
- <panel.string name="forgot_password_url">
- http://secondlife.com/account/request.php
- </panel.string>
- <panel.string name="sign_up_url">
- https://join.secondlife.com/
- </panel.string>
- <layout_stack name="logo_stack">
- <layout_panel name="parent_panel2">
- <layout_stack name="widget_stack">
- <layout_panel name="widget_container">
- <combo_box label="Kullanıcı Adı" name="username_combo" tool_tip="Kaydolduğunuzda seçtiğiniz kullanıcı adı, örn. mustafayalcin12 veya Faruk Gungoren"/>
- <line_editor label="Parola" name="password_edit"/>
- <button label="Oturum Aç" name="connect_btn"/>
- <check_box label="Beni hatırla" name="remember_check"/>
- <text name="forgot_password_text">
- Parolamı unuttum
- </text>
- <text name="sign_up_text">
- Kaydol
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- <layout_panel name="parent_panel3">
- <layout_stack name="images_stack">
- <layout_panel name="images_container">
- <text name="image_caption_left">
- Başlangıç yeriniz Eğitim Adası. Haydi çıkış portalını bulun!
- </text>
- <text name="image_caption_right">
- Sonra da Sosyal Ada&apos;yı keşfe çıkın ve diğer LS sakinleriyle tanışın!
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_login_first.xml b/indra/newview/skins/default/xui/zh/panel_login_first.xml
deleted file mode 100644
index 4d72fcdd03..0000000000
--- a/indra/newview/skins/default/xui/zh/panel_login_first.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<panel name="panel_login">
- <panel.string name="forgot_password_url">
- http://secondlife.com/account/request.php
- </panel.string>
- <panel.string name="sign_up_url">
- http://join.secondlife.com/
- </panel.string>
- <layout_stack name="logo_stack">
- <layout_panel name="parent_panel2">
- <layout_stack name="widget_stack">
- <layout_panel name="widget_container">
- <combo_box label="使用者名稱" name="username_combo" tool_tip="使用者名稱是你註冊時所挑選的,例如 bobsmith12 或 Steller Sunshine"/>
- <line_editor label="密碼" name="password_edit"/>
- <button label="登入" name="connect_btn"/>
- <check_box label="記得我" name="remember_check"/>
- <text name="forgot_password_text">
- 忘記密碼
- </text>
- <text name="sign_up_text">
- 註冊
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- <layout_panel name="parent_panel3">
- <layout_stack name="images_stack">
- <layout_panel name="images_container">
- <text name="image_caption_left">
- 你在「學習島」的第一步。 找到離開的傳送門!
- </text>
- <text name="image_caption_right">
- 接著,到「社交島」探索,認識新的居民朋友!
- </text>
- </layout_panel>
- </layout_stack>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp
index d5e281bba8..10c68432a1 100644
--- a/indra/newview/tests/llviewerassetstats_test.cpp
+++ b/indra/newview/tests/llviewerassetstats_test.cpp
@@ -43,12 +43,15 @@ namespace LLStatViewer
LLTrace::SampleStatHandle<> FPS_SAMPLE("fpssample");
}
-void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars)
+void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars, S32& pending_meshes, S32& control_avatars)
{
counts.resize(3);
counts[0] = 0;
counts[1] = 0;
counts[2] = 1;
+ cloud_avatars = 0;
+ pending_meshes = 0;
+ control_avatars = 0;
}
// static
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index c778f1e838..ceb05980a5 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -151,7 +151,6 @@ class ViewerManifest(LLManifest):
with self.prefix(src_dst="skins"):
# include the entire textures directory recursively
with self.prefix(src_dst="*/textures"):
- self.path("*/*.jpg")
self.path("*/*.png")
self.path("*.tga")
self.path("*.j2c")
@@ -559,6 +558,9 @@ class Windows_x86_64_Manifest(ViewerManifest):
):
self.path(libfile)
+ if self.args['discord'] == 'ON':
+ self.path("discord_partner_sdk.dll")
+
if self.args['openal'] == 'ON':
# Get openal dll
self.path("OpenAL32.dll")
@@ -1021,6 +1023,13 @@ class Darwin_x86_64_Manifest(ViewerManifest):
):
self.path2basename(relpkgdir, libfile)
+ # Discord social SDK
+ if self.args['discord'] == 'ON':
+ for libfile in (
+ "libdiscord_partner_sdk.dylib",
+ ):
+ self.path2basename(relpkgdir, libfile)
+
# OpenAL dylibs
if self.args['openal'] == 'ON':
for libfile in (
@@ -1825,6 +1834,7 @@ if __name__ == "__main__":
extra_arguments = [
dict(name='bugsplat', description="""BugSplat database to which to post crashes,
if BugSplat crash reporting is desired""", default=''),
+ dict(name='discord', description="""Indication discord social sdk libraries are needed""", default='OFF'),
dict(name='openal', description="""Indication openal libraries are needed""", default='OFF'),
dict(name='tracy', description="""Indication tracy profiler is enabled""", default='OFF'),
]