Browse Source

Squashing asset browser filter changes moving to development branch

Signed-off-by: Guthrie Adams <[email protected]>
Guthrie Adams 1 year ago
parent
commit
3d3d959a6c
28 changed files with 669 additions and 663 deletions
  1. 4 2
      Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp
  2. 9 19
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.cpp
  3. 1 2
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h
  4. 4 6
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserTableViewProxyModel.cpp
  5. 1 2
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserTableViewProxyModel.h
  6. 4 5
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserThumbnailViewProxyModel.cpp
  7. 1 1
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserThumbnailViewProxyModel.h
  8. 81 31
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserTreeToTableProxyModel.cpp
  9. 6 2
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetPicker/AssetPickerDialog.cpp
  10. 39 0
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.cpp
  11. 14 0
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.h
  12. 2 7
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntryUtils.cpp
  13. 6 1
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/RootAssetBrowserEntry.cpp
  14. 206 288
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Search/Filter.cpp
  15. 56 50
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Search/Filter.h
  16. 11 19
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserListView.cpp
  17. 141 151
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTableView.cpp
  18. 32 43
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserThumbnailView.cpp
  19. 16 22
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp
  20. 4 4
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/EntryDelegate.cpp
  21. 2 2
      Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/EntryDelegate.h
  22. 1 1
      Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/Model/AssetCompleterModel.cpp
  23. 1 1
      Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/Model/AssetCompleterModel.h
  24. 0 2
      Gems/GraphModel/Code/Include/GraphModel/Model/Slot.h
  25. 1 1
      Gems/GraphModel/Code/Source/Model/Slot.cpp
  26. 10 1
      Gems/LyShine/Code/Editor/AssetTreeEntry.cpp
  27. 1 0
      Gems/LyShine/Code/Editor/AssetTreeEntry.h
  28. 15 0
      README.md

+ 4 - 2
Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp

@@ -116,8 +116,6 @@ AzAssetBrowserWindow::AzAssetBrowserWindow(QWidget* parent)
     AZ_Assert(m_assetBrowserModel, "Failed to get filebrowser model");
     AZ_Assert(m_assetBrowserModel, "Failed to get filebrowser model");
     m_filterModel->setSourceModel(m_assetBrowserModel);
     m_filterModel->setSourceModel(m_assetBrowserModel);
     m_filterModel->SetFilter(m_ui->m_searchWidget->GetFilter());
     m_filterModel->SetFilter(m_ui->m_searchWidget->GetFilter());
-    // Turn off DynamicSort as sorting is now manual.
-    m_filterModel->setDynamicSortFilter(false);
 
 
     m_ui->m_assetBrowserListViewWidget->setVisible(false);
     m_ui->m_assetBrowserListViewWidget->setVisible(false);
     m_ui->m_toolsMenuButton->setVisible(false);
     m_ui->m_toolsMenuButton->setVisible(false);
@@ -523,6 +521,10 @@ void AzAssetBrowserWindow::CreateToolsMenu()
         m_toolsMenu->addAction(openNewAction);
         m_toolsMenu->addAction(openNewAction);
 
 
         m_toolsMenu->addSeparator();
         m_toolsMenu->addSeparator();
+        auto* expandAllAction = new QAction(tr("Expand All"), this);
+        connect(expandAllAction, &QAction::triggered, this, [this] { m_ui->m_assetBrowserTreeViewWidget->expandAll(); });
+        m_toolsMenu->addAction(expandAllAction);
+
         auto* collapseAllAction = new QAction(tr("Collapse All"), this);
         auto* collapseAllAction = new QAction(tr("Collapse All"), this);
         connect(collapseAllAction, &QAction::triggered, this, [this] { m_ui->m_assetBrowserTreeViewWidget->collapseAll(); });
         connect(collapseAllAction, &QAction::triggered, this, [this] { m_ui->m_assetBrowserTreeViewWidget->collapseAll(); });
         m_toolsMenu->addAction(collapseAllAction);
         m_toolsMenu->addAction(collapseAllAction);

+ 9 - 19
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.cpp

@@ -39,6 +39,8 @@ namespace AzToolsFramework
             : QSortFilterProxyModel(parent)
             : QSortFilterProxyModel(parent)
             , m_isTableView(isTableView)
             , m_isTableView(isTableView)
         {
         {
+            setDynamicSortFilter(true);
+            setRecursiveFilteringEnabled(true);
             m_shownColumns.insert(aznumeric_cast<int>(AssetBrowserEntry::Column::DisplayName));
             m_shownColumns.insert(aznumeric_cast<int>(AssetBrowserEntry::Column::DisplayName));
             if (ed_useNewAssetBrowserListView)
             if (ed_useNewAssetBrowserListView)
             {
             {
@@ -107,11 +109,11 @@ namespace AzToolsFramework
             {
             {
                 if (index.column() == aznumeric_cast<int>(AssetBrowserEntry::Column::Name))
                 if (index.column() == aznumeric_cast<int>(AssetBrowserEntry::Column::Name))
                 {
                 {
-                    QString name = static_cast<const SourceAssetBrowserEntry*>(assetBrowserEntry)->GetName().c_str();
-
-                    if (!m_searchString.empty())
+                    const QString name = assetBrowserEntry->GetName().c_str();
+                    if (!m_searchString.isEmpty())
                     {
                     {
-                        name = AzToolsFramework::RichTextHighlighter::HighlightText(name, m_searchString.c_str());
+                        // highlight characters in filter
+                        return AzToolsFramework::RichTextHighlighter::HighlightText(name, m_searchString);
                     }
                     }
                     return name;
                     return name;
                 }
                 }
@@ -132,7 +134,7 @@ namespace AzToolsFramework
 
 
         void AssetBrowserFilterModel::SetSearchString(const QString& searchString)
         void AssetBrowserFilterModel::SetSearchString(const QString& searchString)
         {
         {
-            m_searchString = searchString.toUtf8().data();
+            m_searchString = searchString;
         }
         }
 
 
         bool AssetBrowserFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
         bool AssetBrowserFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
@@ -161,7 +163,7 @@ namespace AzToolsFramework
             {
             {
                 return true;
                 return true;
             }
             }
-            return m_filter->Match(entry);
+            return m_filter->MatchWithoutPropagation(entry);
         }
         }
 
 
         bool AssetBrowserFilterModel::filterAcceptsColumn(int source_column, const QModelIndex&) const
         bool AssetBrowserFilterModel::filterAcceptsColumn(int source_column, const QModelIndex&) const
@@ -194,18 +196,6 @@ namespace AzToolsFramework
             if (compFilter)
             if (compFilter)
             {
             {
                 const auto& subFilters = compFilter->GetSubFilters();
                 const auto& subFilters = compFilter->GetSubFilters();
-                const auto& compFilterIter = AZStd::find_if(subFilters.cbegin(), subFilters.cend(),
-                    [](FilterConstType filter) -> bool
-                    {
-                        const auto assetTypeFilter = qobject_cast<QSharedPointer<const CompositeFilter>>(filter);
-                        return !assetTypeFilter.isNull();
-                    });
-
-                if (compFilterIter != subFilters.end())
-                {
-                    m_assetTypeFilter = qobject_cast<QSharedPointer<const CompositeFilter>>(*compFilterIter);
-                }
-
                 const auto& compositeStringFilterIter = AZStd::find_if(subFilters.cbegin(), subFilters.cend(),
                 const auto& compositeStringFilterIter = AZStd::find_if(subFilters.cbegin(), subFilters.cend(),
                     [](FilterConstType filter) -> bool
                     [](FilterConstType filter) -> bool
                     {
                     {
@@ -246,8 +236,8 @@ namespace AzToolsFramework
                     }
                     }
                 }
                 }
             }
             }
+
             invalidateFilter();
             invalidateFilter();
-            
             Q_EMIT filterChanged();
             Q_EMIT filterChanged();
         }
         }
 
 

+ 1 - 2
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h

@@ -84,7 +84,6 @@ namespace AzToolsFramework
             FilterConstType m_filter;
             FilterConstType m_filter;
             AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: class '...' needs to have dll-interface to be used by clients of class '...'
             AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: class '...' needs to have dll-interface to be used by clients of class '...'
             QSharedPointer<const StringFilter> m_stringFilter;
             QSharedPointer<const StringFilter> m_stringFilter;
-            QWeakPointer<const CompositeFilter> m_assetTypeFilter;
             QCollator m_collator;  // cache the collator as its somewhat expensive to constantly create and destroy one.
             QCollator m_collator;  // cache the collator as its somewhat expensive to constantly create and destroy one.
             AZ_POP_DISABLE_WARNING
             AZ_POP_DISABLE_WARNING
             bool m_invalidateFilter = false;
             bool m_invalidateFilter = false;
@@ -93,7 +92,7 @@ namespace AzToolsFramework
             AssetBrowserEntry::AssetEntrySortMode m_sortMode = AssetBrowserEntry::AssetEntrySortMode::Name;
             AssetBrowserEntry::AssetEntrySortMode m_sortMode = AssetBrowserEntry::AssetEntrySortMode::Name;
             Qt::SortOrder m_sortOrder = Qt::DescendingOrder;
             Qt::SortOrder m_sortOrder = Qt::DescendingOrder;
  
  
-            AZStd::string m_searchString = "";
+            QString m_searchString;
         };
         };
     } // namespace AssetBrowser
     } // namespace AssetBrowser
 } // namespace AzToolsFramework
 } // namespace AzToolsFramework

+ 4 - 6
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserTableViewProxyModel.cpp

@@ -42,12 +42,11 @@ namespace AzToolsFramework
                     {
                     {
                     case Name:
                     case Name:
                         {
                         {
-                            QString name = static_cast<const SourceAssetBrowserEntry*>(assetBrowserEntry)->GetName().c_str();
-
-                            if (!m_searchString.empty())
+                            const QString name = assetBrowserEntry->GetName().c_str();
+                            if (!m_searchString.isEmpty())
                             {
                             {
                                 // highlight characters in filter
                                 // highlight characters in filter
-                                name = AzToolsFramework::RichTextHighlighter::HighlightText(name, m_searchString.c_str());
+                                return AzToolsFramework::RichTextHighlighter::HighlightText(name, m_searchString);
                             }
                             }
                             return name;
                             return name;
                         }
                         }
@@ -183,7 +182,6 @@ namespace AzToolsFramework
             }
             }
         }
         }
         
         
-
         bool AssetBrowserTableViewProxyModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent)
         bool AssetBrowserTableViewProxyModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent)
         {
         {
             if (action == Qt::IgnoreAction)
             if (action == Qt::IgnoreAction)
@@ -244,7 +242,7 @@ namespace AzToolsFramework
 
 
         void AssetBrowserTableViewProxyModel::SetSearchString(const QString& searchString)
         void AssetBrowserTableViewProxyModel::SetSearchString(const QString& searchString)
         {
         {
-             m_searchString = searchString.toUtf8().data();
+            m_searchString = searchString;
         }
         }
     } // namespace AssetBrowser
     } // namespace AssetBrowser
 } // namespace AzToolsFramework
 } // namespace AzToolsFramework

+ 1 - 2
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserTableViewProxyModel.h

@@ -51,8 +51,7 @@ namespace AzToolsFramework
         private:
         private:
             QPersistentModelIndex m_rootIndex;
             QPersistentModelIndex m_rootIndex;
             bool m_searchResultsMode;
             bool m_searchResultsMode;
-
-            AZStd::string m_searchString = "";
+            QString m_searchString;
         };
         };
     } // namespace AssetBrowser
     } // namespace AssetBrowser
 } // namespace AzToolsFramework
 } // namespace AzToolsFramework

+ 4 - 5
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserThumbnailViewProxyModel.cpp

@@ -43,12 +43,11 @@ namespace AzToolsFramework
             {
             {
             case Qt::DisplayRole:
             case Qt::DisplayRole:
                 {
                 {
-                    QString name = static_cast<const SourceAssetBrowserEntry*>(assetBrowserEntry)->GetName().c_str();
-
-                    if (!m_searchString.empty())
+                    const QString name = assetBrowserEntry->GetName().c_str();
+                    if (!m_searchString.isEmpty())
                     {
                     {
                         // highlight characters in filter
                         // highlight characters in filter
-                        name = AzToolsFramework::RichTextHighlighter::HighlightText(name, m_searchString.c_str());
+                        return AzToolsFramework::RichTextHighlighter::HighlightText(name, m_searchString);
                     }
                     }
                     return name;
                     return name;
                 }
                 }
@@ -128,7 +127,7 @@ namespace AzToolsFramework
 
 
         void AssetBrowserThumbnailViewProxyModel::SetSearchString(const QString& searchString)
         void AssetBrowserThumbnailViewProxyModel::SetSearchString(const QString& searchString)
         {
         {
-            m_searchString = searchString.toUtf8().data();
+            m_searchString = searchString;
         }
         }
 
 
         Qt::DropActions AssetBrowserThumbnailViewProxyModel::supportedDropActions() const
         Qt::DropActions AssetBrowserThumbnailViewProxyModel::supportedDropActions() const

+ 1 - 1
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserThumbnailViewProxyModel.h

@@ -46,7 +46,7 @@ namespace AzToolsFramework
         private:
         private:
             QPersistentModelIndex m_rootIndex;
             QPersistentModelIndex m_rootIndex;
             bool m_searchResultsMode;
             bool m_searchResultsMode;
-            AZStd::string m_searchString;
+            QString m_searchString;
         };
         };
     } // namespace AssetBrowser
     } // namespace AssetBrowser
 } // namespace AzToolsFramework
 } // namespace AzToolsFramework

+ 81 - 31
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserTreeToTableProxyModel.cpp

@@ -5,9 +5,10 @@
  * SPDX-License-Identifier: Apache-2.0 OR MIT
  * SPDX-License-Identifier: Apache-2.0 OR MIT
  *
  *
  */
  */
-#include <AzToolsFramework/AssetBrowser/AssetBrowserTreeToTableProxyModel.h>
-#include <AzCore/std/functional.h>
+
 #include <AzCore/Debug/Trace.h>
 #include <AzCore/Debug/Trace.h>
+#include <AzCore/std/functional.h>
+#include <AzToolsFramework/AssetBrowser/AssetBrowserTreeToTableProxyModel.h>
 
 
 namespace AzToolsFramework
 namespace AzToolsFramework
 {
 {
@@ -105,86 +106,128 @@ namespace AzToolsFramework
         {
         {
             beginResetModel();
             beginResetModel();
 
 
-            if (sourceModel())
+            auto sourceModelPtr = sourceModel();
+            if (sourceModelPtr)
             {
             {
-                disconnect(sourceModel(), nullptr, this, nullptr);
+                disconnect(sourceModelPtr, nullptr, this, nullptr);
             }
             }
 
 
             QAbstractProxyModel::setSourceModel(model);
             QAbstractProxyModel::setSourceModel(model);
             if (model)
             if (model)
             {
             {
-                connect(model, &QAbstractItemModel::rowsAboutToBeInserted, this,
+                connect(
+                    model,
+                    &QAbstractItemModel::rowsAboutToBeInserted,
+                    this,
                     [this](const QModelIndex& parent, int start, int end)
                     [this](const QModelIndex& parent, int start, int end)
                     {
                     {
                         RowsAboutToBeInserted(parent, start, end);
                         RowsAboutToBeInserted(parent, start, end);
                     });
                     });
 
 
-                connect(model, &QAbstractItemModel::rowsInserted, this,
+                connect(
+                    model,
+                    &QAbstractItemModel::rowsInserted,
+                    this,
                     [this](const QModelIndex& parent, int start, int end)
                     [this](const QModelIndex& parent, int start, int end)
                     {
                     {
                         RowsInserted(parent, start, end);
                         RowsInserted(parent, start, end);
                     });
                     });
 
 
-                connect(model, &QAbstractItemModel::rowsAboutToBeRemoved, this,
+                connect(
+                    model,
+                    &QAbstractItemModel::rowsAboutToBeRemoved,
+                    this,
                     [this](const QModelIndex& parent, int start, int end)
                     [this](const QModelIndex& parent, int start, int end)
                     {
                     {
                         RowsAboutToBeRemoved(parent, start, end);
                         RowsAboutToBeRemoved(parent, start, end);
                     });
                     });
 
 
-                connect(model, &QAbstractItemModel::rowsRemoved, this,
+                connect(
+                    model,
+                    &QAbstractItemModel::rowsRemoved,
+                    this,
                     [this](const QModelIndex& parent, int start)
                     [this](const QModelIndex& parent, int start)
                     {
                     {
                         RowsRemoved(parent, start);
                         RowsRemoved(parent, start);
                     });
                     });
 
 
-                connect(model, &QAbstractItemModel::rowsAboutToBeMoved, this,
+                connect(
+                    model,
+                    &QAbstractItemModel::rowsAboutToBeMoved,
+                    this,
                     [this]()
                     [this]()
                     {
                     {
                         LayoutChanged();
                         LayoutChanged();
                     });
                     });
 
 
-                connect(model, &QAbstractItemModel::rowsMoved, this,
-                    [this](const QModelIndex& srcParent, int srcStart, [[maybe_unused]]int srcEnd, const QModelIndex& destParent, int destStart)
+                connect(
+                    model,
+                    &QAbstractItemModel::rowsMoved,
+                    this,
+                    [this](
+                        const QModelIndex& srcParent,
+                        int srcStart,
+                        [[maybe_unused]] int srcEnd,
+                        const QModelIndex& destParent,
+                        int destStart)
                     {
                     {
                         RowsMoved(srcParent, srcStart, destParent, destStart);
                         RowsMoved(srcParent, srcStart, destParent, destStart);
                     });
                     });
 
 
-                connect(model, &QAbstractItemModel::modelAboutToBeReset, this,
+                connect(
+                    model,
+                    &QAbstractItemModel::modelAboutToBeReset,
+                    this,
                     [this]()
                     [this]()
                     {
                     {
                         beginResetModel();
                         beginResetModel();
                     });
                     });
 
 
-                connect(model, &QAbstractItemModel::modelReset, this,
+                connect(
+                    model,
+                    &QAbstractItemModel::modelReset,
+                    this,
                     [this]()
                     [this]()
                     {
                     {
                         ModelReset();
                         ModelReset();
                     });
                     });
 
 
-                connect(model, &QAbstractItemModel::dataChanged, this,
+                connect(
+                    model,
+                    &QAbstractItemModel::dataChanged,
+                    this,
                     [this](const QModelIndex& topLeft, const QModelIndex& bottomRight)
                     [this](const QModelIndex& topLeft, const QModelIndex& bottomRight)
                     {
                     {
                         DataChanged(topLeft, bottomRight);
                         DataChanged(topLeft, bottomRight);
                     });
                     });
 
 
-                connect(model, &QAbstractItemModel::layoutAboutToBeChanged, this,
+                connect(
+                    model,
+                    &QAbstractItemModel::layoutAboutToBeChanged,
+                    this,
                     [this]()
                     [this]()
                     {
                     {
                         LayoutAboutToBeChanged();
                         LayoutAboutToBeChanged();
                     });
                     });
 
 
-                connect(model, &QAbstractItemModel::layoutChanged, this,
+                connect(
+                    model,
+                    &QAbstractItemModel::layoutChanged,
+                    this,
                     [this]()
                     [this]()
                     {
                     {
                         LayoutChanged();
                         LayoutChanged();
                     });
                     });
 
 
-                connect(model, &QObject::destroyed, this,
+                connect(
+                    model,
+                    &QObject::destroyed,
+                    this,
                     [this]()
                     [this]()
                     {
                     {
                         resetInternalData();
                         resetInternalData();
                     });
                     });
-             }
+            }
 
 
             resetInternalData();
             resetInternalData();
             if (model && model->hasChildren())
             if (model && model->hasChildren())
@@ -196,12 +239,13 @@ namespace AzToolsFramework
 
 
         QVariant AssetBrowserTreeToTableProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
         QVariant AssetBrowserTreeToTableProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
         {
         {
-            if (!sourceModel() || columnCount() <= section)
+            auto sourceModelPtr = sourceModel();
+            if (!sourceModelPtr || columnCount() <= section)
             {
             {
                 return QVariant();
                 return QVariant();
             }
             }
 
 
-            return sourceModel()->headerData(section, orientation, role);
+            return sourceModelPtr->headerData(section, orientation, role);
         }
         }
 
 
         QModelIndex AssetBrowserTreeToTableProxyModel::parent([[maybe_unused]] const QModelIndex& index) const
         QModelIndex AssetBrowserTreeToTableProxyModel::parent([[maybe_unused]] const QModelIndex& index) const
@@ -367,12 +411,13 @@ namespace AzToolsFramework
 
 
         int AssetBrowserTreeToTableProxyModel::columnCount(const QModelIndex& parent) const
         int AssetBrowserTreeToTableProxyModel::columnCount(const QModelIndex& parent) const
         {
         {
-            if (parent.isValid() || !sourceModel())
+            auto sourceModelPtr = sourceModel();
+            if (parent.isValid() || !sourceModelPtr)
             {
             {
                 return 0;
                 return 0;
             }
             }
 
 
-            return sourceModel()->columnCount();
+            return sourceModelPtr->columnCount();
         }
         }
 
 
         void AssetBrowserTreeToTableProxyModel::UpdateInternalIndices(int start, int offset)
         void AssetBrowserTreeToTableProxyModel::UpdateInternalIndices(int start, int offset)
@@ -385,7 +430,7 @@ namespace AzToolsFramework
             {
             {
                 updates.insert(it.key() + offset, *it);
                 updates.insert(it.key() + offset, *it);
             }
             }
-              
+
             const QHash<int, QPersistentModelIndex>::const_iterator end2 = updates.constEnd();
             const QHash<int, QPersistentModelIndex>::const_iterator end2 = updates.constEnd();
 
 
             for (QHash<int, QPersistentModelIndex>::const_iterator it = updates.constBegin(); it != end2; ++it)
             for (QHash<int, QPersistentModelIndex>::const_iterator it = updates.constBegin(); it != end2; ++it)
@@ -712,7 +757,8 @@ namespace AzToolsFramework
 
 
         QModelIndex AssetBrowserTreeToTableProxyModel::mapFromSource(const QModelIndex& sourceIndex) const
         QModelIndex AssetBrowserTreeToTableProxyModel::mapFromSource(const QModelIndex& sourceIndex) const
         {
         {
-            if (!sourceModel())
+            auto sourceModelPtr = sourceModel();
+            if (!sourceModelPtr)
             {
             {
                 return QModelIndex();
                 return QModelIndex();
             }
             }
@@ -770,7 +816,8 @@ namespace AzToolsFramework
 
 
         QModelIndex AssetBrowserTreeToTableProxyModel::mapToSource(const QModelIndex& proxyIndex) const
         QModelIndex AssetBrowserTreeToTableProxyModel::mapToSource(const QModelIndex& proxyIndex) const
         {
         {
-            if (m_map.Empty() || !proxyIndex.isValid() || !sourceModel())
+            auto sourceModelPtr = sourceModel();
+            if (m_map.Empty() || !proxyIndex.isValid() || !sourceModelPtr)
             {
             {
                 return QModelIndex();
                 return QModelIndex();
             }
             }
@@ -814,23 +861,25 @@ namespace AzToolsFramework
 
 
         Qt::ItemFlags AssetBrowserTreeToTableProxyModel::flags(const QModelIndex& index) const
         Qt::ItemFlags AssetBrowserTreeToTableProxyModel::flags(const QModelIndex& index) const
         {
         {
-            if (!index.isValid() || !sourceModel())
+            auto sourceModelPtr = sourceModel();
+            if (!index.isValid() || !sourceModelPtr)
             {
             {
                 return QAbstractProxyModel::flags(index);
                 return QAbstractProxyModel::flags(index);
             }
             }
 
 
             const QModelIndex srcIndex = mapToSource(index);
             const QModelIndex srcIndex = mapToSource(index);
-            return sourceModel()->flags(srcIndex);
+            return sourceModelPtr->flags(srcIndex);
         }
         }
 
 
         int AssetBrowserTreeToTableProxyModel::rowCount(const QModelIndex& parent) const
         int AssetBrowserTreeToTableProxyModel::rowCount(const QModelIndex& parent) const
         {
         {
-            if (m_parents.contains(parent) || parent.isValid() || !sourceModel())
+            auto sourceModelPtr = sourceModel();
+            if (m_parents.contains(parent) || parent.isValid() || !sourceModelPtr)
             {
             {
                 return 0;
                 return 0;
             }
             }
 
 
-            if (m_map.Empty() && sourceModel()->hasChildren())
+            if (m_map.Empty() && sourceModelPtr->hasChildren())
             {
             {
                 const_cast<AssetBrowserTreeToTableProxyModel*>(this)->RefreshMap();
                 const_cast<AssetBrowserTreeToTableProxyModel*>(this)->RefreshMap();
             }
             }
@@ -839,14 +888,15 @@ namespace AzToolsFramework
 
 
         QVariant AssetBrowserTreeToTableProxyModel::data(const QModelIndex& index, int role) const
         QVariant AssetBrowserTreeToTableProxyModel::data(const QModelIndex& index, int role) const
         {
         {
-            if (!sourceModel())
+            auto sourceModelPtr = sourceModel();
+            if (!sourceModelPtr)
             {
             {
                 return QVariant();
                 return QVariant();
             }
             }
 
 
             if (!index.isValid())
             if (!index.isValid())
             {
             {
-                return sourceModel()->data(index, role);
+                return sourceModelPtr->data(index, role);
             }
             }
 
 
             QModelIndex sourceIndex = mapToSource(index);
             QModelIndex sourceIndex = mapToSource(index);

+ 6 - 2
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetPicker/AssetPickerDialog.cpp

@@ -267,14 +267,18 @@ namespace AzToolsFramework
 
 
             m_selection.GetResults().clear();
             m_selection.GetResults().clear();
 
 
+            AZStd::unordered_set<const AssetBrowserEntry*> entries;
             for (auto entry : selectedAssets)
             for (auto entry : selectedAssets)
             {
             {
-                m_selection.GetSelectionFilter()->Filter(m_selection.GetResults(), entry);
-                if (m_selection.IsValid() && !m_selection.GetMultiselect())
+                m_selection.GetSelectionFilter()->Filter(entries, entry);
+
+                if (!entries.empty() && !m_selection.GetMultiselect())
                 {
                 {
                     break;
                     break;
                 }
                 }
             }
             }
+
+            m_selection.GetResults().assign(entries.begin(), entries.end());
             return m_selection.IsValid();
             return m_selection.IsValid();
         }
         }
 
 

+ 39 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.cpp

@@ -170,6 +170,16 @@ namespace AzToolsFramework
             return m_name;
             return m_name;
         }
         }
 
 
+        const AZ::u32 AssetBrowserEntry::GetGroupNameCrc() const
+        {
+            return m_groupNameCrc;
+        }
+
+        const QString& AssetBrowserEntry::GetGroupName() const
+        {
+            return m_groupName;
+        }
+
         const QString& AssetBrowserEntry::GetDisplayName() const
         const QString& AssetBrowserEntry::GetDisplayName() const
         {
         {
             return m_displayName;
             return m_displayName;
@@ -314,6 +324,35 @@ namespace AzToolsFramework
             }
             }
         }
         }
 
 
+        void AssetBrowserEntry::VisitUp(const AZStd::function<bool(const AssetBrowserEntry*)>& visitorFn) const
+        {
+            if (!visitorFn)
+            {
+                return;
+            }
+
+            for (auto entry = this; entry && entry->GetEntryType() != AssetEntryType::Root; entry = entry->GetParent())
+            {
+                if (!visitorFn(entry))
+                {
+                    return;
+                }
+            }
+        }
+
+        void AssetBrowserEntry::VisitDown(const AZStd::function<bool(const AssetBrowserEntry*)>& visitorFn) const
+        {
+            if (!visitorFn || !visitorFn(this))
+            {
+                return;
+            }
+
+            for (auto child : m_children)
+            {
+                child->VisitDown(visitorFn);
+            }
+        }
+
         const AssetBrowserEntry* AssetBrowserEntry::GetChild(int index) const
         const AssetBrowserEntry* AssetBrowserEntry::GetChild(int index) const
         {
         {
             if (index < m_children.size())
             if (index < m_children.size())

+ 14 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.h

@@ -112,6 +112,10 @@ namespace AzToolsFramework
 
 
             //! Actual name of the asset or folder
             //! Actual name of the asset or folder
             const AZStd::string& GetName() const;
             const AZStd::string& GetName() const;
+            //! Group name provided by asset type info
+            const AZ::u32 GetGroupNameCrc() const;
+            //! Group name provided by asset type info
+            const QString& GetGroupName() const;
             //! Display name represents how entry is shown in asset browser
             //! Display name represents how entry is shown in asset browser
             const QString& GetDisplayName() const;
             const QString& GetDisplayName() const;
 
 
@@ -137,6 +141,14 @@ namespace AzToolsFramework
             const QString& GetEntryTypeAsString() const;
             const QString& GetEntryTypeAsString() const;
             static const AZStd::string ExtensionToType(AZStd::string_view str);
             static const AZStd::string ExtensionToType(AZStd::string_view str);
 
 
+            //! Call the visitor function for the current entry and all of its parents.
+            //! Returning false from the visitor function stops recursion.
+            void VisitUp(const AZStd::function<bool(const AssetBrowserEntry*)>& visitorFn) const;
+
+            //! Recursively call the visitor function for the current entry and all of its children.
+            //! Returning false from the visitor function stops recursion.
+            void VisitDown(const AZStd::function<bool(const AssetBrowserEntry*)>& visitorFn) const;
+
             //! Get immediate children of specific type
             //! Get immediate children of specific type
             template<typename EntryType>
             template<typename EntryType>
             void GetChildren(AZStd::vector<const EntryType*>& entries) const;
             void GetChildren(AZStd::vector<const EntryType*>& entries) const;
@@ -170,6 +182,8 @@ namespace AzToolsFramework
 
 
         protected:
         protected:
             AZStd::string m_name;
             AZStd::string m_name;
+            AZ::u32 m_groupNameCrc{ 0 };
+            QString m_groupName;
             QString m_displayName;
             QString m_displayName;
             QString m_displayPath;
             QString m_displayPath;
             QString m_entryType;
             QString m_entryType;

+ 2 - 7
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntryUtils.cpp

@@ -95,12 +95,7 @@ namespace AzToolsFramework
 
 
                 for (const AssetBrowserEntry* entry : entries)
                 for (const AssetBrowserEntry* entry : entries)
                 {
                 {
-                    if (!entry)
-                    {
-                        continue;
-                    }
-
-                    if (alreadyAdded.find(entry) != alreadyAdded.end())
+                    if (!entry || alreadyAdded.contains(entry))
                     {
                     {
                         continue;
                         continue;
                     }
                     }
@@ -130,7 +125,7 @@ namespace AzToolsFramework
                     if (target)
                     if (target)
                     {
                     {
                         anyFound = true;
                         anyFound = true;
-                        if (alreadyAdded.find(target) == alreadyAdded.end())
+                        if (!alreadyAdded.contains(target))
                         {
                         {
                             entries.push_back(target);
                             entries.push_back(target);
                             alreadyAdded.insert(target);
                             alreadyAdded.insert(target);

+ 6 - 1
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/RootAssetBrowserEntry.cpp

@@ -337,8 +337,13 @@ namespace AzToolsFramework
             product->m_visiblePath = cleanedRelative;
             product->m_visiblePath = cleanedRelative;
             product->SetFullPath((AZ::IO::Path("@products@") / cleanedRelative).LexicallyNormal());
             product->SetFullPath((AZ::IO::Path("@products@") / cleanedRelative).LexicallyNormal());
 
 
+            AZStd::string assetGroupName;
+            AZ::AssetTypeInfoBus::EventResult(
+                assetGroupName, productWithUuidDatabaseEntry.second.m_assetType, &AZ::AssetTypeInfo::GetGroup);
+            product->m_groupName = AzToQtUtf8String(assetGroupName);
+            product->m_groupNameCrc = AZ::Crc32(assetGroupName);
+
             // compute the display data from the above data.
             // compute the display data from the above data.
-            // does someone have information about a more friendly name for this type?
             AZStd::string assetTypeName;
             AZStd::string assetTypeName;
             AZ::AssetTypeInfoBus::EventResult(
             AZ::AssetTypeInfoBus::EventResult(
                 assetTypeName, productWithUuidDatabaseEntry.second.m_assetType, &AZ::AssetTypeInfo::GetAssetTypeDisplayName);
                 assetTypeName, productWithUuidDatabaseEntry.second.m_assetType, &AZ::AssetTypeInfo::GetAssetTypeDisplayName);

+ 206 - 288
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Search/Filter.cpp

@@ -7,14 +7,12 @@
  */
  */
 
 
 #include <AzCore/Asset/AssetTypeInfoBus.h>
 #include <AzCore/Asset/AssetTypeInfoBus.h>
-
 #include <AzFramework/StringFunc/StringFunc.h>
 #include <AzFramework/StringFunc/StringFunc.h>
-
-#include <AzToolsFramework/AssetBrowser/Search/Filter.h>
-#include <AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.h>
-#include <AzToolsFramework/AssetBrowser/Entries/ProductAssetBrowserEntry.h>
 #include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
 #include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
 #include <AzToolsFramework/AssetBrowser/EBusFindAssetTypeByName.h>
 #include <AzToolsFramework/AssetBrowser/EBusFindAssetTypeByName.h>
+#include <AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.h>
+#include <AzToolsFramework/AssetBrowser/Entries/ProductAssetBrowserEntry.h>
+#include <AzToolsFramework/AssetBrowser/Search/Filter.h>
 
 
 namespace AzToolsFramework
 namespace AzToolsFramework
 {
 {
@@ -22,109 +20,76 @@ namespace AzToolsFramework
     {
     {
         namespace
         namespace
         {
         {
-            bool StringMatch(const QString& searched, const QString& text)
+            inline bool StringMatch(const QString& searched, const QString& text)
             {
             {
                 return text.contains(searched, Qt::CaseInsensitive);
                 return text.contains(searched, Qt::CaseInsensitive);
             }
             }
 
 
-            //! Intersect operation between two sets which then overwrites result
-            void Intersect(AZStd::vector<const AssetBrowserEntry*>& result, AZStd::vector<const AssetBrowserEntry*>& set)
+            //! Expand all entries that are either parent or child relationship to the entry and write to result
+            void Expand(AZStd::unordered_set<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry)
             {
             {
-                // inefficient, but sets are tiny so probably not worth the optimization effort
-                AZStd::vector<const AssetBrowserEntry*> intersection;
-                for (auto entry : result)
-                {
-                    if (AZStd::find(set.begin(), set.end(), entry) != set.end())
+                entry->VisitUp(
+                    [&](const auto& currentEntry)
                     {
                     {
-                        intersection.push_back(entry);
-                    }
-                }
-                result = intersection;
-            }
-
-            //! Insert an entry if it doesn't already exist
-            void Join(AZStd::vector<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry)
-            {
-                if (AZStd::find(result.begin(), result.end(), entry) == result.end())
-                {
-                    result.push_back(entry);
-                }
-            }
-
-            //! Join operation between two sets which then overwrites result
-            void Join(AZStd::vector<const AssetBrowserEntry*>& result, AZStd::vector<const AssetBrowserEntry*>& set)
-            {
-                AZStd::vector<const AssetBrowserEntry*> unionResult;
-                for (auto entry : set)
-                {
-                    Join(result, entry);
-                }
-            }
-
-            //! Expand all children recursively and write to result
-            void ExpandDown(AZStd::vector<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry)
-            {
-                Join(result, entry);
-                AZStd::vector<const AssetBrowserEntry*> children;
-                entry->GetChildren<AssetBrowserEntry>(children);
-                for (auto child : children)
-                {
-                    ExpandDown(result, child);
-                }
-            }
+                        result.insert(currentEntry);
+                        return true;
+                    });
 
 
-            //! Expand all entries that are either parent or child relationship to the entry and write to result
-            void Expand(AZStd::vector<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry)
-            {
-                auto parent = entry->GetParent();
-                while (parent && parent->GetEntryType() != AssetBrowserEntry::AssetEntryType::Root)
-                {
-                    Join(result, parent);
-                    parent = parent->GetParent();
-                }
-                ExpandDown(result, entry);
+                entry->VisitDown(
+                    [&](const auto& currentEntry)
+                    {
+                        result.reserve(result.size() + currentEntry->GetChildCount() + 1);
+                        result.insert(currentEntry);
+                        return true;
+                    });
             }
             }
         }
         }
 
 
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         // AssetBrowserEntryFilter
         // AssetBrowserEntryFilter
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
-        AssetBrowserEntryFilter::AssetBrowserEntryFilter()
-            : m_direction(None)
-        {
-        }
-
         bool AssetBrowserEntryFilter::Match(const AssetBrowserEntry* entry) const
         bool AssetBrowserEntryFilter::Match(const AssetBrowserEntry* entry) const
         {
         {
-            if (MatchInternal(entry))
+            if (m_direction == None)
             {
             {
-                return true;
+                if (MatchInternal(entry))
+                {
+                    return true;
+                }
             }
             }
 
 
             if (m_direction & Up)
             if (m_direction & Up)
             {
             {
-                auto parent = entry->GetParent();
-                while (parent && parent->GetEntryType() != AssetBrowserEntry::AssetEntryType::Root)
-                {
-                    if (MatchInternal(parent))
+                bool result = false;
+                entry->VisitUp(
+                    [&result, this](const auto& currentEntry)
                     {
                     {
-                        return true;
-                    }
-                    parent = parent->GetParent();
+                        result = result || MatchInternal(currentEntry);
+                        return !result;
+                    });
+
+                if (result)
+                {
+                    return true;
                 }
                 }
             }
             }
+
             if (m_direction & Down)
             if (m_direction & Down)
             {
             {
-                AZStd::vector<const AssetBrowserEntry*> children;
-                entry->GetChildren<AssetBrowserEntry>(children);
-                for (auto child : children)
-                {
-                    if (MatchDown(child))
+                bool result = false;
+                entry->VisitDown(
+                    [&](const auto& currentEntry)
                     {
                     {
-                        return true;
-                    }
+                        result = result || MatchInternal(currentEntry);
+                        return !result;
+                    });
+
+                if (result)
+                {
+                    return true;
                 }
                 }
             }
             }
+
             return false;
             return false;
         }
         }
 
 
@@ -133,27 +98,43 @@ namespace AzToolsFramework
             return MatchInternal(entry);
             return MatchInternal(entry);
         }
         }
 
 
-        void AssetBrowserEntryFilter::Filter(AZStd::vector<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry) const
+        void AssetBrowserEntryFilter::Filter(AZStd::unordered_set<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry) const
         {
         {
-            FilterInternal(result, entry);
-
-            if (m_direction & Up)
+            if (m_direction == None)
             {
             {
-                auto parent = entry->GetParent();
-                while (parent && parent->GetEntryType() != AssetBrowserEntry::AssetEntryType::Root)
+                if (MatchInternal(entry))
                 {
                 {
-                    FilterInternal(result, parent);
-                    parent = parent->GetParent();
+                    Expand(result, entry);
+                    return;
                 }
                 }
             }
             }
+
+            if (m_direction & Up)
+            {
+                entry->VisitUp(
+                    [&result, this](const auto& currentEntry)
+                    {
+                        if (MatchInternal(currentEntry))
+                        {
+                            Expand(result, currentEntry);
+                            return false;
+                        }
+                        return true;
+                    });
+            }
+
             if (m_direction & Down)
             if (m_direction & Down)
             {
             {
-                AZStd::vector<const AssetBrowserEntry*> children;
-                entry->GetChildren<AssetBrowserEntry>(children);
-                for (auto child : children)
-                {
-                    FilterDown(result, child);
-                }
+                entry->VisitDown(
+                    [&](const auto& currentEntry)
+                    {
+                        if (MatchInternal(currentEntry))
+                        {
+                            Expand(result, currentEntry);
+                            return false;
+                        }
+                        return true;
+                    });
             }
             }
         }
         }
 
 
@@ -182,51 +163,18 @@ namespace AzToolsFramework
             m_direction = direction;
             m_direction = direction;
         }
         }
 
 
-        void AssetBrowserEntryFilter::FilterInternal(AZStd::vector<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry) const
-        {
-            if (MatchInternal(entry))
-            {
-                Join(result, entry);
-            }
-        }
-
-        bool AssetBrowserEntryFilter::MatchDown(const AssetBrowserEntry* entry) const
-        {
-            if (MatchInternal(entry))
-            {
-                return true;
-            }
-            AZStd::vector<const AssetBrowserEntry*> children;
-            entry->GetChildren<AssetBrowserEntry>(children);
-            for (auto child : children)
-            {
-                if (MatchDown(child))
-                {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        void AssetBrowserEntryFilter::FilterDown(AZStd::vector<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry) const
-        {
-            if (MatchInternal(entry))
-            {
-                Join(result, entry);
-            }
-            AZStd::vector<const AssetBrowserEntry*> children;
-            entry->GetChildren<AssetBrowserEntry>(children);
-            for (auto child : children)
-            {
-                FilterDown(result, child);
-            }
-        }
-
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         // StringFilter
         // StringFilter
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
-        StringFilter::StringFilter()
-            : m_filterString("") {}
+        AssetBrowserEntryFilter* StringFilter::Clone() const
+        {
+            auto clone = new StringFilter();
+            clone->m_name = m_name;
+            clone->m_tag = m_tag;
+            clone->m_direction = m_direction;
+            clone->m_filterString = m_filterString;
+            return clone;
+        }
 
 
         void StringFilter::SetFilterString(const QString& filterString)
         void StringFilter::SetFilterString(const QString& filterString)
         {
         {
@@ -258,6 +206,15 @@ namespace AzToolsFramework
         {
         {
         }
         }
 
 
+        AssetBrowserEntryFilter* CustomFilter::Clone() const
+        {
+            auto clone = new CustomFilter(m_filterFn);
+            clone->m_name = m_name;
+            clone->m_tag = m_tag;
+            clone->m_direction = m_direction;
+            return clone;
+        }
+
         QString CustomFilter::GetNameInternal() const
         QString CustomFilter::GetNameInternal() const
         {
         {
             return "Custom Filter";
             return "Custom Filter";
@@ -265,12 +222,22 @@ namespace AzToolsFramework
 
 
         bool CustomFilter::MatchInternal(const AssetBrowserEntry* entry) const
         bool CustomFilter::MatchInternal(const AssetBrowserEntry* entry) const
         {
         {
-            return m_filterFn && m_filterFn(entry);
+            return !m_filterFn || m_filterFn(entry);
         }
         }
 
 
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         // RegExpFilter
         // RegExpFilter
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
+        AssetBrowserEntryFilter* RegExpFilter::Clone() const
+        {
+            auto clone = new RegExpFilter();
+            clone->m_name = m_name;
+            clone->m_tag = m_tag;
+            clone->m_direction = m_direction;
+            clone->m_filterPattern = m_filterPattern;
+            return clone;
+        }
+
         void RegExpFilter::SetFilterPattern(const QRegExp& filterPattern)
         void RegExpFilter::SetFilterPattern(const QRegExp& filterPattern)
         {
         {
             m_filterPattern = filterPattern;
             m_filterPattern = filterPattern;
@@ -291,8 +258,15 @@ namespace AzToolsFramework
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         // AssetTypeFilter
         // AssetTypeFilter
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
-        AssetTypeFilter::AssetTypeFilter()
-            : m_assetType(AZ::Data::AssetType::CreateNull()) {}
+        AssetBrowserEntryFilter* AssetTypeFilter::Clone() const
+        {
+            auto clone = new AssetTypeFilter();
+            clone->m_name = m_name;
+            clone->m_tag = m_tag;
+            clone->m_direction = m_direction;
+            clone->m_assetType = m_assetType;
+            return clone;
+        }
 
 
         void AssetTypeFilter::SetAssetType(AZ::Data::AssetType assetType)
         void AssetTypeFilter::SetAssetType(AZ::Data::AssetType assetType)
         {
         {
@@ -322,32 +296,36 @@ namespace AzToolsFramework
         bool AssetTypeFilter::MatchInternal(const AssetBrowserEntry* entry) const
         bool AssetTypeFilter::MatchInternal(const AssetBrowserEntry* entry) const
         {
         {
             // this filter only works on products.
             // this filter only works on products.
-            if (entry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Product)
+            const ProductAssetBrowserEntry* product = entry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Product
+                ? static_cast<const ProductAssetBrowserEntry*>(entry)
+                : nullptr;
+            if (!product)
             {
             {
-                if (m_assetType.IsNull())
-                {
-                    return true;
-                }
-
-                if (static_cast<const ProductAssetBrowserEntry*>(entry)->GetAssetType() == m_assetType)
-                {
-                    return true;
-                }
+                return false;
             }
             }
-            return false;
+
+            return m_assetType.IsNull() || (product && product->GetAssetType() == m_assetType);
         }
         }
 
 
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         // AssetGroupFilter
         // AssetGroupFilter
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
-        AssetGroupFilter::AssetGroupFilter()
-            : m_group("All")
+        AssetBrowserEntryFilter* AssetGroupFilter::Clone() const
         {
         {
+            auto clone = new AssetGroupFilter();
+            clone->m_name = m_name;
+            clone->m_tag = m_tag;
+            clone->m_direction = m_direction;
+            clone->SetAssetGroup(m_group);
+            return clone;
         }
         }
 
 
         void AssetGroupFilter::SetAssetGroup(const QString& group)
         void AssetGroupFilter::SetAssetGroup(const QString& group)
         {
         {
             m_group = group;
             m_group = group;
+            m_groupCrc = AZ::Crc32(group.toUtf8().constData());
+            m_groupIsAll = m_group.compare("All", Qt::CaseInsensitive) == 0;
+            m_groupIsOther = m_group.compare("Other", Qt::CaseInsensitive) == 0;
         }
         }
 
 
         const QString& AssetGroupFilter::GetAssetTypeGroup() const
         const QString& AssetGroupFilter::GetAssetTypeGroup() const
@@ -363,27 +341,15 @@ namespace AzToolsFramework
         bool AssetGroupFilter::MatchInternal(const AssetBrowserEntry* entry) const
         bool AssetGroupFilter::MatchInternal(const AssetBrowserEntry* entry) const
         {
         {
             // this filter only works on products.
             // this filter only works on products.
-            if (entry->GetEntryType() != AssetBrowserEntry::AssetEntryType::Product)
+            const ProductAssetBrowserEntry* product = entry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Product
+                ? static_cast<const ProductAssetBrowserEntry*>(entry)
+                : nullptr;
+            if (!product)
             {
             {
                 return false;
                 return false;
             }
             }
 
 
-            if (m_group.compare("All", Qt::CaseInsensitive) == 0)
-            {
-                return true;
-            }
-
-            auto product = static_cast<const ProductAssetBrowserEntry*>(entry);
-
-            QString group;
-            AZ::AssetTypeInfoBus::EventResult(group, product->GetAssetType(), &AZ::AssetTypeInfo::GetGroup);
-
-            if (m_group.compare("Other", Qt::CaseInsensitive) == 0 && group.isEmpty())
-            {
-                return true;
-            }
-
-            return (m_group.compare(group, Qt::CaseInsensitive) == 0);
+            return (m_groupIsAll) || (m_groupIsOther && product->GetGroupName().isEmpty()) || (m_groupCrc == product->GetGroupNameCrc());
         }
         }
 
 
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
@@ -394,6 +360,16 @@ namespace AzToolsFramework
         {
         {
         }
         }
 
 
+        AssetBrowserEntryFilter* EntryTypeFilter::Clone() const
+        {
+            auto clone = new EntryTypeFilter();
+            clone->m_name = m_name;
+            clone->m_tag = m_tag;
+            clone->m_direction = m_direction;
+            clone->m_entryType = m_entryType;
+            return clone;
+        }
+
         void EntryTypeFilter::SetEntryType(AssetBrowserEntry::AssetEntryType entryType)
         void EntryTypeFilter::SetEntryType(AssetBrowserEntry::AssetEntryType entryType)
         {
         {
             m_entryType = entryType;
             m_entryType = entryType;
@@ -419,7 +395,23 @@ namespace AzToolsFramework
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         CompositeFilter::CompositeFilter(LogicOperatorType logicOperator)
         CompositeFilter::CompositeFilter(LogicOperatorType logicOperator)
             : m_logicOperator(logicOperator)
             : m_logicOperator(logicOperator)
-            , m_emptyResult(true) {}
+        {
+        }
+
+        AssetBrowserEntryFilter* CompositeFilter::Clone() const
+        {
+            auto clone = new CompositeFilter();
+            clone->m_name = m_name;
+            clone->m_tag = m_tag;
+            clone->m_direction = m_direction;
+            clone->m_logicOperator = m_logicOperator;
+            clone->m_emptyResult = m_emptyResult;
+            for (const auto& subFilter : m_subFilters)
+            {
+                clone->AddFilter(FilterConstType(subFilter->Clone()));
+            }
+            return clone;
+        }
 
 
         void CompositeFilter::AddFilter(FilterConstType filter)
         void CompositeFilter::AddFilter(FilterConstType filter)
         {
         {
@@ -464,7 +456,7 @@ namespace AzToolsFramework
 
 
         QString CompositeFilter::GetNameInternal() const
         QString CompositeFilter::GetNameInternal() const
         {
         {
-            QString name = "";
+            QString name;
             for (auto it = m_subFilters.begin(); it != m_subFilters.end(); ++it)
             for (auto it = m_subFilters.begin(); it != m_subFilters.end(); ++it)
             {
             {
                 name += (*it)->GetName();
                 name += (*it)->GetName();
@@ -478,7 +470,7 @@ namespace AzToolsFramework
 
 
         bool CompositeFilter::MatchInternal(const AssetBrowserEntry* entry) const
         bool CompositeFilter::MatchInternal(const AssetBrowserEntry* entry) const
         {
         {
-            if (m_subFilters.count() == 0)
+            if (m_subFilters.empty())
             {
             {
                 return m_emptyResult;
                 return m_emptyResult;
             }
             }
@@ -486,124 +478,59 @@ namespace AzToolsFramework
             // AND
             // AND
             if (m_logicOperator == LogicOperatorType::AND)
             if (m_logicOperator == LogicOperatorType::AND)
             {
             {
-                for (auto filter : m_subFilters)
-                {
-                    if (!filter->Match(entry))
-                    {
-                        return false;
-                    }
-                }
-                return true;
-            }
-            // OR
-            for (auto filter : m_subFilters)
-            {
-                if (filter->Match(entry))
-                {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        void CompositeFilter::FilterInternal(AZStd::vector<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry) const
-        {
-            // if no subfilters are present in this composite filter then all relating entries would match
-            if (m_subFilters.isEmpty())
-            {
-                // only if match on empty filter is success
-                if (m_emptyResult)
-                {
-                    Expand(result, entry);
-                }
-                return;
-            }
-
-            // AND
-            if (m_logicOperator == LogicOperatorType::AND)
-            {
-                AZStd::vector<const AssetBrowserEntry*> andResult;
-                bool firstResult = true;
-
-                for (auto filter : m_subFilters)
-                {
-                    if (firstResult)
-                    {
-                        firstResult = false;
-                        filter->Filter(andResult, entry);
-                    }
-                    else
-                    {
-                        AZStd::vector<const AssetBrowserEntry*> set;
-                        filter->Filter(set, entry);
-                        Intersect(andResult, set);
-                    }
-                    if (andResult.empty())
-                    {
-                        break;
-                    }
-                }
-                Join(result, andResult);
+                return AZStd::all_of(m_subFilters.begin(), m_subFilters.end(), [&entry](const auto& filter) {
+                    return filter->Match(entry);
+                });
             }
             }
             // OR
             // OR
-            else
-            {
-                for (auto filter : m_subFilters)
-                {
-                    AZStd::vector<const AssetBrowserEntry*> set;
-                    filter->Filter(set, entry);
-                    Join(result, set);
-                }
-            }
+            return AZStd::any_of(m_subFilters.begin(), m_subFilters.end(), [&entry](const auto& filter) {
+                return filter->Match(entry);
+            });
         }
         }
 
 
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         // InverseFilter
         // InverseFilter
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
-        InverseFilter::InverseFilter() {}
+        AssetBrowserEntryFilter* InverseFilter::Clone() const
+        {
+            auto clone = new InverseFilter();
+            clone->m_name = m_name;
+            clone->m_tag = m_tag;
+            clone->m_direction = m_direction;
+            clone->m_filter = FilterConstType(m_filter->Clone());
+            return clone;
+        }
 
 
         void InverseFilter::SetFilter(FilterConstType filter)
         void InverseFilter::SetFilter(FilterConstType filter)
         {
         {
-            if (m_filter == filter)
+            if (m_filter != filter)
             {
             {
-                return;
+                m_filter = filter;
+                Q_EMIT updatedSignal();
             }
             }
-
-            m_filter = filter;
-            Q_EMIT updatedSignal();
         }
         }
 
 
         QString InverseFilter::GetNameInternal() const
         QString InverseFilter::GetNameInternal() const
         {
         {
-            if (m_filter.isNull())
-            {
-                QString name = tr("NOT");
-            }
-            QString name = tr("NOT (%1)").arg(m_filter->GetName());
-            return name;
+            return m_filter.isNull() ? tr("NOT") : tr("NOT (%1)").arg(m_filter->GetName());
         }
         }
 
 
         bool InverseFilter::MatchInternal(const AssetBrowserEntry* entry) const
         bool InverseFilter::MatchInternal(const AssetBrowserEntry* entry) const
         {
         {
-            if (m_filter.isNull())
-            {
-                return false;
-            }
-            return !m_filter->Match(entry);
-        }
-
-        void InverseFilter::FilterInternal(AZStd::vector<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry) const
-        {
-            if (MatchInternal(entry))
-            {
-                Expand(result, entry);
-            }
+            return m_filter && !m_filter->Match(entry);
         }
         }
 
 
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         // CleanerProductsFilter
         // CleanerProductsFilter
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
-        CleanerProductsFilter::CleanerProductsFilter() {}
+        AssetBrowserEntryFilter* CleanerProductsFilter::Clone() const
+        {
+            auto clone = new CleanerProductsFilter();
+            clone->m_name = m_name;
+            clone->m_tag = m_tag;
+            clone->m_direction = m_direction;
+            return clone;
+        }
 
 
         QString CleanerProductsFilter::GetNameInternal() const
         QString CleanerProductsFilter::GetNameInternal() const
         {
         {
@@ -612,39 +539,30 @@ namespace AzToolsFramework
 
 
         bool CleanerProductsFilter::MatchInternal(const AssetBrowserEntry* entry) const
         bool CleanerProductsFilter::MatchInternal(const AssetBrowserEntry* entry) const
         {
         {
-            auto product = azrtti_cast<const ProductAssetBrowserEntry*>(entry);
+            const ProductAssetBrowserEntry* product = entry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Product
+                ? static_cast<const ProductAssetBrowserEntry*>(entry)
+                : nullptr;
             if (!product)
             if (!product)
             {
             {
                 return true;
                 return true;
             }
             }
-            auto source = product->GetParent();
-            if (!source)
-            {
-                return true;
-            }
-            if (source->GetChildCount() != 1)
-            {
-                return true;
-            }
 
 
-            AZStd::string assetTypeName;
-            AZ::AssetTypeInfoBus::EventResult(assetTypeName, product->GetAssetType(), &AZ::AssetTypeInfo::GetAssetTypeDisplayName);
-            if (!assetTypeName.empty())
+            auto source = product->GetParent();
+            if (!source || source->GetChildCount() != 1)
             {
             {
                 return true;
                 return true;
             }
             }
-            
-            return false;
-        }
 
 
-        void CleanerProductsFilter::FilterInternal(AZStd::vector<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry) const
-        {
-            if (MatchInternal(entry))
-            {
-                Expand(result, entry);
-            }
+            bool result = false;
+            AZ::AssetTypeInfoBus::Event(
+                product->GetAssetType(),
+                [&result](AZ::AssetTypeInfoBus::Events* handler)
+                {
+                    const char* assetTypeName = handler->GetAssetTypeDisplayName();
+                    result = assetTypeName && assetTypeName[0];
+                });
+            return result;
         }
         }
-
     } // namespace AssetBrowser
     } // namespace AssetBrowser
 } // namespace AzToolsFramework
 } // namespace AzToolsFramework
 
 

+ 56 - 50
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Search/Filter.h

@@ -8,16 +8,15 @@
 #pragma once
 #pragma once
 
 
 #if !defined(Q_MOC_RUN)
 #if !defined(Q_MOC_RUN)
+#include <AzCore/Asset/AssetTypeInfoBus.h>
+#include <AzCore/std/algorithm.h>
+#include <AzCore/std/containers/unordered_set.h>
+#include <AzCore/std/containers/vector.h>
 #include <AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.h>
 #include <AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.h>
 
 
 #include <QObject>
 #include <QObject>
-#include <QString>
 #include <QSharedPointer>
 #include <QSharedPointer>
 #include <QString>
 #include <QString>
-
-#include <AzCore/Asset/AssetTypeInfoBus.h>
-#include <AzCore/std/containers/vector.h>
-#include <AzCore/std/algorithm.h>
 #endif
 #endif
 
 
 namespace AzToolsFramework
 namespace AzToolsFramework
@@ -32,8 +31,7 @@ namespace AzToolsFramework
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         //! Filters are used to fascilitate searching asset browser for specific asset
         //! Filters are used to fascilitate searching asset browser for specific asset
         //! They are also used for enforcing selection constraints for asset picking
         //! They are also used for enforcing selection constraints for asset picking
-        class AssetBrowserEntryFilter
-            : public QObject
+        class AssetBrowserEntryFilter : public QObject
         {
         {
             Q_OBJECT
             Q_OBJECT
         public:
         public:
@@ -52,8 +50,12 @@ namespace AzToolsFramework
                 Down    = 0x02
                 Down    = 0x02
             };
             };
 
 
-            AssetBrowserEntryFilter();
-            virtual ~AssetBrowserEntryFilter() =  default;
+            AssetBrowserEntryFilter() = default;
+            ~AssetBrowserEntryFilter() override = default;
+
+            //! Cloning function that must be overridden for certain asset browser views that duplicate and modify incoming filters\
+            //! This should be implemented using a copy constructor, which is currently not possible because inheriting QObject prevents it.
+            virtual AssetBrowserEntryFilter* Clone() const = 0;
 
 
             //! Check if entry matches filter
             //! Check if entry matches filter
             bool Match(const AssetBrowserEntry* entry) const;
             bool Match(const AssetBrowserEntry* entry) const;
@@ -63,7 +65,7 @@ namespace AzToolsFramework
             bool MatchWithoutPropagation(const AssetBrowserEntry* entry) const;
             bool MatchWithoutPropagation(const AssetBrowserEntry* entry) const;
 
 
             //! Retrieve all matching entries that are either entry itself or its parents or children
             //! Retrieve all matching entries that are either entry itself or its parents or children
-            void Filter(AZStd::vector<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry) const;
+            void Filter(AZStd::unordered_set<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry) const;
 
 
             //! Filter name is used to uniquely identify the filter
             //! Filter name is used to uniquely identify the filter
             QString GetName() const;
             QString GetName() const;
@@ -76,39 +78,36 @@ namespace AzToolsFramework
             void SetFilterPropagation(int direction);
             void SetFilterPropagation(int direction);
 
 
         Q_SIGNALS:
         Q_SIGNALS:
-            //! Emitted every time a filter is updated, in case of composite filter, the signal is propagated to the top level filter so only one listener needs to connected
+            //! Emitted every time a filter is updated, in case of composite filter, the signal is propagated to the top level filter so
+            //! only one listener needs to connected
             void updatedSignal() const;
             void updatedSignal() const;
 
 
         protected:
         protected:
             //! Internal name auto generated based on filter type and data
             //! Internal name auto generated based on filter type and data
             virtual QString GetNameInternal() const = 0;
             virtual QString GetNameInternal() const = 0;
+
             //! Internal matching logic overrided by every filter type
             //! Internal matching logic overrided by every filter type
             virtual bool MatchInternal(const AssetBrowserEntry* entry) const = 0;
             virtual bool MatchInternal(const AssetBrowserEntry* entry) const = 0;
-            //! Internal filtering logic overrided by every filter type
-            virtual void FilterInternal(AZStd::vector<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry) const;
 
 
-        private:
+        protected:
             QString m_name;
             QString m_name;
             QString m_tag;
             QString m_tag;
-            int m_direction;
-
-            bool MatchDown(const AssetBrowserEntry* entry) const;
-            void FilterDown(AZStd::vector<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry) const;
+            int m_direction{ None };
         };
         };
 
 
-
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         // StringFilter
         // StringFilter
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         //! StringFilter filters assets based on their name
         //! StringFilter filters assets based on their name
-        class StringFilter
-            : public AssetBrowserEntryFilter
+        class StringFilter : public AssetBrowserEntryFilter
         {
         {
             Q_OBJECT
             Q_OBJECT
         public:
         public:
-            StringFilter();
+            StringFilter() = default;
             ~StringFilter() override = default;
             ~StringFilter() override = default;
 
 
+            AssetBrowserEntryFilter* Clone() const override;
+
             void SetFilterString(const QString& filterString);
             void SetFilterString(const QString& filterString);
             QString GetFilterString() const;
             QString GetFilterString() const;
 
 
@@ -123,7 +122,7 @@ namespace AzToolsFramework
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         // CustomFilter
         // CustomFilter
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
-        //! CustomFilter filters assets based on a custom filter function 
+        //! CustomFilter filters assets based on a custom filter function
         class CustomFilter : public AssetBrowserEntryFilter
         class CustomFilter : public AssetBrowserEntryFilter
         {
         {
             Q_OBJECT
             Q_OBJECT
@@ -131,6 +130,8 @@ namespace AzToolsFramework
             CustomFilter(const AZStd::function<bool(const AssetBrowserEntry*)>& filterFn);
             CustomFilter(const AZStd::function<bool(const AssetBrowserEntry*)>& filterFn);
             ~CustomFilter() override = default;
             ~CustomFilter() override = default;
 
 
+            AssetBrowserEntryFilter* Clone() const override;
+
         protected:
         protected:
             QString GetNameInternal() const override;
             QString GetNameInternal() const override;
             bool MatchInternal(const AssetBrowserEntry* entry) const override;
             bool MatchInternal(const AssetBrowserEntry* entry) const override;
@@ -150,6 +151,8 @@ namespace AzToolsFramework
             RegExpFilter() = default;
             RegExpFilter() = default;
             ~RegExpFilter() override = default;
             ~RegExpFilter() override = default;
 
 
+            AssetBrowserEntryFilter* Clone() const override;
+
             void SetFilterPattern(const QRegExp& filterPattern);
             void SetFilterPattern(const QRegExp& filterPattern);
 
 
         protected:
         protected:
@@ -164,14 +167,15 @@ namespace AzToolsFramework
         // AssetTypeFilter
         // AssetTypeFilter
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         //! AssetTypeFilter filters products based on their asset type
         //! AssetTypeFilter filters products based on their asset type
-        class AssetTypeFilter
-            : public AssetBrowserEntryFilter
+        class AssetTypeFilter : public AssetBrowserEntryFilter
         {
         {
             Q_OBJECT
             Q_OBJECT
         public:
         public:
-            AssetTypeFilter();
+            AssetTypeFilter() = default;
             ~AssetTypeFilter() override = default;
             ~AssetTypeFilter() override = default;
 
 
+            AssetBrowserEntryFilter* Clone() const override;
+
             void SetAssetType(AZ::Data::AssetType assetType);
             void SetAssetType(AZ::Data::AssetType assetType);
             void SetAssetType(const char* assetTypeName);
             void SetAssetType(const char* assetTypeName);
             AZ::Data::AssetType GetAssetType() const;
             AZ::Data::AssetType GetAssetType() const;
@@ -181,21 +185,22 @@ namespace AzToolsFramework
             bool MatchInternal(const AssetBrowserEntry* entry) const override;
             bool MatchInternal(const AssetBrowserEntry* entry) const override;
 
 
         private:
         private:
-            AZ::Data::AssetType m_assetType;
+            AZ::Data::AssetType m_assetType{ AZ::Data::AssetType::CreateNull() };
         };
         };
 
 
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         // AssetGroupFilter
         // AssetGroupFilter
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         //! AssetGroupFilter filters products based on their asset group
         //! AssetGroupFilter filters products based on their asset group
-        class AssetGroupFilter
-            : public AssetBrowserEntryFilter
+        class AssetGroupFilter : public AssetBrowserEntryFilter
         {
         {
             Q_OBJECT
             Q_OBJECT
         public:
         public:
-            AssetGroupFilter();
+            AssetGroupFilter() = default;
             ~AssetGroupFilter() override = default;
             ~AssetGroupFilter() override = default;
 
 
+            AssetBrowserEntryFilter* Clone() const override;
+
             void SetAssetGroup(const QString& group);
             void SetAssetGroup(const QString& group);
             const QString& GetAssetTypeGroup() const;
             const QString& GetAssetTypeGroup() const;
 
 
@@ -204,20 +209,24 @@ namespace AzToolsFramework
             bool MatchInternal(const AssetBrowserEntry* entry) const override;
             bool MatchInternal(const AssetBrowserEntry* entry) const override;
 
 
         private:
         private:
-            QString m_group;
+            QString m_group{ "All" };
+            AZ::u32 m_groupCrc{ AZ::Crc32("All") };
+            bool m_groupIsAll{ true };
+            bool m_groupIsOther{ false };
         };
         };
 
 
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         // EntryTypeFilter
         // EntryTypeFilter
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
-        class EntryTypeFilter
-            : public AssetBrowserEntryFilter
+        class EntryTypeFilter : public AssetBrowserEntryFilter
         {
         {
             Q_OBJECT
             Q_OBJECT
         public:
         public:
             EntryTypeFilter();
             EntryTypeFilter();
             ~EntryTypeFilter() override = default;
             ~EntryTypeFilter() override = default;
 
 
+            AssetBrowserEntryFilter* Clone() const override;
+
             void SetEntryType(AssetBrowserEntry::AssetEntryType entryType);
             void SetEntryType(AssetBrowserEntry::AssetEntryType entryType);
             AssetBrowserEntry::AssetEntryType GetEntryType() const;
             AssetBrowserEntry::AssetEntryType GetEntryType() const;
 
 
@@ -237,8 +246,7 @@ namespace AzToolsFramework
             If more complex logic operations required, CompositeFilters can be nested
             If more complex logic operations required, CompositeFilters can be nested
             with different logic operator types
             with different logic operator types
         */
         */
-        class CompositeFilter
-            : public AssetBrowserEntryFilter
+        class CompositeFilter : public AssetBrowserEntryFilter
         {
         {
             Q_OBJECT
             Q_OBJECT
         public:
         public:
@@ -248,9 +256,12 @@ namespace AzToolsFramework
                 AND
                 AND
             };
             };
 
 
+            CompositeFilter() = default;
             explicit CompositeFilter(LogicOperatorType logicOperator);
             explicit CompositeFilter(LogicOperatorType logicOperator);
             ~CompositeFilter() override = default;
             ~CompositeFilter() override = default;
 
 
+            AssetBrowserEntryFilter* Clone() const override;
+
             void AddFilter(FilterConstType filter);
             void AddFilter(FilterConstType filter);
             void RemoveFilter(FilterConstType filter);
             void RemoveFilter(FilterConstType filter);
             void RemoveAllFilters();
             void RemoveAllFilters();
@@ -262,32 +273,31 @@ namespace AzToolsFramework
         protected:
         protected:
             QString GetNameInternal() const override;
             QString GetNameInternal() const override;
             bool MatchInternal(const AssetBrowserEntry* entry) const override;
             bool MatchInternal(const AssetBrowserEntry* entry) const override;
-            void FilterInternal(AZStd::vector<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry) const override;
 
 
         private:
         private:
             QList<FilterConstType> m_subFilters;
             QList<FilterConstType> m_subFilters;
-            LogicOperatorType m_logicOperator;
-            bool m_emptyResult;
+            LogicOperatorType m_logicOperator{ LogicOperatorType::AND };
+            bool m_emptyResult{ true };
         };
         };
 
 
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         // InverseFilter
         // InverseFilter
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         //! Inverse filter negates result of its child filter
         //! Inverse filter negates result of its child filter
-        class InverseFilter
-            : public AssetBrowserEntryFilter
+        class InverseFilter : public AssetBrowserEntryFilter
         {
         {
             Q_OBJECT
             Q_OBJECT
         public:
         public:
-            InverseFilter();
+            InverseFilter() = default;
             ~InverseFilter() override = default;
             ~InverseFilter() override = default;
 
 
+            AssetBrowserEntryFilter* Clone() const override;
+
             void SetFilter(FilterConstType filter);
             void SetFilter(FilterConstType filter);
 
 
         protected:
         protected:
             QString GetNameInternal() const override;
             QString GetNameInternal() const override;
             bool MatchInternal(const AssetBrowserEntry* entry) const override;
             bool MatchInternal(const AssetBrowserEntry* entry) const override;
-            void FilterInternal(AZStd::vector<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry) const override;
 
 
         private:
         private:
             FilterConstType m_filter;
             FilterConstType m_filter;
@@ -297,24 +307,20 @@ namespace AzToolsFramework
         // CleanerProductsFilter
         // CleanerProductsFilter
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         //! Filters out products that shouldn't be shown
         //! Filters out products that shouldn't be shown
-        class CleanerProductsFilter
-            : public AssetBrowserEntryFilter
+        class CleanerProductsFilter : public AssetBrowserEntryFilter
         {
         {
             Q_OBJECT
             Q_OBJECT
         public:
         public:
-            CleanerProductsFilter();
+            CleanerProductsFilter() = default;
             ~CleanerProductsFilter() override = default;
             ~CleanerProductsFilter() override = default;
 
 
+            AssetBrowserEntryFilter* Clone() const override;
+
         protected:
         protected:
             QString GetNameInternal() const override;
             QString GetNameInternal() const override;
             bool MatchInternal(const AssetBrowserEntry* entry) const override;
             bool MatchInternal(const AssetBrowserEntry* entry) const override;
-            void FilterInternal(AZStd::vector<const AssetBrowserEntry*>& result, const AssetBrowserEntry* entry) const override;
-
-        private:
-            FilterConstType m_filter;
         };
         };
 
 
-
         template<class T>
         template<class T>
         struct EBusAggregateUniqueResults
         struct EBusAggregateUniqueResults
         {
         {

+ 11 - 19
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserListView.cpp

@@ -161,28 +161,25 @@ namespace AzToolsFramework
 
 
         void AssetBrowserListView::DeleteEntries()
         void AssetBrowserListView::DeleteEntries()
         {
         {
-            auto entries = GetSelectedAssets(false); // you cannot delete product files.
-
+            const auto& entries = GetSelectedAssets(false); // you cannot delete product files.
             AssetBrowserViewUtils::DeleteEntries(entries, this);
             AssetBrowserViewUtils::DeleteEntries(entries, this);
         }
         }
 
 
         void AssetBrowserListView::MoveEntries()
         void AssetBrowserListView::MoveEntries()
         {
         {
-            auto entries = GetSelectedAssets(false); // you cannot move product files.
-
+            const auto& entries = GetSelectedAssets(false); // you cannot move product files.
             AssetBrowserViewUtils::MoveEntries(entries, this);
             AssetBrowserViewUtils::MoveEntries(entries, this);
         }
         }
 
 
         void AssetBrowserListView::DuplicateEntries()
         void AssetBrowserListView::DuplicateEntries()
         {
         {
-            auto entries = GetSelectedAssets(false); // you may not duplicate product files.
+            const auto& entries = GetSelectedAssets(false); // you may not duplicate product files.
             AssetBrowserViewUtils::DuplicateEntries(entries);
             AssetBrowserViewUtils::DuplicateEntries(entries);
         }
         }
 
 
         void AssetBrowserListView::RenameEntry()
         void AssetBrowserListView::RenameEntry()
         {
         {
-            auto entries = GetSelectedAssets(false); // you cannot rename product files.
-
+            const auto& entries = GetSelectedAssets(false); // you cannot rename product files.
             if (AssetBrowserViewUtils::RenameEntry(entries, this))
             if (AssetBrowserViewUtils::RenameEntry(entries, this))
             {
             {
                 edit(currentIndex());
                 edit(currentIndex());
@@ -191,8 +188,7 @@ namespace AzToolsFramework
 
 
         void AssetBrowserListView::AfterRename(QString newVal)
         void AssetBrowserListView::AfterRename(QString newVal)
         {
         {
-            auto entries = GetSelectedAssets(false); // you cannot rename product files.
-
+            const auto& entries = GetSelectedAssets(false); // you cannot rename product files.
             AssetBrowserViewUtils::AfterRename(newVal, entries, this);
             AssetBrowserViewUtils::AfterRename(newVal, entries, this);
         }
         }
 
 
@@ -211,15 +207,12 @@ namespace AzToolsFramework
             AssetBrowserModel::SourceIndexesToAssetDatabaseEntries(sourceIndexes, entries);
             AssetBrowserModel::SourceIndexesToAssetDatabaseEntries(sourceIndexes, entries);
             if (!includeProducts)
             if (!includeProducts)
             {
             {
-                entries.erase(
-                    AZStd::remove_if(
-                        entries.begin(),
-                        entries.end(),
-                        [&](const AssetBrowserEntry* entry) -> bool
-                        {
-                            return entry->GetEntryType() == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Product;
-                        }),
-                    entries.end());
+                AZStd::erase_if(
+                    entries,
+                    [&](const AssetBrowserEntry* entry) -> bool
+                    {
+                        return entry->GetEntryType() == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Product;
+                    });
             }
             }
 
 
             return entries;
             return entries;
@@ -303,7 +296,6 @@ namespace AzToolsFramework
             header()->setMaximumSectionSize(aznumeric_cast<int>(newWidth * MaxHeaderResizeProportion));
             header()->setMaximumSectionSize(aznumeric_cast<int>(newWidth * MaxHeaderResizeProportion));
         }
         }
 
 
-
         void AssetBrowserListView::OnContextMenu([[maybe_unused]] const QPoint& point)
         void AssetBrowserListView::OnContextMenu([[maybe_unused]] const QPoint& point)
         {
         {
             const auto& selectedAssets = GetSelectedAssets();
             const auto& selectedAssets = GetSelectedAssets();

+ 141 - 151
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTableView.cpp

@@ -5,37 +5,35 @@
  * SPDX-License-Identifier: Apache-2.0 OR MIT
  * SPDX-License-Identifier: Apache-2.0 OR MIT
  *
  *
  */
  */
-#include <AzToolsFramework/AssetBrowser/Views/AssetBrowserTableView.h>
 
 
+#include <AzCore/Utils/Utils.h>
+#include <AzFramework/StringFunc/StringFunc.h>
+#include <AzQtComponents/Components/Widgets/AssetFolderTableView.h>
+#include <AzQtComponents/DragAndDrop/MainWindowDragAndDrop.h>
+#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
 #include <AzToolsFramework/ActionManager/HotKey/HotKeyManagerInterface.h>
 #include <AzToolsFramework/ActionManager/HotKey/HotKeyManagerInterface.h>
+#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
 #include <AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h>
 #include <AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h>
 #include <AzToolsFramework/AssetBrowser/AssetBrowserModel.h>
 #include <AzToolsFramework/AssetBrowser/AssetBrowserModel.h>
 #include <AzToolsFramework/AssetBrowser/AssetBrowserTableViewProxyModel.h>
 #include <AzToolsFramework/AssetBrowser/AssetBrowserTableViewProxyModel.h>
 #include <AzToolsFramework/AssetBrowser/AssetBrowserTreeToTableProxyModel.h>
 #include <AzToolsFramework/AssetBrowser/AssetBrowserTreeToTableProxyModel.h>
 #include <AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.h>
 #include <AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.h>
-#include <AzToolsFramework/AssetBrowser/Entries/SourceAssetBrowserEntry.h>
 #include <AzToolsFramework/AssetBrowser/Entries/ProductAssetBrowserEntry.h>
 #include <AzToolsFramework/AssetBrowser/Entries/ProductAssetBrowserEntry.h>
+#include <AzToolsFramework/AssetBrowser/Entries/SourceAssetBrowserEntry.h>
+#include <AzToolsFramework/AssetBrowser/Views/AssetBrowserTableView.h>
 #include <AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h>
 #include <AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h>
 #include <AzToolsFramework/AssetBrowser/Views/AssetBrowserViewUtils.h>
 #include <AzToolsFramework/AssetBrowser/Views/AssetBrowserViewUtils.h>
-#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
 #include <AzToolsFramework/Editor/ActionManagerIdentifiers/EditorContextIdentifiers.h>
 #include <AzToolsFramework/Editor/ActionManagerIdentifiers/EditorContextIdentifiers.h>
 #include <AzToolsFramework/Editor/ActionManagerUtils.h>
 #include <AzToolsFramework/Editor/ActionManagerUtils.h>
 #include <AzToolsFramework/Editor/RichTextHighlighter.h>
 #include <AzToolsFramework/Editor/RichTextHighlighter.h>
-#include <AzCore/Utils/Utils.h>
-
-#include <AzQtComponents/Components/Widgets/AssetFolderTableView.h>
-#include <AzQtComponents/DragAndDrop/MainWindowDragAndDrop.h>
-
-#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
-#include <AzFramework/StringFunc/StringFunc.h>
 
 
 #if !defined(Q_MOC_RUN)
 #if !defined(Q_MOC_RUN)
-#include <QVBoxLayout>
-#include <QtWidgets/QApplication>
+#include <QApplication>
 #include <QDragMoveEvent>
 #include <QDragMoveEvent>
 #include <QHeaderView>
 #include <QHeaderView>
 #include <QLineEdit>
 #include <QLineEdit>
 #include <QMenu>
 #include <QMenu>
+#include <QVBoxLayout>
 #endif
 #endif
 
 
 namespace AzToolsFramework
 namespace AzToolsFramework
@@ -56,7 +54,6 @@ namespace AzToolsFramework
             // only lists directories, and at the same time get sort and filter entries features from AssetBrowserFilterModel.
             // only lists directories, and at the same time get sort and filter entries features from AssetBrowserFilterModel.
             using namespace AzToolsFramework::AssetBrowser;
             using namespace AzToolsFramework::AssetBrowser;
             AssetBrowserComponentRequestBus::BroadcastResult(m_assetBrowserModel, &AssetBrowserComponentRequests::GetAssetBrowserModel);
             AssetBrowserComponentRequestBus::BroadcastResult(m_assetBrowserModel, &AssetBrowserComponentRequests::GetAssetBrowserModel);
-            m_assetFilterModel->sort(0, Qt::DescendingOrder);
 
 
             m_tableViewProxyModel->setSourceModel(m_assetFilterModel);
             m_tableViewProxyModel->setSourceModel(m_assetFilterModel);
             m_tableViewWidget->setSortingEnabled(false);
             m_tableViewWidget->setSortingEnabled(false);
@@ -70,6 +67,8 @@ namespace AzToolsFramework
                 m_tableViewWidget->header()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
                 m_tableViewWidget->header()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
             }
             }
 
 
+            SetSortMode(AssetBrowserEntry::AssetEntrySortMode::Name);
+
             connect(
             connect(
                 m_tableViewWidget->header(),
                 m_tableViewWidget->header(),
                 &QHeaderView::sortIndicatorChanged,
                 &QHeaderView::sortIndicatorChanged,
@@ -111,14 +110,16 @@ namespace AzToolsFramework
                     emit entryClicked(indexData);
                     emit entryClicked(indexData);
                 });
                 });
 
 
-             connect(
+            connect(
                 m_tableViewWidget,
                 m_tableViewWidget,
-                &AzQtComponents::AssetFolderTableView::rowDeselected, this, []
+                &AzQtComponents::AssetFolderTableView::rowDeselected,
+                this,
+                []
                 {
                 {
                     AssetBrowserPreviewRequestBus::Broadcast(&AssetBrowserPreviewRequest::ClearPreview);
                     AssetBrowserPreviewRequestBus::Broadcast(&AssetBrowserPreviewRequest::ClearPreview);
                 });
                 });
 
 
-             connect(
+            connect(
                 m_tableViewWidget,
                 m_tableViewWidget,
                 &AzQtComponents::AssetFolderTableView::doubleClicked,
                 &AzQtComponents::AssetFolderTableView::doubleClicked,
                 this,
                 this,
@@ -128,82 +129,83 @@ namespace AzToolsFramework
                     emit entryDoubleClicked(indexData);
                     emit entryDoubleClicked(indexData);
                 });
                 });
 
 
-             connect(
-                 m_tableViewWidget,
-                 &AzQtComponents::AssetFolderTableView::customContextMenuRequested,
-                 this,
-                 [this](const QPoint& pos)
-                 {
-                     if (auto index = m_tableViewWidget->indexAt(pos); index.isValid())
-                     {
-                         QMenu menu(this);
-                         AZStd::vector<const AssetBrowserEntry*> entries = GetSelectedAssets();
-                         AssetBrowserInteractionNotificationBus::Broadcast(
-                             &AssetBrowserInteractionNotificationBus::Events::AddContextMenuActions, this, &menu, entries);
-
-                         if (!menu.isEmpty())
-                         {
-                             menu.exec(QCursor::pos());
-                         }
-                     }
-                     else if (!index.isValid() && m_assetTreeView)
-                     {
-                         m_assetTreeView->OnContextMenu(pos);
-                     }
-                 });
-
-              connect(
-                 m_tableViewDelegate,
-                 &TableViewDelegate::renameTableEntry, this,
-                 [this](QString name)
-                 {
-                     AfterRename(name);
-                 });
-
-              AssignWidgetToActionContextHelper(EditorIdentifiers::EditorAssetBrowserActionContextIdentifier, this);
-
-              QAction* deleteAction = new QAction("Delete Action", this);
-              deleteAction->setShortcut(QKeySequence::Delete);
-              deleteAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
-              connect(
-                  deleteAction,
-                  &QAction::triggered,
-                  this,
-                  [this]()
-                  {
-                      DeleteEntries();
-                  });
-              addAction(deleteAction);
-
-              QAction* renameAction = new QAction("Rename Action", this);
-              renameAction->setShortcut(Qt::Key_F2);
-              renameAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
-              connect(
-                  renameAction,
-                  &QAction::triggered,
-                  this,
-                  [this]()
-                  {
-                      RenameEntry();
-                  });
-              addAction(renameAction);
-
-              QAction* duplicateAction = new QAction("Duplicate Action", this);
-              duplicateAction->setShortcut(QKeySequence("Ctrl+D"));
-              duplicateAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
-              connect(
-                  duplicateAction,
-                  &QAction::triggered,
-                  this,
-                  [this]()
-                  {
-                      DuplicateEntries();
-                  });
-              addAction(duplicateAction);
+            connect(
+                m_tableViewWidget,
+                &AzQtComponents::AssetFolderTableView::customContextMenuRequested,
+                this,
+                [this](const QPoint& pos)
+                {
+                    if (auto index = m_tableViewWidget->indexAt(pos); index.isValid())
+                    {
+                        QMenu menu(this);
+                        const auto& entries = GetSelectedAssets();
+                        AssetBrowserInteractionNotificationBus::Broadcast(
+                            &AssetBrowserInteractionNotificationBus::Events::AddContextMenuActions, this, &menu, entries);
+
+                        if (!menu.isEmpty())
+                        {
+                            menu.exec(QCursor::pos());
+                        }
+                    }
+                    else if (!index.isValid() && m_assetTreeView)
+                    {
+                        m_assetTreeView->OnContextMenu(pos);
+                    }
+                });
+
+            connect(
+                m_tableViewDelegate,
+                &TableViewDelegate::renameTableEntry,
+                this,
+                [this](QString name)
+                {
+                    AfterRename(name);
+                });
+
+            AssignWidgetToActionContextHelper(EditorIdentifiers::EditorAssetBrowserActionContextIdentifier, this);
+
+            QAction* deleteAction = new QAction("Delete Action", this);
+            deleteAction->setShortcut(QKeySequence::Delete);
+            deleteAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
+            connect(
+                deleteAction,
+                &QAction::triggered,
+                this,
+                [this]()
+                {
+                    DeleteEntries();
+                });
+            addAction(deleteAction);
+
+            QAction* renameAction = new QAction("Rename Action", this);
+            renameAction->setShortcut(Qt::Key_F2);
+            renameAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
+            connect(
+                renameAction,
+                &QAction::triggered,
+                this,
+                [this]()
+                {
+                    RenameEntry();
+                });
+            addAction(renameAction);
+
+            QAction* duplicateAction = new QAction("Duplicate Action", this);
+            duplicateAction->setShortcut(QKeySequence("Ctrl+D"));
+            duplicateAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
+            connect(
+                duplicateAction,
+                &QAction::triggered,
+                this,
+                [this]()
+                {
+                    DuplicateEntries();
+                });
+            addAction(duplicateAction);
 
 
             connect(
             connect(
                 m_tableViewWidget,
                 m_tableViewWidget,
-                 &AzQtComponents::AssetFolderTableView::showInTableFolderTriggered,
+                &AzQtComponents::AssetFolderTableView::showInTableFolderTriggered,
                 this,
                 this,
                 [this](const QModelIndex& index)
                 [this](const QModelIndex& index)
                 {
                 {
@@ -276,7 +278,7 @@ namespace AzToolsFramework
             return m_tableViewWidget;
             return m_tableViewWidget;
         }
         }
 
 
-         void AssetBrowserTableView::SetName(const QString& name)
+        void AssetBrowserTableView::SetName(const QString& name)
         {
         {
             m_name = name;
             m_name = name;
         }
         }
@@ -308,28 +310,25 @@ namespace AzToolsFramework
 
 
         void AssetBrowserTableView::DeleteEntries()
         void AssetBrowserTableView::DeleteEntries()
         {
         {
-            auto entries = GetSelectedAssets();
-
+            const auto& entries = GetSelectedAssets();
             AssetBrowserViewUtils::DeleteEntries(entries, this);
             AssetBrowserViewUtils::DeleteEntries(entries, this);
         }
         }
 
 
         void AssetBrowserTableView::MoveEntries()
         void AssetBrowserTableView::MoveEntries()
         {
         {
-            auto entries = GetSelectedAssets();
-
+            const auto& entries = GetSelectedAssets();
             AssetBrowserViewUtils::MoveEntries(entries, this);
             AssetBrowserViewUtils::MoveEntries(entries, this);
         }
         }
 
 
         void AssetBrowserTableView::DuplicateEntries()
         void AssetBrowserTableView::DuplicateEntries()
         {
         {
-            auto entries = GetSelectedAssets();
+            const auto& entries = GetSelectedAssets();
             AssetBrowserViewUtils::DuplicateEntries(entries);
             AssetBrowserViewUtils::DuplicateEntries(entries);
         }
         }
 
 
         void AssetBrowserTableView::RenameEntry()
         void AssetBrowserTableView::RenameEntry()
         {
         {
-            auto entries = GetSelectedAssets();
-
+            const auto& entries = GetSelectedAssets();
             if (AssetBrowserViewUtils::RenameEntry(entries, this))
             if (AssetBrowserViewUtils::RenameEntry(entries, this))
             {
             {
                 QModelIndex selectedIndex = m_tableViewWidget->selectionModel()->selectedIndexes()[0];
                 QModelIndex selectedIndex = m_tableViewWidget->selectionModel()->selectedIndexes()[0];
@@ -339,8 +338,7 @@ namespace AzToolsFramework
 
 
         void AssetBrowserTableView::AfterRename(QString newVal)
         void AssetBrowserTableView::AfterRename(QString newVal)
         {
         {
-            auto entries = GetSelectedAssets();
-
+            const auto& entries = GetSelectedAssets();
             AssetBrowserViewUtils::AfterRename(newVal, entries, this);
             AssetBrowserViewUtils::AfterRename(newVal, entries, this);
         }
         }
 
 
@@ -350,8 +348,10 @@ namespace AzToolsFramework
             AZStd::vector<const AssetBrowserEntry*> entries;
             AZStd::vector<const AssetBrowserEntry*> entries;
             if (m_tableViewWidget->selectionModel())
             if (m_tableViewWidget->selectionModel())
             {
             {
-                auto indexes = m_tableViewWidget->selectionModel()->selectedRows();
-                for (const auto index : indexes)
+                const auto& indexes = m_tableViewWidget->selectionModel()->selectedRows();
+                entries.reserve(indexes.size());
+
+                for (const auto& index : indexes)
                 {
                 {
                     const AssetBrowserEntry* item = index.data(AssetBrowserModel::Roles::EntryRole).value<const AssetBrowserEntry*>();
                     const AssetBrowserEntry* item = index.data(AssetBrowserModel::Roles::EntryRole).value<const AssetBrowserEntry*>();
                     if (item)
                     if (item)
@@ -369,7 +369,8 @@ namespace AzToolsFramework
 
 
             if (proxyIndex.isValid())
             if (proxyIndex.isValid())
             {
             {
-                m_tableViewWidget->selectionModel()->select(proxyIndex, QItemSelectionModel::SelectionFlag::ClearAndSelect | QItemSelectionModel::Rows);
+                m_tableViewWidget->selectionModel()->select(
+                    proxyIndex, QItemSelectionModel::SelectionFlag::ClearAndSelect | QItemSelectionModel::Rows);
 
 
                 m_tableViewWidget->scrollTo(proxyIndex, QAbstractItemView::ScrollHint::PositionAtCenter);
                 m_tableViewWidget->scrollTo(proxyIndex, QAbstractItemView::ScrollHint::PositionAtCenter);
 
 
@@ -448,15 +449,13 @@ namespace AzToolsFramework
             }
             }
 
 
             m_assetTreeView = treeView;
             m_assetTreeView = treeView;
-            m_assetTreeView->SetAttachedTableView(this);
-
-            m_assetTreeView->SetAttachedTableView(this);
-
             if (!m_assetTreeView)
             if (!m_assetTreeView)
             {
             {
                 return;
                 return;
             }
             }
 
 
+            m_assetTreeView->SetAttachedTableView(this);
+
             auto treeViewFilterModel = qobject_cast<AssetBrowserFilterModel*>(m_assetTreeView->model());
             auto treeViewFilterModel = qobject_cast<AssetBrowserFilterModel*>(m_assetTreeView->model());
             if (!treeViewFilterModel)
             if (!treeViewFilterModel)
             {
             {
@@ -528,8 +527,8 @@ namespace AzToolsFramework
                 return;
                 return;
             }
             }
 
 
-            auto selectedIndexes = selected.indexes();
-            if (selectedIndexes.count() > 0)
+            const auto& selectedIndexes = selected.indexes();
+            if (!selectedIndexes.empty())
             {
             {
                 auto newRootIndex = m_tableViewProxyModel->mapFromSource(
                 auto newRootIndex = m_tableViewProxyModel->mapFromSource(
                     m_assetFilterModel->mapFromSource(treeViewFilterModel->mapToSource(selectedIndexes[0])));
                     m_assetFilterModel->mapFromSource(treeViewFilterModel->mapToSource(selectedIndexes[0])));
@@ -539,6 +538,8 @@ namespace AzToolsFramework
             {
             {
                 m_tableViewWidget->setRootIndex({});
                 m_tableViewWidget->setRootIndex({});
             }
             }
+
+            m_assetFilterModel->sort(0, Qt::DescendingOrder);
         }
         }
 
 
         void AssetBrowserTableView::UpdateFilterInLocalFilterModel()
         void AssetBrowserTableView::UpdateFilterInLocalFilterModel()
@@ -561,36 +562,33 @@ namespace AzToolsFramework
             }
             }
 
 
             bool hasString{ false };
             bool hasString{ false };
+            const QString tagString("String");
+            const QString tagFolder("Folder");
             auto filterCopy = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
             auto filterCopy = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
-            for (auto& subFilter : filter->GetSubFilters())
+            for (const auto& subFilter : filter->GetSubFilters())
             {
             {
-                // Switch between "search mode" where all results in the asset folder tree are shown,
-                // and "normal mode", where only contents for a single folder are shown, depending on
-                // whether there is an active string search ongoing.
-                if (subFilter->GetTag() == "String")
+                if (subFilter->GetTag() == tagString)
                 {
                 {
                     auto stringCompFilter = qobject_cast<const CompositeFilter*>(subFilter.get());
                     auto stringCompFilter = qobject_cast<const CompositeFilter*>(subFilter.get());
-                    if (!stringCompFilter)
-                    {
-                        continue;
-                    }
-
-                    auto stringSubFilters = stringCompFilter->GetSubFilters();
-
-                    hasString = stringSubFilters.count() != 0;
-                    m_tableViewProxyModel->SetShowSearchResultsMode(hasString);
-                    m_tableViewWidget->SetShowSearchResultsMode(hasString);
+                    hasString |= stringCompFilter && !stringCompFilter->GetSubFilters().empty();
                 }
                 }
 
 
                 // Skip the folder filter on the table view so that we can see files
                 // Skip the folder filter on the table view so that we can see files
-                if (subFilter->GetTag() != "Folder")
+                if (subFilter->GetTag() != tagFolder)
                 {
                 {
-                    filterCopy->AddFilter(subFilter);
+                    filterCopy->AddFilter(FilterConstType(subFilter->Clone()));
                 }
                 }
             }
             }
+
+            // Switch between "search mode" where all results in the asset folder tree are shown,
+            // and "normal mode", where only contents for a single folder are shown, depending on
+            // whether there is an active string search ongoing.
+            m_tableViewProxyModel->SetShowSearchResultsMode(hasString);
+            m_tableViewWidget->SetShowSearchResultsMode(hasString);
+
             if (hasString)
             if (hasString)
             {
             {
-                for (auto& subFilter : filterCopy->GetSubFilters())
+                for (const auto& subFilter : filter->GetSubFilters())
                 {
                 {
                     auto anyCompFilter = qobject_cast<const CompositeFilter*>(subFilter.get());
                     auto anyCompFilter = qobject_cast<const CompositeFilter*>(subFilter.get());
                     if (anyCompFilter)
                     if (anyCompFilter)
@@ -598,19 +596,14 @@ namespace AzToolsFramework
                         auto myCompFilter = const_cast<CompositeFilter*>(anyCompFilter);
                         auto myCompFilter = const_cast<CompositeFilter*>(anyCompFilter);
                         myCompFilter->SetFilterPropagation(AssetBrowserEntryFilter::None);
                         myCompFilter->SetFilterPropagation(AssetBrowserEntryFilter::None);
                     }
                     }
-
                 }
                 }
-                using EntryType = AssetBrowserEntry::AssetEntryType;
-                EntryType types[] = { EntryType::Folder, EntryType::Root, EntryType::Source };
-                auto productFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::OR);
+
+                auto productFilter = new CustomFilter([](const AssetBrowserEntry* entry) {
+                    return entry->GetEntryType() != AssetBrowserEntry::AssetEntryType::Product;
+                });
                 productFilter->SetName("NoProduct");
                 productFilter->SetName("NoProduct");
-                for (auto type : types)
-                {
-                    EntryTypeFilter* entryTypeFilter = new EntryTypeFilter();
-                    entryTypeFilter->SetEntryType(type);
-                    entryTypeFilter->SetFilterPropagation(AssetBrowserEntryFilter::None);
-                    productFilter->AddFilter(FilterConstType(entryTypeFilter));
-                }
+                productFilter->SetFilterPropagation(AssetBrowserEntryFilter::None);
+
                 filterCopy->AddFilter(FilterConstType(productFilter));
                 filterCopy->AddFilter(FilterConstType(productFilter));
                 filterCopy->SetFilterPropagation(AssetBrowserEntryFilter::None);
                 filterCopy->SetFilterPropagation(AssetBrowserEntryFilter::None);
             }
             }
@@ -618,7 +611,9 @@ namespace AzToolsFramework
             {
             {
                 filterCopy->SetFilterPropagation(AssetBrowserEntryFilter::Up | AssetBrowserEntryFilter::Down);
                 filterCopy->SetFilterPropagation(AssetBrowserEntryFilter::Up | AssetBrowserEntryFilter::Down);
             }
             }
+
             m_assetFilterModel->SetFilter(FilterConstType(filterCopy));
             m_assetFilterModel->SetFilter(FilterConstType(filterCopy));
+
             if (hasString)
             if (hasString)
             {
             {
                 m_tableViewWidget->expandAll();
                 m_tableViewWidget->expandAll();
@@ -633,22 +628,19 @@ namespace AzToolsFramework
 
 
         void AssetBrowserTableView::SetSortMode(const AssetBrowserEntry::AssetEntrySortMode mode)
         void AssetBrowserTableView::SetSortMode(const AssetBrowserEntry::AssetEntrySortMode mode)
         {
         {
-            if (mode == m_assetFilterModel->GetSortMode())
+            // If the sort mode is being set to the same value then alternate the sort order
+            if (m_assetFilterModel->GetSortMode() == mode)
             {
             {
-                if (m_assetFilterModel->GetSortOrder() == Qt::DescendingOrder)
-                {
-                    m_assetFilterModel->SetSortOrder(Qt::AscendingOrder);
-                }
-                else
-                {
-                    m_assetFilterModel->SetSortOrder(Qt::DescendingOrder);
-                }
+                m_assetFilterModel->SetSortOrder(
+                    m_assetFilterModel->GetSortOrder() == Qt::DescendingOrder ? Qt::AscendingOrder : Qt::DescendingOrder);
             }
             }
-            m_assetFilterModel->SetSortMode(mode);
 
 
+            m_assetFilterModel->SetSortMode(mode);
             m_assetFilterModel->sort(0, m_assetFilterModel->GetSortOrder());
             m_assetFilterModel->sort(0, m_assetFilterModel->GetSortOrder());
+            m_assetFilterModel->setDynamicSortFilter(true);
 
 
-            m_tableViewWidget->header()->setSortIndicator(SortModeToColumn(m_assetFilterModel->GetSortMode()), m_assetFilterModel->GetSortOrder());
+            m_tableViewWidget->header()->setSortIndicator(
+                SortModeToColumn(m_assetFilterModel->GetSortMode()), m_assetFilterModel->GetSortOrder());
         }
         }
 
 
         AssetBrowserEntry::AssetEntrySortMode AssetBrowserTableView::GetSortMode() const
         AssetBrowserEntry::AssetEntrySortMode AssetBrowserTableView::GetSortMode() const
@@ -663,7 +655,6 @@ namespace AzToolsFramework
 
 
         TableViewDelegate::TableViewDelegate(QWidget* parent)
         TableViewDelegate::TableViewDelegate(QWidget* parent)
             : QStyledItemDelegate(parent)
             : QStyledItemDelegate(parent)
-
         {
         {
         }
         }
 
 
@@ -704,8 +695,7 @@ namespace AzToolsFramework
             }
             }
         }
         }
 
 
-        QWidget* TableViewDelegate::createEditor(
-            QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
+        QWidget* TableViewDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
         {
         {
             QWidget* widget = QStyledItemDelegate::createEditor(parent, option, index);
             QWidget* widget = QStyledItemDelegate::createEditor(parent, option, index);
             if (auto* lineEdit = qobject_cast<QLineEdit*>(widget))
             if (auto* lineEdit = qobject_cast<QLineEdit*>(widget))

+ 32 - 43
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserThumbnailView.cpp

@@ -46,12 +46,9 @@ namespace AzToolsFramework
         {
         {
             // Using our own instance of AssetBrowserFilterModel to be able to show also files when the main model
             // Using our own instance of AssetBrowserFilterModel to be able to show also files when the main model
             // only lists directories, and at the same time get sort and filter entries features from AssetBrowserFilterModel.
             // only lists directories, and at the same time get sort and filter entries features from AssetBrowserFilterModel.
-
-            // Turn off DynamicSort as sorting is now manual.
-            m_assetFilterModel->setDynamicSortFilter(false);
-            m_assetFilterModel->sort(0, Qt::DescendingOrder);
             m_thumbnailViewProxyModel->setSourceModel(m_assetFilterModel);
             m_thumbnailViewProxyModel->setSourceModel(m_assetFilterModel);
             m_thumbnailViewWidget->setModel(m_thumbnailViewProxyModel);
             m_thumbnailViewWidget->setModel(m_thumbnailViewProxyModel);
+            SetSortMode(AssetBrowserEntry::AssetEntrySortMode::Name);
 
 
             connect(
             connect(
                 m_thumbnailViewWidget,
                 m_thumbnailViewWidget,
@@ -101,7 +98,7 @@ namespace AzToolsFramework
                 this,
                 this,
                 [this]()
                 [this]()
                 {
                 {
-                    AZStd::vector<const AssetBrowserEntry*> entries = AZStd::move(GetSelectedAssets());
+                    auto entries = AZStd::move(GetSelectedAssets());
                     if (entries.empty() && m_assetTreeView)
                     if (entries.empty() && m_assetTreeView)
                     {
                     {
                         // Tree has the current open folder selected if context is valid (not searching, etc)
                         // Tree has the current open folder selected if context is valid (not searching, etc)
@@ -245,28 +242,25 @@ namespace AzToolsFramework
 
 
         void AssetBrowserThumbnailView::DeleteEntries()
         void AssetBrowserThumbnailView::DeleteEntries()
         {
         {
-            auto entries = GetSelectedAssets(false); // you cannot delete product files.
-
+            const auto& entries = GetSelectedAssets(false); // you cannot delete product files.
             AssetBrowserViewUtils::DeleteEntries(entries, this);
             AssetBrowserViewUtils::DeleteEntries(entries, this);
         }
         }
 
 
         void AssetBrowserThumbnailView::MoveEntries()
         void AssetBrowserThumbnailView::MoveEntries()
         {
         {
-            auto entries = GetSelectedAssets(false); // you cannot move product files.
-
+            const auto& entries = GetSelectedAssets(false); // you cannot move product files.
             AssetBrowserViewUtils::MoveEntries(entries, this);
             AssetBrowserViewUtils::MoveEntries(entries, this);
         }
         }
 
 
         void AssetBrowserThumbnailView::DuplicateEntries()
         void AssetBrowserThumbnailView::DuplicateEntries()
         {
         {
-            auto entries = GetSelectedAssets(false); // you may not duplicate product files.
+            const auto& entries = GetSelectedAssets(false); // you may not duplicate product files.
             AssetBrowserViewUtils::DuplicateEntries(entries);
             AssetBrowserViewUtils::DuplicateEntries(entries);
         }
         }
 
 
         void AssetBrowserThumbnailView::RenameEntry()
         void AssetBrowserThumbnailView::RenameEntry()
         {
         {
-            auto entries = GetSelectedAssets(false); // you cannot rename product files.
-
+            const auto& entries = GetSelectedAssets(false); // you cannot rename product files.
             if (AssetBrowserViewUtils::RenameEntry(entries, this))
             if (AssetBrowserViewUtils::RenameEntry(entries, this))
             {
             {
                 QModelIndex selectedIndex = m_thumbnailViewWidget->selectionModel()->selectedIndexes()[0];
                 QModelIndex selectedIndex = m_thumbnailViewWidget->selectionModel()->selectedIndexes()[0];
@@ -276,8 +270,7 @@ namespace AzToolsFramework
 
 
         void AssetBrowserThumbnailView::AfterRename(QString newVal)
         void AssetBrowserThumbnailView::AfterRename(QString newVal)
         {
         {
-            auto entries = GetSelectedAssets(false); // you cannot rename product files.
-
+            const auto& entries = GetSelectedAssets(false); // you cannot rename product files.
             AssetBrowserViewUtils::AfterRename(newVal, entries, this);
             AssetBrowserViewUtils::AfterRename(newVal, entries, this);
         }
         }
 
 
@@ -289,16 +282,12 @@ namespace AzToolsFramework
                 AssetBrowserModel::SourceIndexesToAssetDatabaseEntries(m_thumbnailViewWidget->selectionModel()->selectedIndexes(), entries);
                 AssetBrowserModel::SourceIndexesToAssetDatabaseEntries(m_thumbnailViewWidget->selectionModel()->selectedIndexes(), entries);
                 if (!includeProducts)
                 if (!includeProducts)
                 {
                 {
-                    entries.erase(
-                        AZStd::remove_if(
-                            entries.begin(),
-                            entries.end(),
-                            [&](const AssetBrowserEntry* entry) -> bool
-                            {
-                                return entry->GetEntryType() ==
-                                    AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Product;
-                            }),
-                        entries.end());
+                    AZStd::erase_if(
+                        entries,
+                        [&](const AssetBrowserEntry* entry) -> bool
+                        {
+                            return entry->GetEntryType() == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Product;
+                        });
                 }
                 }
             }
             }
             return entries;
             return entries;
@@ -321,13 +310,13 @@ namespace AzToolsFramework
             }
             }
 
 
             m_assetTreeView = treeView;
             m_assetTreeView = treeView;
-            m_assetTreeView->SetAttachedThumbnailView(this);
-
             if (!m_assetTreeView)
             if (!m_assetTreeView)
             {
             {
                 return;
                 return;
             }
             }
 
 
+            m_assetTreeView->SetAttachedThumbnailView(this);
+
             auto treeViewFilterModel = qobject_cast<AssetBrowserFilterModel*>(m_assetTreeView->model());
             auto treeViewFilterModel = qobject_cast<AssetBrowserFilterModel*>(m_assetTreeView->model());
             if (!treeViewFilterModel)
             if (!treeViewFilterModel)
             {
             {
@@ -441,6 +430,8 @@ namespace AzToolsFramework
             {
             {
                 m_thumbnailViewWidget->setRootIndex({});
                 m_thumbnailViewWidget->setRootIndex({});
             }
             }
+
+            m_assetFilterModel->sort(0, Qt::DescendingOrder);
         }
         }
 
 
         void AssetBrowserThumbnailView::OpenItemForEditing(const QModelIndex& index)
         void AssetBrowserThumbnailView::OpenItemForEditing(const QModelIndex& index)
@@ -477,32 +468,31 @@ namespace AzToolsFramework
                 return;
                 return;
             }
             }
 
 
+            bool hasString{ false };
+            const QString tagString("String");
+            const QString tagFolder("Folder");
             auto filterCopy = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
             auto filterCopy = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
             for (const auto& subFilter : filter->GetSubFilters())
             for (const auto& subFilter : filter->GetSubFilters())
             {
             {
-                // Switch between "search mode" where all results in the asset folder tree are shown,
-                // and "normal mode", where only contents for a single folder are shown, depending on
-                // whether there is an active string search ongoing.
-                if (subFilter->GetTag() == "String")
+                if (subFilter->GetTag() == tagString)
                 {
                 {
                     auto stringCompFilter = qobject_cast<const CompositeFilter*>(subFilter.get());
                     auto stringCompFilter = qobject_cast<const CompositeFilter*>(subFilter.get());
-                    if (!stringCompFilter)
-                    {
-                        continue;
-                    }
-
-                    auto stringSubFilters = stringCompFilter->GetSubFilters();
-
-                    m_thumbnailViewProxyModel->SetShowSearchResultsMode(stringSubFilters.count() != 0);
-                    m_thumbnailViewWidget->SetShowSearchResultsMode(stringSubFilters.count() != 0);
+                    hasString |= stringCompFilter && !stringCompFilter->GetSubFilters().empty();
                 }
                 }
 
 
                 // Skip the folder filter on the thumbnail view so that we can see files
                 // Skip the folder filter on the thumbnail view so that we can see files
-                if (subFilter->GetTag() != "Folder")
+                if (subFilter->GetTag() != tagFolder)
                 {
                 {
-                    filterCopy->AddFilter(subFilter);
+                    filterCopy->AddFilter(FilterConstType(subFilter->Clone()));
                 }
                 }
             }
             }
+
+            // Switch between "search mode" where all results in the asset folder tree are shown,
+            // and "normal mode", where only contents for a single folder are shown, depending on
+            // whether there is an active string search ongoing.
+            m_thumbnailViewProxyModel->SetShowSearchResultsMode(hasString);
+            m_thumbnailViewWidget->SetShowSearchResultsMode(hasString);
+
             filterCopy->SetFilterPropagation(AssetBrowserEntryFilter::Down);
             filterCopy->SetFilterPropagation(AssetBrowserEntryFilter::Down);
 
 
             m_assetFilterModel->SetFilter(FilterConstType(filterCopy));
             m_assetFilterModel->SetFilter(FilterConstType(filterCopy));
@@ -511,8 +501,8 @@ namespace AzToolsFramework
         void AssetBrowserThumbnailView::SetSortMode(const AssetBrowserEntry::AssetEntrySortMode mode)
         void AssetBrowserThumbnailView::SetSortMode(const AssetBrowserEntry::AssetEntrySortMode mode)
         {
         {
             m_assetFilterModel->SetSortMode(mode);
             m_assetFilterModel->SetSortMode(mode);
-
             m_assetFilterModel->sort(0, Qt::DescendingOrder);
             m_assetFilterModel->sort(0, Qt::DescendingOrder);
+            m_assetFilterModel->setDynamicSortFilter(true);
         }
         }
 
 
        AssetBrowserEntry::AssetEntrySortMode AssetBrowserThumbnailView::GetSortMode() const
        AssetBrowserEntry::AssetEntrySortMode AssetBrowserThumbnailView::GetSortMode() const
@@ -547,6 +537,5 @@ namespace AzToolsFramework
         {
         {
             m_thumbnailViewProxyModel->SetSearchString(searchString);
             m_thumbnailViewProxyModel->SetSearchString(searchString);
         }
         }
-
     } // namespace AssetBrowser
     } // namespace AssetBrowser
 } // namespace AzToolsFramework
 } // namespace AzToolsFramework

+ 16 - 22
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp

@@ -196,15 +196,12 @@ namespace AzToolsFramework
 
 
             if (!includeProducts)
             if (!includeProducts)
             {
             {
-                entries.erase(
-                    AZStd::remove_if(
-                        entries.begin(),
-                        entries.end(),
-                        [&](const AssetBrowserEntry* entry) -> bool
-                        {
-                            return entry->GetEntryType() == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Product;
-                        }),
-                    entries.end());
+                AZStd::erase_if(
+                    entries,
+                    [&](const AssetBrowserEntry* entry) -> bool
+                    {
+                        return entry->GetEntryType() == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Product;
+                    });
             }
             }
 
 
             return entries;
             return entries;
@@ -222,8 +219,7 @@ namespace AzToolsFramework
         void AssetBrowserTreeView::SelectFileAtPathAfterUpdate(const AZStd::string& assetPath)
         void AssetBrowserTreeView::SelectFileAtPathAfterUpdate(const AZStd::string& assetPath)
         {
         {
             m_fileToSelectAfterUpdate = assetPath;
             m_fileToSelectAfterUpdate = assetPath;
-        }
-        
+        }        
 
 
         void AssetBrowserTreeView::SelectFileAtPath(const AZStd::string& assetPath)
         void AssetBrowserTreeView::SelectFileAtPath(const AZStd::string& assetPath)
         {
         {
@@ -611,6 +607,8 @@ namespace AzToolsFramework
             AZ_Assert(m_assetBrowserSortFilterProxyModel, "Expecting AssetBrowserFilterModel");
             AZ_Assert(m_assetBrowserSortFilterProxyModel, "Expecting AssetBrowserFilterModel");
             m_assetBrowserModel = qobject_cast<AssetBrowserModel*>(m_assetBrowserSortFilterProxyModel->sourceModel());
             m_assetBrowserModel = qobject_cast<AssetBrowserModel*>(m_assetBrowserSortFilterProxyModel->sourceModel());
             QTreeViewWithStateSaving::setModel(model);
             QTreeViewWithStateSaving::setModel(model);
+
+            SetSortMode(AssetBrowserEntry::AssetEntrySortMode::Name);
         }
         }
 
 
         void AssetBrowserTreeView::dragEnterEvent(QDragEnterEvent* event)
         void AssetBrowserTreeView::dragEnterEvent(QDragEnterEvent* event)
@@ -673,7 +671,7 @@ namespace AzToolsFramework
             using namespace AzQtComponents;
             using namespace AzQtComponents;
             DragAndDropContextBase context;
             DragAndDropContextBase context;
             DragAndDropEventsBus::Event(
             DragAndDropEventsBus::Event(
-                DragAndDropContexts::EditorMainWindow, &DragAndDropEvents::DropAtLocation, event, context, QString(pathName.data()));
+                DragAndDropContexts::EditorMainWindow, &DragAndDropEvents::DropAtLocation, event, context, QString(pathName.c_str()));
         }
         }
 
 
         void AssetBrowserTreeView::dragLeaveEvent(QDragLeaveEvent* event)
         void AssetBrowserTreeView::dragLeaveEvent(QDragLeaveEvent* event)
@@ -749,15 +747,13 @@ namespace AzToolsFramework
 
 
         void AssetBrowserTreeView::DeleteEntries()
         void AssetBrowserTreeView::DeleteEntries()
         {
         {
-            auto entries = GetSelectedAssets(false); // you cannot delete product files.
-
+            const auto& entries = GetSelectedAssets(false); // you cannot delete product files.
             AssetBrowserViewUtils::DeleteEntries(entries, this);
             AssetBrowserViewUtils::DeleteEntries(entries, this);
         }
         }
 
 
         void AssetBrowserTreeView::RenameEntry()
         void AssetBrowserTreeView::RenameEntry()
         {
         {
-            auto entries = GetSelectedAssets(false); // you cannot rename product files.
-
+            const auto& entries = GetSelectedAssets(false); // you cannot rename product files.
             if (AssetBrowserViewUtils::RenameEntry(entries, this))
             if (AssetBrowserViewUtils::RenameEntry(entries, this))
             {
             {
                 edit(currentIndex());
                 edit(currentIndex());
@@ -766,21 +762,19 @@ namespace AzToolsFramework
 
 
         void AssetBrowserTreeView::AfterRename(QString newVal)
         void AssetBrowserTreeView::AfterRename(QString newVal)
         {
         {
-            auto entries = GetSelectedAssets(false); // you cannot rename product files.
-
+            const auto& entries = GetSelectedAssets(false); // you cannot rename product files.
             AssetBrowserViewUtils::AfterRename(newVal, entries, this);
             AssetBrowserViewUtils::AfterRename(newVal, entries, this);
         }
         }
 
 
         void AssetBrowserTreeView::DuplicateEntries()
         void AssetBrowserTreeView::DuplicateEntries()
         {
         {
-            auto entries = GetSelectedAssets(false); // you may not duplicate product files.
+            const auto& entries = GetSelectedAssets(false); // you may not duplicate product files.
             AssetBrowserViewUtils::DuplicateEntries(entries);
             AssetBrowserViewUtils::DuplicateEntries(entries);
         }
         }
 
 
         void AssetBrowserTreeView::MoveEntries()
         void AssetBrowserTreeView::MoveEntries()
         {
         {
-            auto entries = GetSelectedAssets(false); // you cannot move product files.
-
+            const auto& entries = GetSelectedAssets(false); // you cannot move product files.
             AssetBrowserViewUtils::MoveEntries(entries, this);
             AssetBrowserViewUtils::MoveEntries(entries, this);
         }
         }
 
 
@@ -825,8 +819,8 @@ namespace AzToolsFramework
         void AssetBrowserTreeView::SetSortMode(const AssetBrowserEntry::AssetEntrySortMode mode)
         void AssetBrowserTreeView::SetSortMode(const AssetBrowserEntry::AssetEntrySortMode mode)
         {
         {
             m_assetBrowserSortFilterProxyModel->SetSortMode(mode);
             m_assetBrowserSortFilterProxyModel->SetSortMode(mode);
-
             m_assetBrowserSortFilterProxyModel->sort(0, Qt::DescendingOrder);
             m_assetBrowserSortFilterProxyModel->sort(0, Qt::DescendingOrder);
+            m_assetBrowserSortFilterProxyModel->setDynamicSortFilter(true);
         }
         }
 
 
         AssetBrowserEntry::AssetEntrySortMode AssetBrowserTreeView::GetSortMode() const
         AssetBrowserEntry::AssetEntrySortMode AssetBrowserTreeView::GetSortMode() const

+ 4 - 4
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/EntryDelegate.cpp

@@ -114,9 +114,9 @@ namespace AzToolsFramework
                 ? qvariant_cast<QString>(entry->data(aznumeric_cast<int>(AssetBrowserEntry::Column::DisplayName)))
                 ? qvariant_cast<QString>(entry->data(aznumeric_cast<int>(AssetBrowserEntry::Column::DisplayName)))
                 : qvariant_cast<QString>(entry->data(aznumeric_cast<int>(AssetBrowserEntry::Column::Path)));
                 : qvariant_cast<QString>(entry->data(aznumeric_cast<int>(AssetBrowserEntry::Column::Path)));
 
 
-            if (!m_searchString.empty())
+            if (!m_searchString.isEmpty())
             {
             {
-                displayString = AzToolsFramework::RichTextHighlighter::HighlightText(displayString, m_searchString.c_str());
+                displayString = AzToolsFramework::RichTextHighlighter::HighlightText(displayString, m_searchString);
             }
             }
 
 
             RichTextHighlighter::PaintHighlightedRichText(displayString, painter, actualOption, remainingRect);
             RichTextHighlighter::PaintHighlightedRichText(displayString, painter, actualOption, remainingRect);
@@ -214,9 +214,9 @@ namespace AzToolsFramework
             return m_iconSize;
             return m_iconSize;
         }
         }
 
 
-        void EntryDelegate::SetSearchString(QString searchString)
+        void EntryDelegate::SetSearchString(const QString& searchString)
         {
         {
-            m_searchString = searchString.toUtf8().data();
+            m_searchString = searchString;
         }
         }
 
 
         SearchEntryDelegate::SearchEntryDelegate(QWidget* parent)
         SearchEntryDelegate::SearchEntryDelegate(QWidget* parent)

+ 2 - 2
Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/EntryDelegate.h

@@ -57,7 +57,7 @@ namespace AzToolsFramework
             //! Set whether to show source control icons, this is still temporary mainly to support existing functionality of material browser
             //! Set whether to show source control icons, this is still temporary mainly to support existing functionality of material browser
             void SetShowSourceControlIcons(bool showSourceControl);
             void SetShowSourceControlIcons(bool showSourceControl);
             void SetShowFavoriteIcons(bool showFavoriteIcons);
             void SetShowFavoriteIcons(bool showFavoriteIcons);
-            void SetSearchString(QString searchString);
+            void SetSearchString(const QString& searchString);
 
 
         signals:
         signals:
             void RenameEntry(const QString& value) const;
             void RenameEntry(const QString& value) const;
@@ -68,7 +68,7 @@ namespace AzToolsFramework
             bool m_showFavoriteIcons = false;
             bool m_showFavoriteIcons = false;
             //! Draw a thumbnail and return its width
             //! Draw a thumbnail and return its width
             int DrawThumbnail(QPainter* painter, const QPoint& point, const QSize& size, const AssetBrowserEntry* entry) const;
             int DrawThumbnail(QPainter* painter, const QPoint& point, const QSize& size, const AssetBrowserEntry* entry) const;
-            AZStd::string m_searchString;
+            QString m_searchString;
         };
         };
 
 
         //! SearchEntryDelegate draws a single item in AssetBrowserListView.
         //! SearchEntryDelegate draws a single item in AssetBrowserListView.

+ 1 - 1
Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/Model/AssetCompleterModel.cpp

@@ -72,7 +72,7 @@ namespace AzToolsFramework
         emit dataChanged(index(0, 0), index(rowCount(), columnCount()));
         emit dataChanged(index(0, 0), index(rowCount(), columnCount()));
     }
     }
 
 
-    void AssetCompleterModel::SearchStringHighlight(QString searchString)
+    void AssetCompleterModel::SearchStringHighlight(const QString& searchString)
     {
     {
         m_highlightString = searchString;
         m_highlightString = searchString;
     }
     }

+ 1 - 1
Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/Model/AssetCompleterModel.h

@@ -36,7 +36,7 @@ namespace AzToolsFramework
         void SetFilter(const AZStd::vector<AZ::Data::AssetType>& assetTypes);
         void SetFilter(const AZStd::vector<AZ::Data::AssetType>& assetTypes);
         void SetFilter(FilterConstType filter);
         void SetFilter(FilterConstType filter);
         void RefreshAssetList();
         void RefreshAssetList();
-        void SearchStringHighlight(QString searchString);
+        void SearchStringHighlight(const QString& searchString);
 
 
         Qt::ItemFlags flags(const QModelIndex &index) const override;
         Qt::ItemFlags flags(const QModelIndex &index) const override;
 
 

+ 0 - 2
Gems/GraphModel/Code/Include/GraphModel/Model/Slot.h

@@ -66,8 +66,6 @@ namespace GraphModel
         bool operator>(const SlotId& rhs) const;
         bool operator>(const SlotId& rhs) const;
 
 
         AZStd::size_t GetHash() const;
         AZStd::size_t GetHash() const;
-        AZStd::string GetRepr() const { return AZStd::string::format("GraphModelSlotId(%s,%d", m_name.c_str(), m_subId); }
-
         AZStd::string ToString() const;
         AZStd::string ToString() const;
 
 
         SlotName m_name;
         SlotName m_name;

+ 1 - 1
Gems/GraphModel/Code/Source/Model/Slot.cpp

@@ -47,9 +47,9 @@ namespace GraphModel
                 ->Constructor<const SlotName&>()
                 ->Constructor<const SlotName&>()
                 ->Constructor<const SlotName&, SlotSubId>()
                 ->Constructor<const SlotName&, SlotSubId>()
                 ->Method("__repr__", &SlotId::ToString)
                 ->Method("__repr__", &SlotId::ToString)
+                ->Method("ToString", &SlotId::ToString)
                 ->Method("IsValid", &SlotId::IsValid)
                 ->Method("IsValid", &SlotId::IsValid)
                 ->Method("GetHash", &SlotId::GetHash)
                 ->Method("GetHash", &SlotId::GetHash)
-                ->Method("__repr__", [](SlotId* self) { return self->GetRepr(); })
                 ->Property("name", BehaviorValueProperty(&SlotId::m_name))
                 ->Property("name", BehaviorValueProperty(&SlotId::m_name))
                 ->Property("subId", BehaviorValueProperty(&SlotId::m_subId))
                 ->Property("subId", BehaviorValueProperty(&SlotId::m_subId))
                 ;
                 ;

+ 10 - 1
Gems/LyShine/Code/Editor/AssetTreeEntry.cpp

@@ -27,6 +27,15 @@ UISliceLibraryFilter::UISliceLibraryFilter(const AZ::Data::AssetType& assetType,
     SetFilterPropagation(AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter::Down);
     SetFilterPropagation(AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter::Down);
 }
 }
 
 
+AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter* UISliceLibraryFilter::Clone() const
+{
+    auto clone = new UISliceLibraryFilter(m_assetType, m_pathToSearch.c_str());
+    clone->m_name = m_name;
+    clone->m_tag = m_tag;
+    clone->m_direction = m_direction;
+    return clone;
+}
+
 QString UISliceLibraryFilter::GetNameInternal() const
 QString UISliceLibraryFilter::GetNameInternal() const
 {
 {
     return "UISliceLibraryFilter";
     return "UISliceLibraryFilter";
@@ -124,7 +133,7 @@ AssetTreeEntry* AssetTreeEntry::BuildAssetTree(const AZ::Data::AssetType& assetT
 
 
     // UISliceLibraryFilter::Filter function returns all assets (recursively) that match the specified filter
     // UISliceLibraryFilter::Filter function returns all assets (recursively) that match the specified filter
     // in this case we are only looking for ui slices.
     // in this case we are only looking for ui slices.
-    AZStd::vector<const AssetBrowserEntry*> entries;
+    AZStd::unordered_set<const AssetBrowserEntry*> entries;
     UISliceLibraryFilter filter(assetType, pathToSearch.c_str());
     UISliceLibraryFilter filter(assetType, pathToSearch.c_str());
     filter.Filter(entries, rootEntry.get());
     filter.Filter(entries, rootEntry.get());
 
 

+ 1 - 0
Gems/LyShine/Code/Editor/AssetTreeEntry.h

@@ -28,6 +28,7 @@ class UISliceLibraryFilter
 public:
 public:
     UISliceLibraryFilter(const AZ::Data::AssetType& assetType, const char* pathToSearch);
     UISliceLibraryFilter(const AZ::Data::AssetType& assetType, const char* pathToSearch);
     ~UISliceLibraryFilter() override = default;
     ~UISliceLibraryFilter() override = default;
+    AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter* Clone() const override;
 
 
 protected:
 protected:
     QString GetNameInternal() const override;
     QString GetNameInternal() const override;

+ 15 - 0
README.md

@@ -5,6 +5,21 @@ O3DE (Open 3D Engine) is an open-source, real-time, multi-platform 3D engine tha
 ## Contribute
 ## Contribute
 For information about contributing to Open 3D Engine, visit [https://o3de.org/docs/contributing/](https://o3de.org/docs/contributing/).
 For information about contributing to Open 3D Engine, visit [https://o3de.org/docs/contributing/](https://o3de.org/docs/contributing/).
 
 
+## Updates to this readme
+July 06, 2021
+- Switch licenses to APACHE-2.0 OR MIT
+
+May 14, 2021 
+- Removed instructions for the 3rdParty zip file and downloader URL. This is no longer a requirement. 
+- Updated instructions for dependencies
+- Links to full documentation
+
+April 7-13, 2021
+- Updates to the 3rdParty zip file
+
+March 25, 2021
+- Initial commit for instructions
+
 ## Download and Install
 ## Download and Install
 
 
 This repository uses Git LFS for storing large binary files.  
 This repository uses Git LFS for storing large binary files.