1 /*
2  * Hydrogen
3  * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4  *
5  * http://www.hydrogen-music.org
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY, without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22 
23 #include "SoundLibraryPanel.h"
24 
25 #include <QtGui>
26 #if QT_VERSION >= 0x050000
27 #  include <QtWidgets>
28 #endif
29 
30 #include "SoundLibraryDatastructures.h"
31 #include "SoundLibraryTree.h"
32 #include "FileBrowser.h"
33 
34 #include "SoundLibrarySaveDialog.h"
35 #include "SoundLibraryPropertiesDialog.h"
36 #include "SoundLibraryExportDialog.h"
37 
38 #include "../HydrogenApp.h"
39 #include "../Widgets/Button.h"
40 #include "../Widgets/PixmapWidget.h"
41 #include "../Skin.h"
42 #include "../SongEditor/SongEditorPanel.h"
43 #include "../PatternEditor/PatternEditorPanel.h"
44 #include "../PatternEditor/DrumPatternEditor.h"
45 #include "../PatternEditor/PatternEditorInstrumentList.h"
46 #include "../InstrumentRack.h"
47 #include "../InstrumentEditor/InstrumentEditorPanel.h"
48 
49 #include <hydrogen/LocalFileMng.h>
50 #include <hydrogen/basics/adsr.h>
51 #include <hydrogen/audio_engine.h>
52 #include <hydrogen/h2_exception.h>
53 #include <hydrogen/hydrogen.h>
54 #include <hydrogen/basics/instrument.h>
55 #include <hydrogen/basics/instrument_list.h>
56 #include <hydrogen/Preferences.h>
57 #include <hydrogen/basics/pattern.h>
58 #include <hydrogen/basics/pattern_list.h>
59 #include <hydrogen/basics/sample.h>
60 #include <hydrogen/basics/song.h>
61 #include <hydrogen/helpers/filesystem.h>
62 
63 using namespace H2Core;
64 
65 #include <cassert>
66 
67 const char* SoundLibraryPanel::__class_name = "SoundLibraryPanel";
68 
SoundLibraryPanel(QWidget * pParent,bool bInItsOwnDialog)69 SoundLibraryPanel::SoundLibraryPanel( QWidget *pParent, bool bInItsOwnDialog )
70  : QWidget( pParent )
71  , Object( __class_name )
72  , __sound_library_tree( nullptr )
73  , __drumkit_menu( nullptr )
74  , __instrument_menu( nullptr )
75  , __song_menu( nullptr )
76  , __pattern_menu( nullptr )
77  , __pattern_menu_list( nullptr )
78  , __system_drumkits_item( nullptr )
79  , __user_drumkits_item( nullptr )
80  , __song_item( nullptr )
81  , __pattern_item( nullptr )
82  , __pattern_item_list( nullptr )
83 {
84 
85 	//INFOLOG( "INIT" );
86 	__drumkit_menu = new QMenu( this );
87 	__drumkit_menu->addAction( tr( "Load" ), this, SLOT( on_drumkitLoadAction() ) );
88 	__drumkit_menu->addAction( tr( "Export" ), this, SLOT( on_drumkitExportAction() ) );
89 	__drumkit_menu->addAction( tr( "Properties" ), this, SLOT( on_drumkitPropertiesAction() ) );
90 	__drumkit_menu->addSeparator();
91 	__drumkit_menu->addAction( tr( "Delete" ), this, SLOT( on_drumkitDeleteAction() ) );
92 
93 	__instrument_menu = new QMenu( this );
94 	__instrument_menu->addSeparator();
95 	__instrument_menu->addAction( tr( "Delete" ), this, SLOT( on_instrumentDeleteAction() ) );
96 
97 	__song_menu = new QMenu( this );
98 	__song_menu->addSeparator();
99 	__song_menu->addAction( tr( "Load" ), this, SLOT( on_songLoadAction() ) );
100 
101 	__pattern_menu = new QMenu( this );
102 	__pattern_menu->addSeparator();
103 	__pattern_menu->addAction( tr( "Load" ), this, SLOT( on_patternLoadAction() ) );
104 	__pattern_menu->addAction( tr( "Delete" ), this, SLOT( on_patternDeleteAction() ) );
105 
106 	__pattern_menu_list = new QMenu( this );
107 	__pattern_menu_list->addSeparator();
108 	__pattern_menu_list->addAction( tr( "Load" ), this, SLOT( on_patternLoadAction() ) );
109 
110 // DRUMKIT LIST
111 	__sound_library_tree = new SoundLibraryTree( nullptr );
112 	connect( __sound_library_tree, SIGNAL( currentItemChanged ( QTreeWidgetItem*, QTreeWidgetItem* ) ), this, SLOT( on_DrumkitList_ItemChanged( QTreeWidgetItem*, QTreeWidgetItem* ) ) );
113 	connect( __sound_library_tree, SIGNAL( itemActivated ( QTreeWidgetItem*, int ) ), this, SLOT( on_DrumkitList_itemActivated( QTreeWidgetItem*, int ) ) );
114 	connect( __sound_library_tree, SIGNAL( leftClicked(QPoint) ), this, SLOT( on_DrumkitList_leftClicked(QPoint)) );
115 	if( !bInItsOwnDialog ) {
116 		connect( __sound_library_tree, SIGNAL( rightClicked(QPoint) ), this, SLOT( on_DrumkitList_rightClicked(QPoint)) );
117 		connect( __sound_library_tree, SIGNAL( onMouseMove( QMouseEvent* ) ), this, SLOT( on_DrumkitList_mouseMove( QMouseEvent* ) ) );
118 	}
119 
120 
121 	// LAYOUT
122 	QVBoxLayout *pVBox = new QVBoxLayout();
123 	pVBox->setSpacing( 0 );
124 	pVBox->setMargin( 0 );
125 
126 	pVBox->addWidget( __sound_library_tree );
127 
128 
129 	this->setLayout( pVBox );
130 
131 	__expand_pattern_list = Preferences::get_instance()->__expandPatternItem;
132 	__expand_songs_list = Preferences::get_instance()->__expandSongItem;
133 
134 	updateDrumkitList();
135 }
136 
137 
138 
~SoundLibraryPanel()139 SoundLibraryPanel::~SoundLibraryPanel()
140 {
141 	for (uint i = 0; i < __system_drumkit_info_list.size(); ++i ) {
142 		delete __system_drumkit_info_list[i];
143 	}
144 	__system_drumkit_info_list.clear();
145 
146 	for (uint i = 0; i < __user_drumkit_info_list.size(); ++i ) {
147 		delete __user_drumkit_info_list[i];
148 	}
149 	__user_drumkit_info_list.clear();
150 
151 }
152 
153 
154 
updateDrumkitList()155 void SoundLibraryPanel::updateDrumkitList()
156 {
157 	QString currentSL = Hydrogen::get_instance()->getCurrentDrumkitname();
158 
159 	LocalFileMng mng;
160 
161 	__sound_library_tree->clear();
162 
163 
164 
165 	__system_drumkits_item = new QTreeWidgetItem( __sound_library_tree );
166 	__system_drumkits_item->setText( 0, tr( "System drumkits" ) );
167 	__system_drumkits_item->setExpanded( true );
168 
169 	__user_drumkits_item = new QTreeWidgetItem( __sound_library_tree );
170 	__user_drumkits_item->setText( 0, tr( "User drumkits" ) );
171 	__user_drumkits_item->setExpanded( true );
172 
173 
174 
175 	for (uint i = 0; i < __system_drumkit_info_list.size(); ++i ) {
176 		delete __system_drumkit_info_list[i];
177 	}
178 	__system_drumkit_info_list.clear();
179 
180 	for (uint i = 0; i < __user_drumkit_info_list.size(); ++i ) {
181 		delete __user_drumkit_info_list[i];
182 	}
183 	__user_drumkit_info_list.clear();
184 
185 	//User drumkit list
186 	QStringList usr_dks = Filesystem::usr_drumkit_list();
187 	for (int i = 0; i < usr_dks.size(); ++i) {
188 		QString absPath = Filesystem::usr_drumkits_dir() + usr_dks[i];
189 		Drumkit *pInfo = Drumkit::load( absPath, false );
190 		if (pInfo) {
191 			__user_drumkit_info_list.push_back( pInfo );
192 			QTreeWidgetItem* pDrumkitItem = new QTreeWidgetItem( __user_drumkits_item );
193 			pDrumkitItem->setText( 0, pInfo->get_name() );
194 			if ( QString(pInfo->get_name() ) == currentSL ){
195 				pDrumkitItem->setBackground( 0, QColor( 50, 50, 50) );
196 			}
197 			InstrumentList *pInstrList = pInfo->get_instruments();
198 			for ( uint nInstr = 0; nInstr < pInstrList->size(); ++nInstr ) {
199 				Instrument *pInstr = pInstrList->get( nInstr );
200 				QTreeWidgetItem* pInstrumentItem = new QTreeWidgetItem( pDrumkitItem );
201 				pInstrumentItem->setText( 0, QString( "[%1] " ).arg( nInstr + 1 ) + pInstr->get_name() );
202 				pInstrumentItem->setToolTip( 0, pInstr->get_name() );
203 			}
204 		}
205 	}
206 
207 	//System drumkit list
208 	QStringList sys_dks = Filesystem::sys_drumkit_list();
209 	for (int i = 0; i < sys_dks.size(); ++i) {
210 		QString absPath = Filesystem::sys_drumkits_dir() + sys_dks[i];
211 		Drumkit *pInfo = Drumkit::load( absPath, false );
212 		if (pInfo) {
213 			__system_drumkit_info_list.push_back( pInfo );
214 			QTreeWidgetItem* pDrumkitItem = new QTreeWidgetItem( __system_drumkits_item );
215 			pDrumkitItem->setText( 0, pInfo->get_name() );
216 			if ( QString( pInfo->get_name() ) == currentSL ){
217 				pDrumkitItem->setBackground( 0, QColor( 50, 50, 50) );
218 			}
219 			InstrumentList *pInstrList = pInfo->get_instruments();
220 			for ( uint nInstr = 0; nInstr < pInstrList->size(); ++nInstr ) {
221 				Instrument *pInstr = pInstrList->get( nInstr );
222 				QTreeWidgetItem* pInstrumentItem = new QTreeWidgetItem( pDrumkitItem );
223 				pInstrumentItem->setText( 0, QString( "[%1] " ).arg( nInstr + 1 ) + pInstr->get_name() );
224 				pInstrumentItem->setToolTip( 0, pInstr->get_name() );
225 			}
226 		}
227 	}
228 
229 	//Songlist
230 	QStringList songs = Filesystem::song_list_cleared();
231 	if ( songs.size() > 0 ) {
232 		__song_item = new QTreeWidgetItem( __sound_library_tree );
233 		__song_item->setText( 0, tr( "Songs" ) );
234 		__song_item->setToolTip( 0, tr("Double click to expand the list") );
235 		__song_item->setExpanded( __expand_songs_list );
236 		for (uint i = 0; i < songs.size(); i++) {
237 			QTreeWidgetItem* pSongItem = new QTreeWidgetItem( __song_item );
238 			QString song = songs[i];
239 			pSongItem->setText( 0 , song.left( song.indexOf(".")) );
240 			pSongItem->setToolTip( 0, song );
241 		}
242 	}
243 
244 
245 	//Pattern list
246 	QStringList patternDirList = Filesystem::pattern_drumkits();
247 	if ( patternDirList.size() > 0 ) {
248 
249 		__pattern_item = new QTreeWidgetItem( __sound_library_tree );
250 		__pattern_item->setText( 0, tr( "Patterns" ) );
251 		__pattern_item->setToolTip( 0, tr("Double click to expand the list") );
252 		__pattern_item->setExpanded( __expand_pattern_list );
253 
254 		//this is the second step to push the mng.function
255 		//SoundLibraryDatabase::create_instance();
256 		SoundLibraryDatabase* db = SoundLibraryDatabase::get_instance();
257 		soundLibraryInfoVector* allPatternDirList = db->getAllPatterns();
258 		QStringList allCategoryNameList = db->getAllPatternCategories();
259 
260 		//now sorting via category
261 
262 		for (uint i = 0; i < allCategoryNameList.size(); ++i) {
263 			QString categoryName = allCategoryNameList[i];
264 
265 			QTreeWidgetItem* pCategoryItem = new QTreeWidgetItem( __pattern_item );
266 			pCategoryItem->setText( 0, categoryName  );
267 
268 			soundLibraryInfoVector::iterator mapIterator;
269 			for( mapIterator=allPatternDirList->begin(); mapIterator != allPatternDirList->end(); mapIterator++ )
270 			{
271 				QString patternCategory = (*mapIterator)->getCategory();
272 				if ( (patternCategory == categoryName) || (patternCategory.isEmpty() && categoryName == "No category") ){
273 					QTreeWidgetItem* pPatternItem = new QTreeWidgetItem( pCategoryItem );
274 					pPatternItem->setText( 0, (*mapIterator)->getName());
275 					pPatternItem->setText( 1, (*mapIterator)->getPath() );
276 					pPatternItem->setToolTip( 0, mng.getDrumkitNameForPattern( (*mapIterator)->getPath() ));
277 					INFOLOG( "Path" +  (*mapIterator)->getPath() );
278 				}
279 			}
280 		}
281 	}
282 
283 
284 }
285 
286 
287 
on_DrumkitList_ItemChanged(QTreeWidgetItem * current,QTreeWidgetItem * previous)288 void SoundLibraryPanel::on_DrumkitList_ItemChanged( QTreeWidgetItem * current, QTreeWidgetItem * previous )
289 {
290 	UNUSED( previous );
291 
292 	if( current == nullptr ){
293 		return;
294 	}
295 
296 	if ( current->parent() == __system_drumkits_item ||
297 		 current->parent() == __user_drumkits_item  ){
298 			emit item_changed( true );
299 	} else {
300 		emit item_changed( false );
301 	}
302 
303 	test_expandedItems();
304 }
305 
306 
307 
on_DrumkitList_itemActivated(QTreeWidgetItem * item,int column)308 void SoundLibraryPanel::on_DrumkitList_itemActivated( QTreeWidgetItem * item, int column )
309 {
310 	UNUSED( column );
311 
312 //	INFOLOG( "[on_DrumkitList_itemActivated]" );
313 	if ( item == __system_drumkits_item || item == __user_drumkits_item || item == __system_drumkits_item->parent() || item->parent() == __song_item || item == __song_item || item == __pattern_item || item->parent() == __pattern_item || item->parent()->parent() == __pattern_item || item == __pattern_item_list || item->parent() == __pattern_item_list || item->parent()->parent() == __pattern_item_list ) {
314 		return;
315 	}
316 
317 	if ( item->parent() == __system_drumkits_item || item->parent() == __user_drumkits_item  ) {
318 		// e' stato selezionato un drumkit
319 	}
320 	else {
321 
322 		// e' stato selezionato uno strumento
323 		QString selectedName = item->text(0);
324 		if( item->text(0) == "Patterns" ) return;
325 
326 		QString sInstrName = selectedName.remove( 0, selectedName.indexOf( "] " ) + 2 );
327 		QString sDrumkitName = item->parent()->text(0);
328 		INFOLOG( QString(sDrumkitName) + ", instr:" + sInstrName );
329 
330 		Instrument *pInstrument = Instrument::load_instrument( sDrumkitName, sInstrName );
331 		pInstrument->set_muted( false );
332 
333 		AudioEngine::get_instance()->get_sampler()->preview_instrument( pInstrument );
334 	}
335 }
336 
337 
338 
339 
340 
341 
342 
on_DrumkitList_rightClicked(QPoint pos)343 void SoundLibraryPanel::on_DrumkitList_rightClicked( QPoint pos )
344 {
345 	if( __sound_library_tree->currentItem() == nullptr ) {
346 		return;
347 	}
348 
349 	if (
350 		( __sound_library_tree->currentItem()->parent() == nullptr ) ||
351 		( __sound_library_tree->currentItem() == __user_drumkits_item ) ||
352 		( __sound_library_tree->currentItem() == __system_drumkits_item )
353 	) {
354 		return;
355 	}
356 
357 	if ( __sound_library_tree->currentItem()->parent() == __song_item ) {
358 		__song_menu->popup( pos );
359 	}
360 
361 	if ( __sound_library_tree->currentItem()->parent()->parent() == __pattern_item && __pattern_item != nullptr ) {
362 		__pattern_menu->popup( pos );
363 	}
364 
365 	if ( __sound_library_tree->currentItem()->parent() == __user_drumkits_item ) {
366 		__drumkit_menu->popup( pos );
367 	}
368 	else if ( __sound_library_tree->currentItem()->parent()->parent() == __user_drumkits_item ) {
369 		__instrument_menu->popup( pos );
370 	}
371 	//else if ( __sound_library_tree->currentItem()->parent()->parent()->parent() ==  __pattern_item_list ) {
372 	//	__pattern_menu_list->popup( pos );
373 	//}
374 
375 
376 	if ( __sound_library_tree->currentItem()->parent() == __system_drumkits_item ) {
377 		__drumkit_menu->popup( pos );
378 	}
379 	else if ( __sound_library_tree->currentItem()->parent()->parent() == __system_drumkits_item ) {
380 		__instrument_menu->popup( pos );
381 	}
382 }
383 
384 
385 
on_DrumkitList_leftClicked(QPoint pos)386 void SoundLibraryPanel::on_DrumkitList_leftClicked( QPoint pos )
387 {
388 	__start_drag_position = pos;
389 }
390 
391 
392 
on_DrumkitList_mouseMove(QMouseEvent * event)393 void SoundLibraryPanel::on_DrumkitList_mouseMove( QMouseEvent *event)
394 {
395 	if (! ( event->buttons() & Qt::LeftButton ) ) {
396 		return;
397 	}
398 
399 	if ( ( event->pos() - __start_drag_position ).manhattanLength() < QApplication::startDragDistance() ) {
400 		return;
401 	}
402 
403 	if ( !__sound_library_tree->currentItem() ) {
404 		return;
405 	}
406 
407 	if (
408 		( __sound_library_tree->currentItem()->parent() == __system_drumkits_item ) ||
409 		( __sound_library_tree->currentItem()->parent() == __user_drumkits_item )
410 	) {
411  		// drumkit selection
412 		//INFOLOG( "ho selezionato un drumkit (system)" );
413 		return;
414 	}
415 	else {
416 		//INFOLOG( "ho selezionato uno strumento" );
417 		// instrument selection
418 		if ( __sound_library_tree->currentItem() == nullptr )
419 		{
420 			return;
421 		}
422 
423 		if ( __sound_library_tree->currentItem()->parent() == nullptr )
424 		{
425 			return;
426 		}
427 
428 		if ( __sound_library_tree->currentItem()->parent() == __song_item )
429 		{
430 			return;
431 		}
432 
433 		if ( __sound_library_tree->currentItem()->parent()->text(0) == nullptr )
434 		{
435 			return;
436 		}
437 
438 		if ( __sound_library_tree->currentItem()->parent() == __pattern_item ) {
439 			return;
440 		}
441 
442 		if ( __sound_library_tree->currentItem()->parent()->parent() == __pattern_item ) {
443 
444 			QString sPatternPath = __sound_library_tree->currentItem()->text( 1 );
445 			QString dragtype = "drag pattern";
446 			QString sText = dragtype + "::" + sPatternPath;
447 
448 			QDrag *pDrag = new QDrag(this);
449 			QMimeData *pMimeData = new QMimeData;
450 
451 			pMimeData->setText( sText );
452 			pDrag->setMimeData( pMimeData);
453 			pDrag->exec( Qt::CopyAction | Qt::MoveAction );
454 			return;
455 		}
456 
457 		QString sDrumkitName = __sound_library_tree->currentItem()->parent()->text(0);
458 		QString sInstrumentName = ( __sound_library_tree->currentItem()->text(0) ).remove( 0, __sound_library_tree->currentItem()->text(0).indexOf( "] " ) + 2 );
459 
460 		QString sText = "importInstrument:" + sDrumkitName + "::" + sInstrumentName;
461 
462 		QDrag *pDrag = new QDrag(this);
463 		QMimeData *pMimeData = new QMimeData;
464 
465 		pMimeData->setText( sText );
466 		pDrag->setMimeData( pMimeData);
467 
468 		pDrag->exec( Qt::CopyAction | Qt::MoveAction );
469 	}
470 }
471 
472 
473 
on_drumkitLoadAction()474 void SoundLibraryPanel::on_drumkitLoadAction()
475 {
476 	restore_background_color();
477 
478 	QString sDrumkitName = __sound_library_tree->currentItem()->text(0);
479 
480 	Drumkit *pDrumkitInfo = nullptr;
481 
482 	// find the drumkit in the list
483 	for ( uint i = 0; i < __system_drumkit_info_list.size(); i++ ) {
484 		Drumkit *pInfo = __system_drumkit_info_list[i];
485 		if ( pInfo->get_name() == sDrumkitName ) {
486 			pDrumkitInfo = pInfo;
487 			break;
488 		}
489 	}
490 
491 	for ( uint i = 0; i < __user_drumkit_info_list.size(); i++ ) {
492 		Drumkit *pInfo = __user_drumkit_info_list[i];
493 		if ( pInfo->get_name() == sDrumkitName ) {
494 			pDrumkitInfo = pInfo;
495 			break;
496 		}
497 	}
498 
499 	if( !pDrumkitInfo ) {
500 		return;
501 	}
502 
503 	InstrumentList *pSongInstrList = Hydrogen::get_instance()->getSong()->get_instrument_list();
504 	InstrumentList *pDrumkitInstrList = pDrumkitInfo->get_instruments();
505 
506 	int oldCount = pSongInstrList->size();
507 	int newCount = pDrumkitInstrList->size();
508 
509 	bool conditionalLoad = false;
510 	bool hasNotes = false;
511 
512 	INFOLOG("Old kit has " + QString::number( oldCount ) + " instruments, new one has " + QString::number( newCount ) );
513 
514 	if ( newCount < oldCount )
515 	{
516 		// Check if any of the instruments that will be removed have notes
517 		for ( int i = 0; i < pSongInstrList->size(); i++)
518 		{
519 			if ( i >= newCount )
520 			{
521 				INFOLOG("Checking if Instrument " + QString::number( i ) + " has notes..." );
522 
523 				if ( Hydrogen::get_instance()->instrumentHasNotes( pSongInstrList->get( i ) ) )
524 				{
525 					hasNotes = true;
526 					INFOLOG("Instrument " + QString::number( i ) + " has notes" );
527 				}
528 			}
529 
530 		}
531 
532 		if ( hasNotes )
533 		{
534 			QMessageBox msgBox;
535 			msgBox.setWindowTitle("Hydrogen");
536 			msgBox.setIcon( QMessageBox::Warning );
537 			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 ) ) );
538 
539 			msgBox.setStandardButtons(QMessageBox::Save);
540 			msgBox.setButtonText(QMessageBox::Save, tr("Keep"));
541 			msgBox.addButton(QMessageBox::Discard);
542 			msgBox.addButton(QMessageBox::Cancel);
543 			msgBox.setDefaultButton(QMessageBox::Cancel);
544 
545 			switch ( msgBox.exec() )
546 			{
547 				case QMessageBox::Save:
548 					// Save old instruments with notes
549 					conditionalLoad = true;
550 					break;
551 
552 				case QMessageBox::Discard:
553 					// discard extra instruments
554 					conditionalLoad = false;
555 					break;
556 
557 				case QMessageBox::Cancel:
558 					// Cancel
559 					return;
560 			}
561 		}
562 	}
563 
564 
565 	assert( pDrumkitInfo );
566 
567 	QApplication::setOverrideCursor(Qt::WaitCursor);
568 
569 	Hydrogen::get_instance()->loadDrumkit( pDrumkitInfo, conditionalLoad );
570 	Hydrogen::get_instance()->getSong()->set_is_modified( true );
571 	HydrogenApp::get_instance()->onDrumkitLoad( pDrumkitInfo->get_name() );
572 	HydrogenApp::get_instance()->getPatternEditorPanel()->getDrumPatternEditor()->updateEditor();
573 	HydrogenApp::get_instance()->getPatternEditorPanel()->updatePianorollEditor();
574 
575 	InstrumentEditorPanel::get_instance()->notifyOfDrumkitChange();
576 
577 	__sound_library_tree->currentItem()->setBackground( 0, QColor( 50, 50, 50) );
578 	QApplication::restoreOverrideCursor();
579 
580 }
581 
582 
583 
update_background_color()584 void SoundLibraryPanel::update_background_color()
585 {
586 	restore_background_color();
587 	change_background_color();
588 }
589 
590 
591 
restore_background_color()592 void SoundLibraryPanel::restore_background_color()
593 {
594 	for (int i = 0; i < __system_drumkits_item->childCount() ; i++){
595 		( __system_drumkits_item->child( i ) )->setBackground( 0, QBrush() );
596 	}
597 
598 	for (int i = 0; i < __user_drumkits_item->childCount() ; i++){
599 		( __user_drumkits_item->child( i ) )->setBackground(0, QBrush() );
600 	}
601 }
602 
603 
604 
change_background_color()605 void SoundLibraryPanel::change_background_color()
606 {
607 	QString sCurDrumkitName =  Hydrogen::get_instance()->getCurrentDrumkitname();
608 
609 	for (int i = 0; i < __system_drumkits_item->childCount() ; i++){
610 		if ( ( __system_drumkits_item->child( i ) )->text( 0 ) == sCurDrumkitName ){
611 			( __system_drumkits_item->child( i ) )->setBackground( 0, QColor( 50, 50, 50)  );
612 			break;
613 		}
614 	}
615 
616 	for (int i = 0; i < __user_drumkits_item->childCount() ; i++){
617 		if ( ( __user_drumkits_item->child( i ))->text( 0 ) == sCurDrumkitName ){
618 			( __user_drumkits_item->child( i ) )->setBackground( 0, QColor( 50, 50, 50)  );
619 			break;
620 		}
621 	}
622 }
623 
624 
625 
on_drumkitDeleteAction()626 void SoundLibraryPanel::on_drumkitDeleteAction()
627 {
628 	QTreeWidgetItem* pItem = __sound_library_tree->currentItem();
629 	QString itemName = QString("%1").arg(__sound_library_tree->currentItem()->text(0));
630 
631 	//if we delete the current loaded drumkit we can get trouble with some empty pointers
632 	// TODO this check is really unsafe
633 	if ( pItem->text(0) == Hydrogen::get_instance()->getCurrentDrumkitname() ){
634 		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(itemName) );
635 		return;
636 	}
637 
638 	if ( pItem->parent() == __system_drumkits_item ) {
639 		QMessageBox::warning( this, "Hydrogen", tr( "\"%1\"is a system drumkit and can't be deleted.").arg(itemName) );
640 		return;
641 	}
642 
643 	int res = QMessageBox::warning( this, "Hydrogen", tr( "Warning, the \"%1\" drumkit will be deleted from disk.\nAre you sure?").arg(itemName), "&Ok", "&Cancel", nullptr, 1 );
644 	if ( res == 1 ) {
645 		return;
646 	}
647 
648 	QApplication::setOverrideCursor(Qt::WaitCursor);
649 	bool success = Drumkit::remove( pItem->text(0) );
650 	test_expandedItems();
651 	updateDrumkitList();
652 	QApplication::restoreOverrideCursor();
653 	if ( !success) {
654 		QMessageBox::warning( this, "Hydrogen", tr( "Drumkit deletion failed.") );
655 	}
656 }
657 
658 
659 
on_drumkitExportAction()660 void SoundLibraryPanel::on_drumkitExportAction()
661 {
662 	QString sDrumkitName = __sound_library_tree->currentItem()->text(0);
663 	SoundLibraryExportDialog exportDialog( this, sDrumkitName);
664 	exportDialog.exec();
665 }
666 
667 
668 
on_drumkitPropertiesAction()669 void SoundLibraryPanel::on_drumkitPropertiesAction()
670 {
671 	QString sDrumkitName = __sound_library_tree->currentItem()->text(0);
672 
673 	Drumkit *drumkitInfo = nullptr;
674 
675 	// find the drumkit in the list
676 	for ( uint i = 0; i < __system_drumkit_info_list.size(); i++ ) {
677 		Drumkit *pInfo = __system_drumkit_info_list[i];
678 		if ( pInfo->get_name() == sDrumkitName ) {
679 			drumkitInfo = pInfo;
680 			break;
681 		}
682 	}
683 	for ( uint i = 0; i < __user_drumkit_info_list.size(); i++ ) {
684 		Drumkit*pInfo = __user_drumkit_info_list[i];
685 		if ( pInfo->get_name() == sDrumkitName ) {
686 			drumkitInfo = pInfo;
687 			break;
688 		}
689 	}
690 
691 	assert( drumkitInfo );
692 
693 	QString sPreDrumkitName = Hydrogen::get_instance()->getCurrentDrumkitname();
694 
695 	Drumkit *preDrumkitInfo = nullptr;
696 
697 
698 	// find the drumkit in the list
699 	for ( uint i = 0; i < __system_drumkit_info_list.size(); i++ ) {
700 		Drumkit *prInfo = __system_drumkit_info_list[i];
701 		if ( prInfo->get_name() == sPreDrumkitName ) {
702 			preDrumkitInfo = prInfo;
703 			break;
704 		}
705 	}
706 	for ( uint i = 0; i < __user_drumkit_info_list.size(); i++ ) {
707 		Drumkit *prInfo = __user_drumkit_info_list[i];
708 		if ( prInfo->get_name() == sPreDrumkitName ) {
709 			preDrumkitInfo = prInfo;
710 			break;
711 		}
712 	}
713 
714 	if ( preDrumkitInfo == nullptr ){
715 		QMessageBox::warning( this, "Hydrogen", QString( "The current loaded song missing his soundlibrary.\nPlease load a existing soundlibrary first") );
716 		return;
717 	}
718 	assert( preDrumkitInfo );
719 
720 	//open the soundlibrary save dialog
721 	SoundLibraryPropertiesDialog dialog( this , drumkitInfo, preDrumkitInfo );
722 	dialog.exec();
723 }
724 
725 
726 
on_instrumentDeleteAction()727 void SoundLibraryPanel::on_instrumentDeleteAction()
728 {
729 	QMessageBox::warning( this, "Hydrogen", QString( "Not implemented yet.") );
730 	ERRORLOG( "[on_instrumentDeleteAction] not implemented yet" );
731 }
732 
on_songLoadAction()733 void SoundLibraryPanel::on_songLoadAction()
734 {
735 	QString sFilename = Filesystem::song_path( __sound_library_tree->currentItem()->text( 0 ) );
736 
737 	Hydrogen *pHydrogen = Hydrogen::get_instance();
738 	if ( pHydrogen->getState() == STATE_PLAYING ) {
739 		pHydrogen->sequencer_stop();
740 	}
741 
742 	Song *pSong = Song::load( sFilename );
743 	if ( pSong == nullptr ) {
744 		QMessageBox::information( this, "Hydrogen", tr("Error loading song.") );
745 		return;
746 	}
747 
748 	// add the new loaded song in the "last used song" vector
749 	Preferences *pPref = Preferences::get_instance();
750 
751 	std::vector<QString> recentFiles = pPref->getRecentFiles();
752 	recentFiles.insert( recentFiles.begin(), sFilename );
753 	pPref->setRecentFiles( recentFiles );
754 
755 	HydrogenApp* pH2App = HydrogenApp::get_instance();
756 
757 	pH2App->setSong( pSong );
758 
759 	//updateRecentUsedSongList();
760 	pHydrogen->setSelectedPatternNumber( 0 );
761 }
762 
763 
764 
on_patternLoadAction()765 void SoundLibraryPanel::on_patternLoadAction()
766 {
767 	LocalFileMng mng;
768 
769 	Hydrogen *pHydrogen = Hydrogen::get_instance();
770 	Song *pSong = pHydrogen->getSong();
771 	PatternList *pPatternList = pSong->get_pattern_list();
772 	QString patternName = __sound_library_tree->currentItem()->text( 0 );
773 	QString drumkitName = __sound_library_tree->currentItem()->toolTip ( 0 );
774 
775 	// FIXME : file path should come from the selected item
776 	Pattern* pErr = Pattern::load_file( Filesystem::pattern_path( drumkitName, patternName ), pSong->get_instrument_list() );
777 
778 	if ( pErr == nullptr ) {
779 		ERRORLOG( "Error loading the pattern" );
780 		return;
781 	}
782 	pPatternList->add ( pErr );
783 	pSong->set_is_modified( true );
784 	HydrogenApp::get_instance()->getSongEditorPanel()->updateAll();
785 }
786 
787 
on_patternDeleteAction()788 void SoundLibraryPanel::on_patternDeleteAction()
789 {
790 	QString patternPath = __sound_library_tree->currentItem()->text( 1 );
791 
792 	int res = QMessageBox::information( this, "Hydrogen", tr( "Warning, the selected pattern will be deleted from disk.\nAre you sure?"), tr("&Ok"), tr("&Cancel"), nullptr, 1 );
793 	if ( res == 1 ) {
794 		return;
795 	}
796 
797 	QFile rmfile( patternPath );
798 	bool err = rmfile.remove();
799 	if ( err == false ) {
800 		ERRORLOG( "Error removing the pattern" );
801 	}
802 
803 	SoundLibraryDatabase::get_instance()->updatePatterns();
804 	test_expandedItems();
805 	updateDrumkitList();
806 }
807 
808 
test_expandedItems()809 void SoundLibraryPanel::test_expandedItems()
810 {
811 	assert( __sound_library_tree );
812 	if ( __song_item == nullptr) {
813 		__expand_songs_list = false;
814 	} else {
815 		__expand_songs_list = __song_item->isExpanded();
816 	}
817 	if ( __pattern_item == nullptr) {
818 		__expand_pattern_list = false;
819 	} else {
820 		__expand_pattern_list = __pattern_item->isExpanded();
821 	}
822 	Preferences::get_instance()->__expandSongItem = __expand_songs_list;
823 	Preferences::get_instance()->__expandPatternItem = __expand_pattern_list;
824 	//ERRORLOG( QString("songs %1 patterns %2").arg(__expand_songs_list).arg(__expand_pattern_list) );
825 }
826