File indexing completed on 2024-05-12 08:51:13

0001 /*
0002    SPDX-FileCopyrightText: 2018 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr>
0003 
0004    SPDX-License-Identifier: LGPL-3.0-or-later
0005  */
0006 
0007 #include "viewmanager.h"
0008 
0009 #include "viewslistdata.h"
0010 #include "viewconfigurationdata.h"
0011 #include "viewsLogging.h"
0012 #include "models/datamodel.h"
0013 #include "models/gridviewproxymodel.h"
0014 
0015 #if KFKIO_FOUND
0016 #include "models/filebrowsermodel.h"
0017 #include "models/filebrowserproxymodel.h"
0018 #endif
0019 
0020 #include "elisa_settings.h"
0021 
0022 #include <KLocalizedString>
0023 
0024 #include <QQmlEngine>
0025 #include <QMetaEnum>
0026 
0027 class ViewManagerPrivate
0028 {
0029 public:
0030     ViewsListData *mViewsListData = nullptr;
0031 
0032     QMap<ElisaUtils::PlayListEntryType, ViewParameters> mChildViews = {
0033         {ElisaUtils::Album, {{},
0034                              QUrl{QStringLiteral("image://icon/view-media-track")},
0035                              ViewManager::ListView,
0036                              ViewManager::GenericDataModel,
0037                              ElisaUtils::FilterById,
0038                              ElisaUtils::Track,
0039                              DataTypes::TrackNumberRole,
0040                              {DataTypes::TrackNumberRole, Qt::DisplayRole},
0041                              {i18nc("@title:inmenu", "Track Number"), i18nc("@title:inmenu", "Title")},
0042                              Qt::AscendingOrder,
0043                              {i18nc("@item:inmenu", "Ascending"), i18nc("@item:inmenu", "Descending"),
0044                               i18nc("@item:inmenu", "A-Z"), i18nc("@item:inmenu", "Z-A")},
0045                              ViewManager::SingleAlbum,
0046                              ViewManager::DiscHeaders,
0047                              ViewManager::IsTrack}},
0048         {ElisaUtils::Genre, {{},
0049                              QUrl{QStringLiteral("image://icon/view-media-artist")},
0050                              ViewManager::GridView,
0051                              ViewManager::GenericDataModel,
0052                              ElisaUtils::FilterByGenre,
0053                              ElisaUtils::Artist,
0054                              Qt::DisplayRole,
0055                              {Qt::DisplayRole},
0056                              {i18nc("@title:inmenu", "Name")},
0057                              Qt::AscendingOrder,
0058                              {i18nc("@item:inmenu", "A-Z"), i18nc("@item:inmenu", "Z-A")},
0059                              QUrl{QStringLiteral("image://icon/view-media-artist")},
0060                              ViewManager::DelegateWithoutSecondaryText,
0061                              ViewManager::ViewHideRating}},
0062         {ElisaUtils::Artist, {{},
0063                               QUrl{QStringLiteral("image://icon/view-media-album-cover")},
0064                               ViewManager::GridView,
0065                               ViewManager::GenericDataModel,
0066                               ElisaUtils::FilterByArtist,
0067                               ElisaUtils::Album,
0068                               DataTypes::TitleRole,
0069                               {DataTypes::TitleRole, DataTypes::GenreRole, DataTypes::YearRole},
0070                               {i18nc("@title:inmenu", "Title"), i18nc("@title:inmenu", "Genre"), i18nc("@title:inmenu", "Year")},
0071                               Qt::AscendingOrder,
0072                               {i18nc("@item:inmenu", "A-Z"), i18nc("@item:inmenu", "Z-A"), i18nc("@item:inmenu", "A-Z"), i18nc("@item:inmenu", "Z-A"), i18nc("@item:inmenu", "Oldest First"), i18nc("@item:inmenu", "Newest First")},
0073                               QUrl{QStringLiteral("image://icon/media-default-album")},
0074                               ViewManager::DelegateWithSecondaryText,
0075                               ViewManager::ViewShowRating}},
0076         {ElisaUtils::Container, {{},
0077                                  QUrl{QStringLiteral("image://icon/folder")},
0078                                  ViewManager::GridView,
0079                                  ViewManager::FileBrowserModel,
0080                                  ElisaUtils::FilterByPath,
0081                                  ElisaUtils::FileName,
0082                                  Qt::DisplayRole,
0083                                  {Qt::DisplayRole},
0084                                  {i18nc("@title:inmenu", "Name")},
0085                                  Qt::AscendingOrder,
0086                                  {i18nc("@item:inmenu", "A-Z"), i18nc("@item:inmenu", "Z-A")},
0087                                  QUrl{QStringLiteral("image://icon/folder")},
0088                                  ViewManager::DelegateWithoutSecondaryText,
0089                                  ViewManager::ViewHideRating}},
0090     };
0091 
0092     int mViewIndex = -1;
0093 
0094     int mInitialIndex = -1;
0095 
0096     QString mInitialFilesViewPath = QDir::rootPath();
0097 
0098     QList<ViewParameters> mViewParametersStack = (mViewsListData ? QList<ViewParameters>{mViewsListData->viewParameters(0)} : QList<ViewParameters>{});
0099 };
0100 
0101 ViewManager::ViewManager(QObject *parent)
0102     : QObject(parent)
0103     , d(std::make_unique<ViewManagerPrivate>())
0104 {
0105 }
0106 
0107 int ViewManager::viewIndex() const
0108 {
0109     return d->mViewIndex;
0110 }
0111 
0112 int ViewManager::initialIndex() const
0113 {
0114     return d->mInitialIndex;
0115 }
0116 
0117 ViewsListData *ViewManager::viewsData() const
0118 {
0119     return d->mViewsListData;
0120 }
0121 
0122 QString ViewManager::initialFilesViewPath() const
0123 {
0124     return d->mInitialFilesViewPath;
0125 }
0126 
0127 ViewManager::~ViewManager() = default;
0128 
0129 void ViewManager::openView(int viewIndex)
0130 {
0131     qCDebug(orgKdeElisaViews()) << "ViewManager::openView" << viewIndex << d->mViewParametersStack.size() << d->mViewsListData;
0132 
0133     if (!d->mViewsListData || d->mViewsListData->isEmpty()) {
0134         return;
0135     }
0136 
0137     d->mViewParametersStack.clear();
0138 
0139     if (viewIndex < 0 || viewIndex >= d->mViewsListData->count()) {
0140         viewIndex = 0;
0141     }
0142 
0143     auto viewParameters = d->mViewsListData->viewParameters(viewIndex);
0144 
0145     qCDebug(orgKdeElisaViews()) << "ViewManager::openView" << "changing view" << viewIndex;
0146 
0147     d->mViewIndex = viewIndex;
0148     Q_EMIT viewIndexChanged();
0149 
0150     applyFilter(viewParameters, viewParameters.mMainTitle, viewParameters);
0151     if (viewParameters.mDataType == ElisaUtils::FileName) { // Folder view
0152         viewParameters.mDataFilter[DataTypes::FilePathRole] = QUrl::fromLocalFile(d->mInitialFilesViewPath);
0153     }
0154     openViewFromData(viewParameters);
0155 }
0156 
0157 void ViewManager::openChildView(const DataTypes::MusicDataType &fullData)
0158 {
0159     qCDebug(orgKdeElisaViews()) << "ViewManager::openChildView"
0160                                 << fullData[DataTypes::TitleRole]
0161                                 << fullData[DataTypes::SecondaryTextRole]
0162                                 << fullData[DataTypes::ImageUrlRole]
0163                                 << fullData[DataTypes::DatabaseIdRole]
0164                                 << fullData[DataTypes::FilePathRole]
0165                                 << fullData[DataTypes::ElementTypeRole]
0166                                 << fullData[DataTypes::IsSingleDiscAlbumRole]
0167                                 << d->mViewParametersStack.size();
0168 
0169     if (!d->mViewParametersStack.size()) {
0170         return;
0171     }
0172 
0173     if (!d->mViewsListData || d->mViewsListData->isEmpty()) {
0174         return;
0175     }
0176 
0177     const auto &lastView = d->mViewParametersStack.back();
0178     auto dataType = fullData[DataTypes::ElementTypeRole].value<ElisaUtils::PlayListEntryType>();
0179     auto title = fullData[DataTypes::TitleRole].toString();
0180     auto innerSecondaryTitle = fullData[DataTypes::ArtistRole].toString();
0181     auto innerImage = fullData[DataTypes::ImageUrlRole].toUrl();
0182 
0183     auto nextViewParameters = d->mChildViews[dataType];
0184 
0185     nextViewParameters.mMainTitle = title;
0186     nextViewParameters.mSecondaryTitle = innerSecondaryTitle;
0187     nextViewParameters.mMainImage = innerImage;
0188     nextViewParameters.mDepth = d->mViewParametersStack.size() + 1;
0189     nextViewParameters.mDataFilter = fullData;
0190 
0191     if (lastView.mFilterType == ElisaUtils::FilterByGenre) {
0192         nextViewParameters.mFilterType = ElisaUtils::FilterByGenreAndArtist;
0193     }
0194 
0195     applyFilter(nextViewParameters, title, lastView);
0196 
0197     // Prevent the user from clicking the same view other and over again
0198     if (this->isSameView(nextViewParameters, lastView)) {
0199         return;
0200     }
0201 
0202     if (dataType == ElisaUtils::Album && nextViewParameters.mDataFilter[DataTypes::IsSingleDiscAlbumRole].toBool())
0203     {
0204         nextViewParameters.mAlbumViewStyle = NoDiscHeaders;
0205     }
0206 
0207     openViewFromData(nextViewParameters);
0208 }
0209 
0210 void ViewManager::openAlbumView(const QString &title, const QString &artist, qulonglong databaseId, const QUrl &albumCoverUrl)
0211 {
0212     openChildView({{DataTypes::ElementTypeRole, ElisaUtils::Album},
0213                    {DataTypes::DatabaseIdRole, databaseId},
0214                    {DataTypes::TitleRole, title},
0215                    {DataTypes::ArtistRole, artist},
0216                    {DataTypes::ImageUrlRole, albumCoverUrl},});
0217 }
0218 
0219 void ViewManager::openArtistView(const QString &artist)
0220 {
0221     openChildView({{DataTypes::ElementTypeRole, ElisaUtils::Artist},
0222                    {DataTypes::TitleRole, artist},});
0223 }
0224 
0225 void ViewManager::openNowPlaying()
0226 {
0227     openView(0);
0228 }
0229 
0230 void ViewManager::openViewFromData(const ViewParameters &viewParamaters)
0231 {
0232     qCDebug(orgKdeElisaViews()) << "ViewManager::openViewFromData" << d->mViewParametersStack.size();
0233 
0234     QAbstractItemModel *newModel = nullptr;
0235     QAbstractProxyModel *proxyModel = nullptr;
0236 
0237     switch (viewParamaters.mModelType)
0238     {
0239     case FileBrowserModel:
0240     {
0241 #if KFKIO_FOUND
0242         newModel = new ::FileBrowserModel;
0243         auto *realProxyModel = new FileBrowserProxyModel;
0244         proxyModel = realProxyModel;
0245 #else
0246         newModel = nullptr;
0247         proxyModel = nullptr;
0248 #endif
0249         break;
0250     }
0251     case GenericDataModel:
0252         newModel = new DataModel;
0253         proxyModel = new GridViewProxyModel;
0254         break;
0255     case UnknownModelType:
0256         qCDebug(orgKdeElisaViews()) << "ViewManager::openViewFromData" << "unknown model type";
0257         break;
0258     }
0259 
0260     QQmlEngine::setObjectOwnership(newModel, QQmlEngine::JavaScriptOwnership);
0261     QQmlEngine::setObjectOwnership(proxyModel, QQmlEngine::JavaScriptOwnership);
0262 
0263     d->mViewParametersStack.push_back(viewParamaters);
0264     switch (viewParamaters.mViewPresentationType)
0265     {
0266     case ViewPresentationType::GridView:
0267     {
0268         qCDebug(orgKdeElisaViews()) << "ViewManager::openViewFromData" << viewParamaters.mViewPresentationType
0269                                     << viewParamaters.mFilterType
0270                                     << viewParamaters.mDepth << viewParamaters.mMainTitle << viewParamaters.mSecondaryTitle
0271                                     << viewParamaters.mMainImage << viewParamaters.mDataType
0272                                     << viewParamaters.mModelType << viewParamaters.mFallbackItemIcon
0273                                     << viewParamaters.mDataFilter
0274                                     << viewParamaters.mViewCanBeRated << viewParamaters.mShowSecondaryTextOnDelegates;
0275 
0276         auto configurationData = std::make_unique<ViewConfigurationData>(viewParamaters.mFilterType, viewParamaters.mDepth,
0277                                                                          viewParamaters.mMainTitle, viewParamaters.mSecondaryTitle,
0278                                                                          viewParamaters.mMainImage, viewParamaters.mDataType,
0279                                                                          newModel, proxyModel, viewParamaters.mFallbackItemIcon,
0280                                                                          viewParamaters.mDataFilter,
0281                                                                          computePreferredSortRole(viewParamaters.mSortRole, viewParamaters.mFilterType),
0282                                                                          viewParamaters.mSortRoles, viewParamaters.mSortRoleNames,
0283                                                                          computePreferredSortOrder(viewParamaters.mSortOrder, viewParamaters.mFilterType),
0284                                                                          viewParamaters.mSortOrderNames,
0285                                                                          viewParamaters.mViewCanBeRated, viewParamaters.mShowSecondaryTextOnDelegates);
0286 
0287         QQmlEngine::setObjectOwnership(configurationData.get(), QQmlEngine::JavaScriptOwnership);
0288 
0289         Q_EMIT openGridView(configurationData.release());
0290         break;
0291     }
0292     case ViewPresentationType::ListView:
0293     {
0294         qCDebug(orgKdeElisaViews()) << "ViewManager::openViewFromData" << viewParamaters.mFilterType
0295                                     << viewParamaters.mDepth << viewParamaters.mMainTitle << viewParamaters.mSecondaryTitle
0296                                     << viewParamaters.mDataFilter[DataTypes::DatabaseIdRole] << viewParamaters.mMainImage
0297                                     << viewParamaters.mModelType << viewParamaters.mDataType
0298                                     << viewParamaters.mDataFilter << viewParamaters.mSortRole
0299                                     << viewParamaters.mSortOrder << viewParamaters.mAlbumCardinality
0300                                     << viewParamaters.mAlbumViewStyle << viewParamaters.mRadioSpecificStyle;
0301 
0302         auto configurationData = std::make_unique<ViewConfigurationData>(viewParamaters.mFilterType, viewParamaters.mDepth,
0303                                                                          viewParamaters.mMainTitle, viewParamaters.mSecondaryTitle,
0304                                                                          viewParamaters.mMainImage, viewParamaters.mDataType,
0305                                                                          newModel, proxyModel, viewParamaters.mDataFilter,
0306                                                                          computePreferredSortRole(viewParamaters.mSortRole, viewParamaters.mFilterType),
0307                                                                          viewParamaters.mSortRoles, viewParamaters.mSortRoleNames,
0308                                                                          computePreferredSortOrder(viewParamaters.mSortOrder, viewParamaters.mFilterType),
0309                                                                          viewParamaters.mSortOrderNames,
0310                                                                          viewParamaters.mAlbumCardinality, viewParamaters.mAlbumViewStyle,
0311                                                                          viewParamaters.mRadioSpecificStyle);
0312 
0313         QQmlEngine::setObjectOwnership(configurationData.get(), QQmlEngine::JavaScriptOwnership);
0314 
0315         Q_EMIT openListView(configurationData.release());
0316         break;
0317     }
0318     case ContextView:
0319         qCDebug(orgKdeElisaViews()) << "ViewManager::openViewFromData" << viewParamaters.mViewPresentationType
0320                                     << viewParamaters.mDepth << viewParamaters.mMainTitle
0321                                     << viewParamaters.mMainImage;
0322         Q_EMIT switchContextView(viewParamaters.mDepth, viewParamaters.mMainTitle, viewParamaters.mMainImage);
0323         break;
0324     case UnknownViewPresentation:
0325         qCDebug(orgKdeElisaViews()) << "ViewManager::openViewFromData" << "unknown view type";
0326         break;
0327     }
0328 }
0329 
0330 void ViewManager::applyFilter(ViewParameters &nextViewParameters,
0331                               QString title, const ViewParameters &lastView) const
0332 {
0333     switch (nextViewParameters.mFilterType)
0334     {
0335     case ElisaUtils::NoFilter:
0336     case ElisaUtils::FilterByRecentlyPlayed:
0337     case ElisaUtils::FilterByFrequentlyPlayed:
0338     case ElisaUtils::FilterByPath:
0339     case ElisaUtils::FilterById:
0340     case ElisaUtils::UnknownFilter:
0341         break;
0342     case ElisaUtils::FilterByGenre:
0343         nextViewParameters.mDataFilter[DataTypes::GenreRole] = std::move(title);
0344         break;
0345     case ElisaUtils::FilterByGenreAndArtist:
0346         nextViewParameters.mDataFilter = lastView.mDataFilter;
0347         nextViewParameters.mDataFilter[DataTypes::ArtistRole] = std::move(title);
0348         break;
0349     case ElisaUtils::FilterByArtist:
0350         nextViewParameters.mDataFilter[DataTypes::ArtistRole] = std::move(title);
0351         break;
0352     }
0353 }
0354 
0355 QString ViewManager::buildViewId() const
0356 {
0357     const auto &entryTypeMetaEnum = QMetaEnum::fromType<ElisaUtils::PlayListEntryType>();
0358 
0359     const auto currView = d->mViewParametersStack.back();
0360     const auto viewId = QString::fromLatin1(entryTypeMetaEnum.valueToKey(currView.mDataType));
0361 
0362     return viewId;
0363 }
0364 
0365 QStringList::iterator ViewManager::findViewPreference(QStringList &list, const QString &viewId) const
0366 {
0367     auto itViewPreference = list.end();
0368     for(itViewPreference = list.begin(); itViewPreference != list.end(); ++itViewPreference) {
0369         auto parts = QStringView(*itViewPreference).split(QStringLiteral("=="));
0370         if (parts.size() != 2) {
0371             continue;
0372         }
0373         if (parts[0] == viewId) {
0374             break;
0375         }
0376     }
0377 
0378     return itViewPreference;
0379 }
0380 
0381 bool ViewManager::viewHasDefaultSortRole(const ElisaUtils::FilterType filterType) const
0382 {
0383     switch (filterType)
0384     {
0385     case ElisaUtils::FilterByRecentlyPlayed:
0386     case ElisaUtils::FilterByFrequentlyPlayed:
0387     case ElisaUtils::FilterById: // Tracks in album view
0388         return true;
0389     default:
0390         return false;
0391     }
0392 }
0393 
0394 Qt::SortOrder ViewManager::computePreferredSortOrder(Qt::SortOrder initialValue, ElisaUtils::FilterType filterType) const
0395 {
0396     if (viewHasDefaultSortRole(filterType)) {
0397         return initialValue;
0398     }
0399 
0400     auto currentSortOrderPreferences = Elisa::ElisaConfiguration::sortOrderPreferences();
0401     auto viewId = buildViewId();
0402     auto itViewPreference = findViewPreference(currentSortOrderPreferences, viewId);
0403 
0404     if (itViewPreference != currentSortOrderPreferences.end()) {
0405         auto result = QStringView(*itViewPreference).split(QStringLiteral("=="));
0406         if (result.size() == 2) {
0407             const auto &sortOrderMetaEnum = QMetaEnum::fromType<Qt::SortOrder>();
0408             bool conversionOk;
0409             auto newValue = static_cast<Qt::SortOrder>(sortOrderMetaEnum.keyToValue(result[1].toLatin1().data(), &conversionOk));
0410             if (conversionOk) {
0411                 initialValue = newValue;
0412             }
0413         }
0414     }
0415 
0416     return initialValue;
0417 }
0418 
0419 int ViewManager::computePreferredSortRole(int initialValue, ElisaUtils::FilterType filterType) const
0420 {
0421     if (viewHasDefaultSortRole(filterType)) {
0422         return initialValue;
0423     }
0424 
0425     auto currentSortRolePreferences = Elisa::ElisaConfiguration::sortRolePreferences();
0426     auto viewId = buildViewId();
0427     auto itViewPreference = findViewPreference(currentSortRolePreferences, viewId);
0428 
0429     if (itViewPreference != currentSortRolePreferences.end()) {
0430         auto result = QStringView(*itViewPreference).split(QStringLiteral("=="));
0431         if (result.size() == 2) {
0432             const auto &sortRoleMetaEnum = QMetaEnum::fromType<DataTypes::ColumnsRoles>();
0433             bool conversionOk;
0434             auto newValue = static_cast<DataTypes::ColumnsRoles>(sortRoleMetaEnum.keyToValue(result[1].toLatin1().data(), &conversionOk));
0435             if (conversionOk) {
0436                 initialValue = newValue;
0437             }
0438         }
0439     }
0440 
0441     return initialValue;
0442 }
0443 
0444 void ViewManager::goBack()
0445 {
0446     qCDebug(orgKdeElisaViews()) << "ViewManager::goBack" << d->mViewParametersStack.size()
0447                                 << d->mViewsListData;
0448 
0449     if (d->mViewParametersStack.size() <= 1) {
0450         return;
0451     }
0452 
0453     Q_EMIT popOneView();
0454 
0455     if (d->mViewParametersStack.size() > 1) {
0456         d->mViewParametersStack.pop_back();
0457     }
0458 
0459     qCDebug(orgKdeElisaViews()) << "ViewManager::goBack" << d->mViewParametersStack.size();
0460 }
0461 
0462 void ViewManager::setViewsData(ViewsListData *viewsData)
0463 {
0464     if (d->mViewsListData == viewsData) {
0465         return;
0466     }
0467 
0468     d->mViewsListData = viewsData;
0469     Q_EMIT viewsDataChanged();
0470 
0471     if (d->mViewsListData && (d->mViewIndex < 0 || d->mViewIndex >= d->mViewsListData->count())) {
0472         d->mViewIndex = d->mInitialIndex;
0473     }
0474 
0475     if (d->mViewsListData && d->mViewIndex >= 0 && d->mViewIndex < d->mViewsListData->count()) {
0476         openView(d->mViewIndex);
0477     }
0478 }
0479 
0480 void ViewManager::setInitialIndex(int newIndex)
0481 {
0482     if (d->mInitialIndex == newIndex) {
0483         return;
0484     }
0485 
0486     d->mInitialIndex = newIndex;
0487     Q_EMIT initialIndexChanged();
0488 
0489     if (d->mViewsListData && (d->mViewIndex < 0 || d->mViewIndex >= d->mViewsListData->count())) {
0490         d->mViewIndex = d->mInitialIndex;
0491     }
0492 
0493     if (d->mViewsListData && d->mViewIndex >= 0 && d->mViewIndex < d->mViewsListData->count()) {
0494         openView(d->mViewIndex);
0495     }
0496 }
0497 
0498 void ViewManager::setInitialFilesViewPath(const QString &initialPath)
0499 {
0500     if (d->mInitialFilesViewPath == initialPath) {
0501         return;
0502     }
0503 
0504     d->mInitialFilesViewPath = initialPath;
0505     Q_EMIT initialFilesViewPathChanged();
0506 }
0507 
0508 void ViewManager::openInitialView()
0509 {
0510     openView(d->mInitialIndex);
0511 }
0512 
0513 void ViewManager::sortOrderChanged(Qt::SortOrder sortOrder)
0514 {
0515     if (viewHasDefaultSortRole(d->mViewParametersStack.back().mFilterType)) {
0516         return;
0517     }
0518 
0519     auto currentSortOrderPreferences = Elisa::ElisaConfiguration::sortOrderPreferences();
0520 
0521     auto viewId = buildViewId();
0522     auto itViewPreference = findViewPreference(currentSortOrderPreferences, viewId);
0523 
0524     const auto &sortOrderMetaEnum = QMetaEnum::fromType<Qt::SortOrder>();
0525     auto enumStringValue = sortOrderMetaEnum.valueToKey(sortOrder);
0526     if (!enumStringValue) {
0527         return;
0528     }
0529     QString newSortOrderPreference = viewId + QStringLiteral("==") + QString::fromLatin1(enumStringValue);
0530 
0531     if (itViewPreference != currentSortOrderPreferences.end()) {
0532         (*itViewPreference) = newSortOrderPreference;
0533     } else {
0534         currentSortOrderPreferences.push_back(newSortOrderPreference);
0535     }
0536 
0537     Elisa::ElisaConfiguration::setSortOrderPreferences(currentSortOrderPreferences);
0538     Elisa::ElisaConfiguration::self()->save();
0539 }
0540 
0541 void ViewManager::sortRoleChanged(int sortRole)
0542 {
0543     if (viewHasDefaultSortRole(d->mViewParametersStack.back().mFilterType)) {
0544         return;
0545     }
0546 
0547     auto currentSortRolePreferences = Elisa::ElisaConfiguration::sortRolePreferences();
0548 
0549     auto viewId = buildViewId();
0550     auto itViewPreference = findViewPreference(currentSortRolePreferences, viewId);
0551 
0552     const auto &sortRoleMetaEnum = QMetaEnum::fromType<DataTypes::ColumnsRoles>();
0553     auto enumStringValue = sortRoleMetaEnum.valueToKey(static_cast<DataTypes::ColumnsRoles>(sortRole));
0554     if (!enumStringValue) {
0555         return;
0556     }
0557     QString newSortRolePreference = viewId + QStringLiteral("==") + QString::fromLatin1(enumStringValue);
0558 
0559     if (itViewPreference != currentSortRolePreferences.end()) {
0560         (*itViewPreference) = newSortRolePreference;
0561     } else {
0562         currentSortRolePreferences.push_back(newSortRolePreference);
0563     }
0564 
0565     Elisa::ElisaConfiguration::setSortRolePreferences(currentSortRolePreferences);
0566     Elisa::ElisaConfiguration::self()->save();
0567 }
0568 
0569 bool ViewManager::isSameView(const ViewParameters &currentView, const ViewParameters &otherView) const {
0570     if (currentView.mDataType != otherView.mDataType) {
0571         return false;
0572     }
0573 
0574     // Best case scenario is matching up database ids
0575     if (currentView.mDataFilter.hasDatabaseId() && otherView.mDataFilter.hasDatabaseId()) {
0576         return currentView.mDataFilter.databaseId() == otherView.mDataFilter.databaseId();
0577     }
0578 
0579     // Unfortunately we don't have access to database ids for most of these types, so handle specific types differently.
0580     switch (currentView.mDataType) {
0581         case ElisaUtils::PlayListEntryType::Album:
0582         case ElisaUtils::PlayListEntryType::Artist:
0583             return currentView.mMainTitle == otherView.mMainTitle;
0584         default:
0585             return false;
0586     }
0587 }
0588 
0589 
0590 #include "moc_viewmanager.cpp"