File indexing completed on 2024-05-19 04:50:28

0001 /****************************************************************************************
0002  * Copyright (c) 2012 Matěj Laitl <matej@laitl.cz>                                      *
0003  *                                                                                      *
0004  * This program is free software; you can redistribute it and/or modify it under        *
0005  * the terms of the GNU General Public License as published by the Free Software        *
0006  * Foundation; either version 2 of the License, or (at your option) any later           *
0007  * version.                                                                             *
0008  *                                                                                      *
0009  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0010  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0011  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0012  *                                                                                      *
0013  * You should have received a copy of the GNU General Public License along with         *
0014  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0015  ****************************************************************************************/
0016 
0017 #include "CommonModel.h"
0018 
0019 #include "MetaValues.h"
0020 #include "core/meta/support/MetaConstants.h"
0021 #include "core/support/Debug.h"
0022 #include "statsyncing/Options.h"
0023 
0024 #include <QIcon>
0025 #include <KLocalizedString>
0026 
0027 #include <QApplication>
0028 #include <QHeaderView>
0029 
0030 using namespace StatSyncing;
0031 
0032 const QSize CommonModel::s_ratingSize( 5*16, 16 );
0033 
0034 CommonModel::CommonModel( const QList<qint64> &columns, const Options &options )
0035     : m_columns( columns )
0036     , m_options( options )
0037 {
0038     Q_ASSERT( m_columns.value( 0 ) == Meta::valTitle );
0039 }
0040 
0041 QVariant
0042 CommonModel::headerData( int section, Qt::Orientation orientation, int role ) const
0043 {
0044     if( orientation != Qt::Horizontal || section < 0 || section >= m_columns.count() )
0045         return QVariant();
0046     qint64 field = m_columns.at( section );
0047     switch( role )
0048     {
0049         case Qt::DisplayRole:
0050             return Meta::i18nForField( field );
0051         case Qt::SizeHintRole:
0052             return sizeHintData( field );
0053         case ResizeModeRole:
0054             switch( field )
0055             {
0056                 case Meta::valTitle:
0057                     return QHeaderView::Stretch;
0058                 case Meta::valRating:
0059                 case Meta::valFirstPlayed:
0060                 case Meta::valLastPlayed:
0061                 case Meta::valPlaycount:
0062                     return QHeaderView::ResizeToContents;
0063                 default:
0064                     return QHeaderView::Interactive;
0065             }
0066         case FieldRole:
0067             return field;
0068     }
0069     return QVariant();
0070 }
0071 
0072 QVariant
0073 CommonModel::sizeHintData( qint64 field ) const
0074 {
0075     switch( field )
0076     {
0077         case Meta::valRating:
0078         {
0079             static QSize size;
0080             if( size.isValid() ) // optimization
0081                 return size;
0082             QStyleOptionViewItem opt;
0083             opt.features = QStyleOptionViewItem::HasDisplay
0084                          | QStyleOptionViewItem::HasCheckIndicator
0085                          | QStyleOptionViewItem::HasDecoration;
0086             opt.state = QStyle::State_Enabled;
0087             opt.decorationSize = s_ratingSize;
0088 
0089             const QWidget *widget = opt.widget;
0090             QStyle *style = widget ? widget->style() : QApplication::style();
0091             size = style->sizeFromContents( QStyle::CT_ItemViewItem, &opt, QSize(), widget );
0092             return size;
0093         }
0094         case Meta::valFirstPlayed:
0095         case Meta::valLastPlayed:
0096         {
0097             static QSize size;
0098             if( size.isValid() ) // optimization
0099                 return size;
0100             QStyleOptionViewItem opt;
0101             opt.features = QStyleOptionViewItem::HasDisplay;
0102             opt.state = QStyle::State_Enabled;
0103             opt.text = QLatin1String("88.88.8888 88:88");
0104 
0105             QStyle *style = QApplication::style();
0106             size = style->sizeFromContents( QStyle::CT_ItemViewItem, &opt, QSize(), nullptr );
0107             return size;
0108         }
0109         case Meta::valPlaycount:
0110         {
0111             static QSize size;
0112             if( size.isValid() ) // optimization
0113                 return size;
0114             QStyleOptionViewItem opt;
0115             opt.features = QStyleOptionViewItem::HasDisplay;
0116             opt.state = QStyle::State_Enabled;
0117             opt.text = QLatin1String("888 (88)");
0118             opt.font.setBold( true );
0119 
0120             QStyle *style = QApplication::style();
0121             size = style->sizeFromContents( QStyle::CT_ItemViewItem, &opt, QSize(), nullptr );
0122             return size;
0123         }
0124     }
0125     return QVariant();
0126 }
0127 
0128 QVariant
0129 CommonModel::textAlignmentData( qint64 field ) const
0130 {
0131     switch( field )
0132     {
0133         case Meta::valRating:
0134         case Meta::valFirstPlayed:
0135         case Meta::valLastPlayed:
0136         case Meta::valPlaycount:
0137             return Qt::AlignRight;
0138     }
0139     return QVariant();
0140 }
0141 
0142 QVariant
0143 CommonModel::trackData( const TrackPtr &track, qint64 field, int role ) const
0144 {
0145     switch( role )
0146     {
0147         case Qt::DisplayRole:
0148             switch( field )
0149             {
0150                 case Meta::valTitle:
0151                     return trackTitleData( track );
0152                 case Meta::valRating:
0153                     return track->rating();
0154                 case Meta::valFirstPlayed:
0155                     return track->firstPlayed();
0156                 case Meta::valLastPlayed:
0157                     return track->lastPlayed();
0158                 case Meta::valPlaycount:
0159                 {
0160                     int recent = track->recentPlayCount();
0161                     return recent ? QVariant( i18nc( "%1 is play count and %2 is recent play count",
0162                         "%1 (%2)", track->playCount(), recent ) ) : QVariant( track->playCount() );
0163                 }
0164                 case Meta::valLabel:
0165                     return QStringList( ( track->labels() - m_options.excludedLabels() ).values() ).join( i18nc(
0166                         "comma between list words", ", " ) );
0167                 default:
0168                     return QStringLiteral( "Unknown field!" );
0169             }
0170             break;
0171         case Qt::ToolTipRole:
0172             switch( field )
0173             {
0174                 case Meta::valTitle:
0175                     return trackToolTipData( track );
0176                 case Meta::valPlaycount:
0177                     return i18np( "Played %2 times of which one play is recent and unique "
0178                         "to this source", "Played %2 times of which %1 plays are recent "
0179                         "and unique to this source", track->recentPlayCount(), track->playCount() );
0180                 case Meta::valLabel:
0181                 {
0182                     QSet<QString> labels = track->labels() - m_options.excludedLabels();
0183                     QSet<QString> excludedLabels = track->labels() & m_options.excludedLabels();
0184                     QStringList texts;
0185                     if( !labels.isEmpty() )
0186                         texts << i18n( "Labels: %1", QStringList( labels.values() ).join( i18nc(
0187                         "comma between list words", ", " ) ) );
0188                     if( !excludedLabels.isEmpty() )
0189                         texts << i18n( "Ignored labels: %1", QStringList( excludedLabels.values() ).join( i18nc(
0190                             "comma between list words", ", " ) ) );
0191                     return texts.isEmpty() ? QVariant() : texts.join( QStringLiteral("\n") );
0192                 }
0193             }
0194             break;
0195         case Qt::TextAlignmentRole:
0196             return textAlignmentData( field );
0197         case Qt::SizeHintRole:
0198             return sizeHintData( field );
0199         case FieldRole:
0200             return field;
0201     }
0202     return QVariant();
0203 }
0204 
0205 QVariant
0206 CommonModel::trackTitleData( const TrackPtr &track ) const
0207 {
0208     return i18n( "%1 - %2 - %3", track->artist(), track->album(), track->name() );
0209 }
0210 
0211 QVariant
0212 CommonModel::trackToolTipData( const TrackPtr &track ) const
0213 {
0214     return trackTitleData( track ); // TODO nicer toolTip, display more fields
0215 }