hydrogen 1.2.3
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-2024 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
32#include <core/H2Exception.h>
34#include <core/Basics/Drumkit.h>
35#include <core/Hydrogen.h>
38
39#include <QTreeWidget>
40#include <QDomDocument>
41#include <QMessageBox>
42#include <QHeaderView>
43#include <QCryptographicHash>
44
45#include <memory>
46
47const int max_redirects = 30;
48
49SoundLibraryImportDialog::SoundLibraryImportDialog( QWidget* pParent, bool bOnlineImport )
50 : QDialog( pParent )
51{
52 setupUi( this );
53
54 setWindowTitle( tr( "Sound Library import" ) );
55
56 QStringList headers;
57 headers << tr( "Sound library" ) << tr( "Status" );
58 QTreeWidgetItem* header = new QTreeWidgetItem( headers );
59 m_pDrumkitTree->setHeaderItem( header );
60 m_pDrumkitTree->header()->resizeSection( 0, 200 );
61
62 connect( m_pDrumkitTree, SIGNAL( currentItemChanged ( QTreeWidgetItem*, QTreeWidgetItem* ) ), this, SLOT( soundLibraryItemChanged( QTreeWidgetItem*, QTreeWidgetItem* ) ) );
63 connect( repositoryCombo, SIGNAL(currentIndexChanged(int)), this, SLOT( onRepositoryComboBoxIndexChanged(int) ));
64
65 SoundLibraryNameLbl->setText( "" );
66 SoundLibraryInfoLbl->setText( "" );
67 DownloadBtn->setEnabled( false );
68
69 InstallBtn->setEnabled (false );
70
72
73 adjustSize();
74 setFixedSize( width(), height() );
75
76 if( bOnlineImport){
77 tabWidget->setCurrentIndex( 0 );
78 } else {
79 tabWidget->setCurrentIndex( 1 );
80 }
81}
82
83
84
85
87{
88 if ( auto pH2App = HydrogenApp::get_instance() ) {
89 pH2App->removeEventListener( this );
90 }
91}
92
93//update combo box
95{
97
98 /*
99 Read serverList from config and put servers into the comboBox
100 */
101
102 if( pref->sServerList.size() == 0 ) {
103 pref->sServerList.push_back( "http://hydrogen-music.org/feeds/drumkit_list.php" );
104 }
105
106 repositoryCombo->clear();
107
108 std::list<QString>::const_iterator cur_Server;
109 for( cur_Server = pref->sServerList.begin(); cur_Server != pref->sServerList.end(); ++cur_Server ) {
110 repositoryCombo->insertItem( 0, *cur_Server );
111 }
113}
114
116{
117 UNUSED(i);
118
119 if(!repositoryCombo->currentText().isEmpty())
120 {
121 QString cacheFile = getCachedFilename();
122 if( !H2Core::Filesystem::file_exists( cacheFile, true ) )
123 {
125 }
127 }
128}
129
134{
135 SoundLibraryRepositoryDialog repoDialog( this );
136 repoDialog.exec();
138}
139
141{
142 // Note: After a kit is installed the list refreshes and this gets called to
143 // clear the image cache - maybe we want to keep the cache in this case?
144 QString cacheDir = H2Core::Filesystem::repositories_cache_dir() ;
145 INFOLOG("Deleting cached image files from " + cacheDir );
146
147 QDir dir( cacheDir );
148 dir.setNameFilters(QStringList() << "*.png");
149 dir.setFilter(QDir::Files);
150 foreach(QString dirFile, dir.entryList())
151 {
152 if ( !dir.remove(dirFile) )
153 {
154 WARNINGLOG("Error removing image file(s) from cache.");
155 }
156 }
157}
158
160{
162 QString serverMd5 = QString(QCryptographicHash::hash(( repositoryCombo->currentText().toLatin1() ),QCryptographicHash::Md5).toHex());
163 QString cacheFile = cacheDir + "/" + serverMd5;
164 return cacheFile;
165}
166
168{
170 QString kitNameMd5 = QString(QCryptographicHash::hash(( SoundLibraryNameLbl->text().toLatin1() ),QCryptographicHash::Md5).toHex());
171 QString cacheFile = cacheDir + "/" + kitNameMd5 + ".png";
172 return cacheFile;
173}
174
175
176void SoundLibraryImportDialog::writeCachedData(const QString& fileName, const QString& data)
177{
178 if( data.isEmpty() )
179 {
180 return;
181 }
182
183 QFile outFile( fileName );
184 if( !outFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
185 {
186 ERRORLOG( QString("Failed to open file for writing repository cache: %1").arg( fileName ) );
187 return;
188 }
189
190 QTextStream stream( &outFile );
191 stream << data;
192
193 outFile.close();
194}
195
196void SoundLibraryImportDialog::writeCachedImage( const QString& imageFile, QPixmap& pixmap )
197{
198 QString cacheFile = getCachedImageFilename() ;
199
200 QFile outFile( cacheFile );
201 if( !outFile.open( QIODevice::WriteOnly ) )
202 {
203 ERRORLOG( QString("Failed to open file for writing repository image cache: %1").arg( imageFile ) );
204 return;
205 }
206
207 pixmap.save(&outFile);
208
209 outFile.close();
210}
211
212QString SoundLibraryImportDialog::readCachedData(const QString& fileName)
213{
214 QString content;
215 QFile inFile( fileName );
216 if( !inFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
217 {
218 ERRORLOG( QString("Failed to open file for reading: %1").arg( fileName ) );
219 return content;
220 }
221
222 QDomDocument document;
223 if( !document.setContent( &inFile ) )
224 {
225 inFile.close();
226 return content;
227 }
228 inFile.close();
229
230 content = document.toString();
231
232 return content;
233}
234
235QString SoundLibraryImportDialog::readCachedImage( const QString& imageFile )
236{
237 QString cacheFile = getCachedImageFilename() ;
238
239 QFile file( cacheFile );
240 if( !file.exists() )
241 {
242 // no image in cache, just return NULL
243 return nullptr;
244 }
245
246 return cacheFile;
247}
248
250{
251 QString sDrumkitXML;
252 QString cacheFile = getCachedFilename();
253
254 if(H2Core::Filesystem::file_exists(cacheFile,true))
255 {
256 sDrumkitXML = readCachedData(cacheFile);
257 }
258
259 m_soundLibraryList.clear();
260 QDomDocument dom;
261 dom.setContent( sDrumkitXML );
262 QDomNode drumkitNode = dom.documentElement().firstChild();
263 while ( !drumkitNode.isNull() ) {
264 if( !drumkitNode.toElement().isNull() ) {
265
266 if ( drumkitNode.toElement().tagName() == "drumkit" || drumkitNode.toElement().tagName() == "song" || drumkitNode.toElement().tagName() == "pattern" ) {
267
268 H2Core::SoundLibraryInfo soundLibInfo;
269
270 if ( drumkitNode.toElement().tagName() =="song" ) {
271 soundLibInfo.setType( "song" );
272 }
273
274 if ( drumkitNode.toElement().tagName() =="drumkit" ) {
275 soundLibInfo.setType( "drumkit" );
276 }
277
278 if ( drumkitNode.toElement().tagName() =="pattern" ) {
279 soundLibInfo.setType( "pattern" );
280 }
281
282 QDomElement nameNode = drumkitNode.firstChildElement( "name" );
283 if ( !nameNode.isNull() ) {
284 soundLibInfo.setName( nameNode.text() );
285 }
286
287 QDomElement urlNode = drumkitNode.firstChildElement( "url" );
288 if ( !urlNode.isNull() ) {
289 soundLibInfo.setUrl( urlNode.text() );
290 }
291
292 QDomElement infoNode = drumkitNode.firstChildElement( "info" );
293 if ( !infoNode.isNull() ) {
294 soundLibInfo.setInfo( infoNode.text() );
295 }
296
297 QDomElement authorNode = drumkitNode.firstChildElement( "author" );
298 if ( !authorNode.isNull() ) {
299 soundLibInfo.setAuthor( authorNode.text() );
300 }
301
302 QDomElement licenseNode = drumkitNode.firstChildElement( "license" );
303 if ( !licenseNode.isNull() ) {
304 soundLibInfo.setLicense( licenseNode.text() );
305 }
306
307 QDomElement imageNode = drumkitNode.firstChildElement( "image" );
308 if ( !imageNode.isNull() ) {
309 soundLibInfo.setImage( imageNode.text() );
310 }
311
312 QDomElement imageLicenseNode = drumkitNode.firstChildElement( "imageLicense" );
313 if ( !imageLicenseNode.isNull() ) {
314 soundLibInfo.setImageLicense( imageLicenseNode.text() );
315 }
316
317
318 m_soundLibraryList.push_back( soundLibInfo );
319 }
320 }
321 drumkitNode = drumkitNode.nextSibling();
322 }
323
325
326}
327
332{
333 QApplication::setOverrideCursor(Qt::WaitCursor);
334 QString downloadUrl = repositoryCombo->currentText();
335 QString sDrumkitXML;
336
337 for (int ii=1; ii <= max_redirects; ii++) {
338 DownloadWidget drumkitList( this, tr( "Updating SoundLibrary list..." ), downloadUrl);
339 drumkitList.exec();
340
341 if (!drumkitList.get_redirect_url().isEmpty()) {
342 downloadUrl = drumkitList.get_redirect_url().toEncoded();
343 } else if (drumkitList.get_error().isEmpty()) {
344 sDrumkitXML = drumkitList.get_xml_content();
345 break;
346 }
347
348 // Only show a popup with the error messages once after
349 // attempting all redirects. We assume in here that the error
350 // does stay the same for all redirects.
351 if ( ii == max_redirects ) {
352 QMessageBox::warning( this, "Hydrogen", drumkitList.get_error() );
353 }
354
355 }
356
357 /*
358 * Hydrogen creates the following cache hierarchy to cache
359 * the content of server lists:
360 *
361 * CACHE_DIR
362 * +-----repositories
363 * +-----serverlist_$(md5(SERVER_NAME))
364 */
365
366
367 QString cacheFile = getCachedFilename();
368
369
370 writeCachedData(cacheFile, sDrumkitXML);
371
373 QApplication::restoreOverrideCursor();
374}
375
376
377
378
380{
381 // build the sound library tree
382 m_pDrumkitTree->clear();
383
384 m_pDrumkitsItem = new QTreeWidgetItem( m_pDrumkitTree );
385 m_pDrumkitsItem->setText( 0, tr( "Drumkits" ) );
386 m_pDrumkitsItem->setExpanded( true );
387
388
389 m_pSongItem = new QTreeWidgetItem( m_pDrumkitTree );
390 m_pSongItem->setText( 0, tr( "Songs" ) );
391 m_pSongItem->setExpanded( true );
392
393 m_pPatternItem = new QTreeWidgetItem( m_pDrumkitTree );
394 m_pPatternItem->setText( 0, tr( "Patterns" ) );
395 m_pPatternItem->setExpanded( true );
396
397 for ( uint i = 0; i < m_soundLibraryList.size(); ++i ) {
398 QString sLibraryName = m_soundLibraryList[ i ].getName();
399
400 QTreeWidgetItem* pDrumkitItem = nullptr;
401
402 if ( m_soundLibraryList[ i ].getType() == "song" ) {
403 pDrumkitItem = new QTreeWidgetItem( m_pSongItem );
404 } else if ( m_soundLibraryList[ i ].getType() == "drumkit" ) {
405 pDrumkitItem = new QTreeWidgetItem( m_pDrumkitsItem );
406 } else if ( m_soundLibraryList[ i ].getType() == "pattern" ) {
407 pDrumkitItem = new QTreeWidgetItem( m_pPatternItem );
408 }
409
410 if( pDrumkitItem ) {
412 pDrumkitItem->setText( 0, sLibraryName );
413 pDrumkitItem->setText( 1, tr( "Installed" ) );
414 }
415 else {
416 pDrumkitItem->setText( 0, sLibraryName );
417 pDrumkitItem->setText( 1, tr( "New" ) );
418 }
419 }
420 }
421
422 // Also clear out the image cache
424
425}
426
430
431
434{
435 // check if the filename matches with an already installed soundlibrary directory.
436 // The filename used in the Soundlibrary URL must be the same of the unpacked directory.
437 // E.g: V-Synth_VariBreaks.h2drumkit must contain the V-Synth_VariBreaks directory once unpacked.
438 // Many drumkit are broken now (wrong filenames) and MUST be fixed!
439
440 QString sName = QFileInfo( sInfo.getUrl() ).fileName();
441 sName = sName.left( sName.lastIndexOf( "." ) );
442
443 if ( sInfo.getType() == "drumkit" ) {
445 return true;
446 }
447 }
448
449 if ( sInfo.getType() == "pattern" ) {
451 ->isPatternInstalled( sInfo.getName() );
452 }
453
454 if ( sInfo.getType() == "song" ) {
455 if ( H2Core::Filesystem::song_exists(sName) ) {
456 return true;
457 }
458 }
459
460 return false;
461}
462
464{
465 QPixmap pixmap;
466 pixmap.load( img ) ;
467
468 writeCachedImage( drumkitImageLabel->text(), pixmap );
469 showImage( pixmap );
470}
471
473{
474 int x = (int) drumkitImageLabel->size().width();
475 int y = drumkitImageLabel->size().height();
476 float labelAspect = (float) x / y;
477 float imageAspect = (float) pixmap.width() / pixmap.height();
478
479 if ( ( x < pixmap.width() ) || ( y < pixmap.height() ) )
480 {
481 if ( labelAspect >= imageAspect )
482 {
483 // image is taller or the same as label frame
484 pixmap = pixmap.scaledToHeight( y );
485 }
486 else
487 {
488 // image is wider than label frame
489 pixmap = pixmap.scaledToWidth( x );
490 }
491 }
492 drumkitImageLabel->setPixmap( pixmap ); // TODO: Check if valid!
493
494}
495
496
497void SoundLibraryImportDialog::soundLibraryItemChanged( QTreeWidgetItem* current, QTreeWidgetItem* previous )
498{
499 UNUSED( previous );
500 if ( current ) {
501
502 QString selected = current->text(0);
503 for ( uint i = 0; i < m_soundLibraryList.size(); ++i ) {
504 if ( m_soundLibraryList[ i ].getName() == selected ) {
506
507 //bool alreadyInstalled = isSoundLibraryAlreadyInstalled( info.m_sURL );
508
509 SoundLibraryNameLbl->setText( info.getName() );
510
511 if( info.getType() == "pattern" ){
512 SoundLibraryInfoLbl->setText("");
513 } else {
514 SoundLibraryInfoLbl->setText( info.getInfo() );
515 }
516
517 AuthorLbl->setText( tr( "Author: %1" ).arg( info.getAuthor() ) );
518
519 LicenseLbl->setText( tr( "Drumkit License: %1" )
520 .arg( info.getLicense().getLicenseString() ) );
521
522 ImageLicenseLbl->setText( tr("Image License: %1" )
523 .arg( info.getImageLicense().getLicenseString() ) );
524
525 // Load the drumkit image
526 // Clear any image first
527 drumkitImageLabel->setPixmap( QPixmap() );
528 drumkitImageLabel->setText( info.getImage() );
529
530 if ( info.getImage().length() > 0 ) {
532 // get image file from local disk
533 QString sName = QFileInfo( info.getUrl() ).fileName();
534 sName = sName.left( sName.lastIndexOf( "." ) );
535
536 auto pDrumkit = H2Core::Hydrogen::get_instance()
538 if ( pDrumkit != nullptr ) {
539 // get the image from the local filesystem
540 QPixmap pixmap ( pDrumkit->get_path() + "/" + pDrumkit->get_image() );
541 INFOLOG("Loaded image " + pDrumkit->get_image() + " from local filesystem");
542 showImage( pixmap );
543 }
544 else {
545 ___ERRORLOG ( "Error loading the drumkit" );
546 }
547
548 }
549 else {
550 // Try from the cache
551 QString cachedFile = readCachedImage( info.getImage() );
552
553 if ( cachedFile.length() > 0 ) {
554 QPixmap pixmap ( cachedFile );
555 showImage( pixmap );
556 INFOLOG( "Loaded image " + info.getImage() + " from cache (" + cachedFile + ")" );
557 }
558 else {
559 // Get the drumkit's directory name from URL
560 //
561 // Example: if the server repo URL is: http://www.hydrogen-music.org/feeds/drumkit_list.php
562 // and the image name from the XML is Roland_TR-808_drum_machine.jpg
563 // the URL for the image will be: http://www.hydrogen-music.org/feeds/images/Roland_TR-808_drum_machine.jpg
564
565 if ( info.getImage().length() > 0 ) {
566 QString sImageUrl;
567 QString sLocalFile;
568
569 sImageUrl = repositoryCombo->currentText().left( repositoryCombo->currentText().lastIndexOf( QString( "/" )) + 1 ) + info.getImage() ;
570 sLocalFile = QDir::tempPath() + "/" + QFileInfo( sImageUrl ).fileName();
571
572 DownloadWidget dl( this, tr( "" ), sImageUrl, sLocalFile );
573 dl.exec();
574
575 loadImage( sLocalFile );
576 // Delete the temporary file
577 QFile::remove( sLocalFile );
578 }
579 }
580 }
581 }
582
583 DownloadBtn->setEnabled( true );
584 return;
585 }
586 }
587 }
588
589 SoundLibraryNameLbl->setText( "" );
590 SoundLibraryInfoLbl->setText( "" );
591 AuthorLbl->setText( "" );
592 DownloadBtn->setEnabled( false );
593}
594
595
596
598{
599 QApplication::setOverrideCursor(Qt::WaitCursor);
600 QString selected = m_pDrumkitTree->currentItem()->text(0);
601
602 for ( uint i = 0; i < m_soundLibraryList.size(); ++i ) {
603 if ( m_soundLibraryList[ i ].getName() == selected ) {
604 // Download the sound library
605 QString sURL = m_soundLibraryList[ i ].getUrl();
606 QString sType = m_soundLibraryList[ i ].getType();
607 QString sLocalFile;
608
609 if( sType == "drumkit") {
610 sLocalFile = QDir::tempPath() + "/" + QFileInfo( sURL ).fileName();
611 }
612
613 if( sType == "song") {
614 sLocalFile = H2Core::Filesystem::songs_dir() + QFileInfo( sURL ).fileName();
615 }
616
617 if( sType == "pattern") {
618 sLocalFile = H2Core::Filesystem::patterns_dir() + QFileInfo( sURL ).fileName();
619 }
620
621 bool Error = false;
622
623 for ( int i = 0; i < max_redirects; ++i ) {
624 DownloadWidget dl( this, tr( "Downloading SoundLibrary..." ), sURL, sLocalFile );
625 dl.exec();
626
627 QUrl redirect_url = dl.get_redirect_url();
628 if (redirect_url.isEmpty() ) {
629 // ok, we have all data
630 Error = !dl.get_error().isEmpty();
631 break;
632 }
633 else {
634 sURL = redirect_url.toEncoded();
635 Error = !dl.get_error().isEmpty();
636 }
637 }
638
639
640 //No 'else', error message has been already displayed by DL widget
641 if(!Error)
642 {
643 // install the new soundlibrary
644 try {
645 if ( sType == "drumkit" ) {
646 H2Core::Drumkit::install( sLocalFile );
647 QApplication::restoreOverrideCursor();
648 QMessageBox::information( this, "Hydrogen", QString( tr( "SoundLibrary imported in %1" ) ).arg( H2Core::Filesystem::usr_data_path() ) );
649 }
650
651 if ( sType == "song" || sType == "pattern") {
652 QApplication::restoreOverrideCursor();
653 }
654 }
655 catch( H2Core::H2Exception ex ) {
656 QApplication::restoreOverrideCursor();
657 QMessageBox::warning( this, "Hydrogen", tr( "An error occurred importing the SoundLibrary." ) );
658 }
659 }
660 else
661 {
662 QApplication::restoreOverrideCursor();
663 }
664
665 QApplication::setOverrideCursor(Qt::WaitCursor);
666 // remove the downloaded files..
667 if( sType == "drumkit" ) {
668 QDir dir;
669 dir.remove( sLocalFile );
670 }
671
672 // update the drumkit list
674 QApplication::restoreOverrideCursor();
675 return;
676 }
677 }
678}
679
680
681
682
684{
686 if ( ! H2Core::Filesystem::dir_readable( sPath, false ) ){
687 sPath = QDir::homePath();
688 }
689
690 FileDialog fd(this);
691 fd.setAcceptMode( QFileDialog::AcceptOpen );
692 fd.setFileMode(QFileDialog::ExistingFile);
693 fd.setNameFilter( "Hydrogen drumkit (*.h2drumkit)" );
694 fd.setDirectory( sPath );
695
696 fd.setWindowTitle( tr( "Import drumkit" ) );
697
698 QString filename = "";
699 if (fd.exec() == QDialog::Accepted) {
700 filename = fd.selectedFiles().first();
701 }
702
703 if (filename != "") {
704 SoundLibraryPathTxt->setText( filename );
705 H2Core::Preferences::get_instance()->setLastImportDrumkitDirectory( fd.directory().absolutePath() );
706 InstallBtn->setEnabled ( true );
707 }
708}
709
710
711
712
714{
715 QApplication::setOverrideCursor(Qt::WaitCursor);
716
717 try {
718 H2Core::Drumkit::install( SoundLibraryPathTxt->text() );
719 // update the drumkit list
721 QApplication::restoreOverrideCursor();
722 QMessageBox::information( this, "Hydrogen",
723 QString( tr( "SoundLibrary imported in %1" )
725 }
726 catch( H2Core::H2Exception ex ) {
727 QApplication::restoreOverrideCursor();
728 QMessageBox::warning( this, "Hydrogen", tr( "An error occurred importing the SoundLibrary." ) );
729 }
730}
731
732
733
#define INFOLOG(x)
Definition Object.h:237
#define WARNINGLOG(x)
Definition Object.h:238
#define ERRORLOG(x)
Definition Object.h:239
#define ___ERRORLOG(x)
Definition Object.h:257
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:33
static bool install(const QString &sSourcePath, const QString &sTargetPath="", bool bSilent=false)
Extract a .h2drumkit file.
Definition Drumkit.cpp:565
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:83
SoundLibraryDatabase * getSoundLibraryDatabase() const
Definition Hydrogen.h:94
QString getLicenseString() const
Definition License.h:146
Manager for User Preferences File (singleton)
Definition Preferences.h:78
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