File indexing completed on 2024-05-19 04:49:27
0001 /**************************************************************************************** 0002 * Copyright (c) 2007-2008 Maximilian Kossick <maximilian.kossick@googlemail.com> * 0003 * Copyright (c) 2008 Jason A. Donenfeld <Jason@zx2c4.com> * 0004 * Copyright (c) 2010 Casey Link <unnamedrambler@gmail.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 "CollectionLocation" 0020 0021 #include "CollectionLocation.h" 0022 0023 #include "core/capabilities/TranscodeCapability.h" 0024 #include "core/collections/Collection.h" 0025 #include "core/collections/CollectionLocationDelegate.h" 0026 #include "core/collections/QueryMaker.h" 0027 #include "core/meta/Meta.h" 0028 #include "core/support/Components.h" 0029 #include "core/support/Debug.h" 0030 #include "core/transcoding/TranscodingConfiguration.h" 0031 #include "core/transcoding/TranscodingController.h" 0032 0033 #include <KLocalizedString> 0034 #include <QDir> 0035 #include <QTimer> 0036 0037 using namespace Collections; 0038 0039 CollectionLocation::CollectionLocation() 0040 :QObject() 0041 , m_destination( nullptr ) 0042 , m_source( nullptr ) 0043 , m_sourceTracks() 0044 , m_parentCollection( nullptr ) 0045 , m_removeSources( false ) 0046 , m_isRemoveAction( false ) 0047 , m_noRemoveConfirmation( false ) 0048 , m_transcodingConfiguration( Transcoding::JUST_COPY ) 0049 { 0050 //nothing to do 0051 } 0052 0053 CollectionLocation::CollectionLocation( Collections::Collection *parentCollection) 0054 :QObject() 0055 , m_destination( nullptr ) 0056 , m_source( nullptr ) 0057 , m_sourceTracks() 0058 , m_parentCollection( parentCollection ) 0059 , m_removeSources( false ) 0060 , m_isRemoveAction( false ) 0061 , m_noRemoveConfirmation( false ) 0062 , m_transcodingConfiguration( Transcoding::JUST_COPY ) 0063 { 0064 //nothing to do 0065 } 0066 0067 CollectionLocation::~CollectionLocation() 0068 { 0069 //nothing to do 0070 } 0071 0072 Collections::Collection* 0073 CollectionLocation::collection() const 0074 { 0075 return m_parentCollection; 0076 } 0077 0078 QString 0079 CollectionLocation::prettyLocation() const 0080 { 0081 return QString(); 0082 } 0083 0084 QStringList 0085 CollectionLocation::actualLocation() const 0086 { 0087 return QStringList(); 0088 } 0089 0090 bool 0091 CollectionLocation::isWritable() const 0092 { 0093 return false; 0094 } 0095 0096 bool 0097 CollectionLocation::isOrganizable() const 0098 { 0099 return false; 0100 } 0101 0102 void 0103 CollectionLocation::prepareCopy( const Meta::TrackPtr &track, CollectionLocation *destination ) 0104 { 0105 Q_ASSERT(destination); 0106 Meta::TrackList list; 0107 list.append( track ); 0108 prepareCopy( list, destination ); 0109 } 0110 0111 void 0112 CollectionLocation::prepareCopy( const Meta::TrackList &tracks, CollectionLocation *destination ) 0113 { 0114 if( !destination->isWritable() ) 0115 { 0116 CollectionLocationDelegate *delegate = Amarok::Components::collectionLocationDelegate(); 0117 delegate->notWriteable( this ); 0118 destination->deleteLater(); 0119 deleteLater(); 0120 return; 0121 } 0122 0123 m_destination = destination; 0124 m_destination->setSource( this ); 0125 startWorkflow( tracks, false ); 0126 } 0127 0128 void 0129 CollectionLocation::prepareCopy( Collections::QueryMaker *qm, CollectionLocation *destination ) 0130 { 0131 DEBUG_BLOCK 0132 if( !destination->isWritable() ) 0133 { 0134 CollectionLocationDelegate *delegate = Amarok::Components::collectionLocationDelegate(); 0135 delegate->notWriteable( this ); 0136 destination->deleteLater(); 0137 qm->deleteLater(); 0138 deleteLater(); 0139 return; 0140 } 0141 m_destination = destination; 0142 m_removeSources = false; 0143 m_isRemoveAction = false; 0144 connect( qm, &Collections::QueryMaker::newTracksReady, this, &CollectionLocation::resultReady ); 0145 connect( qm, &Collections::QueryMaker::queryDone, this, &CollectionLocation::queryDone ); 0146 qm->setQueryType( Collections::QueryMaker::Track ); 0147 qm->run(); 0148 } 0149 0150 void 0151 CollectionLocation::prepareMove( const Meta::TrackPtr &track, CollectionLocation *destination ) 0152 { 0153 Meta::TrackList list; 0154 list.append( track ); 0155 prepareMove( list, destination ); 0156 } 0157 0158 void 0159 CollectionLocation::prepareMove( const Meta::TrackList &tracks, CollectionLocation *destination ) 0160 { 0161 DEBUG_BLOCK 0162 if( !destination->isWritable() ) 0163 { 0164 CollectionLocationDelegate *delegate = Amarok::Components::collectionLocationDelegate(); 0165 delegate->notWriteable( this ); 0166 destination->deleteLater(); 0167 deleteLater(); 0168 return; 0169 } 0170 0171 m_destination = destination; 0172 m_destination->setSource( this ); 0173 startWorkflow( tracks, true ); 0174 } 0175 0176 void 0177 CollectionLocation::prepareMove( Collections::QueryMaker *qm, CollectionLocation *destination ) 0178 { 0179 DEBUG_BLOCK 0180 if( !destination->isWritable() ) 0181 { 0182 Collections::CollectionLocationDelegate *delegate = Amarok::Components::collectionLocationDelegate(); 0183 delegate->notWriteable( this ); 0184 destination->deleteLater(); 0185 qm->deleteLater(); 0186 deleteLater(); 0187 return; 0188 } 0189 m_destination = destination; 0190 m_isRemoveAction = false; 0191 m_removeSources = true; 0192 connect( qm, &Collections::QueryMaker::newTracksReady, this, &CollectionLocation::resultReady ); 0193 connect( qm, &Collections::QueryMaker::queryDone, this, &CollectionLocation::queryDone ); 0194 qm->setQueryType( Collections::QueryMaker::Track ); 0195 qm->run(); 0196 } 0197 0198 void 0199 CollectionLocation::prepareRemove( const Meta::TrackList &tracks ) 0200 { 0201 DEBUG_BLOCK 0202 if( !isWritable() ) 0203 { 0204 Collections::CollectionLocationDelegate *delegate = Amarok::Components::collectionLocationDelegate(); 0205 delegate->notWriteable( this ); 0206 deleteLater(); 0207 return; 0208 } 0209 startRemoveWorkflow( tracks ); 0210 } 0211 0212 void 0213 CollectionLocation::prepareRemove( Collections::QueryMaker *qm ) 0214 { 0215 DEBUG_BLOCK 0216 if( !isWritable() ) 0217 { 0218 Collections::CollectionLocationDelegate *delegate = Amarok::Components::collectionLocationDelegate(); 0219 delegate->notWriteable( this ); 0220 qm->deleteLater(); 0221 deleteLater(); 0222 return; 0223 } 0224 0225 m_isRemoveAction = true; 0226 m_removeSources = false; 0227 0228 connect( qm, &Collections::QueryMaker::newTracksReady, this, &CollectionLocation::resultReady ); 0229 connect( qm, &Collections::QueryMaker::queryDone, this, &CollectionLocation::queryDone ); 0230 qm->setQueryType( Collections::QueryMaker::Track ); 0231 qm->run(); 0232 } 0233 0234 bool 0235 CollectionLocation::insert( const Meta::TrackPtr &track, const QString &url ) 0236 { 0237 Q_UNUSED( track ) 0238 Q_UNUSED( url ) 0239 warning() << __PRETTY_FUNCTION__ << "Don't call this method. It exists only because" 0240 << "database importers need it. Call prepareCopy() instead."; 0241 return false; 0242 } 0243 0244 void 0245 CollectionLocation::abort() 0246 { 0247 Q_EMIT aborted(); 0248 } 0249 0250 void 0251 CollectionLocation::getKIOCopyableUrls( const Meta::TrackList &tracks ) 0252 { 0253 DEBUG_BLOCK 0254 QMap<Meta::TrackPtr, QUrl> urls; 0255 foreach( Meta::TrackPtr track, tracks ) 0256 { 0257 if( track->isPlayable() ) 0258 { 0259 urls.insert( track, track->playableUrl() ); 0260 debug() << "adding url " << track->playableUrl(); 0261 } 0262 } 0263 0264 slotGetKIOCopyableUrlsDone( urls ); 0265 } 0266 0267 void 0268 CollectionLocation::copyUrlsToCollection( const QMap<Meta::TrackPtr, QUrl> &sources, 0269 const Transcoding::Configuration &configuration ) 0270 { 0271 DEBUG_BLOCK 0272 //reimplement in implementations which are writable 0273 Q_UNUSED( sources ) 0274 Q_UNUSED( configuration ) 0275 slotCopyOperationFinished(); 0276 } 0277 0278 void 0279 CollectionLocation::removeUrlsFromCollection( const Meta::TrackList &sources ) 0280 { 0281 DEBUG_BLOCK 0282 //reimplement in implementations which are writable 0283 Q_UNUSED( sources ) 0284 slotRemoveOperationFinished(); 0285 } 0286 0287 void 0288 CollectionLocation::showSourceDialog( const Meta::TrackList &tracks, bool removeSources ) 0289 { 0290 Q_UNUSED( tracks ) 0291 Q_UNUSED( removeSources ) 0292 0293 m_transcodingConfiguration = getDestinationTranscodingConfig(); 0294 if( m_transcodingConfiguration.isValid() ) 0295 slotShowSourceDialogDone(); 0296 else 0297 abort(); 0298 } 0299 0300 Transcoding::Configuration 0301 CollectionLocation::getDestinationTranscodingConfig() 0302 { 0303 Transcoding::Configuration configuration( Transcoding::JUST_COPY ); 0304 Collection *destCollection = destination() ? destination()->collection() : nullptr; 0305 if( !destCollection ) 0306 return configuration; 0307 if( !destCollection->has<Capabilities::TranscodeCapability>() ) 0308 return configuration; 0309 QScopedPointer<Capabilities::TranscodeCapability> tc( 0310 destCollection->create<Capabilities::TranscodeCapability>() ); 0311 if( !tc ) 0312 return configuration; 0313 0314 Transcoding::Controller* tcC = Amarok::Components::transcodingController(); 0315 QSet<Transcoding::Encoder> availableEncoders; 0316 if( tcC ) 0317 availableEncoders = tcC->availableEncoders(); 0318 0319 Transcoding::Configuration saved = tc->savedConfiguration(); 0320 if( saved.isValid() && ( saved.isJustCopy() || availableEncoders.contains( saved.encoder() ) ) ) 0321 return saved; 0322 // saved configuration was not available or was invalid, ask user 0323 0324 CollectionLocationDelegate *delegate = Amarok::Components::collectionLocationDelegate(); 0325 bool saveConfiguration = false; 0326 CollectionLocationDelegate::OperationType operation = CollectionLocationDelegate::Copy; 0327 if( isGoingToRemoveSources() ) 0328 operation = CollectionLocationDelegate::Move; 0329 if( collection() && collection() == destination()->collection() ) 0330 operation = CollectionLocationDelegate::Move; // organizing 0331 configuration = delegate->transcode( tc->playableFileTypes(), &saveConfiguration, 0332 operation, destCollection->prettyName(), 0333 saved ); 0334 if( configuration.isValid() ) 0335 { 0336 if( saveConfiguration ) 0337 tc->setSavedConfiguration( configuration ); 0338 else //save the trackSelection value for restore anyway 0339 tc->setSavedConfiguration( Transcoding::Configuration( Transcoding::INVALID, 0340 configuration.trackSelection() ) ); 0341 } 0342 return configuration; // may be invalid, it means user has hit cancel 0343 } 0344 0345 void 0346 CollectionLocation::showDestinationDialog( const Meta::TrackList &tracks, 0347 bool removeSources, 0348 const Transcoding::Configuration &configuration ) 0349 { 0350 Q_UNUSED( tracks ) 0351 Q_UNUSED( configuration ) 0352 setGoingToRemoveSources( removeSources ); 0353 slotShowDestinationDialogDone(); 0354 } 0355 0356 void 0357 CollectionLocation::showRemoveDialog( const Meta::TrackList &tracks ) 0358 { 0359 DEBUG_BLOCK 0360 0361 if( !isHidingRemoveConfirm() ) 0362 { 0363 Collections::CollectionLocationDelegate *delegate = Amarok::Components::collectionLocationDelegate(); 0364 0365 const bool del = delegate->reallyDelete( this, tracks ); 0366 0367 if( !del ) 0368 slotFinishRemove(); 0369 else 0370 slotShowRemoveDialogDone(); 0371 } else 0372 slotShowRemoveDialogDone(); 0373 } 0374 0375 QString 0376 CollectionLocation::operationText( const Transcoding::Configuration &configuration ) 0377 { 0378 if( source()->collection() == collection() ) 0379 { 0380 if( configuration.isJustCopy() ) 0381 return i18n( "Organize tracks" ); 0382 else 0383 return i18n( "Transcode and organize tracks" ); 0384 } 0385 if( isGoingToRemoveSources() ) 0386 { 0387 if( configuration.isJustCopy() ) 0388 return i18n( "Move tracks" ); 0389 else 0390 return i18n( "Transcode and move tracks" ); 0391 } 0392 else 0393 { 0394 if( configuration.isJustCopy() ) 0395 return i18n( "Copy tracks" ); 0396 else 0397 return i18n( "Transcode and copy tracks" ); 0398 } 0399 } 0400 0401 QString 0402 CollectionLocation::operationInProgressText( const Transcoding::Configuration &configuration, 0403 int trackCount, QString destinationName ) 0404 { 0405 if( destinationName.isEmpty() ) 0406 destinationName = prettyLocation(); 0407 if( source()->collection() == collection() ) 0408 { 0409 if( configuration.isJustCopy() ) 0410 return i18np( "Organizing one track", 0411 "Organizing %1 tracks", trackCount ); 0412 else 0413 return i18np( "Transcoding and organizing one track", 0414 "Transcoding and organizing %1 tracks", trackCount ); 0415 } 0416 if( isGoingToRemoveSources() ) 0417 { 0418 if( configuration.isJustCopy() ) 0419 return i18np( "Moving one track to %2", 0420 "Moving %1 tracks to %2", trackCount, destinationName ); 0421 else 0422 return i18np( "Transcoding and moving one track to %2", 0423 "Transcoding and moving %1 tracks to %2", trackCount, destinationName ); 0424 } 0425 else 0426 { 0427 if( configuration.isJustCopy() ) 0428 return i18np( "Copying one track to %2", 0429 "Copying %1 tracks to %2", trackCount, destinationName ); 0430 else 0431 return i18np( "Transcoding and copying one track to %2", 0432 "Transcoding and copying %1 tracks to %2", trackCount, destinationName ); 0433 } 0434 } 0435 0436 void 0437 CollectionLocation::slotGetKIOCopyableUrlsDone( const QMap<Meta::TrackPtr, QUrl> &sources ) 0438 { 0439 Q_EMIT startCopy( sources, m_transcodingConfiguration ); 0440 } 0441 0442 void 0443 CollectionLocation::slotCopyOperationFinished() 0444 { 0445 Q_EMIT finishCopy(); 0446 } 0447 0448 void 0449 CollectionLocation::slotRemoveOperationFinished() 0450 { 0451 Q_EMIT finishRemove(); 0452 } 0453 0454 void 0455 CollectionLocation::slotShowSourceDialogDone() 0456 { 0457 Q_EMIT prepareOperation( m_sourceTracks, m_removeSources, m_transcodingConfiguration ); 0458 } 0459 0460 void 0461 CollectionLocation::slotShowDestinationDialogDone() 0462 { 0463 Q_EMIT operationPrepared(); 0464 } 0465 0466 void 0467 CollectionLocation::slotShowRemoveDialogDone() 0468 { 0469 Q_EMIT startRemove(); 0470 } 0471 0472 void 0473 CollectionLocation::slotShowSourceDialog() 0474 { 0475 showSourceDialog( m_sourceTracks, m_removeSources ); 0476 } 0477 0478 void 0479 CollectionLocation::slotPrepareOperation( const Meta::TrackList &tracks, bool removeSources, 0480 const Transcoding::Configuration &configuration ) 0481 { 0482 m_removeSources = removeSources; 0483 showDestinationDialog( tracks, removeSources, configuration ); 0484 } 0485 0486 void 0487 CollectionLocation::slotOperationPrepared() 0488 { 0489 getKIOCopyableUrls( m_sourceTracks ); 0490 } 0491 0492 void 0493 CollectionLocation::slotStartCopy( const QMap<Meta::TrackPtr, QUrl> &sources, 0494 const Transcoding::Configuration &configuration ) 0495 { 0496 DEBUG_BLOCK 0497 copyUrlsToCollection( sources, configuration ); 0498 } 0499 0500 void 0501 CollectionLocation::slotFinishCopy() 0502 { 0503 DEBUG_BLOCK 0504 if( m_removeSources ) 0505 { 0506 removeSourceTracks( m_tracksSuccessfullyTransferred ); 0507 m_sourceTracks.clear(); 0508 m_tracksSuccessfullyTransferred.clear(); 0509 } 0510 else 0511 { 0512 m_sourceTracks.clear(); 0513 m_tracksSuccessfullyTransferred.clear(); 0514 0515 if( m_destination ) 0516 m_destination->deleteLater(); 0517 m_destination = nullptr; 0518 this->deleteLater(); 0519 } 0520 } 0521 0522 void 0523 CollectionLocation::slotStartRemove() 0524 { 0525 DEBUG_BLOCK 0526 removeUrlsFromCollection( m_sourceTracks ); 0527 } 0528 0529 void 0530 CollectionLocation::slotFinishRemove() 0531 { 0532 DEBUG_BLOCK 0533 0534 Collections::CollectionLocationDelegate *delegate = Amarok::Components::collectionLocationDelegate(); 0535 if( m_tracksWithError.size() > 0 ) 0536 { 0537 delegate->errorDeleting( this, m_tracksWithError.keys() ); 0538 m_tracksWithError.clear(); 0539 } 0540 0541 QStringList dirsToRemove; 0542 debug() << "remove finished updating"; 0543 foreach( Meta::TrackPtr track, m_tracksSuccessfullyTransferred ) 0544 { 0545 if(!track) 0546 continue; 0547 0548 if( track->playableUrl().isLocalFile() ) 0549 dirsToRemove.append( track->playableUrl().adjusted( QUrl::RemoveFilename ).path() ); 0550 } 0551 0552 if( !dirsToRemove.isEmpty() && delegate->deleteEmptyDirs( this ) ) 0553 { 0554 debug() << "Removing empty directories"; 0555 dirsToRemove.removeDuplicates(); 0556 dirsToRemove.sort(); 0557 while( !dirsToRemove.isEmpty() ) 0558 { 0559 QDir dir( dirsToRemove.takeLast() ); 0560 if( !dir.exists() ) 0561 continue; 0562 0563 dir.setFilter( QDir::NoDotAndDotDot ); 0564 while( !dir.isRoot() && dir.isEmpty() ) 0565 { 0566 const QString name = dir.dirName(); 0567 dir.cdUp(); 0568 if( !dir.rmdir( name ) ) 0569 { 0570 debug() << "Unable to remove " << name; 0571 break; 0572 } 0573 } 0574 } 0575 } 0576 0577 m_tracksSuccessfullyTransferred.clear(); 0578 m_sourceTracks.clear(); 0579 this->deleteLater(); 0580 } 0581 0582 void 0583 CollectionLocation::slotAborted() 0584 { 0585 m_destination->deleteLater(); 0586 deleteLater(); 0587 } 0588 0589 void 0590 CollectionLocation::resultReady( const Meta::TrackList &tracks ) 0591 { 0592 m_sourceTracks << tracks; 0593 } 0594 0595 void 0596 CollectionLocation::queryDone() 0597 { 0598 DEBUG_BLOCK 0599 QObject *obj = sender(); 0600 if( obj ) 0601 { 0602 obj->deleteLater(); 0603 } 0604 if( m_isRemoveAction ) 0605 { 0606 debug() << "we were about to remove something, lets proceed"; 0607 prepareRemove( m_sourceTracks ); 0608 } 0609 else if( m_removeSources ) 0610 { 0611 debug() << "we were about to move something, lets proceed"; 0612 prepareMove( m_sourceTracks, m_destination ); 0613 } 0614 else 0615 { 0616 debug() << "we were about to copy something, lets proceed"; 0617 prepareCopy( m_sourceTracks, m_destination ); 0618 } 0619 } 0620 0621 void 0622 CollectionLocation::setupConnections() 0623 { 0624 connect( this, &CollectionLocation::prepareOperation, 0625 m_destination, &Collections::CollectionLocation::slotPrepareOperation ); 0626 connect( m_destination, &Collections::CollectionLocation::operationPrepared, 0627 this, &CollectionLocation::slotOperationPrepared ); 0628 connect( this, &CollectionLocation::startCopy, 0629 m_destination, &Collections::CollectionLocation::slotStartCopy ); 0630 connect( m_destination, &Collections::CollectionLocation::finishCopy, 0631 this, &CollectionLocation::slotFinishCopy ); 0632 connect( this, &CollectionLocation::aborted, this, &CollectionLocation::slotAborted ); 0633 connect( m_destination, &Collections::CollectionLocation::aborted, this, &CollectionLocation::slotAborted ); 0634 } 0635 0636 void 0637 CollectionLocation::setupRemoveConnections() 0638 { 0639 connect( this, &CollectionLocation::aborted, 0640 this, &CollectionLocation::slotAborted ); 0641 connect( this, &CollectionLocation::startRemove, 0642 this, &CollectionLocation::slotStartRemove ); 0643 connect( this, &CollectionLocation::finishRemove, 0644 this, &CollectionLocation::slotFinishRemove ); 0645 } 0646 0647 void 0648 CollectionLocation::startWorkflow( const Meta::TrackList &tracks, bool removeSources ) 0649 { 0650 DEBUG_BLOCK 0651 m_removeSources = removeSources; 0652 m_sourceTracks = tracks; 0653 setupConnections(); 0654 if( tracks.size() <= 0 ) 0655 abort(); 0656 else 0657 // show dialog in next mainloop iteration so that prepare[Something]() returns quickly 0658 QTimer::singleShot( 0, this, &CollectionLocation::slotShowSourceDialog ); 0659 } 0660 0661 void 0662 CollectionLocation::startRemoveWorkflow( const Meta::TrackList &tracks ) 0663 { 0664 DEBUG_BLOCK 0665 m_sourceTracks = tracks; 0666 setupRemoveConnections(); 0667 if( tracks.isEmpty() ) 0668 abort(); 0669 else 0670 showRemoveDialog( tracks ); 0671 } 0672 0673 void 0674 CollectionLocation::removeSourceTracks( const Meta::TrackList &tracks ) 0675 { 0676 DEBUG_BLOCK 0677 debug() << "Transfer errors:" << m_tracksWithError.count() << "of" << tracks.count(); 0678 0679 foreach( Meta::TrackPtr track, m_tracksWithError.keys() ) 0680 { 0681 debug() << "transfer error for track" << track->playableUrl(); 0682 } 0683 0684 QSet<Meta::TrackPtr> toRemove(tracks.begin(), tracks.end()); 0685 QList<Meta::TrackPtr> trackswitherrorkeys=m_tracksWithError.keys(); 0686 QSet<Meta::TrackPtr> errored(trackswitherrorkeys.begin(), trackswitherrorkeys.end()); 0687 toRemove.subtract( errored ); 0688 0689 // start the remove workflow 0690 setHidingRemoveConfirm( true ); 0691 prepareRemove( toRemove.values() ); 0692 } 0693 0694 CollectionLocation* 0695 CollectionLocation::source() const 0696 { 0697 return m_source; 0698 } 0699 0700 CollectionLocation* 0701 CollectionLocation::destination() const 0702 { 0703 return m_destination; 0704 } 0705 0706 void 0707 CollectionLocation::setSource( CollectionLocation *source ) 0708 { 0709 m_source = source; 0710 } 0711 0712 void 0713 CollectionLocation::transferSuccessful( const Meta::TrackPtr &track ) 0714 { 0715 m_tracksSuccessfullyTransferred.append( track ); 0716 } 0717 0718 bool 0719 CollectionLocation::isGoingToRemoveSources() const 0720 { 0721 return m_removeSources; 0722 } 0723 void 0724 CollectionLocation::setGoingToRemoveSources( bool removeSources ) 0725 { 0726 m_removeSources = removeSources; 0727 } 0728 0729 bool 0730 CollectionLocation::isHidingRemoveConfirm() const 0731 { 0732 return m_noRemoveConfirmation; 0733 } 0734 0735 void 0736 CollectionLocation::setHidingRemoveConfirm( bool hideRemoveConfirm ) 0737 { 0738 m_noRemoveConfirmation = hideRemoveConfirm; 0739 } 0740 0741 void 0742 CollectionLocation::transferError( const Meta::TrackPtr &track, const QString &error ) 0743 { 0744 m_tracksWithError.insert( track, error ); 0745 } 0746