summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Nikolenko <maximnproductengine@lindenlab.com>2026-08-28 19:19:09 +0300
committerGitHub <noreply@github.com>2026-08-28 19:19:09 +0300
commite3320f649d2e25aac6df491614b42c94645679c7 (patch)
tree8e4d86e996501361576f0648e1e6203b8fe36a02
parent3a9706136a16caeeb85d9c76828835f1b266800f (diff)
parent6d7abb3f97d64d0232e6499cd1e05baa31d73e5c (diff)
Merge pull request #6201 from secondlife/maxim/develop-6174
#6174 Allow changing maturity preference on maturity error dialog
-rw-r--r--indra/llui/lltextbase.cpp8
-rw-r--r--indra/llui/lltextbase.h5
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/llfloatermaturitydialog.cpp86
-rw-r--r--indra/newview/llfloatermaturitydialog.h47
-rw-r--r--indra/newview/llviewerfloaterreg.cpp2
-rw-r--r--indra/newview/llviewermessage.cpp34
-rw-r--r--indra/newview/skins/default/xui/en/floater_maturity_dialog.xml100
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml11
9 files changed, 287 insertions, 8 deletions
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 802367720f..06645df203 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -158,6 +158,7 @@ LLTextBase::Params::Params()
track_end("track_end", false),
read_only("read_only", false),
skip_link_underline("skip_link_underline", false),
+ link_color("link_color"),
spellcheck("spellcheck", false),
v_pad("v_pad", 0),
h_pad("h_pad", 0),
@@ -196,6 +197,8 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mReadOnly(p.read_only),
mSkipTripleClick(false),
mSkipLinkUnderline(p.skip_link_underline),
+ mHasLinkColor(p.link_color.isProvided()),
+ mLinkColor(p.link_color.isProvided() ? p.link_color() : LLUIColor()),
mSpellCheck(p.spellcheck),
mSpellCheckStart(-1),
mSpellCheckEnd(-1),
@@ -2426,6 +2429,11 @@ void LLTextBase::appendTextImpl(const std::string& new_text, const LLStyle::Para
LLStyle::Params link_params(style_params);
link_params.overwriteFrom(match.getStyle());
+ if (mHasLinkColor)
+ {
+ link_params.color = mLinkColor;
+ link_params.readonly_color = mLinkColor;
+ }
// output the text before the Url
if (start > 0)
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 62f984b8fc..d3edd17dca 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -351,7 +351,8 @@ public:
bg_writeable_color,
bg_focus_color,
text_selected_color,
- bg_selected_color;
+ bg_selected_color,
+ link_color;
Optional<bool> bg_visible,
border_visible,
@@ -777,6 +778,8 @@ protected:
bool mAlwaysShowIcons;
bool mSkipLinkUnderline;
+ bool mHasLinkColor;
+ LLUIColor mLinkColor;
// support widgets
LLHandle<LLContextMenu> mPopupMenuHandle;
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 7aa255c5da..c9db55c52d 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -260,6 +260,7 @@ set(viewer_SOURCE_FILES
llfloaterloadprefpreset.cpp
llfloatermarketplacelistings.cpp
llfloatermap.cpp
+ llfloatermaturitydialog.cpp
llfloatermediasettings.cpp
llfloatermemleak.cpp
llfloatermodelpreview.cpp
@@ -948,6 +949,7 @@ set(viewer_HEADER_FILES
llfloatermap.h
llfloatermarketplace.h
llfloatermarketplacelistings.h
+ llfloatermaturitydialog.h
llfloatermediasettings.h
llfloatermemleak.h
llfloatermodelpreview.h
diff --git a/indra/newview/llfloatermaturitydialog.cpp b/indra/newview/llfloatermaturitydialog.cpp
new file mode 100644
index 0000000000..afa9a70024
--- /dev/null
+++ b/indra/newview/llfloatermaturitydialog.cpp
@@ -0,0 +1,86 @@
+/**
+ * @file llfloatermaturitydialog.cpp
+ * @brief LLFloaterMaturityDialog class implementation
+ *
+ * $LicenseInfo:firstyear=2026&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2026, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatermaturitydialog.h"
+
+#include "llbutton.h"
+#include "llagent.h"
+#include "lltextbox.h"
+#include "llviewercontrol.h"
+#include "llviewerregion.h"
+
+LLFloaterMaturityDialog::LLFloaterMaturityDialog(const LLSD& key)
+ : LLModalDialog(key, true)
+{
+}
+
+bool LLFloaterMaturityDialog::postBuild()
+{
+ setCanDrag(false);
+ getChild<LLButton>("continue_btn")->setCommitCallback(
+ [this](LLUICtrl*, const LLSD&) { onContinue(); });
+ getChild<LLButton>("cancel_btn")->setCommitCallback(
+ [this](LLUICtrl*, const LLSD&) { onCancel(); });
+
+ return true;
+}
+
+void LLFloaterMaturityDialog::onOpen(const LLSD& key)
+{
+ LLModalDialog::onOpen(key);
+
+ mRegionAccess = static_cast<U8>(key.asInteger());
+
+ LLStringUtil::format_map_t args;
+ args["[MATURITY]"] = LLViewerRegion::accessToString(mRegionAccess);
+ getChild<LLTextBox>("location_rated_lbl")->setText(getString("location_rated_string", args));
+ getChild<LLTextBox>("current_maturity_lbl")->setText(getString("update_maturity_string", args));
+ getChild<LLButton>("continue_btn")->setLabel(getString("allow_maturity_string", args));
+
+ centerOnScreen();
+}
+
+void LLFloaterMaturityDialog::draw()
+{
+ // Skip floater shadow/background; icon child provides the visual background
+ LLView::draw();
+}
+
+void LLFloaterMaturityDialog::onContinue()
+{
+ gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(mRegionAccess));
+ gAgent.restartFailedTeleportRequest();
+ closeFloater();
+}
+
+void LLFloaterMaturityDialog::onCancel()
+{
+ gAgent.clearTeleportRequest();
+ closeFloater();
+}
+
diff --git a/indra/newview/llfloatermaturitydialog.h b/indra/newview/llfloatermaturitydialog.h
new file mode 100644
index 0000000000..4ca1a53c2a
--- /dev/null
+++ b/indra/newview/llfloatermaturitydialog.h
@@ -0,0 +1,47 @@
+/**
+ * @file llfloatermaturitydialog.h
+ * @brief LLFloaterMaturityDialog class definition
+ *
+ * $LicenseInfo:firstyear=2026&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2026, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#pragma once
+
+#include "llmodaldialog.h"
+
+class LLFloaterMaturityDialog : public LLModalDialog
+{
+ friend class LLFloaterReg;
+public:
+ bool postBuild() override;
+ void onOpen(const LLSD& key) override;
+ void draw() override;
+
+private:
+ LLFloaterMaturityDialog(const LLSD& key);
+ ~LLFloaterMaturityDialog() = default;
+
+ void onContinue();
+ void onCancel();
+
+ U8 mRegionAccess = SIM_ACCESS_ADULT;
+};
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 54a8b22a5a..0cfbcc06c0 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -101,6 +101,7 @@
#include "llfloatermap.h"
#include "llfloatermarketplace.h"
#include "llfloatermarketplacelistings.h"
+#include "llfloatermaturitydialog.h"
#include "llfloatermediasettings.h"
#include "llfloatermemleak.h"
#include "llfloatermodelpreview.h"
@@ -424,6 +425,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("marketplace", "floater_marketplace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMarketplace>);
LLFloaterReg::add("marketplace_listings", "floater_marketplace_listings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMarketplaceListings>);
LLFloaterReg::add("marketplace_validation", "floater_marketplace_validation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMarketplaceValidation>);
+ LLFloaterReg::add("maturity_dialog", "floater_maturity_dialog.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMaturityDialog>);
LLFloaterReg::add("message_critical", "floater_critical.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
LLFloaterReg::add("message_tos", "floater_tos.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
LLFloaterReg::add("moveview", "floater_moveview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMove>);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 1f76914335..240de962e6 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -4928,10 +4928,12 @@ bool handle_teleport_access_blocked(LLSD& llsdBlock, const std::string & notific
{
U8 regionAccess = static_cast<U8>(llsdBlock["_region_access"].asInteger());
std::string regionMaturity = LLViewerRegion::accessToString(regionAccess);
+ llsdBlock["REGIONMATURITY_CAP"] = regionMaturity;
LLStringUtil::toLower(regionMaturity);
llsdBlock["REGIONMATURITY"] = regionMaturity;
LLNotificationPtr tp_failure_notification;
+ bool skip_notif = false;
std::string notifySuffix;
if (notificationID == std::string("TeleportEntryAccessBlocked"))
@@ -5001,21 +5003,39 @@ bool handle_teleport_access_blocked(LLSD& llsdBlock, const std::string & notific
}
} // End of special handling for "TeleportEntryAccessBlocked"
else
- { // Normal case, no message munging
- gAgent.clearTeleportRequest();
- if (LLNotifications::getInstance()->templateExists(notificationID))
+ {
+ if (notificationID == "RegionTPAccessBlocked")
{
- tp_failure_notification = LLNotificationsUtil::add(notificationID, llsdBlock, llsdBlock);
+ bool can_change_maturity = (regionAccess == SIM_ACCESS_MATURE) ? gAgent.isMature() : gAgent.isAdult();
+ if (can_change_maturity)
+ {
+ LLFloaterReg::showInstance("maturity_dialog", LLSD((S32)regionAccess));
+ skip_notif = true;
+ }
+ else
+ {
+ gAgent.clearTeleportRequest();
+ tp_failure_notification = LLNotificationsUtil::add("RegionTPAccessBlocked_NotifyAdultsOnly", llsdBlock);
+ }
}
else
{
- llsdBlock["MESSAGE"] = defaultMessage;
- tp_failure_notification = LLNotificationsUtil::add("GenericAlertOK", llsdBlock);
+ // Normal case, no message munging
+ gAgent.clearTeleportRequest();
+ if (LLNotifications::getInstance()->templateExists(notificationID))
+ {
+ tp_failure_notification = LLNotificationsUtil::add(notificationID, llsdBlock, llsdBlock);
+ }
+ else
+ {
+ llsdBlock["MESSAGE"] = defaultMessage;
+ tp_failure_notification = LLNotificationsUtil::add("GenericAlertOK", llsdBlock);
+ }
}
returnValue = true;
}
- if ((tp_failure_notification == NULL) || tp_failure_notification->isIgnored())
+ if (((tp_failure_notification == NULL) || tp_failure_notification->isIgnored()) && !skip_notif)
{
// Given a simple notification if no tp_failure_notification is set or it is ignore
LLNotificationsUtil::add(notificationID + notifySuffix, llsdBlock);
diff --git a/indra/newview/skins/default/xui/en/floater_maturity_dialog.xml b/indra/newview/skins/default/xui/en/floater_maturity_dialog.xml
new file mode 100644
index 0000000000..35769534ac
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_maturity_dialog.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater
+ height="185"
+ width="540"
+ layout="topleft"
+ name="floater_maturity_dialog"
+ title="MATURITY"
+ show_title="false"
+ header_height="0"
+ bg_opaque_image="Window_NoTitle_Foreground"
+ bg_alpha_image="Window_NoTitle_Background"
+ can_resize="false"
+ can_drag_on_left="false"
+ can_minimize="false"
+ single_instance="true"
+ can_close="false"
+ background_visible="false">
+ <floater.string
+ name="location_rated_string"
+ value="The location you've chosen is rated [MATURITY]."/>
+ <floater.string
+ name="update_maturity_string"
+ value="Your current maturity preference doesn't include [MATURITY] content. Allowing it will update your preference."/>
+ <floater.string
+ name="allow_maturity_string"
+ value="Allow [MATURITY] content"/>
+ <icon
+ color="FloaterFocusBackgroundColor"
+ follows="left|right|bottom|top"
+ image_name="Rounded_Square"
+ layout="topleft"
+ left="0"
+ top="0"
+ height="185"
+ width="540"/>
+ <text
+ type="string"
+ length="1"
+ follows="top|left|right"
+ font="SansSerifMediumBold"
+ text_color="White"
+ layout="topleft"
+ left="20"
+ height="18"
+ top="20"
+ right="-10"
+ name="location_rated_lbl">
+ The location you've chosen is rated Adult.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left|right"
+ text_color="White"
+ layout="topleft"
+ left="20"
+ height="32"
+ top_pad="10"
+ right="-10"
+ word_wrap="true"
+ name="current_maturity_lbl">
+ Your current maturity preference doesn't include Adult content. Allowing it will update your preference.
+ </text>
+
+ <button
+ follows="top|left"
+ layout="topleft"
+ height="28"
+ label="Allow content"
+ left="20"
+ top_pad="18"
+ name="continue_btn"
+ width="245" />
+
+ <button
+ follows="top|left"
+ layout="topleft"
+ height="28"
+ label="Cancel"
+ left_pad="10"
+ name="cancel_btn"
+ width="245" />
+
+ <text
+ type="string"
+ length="1"
+ follows="top|left|right"
+ text_color="White"
+ link_color="White"
+ layout="topleft"
+ left="20"
+ height="16"
+ top_pad="25"
+ right="-10"
+ parse_urls="true"
+ name="learn_more_lbl">
+[https://lindenlab.freshdesk.com/support/solutions/articles/31000135220-i-can-t-access-adult-land-and-content- Learn more] about maturity ratings.
+ </text>
+
+</floater>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 733734a0d2..51a42f0ce7 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -5691,6 +5691,17 @@ You won't receive any more notifications that you're about to visit a region wit
<notification
icon="alertmodal.tga"
+ name="RegionTPAccessBlocked_NotifyAdultsOnly"
+ type="alertmodal">
+ <tag>fail</tag>
+ The region you are trying to visit is rated [REGIONMATURITY_CAP], which is not available on your account type.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="LandClaimAccessBlocked"
type="alertmodal">
The land you're trying to claim has a maturity rating exceeding your current preferences. You can change your preferences using Me &gt; Preferences &gt; General.