From 850c0c5008bb802eb8dd96fe0aafdad87798d76c Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Sat, 14 Oct 2023 20:45:07 -0400
Subject: [PATCH] Add selective cache clearing floater

---
 indra/llui/llmodaldialog.cpp                  |  11 ++
 indra/newview/CMakeLists.txt                  |   2 +
 indra/newview/app_settings/settings.xml       |  36 ++++-
 indra/newview/llagentlanguage.cpp             |   1 +
 indra/newview/llappviewer.cpp                 |  69 ++++++++-
 indra/newview/llappviewer.h                   |   2 +
 indra/newview/llfloaterclearcache.cpp         | 131 ++++++++++++++++++
 indra/newview/llfloaterclearcache.h           |  54 ++++++++
 indra/newview/llfloaterpreference.cpp         |   6 +-
 indra/newview/llfloatersavecamerapreset.cpp   |   2 +-
 indra/newview/llviewerfloaterreg.cpp          |   2 +
 .../default/xui/en/floater_clear_cache.xml    | 116 ++++++++++++++++
 .../skins/default/xui/en/notifications.xml    |   7 +
 13 files changed, 429 insertions(+), 10 deletions(-)
 create mode 100644 indra/newview/llfloaterclearcache.cpp
 create mode 100644 indra/newview/llfloaterclearcache.h
 create mode 100644 indra/newview/skins/default/xui/en/floater_clear_cache.xml

diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp
index 661ebc64157..d47e51f3c21 100644
--- a/indra/llui/llmodaldialog.cpp
+++ b/indra/llui/llmodaldialog.cpp
@@ -46,6 +46,7 @@ LLModalDialog::LLModalDialog( const LLSD& key, BOOL modal )
 	{
 		setCanMinimize(FALSE);
 		setCanClose(FALSE);
+		setCanCollapse(FALSE);
 	}
 	setVisible( FALSE );
 	setBackgroundVisible(TRUE);
@@ -72,6 +73,16 @@ LLModalDialog::~LLModalDialog()
 // virtual
 BOOL LLModalDialog::postBuild()
 {
+	if (mModal)
+	{
+		setCanMinimize(FALSE);
+		setCanClose(FALSE);
+		setCanCollapse(FALSE);
+	}
+	setVisible(FALSE);
+	setBackgroundVisible(TRUE);
+	setBackgroundOpaque(TRUE);
+	centerOnScreen(); // default position
 	return LLFloater::postBuild();
 }
 
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index cef9ed018c5..caebdc95654 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -245,6 +245,7 @@ set(viewer_SOURCE_FILES
     llfloaterchatalerts.cpp
     llfloaterchatvoicevolume.cpp
     llfloaterclassified.cpp
+    llfloaterclearcache.cpp
     llfloatercolorpicker.cpp
     llfloaterconversationlog.cpp
     llfloaterconversationpreview.cpp
@@ -972,6 +973,7 @@ set(viewer_HEADER_FILES
     llfloaterchatalerts.h
     llfloaterchatvoicevolume.h
     llfloaterclassified.h
+    llfloaterclearcache.h
     llfloatercolorpicker.h
     llfloaterconversationlog.h
     llfloaterconversationpreview.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index c9b5885ed9c..fee9f0e0489 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8895,7 +8895,41 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    <key>PushToTalkButton</key>
+	<key>PurgeWebCacheOnNextStartup</key>
+	<map>
+		<key>Comment</key>
+		<string>Clear web data and cookies next time viewer is run</string>
+		<key>Persist</key>
+		<integer>1</integer>
+		<key>Type</key>
+		<string>Boolean</string>
+		<key>Value</key>
+		<integer>0</integer>
+	</map>
+	<key>PurgeCacheSelective</key>
+	<map>
+		<key>Comment</key>
+		<string>Clear local file cache every time viewer is run</string>
+		<key>Persist</key>
+		<integer>1</integer>
+		<key>Type</key>
+		<string>Boolean</string>
+		<key>Value</key>
+		<integer>0</integer>
+	</map>
+	<key>PurgeCacheSelectiveData</key>
+	<map>
+		<key>Comment</key>
+		<string>Map of caches to clear on next startup.</string>
+		<key>Persist</key>
+		<integer>1</integer>
+		<key>Type</key>
+		<string>LLSD</string>
+		<key>Value</key>
+		<map>
+		</map>
+	</map>
+	<key>PushToTalkButton</key>
     <map>
       <key>Comment</key>
       <string>(Obsolete)Which button or keyboard key is used for push-to-talk</string>
diff --git a/indra/newview/llagentlanguage.cpp b/indra/newview/llagentlanguage.cpp
index cdb0e3302db..5e40ef8f56b 100644
--- a/indra/newview/llagentlanguage.cpp
+++ b/indra/newview/llagentlanguage.cpp
@@ -48,6 +48,7 @@ void LLAgentLanguage::onChange()
 {
 	// Clear inventory cache so that default names of inventory items
 	// appear retranslated (EXT-8308).
+	LL_INFOS() << "Agent language changed" << LL_ENDL;
 	gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE);
 }
 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index eb710629bb5..e43426b2222 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -4074,7 +4074,7 @@ bool LLAppViewer::initCache()
 			gSavedSettings.getBOOL("PurgeCacheOnNextStartup"))
 		{
 			LL_INFOS("AppCache") << "Startup cache purge requested: " << (gSavedSettings.getBOOL("PurgeCacheOnStartup") ? "ALWAYS" : "ONCE") << LL_ENDL;
-			gSavedSettings.setBOOL("PurgeCacheOnNextStartup", false);
+			gSavedSettings.setBOOL("PurgeCacheOnNextStartup", FALSE);
 			mPurgeCache = true;
 			// STORM-1141 force purgeAllTextures to get called to prevent a crash here. -brad
 			texture_cache_mismatch = true;
@@ -4108,6 +4108,11 @@ bool LLAppViewer::initCache()
 			LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
 			purgeCache();
 		}
+
+		if (gSavedSettings.getBool("PurgeCacheSelective"))
+		{
+			purgeCacheSelective(gSavedSettings.getLLSD("PurgeCacheSelectiveData"));
+		}
 	}
 
 	// Init the asset cache
@@ -4184,6 +4189,64 @@ void LLAppViewer::purgeCache()
 
 	LLSplashScreen::update(LLTrans::getString("StartupClearingShaderCache"));
 	LLViewerShaderMgr::instance()->clearShaderCache();
+	purgeWebCache();
+	gDirUtilp->deleteDirAndContents(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "inv_cache"));
+	gDirUtilp->deleteDirAndContents(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "lslpreproc"));
+	gDirUtilp->deleteDirAndContents(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "gridcache"));
+	gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*");
+}
+
+void LLAppViewer::purgeCacheSelective(const LLSD& insd)
+{
+	if(insd.has("textures"))
+	{
+		LL_INFOS("AppCache") << "Purging Texture Cache..." << LL_ENDL;
+		LLSplashScreen::update(LLTrans::getString("StartupClearingTextureCache"));
+		LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE);
+	}
+
+	if (insd.has("assets"))
+	{
+		LL_INFOS("AppCache") << "Purging Disk Cache..." << LL_ENDL;
+		LLSplashScreen::update(LLTrans::getString("StartupClearingDiskCache"));
+		LLDiskCache::getInstance()->clearCache(LL_PATH_CACHE, false);
+	}
+
+	if (insd.has("regions"))
+	{
+		LL_INFOS("AppCache") << "Purging Object Cache..." << LL_ENDL;
+		LLSplashScreen::update(LLTrans::getString("StartupClearingObjectCache"));
+		LLVOCache::getInstance()->removeCache(LL_PATH_CACHE);
+	}
+
+	if (insd.has("inventory"))
+	{
+		LL_INFOS("AppCache") << "Purging Inventory Cache..." << LL_ENDL;
+		gDirUtilp->deleteDirAndContents(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "inv_cache"));
+	}
+
+	if (insd.has("shaders"))
+	{
+		LL_INFOS("AppCache") << "Purging Shader Cache..." << LL_ENDL;
+		LLSplashScreen::update(LLTrans::getString("StartupClearingShaderCache"));
+		LLViewerShaderMgr::instance()->clearShaderCache();
+	}
+
+	if (insd.has("web"))
+	{
+		purgeWebCache();
+	}
+
+	if (insd.has("userdata"))
+	{
+		gDirUtilp->deleteDirAndContents(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "lslpreproc"));
+		gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*.*");
+	}
+}
+
+void LLAppViewer::purgeWebCache()
+{
+	LL_INFOS("AppCache") << "Purging CEF Cache..." << LL_ENDL;
 	std::string browser_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "cef_cache");
 	if (LLFile::isdir(browser_cache))
 	{
@@ -4195,10 +4258,6 @@ void LLAppViewer::purgeCache()
 	{
 		gDirUtilp->deleteDirAndContents(browser_data);
 	}
-	gDirUtilp->deleteDirAndContents(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "inv_cache"));
-	gDirUtilp->deleteDirAndContents(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "lslpreproc"));
-	gDirUtilp->deleteDirAndContents(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "gridcache"));
-	gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*");
 }
 
 //purge cache immediately, do not wait until the next login.
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index b283e3d41b5..9e52c044c36 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -204,6 +204,8 @@ class LLAppViewer : public LLApp
     void initGeneralThread();
 	void purgeUserDataOnExit() { mPurgeUserDataOnExit = true; }
 	void purgeCache(); // Clear the local cache. 
+	void purgeCacheSelective(const LLSD& insd); // Clear the local cache. 
+	void purgeWebCache(); // Clear the local cache. 
 	void purgeCacheImmediate(); //clear local cache immediately.
 	S32  updateTextureThreads(F32 max_time);
 
diff --git a/indra/newview/llfloaterclearcache.cpp b/indra/newview/llfloaterclearcache.cpp
new file mode 100644
index 00000000000..c3aa0391dbc
--- /dev/null
+++ b/indra/newview/llfloaterclearcache.cpp
@@ -0,0 +1,131 @@
+/**
+ * @file llfloaterclearcache.cpp
+ * @brief Floater to save a camera preset
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Alchemy Viewer Source Code
+ * Copyright (C) 2023, Rye Mutt <rye@alchemyviewer.org>
+ *
+ * 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
+ *
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterclearcache.h"
+
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llbutton.h"
+#include "llcombobox.h"
+#include "llfloaterpreference.h"
+#include "llfloaterreg.h"
+#include "lllineeditor.h"
+#include "llnotificationsutil.h"
+#include "llpresetsmanager.h"
+#include "llradiogroup.h"
+#include "lltrans.h"
+#include "llvoavatarself.h"
+
+LLFloaterClearCache::LLFloaterClearCache(const LLSD& key)
+	: LLModalDialog(key)
+{
+}
+
+// virtual
+BOOL LLFloaterClearCache::postBuild()
+{
+	mOkButton = getChild<LLButton>("clear_selected");
+	mOkButton->setCommitCallback(boost::bind(&LLFloaterClearCache::onBtnClearSelected, this));
+
+	getChild<LLCheckBoxCtrl>("clear_textures")->setCommitCallback(boost::bind(&LLFloaterClearCache::refreshButtons, this));
+	getChild<LLCheckBoxCtrl>("clear_assets")->setCommitCallback(boost::bind(&LLFloaterClearCache::refreshButtons, this));
+	getChild<LLCheckBoxCtrl>("clear_inventory")->setCommitCallback(boost::bind(&LLFloaterClearCache::refreshButtons, this));
+	getChild<LLCheckBoxCtrl>("clear_regions")->setCommitCallback(boost::bind(&LLFloaterClearCache::refreshButtons, this));
+	getChild<LLCheckBoxCtrl>("clear_web")->setCommitCallback(boost::bind(&LLFloaterClearCache::refreshButtons, this));
+	getChild<LLCheckBoxCtrl>("clear_userdata")->setCommitCallback(boost::bind(&LLFloaterClearCache::refreshButtons, this));
+
+	getChild<LLButton>("clear_all")->setCommitCallback(boost::bind(&LLFloaterClearCache::onBtnClearAll, this));
+	getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterClearCache::onBtnCancel, this));
+
+	refreshButtons();
+
+	return LLModalDialog::postBuild();
+}
+
+
+void LLFloaterClearCache::onOpen(const LLSD& key)
+{
+	LLModalDialog::onOpen(key);
+}
+
+void LLFloaterClearCache::onBtnClearSelected()
+{
+	LLSD caches;
+	if (getChild<LLCheckBoxCtrl>("clear_textures")->get())
+	{
+		caches.insert("textures", "true");
+	}
+	if (getChild<LLCheckBoxCtrl>("clear_assets")->get())
+	{
+		caches.insert("assets", "true");
+	}
+	if (getChild<LLCheckBoxCtrl>("clear_inventory")->get())
+	{
+		caches.insert("inventory", "true");
+	}
+	if (getChild<LLCheckBoxCtrl>("clear_regions")->get())
+	{
+		caches.insert("regions", "true");
+	}
+	if (getChild<LLCheckBoxCtrl>("clear_web")->get())
+	{
+		caches.insert("web", "true");
+	}
+	if (getChild<LLCheckBoxCtrl>("clear_userdata")->get())
+	{
+		caches.insert("userdata", "true");
+	}
+
+	gSavedSettings.setLLSD("PurgeCacheSelectiveData", caches);
+	gSavedSettings.setBOOL("PurgeCacheSelective", true);
+
+	LLNotificationsUtil::add("CacheWillClear");
+	closeFloater();
+}
+
+void LLFloaterClearCache::onBtnClearAll()
+{
+	gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE);
+	LLNotificationsUtil::add("CacheWillClear");
+	closeFloater();
+}
+
+void LLFloaterClearCache::onBtnCancel()
+{
+	closeFloater();
+}
+
+void LLFloaterClearCache::refreshButtons()
+{
+	mOkButton->setEnabled(getChild<LLCheckBoxCtrl>("clear_textures")->get() ||
+		getChild<LLCheckBoxCtrl>("clear_assets")->get() ||
+		getChild<LLCheckBoxCtrl>("clear_inventory")->get() ||
+		getChild<LLCheckBoxCtrl>("clear_regions")->get() ||
+		getChild<LLCheckBoxCtrl>("clear_web")->get() ||
+		getChild<LLCheckBoxCtrl>("clear_userdata")->get()
+	);
+}
\ No newline at end of file
diff --git a/indra/newview/llfloaterclearcache.h b/indra/newview/llfloaterclearcache.h
new file mode 100644
index 00000000000..774f6c27d3e
--- /dev/null
+++ b/indra/newview/llfloaterclearcache.h
@@ -0,0 +1,54 @@
+/** 
+ * @file llfloaterclearcache.h
+ * @brief Floater to set caches to clear
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Alchemy Viewer Source Code
+ * Copyright (C) 2023, Rye Mutt <rye@alchemyviewer.org>
+ * 
+ * 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
+ *
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERCLEARCACHE_H
+#define LL_LLFLOATERCLEARCACHE_H
+
+#include "llmodaldialog.h"
+
+class LLComboBox;
+class LLRadioGroup;
+class LLLineEditor;
+
+class LLFloaterClearCache final : public LLModalDialog
+{
+
+public:
+	LLFloaterClearCache(const LLSD &key);
+
+	BOOL postBuild() override;
+	void onOpen(const LLSD& key) override;
+
+	void onBtnClearSelected();
+	void onBtnClearAll();
+	void onBtnCancel();
+
+	void refreshButtons();
+
+private:
+	LLButton*		mOkButton = nullptr;
+};
+
+#endif // LL_LLFLOATERCLEARCACHE_H
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 46dc4e961e7..3745c6d4aff 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -232,8 +232,8 @@ bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response
 		LLNavigationBar::getInstance()->clearHistoryCache();
 		
 		// flag client texture cache for clearing next time the client runs
-		gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE);
-		LLNotificationsUtil::add("CacheWillClear");
+		gSavedSettings.setBOOL("PurgeWebCacheOnNextStartup", TRUE);
+		LLNotificationsUtil::add("WebCacheWillClear");
 
 		LLSearchHistory::getInstance()->clearHistory();
 		LLSearchHistory::getInstance()->save();
@@ -1427,7 +1427,7 @@ void LLFloaterPreference::refreshEnabledGraphics()
 
 void LLFloaterPreference::onClickClearCache()
 {
-	LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache);
+	LLFloaterReg::showInstance("clear_cache");
 }
 
 void LLFloaterPreference::onClickBrowserClearCache()
diff --git a/indra/newview/llfloatersavecamerapreset.cpp b/indra/newview/llfloatersavecamerapreset.cpp
index 5704a7a525c..dc86a8c16c3 100644
--- a/indra/newview/llfloatersavecamerapreset.cpp
+++ b/indra/newview/llfloatersavecamerapreset.cpp
@@ -64,7 +64,7 @@ BOOL LLFloaterSaveCameraPreset::postBuild()
 
 	LLPresetsManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterSaveCameraPreset::onPresetsListChange, this));
 
-	return TRUE;
+	return LLModalDialog::postBuild();
 }
 
 void LLFloaterSaveCameraPreset::onPresetNameEdited()
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index c820fed71c6..51ff29d396b 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -75,6 +75,7 @@
 // [/SL:KB]
 #include "llfloaterchatvoicevolume.h"
 #include "llfloaterclassified.h"
+#include "llfloaterclearcache.h"
 #include "llfloaterconversationlog.h"
 #include "llfloaterconversationpreview.h"
 #include "llfloatercreatelandmark.h"
@@ -367,6 +368,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("build_options", "floater_build_options.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBuildOptions>);
 	LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBump>);
 
+	LLFloaterReg::add("clear_cache", "floater_clear_cache.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterClearCache>);
 	LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
 	LLFloaterReg::add("camera_presets", "floater_camera_presets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCameraPresets>);
 // [SL:KB] - Patch: Chat-Alerts | Checked: 2012-07-17 (Catznip-3.3)
diff --git a/indra/newview/skins/default/xui/en/floater_clear_cache.xml b/indra/newview/skins/default/xui/en/floater_clear_cache.xml
new file mode 100644
index 00000000000..9a4983a37dc
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_clear_cache.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<floater
+   height="235"
+   help_topic="floater_clear_cache"
+   layout="topleft"
+   name="clear_cache"
+   title="Clear Cache"
+   width="290">
+   <text
+      type="string"
+      length="1"
+      follows="top|left"
+      layout="topleft"
+      name="region_name"
+      word_wrap="true"
+      left="40"
+      width="230">
+      What cache data do you wish to clear?
+   </text>
+   <check_box
+      height="16"
+      label="Textures"
+      layout="topleft"
+      name="clear_textures"
+      tool_tip="If checked, all texture cache data will be cleared. "
+      width="130"
+      left="50"
+      top_pad="12"
+      value="true" />
+   <check_box
+      height="16"
+      label="Assets (Meshes, Sounds, Animations)"
+      layout="topleft"
+      name="clear_assets"
+      tool_tip="If checked, all asset cache data inlcuding meshes, animations, sounds, and other miscellaneous asset data will be cleared. "
+      width="130"
+      left="50"
+      top_pad="10"
+      value="true" />
+   <check_box
+      height="16"
+      label="Inventory"
+      layout="topleft"
+      name="clear_inventory"
+      tool_tip="If checked, all inventory cache data will be cleared. "
+      width="130"
+      left="50"
+      top_pad="10"
+      value="true" />
+   <check_box
+      height="16"
+      label="Region Objects"
+      layout="topleft"
+      name="clear_regions"
+      tool_tip="If checked, region interest list and object update cache will be cleared. "
+      width="130"
+      left="50"
+      top_pad="10"
+      value="true" />
+   <check_box
+      height="16"
+      label="Shaders"
+      layout="topleft"
+      name="clear_shaders"
+      tool_tip="If checked, precompiled shader cache data will be cleared."
+      width="130"
+      left="50"
+      top_pad="10"
+      value="true" />
+   <check_box
+      height="16"
+      label="Web Data and Cookies"
+      layout="topleft"
+      name="clear_web"
+      tool_tip="If checked, all web browser data will be cleared. "
+      width="130"
+      left="50"
+      top_pad="10"
+      value="true" />
+   <check_box
+      height="16"
+      label="Misc Data"
+      layout="topleft"
+      name="clear_userdata"
+      tool_tip="If checked, all mute list, experience, avatar and group name caches will be cleared. "
+      width="130"
+      left="50"
+      top_pad="10"
+      value="true" />
+   <button
+      enabled="false"
+      follows="top|left"
+      height="25"
+      label="Clear Selected"
+      layout="topleft"
+      top="205"
+      left="5"
+      name="clear_selected"
+      width="90" />
+   <button
+      follows="bottom|right"
+      height="25"
+      label="Clear All"
+      layout="topleft"
+      left_pad="5"
+      name="clear_all"
+      width="90" />
+   <button
+      follows="bottom|right"
+      height="25"
+      label="Cancel"
+      layout="topleft"
+      left_pad="5"
+      name="cancel"
+      width="90" />
+</floater>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 632c617d61d..aa9e74df935 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1637,6 +1637,13 @@ Would you like to disable all popups which can be skipped?
    type="alertmodal">
 Cache will be cleared after you restart [APP_NAME].
   </notification>
+	
+  <notification
+   icon="alertmodal.tga"
+   name="WebCacheWillClear"
+   type="alertmodal">
+Web Browser caches will be cleared after you restart [APP_NAME].
+  </notification>
 
   <notification
    icon="alertmodal.tga"
-- 
GitLab