QmlDesigner: Persist horizontal component library's selected category

Moved showing and hiding categories logic to Cpp side so that:
- Currently selected category is persisted when the component library
  model is reset.
- QML side is clean of the mix of logic and UI.

Also reworked some logic/variables that are making the logic complex.

Task-number: QDS-5215
Change-Id: I8e9f5893f37a982283f1b1be9fee022f0b8afa32
Reviewed-by: Samuel Ghinet <samuel.ghinet@qt.io>
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
Mahmoud Badri
2021-10-15 00:30:59 +03:00
parent 80feee2b63
commit 5de4743bb4
8 changed files with 261 additions and 162 deletions

View File

@@ -78,15 +78,10 @@ Item {
property string importToRemove: "" property string importToRemove: ""
property string importToAdd: "" property string importToAdd: ""
property var currentItem: null
property var currentCategory: null property var currentCategory: null
property var currentImport: null property var currentImport: null
property bool isHorizontalView: false property bool isHorizontalView: false
// horizontal component lib variables
property var selectedCategory: null
property var selectedCategoryImport: null
// called from C++ to close context menu on focus out // called from C++ to close context menu on focus out
function closeContextMenu() function closeContextMenu()
{ {
@@ -94,21 +89,6 @@ Item {
itemContextMenu.close() itemContextMenu.close()
} }
function showImportCategories()
{
if (itemLibraryModel.isAllCategoriesHidden()) {
itemsView.currentImport.importCatVisibleState = true
if (!itemLibraryModel.getIsAnyCategoryHidden())
itemLibraryModel.isAnyCategoryHidden = false
itemsView.selectedCategory = itemLibraryModel.selectImportFirstVisibleCategory()
}
itemsView.currentImport.importCatVisibleState = true
if (!itemLibraryModel.getIsAnyCategoryHidden())
itemLibraryModel.isAnyCategoryHidden = false
}
onWidthChanged: { onWidthChanged: {
itemsView.isHorizontalView = itemsView.width > widthLimit itemsView.isHorizontalView = itemsView.width > widthLimit
} }
@@ -135,10 +115,7 @@ Item {
visible: itemsView.currentCategory === null visible: itemsView.currentCategory === null
height: visible ? implicitHeight : 0 height: visible ? implicitHeight : 0
enabled: itemsView.importToRemove !== "" enabled: itemsView.importToRemove !== ""
onTriggered: { onTriggered: rootView.removeImport(itemsView.importToRemove)
showImportCategories()
rootView.removeImport(itemsView.importToRemove)
}
} }
StudioControls.MenuSeparator { StudioControls.MenuSeparator {
@@ -169,12 +146,8 @@ Item {
text: qsTr("Hide Category") text: qsTr("Hide Category")
visible: itemsView.currentCategory visible: itemsView.currentCategory
height: visible ? implicitHeight : 0 height: visible ? implicitHeight : 0
onTriggered: { onTriggered: itemLibraryModel.hideCategory(itemsView.currentImport.importUrl,
itemLibraryModel.isAnyCategoryHidden = true itemsView.currentCategory.categoryName)
itemsView.currentCategory.categoryVisible = false
itemsView.currentCategory.categorySelected = false
itemsView.selectedCategory = itemLibraryModel.selectImportFirstVisibleCategory()
}
} }
StudioControls.MenuSeparator { StudioControls.MenuSeparator {
@@ -184,23 +157,14 @@ Item {
StudioControls.MenuItem { StudioControls.MenuItem {
text: qsTr("Show Module Hidden Categories") text: qsTr("Show Module Hidden Categories")
enabled: itemsView.currentImport && !itemsView.currentImport.importCatVisibleState enabled: itemsView.currentImport && !itemsView.currentImport.allCategoriesVisible
onTriggered: showImportCategories() onTriggered: itemLibraryModel.showImportHiddenCategories(itemsView.currentImport.importUrl)
} }
StudioControls.MenuItem { StudioControls.MenuItem {
text: qsTr("Show All Hidden Categories") text: qsTr("Show All Hidden Categories")
enabled: itemLibraryModel.isAnyCategoryHidden enabled: itemLibraryModel.isAnyCategoryHidden
onTriggered: { onTriggered: itemLibraryModel.showAllHiddenCategories()
if (itemLibraryModel.isAllCategoriesHidden()) {
itemLibraryModel.showHiddenCategories()
itemsView.selectedCategory = itemLibraryModel.selectImportFirstVisibleCategory()
itemLibraryModel.isAnyCategoryHidden = false
}
itemLibraryModel.isAnyCategoryHidden = false
itemLibraryModel.showHiddenCategories()
}
} }
} }
@@ -419,8 +383,6 @@ Item {
onClicked: (mouse) => { onClicked: (mouse) => {
itemLibraryModel.selectImportCategory(parent.parent.currentImportModel.importUrl, model.index) itemLibraryModel.selectImportCategory(parent.parent.currentImportModel.importUrl, model.index)
itemsView.selectedCategory = model
itemsView.selectedCategoryImport = parent.parent.currentImportModel
if (mouse.button === Qt.RightButton && !rootView.isSearchActive() && categoryModel.rowCount() !== 1) { if (mouse.button === Qt.RightButton && !rootView.isSearchActive() && categoryModel.rowCount() !== 1) {
itemsView.currentCategory = model itemsView.currentCategory = model
@@ -428,13 +390,6 @@ Item {
moduleContextMenu.popup() moduleContextMenu.popup()
} }
} }
Component.onCompleted: {
if (categorySelected)
categorySelected = !categorySelected
itemsView.selectedCategory = itemLibraryModel.selectImportFirstVisibleCategory()
if (itemsView.selectedCategory === categorySelected)
itemsView.selectedCategoryImport = itemsView.selectedCategory.parent.currentImportModel
}
} }
} }
} }
@@ -473,10 +428,10 @@ Item {
rowSpacing: 7 rowSpacing: 7
Repeater { Repeater {
model: itemsView.selectedCategory ? itemsView.selectedCategory.itemModel : null model: itemLibraryModel.itemsModel
delegate: ItemDelegate { delegate: ItemDelegate {
visible: itemVisible visible: itemVisible
textColor: itemsView.selectedCategoryImport && itemsView.selectedCategoryImport.importUnimported textColor: itemLibraryModel.importUnimportedSelected
? StudioTheme.Values.themeUnimportedModuleColor : StudioTheme.Values.themeTextColor ? StudioTheme.Values.themeUnimportedModuleColor : StudioTheme.Values.themeTextColor
width: styleConstants.cellWidth + hItemGrid.flexibleWidth width: styleConstants.cellWidth + hItemGrid.flexibleWidth
height: styleConstants.cellHeight height: styleConstants.cellHeight

View File

@@ -147,20 +147,19 @@ void ItemLibraryCategoriesModel::resetModel()
bool ItemLibraryCategoriesModel::isAllCategoriesHidden() const bool ItemLibraryCategoriesModel::isAllCategoriesHidden() const
{ {
for (const auto &category : std::as_const(m_categoryList)) { for (const auto &category : std::as_const(m_categoryList)) {
// ignore "All Other Components" as its categoryVisible is always true if (category->isCategoryVisible())
if (category->isCategoryVisible() && category->categoryName() != "All Other Components")
return false; return false;
} }
return true; return true;
} }
void ItemLibraryCategoriesModel::showAllCategories(bool show) void ItemLibraryCategoriesModel::showAllCategories()
{ {
for (const auto &category : std::as_const(m_categoryList)) { for (const auto &category : std::as_const(m_categoryList)) {
if (category->isCategoryVisible() != show) { if (!category->isCategoryVisible()) {
category->setCategoryVisible(show); category->setCategoryVisible(true);
ItemLibraryModel::saveCategoryVisibleState(show, category->categoryName(), ItemLibraryModel::saveCategoryVisibleState(true, category->categoryName(),
category->ownerImport()->importName()); category->ownerImport()->importName());
} }
} }
@@ -168,7 +167,21 @@ void ItemLibraryCategoriesModel::showAllCategories(bool show)
emit dataChanged(index(0), index(m_categoryList.size() - 1), {m_roleNames.key("categoryVisible")}); emit dataChanged(index(0), index(m_categoryList.size() - 1), {m_roleNames.key("categoryVisible")});
} }
QObject *ItemLibraryCategoriesModel::selectFirstVisibleCategory() void ItemLibraryCategoriesModel::hideCategory(const QString &categoryName)
{
for (int i = 0; i < m_categoryList.size(); ++i) {
const auto category = m_categoryList.at(i);
if (category->categoryName() == categoryName) {
category->setCategoryVisible(false);
ItemLibraryModel::saveCategoryVisibleState(false, category->categoryName(),
category->ownerImport()->importName());
emit dataChanged(index(i), index(i), {m_roleNames.key("categoryVisible")});
break;
}
}
}
int ItemLibraryCategoriesModel::selectFirstVisibleCategory()
{ {
for (int i = 0; i < m_categoryList.length(); ++i) { for (int i = 0; i < m_categoryList.length(); ++i) {
const auto category = m_categoryList.at(i); const auto category = m_categoryList.at(i);
@@ -176,29 +189,34 @@ QObject *ItemLibraryCategoriesModel::selectFirstVisibleCategory()
if (category->isCategoryVisible()) { if (category->isCategoryVisible()) {
category->setCategorySelected(true); category->setCategorySelected(true);
emit dataChanged(index(i), index(i), {m_roleNames.key("categorySelected")}); emit dataChanged(index(i), index(i), {m_roleNames.key("categorySelected")});
return category; return i;
} }
} }
return -1;
}
void ItemLibraryCategoriesModel::clearSelectedCategory(int categoryIndex)
{
if (categoryIndex == -1 || m_categoryList.isEmpty())
return;
m_categoryList.at(categoryIndex)->setCategorySelected(false);
emit dataChanged(index(categoryIndex), index(categoryIndex), {m_roleNames.key("categorySelected")});
}
QPointer<ItemLibraryCategory> ItemLibraryCategoriesModel::selectCategory(int categoryIndex)
{
if (categoryIndex == -1 || m_categoryList.isEmpty())
return nullptr; return nullptr;
}
void ItemLibraryCategoriesModel::clearSelectedCategories() const QPointer<ItemLibraryCategory> category = m_categoryList.at(categoryIndex);
{
for (const auto &category : std::as_const(m_categoryList))
category->setCategorySelected(false);
emit dataChanged(index(0), index(m_categoryList.size() - 1), {m_roleNames.key("categorySelected")});
}
void ItemLibraryCategoriesModel::selectCategory(int categoryIndex)
{
const auto category = m_categoryList.at(categoryIndex);
if (!category->categorySelected()) { if (!category->categorySelected()) {
clearSelectedCategories();
category->setCategorySelected(true); category->setCategorySelected(true);
emit dataChanged(index(categoryIndex),index(categoryIndex), {m_roleNames.key("categorySelected")}); emit dataChanged(index(categoryIndex),index(categoryIndex), {m_roleNames.key("categorySelected")});
} }
return category;
} }
void ItemLibraryCategoriesModel::addRoleNames() void ItemLibraryCategoriesModel::addRoleNames()

View File

@@ -55,10 +55,11 @@ public:
bool isAllCategoriesHidden() const; bool isAllCategoriesHidden() const;
void sortCategorySections(); void sortCategorySections();
void resetModel(); void resetModel();
void showAllCategories(bool show = true); void showAllCategories();
void clearSelectedCategories(); void hideCategory(const QString &categoryName);
QObject *selectFirstVisibleCategory(); void clearSelectedCategory(int categoryIndex);
void selectCategory(int categoryIndex); int selectFirstVisibleCategory();
QPointer<ItemLibraryCategory> selectCategory(int categoryIndex);
private: private:
void addRoleNames(); void addRoleNames();

View File

@@ -137,6 +137,7 @@ void ItemLibraryCategory::setExpanded(bool expanded)
void ItemLibraryCategory::setCategorySelected(bool selected) void ItemLibraryCategory::setCategorySelected(bool selected)
{ {
m_categorySelected = selected; m_categorySelected = selected;
emit categorySelectedChanged();
} }
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -133,28 +133,38 @@ bool ItemLibraryImport::updateCategoryVisibility(const QString &searchText, bool
return hasVisibleCategories; return hasVisibleCategories;
} }
void ItemLibraryImport::showAllCategories(bool show) void ItemLibraryImport::showAllCategories()
{ {
m_categoryModel.showAllCategories(show); m_categoryModel.showAllCategories();
setAllCategoriesVisible(true);
} }
void ItemLibraryImport::selectCategory(int categoryIndex) void ItemLibraryImport::hideCategory(const QString &categoryName)
{ {
m_categoryModel.selectCategory(categoryIndex); m_categoryModel.hideCategory(categoryName);
setAllCategoriesVisible(false);
} }
QObject *ItemLibraryImport::selectFirstVisibleCategory() ItemLibraryCategory *ItemLibraryImport::selectCategory(int categoryIndex)
{
return m_categoryModel.selectCategory(categoryIndex);
}
int ItemLibraryImport::selectFirstVisibleCategory()
{ {
return m_categoryModel.selectFirstVisibleCategory(); return m_categoryModel.selectFirstVisibleCategory();
} }
void ItemLibraryImport::clearSelectedCategories() void ItemLibraryImport::clearSelectedCategory(int categoryIndex)
{ {
m_categoryModel.clearSelectedCategories(); m_categoryModel.clearSelectedCategory(categoryIndex);
} }
bool ItemLibraryImport::isAllCategoriesHidden() const bool ItemLibraryImport::isAllCategoriesHidden() const
{ {
if (!m_isVisible)
return true;
return m_categoryModel.isAllCategoriesHidden(); return m_categoryModel.isAllCategoriesHidden();
} }
@@ -221,7 +231,7 @@ void ItemLibraryImport::setImportExpanded(bool expanded)
} }
} }
ItemLibraryCategory *ItemLibraryImport::getCategorySection(const QString &categoryName) const ItemLibraryCategory *ItemLibraryImport::getCategoryByName(const QString &categoryName) const
{ {
for (ItemLibraryCategory *catSec : std::as_const(m_categoryModel.categorySections())) { for (ItemLibraryCategory *catSec : std::as_const(m_categoryModel.categorySections())) {
if (catSec->categoryName() == categoryName) if (catSec->categoryName() == categoryName)
@@ -231,6 +241,16 @@ ItemLibraryCategory *ItemLibraryImport::getCategorySection(const QString &catego
return nullptr; return nullptr;
} }
ItemLibraryCategory *ItemLibraryImport::getCategoryAt(int categoryIndex) const
{
const QList<QPointer<ItemLibraryCategory>> categories = m_categoryModel.categorySections();
if (categoryIndex != -1 && !categories.isEmpty())
return categories.at(categoryIndex);
return nullptr;
}
// static // static
QString ItemLibraryImport::userComponentsTitle() QString ItemLibraryImport::userComponentsTitle()
{ {
@@ -264,22 +284,14 @@ void ItemLibraryImport::updateRemovable()
} }
} }
// returns true if all categories are visible, otherwise false bool ItemLibraryImport::allCategoriesVisible() const
bool ItemLibraryImport::importCatVisibleState() const
{ {
if (m_categoryModel.rowCount() > 0) { return m_allCategoriesVisible;
for (ItemLibraryCategory *cat : m_categoryModel.categorySections()) {
if (!cat->isCategoryVisible())
return false;
}
} }
return true; void ItemLibraryImport::setAllCategoriesVisible(bool visible)
}
void ItemLibraryImport::setImportCatVisibleState(bool show)
{ {
m_categoryModel.showAllCategories(show); m_allCategoriesVisible = visible;
} }
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -43,7 +43,7 @@ class ItemLibraryImport : public QObject
Q_PROPERTY(bool importExpanded READ importExpanded WRITE setImportExpanded NOTIFY importExpandChanged FINAL) Q_PROPERTY(bool importExpanded READ importExpanded WRITE setImportExpanded NOTIFY importExpandChanged FINAL)
Q_PROPERTY(bool importRemovable READ importRemovable NOTIFY importRemovableChanged FINAL) Q_PROPERTY(bool importRemovable READ importRemovable NOTIFY importRemovableChanged FINAL)
Q_PROPERTY(bool importUnimported READ importUnimported FINAL) Q_PROPERTY(bool importUnimported READ importUnimported FINAL)
Q_PROPERTY(bool importCatVisibleState READ importCatVisibleState WRITE setImportCatVisibleState NOTIFY importCatVisibleStateChanged FINAL) Q_PROPERTY(bool allCategoriesVisible READ allCategoriesVisible WRITE setAllCategoriesVisible NOTIFY allCategoriesVisibleChanged FINAL)
Q_PROPERTY(QObject *categoryModel READ categoryModel NOTIFY categoryModelChanged FINAL) Q_PROPERTY(QObject *categoryModel READ categoryModel NOTIFY categoryModelChanged FINAL)
public: public:
@@ -65,11 +65,12 @@ public:
bool importVisible() const; bool importVisible() const;
bool importUsed() const; bool importUsed() const;
bool importRemovable() const; bool importRemovable() const;
bool importCatVisibleState() const; bool allCategoriesVisible() const;
bool hasCategories() const; bool hasCategories() const;
bool hasSingleCategory() const; bool hasSingleCategory() const;
bool isAllCategoriesHidden() const; bool isAllCategoriesHidden() const;
ItemLibraryCategory *getCategorySection(const QString &categoryName) const; ItemLibraryCategory *getCategoryByName(const QString &categoryName) const;
ItemLibraryCategory *getCategoryAt(int categoryIndex) const;
void addCategory(ItemLibraryCategory *category); void addCategory(ItemLibraryCategory *category);
QObject *categoryModel(); QObject *categoryModel();
@@ -78,12 +79,14 @@ public:
void setImportUsed(bool importUsed); void setImportUsed(bool importUsed);
void sortCategorySections(); void sortCategorySections();
void setImportExpanded(bool expanded = true); void setImportExpanded(bool expanded = true);
void setImportCatVisibleState(bool show); void setAllCategoriesVisible(bool visible);
void expandCategories(bool expand = true); void expandCategories(bool expand = true);
void showAllCategories(bool show = true); void showAllCategories();
void selectCategory(int categoryIndex); void hideCategory(const QString &categoryName);
QObject *selectFirstVisibleCategory(); ItemLibraryCategory *selectCategory(int categoryIndex);
void clearSelectedCategories(); int selectFirstVisibleCategory();
void clearSelectedCategory(int categoryIndex);
bool importUnimported() const { return m_sectionType == SectionType::Unimported; }
static QString userComponentsTitle(); static QString userComponentsTitle();
static QString quick3DAssetsTitle(); static QString quick3DAssetsTitle();
@@ -97,17 +100,17 @@ signals:
void importUsedChanged(); void importUsedChanged();
void importExpandChanged(); void importExpandChanged();
void importRemovableChanged(); void importRemovableChanged();
void importCatVisibleStateChanged(); void allCategoriesVisibleChanged();
private: private:
void updateRemovable(); void updateRemovable();
bool importUnimported() const { return m_sectionType == SectionType::Unimported; }
Import m_import; Import m_import;
bool m_importExpanded = true; bool m_importExpanded = true;
bool m_isVisible = true; bool m_isVisible = true;
bool m_importUsed = false; bool m_importUsed = false;
bool m_importRemovable = false; bool m_importRemovable = false;
bool m_allCategoriesVisible = true;
SectionType m_sectionType = SectionType::Default; SectionType m_sectionType = SectionType::Default;
ItemLibraryCategoriesModel m_categoryModel; ItemLibraryCategoriesModel m_categoryModel;
}; };

View File

@@ -59,8 +59,8 @@ bool ItemLibraryModel::loadExpandedState(const QString &sectionName)
return expandedStateHash.value(sectionName, true); return expandedStateHash.value(sectionName, true);
} }
void ItemLibraryModel::saveCategoryVisibleState(bool isVisible, const QString &categoryName, const void ItemLibraryModel::saveCategoryVisibleState(bool isVisible, const QString &categoryName,
QString &importName) const QString &importName)
{ {
categoryVisibleStateHash.insert(categoryName + '_' + importName, isVisible); categoryVisibleStateHash.insert(categoryName + '_' + importName, isVisible);
} }
@@ -70,58 +70,61 @@ bool ItemLibraryModel::loadCategoryVisibleState(const QString &categoryName, con
return categoryVisibleStateHash.value(categoryName + '_' + importName, true); return categoryVisibleStateHash.value(categoryName + '_' + importName, true);
} }
void ItemLibraryModel::showHiddenCategories() void ItemLibraryModel::selectImportCategory(const QString &importUrl, int categoryIndex)
{ {
clearSelectedCategory();
m_selectedImportUrl = importUrl;
m_selectedCategoryIndex = categoryIndex;
updateSelection();
}
void ItemLibraryModel::clearSelectedCategory()
{
if (m_selectedCategoryIndex != -1) {
ItemLibraryImport *selectedImport = importByUrl(m_selectedImportUrl);
if (selectedImport)
selectedImport->clearSelectedCategory(m_selectedCategoryIndex);
}
}
void ItemLibraryModel::selectImportFirstVisibleCategory()
{
if (m_selectedCategoryIndex != -1) {
ItemLibraryImport *selectedImport = importByUrl(m_selectedImportUrl);
if (selectedImport) {
ItemLibraryCategory *selectedCategory = selectedImport->getCategoryAt(m_selectedCategoryIndex);
if (selectedCategory) {
bool isUnimported = selectedImport->sectionType() == ItemLibraryImport::SectionType::Unimported;
// unimported category is always visible so checking its Import visibility instead
bool isVisible = isUnimported ? selectedImport->importVisible()
: selectedCategory->isCategoryVisible();
if (isVisible)
return; // there is already a selected visible category
clearSelectedCategory();
}
}
}
for (const QPointer<ItemLibraryImport> &import : std::as_const(m_importList)) { for (const QPointer<ItemLibraryImport> &import : std::as_const(m_importList)) {
if (import->hasCategories()) if (!import->isAllCategoriesHidden()) {
import->showAllCategories(true); m_selectedImportUrl = import->importUrl();
m_selectedCategoryIndex = import->selectFirstVisibleCategory();
ItemLibraryCategory *selectedCategory = import->getCategoryAt(m_selectedCategoryIndex);
if (selectedCategory) {
setItemsModel(selectedCategory->itemModel());
setImportUnimportedSelected(import->importUnimported());
return;
} }
categoryVisibleStateHash.clear();
}
bool ItemLibraryModel::getIsAnyCategoryHidden() const
{
for (const bool &catState : std::as_const(categoryVisibleStateHash)) {
if (!catState)
return true;
}
return false;
}
void ItemLibraryModel::selectImportCategory(const QString importUrl, int categoryIndex)
{
ItemLibraryImport *selectedCategoryImport = importByUrl(importUrl);
for (int i = 0; i < m_importList.length(); ++i) {
const auto importToSelect = m_importList.at(i);
if (selectedCategoryImport == importToSelect)
importToSelect->selectCategory(categoryIndex);
else
importToSelect->clearSelectedCategories();
} }
} }
bool ItemLibraryModel::isAllCategoriesHidden() const m_selectedImportUrl.clear();
{ m_selectedCategoryIndex = -1;
for (int i = 0; i < m_importList.length(); ++i) { setItemsModel(nullptr);
if (!m_importList.at(i)->isAllCategoriesHidden())
return false;
}
return true;
}
QObject *ItemLibraryModel::selectImportFirstVisibleCategory()
{
for (const QPointer<ItemLibraryImport> &import : std::as_const(m_importList)) {
if (!import->isAllCategoriesHidden())
return import->selectFirstVisibleCategory();
}
return nullptr;
} }
bool ItemLibraryModel::isAnyCategoryHidden() const bool ItemLibraryModel::isAnyCategoryHidden() const
@@ -137,6 +140,30 @@ void ItemLibraryModel::setIsAnyCategoryHidden(bool state)
} }
} }
bool ItemLibraryModel::importUnimportedSelected() const
{
return m_importUnimportedSelected;
}
void ItemLibraryModel::setImportUnimportedSelected(bool state)
{
if (state != m_importUnimportedSelected) {
m_importUnimportedSelected = state;
emit importUnimportedSelectedChanged();
}
}
QObject *ItemLibraryModel::itemsModel() const
{
return m_itemsModel;
}
void ItemLibraryModel::setItemsModel(QObject *model)
{
m_itemsModel = model;
emit itemsModelChanged();
}
void ItemLibraryModel::expandAll() void ItemLibraryModel::expandAll()
{ {
int i = 0; int i = 0;
@@ -164,6 +191,46 @@ void ItemLibraryModel::collapseAll()
} }
} }
void ItemLibraryModel::hideCategory(const QString &importUrl, const QString &categoryName)
{
ItemLibraryImport *import = importByUrl(importUrl);
if (!import)
return;
import->hideCategory(categoryName);
selectImportFirstVisibleCategory();
setIsAnyCategoryHidden(true);
}
void ItemLibraryModel::showImportHiddenCategories(const QString &importUrl)
{
ItemLibraryImport *targetImport = nullptr;
bool hiddenCatsExist = false;
for (const QPointer<ItemLibraryImport> &import : std::as_const(m_importList)) {
if (import->importUrl() == importUrl)
targetImport = import;
else
hiddenCatsExist |= !import->allCategoriesVisible();
}
if (targetImport) {
targetImport->showAllCategories();
updateSelection(); // useful when all categories are hidden
setIsAnyCategoryHidden(hiddenCatsExist);
}
}
void ItemLibraryModel::showAllHiddenCategories()
{
for (const QPointer<ItemLibraryImport> &import : std::as_const(m_importList))
import->showAllCategories();
updateSelection(); // useful when all categories are hidden
setIsAnyCategoryHidden(false);
categoryVisibleStateHash.clear();
}
void ItemLibraryModel::setFlowMode(bool b) void ItemLibraryModel::setFlowMode(bool b)
{ {
m_flowMode = b; m_flowMode = b;
@@ -242,6 +309,8 @@ void ItemLibraryModel::setSearchText(const QString &searchText)
bool changed = false; bool changed = false;
updateVisibility(&changed); updateVisibility(&changed);
selectImportFirstVisibleCategory();
} }
} }
@@ -411,7 +480,7 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model)
} }
// get or create category section // get or create category section
ItemLibraryCategory *categorySection = importSection->getCategorySection(catName); ItemLibraryCategory *categorySection = importSection->getCategoryByName(catName);
if (!categorySection) { if (!categorySection) {
categorySection = new ItemLibraryCategory(catName, importSection); categorySection = new ItemLibraryCategory(catName, importSection);
importSection->addCategory(categorySection); importSection->addCategory(categorySection);
@@ -428,8 +497,11 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model)
} }
sortSections(); sortSections();
bool changed = false; bool changed = false;
updateVisibility(&changed); updateVisibility(&changed);
updateSelection();
endResetModel(); endResetModel();
} }
@@ -453,6 +525,23 @@ void ItemLibraryModel::clearSections()
m_importList.clear(); m_importList.clear();
} }
void ItemLibraryModel::updateSelection()
{
if (m_selectedCategoryIndex != -1) {
ItemLibraryImport *selectedImport = importByUrl(m_selectedImportUrl);
if (selectedImport) {
ItemLibraryCategory *selectedCategory = selectedImport->selectCategory(m_selectedCategoryIndex);
if (selectedCategory) {
setItemsModel(selectedCategory->itemModel());
setImportUnimportedSelected(selectedImport->importUnimported());
return;
}
}
}
selectImportFirstVisibleCategory();
}
void ItemLibraryModel::registerQmlTypes() void ItemLibraryModel::registerQmlTypes()
{ {
qmlRegisterAnonymousType<QmlDesigner::ItemLibraryModel>("ItemLibraryModel", 1); qmlRegisterAnonymousType<QmlDesigner::ItemLibraryModel>("ItemLibraryModel", 1);

View File

@@ -33,15 +33,19 @@ QT_FORWARD_DECLARE_CLASS(QMimeData)
namespace QmlDesigner { namespace QmlDesigner {
class ItemLibraryInfo; class ItemLibraryCategory;
class ItemLibraryEntry; class ItemLibraryEntry;
class Model;
class ItemLibraryImport; class ItemLibraryImport;
class ItemLibraryInfo;
class Model;
class ItemLibraryModel : public QAbstractListModel class ItemLibraryModel : public QAbstractListModel
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool isAnyCategoryHidden READ isAnyCategoryHidden WRITE setIsAnyCategoryHidden NOTIFY isAnyCategoryHiddenChanged FINAL) Q_PROPERTY(bool isAnyCategoryHidden READ isAnyCategoryHidden WRITE setIsAnyCategoryHidden NOTIFY isAnyCategoryHiddenChanged FINAL)
Q_PROPERTY(QObject *itemsModel READ itemsModel WRITE setItemsModel NOTIFY itemsModelChanged)
Q_PROPERTY(bool importUnimportedSelected READ importUnimportedSelected WRITE setImportUnimportedSelected NOTIFY importUnimportedSelectedChanged)
public: public:
explicit ItemLibraryModel(QObject *parent = nullptr); explicit ItemLibraryModel(QObject *parent = nullptr);
@@ -66,20 +70,26 @@ public:
bool isAnyCategoryHidden() const; bool isAnyCategoryHidden() const;
void setIsAnyCategoryHidden(bool state); void setIsAnyCategoryHidden(bool state);
bool importUnimportedSelected() const;
void setImportUnimportedSelected(bool state);
QObject *itemsModel() const;
void setItemsModel(QObject *model);
static void registerQmlTypes(); static void registerQmlTypes();
static void saveExpandedState(bool expanded, const QString &sectionName); static void saveExpandedState(bool expanded, const QString &sectionName);
static bool loadExpandedState(const QString &sectionName); static bool loadExpandedState(const QString &sectionName);
static void saveCategoryVisibleState(bool isVisible, const QString &categoryName, const QString static void saveCategoryVisibleState(bool isVisible, const QString &categoryName, const QString
&importName); &importName);
static bool loadCategoryVisibleState(const QString &categoryName, const QString &importName); static bool loadCategoryVisibleState(const QString &categoryName, const QString &importName);
void selectImportFirstVisibleCategory();
Q_INVOKABLE void expandAll(); Q_INVOKABLE void expandAll();
Q_INVOKABLE void collapseAll(); Q_INVOKABLE void collapseAll();
Q_INVOKABLE void showHiddenCategories(); Q_INVOKABLE void hideCategory(const QString &importUrl, const QString &categoryName);
Q_INVOKABLE bool getIsAnyCategoryHidden() const; Q_INVOKABLE void showImportHiddenCategories(const QString &importUrl);
Q_INVOKABLE void selectImportCategory(const QString importUrl, int categoryIndex); Q_INVOKABLE void showAllHiddenCategories();
Q_INVOKABLE QObject *selectImportFirstVisibleCategory(); Q_INVOKABLE void selectImportCategory(const QString &importUrl, int categoryIndex);
Q_INVOKABLE bool isAllCategoriesHidden() const;
Import entryToImport(const ItemLibraryEntry &entry); Import entryToImport(const ItemLibraryEntry &entry);
@@ -87,12 +97,18 @@ public:
signals: signals:
void isAnyCategoryHiddenChanged(); void isAnyCategoryHiddenChanged();
void importUnimportedSelectedChanged();
void selectedCategoryChanged();
void selectedImportUrlChanged();
void itemsModelChanged();
private: private:
void updateVisibility(bool *changed); void updateVisibility(bool *changed);
void addRoleNames(); void addRoleNames();
void sortSections(); void sortSections();
void clearSections(); void clearSections();
void updateSelection();
void clearSelectedCategory();
QList<QPointer<ItemLibraryImport>> m_importList; QList<QPointer<ItemLibraryImport>> m_importList;
QHash<int, QByteArray> m_roleNames; QHash<int, QByteArray> m_roleNames;
@@ -100,6 +116,10 @@ private:
QString m_searchText; QString m_searchText;
bool m_flowMode = false; bool m_flowMode = false;
bool m_isAnyCategoryHidden = false; bool m_isAnyCategoryHidden = false;
bool m_importUnimportedSelected = false;
QString m_selectedImportUrl;
int m_selectedCategoryIndex = -1;
QObject *m_itemsModel = nullptr; // items model for the horizontal layout
inline static QHash<QString, bool> expandedStateHash; inline static QHash<QString, bool> expandedStateHash;
inline static QHash<QString, bool> categoryVisibleStateHash; inline static QHash<QString, bool> categoryVisibleStateHash;