File indexing completed on 2024-05-05 04:51:37

0001 /*
0002     SPDX-FileCopyrightText: 2010 Michal Malek <michalm@jabster.pl>
0003     SPDX-FileCopyrightText: 1998-2010 Sebastian Trueg <trueg@k3b.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "k3bexternalbinmodel.h"
0009 #include "k3bexternalbinmanager.h"
0010 
0011 #include <KLocalizedString>
0012 
0013 #include <QHash>
0014 #include <QList>
0015 #include <QFont>
0016 #include <QPalette>
0017 #include <QApplication>
0018 
0019 namespace K3b {
0020 
0021 class ExternalBinModel::Private
0022 {
0023 public:
0024     Private( ExternalBinManager* m ) : manager( m ) {}
0025 
0026     ExternalBinManager* manager;
0027     QList<ExternalProgram*> programs;
0028     QHash<ExternalProgram*,const ExternalBin*> defaults;
0029 };
0030 
0031 ExternalBinModel::ExternalBinModel( ExternalBinManager* manager, QObject* parent )
0032     : QAbstractItemModel( parent ),
0033       d( new Private( manager ) )
0034 {
0035 }
0036 
0037 
0038 ExternalBinModel::~ExternalBinModel()
0039 {
0040     delete d;
0041 }
0042 
0043 
0044 void ExternalBinModel::reload()
0045 {
0046     beginResetModel();
0047 
0048     d->programs.clear();
0049     d->defaults.clear();
0050 
0051     // load programs
0052     const QMap<QString, K3b::ExternalProgram*>& map = d->manager->programs();
0053     for( QMap<QString, K3b::ExternalProgram*>::const_iterator it = map.begin(); it != map.end(); ++it ) {
0054 
0055         K3b::ExternalProgram* p = *it;
0056         d->programs.append( p );
0057         d->defaults.insert( p, p->defaultBin() );
0058     }
0059 
0060     endResetModel();
0061 }
0062 
0063 
0064 void ExternalBinModel::save()
0065 {
0066     Q_FOREACH( ExternalProgram* program, d->programs ) {
0067         program->setDefault( d->defaults[ program ] );
0068     }
0069 }
0070 
0071 
0072 ExternalProgram* ExternalBinModel::programForIndex( const QModelIndex& index ) const
0073 {
0074     if( index.isValid() && index.internalPointer() == 0 &&
0075         index.row() >= 0 && index.row() < d->programs.size() )
0076         return d->programs.at( index.row() );
0077     else
0078         return 0;
0079 }
0080 
0081 
0082 QModelIndex ExternalBinModel::indexForProgram( ExternalProgram* program, int column ) const
0083 {
0084     int i = d->programs.indexOf( program );
0085     if( i >= 0 && i < d->programs.size() )
0086         return createIndex( i, column, nullptr );
0087     else
0088         return QModelIndex();
0089 }
0090 
0091 
0092 const ExternalBin* ExternalBinModel::binForIndex( const QModelIndex& index ) const
0093 {
0094     if( index.isValid() && index.internalId() != 0 )
0095         return static_cast<const ExternalBin*>( index.internalPointer() );
0096     else
0097         return 0;
0098 }
0099 
0100 
0101 QModelIndex ExternalBinModel::indexForBin( const ExternalBin* bin, int column ) const
0102 {
0103     if( bin ) {
0104         int i = bin->program().bins().indexOf( bin );
0105         if( i >= 0 && i < bin->program().bins().size() )
0106             return createIndex( i, column, const_cast<void*>( reinterpret_cast<const void*>( bin ) ) );
0107     }
0108     return QModelIndex();
0109 }
0110 
0111 
0112 QModelIndex ExternalBinModel::index( int row, int column, const QModelIndex& parent ) const
0113 {
0114     if( !hasIndex( row, column, parent ) )
0115         return QModelIndex();
0116     else if( ExternalProgram* program = programForIndex( parent ) )
0117         return indexForBin( program->bins().at( row ), column );
0118     else
0119         return indexForProgram( d->programs.at( row ), column );
0120 }
0121 
0122 
0123 QModelIndex ExternalBinModel::parent( const QModelIndex& index ) const
0124 {
0125     if( const ExternalBin* bin = binForIndex( index ) )
0126         return indexForProgram( &bin->program() );
0127     else
0128         return QModelIndex();
0129 }
0130 
0131 
0132 Qt::ItemFlags ExternalBinModel::flags( const QModelIndex& index ) const
0133 {
0134     if( programForIndex( index ) != 0 )
0135     {
0136         return Qt::ItemIsEnabled;
0137     }
0138     else if( const ExternalBin* bin = binForIndex( index ) )
0139     {
0140         if( bin->program().bins().size() > 1 )
0141             return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
0142         else
0143             return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
0144     }
0145     else
0146     {
0147         return Qt::ItemFlags();
0148     }
0149 }
0150 
0151 
0152 QVariant ExternalBinModel::data( const QModelIndex& index, int role ) const
0153 {
0154     if( ExternalProgram* program = programForIndex( index ) ) {
0155         if( Qt::DisplayRole == role && index.column() == PathColumn ) {
0156             if( program->bins().isEmpty() )
0157                 return i18n( "%1 (not found)", program->name() );
0158             else
0159                 return program->name();
0160         }
0161         else if( Qt::FontRole == role && index.column() == PathColumn ) {
0162             QFont font;
0163             font.setBold( true );
0164             return font;
0165         }
0166         else if( Qt::BackgroundRole == role ) {
0167             return QApplication::palette().alternateBase();
0168         }
0169     }
0170     else if( const ExternalBin* bin = binForIndex( index ) ) {
0171         if( Qt::DisplayRole == role ) {
0172             switch( index.column() ) {
0173                 case PathColumn: return bin->path();
0174                 case VersionColumn: return bin->version().toString();
0175                 case FeaturesColumn: return bin->features().join( ", " );
0176                 default: return QVariant();
0177             }
0178         }
0179         else if( Qt::CheckStateRole == role && index.column() == PathColumn ) {
0180             if( bin == d->defaults[ &bin->program() ] )
0181                 return Qt::Checked;
0182             else
0183                 return Qt::Unchecked;
0184         }
0185         else if( Qt::ToolTipRole == role && index.column() == FeaturesColumn ) {
0186             return bin->features().join( ", " );
0187         }
0188     }
0189     return QVariant();
0190 }
0191 
0192 
0193 bool ExternalBinModel::setData( const QModelIndex& index, const QVariant& value, int role )
0194 {
0195     if( Qt::CheckStateRole == role && value.toBool() ) {
0196         if( const ExternalBin* bin = binForIndex( index ) ) {
0197             if( d->defaults[ &bin->program() ] != bin ) {
0198                 d->defaults[ &bin->program() ] = bin;
0199                 Q_EMIT dataChanged( indexForBin( bin->program().bins().first() ),
0200                                     indexForBin( bin->program().bins().last() ) );
0201                 return true;
0202             }
0203         }
0204     }
0205     return false;
0206 }
0207 
0208 
0209 int ExternalBinModel::columnCount( const QModelIndex& /*parent*/ ) const
0210 {
0211     return NumColumns;
0212 }
0213 
0214 
0215 int ExternalBinModel::rowCount( const QModelIndex& parent ) const
0216 {
0217     if( ExternalProgram* program = programForIndex( parent ) )
0218         return program->bins().size();
0219     else if( !parent.isValid() )
0220         return d->programs.size();
0221     else
0222         return 0;
0223 }
0224 
0225 
0226 QVariant ExternalBinModel::headerData( int section, Qt::Orientation orientation, int role ) const
0227 {
0228     if( orientation == Qt::Horizontal && role == Qt::DisplayRole ) {
0229         switch( section ) {
0230             case PathColumn: return i18n( "Path" );
0231             case VersionColumn: return i18n( "Version" );
0232             case FeaturesColumn: return i18n( "Features" );
0233             default: return QVariant();
0234         }
0235     }
0236     return QVariant();
0237 }
0238 
0239 
0240 QModelIndex ExternalBinModel::buddy( const QModelIndex& index ) const
0241 {
0242     if( binForIndex( index ) != 0 )
0243         return ExternalBinModel::index( index.row(), PathColumn, index.parent() );
0244     else
0245         return index;
0246 }
0247 
0248 } // namespace K3b
0249 
0250 #include "moc_k3bexternalbinmodel.cpp"