diff --git a/core/MenuItem.h b/core/MenuItem.h --- a/core/MenuItem.h +++ b/core/MenuItem.h @@ -155,6 +155,10 @@ */ void setService( const KService::Ptr& service ); + bool showDefaultIndicator() const; + + void updateDefaultIndicator(); + private: class Private; Private *const d; diff --git a/core/MenuItem.cpp b/core/MenuItem.cpp --- a/core/MenuItem.cpp +++ b/core/MenuItem.cpp @@ -25,6 +25,7 @@ #include #include +#include static bool childIsLessThan( MenuItem *left, MenuItem *right ) { @@ -43,13 +44,15 @@ int weight; KService::Ptr service; KCModuleInfo item; + bool showDefaultIndicator; }; MenuItem::MenuItem( bool isMenu, MenuItem * itsParent ) : d( new Private() ) { d->parent = itsParent; d->menu = isMenu; + d->showDefaultIndicator = false; if ( d->parent ) { d->parent->children().append( this ); @@ -138,4 +141,23 @@ } else { d->weight = 100; } + updateDefaultIndicator(); +} + +bool MenuItem::showDefaultIndicator() const +{ + return d->showDefaultIndicator; +} + +void MenuItem::updateDefaultIndicator() +{ + d->showDefaultIndicator = !KCModuleLoader::isDefaults(d->item); + if (menu()) { + for (auto child : children()) { + d->showDefaultIndicator |= child->showDefaultIndicator(); + } + } + if (d->parent) { + d->parent->updateDefaultIndicator(); + } } diff --git a/core/MenuModel.h b/core/MenuModel.h --- a/core/MenuModel.h +++ b/core/MenuModel.h @@ -56,7 +56,9 @@ DepthRole, - IsCategoryRole + IsCategoryRole, + + DefaultIndicatorRole }; /** diff --git a/core/MenuModel.cpp b/core/MenuModel.cpp --- a/core/MenuModel.cpp +++ b/core/MenuModel.cpp @@ -50,6 +50,7 @@ QHash names = QAbstractItemModel::roleNames(); names[DepthRole] = "DepthRole"; names[IsCategoryRole] = "IsCategoryRole"; + names[DefaultIndicatorRole] = "showDefaultIndicator"; return names; } @@ -131,6 +132,9 @@ case MenuModel::IsCategoryRole: theData.setValue( mi->menu() ); break; + case MenuModel::DefaultIndicatorRole: + theData.setValue(mi->showDefaultIndicator()); + break; default: break; } diff --git a/core/ModuleView.h b/core/ModuleView.h --- a/core/ModuleView.h +++ b/core/ModuleView.h @@ -188,6 +188,11 @@ */ void moduleChanged( bool state ); + /** + * Emitted after the currently active module was saved. + */ + void moduleSaved(); + /** * Emitted when the ModuleView is asked to close.\n */ diff --git a/core/ModuleView.cpp b/core/ModuleView.cpp --- a/core/ModuleView.cpp +++ b/core/ModuleView.cpp @@ -296,6 +296,7 @@ } module->save(); + emit moduleSaved(); return true; } diff --git a/sidebar/SidebarMode.h b/sidebar/SidebarMode.h --- a/sidebar/SidebarMode.h +++ b/sidebar/SidebarMode.h @@ -51,6 +51,7 @@ explicit SubcategoryModel(QAbstractItemModel *parentModel, QObject *parent = nullptr); QString title() const; + QHash roleNames() const override; void setParentIndex(const QModelIndex &activeModule); @@ -118,6 +119,7 @@ private Q_SLOTS: void moduleLoaded(); + void updateDefaults(); void initWidget(); Q_SIGNALS: diff --git a/sidebar/SidebarMode.cpp b/sidebar/SidebarMode.cpp --- a/sidebar/SidebarMode.cpp +++ b/sidebar/SidebarMode.cpp @@ -101,6 +101,7 @@ const QModelIndex& index = m_parentModel->index(i, 0, activeModule); QStandardItem *item = new QStandardItem(m_parentModel->data(index, Qt::DecorationRole).value(), m_parentModel->data(index, Qt::DisplayRole).toString()); item->setData(index.data(Qt::UserRole), Qt::UserRole); + item->setData(index.data(MenuModel::DefaultIndicatorRole), MenuModel::DefaultIndicatorRole); appendRow(item); } } @@ -111,6 +112,13 @@ emit titleChanged(); } +QHash SubcategoryModel::roleNames() const +{ + auto roleNames = QStandardItemModel::roleNames(); + roleNames.insert(MenuModel::DefaultIndicatorRole, "showDefaultIndicator"); + return roleNames; +} + class MostUsedModel : public QSortFilterProxyModel { @@ -372,6 +380,7 @@ d->mainLayout->setContentsMargins(0, 0, 0, 0); d->moduleView = new ModuleView( d->mainWidget ); connect( d->moduleView, &ModuleView::moduleChanged, this, &SidebarMode::moduleLoaded ); + connect(d->moduleView, &ModuleView::moduleSaved, this, &SidebarMode::updateDefaults); d->quickWidget = nullptr; moduleView()->setFaceType(KPageView::Plain); if (applicationMode() == BaseMode::InfoCenter) { @@ -571,6 +580,34 @@ d->moduleView->show(); } +void SidebarMode::updateDefaults() +{ + QModelIndex categoryIdx = d->categorizedModel->index(d->activeCategoryRow, 0); + auto item = categoryIdx.data(Qt::UserRole).value(); + Q_ASSERT(item); + // If subcategory exist update from subcategory + if (!item->children().isEmpty()) { + item = item->child(d->activeSubCategoryRow); + } + item->updateDefaultIndicator(); + + emit d->categorizedModel->dataChanged(categoryIdx, categoryIdx); + + auto subCateogryIdx = d->subCategoryModel->index(d->activeSubCategoryRow, 0); + d->subCategoryModel->setData(subCateogryIdx, item->showDefaultIndicator(), MenuModel::DefaultIndicatorRole); + emit d->subCategoryModel->dataChanged(subCateogryIdx, subCateogryIdx); + + if (d->activeSearchRow > -1) { + auto searchIdx = d->searchModel->index(d->activeSearchRow, 0); + auto idx = d->categorizedModel->mapFromSource(d->flatModel->mapToSource(d->searchModel->mapToSource(searchIdx))); + emit d->searchModel->dataChanged(searchIdx, searchIdx); + if (idx.parent().isValid()) { + auto searchIdxParent = d->searchModel->mapFromSource(d->flatModel->mapFromSource(d->categorizedModel->mapToSource(idx.parent()))); + emit d->searchModel->dataChanged(searchIdxParent, searchIdxParent); + } + } +} + int SidebarMode::activeSearchRow() const { return d->activeSearchRow; diff --git a/sidebar/package/contents/ui/CategoriesPage.qml b/sidebar/package/contents/ui/CategoriesPage.qml --- a/sidebar/package/contents/ui/CategoriesPage.qml +++ b/sidebar/package/contents/ui/CategoriesPage.qml @@ -184,23 +184,7 @@ highlighted: categoryView.currentIndex == index Keys.onEnterPressed: clicked(); Keys.onReturnPressed: clicked(); - contentItem: RowLayout { - id: layout - spacing: Kirigami.Settings.tabletMode ? Kirigami.Units.largeSpacing : Kirigami.Units.smallSpacing - Kirigami.Icon { - id: icon - source: model.decoration - Layout.preferredHeight: Layout.preferredWidth - Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium - Layout.leftMargin: (model.DepthRole-1) * (icon.width + layout.spacing) - } - QQC2.Label { - Layout.fillWidth: true - text: model.display - color: (delegate.highlighted || delegate.checked || (delegate.pressed && delegate.supportsMouseEvents)) ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.textColor - elide: Text.ElideRight - } - } + contentItem: CategoryItem {} } } } diff --git a/sidebar/package/contents/ui/CategoryItem.qml b/sidebar/package/contents/ui/CategoryItem.qml new file mode 100644 --- /dev/null +++ b/sidebar/package/contents/ui/CategoryItem.qml @@ -0,0 +1,32 @@ +import QtQuick 2.5 +import QtQuick.Controls 2.5 as QQC2 +import QtQuick.Layouts 1.1 +import org.kde.kirigami 2.10 as Kirigami + +RowLayout { + id: layout + spacing: Kirigami.Settings.tabletMode ? Kirigami.Units.largeSpacing : Kirigami.Units.smallSpacing + Kirigami.Icon { + id: icon + source: model.decoration + Layout.preferredHeight: Layout.preferredWidth + Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium + Layout.leftMargin: model.DepthRole > 1 ? (model.DepthRole - 1) * (Kirigami.Units.iconSizes.smallMedium + layout.spacing) : 0 + } + QQC2.Label { + Layout.fillWidth: true + text: model.display + color: (delegate.highlighted || delegate.checked || (delegate.pressed && delegate.supportsMouseEvents)) ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.textColor + elide: Text.ElideRight + } + + Rectangle { + id: defaultIndicator + radius: width * 0.5 + width: Kirigami.Units.largeSpacing + height: Kirigami.Units.largeSpacing + visible: model.showDefaultIndicator + Kirigami.Theme.colorSet: Kirigami.Theme.View + color: (delegate.highlighted || delegate.checked || (delegate.pressed && delegate.supportsMouseEvents)) ? Kirigami.Theme.backgroundColor : Kirigami.Theme.focusColor + } +} diff --git a/sidebar/package/contents/ui/SubCategoryPage.qml b/sidebar/package/contents/ui/SubCategoryPage.qml --- a/sidebar/package/contents/ui/SubCategoryPage.qml +++ b/sidebar/package/contents/ui/SubCategoryPage.qml @@ -155,10 +155,8 @@ } } - delegate: Kirigami.BasicListItem { + delegate: Kirigami.AbstractListItem { id: delegate - icon: model.decoration - label: model.display separatorVisible: false onClicked: { systemsettings.loadModule(subCategoryView.model.index(index, 0)); @@ -178,6 +176,7 @@ highlighted: systemsettings.activeSubCategoryRow == index Keys.onEnterPressed: clicked(); Keys.onReturnPressed: clicked(); + contentItem: CategoryItem {} } } }