hydrogen 1.2.6
SoundLibraryImportDialog.cpp
Go to the documentation of this file.
1/*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 * Copyright(c) 2008-2025 The hydrogen development team [hydrogen-devel@lists.sourceforge.net]
5 *
6 * http://www.hydrogen-music.org
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY, without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see https://www.gnu.org/licenses
20 *
21 */
22
25#include "SoundLibraryPanel.h"
26
29#include "../HydrogenApp.h"
30#include "../InstrumentRack.h"
31#include "../CommonStrings.h"
32
33#include <core/H2Exception.h>
35#include <core/Basics/Drumkit.h>
36#include <core/Hydrogen.h>
39
40#include <QTreeWidget>
41#include <QDomDocument>
42#include <QMessageBox>
43#include <QHeaderView>
44#include <QCryptographicHash>
45
46#ifndef H2CORE_HAVE_QT6
47 #include <QTextCodec>
48#endif
49
50#include <memory>
51
52const int max_redirects = 30;
53
54SoundLibraryImportDialog::SoundLibraryImportDialog( QWidget* pParent, bool bOnlineImport )
55 : QDialog( pParent )
56{
57 setupUi( this );
58
59 // Show and enable maximize button. This is key when enlarging the
60 // application using a scaling factor and allows the OS to force its size
61 // beyond the minimum and make the scrollbars appear.
62 setWindowFlags( windowFlags() | Qt::CustomizeWindowHint |
63 Qt::WindowMinMaxButtonsHint );
64
65 setWindowTitle( tr( "Sound Library import" ) );
66
67 QStringList headers;
68 headers << tr( "Sound library" ) << tr( "Status" );
69 QTreeWidgetItem* header = new QTreeWidgetItem( headers );
70 m_pDrumkitTree->setHeaderItem( header );
71 m_pDrumkitTree->header()->resizeSection( 0, 200 );
72
73 connect( m_pDrumkitTree, SIGNAL( currentItemChanged ( QTreeWidgetItem*, QTreeWidgetItem* ) ), this, SLOT( soundLibraryItemChanged( QTreeWidgetItem*, QTreeWidgetItem* ) ) );
74 connect( repositoryCombo, SIGNAL(currentIndexChanged(int)), this, SLOT( onRepositoryComboBoxIndexChanged(int) ));
75
76 SoundLibraryNameLbl->setText( "" );
77 SoundLibraryInfoLbl->setText( "" );
78 DownloadBtn->setEnabled( false );
79
80 InstallBtn->setEnabled (false );
81
83
84 if( bOnlineImport){
85 tabWidget->setCurrentIndex( 0 );
86 } else {
87 tabWidget->setCurrentIndex( 1 );
88 }
89}
90
91
92
93
95{
96 if ( auto pH2App = HydrogenApp::get_instance() ) {
97 pH2App->removeEventListener( this );
98 }
99}
100
101//update combo box
103{
105
106 /*
107 Read serverList from config and put servers into the comboBox
108 */
109
110 if( pref->sServerList.size() == 0 ) {
111 pref->sServerList.push_back( "http://hydrogen-music.org/feeds/drumkit_list.php" );
112 }
113
114 repositoryCombo->clear();
115
116 std::list<QString>::const_iterator cur_Server;
117 for( cur_Server = pref->sServerList.begin(); cur_Server != pref->sServerList.end(); ++cur_Server ) {
118 repositoryCombo->insertItem( 0, *cur_Server );
119 }
121}
122
124{
125 UNUSED(i);
126
127 if(!repositoryCombo->currentText().isEmpty())
128 {
129 QString cacheFile = getCachedFilename();
130 if( !H2Core::Filesystem::file_exists( cacheFile, true ) )
131 {
133 }
135 }
136}
137
142{
143 SoundLibraryRepositoryDialog repoDialog( this );
144 repoDialog.exec();
146}
147
149{
150 // Note: After a kit is installed the list refreshes and this gets called to
151 // clear the image cache - maybe we want to keep the cache in this case?
152 QString cacheDir = H2Core::Filesystem::repositories_cache_dir() ;
153 INFOLOG("Deleting cached image files from " + cacheDir );
154
155 QDir dir( cacheDir );
156 dir.setNameFilters(QStringList() << "*.png");
157 dir.setFilter(QDir::Files);
158 foreach(QString dirFile, dir.entryList())
159 {
160 if ( !dir.remove(dirFile) )
161 {
162 WARNINGLOG("Error removing image file(s) from cache.");
163 }
164 }
165}
166
168{
170 QString serverMd5 = QString(QCryptographicHash::hash(( repositoryCombo->currentText().toLatin1() ),QCryptographicHash::Md5).toHex());
171 QString cacheFile = cacheDir + "/" + serverMd5;
172 return cacheFile;
173}
174
176{
178 QString kitNameMd5 = QString(QCryptographicHash::hash(( SoundLibraryNameLbl->text().toLatin1() ),QCryptographicHash::Md5).toHex());
179 QString cacheFile = cacheDir + "/" + kitNameMd5 + ".png";
180 return cacheFile;
181}
182
183
184void SoundLibraryImportDialog::writeCachedData(const QString& fileName, const QString& data)
185{
186 if( data.isEmpty() )
187 {
188 return;
189 }
190
191 QFile outFile( fileName );
192 if( !outFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
193 {
194 ERRORLOG( QString("Failed to open file for writing repository cache: %1").arg( fileName ) );
195 return;
196 }
197
198 QTextStream stream( &outFile );
199 stream << data;
200
201 outFile.close();
202}
203
204void SoundLibraryImportDialog::writeCachedImage( const QString& imageFile, QPixmap& pixmap )
205{
206 QString cacheFile = getCachedImageFilename() ;
207
208 QFile outFile( cacheFile );
209 if( !outFile.open( QIODevice::WriteOnly ) )
210 {
211 ERRORLOG( QString("Failed to open file for writing repository image cache: %1").arg( imageFile ) );
212 return;
213 }
214
215 pixmap.save(&outFile);
216
217 outFile.close();
218}
219
220QString SoundLibraryImportDialog::readCachedData(const QString& fileName)
221{
222 QString content;
223 QFile inFile( fileName );
224 if( !inFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
225 {
226 ERRORLOG( QString("Failed to open file for reading: %1").arg( fileName ) );
227 return content;
228 }
229
230 QDomDocument document;
231 if( !document.setContent( &inFile ) )
232 {
233 inFile.close();
234 return content;
235 }
236 inFile.close();
237
238 content = document.toString();
239
240 return content;
241}
242
243QString SoundLibraryImportDialog::readCachedImage( const QString& imageFile )
244{
245 QString cacheFile = getCachedImageFilename() ;
246
247 QFile file( cacheFile );
248 if( !file.exists() )
249 {
250 // no image in cache, just return NULL
251 return nullptr;
252 }
253
254 return cacheFile;
255}
256
258{
259 QString sDrumkitXML;
260 QString cacheFile = getCachedFilename();
261
262 if(H2Core::Filesystem::file_exists(cacheFile,true))
263 {
264 sDrumkitXML = readCachedData(cacheFile);
265 }
266
267 m_soundLibraryList.clear();
268 QDomDocument dom;
269 dom.setContent( sDrumkitXML );
270 QDomNode drumkitNode = dom.documentElement().firstChild();
271 while ( !drumkitNode.isNull() ) {
272 if( !drumkitNode.toElement().isNull() ) {
273
274 if ( drumkitNode.toElement().tagName() == "drumkit" || drumkitNode.toElement().tagName() == "song" || drumkitNode.toElement().tagName() == "pattern" ) {
275
276 H2Core::SoundLibraryInfo soundLibInfo;
277
278 if ( drumkitNode.toElement().tagName() =="song" ) {
279 soundLibInfo.setType( "song" );
280 }
281
282 if ( drumkitNode.toElement().tagName() =="drumkit" ) {
283 soundLibInfo.setType( "drumkit" );
284 }
285
286 if ( drumkitNode.toElement().tagName() =="pattern" ) {
287 soundLibInfo.setType( "pattern" );
288 }
289
290 QDomElement nameNode = drumkitNode.firstChildElement( "name" );
291 if ( !nameNode.isNull() ) {
292 soundLibInfo.setName( nameNode.text() );
293 }
294
295 QDomElement urlNode = drumkitNode.firstChildElement( "url" );
296 if ( !urlNode.isNull() ) {
297 soundLibInfo.setUrl( urlNode.text() );
298 }
299
300 QDomElement infoNode = drumkitNode.firstChildElement( "info" );
301 if ( !infoNode.isNull() ) {
302 soundLibInfo.setInfo( infoNode.text() );
303 }
304
305 QDomElement authorNode = drumkitNode.firstChildElement( "author" );
306 if ( !authorNode.isNull() ) {
307 soundLibInfo.setAuthor( authorNode.text() );
308 }
309
310 QDomElement licenseNode = drumkitNode.firstChildElement( "license" );
311 if ( !licenseNode.isNull() ) {
312 soundLibInfo.setLicense( licenseNode.text() );
313 }
314
315 QDomElement imageNode = drumkitNode.firstChildElement( "image" );
316 if ( !imageNode.isNull() ) {
317 soundLibInfo.setImage( imageNode.text() );
318 }
319
320 QDomElement imageLicenseNode = drumkitNode.firstChildElement( "imageLicense" );
321 if ( !imageLicenseNode.isNull() ) {
322 soundLibInfo.setImageLicense( imageLicenseNode.text() );
323 }
324
325
326 m_soundLibraryList.push_back( soundLibInfo );
327 }
328 }
329 drumkitNode = drumkitNode.nextSibling();
330 }
331
333
334}
335
340{
341 QApplication::setOverrideCursor(Qt::WaitCursor);
342 QString downloadUrl = repositoryCombo->currentText();
343 QString sDrumkitXML;
344
345 for (int ii=1; ii <= max_redirects; ii++) {
346 DownloadWidget drumkitList( this, tr( "Updating SoundLibrary list..." ), downloadUrl);
347 drumkitList.exec();
348
349 if (!drumkitList.get_redirect_url().isEmpty()) {
350 downloadUrl = drumkitList.get_redirect_url().toEncoded();
351 } else if (drumkitList.get_error().isEmpty()) {
352 sDrumkitXML = drumkitList.get_xml_content();
353 break;
354 }
355
356 // Only show a popup with the error messages once after
357 // attempting all redirects. We assume in here that the error
358 // does stay the same for all redirects.
359 if ( ii == max_redirects ) {
360 QMessageBox::warning( this, "Hydrogen", drumkitList.get_error() );
361 }
362
363 }
364
365 /*
366 * Hydrogen creates the following cache hierarchy to cache
367 * the content of server lists:
368 *
369 * CACHE_DIR
370 * +-----repositories
371 * +-----serverlist_$(md5(SERVER_NAME))
372 */
373
374
375 QString cacheFile = getCachedFilename();
376
377
378 writeCachedData(cacheFile, sDrumkitXML);
379
381 QApplication::restoreOverrideCursor();
382}
383
384
385
386
388{
389 // build the sound library tree
390 m_pDrumkitTree->clear();
391
392 m_pDrumkitsItem = new QTreeWidgetItem( m_pDrumkitTree );
393 m_pDrumkitsItem->setText( 0, tr( "Drumkits" ) );
394 m_pDrumkitsItem->setExpanded( true );
395
396
397 m_pSongItem = new QTreeWidgetItem( m_pDrumkitTree );
398 m_pSongItem->setText( 0, tr( "Songs" ) );
399 m_pSongItem->setExpanded( true );
400
401 m_pPatternItem = new QTreeWidgetItem( m_pDrumkitTree );
402 m_pPatternItem->setText( 0, tr( "Patterns" ) );
403 m_pPatternItem->setExpanded( true );
404
405 for ( uint i = 0; i < m_soundLibraryList.size(); ++i ) {
406 QString sLibraryName = m_soundLibraryList[ i ].getName();
407
408 QTreeWidgetItem* pDrumkitItem = nullptr;
409
410 if ( m_soundLibraryList[ i ].getType() == "song" ) {
411 pDrumkitItem = new QTreeWidgetItem( m_pSongItem );
412 } else if ( m_soundLibraryList[ i ].getType() == "drumkit" ) {
413 pDrumkitItem = new QTreeWidgetItem( m_pDrumkitsItem );
414 } else if ( m_soundLibraryList[ i ].getType() == "pattern" ) {
415 pDrumkitItem = new QTreeWidgetItem( m_pPatternItem );
416 }
417
418 if( pDrumkitItem ) {
420 pDrumkitItem->setText( 0, sLibraryName );
421 pDrumkitItem->setText( 1, tr( "Installed" ) );
422 }
423 else {
424 pDrumkitItem->setText( 0, sLibraryName );
425 pDrumkitItem->setText( 1, tr( "New" ) );
426 }
427 }
428 }
429
430 // Also clear out the image cache
432
433}
434
438
439
442{
443 // check if the filename matches with an already installed soundlibrary directory.
444 // The filename used in the Soundlibrary URL must be the same of the unpacked directory.
445 // E.g: V-Synth_VariBreaks.h2drumkit must contain the V-Synth_VariBreaks directory once unpacked.
446 // Many drumkit are broken now (wrong filenames) and MUST be fixed!
447
448 QString sName = QFileInfo( sInfo.getUrl() ).fileName();
449 sName = sName.left( sName.lastIndexOf( "." ) );
450
451 if ( sInfo.getType() == "drumkit" ) {
453 return true;
454 }
455 }
456
457 if ( sInfo.getType() == "pattern" ) {
459 ->isPatternInstalled( sInfo.getName() );
460 }
461
462 if ( sInfo.getType() == "song" ) {
463 if ( H2Core::Filesystem::song_exists(sName) ) {
464 return true;
465 }
466 }
467
468 return false;
469}
470
472{
473 QPixmap pixmap;
474 pixmap.load( img ) ;
475
476 writeCachedImage( drumkitImageLabel->text(), pixmap );
477 showImage( pixmap );
478}
479
481{
482 int x = (int) drumkitImageLabel->size().width();
483 int y = drumkitImageLabel->size().height();
484 float labelAspect = (float) x / y;
485 float imageAspect = (float) pixmap.width() / pixmap.height();
486
487 if ( ( x < pixmap.width() ) || ( y < pixmap.height() ) )
488 {
489 if ( labelAspect >= imageAspect )
490 {
491 // image is taller or the same as label frame
492 pixmap = pixmap.scaledToHeight( y );
493 }
494 else
495 {
496 // image is wider than label frame
497 pixmap = pixmap.scaledToWidth( x );
498 }
499 }
500 drumkitImageLabel->setPixmap( pixmap ); // TODO: Check if valid!
501
502}
503
504
505void SoundLibraryImportDialog::soundLibraryItemChanged( QTreeWidgetItem* current, QTreeWidgetItem* previous )
506{
507 UNUSED( previous );
508 if ( current ) {
509
510 QString selected = current->text(0);
511 for ( uint i = 0; i < m_soundLibraryList.size(); ++i ) {
512 if ( m_soundLibraryList[ i ].getName() == selected ) {
514
515 //bool alreadyInstalled = isSoundLibraryAlreadyInstalled( info.m_sURL );
516
517 SoundLibraryNameLbl->setText( info.getName() );
518
519 if( info.getType() == "pattern" ){
520 SoundLibraryInfoLbl->setText("");
521 } else {
522 SoundLibraryInfoLbl->setText( info.getInfo() );
523 }
524
525 AuthorLbl->setText( tr( "Author: %1" ).arg( info.getAuthor() ) );
526
527 LicenseLbl->setText( tr( "Drumkit License: %1" )
528 .arg( info.getLicense().getLicenseString() ) );
529
530 ImageLicenseLbl->setText( tr("Image License: %1" )
531 .arg( info.getImageLicense().getLicenseString() ) );
532
533 // Load the drumkit image
534 // Clear any image first
535 drumkitImageLabel->setPixmap( QPixmap() );
536 drumkitImageLabel->setText( info.getImage() );
537
538 if ( info.getImage().length() > 0 ) {
540 // get image file from local disk
541 QString sName = QFileInfo( info.getUrl() ).fileName();
542 sName = sName.left( sName.lastIndexOf( "." ) );
543
544 auto pDrumkit = H2Core::Hydrogen::get_instance()
546 if ( pDrumkit != nullptr ) {
547 // get the image from the local filesystem
548 QPixmap pixmap ( pDrumkit->get_path() + "/" + pDrumkit->get_image() );
549 INFOLOG("Loaded image " + pDrumkit->get_image() + " from local filesystem");
550 showImage( pixmap );
551 }
552 else {
553 ___ERRORLOG ( "Error loading the drumkit" );
554 }
555
556 }
557 else {
558 // Try from the cache
559 QString cachedFile = readCachedImage( info.getImage() );
560
561 if ( cachedFile.length() > 0 ) {
562 QPixmap pixmap ( cachedFile );
563 showImage( pixmap );
564 INFOLOG( "Loaded image " + info.getImage() + " from cache (" + cachedFile + ")" );
565 }
566 else {
567 // Get the drumkit's directory name from URL
568 //
569 // Example: if the server repo URL is: http://www.hydrogen-music.org/feeds/drumkit_list.php
570 // and the image name from the XML is Roland_TR-808_drum_machine.jpg
571 // the URL for the image will be: http://www.hydrogen-music.org/feeds/images/Roland_TR-808_drum_machine.jpg
572
573 if ( info.getImage().length() > 0 ) {
574 QString sImageUrl;
575 QString sLocalFile;
576
577 sImageUrl = repositoryCombo->currentText().left( repositoryCombo->currentText().lastIndexOf( QString( "/" )) + 1 ) + info.getImage() ;
578 sLocalFile = QDir::tempPath() + "/" + QFileInfo( sImageUrl ).fileName();
579
580 DownloadWidget dl( this, tr( "" ), sImageUrl, sLocalFile );
581 dl.exec();
582
583 loadImage( sLocalFile );
584 // Delete the temporary file
585 QFile::remove( sLocalFile );
586 }
587 }
588 }
589 }
590
591 DownloadBtn->setEnabled( true );
592 return;
593 }
594 }
595 }
596
597 SoundLibraryNameLbl->setText( "" );
598 SoundLibraryInfoLbl->setText( "" );
599 AuthorLbl->setText( "" );
600 DownloadBtn->setEnabled( false );
601}
602
603
604
606{
607 QApplication::setOverrideCursor(Qt::WaitCursor);
608 QString selected = m_pDrumkitTree->currentItem()->text(0);
609
610 for ( uint i = 0; i < m_soundLibraryList.size(); ++i ) {
611 if ( m_soundLibraryList[ i ].getName() == selected ) {
612 // Download the sound library
613 QString sURL = m_soundLibraryList[ i ].getUrl();
614 QString sType = m_soundLibraryList[ i ].getType();
615 QString sLocalFile;
616
617 if( sType == "drumkit") {
618 sLocalFile = QDir::tempPath() + "/" + QFileInfo( sURL ).fileName();
619 }
620
621 if( sType == "song") {
622 sLocalFile = H2Core::Filesystem::songs_dir() + QFileInfo( sURL ).fileName();
623 }
624
625 if( sType == "pattern") {
626 sLocalFile = H2Core::Filesystem::patterns_dir() + QFileInfo( sURL ).fileName();
627 }
628
629 bool Error = false;
630
631 for ( int i = 0; i < max_redirects; ++i ) {
632 DownloadWidget dl( this, tr( "Downloading SoundLibrary..." ), sURL, sLocalFile );
633 dl.exec();
634
635 QUrl redirect_url = dl.get_redirect_url();
636 if (redirect_url.isEmpty() ) {
637 // ok, we have all data
638 Error = !dl.get_error().isEmpty();
639 break;
640 }
641 else {
642 sURL = redirect_url.toEncoded();
643 Error = !dl.get_error().isEmpty();
644 }
645 }
646
647
648 //No 'else', error message has been already displayed by DL widget
649 if(!Error)
650 {
651 // install the new soundlibrary
652 try {
653 if ( sType == "drumkit" ) {
654 H2Core::Drumkit::install( sLocalFile );
655 QApplication::restoreOverrideCursor();
656 QMessageBox::information( this, "Hydrogen", QString( tr( "SoundLibrary imported in %1" ) ).arg( H2Core::Filesystem::usr_data_path() ) );
657 }
658
659 if ( sType == "song" || sType == "pattern") {
660 QApplication::restoreOverrideCursor();
661 }
662 }
663 catch( H2Core::H2Exception ex ) {
664 QApplication::restoreOverrideCursor();
665 QMessageBox::warning( this, "Hydrogen", tr( "An error occurred importing the SoundLibrary." ) );
666 }
667 }
668 else
669 {
670 QApplication::restoreOverrideCursor();
671 }
672
673 QApplication::setOverrideCursor(Qt::WaitCursor);
674 // remove the downloaded files..
675 if( sType == "drumkit" ) {
676 QDir dir;
677 dir.remove( sLocalFile );
678 }
679
680 // update the drumkit list
682 QApplication::restoreOverrideCursor();
683 return;
684 }
685 }
686}
687
688
689
690
692{
694 if ( ! H2Core::Filesystem::dir_readable( sPath, false ) ){
695 sPath = QDir::homePath();
696 }
697
698 FileDialog fd(this);
699 fd.setAcceptMode( QFileDialog::AcceptOpen );
700 fd.setFileMode(QFileDialog::ExistingFile);
701 fd.setNameFilter( "Hydrogen drumkit (*.h2drumkit)" );
702 fd.setDirectory( sPath );
703
704 fd.setWindowTitle( tr( "Import drumkit" ) );
705
706 QString filename = "";
707 if (fd.exec() == QDialog::Accepted) {
708 filename = fd.selectedFiles().first();
709 }
710
711 if (filename != "") {
712 SoundLibraryPathTxt->setText( filename );
713 H2Core::Preferences::get_instance()->setLastImportDrumkitDirectory( fd.directory().absolutePath() );
714 InstallBtn->setEnabled ( true );
715 }
716}
717
718
719
720
722{
723 QApplication::setOverrideCursor(Qt::WaitCursor);
724
725 QString sError = tr( "An error occurred importing the SoundLibrary." );
726
727 try {
728 QString sImportedPath;
729 bool bEncodingIssues;
731 SoundLibraryPathTxt->text(), "", &sImportedPath,
732 &bEncodingIssues, false ) ) {
733 QApplication::restoreOverrideCursor();
734
735#ifndef H2CORE_HAVE_QT6
736 // Check whether encoding might be the problem in here.
737 auto pCodec = QTextCodec::codecForLocale();
738 if ( ! pCodec->canEncode( SoundLibraryPathTxt->text() ) ) {
739 QMessageBox::critical(
740 this, "Hydrogen", QString( "%1\n\n%2\n\n%3: [%4]" )
741 .arg( sError ).arg( SoundLibraryPathTxt->text() )
742 .arg( HydrogenApp::get_instance()->getCommonStrings()
743 ->getEncodingError() )
744 .arg( QString( pCodec->name() ) ) );
745 }
746 else {
747 QMessageBox::critical( this, "Hydrogen", sError );
748 }
749#else
750 QMessageBox::critical( this, "Hydrogen", sError );
751#endif
752
753 return;
754 }
755
756 // update the drumkit list
758 QApplication::restoreOverrideCursor();
759 if ( ! bEncodingIssues ) {
760 QMessageBox::information( this, "Hydrogen",
761 QString( tr( "SoundLibrary imported in %1" )
762 .arg( sImportedPath ) ) );
763 }
764 else {
765 QMessageBox::warning(
766 this, "Hydrogen",
767 QString( tr( "SoundLibrary imported in %1" )
768 .arg( sImportedPath ) )
769 .append( tr( "\nBut there were encoding issues.\n\nPlease set your system's locale to UTF-8!" ) ) );
770 }
771 }
772 catch( H2Core::H2Exception ex ) {
773 QApplication::restoreOverrideCursor();
774 QMessageBox::warning( this, "Hydrogen", sError );
775 }
776}
777
778
779
#define INFOLOG(x)
Definition Object.h:240
#define WARNINGLOG(x)
Definition Object.h:241
#define ERRORLOG(x)
Definition Object.h:242
#define ___ERRORLOG(x)
Definition Object.h:260
const int max_redirects
QUrl get_redirect_url()
const QString & get_xml_content()
const QString & get_error()
Custom file dialog checking whether the user has write access to the selected folder before allowing ...
Definition FileDialog.h:34
static bool install(const QString &sSourcePath, const QString &sTargetPath="", QString *pInstalledPath=nullptr, bool *pEncodingIssuesDetected=nullptr, bool bSilent=false)
Extract a .h2drumkit file.
Definition Drumkit.cpp:721
static bool dir_readable(const QString &path, bool silent=false)
returns true if the given path is a readable regular directory
static bool drumkit_exists(const QString &dk_name)
returns true if the drumkit exists within usable system or user drumkits
static QString songs_dir()
returns user songs path
static QString repositories_cache_dir()
returns user repository cache path
static bool file_exists(const QString &path, bool silent=false)
returns true if the given path is an existing regular file
static QString usr_data_path()
returns user data path
static bool song_exists(const QString &sg_name)
returns true if the song file exists
static QString patterns_dir()
returns user patterns path
static Hydrogen * get_instance()
Returns the current Hydrogen instance __instance.
Definition Hydrogen.h:84
SoundLibraryDatabase * getSoundLibraryDatabase() const
Definition Hydrogen.h:95
QString getLicenseString() const
Definition License.h:146
Manager for User Preferences File (singleton)
Definition Preferences.h:79
QString getLastImportDrumkitDirectory() const
static Preferences * get_instance()
Returns a pointer to the current Preferences singleton stored in __instance.
std::list< QString > sServerList
void setLastImportDrumkitDirectory(QString sPath)
bool isPatternInstalled(const QString &sPatternName) const
std::shared_ptr< Drumkit > getDrumkit(const QString &sDrumkitPath, bool bLoad=true)
Retrieve a drumkit from the database.
This class holds information about a soundlibrary.
void setAuthor(const QString &author)
void setInfo(const QString &info)
void setUrl(const QString &url)
H2Core::License getLicense() const
void setImage(const QString &image)
void setLicense(const H2Core::License &license)
void setName(const QString &name)
void setImageLicense(const H2Core::License &imageLicense)
H2Core::License getImageLicense() const
void setType(const QString &type)
static HydrogenApp * get_instance()
Returns the instance of HydrogenApp class.
std::vector< H2Core::SoundLibraryInfo > m_soundLibraryList
bool isSoundLibraryItemAlreadyInstalled(H2Core::SoundLibraryInfo sInfo)
Is the SoundLibrary already installed?
void writeCachedData(const QString &fileName, const QString &data)
QString readCachedData(const QString &fileName)
QString readCachedImage(const QString &imageFile)
virtual void soundLibraryChangedEvent() override
void soundLibraryItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)
void on_UpdateListBtn_clicked()
Download and update the drumkit list.
void writeCachedImage(const QString &imageFile, QPixmap &pixmap)
SoundLibraryImportDialog(QWidget *pParent, bool bOnlineImport)
void on_EditListBtn_clicked()
Edit the server list.
#define UNUSED(v)
Definition Globals.h:42