[kde-doc-english] [amarok] /: Collection Browser: replace "Artist" by "Album Artist" by default

Matěj Laitl matej at laitl.cz
Thu Jun 27 18:35:28 UTC 2013


Git commit 78415dfb1d44c59a0f53748071ce57b794abd83a by Matěj Laitl.
Committed on 27/06/2013 at 18:13.
Pushed by laitl into branch 'master'.

Collection Browser: replace "Artist" by "Album Artist" by default

CHANGES:
 * Collection Browser: Artist level was renamed to Track Artist and replaced by Album
   Artist by default. Various Artists item is no longer shown under Track Artist level.

Following was done:
 a) shop showing "Various Artists" under "Artist" level and therefore
    stop showing some tracks twice. Show "Various Artists" only under the
    "Album Artist" level where it logically belongs
 b) tweak the default presets to use "Album Artist" where they previously
    used "Arist", except for "Album / Artist" where it doesn't make sense
 c) adapt user configs treat "artist" as "album artist" for users migrating
    from older Amarok releases
 d) rename "Artist" level to "Track Artist" make the distinction more clear
 e) use current "Artist" icon even for Album Artist level, Sentynel and
    Mamarok finds the current one way too fugly

^^^ I think that the points above combined would mean nearly no
disruption in user experience and would make the interface more logical
and correct.

GUI: A set of changes to Collection Browser levels, "Artist" level was
renamed to "Track Artist", its behaviour was changed and it was replaced
by "Album Artist" by default.
CCMAIL: amarok-devel at kde.org
CCMAIL: amarok-promo at kde.org

M  +2    -0    ChangeLog
M  +1    -1    src/browsers/BrowserDefines.h
M  +49   -30   src/browsers/CollectionTreeItemModelBase.cpp
M  +6    -1    src/browsers/CollectionTreeItemModelBase.h
M  +78   -88   src/browsers/collectionbrowser/CollectionWidget.cpp
M  +4    -4    src/browsers/collectionbrowser/CollectionWidget.h

http://commits.kde.org/amarok/78415dfb1d44c59a0f53748071ce57b794abd83a

diff --git a/ChangeLog b/ChangeLog
index a0a39d0..84eb9e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -33,6 +33,8 @@ VERSION 2.8-Beta 1
    * Added Ctrl+H shortcut to randomize playlist, patch by Harsh Gupta. (BR 208061)
 
   CHANGES:
+   * Collection Browser: Artist level was renamed to Track Artist and replaced by Album
+     Artist by default. Various Artists item is no longer shown under Track Artist level.
    * Removed the splash screen.
    * Playlist-related actions were harmonized, double-clicking or pressing enter will
      append tracks to playlist, middle-clicking or using any "play media" action will
diff --git a/src/browsers/BrowserDefines.h b/src/browsers/BrowserDefines.h
index d3f01f2..8e0f258 100644
--- a/src/browsers/BrowserDefines.h
+++ b/src/browsers/BrowserDefines.h
@@ -30,7 +30,7 @@ namespace CategoryId
     enum CatMenuId {
         None = 0,
         Album = 1,
-        Artist = 2,
+        Artist = 8, // used to be 2, transitioned to 8 to allow for transition pre Amarok 2.8
         AlbumArtist = 3,
         Composer = 4,
         Genre = 5,
diff --git a/src/browsers/CollectionTreeItemModelBase.cpp b/src/browsers/CollectionTreeItemModelBase.cpp
index b811c34..4ec642b 100644
--- a/src/browsers/CollectionTreeItemModelBase.cpp
+++ b/src/browsers/CollectionTreeItemModelBase.cpp
@@ -54,8 +54,12 @@ inline uint qHash( const Meta::DataPtr &data )
     return qHash( data.data() );
 }
 
+/**
+ * This set determines which collection browser levels should have shown Various Artists
+ * item under them. AlbumArtist is certain, (Track)Artist is questionable.
+ */
 static const QSet<CategoryId::CatMenuId> variousArtistCategories =
-        QSet<CategoryId::CatMenuId>() << CategoryId::AlbumArtist << CategoryId::Artist;
+        QSet<CategoryId::CatMenuId>() << CategoryId::AlbumArtist;
 
 CollectionTreeItemModelBase::CollectionTreeItemModelBase( )
     : QAbstractItemModel()
@@ -485,31 +489,6 @@ CollectionTreeItemModelBase::ensureChildrenLoaded( CollectionTreeItem *item )
     }
 }
 
-QIcon
-CollectionTreeItemModelBase::iconForLevel(int level) const
-{
-    switch( m_levelType.value( level ) )
-    {
-        case CategoryId::Album :
-            return KIcon( "media-optical-amarok" );
-        case CategoryId::Artist :
-            return KIcon( "view-media-artist-amarok" );
-        case CategoryId::AlbumArtist :
-            return KIcon( "amarok_artist" );
-        case CategoryId::Composer :
-            return KIcon( "filename-composer-amarok" );
-        case CategoryId::Genre :
-            return KIcon( "favorite-genres-amarok" );
-        case CategoryId::Year :
-            return KIcon( "clock" );
-        case CategoryId::Label :
-            return KIcon( "label-amarok" );
-        case CategoryId::None :
-        default:
-            return KIcon( "image-missing" );
-    }
-}
-
 void CollectionTreeItemModelBase::listForLevel(int level, Collections::QueryMaker * qm, CollectionTreeItem * parent)
 {
     if( qm && parent )
@@ -967,15 +946,47 @@ CollectionTreeItemModelBase::updateHeaderText()
     m_headerText.chop( 3 );
 }
 
+QIcon
+CollectionTreeItemModelBase::iconForCategory( CategoryId::CatMenuId category )
+{
+    switch( category )
+    {
+        case CategoryId::Album :
+            return KIcon( "media-optical-amarok" );
+        case CategoryId::Artist :
+            return KIcon( "view-media-artist-amarok" );
+        case CategoryId::AlbumArtist :
+            return KIcon( "view-media-artist-amarok" );
+        case CategoryId::Composer :
+            return KIcon( "filename-composer-amarok" );
+        case CategoryId::Genre :
+            return KIcon( "favorite-genres-amarok" );
+        case CategoryId::Year :
+            return KIcon( "clock" );
+        case CategoryId::Label :
+            return KIcon( "label-amarok" );
+        case CategoryId::None:
+        default:
+            return KIcon( "image-missing" );
+    }
+
+}
+
+QIcon
+CollectionTreeItemModelBase::iconForLevel( int level ) const
+{
+    return iconForCategory( m_levelType.value( level ) );
+}
+
 QString
-CollectionTreeItemModelBase::nameForLevel( int level ) const
+CollectionTreeItemModelBase::nameForCategory( CategoryId::CatMenuId category, bool showYears )
 {
-    switch( m_levelType.value( level ) )
+    switch( category )
     {
         case CategoryId::Album:
-            return AmarokConfig::showYears() ? i18n( "Year - Album" ) : i18n( "Album" );
+            return showYears ? i18n( "Year - Album" ) : i18n( "Album" );
         case CategoryId::Artist:
-            return i18n( "Artist" );
+            return i18n( "Track Artist" );
         case CategoryId::AlbumArtist:
             return i18n( "Album Artist" );
         case CategoryId::Composer:
@@ -986,11 +997,19 @@ CollectionTreeItemModelBase::nameForLevel( int level ) const
             return i18n( "Year" );
         case CategoryId::Label:
             return i18n( "Label" );
+        case CategoryId::None:
+            return i18n( "None" );
         default:
             return QString();
     }
 }
 
+QString
+CollectionTreeItemModelBase::nameForLevel( int level ) const
+{
+    return nameForCategory( m_levelType.value( level ), AmarokConfig::showYears() );
+}
+
 void
 CollectionTreeItemModelBase::handleCompilations( Collections::QueryMaker::QueryType queryType, CollectionTreeItem *parent ) const
 {
diff --git a/src/browsers/CollectionTreeItemModelBase.h b/src/browsers/CollectionTreeItemModelBase.h
index f65c782..146d95d 100644
--- a/src/browsers/CollectionTreeItemModelBase.h
+++ b/src/browsers/CollectionTreeItemModelBase.h
@@ -69,7 +69,6 @@ class AMAROK_EXPORT CollectionTreeItemModelBase : public QAbstractItemModel
         virtual QMimeData* mimeData( const QList<CollectionTreeItem*> &items ) const;
         virtual QMimeData* mimeData( const QModelIndexList &indices ) const;
 
-        virtual QIcon iconForLevel( int level ) const;
         virtual void listForLevel( int level, Collections::QueryMaker *qm, CollectionTreeItem* parent );
 
         virtual void setLevels( const QList<CategoryId::CatMenuId> &levelType );
@@ -98,6 +97,9 @@ class AMAROK_EXPORT CollectionTreeItemModelBase : public QAbstractItemModel
          */
         bool hasRunningQueries() const;
 
+        static QIcon iconForCategory( CategoryId::CatMenuId category );
+        static QString nameForCategory( CategoryId::CatMenuId category, bool showYears = false );
+
     signals:
         void expandIndex( const QModelIndex &index );
         void allQueriesFinished();
@@ -128,7 +130,10 @@ class AMAROK_EXPORT CollectionTreeItemModelBase : public QAbstractItemModel
     protected:
         virtual void populateChildren(const Meta::DataList &dataList, CollectionTreeItem *parent, const QModelIndex &parentIndex );
         virtual void updateHeaderText();
+
+        virtual QIcon iconForLevel( int level ) const;
         virtual QString nameForLevel( int level ) const;
+
         virtual int levelModifier() const = 0;
         virtual QVariant dataForItem( CollectionTreeItem *item, int role, int level = -1 ) const;
 
diff --git a/src/browsers/collectionbrowser/CollectionWidget.cpp b/src/browsers/collectionbrowser/CollectionWidget.cpp
index 8e2c881..87290fa 100644
--- a/src/browsers/collectionbrowser/CollectionWidget.cpp
+++ b/src/browsers/collectionbrowser/CollectionWidget.cpp
@@ -56,6 +56,8 @@ CollectionWidget *CollectionWidget::s_instance = 0;
 
 #define CATEGORY_LEVEL_COUNT 3
 
+Q_DECLARE_METATYPE( QList<CategoryId::CatMenuId> ) // needed to QAction payload
+
 class CollectionWidget::Private
 {
 public:
@@ -156,14 +158,6 @@ CollectionWidget::CollectionWidget( const QString &name , QWidget *parent )
     KHBox *hbox = new KHBox( this );
     d->stack = new QStackedWidget( this );
 
-    // -- read the view level settings from the configuration
-    QList<int> levelNumbers = Amarok::config( "Collection Browser" ).readEntry( "TreeCategory", QList<int>() );
-    QList<CategoryId::CatMenuId> levels;
-    foreach( int levelNumber, levelNumbers )
-        levels << CategoryId::CatMenuId( levelNumber );
-    if ( levels.isEmpty() )
-        levels << CategoryId::Artist << CategoryId::Album;
-
     // -- read the current view mode from the configuration
     const QMetaObject *mo = metaObject();
     const QMetaEnum me = mo->enumerator( mo->indexOfEnumerator( "ViewMode" ) );
@@ -190,78 +184,67 @@ CollectionWidget::CollectionWidget( const QString &name , QWidget *parent )
 
     QMenu *filterMenu = new QMenu( 0 );
 
-    QAction *action = new QAction( i18n( "Artist / Album" ), this );
-    connect( action, SIGNAL(triggered(bool)), SLOT(sortByArtistAlbum()) );
-    filterMenu->addAction( action );
-
-    action = new QAction( i18n( "Album / Artist" ), this );
-    connect( action, SIGNAL(triggered(bool)), SLOT(sortByAlbumArtist()) );
-    filterMenu->addAction( action );
-
-    action = new QAction( i18n( "Genre / Artist" ), this );
-    connect( action, SIGNAL(triggered(bool)), SLOT(sortByGenreArtist()) );
-    filterMenu->addAction( action );
-
-    action = new QAction( i18n( "Genre / Artist / Album" ), this );
-    connect( action, SIGNAL(triggered(bool)), SLOT(sortByGenreArtistAlbum()) );
-    filterMenu->addAction( action );
-
+    using namespace CategoryId;
+    static const QList<QList<CatMenuId> > levelPresets = QList<QList<CatMenuId> >()
+        << ( QList<CatMenuId>() << CategoryId::AlbumArtist << CategoryId::Album )
+        << ( QList<CatMenuId>() << CategoryId::Album << CategoryId::Artist ) // album artist has no sense here
+        << ( QList<CatMenuId>() << CategoryId::Genre << CategoryId::AlbumArtist )
+        << ( QList<CatMenuId>() << CategoryId::Genre << CategoryId::AlbumArtist << CategoryId::Album );
+    foreach( const QList<CatMenuId> &levels, levelPresets )
+    {
+        QStringList categoryLabels;
+        foreach( CatMenuId category, levels )
+            categoryLabels << CollectionTreeItemModelBase::nameForCategory( category );
+        QAction *action = filterMenu->addAction( categoryLabels.join( i18nc(
+                "separator between collection browser level categories, i.e. the ' / ' "
+                "in 'Artist / Album'", " / " ) ) );
+        action->setData( QVariant::fromValue( levels ) );
+    }
+    // following catches all actions in the filter menu
+    connect( filterMenu, SIGNAL(triggered(QAction*)), SLOT(sortByActionPayload(QAction*)) );
     filterMenu->addSeparator();
 
+    // -- read the view level settings from the configuration
+    QList<CategoryId::CatMenuId> levels = readLevelsFromConfig();
+    if ( levels.isEmpty() )
+        levels << levelPresets.at( 0 ); // use first preset as default
+
     // -- generate the level menus
     d->menuLevel[0] = filterMenu->addMenu( i18n( "First Level" ) );
     d->menuLevel[1] = filterMenu->addMenu( i18n( "Second Level" ) );
     d->menuLevel[2] = filterMenu->addMenu( i18n( "Third Level" ) );
 
     // - fill the level menus
+    static const QList<CatMenuId> levelChoices = QList<CatMenuId>()
+            << CategoryId::AlbumArtist
+            << CategoryId::Artist
+            << CategoryId::Album
+            << CategoryId::Genre
+            << CategoryId::Composer
+            << CategoryId::Label;
     for( int i = 0; i < CATEGORY_LEVEL_COUNT; i++ )
     {
+        QList<CatMenuId> usedLevelChoices = levelChoices;
         QActionGroup *actionGroup = new QActionGroup( this );
+        if( i > 0 ) // skip first submenu
+            usedLevelChoices.prepend( CategoryId::None );
 
-        if( i > 0 )
+        QMenu *menuLevel = d->menuLevel[i];
+        foreach( CatMenuId level, usedLevelChoices )
         {
-            QAction *action = d->menuLevel[i]->addAction( i18n( "None" ) );
-            action->setData( CategoryId::None );
+            QAction *action = menuLevel->addAction( CollectionTreeItemModelBase::nameForCategory( level ) );
+            action->setData( QVariant::fromValue<CatMenuId>( level ) );
             action->setCheckable( true );
+            action->setChecked( ( levels.count() > i ) ? ( levels[i] == level )
+                    : ( level == CategoryId::None ) );
             actionGroup->addAction( action );
-
-            if( levels.count() <= i )
-                action->setChecked( true );
-        }
-
-        // - and now the different selections
-        struct LevelDefinition {
-            qint64 field;
-            CategoryId::CatMenuId menuId;
-        };
-        LevelDefinition definitions[] = { {Meta::valArtist, CategoryId::Artist},
-                                          {Meta::valAlbum, CategoryId::Album},
-                                          {Meta::valAlbumArtist, CategoryId::AlbumArtist},
-                                          {Meta::valGenre, CategoryId::Genre},
-                                          {Meta::valComposer, CategoryId::Composer},
-                                          {Meta::valLabel, CategoryId::Label} };
-
-        for( unsigned int j = 0; j < sizeof( definitions ) / sizeof( definitions[0] ); j++ )
-        {
-            QAction *action = d->menuLevel[i]->addAction( Meta::i18nForField( definitions[j].field ) );
-            action->setData( QVariant::fromValue<CategoryId::CatMenuId>( definitions[j].menuId ) );
-            action->setCheckable( true );
-            actionGroup->addAction( action );
-
-            if( levels.count() > i && levels[i] == definitions[j].menuId )
-                action->setChecked( true );
         }
 
         d->levelGroups[i] = actionGroup;
+        connect( menuLevel, SIGNAL(triggered(QAction*)), SLOT(sortLevelSelected(QAction*)) );
     }
 
-    connect( d->menuLevel[0], SIGNAL(triggered(QAction*)), SLOT(sortLevelSelected(QAction*)) );
-    connect( d->menuLevel[1], SIGNAL(triggered(QAction*)), SLOT(sortLevelSelected(QAction*)) );
-    connect( d->menuLevel[2], SIGNAL(triggered(QAction*)), SLOT(sortLevelSelected(QAction*)) );
-
-
-    // -- create the checkboxes
-
+    // -- create the checkboxesh
     filterMenu->addSeparator();
     QAction *showYears = filterMenu->addAction( i18n( "Show Years" ) );
     showYears->setCheckable( true );
@@ -331,35 +314,11 @@ CollectionWidget::sortLevelSelected( QAction *action )
 }
 
 void
-CollectionWidget::sortByArtistAlbum()
-{
-    QList<CategoryId::CatMenuId> levels;
-    levels << CategoryId::Artist << CategoryId::Album;
-    setLevels( levels );
-}
-
-void
-CollectionWidget::sortByAlbumArtist()
-{
-    QList<CategoryId::CatMenuId> levels;
-    levels << CategoryId::Album << CategoryId::Artist;
-    setLevels( levels );
-}
-
-void
-CollectionWidget::sortByGenreArtist()
+CollectionWidget::sortByActionPayload( QAction *action )
 {
-    QList<CategoryId::CatMenuId> levels;
-    levels << CategoryId::Genre << CategoryId::Artist;
-    setLevels( levels );
-}
-
-void
-CollectionWidget::sortByGenreArtistAlbum()
-{
-    QList<CategoryId::CatMenuId> levels;
-    levels << CategoryId::Genre << CategoryId::Artist << CategoryId::Album;
-    setLevels( levels );
+    QList<CategoryId::CatMenuId> levels = action->data().value<QList<CategoryId::CatMenuId> >();
+    if( !levels.isEmpty() )
+        setLevels( levels );
 }
 
 void
@@ -464,4 +423,35 @@ void CollectionWidget::toggleView( bool merged )
     Amarok::config( "Collection Browser" ).writeEntry( "View Mode", me.valueToKey( d->viewMode ) );
 }
 
+QList<CategoryId::CatMenuId>
+CollectionWidget::readLevelsFromConfig() const
+{
+    QList<int> levelNumbers = Amarok::config( "Collection Browser" ).readEntry( "TreeCategory", QList<int>() );
+    QList<CategoryId::CatMenuId> levels;
+
+    // we changed "Track Artist" to "Album Artist" default before Amarok 2.8. Migrate user
+    // config mentioning Track Artist to Album Artist where it makes sense:
+    static const int OldArtistValue = 2;
+    bool albumOrAlbumArtistEncountered = false;
+    foreach( int levelNumber, levelNumbers )
+    {
+        CategoryId::CatMenuId category;
+        if( levelNumber == OldArtistValue )
+        {
+            if( albumOrAlbumArtistEncountered )
+                category = CategoryId::Artist;
+            else
+                category = CategoryId::AlbumArtist;
+        }
+        else
+            category = CategoryId::CatMenuId( levelNumber );
+
+        levels << category;
+        if( category == CategoryId::Album || category == CategoryId::AlbumArtist )
+            albumOrAlbumArtistEncountered = true;
+    }
+
+    return levels;
+}
+
 #include "CollectionWidget.moc"
diff --git a/src/browsers/collectionbrowser/CollectionWidget.h b/src/browsers/collectionbrowser/CollectionWidget.h
index c281f41..7480015 100644
--- a/src/browsers/collectionbrowser/CollectionWidget.h
+++ b/src/browsers/collectionbrowser/CollectionWidget.h
@@ -55,12 +55,10 @@ class CollectionWidget : public BrowserCategory
         void setLevels( const QList<CategoryId::CatMenuId> &levels );
 
         void focusInputLine();
+
     public slots:
         void sortLevelSelected( QAction * );
-        void sortByArtistAlbum();
-        void sortByAlbumArtist();
-        void sortByGenreArtist();
-        void sortByGenreArtistAlbum();
+        void sortByActionPayload( QAction * );
         void slotShowYears( bool checked );
         void slotShowTrackNumbers( bool checked );
         void slotShowCovers( bool checked );
@@ -68,6 +66,8 @@ class CollectionWidget : public BrowserCategory
         void toggleView( bool merged );
 
     private:
+        QList<CategoryId::CatMenuId> readLevelsFromConfig() const;
+
         class Private;
         Private *const d;
         static CollectionWidget *s_instance;



More information about the kde-doc-english mailing list