hydrogen 1.2.3
SoundLibraryPanel.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
23#include "SoundLibraryPanel.h"
24
25#include <QtGui>
26#include <QtWidgets>
27
28#include "SoundLibraryTree.h"
29#include "FileBrowser.h"
30
33
34#include "../HydrogenApp.h"
35#include "../CommonStrings.h"
36#include "../Widgets/Button.h"
42#include "../InstrumentRack.h"
44
45#include <core/Basics/Adsr.h>
47#include <core/H2Exception.h>
48#include <core/Hydrogen.h>
49#include <core/Basics/Drumkit.h>
52#include <core/Basics/Pattern.h>
54#include <core/Basics/Sample.h>
55#include <core/Basics/Song.h>
58
59using namespace H2Core;
60
61#include <cassert>
62
63SoundLibraryPanel::SoundLibraryPanel( QWidget *pParent, bool bInItsOwnDialog )
64 : QWidget( pParent )
65 , __sound_library_tree( nullptr )
66 , __drumkit_menu( nullptr )
67 , __song_menu( nullptr )
68 , __pattern_menu( nullptr )
69 , __pattern_menu_list( nullptr )
70 , m_pTreeSystemDrumkitsItem( nullptr )
71 , m_pTreeUserDrumkitsItem( nullptr )
72 , m_pTreeSessionDrumkitsItem( nullptr )
73 , __song_item( nullptr )
74 , __pattern_item( nullptr )
75 , __pattern_item_list( nullptr )
76 , m_bInItsOwnDialog( bInItsOwnDialog )
77{
78
79 __drumkit_menu = new QMenu( this );
80 __drumkit_menu->addAction( tr( "Load" ), this, SLOT( on_drumkitLoadAction() ) );
81 __drumkit_menu->addAction( tr( "Export" ), this, SLOT( on_drumkitExportAction() ) );
82 __drumkit_menu->addAction( tr( "Properties" ), this, SLOT( on_drumkitPropertiesAction() ) );
83 __drumkit_menu->addSeparator();
84 __drumkit_menu->addAction( tr( "Delete" ), this, SLOT( on_drumkitDeleteAction() ) );
85
86 // A version with reduced functionality for read-only drumkits
87 __drumkit_menu_system = new QMenu( this );
88 __drumkit_menu_system->addAction( tr( "Load" ), this, SLOT( on_drumkitLoadAction() ) );
89 __drumkit_menu_system->addAction( tr( "Export" ), this, SLOT( on_drumkitExportAction() ) );
90 __drumkit_menu_system->addAction( tr( "Properties" ), this, SLOT( on_drumkitPropertiesAction() ) );
91
92 __song_menu = new QMenu( this );
93 __song_menu->addSeparator();
94 __song_menu->addAction( tr( "Load" ), this, SLOT( on_songLoadAction() ) );
95
96 __pattern_menu = new QMenu( this );
97 __pattern_menu->addSeparator();
98 __pattern_menu->addAction( tr( "Load" ), this, SLOT( on_patternLoadAction() ) );
99 __pattern_menu->addAction( tr( "Delete" ), this, SLOT( on_patternDeleteAction() ) );
100
101 __pattern_menu_list = new QMenu( this );
102 __pattern_menu_list->addSeparator();
103 __pattern_menu_list->addAction( tr( "Load" ), this, SLOT( on_patternLoadAction() ) );
104
105// DRUMKIT LIST
106 __sound_library_tree = new SoundLibraryTree( nullptr );
107 connect( __sound_library_tree, SIGNAL( currentItemChanged ( QTreeWidgetItem*, QTreeWidgetItem* ) ), this, SLOT( on_DrumkitList_ItemChanged( QTreeWidgetItem*, QTreeWidgetItem* ) ) );
108 connect( __sound_library_tree, SIGNAL( itemActivated ( QTreeWidgetItem*, int ) ), this, SLOT( on_DrumkitList_itemActivated( QTreeWidgetItem*, int ) ) );
109 connect( __sound_library_tree, SIGNAL( leftClicked(QPoint) ), this, SLOT( on_DrumkitList_leftClicked(QPoint)) );
110 if( ! m_bInItsOwnDialog ) {
111 connect( __sound_library_tree, SIGNAL( rightClicked(QPoint) ), this, SLOT( on_DrumkitList_rightClicked(QPoint)) );
112 connect( __sound_library_tree, SIGNAL( onMouseMove( QMouseEvent* ) ), this, SLOT( on_DrumkitList_mouseMove( QMouseEvent* ) ) );
113 }
114
115
116 // LAYOUT
117 QVBoxLayout *pVBox = new QVBoxLayout();
118 pVBox->setSpacing( 0 );
119 pVBox->setMargin( 0 );
120
121 pVBox->addWidget( __sound_library_tree );
122
123
124 this->setLayout( pVBox );
125
128
130
131 updateTree();
132
134}
135
136
137
139{
140 if ( auto pH2App = HydrogenApp::get_instance() ) {
141 pH2App->removeEventListener( this );
142 }
143}
144
145
146
148{
150 auto pHydrogen = H2Core::Hydrogen::get_instance();
151 auto pSoundLibraryDatabase = pHydrogen->getSoundLibraryDatabase();
152 auto pCommonStrings = HydrogenApp::get_instance()->getCommonStrings();
153
154 __sound_library_tree->clear();
155
156 QFont boldFont( pPref->getApplicationFontFamily(), getPointSize( pPref->getFontSize() ) );
157 boldFont.setBold( true );
158
159 QFont childFont( pPref->getLevel2FontFamily(), getPointSize( pPref->getFontSize() ) );
160 setFont( childFont );
161
163 m_pTreeUserDrumkitsItem = nullptr;
165
166 // top-level drumkit items found
167 QList<QTreeWidgetItem*> drumkitItems;
168
169 // drumkit list
170 m_drumkitRegister.clear();
171 m_drumkitLabels.clear();
172 for ( const auto& pDrumkitEntry : pSoundLibraryDatabase->getDrumkitDatabase() ) {
173 auto pDrumkit = pDrumkitEntry.second;
174 if ( pDrumkit != nullptr ) {
175 QString sItemLabel = pDrumkit->get_name();
176 auto drumkitType =
177 Filesystem::determineDrumkitType( pDrumkitEntry.first );
178
179 QTreeWidgetItem* pDrumkitItem;
180 if ( drumkitType == Filesystem::DrumkitType::System ) {
181 if ( m_pTreeSystemDrumkitsItem == nullptr ) {
182 m_pTreeSystemDrumkitsItem = new QTreeWidgetItem();
183 m_pTreeSystemDrumkitsItem->setText( 0, tr( "System drumkits" ) );
184 m_pTreeSystemDrumkitsItem->setFont( 0, boldFont );
185 }
186
187 pDrumkitItem = new QTreeWidgetItem( m_pTreeSystemDrumkitsItem );
188 sItemLabel.append( QString( " (%1)" )
189 .arg( pCommonStrings->getSoundLibrarySystemSuffix() ) );
190 }
191 else if ( drumkitType == Filesystem::DrumkitType::User ) {
192 if ( m_pTreeUserDrumkitsItem == nullptr ) {
193 m_pTreeUserDrumkitsItem = new QTreeWidgetItem();
194 m_pTreeUserDrumkitsItem->setText( 0, tr( "User drumkits" ) );
195 m_pTreeUserDrumkitsItem->setFont( 0, boldFont );
196 }
197
198 pDrumkitItem = new QTreeWidgetItem( m_pTreeUserDrumkitsItem );
199 } else {
200 if ( m_pTreeSessionDrumkitsItem == nullptr ) {
201 m_pTreeSessionDrumkitsItem = new QTreeWidgetItem();
202 m_pTreeSessionDrumkitsItem->setText( 0, tr( "Session drumkits" ) );
203 m_pTreeSessionDrumkitsItem->setFont( 0, boldFont );
204 }
205 pDrumkitItem = new QTreeWidgetItem( m_pTreeSessionDrumkitsItem );
206 sItemLabel.append( QString( " (%1)" )
207 .arg( pCommonStrings->getSoundLibrarySessionSuffix() ) );
208 }
209
210
211 // Ensure uniqueness of the label.
212 int nCount = 1;
213 while ( m_drumkitLabels.contains( sItemLabel ) ) {
214 sItemLabel = QString( "%1 (%2)" )
215 .arg( pDrumkit->get_name() ).arg( nCount );
216 nCount++;
217 }
218
219 m_drumkitLabels << sItemLabel;
220 m_drumkitRegister[ sItemLabel ] = pDrumkitEntry.first;
221
222 pDrumkitItem->setText( 0, sItemLabel );
223 pDrumkitItem->setToolTip( 0, pDrumkitEntry.first );
224 if ( ! m_bInItsOwnDialog ) {
225 auto pInstrList = pDrumkit->get_instruments();
226 for ( const auto& pInstrument : *pDrumkit->get_instruments() ) {
227 if ( pInstrument != nullptr ) {
228 QTreeWidgetItem* pInstrumentItem = new QTreeWidgetItem( pDrumkitItem );
229 pInstrumentItem->setText( 0, QString( "[%1] %2" )
230 .arg( pInstrument->get_id() )
231 .arg( pInstrument->get_name() ) );
232 pInstrumentItem->setToolTip( 0, pInstrument->get_name() );
233 }
234 }
235 }
236 }
237 }
238
239 // Ensure the ordering of the top-level nodes is always
240 // system > user > session
241 if ( m_pTreeSystemDrumkitsItem != nullptr ) {
242 drumkitItems << m_pTreeSystemDrumkitsItem;
243 }
244 if ( m_pTreeUserDrumkitsItem != nullptr ) {
245 drumkitItems << m_pTreeUserDrumkitsItem;
246 }
247 if ( m_pTreeSessionDrumkitsItem != nullptr ) {
248 drumkitItems << m_pTreeSessionDrumkitsItem;
249 }
250 __sound_library_tree->addTopLevelItems( drumkitItems );
251
252 // Ensure drumkit nodes are expanded (necessary when added as
253 // above.)
254 if ( m_pTreeSystemDrumkitsItem != nullptr ) {
255 m_pTreeSystemDrumkitsItem->setExpanded( true );
256 }
257 if ( m_pTreeUserDrumkitsItem != nullptr ) {
258 m_pTreeUserDrumkitsItem->setExpanded( true );
259 }
260 if ( m_pTreeSessionDrumkitsItem != nullptr ) {
261 m_pTreeSessionDrumkitsItem->setExpanded( true );
262 }
263
264 if ( ! m_bInItsOwnDialog ) {
265 //Songlist
266 QStringList songs = Filesystem::song_list_cleared();
267 if ( songs.size() > 0 ) {
268 __song_item = new QTreeWidgetItem( __sound_library_tree );
269 __song_item->setText( 0, tr( "Songs" ) );
270 __song_item->setToolTip( 0, tr("Double click to expand the list") );
271 __song_item->setExpanded( __expand_songs_list );
272 __song_item->setFont( 0, boldFont );
273 for (uint i = 0; i < songs.size(); i++) {
274 QTreeWidgetItem* pSongItem = new QTreeWidgetItem( __song_item );
275 QString song = songs[i];
276 pSongItem->setText( 0 , song.left( song.indexOf(".")) );
277 pSongItem->setToolTip( 0, song );
278 }
279 }
280
281
282 //Pattern list
283 QStringList patternDirList = Filesystem::pattern_drumkits();
284 if ( patternDirList.size() > 0 ) {
285
286 __pattern_item = new QTreeWidgetItem( __sound_library_tree );
287 __pattern_item->setText( 0, tr( "Patterns" ) );
288 __pattern_item->setToolTip( 0, tr("Double click to expand the list") );
290 __pattern_item->setFont( 0, boldFont );
291
292 auto patternInfoVector = pSoundLibraryDatabase->getPatternInfoVector();
293 QStringList patternCategories =
294 pSoundLibraryDatabase->getPatternCategories();
295
296 //now sorting via category
297
298 /*: Base tooltip displayed when hovering over a pattern in
299 the Sound Library. It indicates which drumkit the
300 pattern was created with*/
301 QString sPatternTooltip = tr( "Created for drumkit" );
302 for ( const auto& categoryName : patternCategories ) {
303
304 QTreeWidgetItem* pCategoryItem = new QTreeWidgetItem( __pattern_item );
305 pCategoryItem->setText( 0, categoryName );
306
307 for ( const auto& pInfo : patternInfoVector ) {
308 QString patternCategory = pInfo->getCategory();
309 if ( ( patternCategory == categoryName ) ||
310 ( patternCategory.isEmpty() && categoryName == "No category" ) ){
311 QTreeWidgetItem* pPatternItem = new QTreeWidgetItem( pCategoryItem );
312 pPatternItem->setText( 0, pInfo->getName());
313 pPatternItem->setText( 1, pInfo->getPath() );
314 pPatternItem->setToolTip( 0, QString( "%1 [%2]" )
315 .arg( sPatternTooltip )
316 .arg( pInfo->getDrumkitName() ) );
317 }
318 }
319 }
320 }
321 }
322
324}
325
326
327
328void SoundLibraryPanel::on_DrumkitList_ItemChanged( QTreeWidgetItem * current, QTreeWidgetItem * previous )
329{
330 UNUSED( previous );
331
332 if( current == nullptr ){
333 return;
334 }
335
336 if ( current->parent() == m_pTreeSystemDrumkitsItem ||
337 current->parent() == m_pTreeUserDrumkitsItem ||
338 current->parent() == m_pTreeSessionDrumkitsItem ){
339 emit item_changed( true );
340 } else {
341 emit item_changed( false );
342 }
343
345}
346
347
348
349void SoundLibraryPanel::on_DrumkitList_itemActivated( QTreeWidgetItem * item, int column )
350{
351 UNUSED( column );
352
353// INFOLOG( "[on_DrumkitList_itemActivated]" );
354 if ( item == m_pTreeSystemDrumkitsItem ||
355 item == m_pTreeUserDrumkitsItem ||
357 ( ( m_pTreeSystemDrumkitsItem != nullptr &&
358 item == m_pTreeSystemDrumkitsItem->parent() ) ||
359 ( m_pTreeUserDrumkitsItem != nullptr &&
360 item == m_pTreeUserDrumkitsItem->parent() ) ||
361 ( m_pTreeSessionDrumkitsItem != nullptr &&
362 item == m_pTreeSessionDrumkitsItem->parent() ) )||
363 item->parent() == __song_item ||
364 item == __song_item ||
365 item == __pattern_item ||
366 item->parent() == __pattern_item ||
367 item->parent()->parent() == __pattern_item ||
368 item == __pattern_item_list ||
369 item->parent() == __pattern_item_list ||
370 item->parent()->parent() == __pattern_item_list ) {
371 return;
372 }
373
374 if ( item->parent() == m_pTreeSystemDrumkitsItem ||
375 item->parent() == m_pTreeUserDrumkitsItem ||
376 item->parent() == m_pTreeSessionDrumkitsItem ) {
377 // Double clicking a drumkit
378 }
379 else {
380 // Double clicking an instrument
381 QString sSelectedName = item->text(0);
382
383 QString sInstrName = sSelectedName.remove( 0, sSelectedName.indexOf( "] " ) + 2 );
384 QString sDrumkitName = item->parent()->text(0);
385 QString sDrumkitPath = m_drumkitRegister[ sDrumkitName ];
386 INFOLOG( QString( "Loading instrument [%1] from drumkit [%2] located in [%3]" )
387 .arg( sInstrName ).arg( sDrumkitName ).arg( sDrumkitPath ) );
388
389 auto pInstrument = Instrument::load_instrument( sDrumkitPath, sInstrName );
390
391 if ( pInstrument == nullptr ) {
392 ERRORLOG( "Unable to load instrument. Abort" );
393 return;
394 }
395
396 pInstrument->set_muted( false );
397
399 }
400}
401
402
403
404
405
406
407
409{
410 if( __sound_library_tree->currentItem() == nullptr ) {
411 return;
412 }
413
414 if (
415 __sound_library_tree->currentItem()->parent() == nullptr ||
419 return;
420 }
421
422 if ( __sound_library_tree->currentItem()->parent() == __song_item ) {
423 __song_menu->popup( pos );
424 }
425
426 if ( __sound_library_tree->currentItem()->parent()->parent() == __pattern_item && __pattern_item != nullptr ) {
427 __pattern_menu->popup( pos );
428 }
429
430 if ( __sound_library_tree->currentItem()->parent() == m_pTreeUserDrumkitsItem ) {
431 __drumkit_menu->popup( pos );
432 }
433
434 if ( __sound_library_tree->currentItem()->parent() == m_pTreeSystemDrumkitsItem ) {
435 __drumkit_menu_system->popup( pos );
436 }
437
438 // We do not provide distinct parent items for read-only and
439 // writable session drumkits as it would make the GUI unnecessary
440 // complex. Instead, the level of access for the current user is
441 // checked during runtime (which should be a very rare thing to do).
442 if ( __sound_library_tree->currentItem()->parent() == m_pTreeSessionDrumkitsItem ) {
443 const QString sDrumkitName = __sound_library_tree->currentItem()->text( 0 );
444 const QString sDrumkitPath = m_drumkitRegister[ sDrumkitName ];
445 const auto drumkitType = Filesystem::determineDrumkitType( sDrumkitPath );
446
447 if ( drumkitType == Filesystem::DrumkitType::SessionReadOnly ) {
448 __drumkit_menu_system->popup( pos );
449 } else {
450 __drumkit_menu->popup( pos );
451 }
452 }
453
454}
455
456
457
462
463
464
466{
467 if (! ( event->buttons() & Qt::LeftButton ) ) {
468 return;
469 }
470
471 if ( ( event->pos() - __start_drag_position ).manhattanLength() < QApplication::startDragDistance() ) {
472 return;
473 }
474
475 if ( !__sound_library_tree->currentItem() ) {
476 return;
477 }
478
479 if ( __sound_library_tree->currentItem()->parent() == m_pTreeSystemDrumkitsItem ||
480 __sound_library_tree->currentItem()->parent() == m_pTreeUserDrumkitsItem ||
481 __sound_library_tree->currentItem()->parent() == m_pTreeSessionDrumkitsItem ) {
482 // drumkit selection
483 //INFOLOG( "ho selezionato un drumkit (system)" );
484 return;
485 }
486 else {
487 //INFOLOG( "ho selezionato uno strumento" );
488 // instrument selection
489 if ( __sound_library_tree->currentItem() == nullptr )
490 {
491 return;
492 }
493
494 if ( __sound_library_tree->currentItem()->parent() == nullptr )
495 {
496 return;
497 }
498
499 if ( __sound_library_tree->currentItem()->parent() == __song_item )
500 {
501 return;
502 }
503
504 if ( __sound_library_tree->currentItem()->parent()->text(0) == nullptr )
505 {
506 return;
507 }
508
509 if ( __sound_library_tree->currentItem()->parent() == __pattern_item ) {
510 return;
511 }
512
513 if ( __sound_library_tree->currentItem()->parent()->parent() == __pattern_item ) {
514
515 QString sPatternPath = __sound_library_tree->currentItem()->text( 1 );
516 QString dragtype = "drag pattern";
517 QString sText = dragtype + "::" + sPatternPath;
518
519 QDrag *pDrag = new QDrag(this);
520 QMimeData *pMimeData = new QMimeData;
521
522 pMimeData->setText( sText );
523 pDrag->setMimeData( pMimeData);
524 pDrag->exec( Qt::CopyAction | Qt::MoveAction );
525 return;
526 }
527
528 const QString sDrumkitName = __sound_library_tree->currentItem()->parent()->text(0);
529 const QString sDrumkitPath = m_drumkitRegister[ sDrumkitName ];
530 const QString sInstrumentName = ( __sound_library_tree->currentItem()->text(0) )
531 .remove( 0, __sound_library_tree->currentItem()->text(0).indexOf( "] " ) + 2 );
532
533 const QString sText = "importInstrument:" + sDrumkitPath + "::" + sInstrumentName;
534
535 QDrag *pDrag = new QDrag(this);
536 QMimeData *pMimeData = new QMimeData;
537
538 pMimeData->setText( sText );
539 pDrag->setMimeData( pMimeData);
540
541 pDrag->exec( Qt::CopyAction | Qt::MoveAction );
542 }
543}
544
545
546
548{
549 auto pHydrogen = H2Core::Hydrogen::get_instance();
550
551 QString sDrumkitName = __sound_library_tree->currentItem()->text(0);
552 QString sDrumkitPath = m_drumkitRegister[ sDrumkitName ];
553 auto pDrumkit =
554 pHydrogen->getSoundLibraryDatabase()->getDrumkit( sDrumkitPath );
555
556 if ( pDrumkit == nullptr ) {
557 ERRORLOG( QString( "Unable to find drumkit [%1] (mapped to path [%2]" )
558 .arg( sDrumkitName ).arg( sDrumkitPath ) );
559 return;
560 }
561
562 auto pSongInstrList = pHydrogen->getSong()->getInstrumentList();
563 auto pDrumkitInstrList = pDrumkit->get_instruments();
564
565 int oldCount = pSongInstrList->size();
566 int newCount = pDrumkitInstrList->size();
567
568 bool conditionalLoad = false;
569 bool hasNotes = false;
570
571 INFOLOG("Old kit has " + QString::number( oldCount ) + " instruments, new one has " + QString::number( newCount ) );
572
573 if ( newCount < oldCount )
574 {
575 // Check if any of the instruments that will be removed have notes
576 for ( int i = 0; i < pSongInstrList->size(); i++)
577 {
578 if ( i >= newCount )
579 {
580 INFOLOG("Checking if Instrument " + QString::number( i ) + " has notes..." );
581
582 if ( pHydrogen->instrumentHasNotes( pSongInstrList->get( i ) ) )
583 {
584 hasNotes = true;
585 INFOLOG("Instrument " + QString::number( i ) + " has notes" );
586 }
587 }
588
589 }
590
591 if ( hasNotes ) {
592 auto pCommonStrings = HydrogenApp::get_instance()->getCommonStrings();
593 QMessageBox msgBox;
594 msgBox.setWindowTitle("Hydrogen");
595 msgBox.setIcon( QMessageBox::Warning );
596 msgBox.setText( tr( "The existing kit has %1 instruments but the new one only has %2.\nThe first %2 instruments will be replaced with the new instruments and will keep their notes, but some of the remaining instruments have notes.\nWould you like to keep or discard the remaining instruments and notes?\n").arg( QString::number( oldCount ),QString::number( newCount ) ) );
597
598 msgBox.setStandardButtons( QMessageBox::Save | QMessageBox::Discard |
599 QMessageBox::Cancel );
600 msgBox.setButtonText(QMessageBox::Save, tr("Keep"));
601 msgBox.setButtonText(QMessageBox::Discard,
602 pCommonStrings->getButtonDiscard() );
603 msgBox.setButtonText(QMessageBox::Cancel,
604 pCommonStrings->getButtonCancel());
605 msgBox.setDefaultButton(QMessageBox::Cancel);
606
607 switch ( msgBox.exec() )
608 {
609 case QMessageBox::Save:
610 // Save old instruments with notes
611 conditionalLoad = true;
612 break;
613
614 case QMessageBox::Discard:
615 // discard extra instruments
616 conditionalLoad = false;
617 break;
618
619 case QMessageBox::Cancel:
620 // Cancel
621 return;
622 }
623 }
624 }
625
626 assert( pDrumkit );
627
628 QApplication::setOverrideCursor(Qt::WaitCursor);
629
630 pHydrogen->getCoreActionController()->setDrumkit( pDrumkit, conditionalLoad );
631
632 QApplication::restoreOverrideCursor();
633}
634
638
642
648
649
650
652{
653 if ( m_pTreeSystemDrumkitsItem != nullptr ) {
654 for (int i = 0; i < m_pTreeSystemDrumkitsItem->childCount() ; i++){
655 ( m_pTreeSystemDrumkitsItem->child( i ) )->setBackground( 0, QBrush() );
656 }
657 }
658
659 if ( m_pTreeUserDrumkitsItem != nullptr ) {
660 for (int i = 0; i < m_pTreeUserDrumkitsItem->childCount() ; i++){
661 ( m_pTreeUserDrumkitsItem->child( i ) )->setBackground(0, QBrush() );
662 }
663 }
664
665 if ( m_pTreeSessionDrumkitsItem != nullptr ) {
666 for (int i = 0; i < m_pTreeSessionDrumkitsItem->childCount() ; i++){
667 ( m_pTreeSessionDrumkitsItem->child( i ) )->setBackground( 0, QBrush() );
668 }
669 }
670
671}
672
673QString SoundLibraryPanel::getDrumkitLabel( const QString& sDrumkitPath ) const {
674 for ( const auto& entry : m_drumkitRegister ) {
675 if ( entry.second == sDrumkitPath ) {
676 return entry.first;
677 }
678 }
679
680 return "";
681}
682QString SoundLibraryPanel::getDrumkitPath( const QString& sDrumkitLabel ) const {
683 return m_drumkitRegister.at( sDrumkitLabel );
684}
685
687{
688 auto pSelectedInstrument = Hydrogen::get_instance()->getSelectedInstrument();
689 if ( pSelectedInstrument == nullptr ) {
690 DEBUGLOG( "No instrument selected" );
691 return;
692 }
693 QString sDrumkitPath = pSelectedInstrument->get_drumkit_path();
694 QString sDrumkitLabel = getDrumkitLabel( sDrumkitPath );
695
696 if ( sDrumkitLabel.isEmpty() ) {
697 ERRORLOG( QString( "Unable to find label corresponding to drumkit [%1]. No highlighting applied" )
698 .arg( sDrumkitPath ) );
699 return;
700 }
701
702 if ( m_pTreeSystemDrumkitsItem != nullptr ) {
703 for ( int i = 0; i < m_pTreeSystemDrumkitsItem->childCount() ; i++){
704 if ( ( m_pTreeSystemDrumkitsItem->child( i ) )->text( 0 ) == sDrumkitLabel ){
705 ( m_pTreeSystemDrumkitsItem->child( i ) )->setBackground( 0, QColor( 50, 50, 50) );
706 return;
707 }
708 }
709 }
710
711 if ( m_pTreeUserDrumkitsItem != nullptr ) {
712 for (int i = 0; i < m_pTreeUserDrumkitsItem->childCount() ; i++){
713 if ( ( m_pTreeUserDrumkitsItem->child( i ))->text( 0 ) == sDrumkitLabel ){
714 ( m_pTreeUserDrumkitsItem->child( i ) )->setBackground( 0, QColor( 50, 50, 50) );
715 break;
716 }
717 }
718 }
719
720 if ( m_pTreeSessionDrumkitsItem != nullptr ) {
721 for ( int i = 0; i < m_pTreeSessionDrumkitsItem->childCount() ; i++){
722 if ( ( m_pTreeSessionDrumkitsItem->child( i ) )->text( 0 ) == sDrumkitLabel ){
723 ( m_pTreeSessionDrumkitsItem->child( i ) )->setBackground( 0, QColor( 50, 50, 50) );
724 return;
725 }
726 }
727 }
728
729}
730
731
733{
734 QTreeWidgetItem* pItem = __sound_library_tree->currentItem();
735 const QString sDrumkitName = pItem->text(0);
736 const QString sDrumkitPath = m_drumkitRegister[ sDrumkitName ];
737 const auto drumkitType = Filesystem::determineDrumkitType( sDrumkitPath );
738
739 auto pCommonStrings = HydrogenApp::get_instance()->getCommonStrings();
740
741 if ( pItem->parent() == m_pTreeSystemDrumkitsItem ||
742 ( pItem->parent() == m_pTreeSessionDrumkitsItem &&
743 drumkitType == Filesystem::DrumkitType::SessionReadOnly ) ) {
744 QMessageBox::warning( this, "Hydrogen", QString( "\"%1\" " )
745 .arg(sDrumkitName)
746 .append( tr( "is a read-only drumkit and can't be deleted.") ) );
747 return;
748 }
749
750 // If we delete the current loaded drumkit we can get trouble with some empty pointers
751 if ( pItem->text(0) == Hydrogen::get_instance()->getLastLoadedDrumkitName() ){
752 QMessageBox::warning( this, "Hydrogen", tr( "It is not possible to delete the currently loaded drumkit: \n \"%1\".\nTo delete this drumkit first load another drumkit.").arg(sDrumkitName) );
753 return;
754 }
755
756 int res = QMessageBox::warning( this, "Hydrogen",
757 tr( "Warning, the \"%1\" drumkit will be deleted from disk.\nAre you sure?").arg(sDrumkitName),
758 pCommonStrings->getButtonOk(),
759 pCommonStrings->getButtonCancel(),
760 nullptr, 1 );
761 if ( res == 1 ) {
762 return;
763 }
764
765 QApplication::setOverrideCursor(Qt::WaitCursor);
766 bool bSuccess = Drumkit::remove( m_drumkitRegister[ pItem->text(0) ] );
767 QApplication::restoreOverrideCursor();
768 if ( ! bSuccess ) {
769 QMessageBox::warning( this, "Hydrogen", tr( "Drumkit deletion failed.") );
770 }
771}
772
773
774
776{
777 auto pSoundLibraryDatabase =
779
780 QString sDrumkitName = __sound_library_tree->currentItem()->text(0);
781 QString sDrumkitPath = m_drumkitRegister[ sDrumkitName ];
782 auto pDrumkit = pSoundLibraryDatabase->getDrumkit( sDrumkitPath );
783
784 SoundLibraryExportDialog exportDialog( this, pDrumkit );
785 exportDialog.exec();
786}
787
788
789
791{
792 auto pHydrogen = H2Core::Hydrogen::get_instance();
793 auto pSoundLibraryDatabase = pHydrogen->getSoundLibraryDatabase();
794
795 QString sDrumkitName = __sound_library_tree->currentItem()->text(0);
796 QString sDrumkitPath = m_drumkitRegister[ sDrumkitName ];
797 auto pDrumkit = pSoundLibraryDatabase->getDrumkit( sDrumkitPath );
798
799 if ( pDrumkit == nullptr ) {
800 ERRORLOG( QString( "Unable to find drumkit [%1] (mapped to path [%2]" )
801 .arg( sDrumkitName ).arg( sDrumkitPath ) );
802 return;
803 }
804
805 // We provide a copy of the recent drumkit to ensure the drumkit
806 // is not getting dirty upon saving (in case new properties are
807 // stored in the kit but writing it to disk fails).
808 auto pNewDrumkit = std::make_shared<Drumkit>( pDrumkit );
809 SoundLibraryPropertiesDialog dialog( this, pNewDrumkit, true );
810 dialog.exec();
811}
812
814{
815 QString sFilename = Filesystem::song_path( __sound_library_tree->currentItem()->text( 0 ) );
816
817 HydrogenApp::get_instance()->openSong( sFilename );
818}
819
820
821
823
824 QString sPatternName = __sound_library_tree->currentItem()->text( 0 );
825 QString sDrumkitName = __sound_library_tree->currentItem()->toolTip ( 0 );
827 ->openPattern( Filesystem::pattern_path( sDrumkitName,
828 sPatternName ) );
829}
830
831
833{
834 auto pCommonStrings = HydrogenApp::get_instance()->getCommonStrings();
835 QString patternPath = __sound_library_tree->currentItem()->text( 1 );
836
837 int res = QMessageBox::information( this, "Hydrogen",
838 tr( "Warning, the selected pattern will be deleted from disk.\nAre you sure?"),
839 pCommonStrings->getButtonOk(),
840 pCommonStrings->getButtonCancel(),
841 nullptr, 1 );
842 if ( res == 1 ) {
843 return;
844 }
845
846 QFile rmfile( patternPath );
847 bool err = rmfile.remove();
848 if ( err == false ) {
849 ERRORLOG( "Error removing the pattern" );
850 }
851
853}
854
859
861{
862 assert( __sound_library_tree );
863 if ( __song_item == nullptr) {
864 __expand_songs_list = false;
865 } else {
866 __expand_songs_list = __song_item->isExpanded();
867 }
868 if ( __pattern_item == nullptr) {
869 __expand_pattern_list = false;
870 } else {
872 }
875 //ERRORLOG( QString("songs %1 patterns %2").arg(__expand_songs_list).arg(__expand_pattern_list) );
876}
877
880
881 if ( changes & H2Core::Preferences::Changes::Font ) {
882
883 QFont font( pPref->getLevel2FontFamily(), getPointSize( pPref->getFontSize() ) );
884 QFont boldFont( pPref->getApplicationFontFamily(), getPointSize( pPref->getFontSize() ) );
885 boldFont.setBold( true );
886
887 int ii, jj;
888 QTreeWidgetItem* childNode;
889 if ( m_pTreeSystemDrumkitsItem != nullptr ) {
890 m_pTreeSystemDrumkitsItem->setFont( 0, boldFont );
891 for ( ii = 0; ii < m_pTreeSystemDrumkitsItem->childCount(); ii++ ){
892 childNode = m_pTreeSystemDrumkitsItem->child( ii );
893 childNode->setFont( 0, font );
894 for ( jj = 0; jj < childNode->childCount(); jj++ ) {
895 childNode->child( jj )->setFont( 0, font );
896 }
897 }
898 }
899
900 if ( m_pTreeUserDrumkitsItem != nullptr ) {
901 m_pTreeUserDrumkitsItem->setFont( 0, boldFont );
902 for ( ii = 0; ii < m_pTreeUserDrumkitsItem->childCount(); ii++ ){
903 childNode = m_pTreeUserDrumkitsItem->child( ii );
904 childNode->setFont( 0, font );
905 for ( jj = 0; jj < childNode->childCount(); jj++ ) {
906 childNode->child( jj )->setFont( 0, font );
907 }
908 }
909 }
910
911 if ( m_pTreeSessionDrumkitsItem != nullptr ) {
912 m_pTreeSessionDrumkitsItem->setFont( 0, boldFont );
913 for ( ii = 0; ii < m_pTreeSessionDrumkitsItem->childCount(); ii++ ){
914 childNode = m_pTreeSessionDrumkitsItem->child( ii );
915 childNode->setFont( 0, font );
916 for ( jj = 0; jj < childNode->childCount(); jj++ ) {
917 childNode->child( jj )->setFont( 0, font );
918 }
919 }
920 }
921
922 if ( __song_item != nullptr ) {
923 __song_item->setFont( 0, boldFont );
924 for ( ii = 0; ii < __song_item->childCount(); ii++ ){
925 __song_item->child( ii )->setFont( 0, font );
926 __song_item->setFont( ii, font );
927 }
928 }
929
930 if ( __pattern_item != nullptr ) {
931 __pattern_item->setFont( 0, boldFont );
932 for ( ii = 0; ii < __pattern_item->childCount(); ii++ ){
933 childNode = __pattern_item->child( ii );
934 childNode->setFont( 0, font );
935 for ( jj = 0; jj < childNode->childCount(); jj++ ) {
936 childNode->child( jj )->setFont( 0, font );
937 }
938 }
939 }
940 }
941}
942
944 // A new song got loaded
945 if ( nValue == 0 ) {
947 }
948}
#define INFOLOG(x)
Definition Object.h:237
#define ERRORLOG(x)
Definition Object.h:239
#define DEBUGLOG(x)
Definition Object.h:236
Sampler * getSampler() const
bool openPattern(const QString &sPath, int nPatternNumber=-1)
Opens a pattern from disk and adds it to the pattern list.
static bool remove(const QString &sDrumkitDir)
remove a drumkit from the disk
Definition Drumkit.cpp:548
static QString song_path(const QString &sg_name)
returns user song path, add file extension
static DrumkitType determineDrumkitType(const QString &sPath)
static QStringList song_list_cleared()
returns a list of existing songs, excluding the autosaved one
static QStringList pattern_drumkits()
returns a list of existing drumkit sub dir into the patterns directory
static QString pattern_path(const QString &dk_name, const QString &p_name)
returns user patterns path, add file extension
static Hydrogen * get_instance()
Returns the current Hydrogen instance __instance.
Definition Hydrogen.h:83
AudioEngine * getAudioEngine() const
Definition Hydrogen.h:649
std::shared_ptr< Instrument > getSelectedInstrument() const
SoundLibraryDatabase * getSoundLibraryDatabase() const
Definition Hydrogen.h:94
QString getLastLoadedDrumkitName() const
CoreActionController * getCoreActionController() const
Definition Hydrogen.h:639
static std::shared_ptr< Instrument > load_instrument(const QString &drumkit_path, const QString &instrument_name)
creates a new Instrument, loads samples from a given instrument within a given drumkit
static Preferences * get_instance()
Returns a pointer to the current Preferences singleton stored in __instance.
Changes
Bitwise or-able options showing which part of the Preferences were altered using the PreferencesDialo...
@ Font
Either the font size or font family have changed.
void preview_instrument(std::shared_ptr< Instrument > pInstr)
Definition Sampler.cpp:1398
void updatePatterns(bool bTriggerEvent=true)
void addEventListener(EventListener *pListener)
static HydrogenApp * get_instance()
Returns the instance of HydrogenApp class.
std::shared_ptr< CommonStrings > getCommonStrings()
static bool openSong(QString sFilename)
void preferencesChanged(H2Core::Preferences::Changes changes)
Propagates a change in the Preferences through the GUI.
std::map< QString, QString > m_drumkitRegister
Used to uniquely identify the drumkit corresponding to an item in the tree.
QString getDrumkitLabel(const QString &sDrumkitPath) const
QTreeWidgetItem * m_pTreeSessionDrumkitsItem
void on_DrumkitList_ItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
SoundLibraryPanel(QWidget *parent, bool bInItsOwnDialog)
void on_DrumkitList_leftClicked(QPoint pos)
QTreeWidgetItem * __pattern_item
void onPreferencesChanged(H2Core::Preferences::Changes changes)
virtual void updateSongEvent(int nValue) override
virtual void soundLibraryChangedEvent() override
virtual void drumkitLoadedEvent() override
QTreeWidgetItem * __pattern_item_list
bool m_bInItsOwnDialog
Whether the dialog was constructed via a click in the MainForm or as part of the GUI.
QStringList m_drumkitLabels
List of all labels used for drumkits in the tree.
void item_changed(bool bDrumkitSelected)
QString getDrumkitPath(const QString &sDrumkitLabel) const
SoundLibraryTree * __sound_library_tree
virtual void selectedInstrumentChangedEvent() override
QTreeWidgetItem * m_pTreeSystemDrumkitsItem
QTreeWidgetItem * __song_item
void on_DrumkitList_mouseMove(QMouseEvent *event)
void on_DrumkitList_itemActivated(QTreeWidgetItem *item, int column)
QTreeWidgetItem * m_pTreeUserDrumkitsItem
void on_DrumkitList_rightClicked(QPoint pos)
constexpr int getPointSize(H2Core::FontTheme::FontSize fontSize) const
#define UNUSED(v)
Definition Globals.h:42