File indexing completed on 2024-10-06 04:26:01
0001 /* 0002 SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "k3bplacesmodel.h" 0007 #include "k3bdevicemodel.h" 0008 0009 #include "k3bcore.h" 0010 #include "k3bdevice.h" 0011 #include "k3bdevicemanager.h" 0012 #include "k3bmediacache.h" 0013 #include "k3bmedium.h" 0014 0015 #include <KDirSortFilterProxyModel> 0016 #include <KFilePlacesModel> 0017 #include <KDirModel> 0018 #include <KDirLister> 0019 #include <Solid/StorageAccess> 0020 0021 #include <QIcon> 0022 0023 typedef QMap<KDirModel*, KDirSortFilterProxyModel*> DirModels; 0024 0025 0026 class K3b::PlacesModel::Private 0027 { 0028 public: 0029 K3b::DeviceModel* deviceModel; 0030 KFilePlacesModel* filePlacesModel; 0031 DirModels dirModels; 0032 }; 0033 0034 0035 0036 K3b::PlacesModel::PlacesModel( QObject* parent ) 0037 : K3b::MetaItemModel( parent ), 0038 d( new Private() ) 0039 { 0040 d->deviceModel = new K3b::DeviceModel( this ); 0041 d->filePlacesModel = new KFilePlacesModel( this ); 0042 addSubModel( "Devices", QIcon::fromTheme( "media-optical" ), d->deviceModel, true ); 0043 0044 // TODO: Currently our place list doesn't follow changes KFilePlacesModel. 0045 // This needs to be changed. Adding, removing and editing places would be also nice. 0046 for( int i = 0; i < d->filePlacesModel->rowCount(); ++i ) { 0047 QModelIndex place = d->filePlacesModel->index( i, 0 ); 0048 QUrl url = d->filePlacesModel->url( place ); 0049 0050 // Let's filter out device-related places 0051 // and custom protocols (we doesn't support burning from them) 0052 if( !d->filePlacesModel->isDevice( place ) && url.isLocalFile() ) { 0053 addPlace( 0054 d->filePlacesModel->text( place ), 0055 d->filePlacesModel->icon( place ), 0056 url ); 0057 } 0058 } 0059 0060 connect( d->deviceModel, SIGNAL(modelAboutToBeReset()), 0061 this, SIGNAL(modelAboutToBeReset()) ); 0062 connect( d->deviceModel, SIGNAL(modelReset()), 0063 this, SIGNAL(modelReset()) ); 0064 connect( k3bcore->deviceManager(), SIGNAL(changed(K3b::Device::DeviceManager*)), 0065 this, SLOT(slotDevicesChanged(K3b::Device::DeviceManager*)) ); 0066 slotDevicesChanged( k3bcore->deviceManager() ); 0067 } 0068 0069 0070 K3b::PlacesModel::~PlacesModel() 0071 { 0072 delete d; 0073 } 0074 0075 0076 KFileItem K3b::PlacesModel::itemForIndex( const QModelIndex& index ) const 0077 { 0078 // KDirSortFilterProxyModel does not have the Q_OBJECT macro. Thus, we need to use dynamic_cast 0079 KDirSortFilterProxyModel* proxy = dynamic_cast<KDirSortFilterProxyModel*>( subModelForIndex( index ) ); 0080 if ( proxy ) { 0081 KDirModel* model = qobject_cast<KDirModel*>( proxy->sourceModel() ); 0082 return model->itemForIndex( proxy->mapToSource( mapToSubModel( index ) ) ); 0083 } 0084 return KFileItem(); 0085 } 0086 0087 0088 K3b::Device::Device* K3b::PlacesModel::deviceForIndex( const QModelIndex& index ) const 0089 { 0090 if ( qobject_cast<K3b::DeviceModel*>( subModelForIndex( index ) ) == d->deviceModel ) { 0091 return d->deviceModel->deviceForIndex( mapToSubModel( index ) ); 0092 } 0093 return 0; 0094 } 0095 0096 0097 QModelIndex K3b::PlacesModel::indexForDevice( K3b::Device::Device* dev ) const 0098 { 0099 return mapFromSubModel( d->deviceModel->indexForDevice( dev ) ); 0100 } 0101 0102 0103 void K3b::PlacesModel::expandToUrl( const QUrl& url ) 0104 { 0105 qDebug() << url; 0106 0107 // Check if url is not device's 0108 Q_FOREACH( Device::Device* device, d->deviceModel->devices() ) 0109 { 0110 if( Solid::StorageAccess* solidStorage = device->solidStorage() ) { 0111 QUrl parent = QUrl::fromLocalFile( solidStorage->filePath() ); 0112 if( parent.isParentOf( url ) ) { 0113 qDebug() << url << "will be expanded to device" << device->description(); 0114 emit expand( mapFromSubModel( d->deviceModel->indexForDevice( device ) ) ); 0115 return; 0116 } 0117 } 0118 else if( url.scheme() == "audiocd" ) 0119 { 0120 const Medium& medium = k3bcore->mediaCache()->medium( device ); 0121 if( medium.content() & Medium::ContentAudio ) 0122 { 0123 qDebug() << url << "will be expanded to device" << device->description(); 0124 emit expand( mapFromSubModel( d->deviceModel->indexForDevice( device ) ) ); 0125 return; 0126 } 0127 } 0128 } 0129 0130 // search for the best suited place that contains this URL 0131 int maxDepth = 0; 0132 KDirModel* modelToExpand = 0; 0133 0134 for( DirModels::iterator it = d->dirModels.begin(); it != d->dirModels.end(); ++it ) { 0135 KDirModel* model = it.key(); 0136 QUrl parent = model->dirLister()->url(); 0137 if ( parent.isParentOf( url ) ) { 0138 if ( parent.path().length() > maxDepth ) { 0139 maxDepth = parent.path().length(); 0140 modelToExpand = model; 0141 } 0142 } 0143 } 0144 0145 if ( modelToExpand ) { 0146 qDebug() << modelToExpand->dirLister()->url() << " will be expanded."; 0147 if( modelToExpand->dirLister()->url().matches( url, QUrl::StripTrailingSlash ) ) { 0148 emit expand( indexForSubModel( d->dirModels[ modelToExpand ] ) ); 0149 } 0150 else { 0151 modelToExpand->expandToUrl( url ); 0152 } 0153 } 0154 } 0155 0156 0157 void K3b::PlacesModel::addPlace( const QString& name, const QIcon& icon, const QUrl& rootUrl ) 0158 { 0159 KDirModel* model = new KDirModel( this ); 0160 connect( model, SIGNAL(expand(QModelIndex)), this, SLOT(slotExpand(QModelIndex)) ); 0161 model->dirLister()->setAutoErrorHandlingEnabled( false ); 0162 model->dirLister()->setDirOnlyMode( true ); 0163 model->dirLister()->openUrl( rootUrl, KDirLister::Keep ); 0164 0165 KDirSortFilterProxyModel* proxy = new KDirSortFilterProxyModel( model ); 0166 proxy->setSourceModel( model ); 0167 d->dirModels.insert( model, proxy ); 0168 addSubModel( name, icon, proxy ); 0169 } 0170 0171 0172 void K3b::PlacesModel::slotExpand( const QModelIndex& index ) 0173 { 0174 qDebug() << index; 0175 KDirModel* model = ( KDirModel* )index.model(); 0176 emit expand( mapFromSubModel( d->dirModels[model]->mapFromSource( index ) ) ); 0177 } 0178 0179 0180 void K3b::PlacesModel::slotDevicesChanged( K3b::Device::DeviceManager* dm ) 0181 { 0182 qDebug(); 0183 d->deviceModel->setDevices( dm->allDevices() ); 0184 } 0185 0186 #include "moc_k3bplacesmodel.cpp"