24#include <core/config.h>
25#ifdef H2CORE_HAVE_LIBARCHIVE
27#include <archive_entry.h>
54 __instruments( nullptr ),
56 __author(
"undefined author" ),
57 __info(
"No information available." ),
63 __components = std::make_shared<std::vector<std::shared_ptr<DrumkitComponent>>>();
69 __path( other->get_path() ),
70 __name( other->get_name() ),
71 __author( other->get_author() ),
72 __info( other->get_info() ),
73 __license( other->get_license() ),
74 __image( other->get_image() ),
75 __imageLicense( other->get_image_license() ),
76 __samples_loaded( other->samples_loaded() )
78 __instruments = std::make_shared<InstrumentList>( other->get_instruments() );
80 __components = std::make_shared<std::vector<std::shared_ptr<DrumkitComponent>>>();
81 for (
const auto& pComponent : *other->get_components() ) {
82 __components->push_back( std::make_shared<DrumkitComponent>( pComponent ) );
90std::shared_ptr<Drumkit>
Drumkit::load(
const QString& sDrumkitPath,
bool bUpgrade,
bool bSilent )
93 ERRORLOG( QString(
"[%1] is not valid drumkit folder" ).arg( sDrumkitPath ) );
99 bool bReadingSuccessful =
true;
107 doc.
read( sDrumkitFile,
nullptr, bSilent );
109 bReadingSuccessful =
false;
112 XMLNode root = doc.firstChildElement(
"drumkit_info" );
113 if ( root.isNull() ) {
114 ERRORLOG(
"drumkit_info node not found" );
122 if ( pDrumkit ==
nullptr ) {
123 ERRORLOG( QString(
"Unable to load drumkit [%1]" ).arg( sDrumkitFile ) );
127 if ( ! bReadingSuccessful && bUpgrade ) {
136 QString sDrumkitName = node->
read_string(
"name",
"",
false,
false, bSilent );
137 if ( sDrumkitName.isEmpty() ) {
138 ERRORLOG(
"Drumkit has no name, abort" );
142 std::shared_ptr<Drumkit> pDrumkit = std::make_shared<Drumkit>();
144 pDrumkit->__path = sDrumkitPath;
145 pDrumkit->__name = sDrumkitName;
146 pDrumkit->__author = node->
read_string(
"author",
"undefined author",
148 pDrumkit->__info = node->
read_string(
"info",
"No information available.",
149 true,
true, bSilent );
152 true,
true, bSilent ),
153 pDrumkit->__author );
154 pDrumkit->set_license( license );
159 pDrumkit->set_image( node->
read_string(
"image",
"",
160 true,
true,
true ) );
163 pDrumkit->__author );
164 pDrumkit->set_image_license( imageLicense );
166 XMLNode componentListNode = node->firstChildElement(
"componentList" );
167 if ( ! componentListNode.isNull() ) {
168 XMLNode componentNode = componentListNode.firstChildElement(
"drumkitComponent" );
169 while ( ! componentNode.isNull() ) {
171 if ( pDrumkitComponent !=
nullptr ) {
172 pDrumkit->get_components()->push_back(pDrumkitComponent);
175 componentNode = componentNode.nextSiblingElement(
"drumkitComponent" );
179 auto pDrumkitComponent = std::make_shared<DrumkitComponent>( 0,
"Main" );
180 pDrumkit->get_components()->push_back(pDrumkitComponent);
188 if ( pInstrumentList ==
nullptr ) {
189 WARNINGLOG(
"instrument list could not be loaded. Using empty one." );
190 pInstrumentList = std::make_shared<InstrumentList>();
193 pDrumkit->set_instruments( pInstrumentList );
198 pDrumkit->propagateLicense();
206 INFOLOG( QString(
"Loading drumkit %1 instrument samples" ).arg(
__name ) );
217 XMLNode root = doc.firstChildElement(
"drumkit_info" );
219 QString sAuthor = root.
read_string(
"author",
"undefined author",
220 true,
true, bSilent );
221 QString sLicenseString = root.
read_string(
"license",
"undefined license",
222 false,
true, bSilent );
223 if ( sLicenseString.isNull() ) {
224 ERRORLOG( QString(
"Unable to retrieve license information from [%1]" )
225 .arg( sDrumkitDir ) );
229 return std::move(
License( sLicenseString, sAuthor ) );
238 ERRORLOG( QString(
"[%1] is not valid drumkit folder" ).arg( sDrumkitDir ) );
246 WARNINGLOG( QString(
"[%1] does not validate against drumkit schema. Trying to retrieve its name nevertheless.")
247 .arg( sDrumkitPath ) );
250 if ( ! pDoc->
read( sDrumkitPath,
nullptr, bSilent ) ) {
251 ERRORLOG( QString(
"Unable to load drumkit name for [%1]" )
252 .arg( sDrumkitPath ) );
257 XMLNode root = pDoc->firstChildElement(
"drumkit_info" );
258 if ( root.isNull() ) {
259 ERRORLOG( QString(
"Unable to load drumkit name for [%1]. 'drumkit_info' node not found" )
260 .arg( sDrumkitPath ) );
269 if ( pDrumkit !=
nullptr ) {
272 ERRORLOG( QString(
"No drumkit.xml found in folder [%1]" ).arg( sDrumkitPath ) );
277 ERRORLOG( QString(
"Drumkit in [%1] is out of date but can not be upgraded since path is not writable (please copy it to your user's home instead)" ).arg( sDrumkitPath ) );
281 INFOLOG( QString(
"Upgrading drumkit [%1]" ).arg( sDrumkitPath ) );
290 pDrumkit->save( sDrumkitPath, -1,
true, bSilent );
296 INFOLOG( QString(
"Unloading drumkit %1 instrument samples" ).arg(
__name ) );
309 if ( ! sComponentName.isEmpty() ) {
310 sExportName.append(
"_" +
312 if ( ! bRecentVersion ) {
313 sExportName.append(
"_legacy" );
320bool Drumkit::save(
const QString& sDrumkitPath,
int nComponentID,
bool bRecentVersion,
bool bSilent )
322 QString sDrumkitFolder( sDrumkitPath );
323 if ( sDrumkitPath.isEmpty() ) {
332 QFileInfo fi( sDrumkitPath );
334 WARNINGLOG( QString(
"Please provide the path to the drumkit folder instead to the drumkit.xml file within: [%1]" )
335 .arg( sDrumkitPath ) );
336 sDrumkitFolder = fi.dir().absolutePath();
342 ERRORLOG( QString(
"Unable to export drumkit [%1] to [%2]. Could not create drumkit folder." )
343 .arg(
__name ).arg( sDrumkitFolder ) );
349 ERRORLOG( QString(
"Unable to export drumkit [%1] to [%2]. Drumkit folder not writable." )
350 .arg(
__name ).arg( sDrumkitFolder ) );
355 INFOLOG( QString(
"Saving drumkit [%1] into [%2]" )
356 .arg(
__name ).arg( sDrumkitFolder ) );
361 ERRORLOG( QString(
"Unable to save samples of drumkit [%1] to [%2]. Abort." )
362 .arg(
__name ).arg( sDrumkitFolder ) );
366 if ( !
save_image( sDrumkitFolder, bSilent ) ) {
367 ERRORLOG( QString(
"Unable to save image of drumkit [%1] to [%2]. Abort." )
368 .arg(
__name ).arg( sDrumkitFolder ) );
388 save_to( &root, nComponentID, bRecentVersion, bSilent );
405 if ( bRecentVersion ) {
409 pComponent->save_to( &components_node );
413 bool bComponentFound =
false;
415 if ( component_id != -1 ) {
417 if ( pComponent !=
nullptr &&
418 pComponent->get_id() == component_id ) {
419 bComponentFound =
true;
420 pComponent->save_to( &components_node );
424 WARNINGLOG(
"Drumkit has no components. Storing an empty one as fallback." );
427 if ( ! bComponentFound ) {
428 if ( component_id != -1 ) {
429 ERRORLOG( QString(
"Unable to retrieve DrumkitComponent [%1]. Storing an empty one as fallback." )
430 .arg( component_id ) );
432 auto pDrumkitComponent = std::make_shared<DrumkitComponent>( 0,
"Main" );
433 pDrumkitComponent->save_to( &components_node );
438 if ( component_id == -1 ) {
439 ERRORLOG(
"Exporting the full drumkit with all components is allowed when targeting the legacy versions >= 0.9.6" );
445 __instruments->save_to( node, component_id, bRecentVersion,
false );
447 WARNINGLOG(
"Drumkit has no instruments. Storing an InstrumentList with a single empty Instrument as fallback." );
448 auto pInstrumentList = std::make_shared<InstrumentList>();
449 auto pInstrument = std::make_shared<Instrument>();
450 pInstrumentList->insert( 0, pInstrument );
451 pInstrumentList->save_to( node, component_id, bRecentVersion );
458 INFOLOG( QString(
"Saving drumkit [%1] samples into [%2]" )
459 .arg(
__name ).arg( sDrumkitFolder ) );
463 for (
int i = 0; i < pInstrList->size(); i++ ) {
464 auto pInstrument = ( *pInstrList )[i];
465 for (
const auto& pComponent : *pInstrument->get_components() ) {
468 auto pLayer = pComponent->get_layer( n );
469 if ( pLayer !=
nullptr && pLayer->get_sample() != nullptr ) {
470 QString src = pLayer->get_sample()->get_filepath();
471 QString dst = sDrumkitFolder +
"/" + pLayer->get_sample()->get_filename();
474 QString original_dst = dst;
477 int insertPosition = original_dst.length();
478 if ( original_dst.lastIndexOf(
".") > 0 ) {
479 insertPosition = original_dst.lastIndexOf(
".");
482 pLayer->get_sample()->set_filename( dst );
500 QString dst = sDrumkitDir +
"/" +
__image;
503 ERRORLOG( QString(
"Error copying %1 to %2").arg( src ).arg( dst ) );
524 if ( ppInstrument !=
nullptr ) {
526 ppInstrument->set_drumkit_path(
__path );
527 ppInstrument->set_drumkit_name(
__name );
528 for (
const auto& ppInstrumentComponent : *ppInstrument->get_components() ) {
529 if ( ppInstrumentComponent !=
nullptr ) {
530 for (
const auto& ppInstrumentLayer : *ppInstrumentComponent ) {
531 if ( ppInstrumentLayer !=
nullptr ) {
532 auto pSample = ppInstrumentLayer->get_sample();
533 if ( pSample !=
nullptr ) {
551 ERRORLOG( QString(
"%1 is not valid drumkit folder" ).arg( sDrumkitDir ) );
555 INFOLOG( QString(
"Removing drumkit: %1" ).arg( sDrumkitDir ) );
557 ERRORLOG( QString(
"Unable to remove drumkit: %1" ).arg( sDrumkitDir ) );
565bool Drumkit::install(
const QString& sSourcePath,
const QString& sTargetPath,
bool bSilent )
567 if ( sTargetPath.isEmpty() ) {
569 _INFOLOG( QString(
"Install drumkit [%1]" ).arg( sSourcePath ) );
578 _INFOLOG( QString(
"Extract drumkit from [%1] to [%2]" )
579 .arg( sSourcePath ).arg( sTargetPath ) );
583#ifdef H2CORE_HAVE_LIBARCHIVE
585 struct archive* arch;
586 struct archive_entry* entry;
588 arch = archive_read_new();
590#if ARCHIVE_VERSION_NUMBER < 3000000
591 archive_read_support_compression_all( arch );
593 archive_read_support_filter_all( arch );
596 archive_read_support_format_all( arch );
598#if ARCHIVE_VERSION_NUMBER < 3000000
599 if ( archive_read_open_file( arch, sSourcePath.toLocal8Bit(), 10240 ) ) {
601 if ( archive_read_open_filename( arch, sSourcePath.toLocal8Bit(), 10240 ) ) {
603 _ERRORLOG( QString(
"archive_read_open_file() [%1] %2" )
604 .arg( archive_errno( arch ) )
605 .arg( archive_error_string( arch ) ) );
606 archive_read_close( arch );
608#if ARCHIVE_VERSION_NUMBER < 3000000
609 archive_read_finish( arch );
611 archive_read_free( arch );
619 if ( ! sTargetPath.isEmpty() ) {
620 dk_dir = sTargetPath +
"/";
625 while ( ( r = archive_read_next_header( arch, &entry ) ) != ARCHIVE_EOF ) {
626 if ( r != ARCHIVE_OK ) {
627 _ERRORLOG( QString(
"archive_read_next_header() [%1] %2" )
628 .arg( archive_errno( arch ) )
629 .arg( archive_error_string( arch ) ) );
633 QString np = dk_dir + archive_entry_pathname( entry );
635 QByteArray newpath = np.toLocal8Bit();
637 archive_entry_set_pathname( entry, newpath.data() );
638 r = archive_read_extract( arch, entry, 0 );
639 if ( r == ARCHIVE_WARN ) {
640 _WARNINGLOG( QString(
"archive_read_extract() [%1] %2" )
641 .arg( archive_errno( arch ) )
642 .arg( archive_error_string( arch ) ) );
643 }
else if ( r != ARCHIVE_OK ) {
644 _ERRORLOG( QString(
"archive_read_extract() [%1] %2" )
645 .arg( archive_errno( arch ) )
646 .arg( archive_error_string( arch ) ) );
651 archive_read_close( arch );
653#if ARCHIVE_VERSION_NUMBER < 3000000
654 archive_read_finish( arch );
656 archive_read_free( arch );
664 QString gzd_name = sSourcePath.left( sSourcePath.indexOf(
"." ) ) +
".tar";
665 FILE* gzd_file = fopen( gzd_name.toLocal8Bit(),
"wb" );
666 gzFile gzip_file = gzopen( sSourcePath.toLocal8Bit(),
"rb" );
668 _ERRORLOG( QString(
"Error reading drumkit file: %1" )
669 .arg( sSourcePath ) );
670 gzclose( gzip_file );
675 while ( gzread( gzip_file, buf, 4096 ) > 0 ) {
676 fwrite( buf,
sizeof( uchar ), 4096, gzd_file );
678 gzclose( gzip_file );
683 QByteArray tar_path = gzd_name.toLocal8Bit();
685 if ( tar_open( &tar_file, tar_path.data(), NULL, O_RDONLY, 0, TAR_GNU ) == -1 ) {
686 _ERRORLOG( QString(
"tar_open(): %1" ).arg( QString::fromLocal8Bit( strerror( errno ) ) ) );
693 if ( ! sTargetPath.isEmpty() ) {
694 dk_dir = sTargetPath +
"/";
699 strncpy( dst_dir, dk_dir.toLocal8Bit(), 1024 );
700 if ( tar_extract_all( tar_file, dst_dir ) != 0 ) {
701 _ERRORLOG( QString(
"tar_extract_all(): %1" )
702 .arg( QString::fromLocal8Bit( strerror( errno ) ) ) );
705 if ( tar_close( tar_file ) != 0 ) {
707 .arg( QString::fromLocal8Bit( strerror( errno ) ) ) );
718bool Drumkit::exportTo(
const QString& sTargetDir,
const QString& sComponentName,
bool bRecentVersion,
bool bSilent ) {
721 ERRORLOG( QString(
"Provided destination folder [%1] is not valid" )
722 .arg( sTargetDir ) );
726 if ( ! bRecentVersion && sComponentName.isEmpty() ) {
727 ERRORLOG(
"A DrumkiComponent name is required to exported a drumkit in a format similar to the one prior to version 0.9.7" );
744 QString sOldDrumkitName =
__name;
745 QString sDrumkitName =
getExportName( sComponentName, bRecentVersion );
747 QString sTargetName = sTargetDir +
"/" + sDrumkitName +
751 QString sMsg(
"Export ");
753 if ( sComponentName.isEmpty() && bRecentVersion ) {
754 sMsg.append(
"drumkit " );
756 sMsg.append( QString(
"component: [%1] " ).arg( sComponentName ) );
759 sMsg.append( QString(
"to [%1] " ).arg( sTargetName ) );
761 if ( bRecentVersion ) {
762 sMsg.append(
"using the most recent format" );
764 sMsg.append(
"using the legacy format supported by Hydrogen versions <= 0.9.6" );
774 if ( ! sComponentName.isEmpty() ) {
775 tmpFolder.setAutoRemove(
false );
782 int nComponentID = -1;
783 if ( ! sComponentName.isEmpty() ) {
785 if( pComponent->get_name().compare( sComponentName ) == 0) {
786 nComponentID = pComponent->get_id();
791 if ( nComponentID == -1 ) {
792 ERRORLOG( QString(
"Component [%1] could not be found in current Drumkit [%2]" )
793 .arg( sComponentName )
798 if ( !
save( tmpFolder.path(), nComponentID, bRecentVersion, bSilent ) ) {
799 ERRORLOG( QString(
"Unable to save backup drumkit to [%1] using component ID [%2]" )
800 .arg( tmpFolder.path() ).arg( nComponentID ) );
805 ERRORLOG( QString(
"Unabled to access folder associated with drumkit [%1]" )
813 QStringList sourceFilesList = sourceDir.entryList( QDir::Files );
816 QStringList filesUsed;
829 QStringList suffixBlacklist;
830 suffixBlacklist <<
"wav" <<
"flac" <<
"aifc" <<
"aif" <<
"aiff" <<
"au"
831 <<
"caf" <<
"w64" <<
"ogg" <<
"pcm" <<
"l16" <<
"vob"
832 <<
"mp1" <<
"mp2" <<
"mp3";
836 for (
const auto& ssFile : sourceFilesList ) {
838 nComponentID != -1 ) {
842 bSampleFound =
false;
844 if( pInstr !=
nullptr ) {
845 for (
auto const& pComponent : *( pInstr->get_components() ) ) {
846 if ( pComponent !=
nullptr &&
847 ( nComponentID == -1 ||
848 pComponent->get_drumkit_componentID() == nComponentID ) ) {
850 const auto pLayer = pComponent->get_layer( n );
851 if( pLayer !=
nullptr && pLayer->get_sample() != nullptr ) {
852 if( pLayer->get_sample()->get_filename().compare( ssFile ) == 0 ) {
853 filesUsed << sourceDir.filePath( ssFile );
865 if ( ! bSampleFound ) {
866 QFileInfo ffileInfo( sourceDir.filePath( ssFile ) );
867 if ( ! suffixBlacklist.contains( ffileInfo.suffix(),
868 Qt::CaseInsensitive ) ) {
874 ssFile.contains(
".bak" ) ) ) {
875 filesUsed << sourceDir.filePath( ssFile );
882#if defined(H2CORE_HAVE_LIBARCHIVE)
885 struct archive_entry *entry;
891 a = archive_write_new();
893 #if ARCHIVE_VERSION_NUMBER < 3000000
894 archive_write_set_compression_gzip(a);
896 archive_write_add_filter_gzip(a);
899 archive_write_set_format_pax_restricted(a);
901 int ret = archive_write_open_filename(a, sTargetName.toUtf8().constData());
902 if ( ret != ARCHIVE_OK ) {
903 ERRORLOG( QString(
"Couldn't create archive [%0]" )
904 .arg( sTargetName ) );
909 bool bFoundFileInRightComponent;
910 for (
const auto& sFilename : filesUsed ) {
911 QFileInfo ffileInfo( sFilename );
912 QString sTargetFilename = sDrumkitName +
"/" + ffileInfo.fileName();
918 ERRORLOG( QString(
"Unable to export drumkit. File [%1] does not exists or is not readable." )
924 stat( sFilename.toUtf8().constData(), &st );
925 entry = archive_entry_new();
926 archive_entry_set_pathname(entry, sTargetFilename.toUtf8().constData());
927 archive_entry_set_size(entry, st.st_size);
928 archive_entry_set_filetype(entry, AE_IFREG);
929 archive_entry_set_perm(entry, 0644);
930 archive_write_header(a, entry);
931 f = fopen( sFilename.toUtf8().constData(),
"rb" );
932 len = fread(buff,
sizeof(
char),
sizeof(buff), f);
934 archive_write_data(a, buff, len);
935 len = fread(buff,
sizeof(
char),
sizeof(buff), f);
938 archive_entry_free(entry);
940 archive_write_close(a);
942 #if ARCHIVE_VERSION_NUMBER < 3000000
943 archive_write_finish(a);
945 archive_write_free(a);
948 sourceFilesList.clear();
961 if ( nComponentID != -1 ) {
971 QDir sTmpSourceDir( tmpFolder.path() +
"/" + sDirName );
972 if ( sTmpSourceDir.exists() ) {
973 sTmpSourceDir.removeRecursively();
977 ERRORLOG( QString(
"Unable to create tmp folder [%1]" )
978 .arg( tmpFolder.path() +
"/" + sDirName ) );
983 QString sNewFilePath;
984 QStringList copiedFiles;
985 for (
const auto& ssFile : filesUsed ) {
986 QString sNewFilePath( ssFile );
987 sNewFilePath.replace( sNewFilePath.left( sNewFilePath.lastIndexOf(
"/" ) ),
988 tmpFolder.path() +
"/" + sDirName );
990 ERRORLOG( QString(
"Unable to copy file [%1] to [%2]." )
991 .arg( ssFile ).arg( sNewFilePath ) );
996 copiedFiles << sNewFilePath;
999 filesUsed = copiedFiles;
1000 sourceDir = QDir( tmpFolder.path() +
"/" + sDirName );
1009 filesUsed = filesUsed.replaceInStrings( sourceDir.absolutePath(),
1010 sourceDir.dirName() );
1012 QString sCmd = QString(
"tar czf %1 -C %2 -- \"%3\"" )
1014 .arg( sourceDir.absolutePath().left( sourceDir.absolutePath().lastIndexOf(
"/" ) ) )
1015 .arg( filesUsed.join(
"\" \"" ) );
1016 int nRet = std::system( sCmd.toLocal8Bit() );
1019 ERRORLOG( QString(
"Unable to export drumkit using system command:\n%1" )
1034 ERRORLOG(
"Operation not supported on Windows" );
1046 sOutput = QString(
"%1[Drumkit]\n" ).arg( sPrefix )
1047 .append( QString(
"%1%2path: %3\n" ).arg( sPrefix ).arg( s ).arg(
__path ) )
1048 .append( QString(
"%1%2name: %3\n" ).arg( sPrefix ).arg( s ).arg(
__name ) )
1049 .append( QString(
"%1%2author: %3\n" ).arg( sPrefix ).arg( s ).arg(
__author ) )
1050 .append( QString(
"%1%2info: %3\n" ).arg( sPrefix ).arg( s ).arg(
__info ) )
1051 .append( QString(
"%1%2license: %3\n" ).arg( sPrefix ).arg( s ).arg(
__license.
toQString() ) )
1052 .append( QString(
"%1%2image: %3\n" ).arg( sPrefix ).arg( s ).arg(
__image ) )
1054 .append( QString(
"%1%2samples_loaded: %3\n" ).arg( sPrefix ).arg( s ).arg(
__samples_loaded ) )
1055 .append( QString(
"%1" ).arg(
__instruments->toQString( sPrefix + s, bShort ) ) )
1056 .append( QString(
"%1%2components:\n" ).arg( sPrefix ).arg( s ) );
1058 if ( cc !=
nullptr ) {
1059 sOutput.append( QString(
"%1" ).arg( cc->toQString( sPrefix + s + s, bShort ) ) );
1064 sOutput = QString(
"[Drumkit]" )
1065 .append( QString(
" path: %1" ).arg(
__path ) )
1066 .append( QString(
", name: %1" ).arg(
__name ) )
1067 .append( QString(
", author: %1" ).arg(
__author ) )
1068 .append( QString(
", info: %1" ).arg(
__info ) )
1070 .append( QString(
", image: %1" ).arg(
__image ) )
1073 .append( QString(
", [%1]" ).arg(
__instruments->toQString( sPrefix + s, bShort ) ) )
1074 .append( QString(
", components: [ " ) );
1076 if ( cc !=
nullptr ) {
1077 sOutput.append( QString(
"[%1]" ).arg( cc->toQString( sPrefix + s + s, bShort ).replace(
"\n",
" " ) ) );
1080 sOutput.append(
"]\n" );
static QString sPrintIndention
String used to format the debugging string output of some core classes.
static std::shared_ptr< DrumkitComponent > load_from(XMLNode *node)
QString __name
drumkit name
static bool loadDoc(const QString &sDrumkitDir, XMLDoc *pDoc, bool bSilent=false)
Loads the drumkit stored in sDrumkitDir into pDoc and takes care of all the error handling.
std::shared_ptr< InstrumentList > get_instruments() const
returns __instruments
void set_name(const QString &name)
__name setter
const License & get_license() const
__license accessor
void save_to(XMLNode *node, int component_id=-1, bool bRecentVersion=true, bool bSilent=false) const
static std::shared_ptr< Drumkit > load_from(XMLNode *node, const QString &dk_path, bool bSilent=false)
load a drumkit from an XMLNode
bool save_image(const QString &dk_dir, bool bSilent=false) const
save the drumkit image into the new directory
std::shared_ptr< std::vector< std::shared_ptr< DrumkitComponent > > > __components
list of drumkit component
void propagateLicense()
Assign the license stored in #m_license to all samples contained in the kit.
License __imageLicense
drumkit image license
~Drumkit()
drumkit destructor, delete __instruments
static void upgrade_drumkit(std::shared_ptr< Drumkit > pDrumkit, const QString &dk_path, bool bSilent=false)
Saves the current drumkit to dk_path, but makes a backup.
std::shared_ptr< InstrumentList > __instruments
the list of instruments
QString __info
drumkit free text
bool save_samples(const QString &dk_dir, bool bSilent=false) const
save a drumkit instruments samples into a directory
void load_samples()
Calls the InstrumentList::load_samples() member function of __instruments.
QString __author
drumkit author
static bool remove(const QString &sDrumkitDir)
remove a drumkit from the disk
std::vector< std::shared_ptr< InstrumentList::Content > > summarizeContent() const
Returns vector of lists containing instrument name, component name, file name, the license of all ass...
QString __image
drumkit image filename
static std::shared_ptr< Drumkit > load(const QString &dk_dir, bool bUpgrade=true, bool bSilent=false)
Load drumkit information from a directory.
static License loadLicenseFrom(const QString &sDrumkitDir, bool bSilent=false)
Loads the license information of a drumkit contained in directory sDrumkitDir.
QString getExportName(const QString &sComponentName, bool bRecentVersion) const
Returns the base name used when exporting the drumkit.
QString toQString(const QString &sPrefix="", bool bShort=true) const override
Formatted string version for debugging purposes.
QString __path
absolute drumkit path
bool exportTo(const QString &sTargetDir, const QString &sComponentName="", bool bRecentVersion=true, bool bSilent=false)
Compresses the drumkit into a .h2drumkit file.
void unload_samples()
Calls the InstrumentList::unload_samples() member function of __instruments.
static bool install(const QString &sSourcePath, const QString &sTargetPath="", bool bSilent=false)
Extract a .h2drumkit file.
Drumkit()
drumkit constructor, does nothing
bool __samples_loaded
true if the instrument samples are loaded
bool save(const QString &sDrumkitPath="", int nComponentID=-1, bool bRecentVersion=true, bool bSilent=false)
Save a drumkit to disk.
QString getFolderName() const
Returns a version of __name stripped of all whitespaces and other characters which would prevent its ...
void set_components(std::shared_ptr< std::vector< std::shared_ptr< DrumkitComponent > > > components)
void set_instruments(std::shared_ptr< InstrumentList > instruments)
set __instruments, delete existing one
License __license
drumkit license description
static bool file_copy(const QString &src, const QString &dst, bool overwrite=false, bool bSilent=false)
copy a source file to a destination
static QString validateFilePath(const QString &sPath)
Takes an arbitrary path, replaces white spaces by underscores and removes all characters apart from l...
static bool dir_readable(const QString &path, bool silent=false)
returns true if the given path is a readable regular directory
static bool drumkit_valid(const QString &dk_path)
returns true if the path contains a usable drumkit
static QString usr_drumkits_dir()
returns user drumkits path
static bool rm(const QString &path, bool recursive=false, bool bSilent=false)
remove a path
static QString drumkit_backup_path(const QString &dk_path)
Create a backup path from a drumkit path.
static QString drumkit_xsd_path()
returns the path to the drumkit XSD (xml schema definition) file
static bool dir_writable(const QString &path, bool silent=false)
returns true if the given path is a writable regular directory
static bool file_exists(const QString &path, bool silent=false)
returns true if the given path is an existing regular file
static bool mkdir(const QString &path)
create a path
static QString drumkit_file(const QString &dk_path)
returns the path to the xml file within a supposed drumkit path
static QString tmp_dir()
returns temp path
static const QString drumkit_ext
static bool path_usable(const QString &path, bool create=true, bool silent=false)
returns true if the path is a readable and writable regular directory, create if it not exists
static QString drumkit_xml()
Returns filename and extension of the expected drumkit file.
static bool file_readable(const QString &path, bool silent=false)
returns true if the given path is an existing readable regular file
static bool dir_exists(const QString &path, bool silent=false)
returns true if the given path is a regular directory
static Hydrogen * get_instance()
Returns the current Hydrogen instance __instance.
SoundLibraryDatabase * getSoundLibraryDatabase() const
static int getMaxLayers()
static std::shared_ptr< InstrumentList > load_from(XMLNode *node, const QString &sDrumkitPath, const QString &sDrumkitName, const License &license=License(), bool bSilent=false)
load an instrument list from an XMLNode
Wrapper class to help Hydrogen deal with the license information specified in a drumkit.
@ GPL
Not a desirable license for audio data but introduced here specifically since it is already used by a...
LicenseType getType() const
QString getLicenseString() const
static QString getGPLLicenseNotice(const QString &sAuthor)
QString toQString(const QString &sPrefix="", bool bShort=true) const override
Formatted string version for debugging purposes.
void updateDrumkits(bool bTriggerEvent=true)
XMLDoc is a subclass of QDomDocument with read and write methods.
XMLNode set_root(const QString &node_name, const QString &xmlns=nullptr)
create the xml header and root node
bool read(const QString &filepath, const QString &schemapath=nullptr, bool bSilent=false)
read the content of an xml file
bool write(const QString &filepath)
write itself into a file
XMLNode is a subclass of QDomNode with read and write values methods.
QString read_string(const QString &node, const QString &default_value, bool inexistent_ok=true, bool empty_ok=true, bool bSilent=false)
reads a string stored into a child node
XMLNode createNode(const QString &name)
create a new XMLNode that has to be appended into de XMLDoc
void write_string(const QString &node, const QString &value)
write a string into a child node