File indexing completed on 2024-05-19 04:49:12

0001 /****************************************************************************************
0002  * Copyright (c) 2006 Ian Monroe <ian@monroe.nu>                                        *
0003  * Copyright (c) 2006 Seb Ruiz <ruiz@kde.org>                                           *
0004  * Copyright (c) 2007 Maximilian Kossick <maximilian.kossick@googlemail.com>            *
0005  *                                                                                      *
0006  * This program is free software; you can redistribute it and/or modify it under        *
0007  * the terms of the GNU General Public License as published by the Free Software        *
0008  * Foundation; either version 2 of the License, or (at your option) any later           *
0009  * version.                                                                             *
0010  *                                                                                      *
0011  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0012  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0013  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0014  *                                                                                      *
0015  * You should have received a copy of the GNU General Public License along with         *
0016  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0017  ****************************************************************************************/
0018 
0019 #define DEBUG_PREFIX "MediaDeviceCollection"
0020 
0021 #include "MediaDeviceMonitor.h"
0022 #include "core/capabilities/ActionsCapability.h"
0023 #include "core-impl/collections/mediadevicecollection/MediaDeviceCollection.h"
0024 #include "core-impl/collections/mediadevicecollection/support/MediaDeviceInfo.h"
0025 #include "core-impl/collections/support/MemoryQueryMaker.h"
0026 
0027 #include <KDiskFreeSpaceInfo>
0028 
0029 using namespace Collections;
0030 
0031 MediaDeviceCollectionFactoryBase::MediaDeviceCollectionFactoryBase( ConnectionAssistant* assistant )
0032     : Collections::CollectionFactory()
0033     , m_assistant( assistant )
0034 {
0035 }
0036 
0037 
0038 MediaDeviceCollectionFactoryBase::~MediaDeviceCollectionFactoryBase()
0039 {
0040 }
0041 
0042 void
0043 MediaDeviceCollectionFactoryBase::init()
0044 {
0045     // When assistant identifies a device, Factory will attempt to build Collection
0046     connect( m_assistant, &ConnectionAssistant::identified, this, &MediaDeviceCollectionFactoryBase::slotDeviceDetected );
0047 
0048     // When assistant told to disconnect, Factory will disconnect
0049     // the device, and have the Collection destroyed
0050     connect( m_assistant, &ConnectionAssistant::disconnected, this, &MediaDeviceCollectionFactoryBase::slotDeviceDisconnected );
0051 
0052     // Register the device type with the Monitor
0053     MediaDeviceMonitor::instance()->registerDeviceType( m_assistant );
0054 
0055     m_initialized = true;
0056 }
0057 
0058 void MediaDeviceCollectionFactoryBase::slotDeviceDetected(MediaDeviceInfo* info)
0059 {
0060     MediaDeviceCollection* coll = nullptr;
0061     // If device not already connected to
0062     if( !m_collectionMap.contains( info->udi() ) )
0063     {
0064         // create the collection using the info provided
0065         coll = createCollection( info );
0066         // if collection successfully created,
0067         // aka device connected to, then...
0068         if( coll )
0069         {
0070             // insert it into the map of known collections
0071             m_collectionMap.insert( info->udi(), coll );
0072             connect( coll, &Collections::MediaDeviceCollection::collectionReady,
0073                      this, &MediaDeviceCollectionFactoryBase::newCollection );
0074             connect( coll, &Collections::MediaDeviceCollection::collectionDisconnected,
0075                      this, &MediaDeviceCollectionFactoryBase::slotDeviceDisconnected );
0076             coll->init();
0077         }
0078     }
0079 }
0080 
0081 void
0082 MediaDeviceCollectionFactoryBase::slotDeviceDisconnected( const QString &udi )
0083 {
0084     DEBUG_BLOCK
0085     // If device is known about
0086     if( m_collectionMap.contains( udi ) )
0087     {
0088         // Pull collection for the udi out of map
0089         MediaDeviceCollection* coll = m_collectionMap[ udi ];
0090         // If collection exists/found
0091         if( coll )
0092         {
0093             // Remove collection from map
0094             m_collectionMap.remove( udi );
0095             // Have Collection disconnect device
0096             // and destroy itself
0097             coll->deleteCollection();
0098         }
0099     }
0100 
0101     return;
0102 }
0103 
0104 //MediaDeviceCollection
0105 
0106 MediaDeviceCollection::MediaDeviceCollection()
0107     : Collection()
0108     , m_ejectAction( nullptr )
0109     , m_mc( new MemoryCollection() )
0110 {
0111     connect( this, &MediaDeviceCollection::attemptConnectionDone,
0112              this, &MediaDeviceCollection::slotAttemptConnectionDone );
0113 }
0114 
0115 MediaDeviceCollection::~MediaDeviceCollection()
0116 {
0117     DEBUG_BLOCK
0118 }
0119 
0120 QueryMaker*
0121 MediaDeviceCollection::queryMaker()
0122 {
0123     return new MemoryQueryMaker( m_mc.toWeakRef(), collectionId() );
0124 }
0125 
0126 QString MediaDeviceCollection::collectionId() const
0127 {
0128     return m_udi;
0129 }
0130 
0131 void
0132 MediaDeviceCollection::startFullScanDevice()
0133 {
0134     DEBUG_BLOCK
0135     // If handler successfully connected to device
0136 
0137     m_handler->parseTracks();
0138     //Q_EMIT collectionReady( this );
0139 }
0140 
0141 Meta::MediaDeviceHandler*
0142 MediaDeviceCollection::handler()
0143 {
0144     return m_handler;
0145 }
0146 
0147 void
0148 MediaDeviceCollection::eject()
0149 {
0150     DEBUG_BLOCK
0151     // Do nothing special here.
0152     Q_EMIT collectionDisconnected( m_udi );
0153 }
0154 
0155 void
0156 MediaDeviceCollection::deleteCollection()
0157 {
0158     DEBUG_BLOCK
0159     Q_EMIT deletingCollection();
0160     Q_EMIT remove();
0161 }
0162 
0163 void
0164 MediaDeviceCollection::slotAttemptConnectionDone( bool success )
0165 {
0166     DEBUG_BLOCK
0167     if( success )
0168     {
0169         debug() << "starting full scan";
0170         // TODO: thread the track parsing?
0171         startFullScanDevice();
0172     }
0173     else
0174     {
0175         debug() << "connection failed, not scanning";
0176         Q_EMIT collectionDisconnected( m_udi );
0177     }
0178 }
0179 
0180 /// CollectionCapability for Disconnect Action
0181 
0182 bool
0183 MediaDeviceCollection::hasCapabilityInterface( Capabilities::Capability::Type type ) const
0184 {
0185     switch( type )
0186     {
0187         case Capabilities::Capability::Actions:
0188             return true;
0189 
0190         default:
0191             return false;
0192     }
0193 }
0194 
0195 Capabilities::Capability*
0196 MediaDeviceCollection::createCapabilityInterface( Capabilities::Capability::Type type )
0197 {
0198     switch( type )
0199     {
0200         case Capabilities::Capability::Actions:
0201             {
0202                 QList< QAction* > actions;
0203                 actions << m_handler->collectionActions();
0204                 actions << ejectAction();
0205                 return new Capabilities::ActionsCapability( actions );
0206             }
0207         default:
0208             return nullptr;
0209     }
0210 }
0211 
0212 bool
0213 MediaDeviceCollection::hasCapacity() const
0214 {
0215     return totalCapacity() > 0;
0216 }
0217 
0218 float
0219 MediaDeviceCollection::usedCapacity() const
0220 {
0221     return m_handler->usedcapacity();
0222 }
0223 
0224 float
0225 MediaDeviceCollection::totalCapacity() const
0226 {
0227     return m_handler->totalcapacity();
0228 }
0229 
0230 void
0231 MediaDeviceCollection::emitCollectionReady()
0232 {
0233     Q_EMIT collectionReady( this );
0234 }
0235 
0236 QAction *
0237 MediaDeviceCollection::ejectAction() const
0238 {
0239     if( !m_ejectAction )
0240     {
0241         m_ejectAction = new QAction( QIcon::fromTheme( QStringLiteral("media-eject") ), i18n( "&Disconnect Device" ),
0242                                      const_cast<MediaDeviceCollection*>(this) );
0243         m_ejectAction->setProperty( "popupdropper_svg_id", "eject" );
0244 
0245         connect( m_ejectAction, &QAction::triggered, this, &MediaDeviceCollection::eject );
0246     }
0247     return m_ejectAction;
0248 }
0249