From d7edeb2df8b225c39727bf506b4e5126852e2d5d Mon Sep 17 00:00:00 2001
From: Kitty Barnett <develop@catznip.com>
Date: Fri, 2 Jun 2017 16:44:00 +0200
Subject: [PATCH] STORM-2149: Add a warning notification when deleting a folder
 of filtered content

---
 doc/contributions.txt                         |  1 +
 indra/llui/llfolderview.cpp                   | 12 +++++++
 indra/llui/llfolderview.h                     | 12 +++++++
 indra/llui/llfolderviewitem.cpp               |  5 +++
 indra/llui/llnotifications.cpp                |  6 ++++
 indra/llui/llnotifications.h                  |  2 ++
 indra/newview/llinventoryfunctions.cpp        | 33 ++++++++++++++-----
 .../skins/default/xui/en/notifications.xml    | 16 +++++++++
 8 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/doc/contributions.txt b/doc/contributions.txt
index e4b24b3abe..1d591e2ec2 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -822,6 +822,7 @@ Kitty Barnett
 	MAINT-6153
 	MAINT-6154
 	MAINT-6568
+	STORM-2149
 Kolor Fall
 Komiko Okamoto
 Korvel Noh
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index f9664e0658..895753aeae 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -102,6 +102,18 @@ void LLCloseAllFoldersFunctor::doFolder(LLFolderViewFolder* folder)
 void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)
 { }
 
+//---------------------------------------------------------------------------
+
+void LLAllDescendentsPassedFilter::doFolder(LLFolderViewFolder* folder)
+{
+	mAllDescendentsPassedFilter &= (folder) && (folder->passedFilter()) && (folder->descendantsPassedFilter());
+}
+
+void LLAllDescendentsPassedFilter::doItem(LLFolderViewItem* item)
+{
+	mAllDescendentsPassedFilter &= (item) && (item->passedFilter());
+}
+
 ///----------------------------------------------------------------------------
 /// Class LLFolderViewScrollContainer
 ///----------------------------------------------------------------------------
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index b5deefd653..2926e160d0 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -400,6 +400,18 @@ public:
 	virtual void doItem(LLFolderViewItem* item);
 };
 
+class LLAllDescendentsPassedFilter : public LLFolderViewFunctor
+{
+public:
+	LLAllDescendentsPassedFilter() : mAllDescendentsPassedFilter(true) {}
+	/*virtual*/ ~LLAllDescendentsPassedFilter() {}
+	/*virtual*/ void doFolder(LLFolderViewFolder* folder);
+	/*virtual*/ void doItem(LLFolderViewItem* item);
+	bool allDescendentsPassedFilter() const { return mAllDescendentsPassedFilter; }
+protected:
+	bool mAllDescendentsPassedFilter;
+};
+
 // Flags for buildContextMenu()
 const U32 SUPPRESS_OPEN_ITEM = 0x1;
 const U32 FIRST_SELECTED_ITEM = 0x2;
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 3d618548c4..0510e472c5 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -1176,6 +1176,11 @@ BOOL LLFolderViewFolder::needsArrange()
 	return mLastArrangeGeneration < getRoot()->getArrangeGeneration();
 }
 
+bool LLFolderViewFolder::descendantsPassedFilter(S32 filter_generation)
+{
+	return getViewModelItem()->descendantsPassedFilter(filter_generation);
+}
+
 // Passes selection information on to children and record selection
 // information if necessary.
 BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem,
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index c364c4d5ae..d40347de13 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1798,6 +1798,12 @@ bool LLNotifications::getIgnoreAllNotifications()
 {
 	return mIgnoreAllNotifications; 
 }
+
+bool LLNotifications::getIgnored(const std::string& name)
+{
+	LLNotificationTemplatePtr templatep = getTemplate(name);
+	return (mIgnoreAllNotifications) || ( (templatep->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO) && (templatep->mForm->getIgnored()) );
+}
 													
 bool LLNotifications::isVisibleByRules(LLNotificationPtr n)
 {
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 4a701d0ca7..a7a5490432 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -964,6 +964,8 @@ public:
 	void setIgnoreAllNotifications(bool ignore);
 	bool getIgnoreAllNotifications();
 
+	bool getIgnored(const std::string& name);
+
 	bool isVisibleByRules(LLNotificationPtr pNotification);
 	
 private:
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 2bb6fb853c..90d6e9b8a8 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -2297,15 +2297,12 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
     
 	if ("delete" == action)
 	{
-		LLSD args;
-		args["QUESTION"] = LLTrans::getString(root->getSelectedCount() > 1 ? "DeleteItems" :  "DeleteItem");
 		static bool sDisplayedAtSession = false;
-		std::set<LLFolderViewItem*>::iterator set_iter = selected_items.begin();
-		LLFolderViewModelItemInventory * viewModel = NULL;
+
 		bool has_folder_items = false;
-		for (; set_iter != selected_items.end(); ++set_iter)
+		for (std::set<LLFolderViewItem*>::iterator set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
 		{
-			viewModel = dynamic_cast<LLFolderViewModelItemInventory *>((*set_iter)->getViewModelItem());
+			LLFolderViewModelItemInventory * viewModel = dynamic_cast<LLFolderViewModelItemInventory *>((*set_iter)->getViewModelItem());
 			if (viewModel && viewModel->hasChildren())
 			{
 				has_folder_items = true;
@@ -2317,16 +2314,34 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
 			bool ignore = !(LLUI::sSettingGroups["ignores"]->getBOOL("DeleteItems"));
 			if (ignore)
 			{
-
 				if (!sDisplayedAtSession)
 				{
 					LLUI::sSettingGroups["ignores"]->setBOOL("DeleteItems", TRUE);
 					sDisplayedAtSession = true;
 				}
-
 			}
 		}
-		LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root->getHandle()));
+		
+		LLAllDescendentsPassedFilter f;
+		for (std::set<LLFolderViewItem*>::iterator it = selected_items.begin(); (it != selected_items.end()) && (f.allDescendentsPassedFilter()); ++it)
+		{
+			if (LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(*it))
+			{
+				folder->applyFunctorRecursively(f);
+			}
+		}
+
+		// Fall through to the generic confirmation if the user choose to ignore the specialized one
+		if ( (!f.allDescendentsPassedFilter()) && (!LLNotifications::instance().getIgnored("DeleteFilteredItems")) )
+		{
+			LLNotificationsUtil::add("DeleteFilteredItems", LLSD(), LLSD(), boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root->getHandle()));
+		}
+		else
+		{
+			LLSD args;
+			args["QUESTION"] = LLTrans::getString(root->getSelectedCount() > 1 ? "DeleteItems" :  "DeleteItem");
+			LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root->getHandle()));
+		}
         // Note: marketplace listings will be updated in the callback if delete confirmed
 		return;
 	}
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 16bf0e344d..97f614cf62 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6010,6 +6010,22 @@ You cannot undo this action.
      notext="Cancel"
      yestext="OK"/>
   </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="DeleteFilteredItems"
+   type="alertmodal">
+    <unique/>
+    Your inventory is currently filtered and not all of the items you're about to delete are currently visible.
+
+Are you sure you want to delete them?
+    <tag>confirm</tag>
+    <usetemplate
+     ignoretext="Confirm before deleting filtered items"
+     name="okcancelignore"
+     notext="Cancel"
+     yestext="OK"/>
+  </notification>
   
   <notification
      icon="alertmodal.tga"
-- 
GitLab