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 "AudioFileBrowser.h"
24 #include "../HydrogenApp.h"
25 #include "InstrumentEditor/InstrumentEditor.h"
26 #include "SampleWaveDisplay.h"
27 #include "../Widgets/Button.h"
28 #include "../Skin.h"
29
30 #include <hydrogen/Preferences.h>
31 #include <hydrogen/basics/sample.h>
32 #include <hydrogen/audio_engine.h>
33
34 #include <QModelIndex>
35 #include <QTreeWidget>
36 #include <QMessageBox>
37
38 using namespace H2Core;
39 using namespace std;
40
41 const char* AudioFileBrowser::__class_name = "AudioFileBrowser";
42
AudioFileBrowser(QWidget * pParent,bool bAllowMultiSelect,bool bShowInstrumentManipulationControls)43 AudioFileBrowser::AudioFileBrowser ( QWidget* pParent, bool bAllowMultiSelect, bool bShowInstrumentManipulationControls)
44 : QDialog ( pParent )
45 , Object ( __class_name )
46 {
47 setupUi ( this );
48 INFOLOG ( "INIT" );
49 setWindowTitle ( tr ( "Audio File Browser" ) );
50 setFixedSize ( width(), height() );
51
52 m_bAllowMultiSelect = bAllowMultiSelect;
53 m_bShowInstrumentManipulationControls = bShowInstrumentManipulationControls;
54
55 m_pDirModel = new QDirModel();
56 m_pDirModel->setFilter( QDir::AllDirs | QDir::AllEntries | QDir::NoDotAndDotDot );
57 m_pDirModel->setNameFilters( QStringList() << "*.ogg" << "*.OGG" << "*.wav" << "*.WAV" << "*.flac"<< "*.FLAC" << "*.aiff" << "*.AIFF"<< "*.au" << "*.AU" );
58 m_pDirModel->setSorting( QDir::DirsFirst |QDir::Name );
59 m_ModelIndex = m_pDirModel->index( QDir::currentPath() );
60
61 m_pPlayBtn->setEnabled( false );
62 m_pStopBtn->setEnabled( false );
63 openBTN->setEnabled( false );
64
65 m_pTree = new QTreeView( treeView );
66 m_pTree->setModel( m_pDirModel );
67 m_pTree->resize( 799, 310 );
68 m_pTree->header()->resizeSection( 0, 405 );
69 m_pTree->setAlternatingRowColors( true );
70 m_pTree->setRootIndex( m_pDirModel->index( Preferences::get_instance()->__lastsampleDirectory ) );
71
72 pathLineEdit->setText( Preferences::get_instance()->__lastsampleDirectory );
73 m_pSampleFilename = "";
74 m_pSelectedFile << "false" << "false";
75
76 m_sEmptySampleFilename = Filesystem::empty_sample_path();
77
78 m_pPathUptoolButton->setIcon( QIcon( Skin::getImagePath() + "/audiFileBrowser/go-up.png"));
79 m_pPathUptoolButton->setToolTip( QString("Parent Folder"));
80 m_pPathHometoolButton->setIcon( QIcon( Skin::getImagePath() + "/audiFileBrowser/go-home.png"));
81 m_pPathHometoolButton->setToolTip( QString("Home"));
82
83 m_pPlayBtn->setIcon( QIcon( Skin::getImagePath() + "/audiFileBrowser/player_play.png"));
84 m_pPlayBtn->setToolTip( QString("Play selected"));
85 m_pStopBtn->setIcon( QIcon( Skin::getImagePath() + "/audiFileBrowser/player_stop.png"));
86 m_pStopBtn->setToolTip( QString("Stop"));
87
88 m_pSampleWaveDisplay = new SampleWaveDisplay( waveformview );
89 m_pSampleWaveDisplay->updateDisplay( m_sEmptySampleFilename );
90 m_pSampleWaveDisplay->move( 3, 3 );
91
92 playSamplescheckBox->setChecked( Preferences::get_instance()->__playsamplesonclicking );
93 //get the kde or gnome environment variable for mouse double or single clicking
94 m_SingleClick = false;
95 getEnvironment();
96
97 if( !m_bShowInstrumentManipulationControls ) {
98 useNameCheckBox->hide();
99 autoVelCheckBox->hide();
100 }
101
102 connect( m_pTree, SIGNAL( clicked( const QModelIndex&) ), SLOT( clicked( const QModelIndex& ) ) );
103 connect( m_pTree, SIGNAL( doubleClicked( const QModelIndex&) ), SLOT( doubleClicked( const QModelIndex& ) ) );
104 connect( pathLineEdit, SIGNAL( returnPressed() ), SLOT( updateModelIndex() ) );
105 }
106
107
108
~AudioFileBrowser()109 AudioFileBrowser::~AudioFileBrowser()
110 {
111 Sample *pNewSample = Sample::load( m_sEmptySampleFilename );
112 AudioEngine::get_instance()->get_sampler()->preview_sample( pNewSample, 100 );
113 INFOLOG ( "DESTROY" );
114 }
115
116
isFileSupported(QString filename)117 bool AudioFileBrowser::isFileSupported( QString filename )
118 {
119 if (
120 ( filename.endsWith( ".ogg" ) ) ||
121 ( filename.endsWith( ".OGG" ) ) ||
122 ( filename.endsWith( ".wav" ) ) ||
123 ( filename.endsWith( ".WAV" ) ) ||
124 ( filename.endsWith( ".au" ) ) ||
125 ( filename.endsWith( ".AU" ) ) ||
126 ( filename.endsWith( ".aiff" ) ) ||
127 ( filename.endsWith( ".AIFF" ) ) ||
128 ( filename.endsWith( ".flac" ) ) ||
129 ( filename.endsWith( ".FLAC" ) )
130 ){
131 return true;
132 } else {
133 return false;
134 }
135 }
136
137
getEnvironment()138 void AudioFileBrowser::getEnvironment()
139 {
140 QString desktopSession = getenv("DESKTOP_SESSION");
141 //kde
142 if( desktopSession == "kde" ) {
143 QFile envfile( QDir::homePath() + "/.kde/share/config/kdeglobals");
144
145 if ( !envfile.open(QIODevice::ReadOnly | QIODevice::Text) ) {
146 return;
147 }
148
149 QTextStream envin( &envfile );
150 while ( !envin.atEnd() ) {
151 QString envLine = envin.readLine();
152 if( envLine == QString("SingleClick=true" ) ) {
153 m_SingleClick = true;
154 break;
155 }
156 }
157 }
158
159 //for gnome, xfce and all others we use double click as default
160 }
161
162
163
keyPressEvent(QKeyEvent * ev)164 void AudioFileBrowser::keyPressEvent (QKeyEvent *ev)
165 {
166 if( ev->modifiers()==Qt::ControlModifier && m_bAllowMultiSelect) {
167 m_pTree->setSelectionMode( QAbstractItemView::MultiSelection );
168 openBTN->setEnabled( true );
169 }
170 }
171
172
173
keyReleaseEvent(QKeyEvent * ev)174 void AudioFileBrowser::keyReleaseEvent (QKeyEvent *ev)
175 {
176 m_pTree->setSelectionMode( QAbstractItemView::SingleSelection );
177 }
178
179
180
updateModelIndex()181 void AudioFileBrowser::updateModelIndex()
182 {
183 QString toRemove;
184 QString newPath = pathLineEdit->text();
185
186 if( QDir( newPath ).exists() ) {
187 m_pTree->setRootIndex( m_pDirModel->index( newPath ) );
188 } else {
189 toRemove = newPath.section( '/', -1 );
190 // QMessageBox::information ( this, "Hydrogen", newpath + toremove);
191 newPath.replace( toRemove, "" );
192 m_pTree->setRootIndex( m_pDirModel->index( newPath ) );
193 }
194 }
195
196
197
clicked(const QModelIndex & index)198 void AudioFileBrowser::clicked( const QModelIndex& index )
199 {
200 QString path = m_pDirModel->filePath( index );
201
202 if( m_SingleClick ) {
203 browseTree( index );
204 }
205
206 if( isFileSupported( path ) ) {
207 browseTree( index );
208 }
209 }
210
211
212
doubleClicked(const QModelIndex & index)213 void AudioFileBrowser::doubleClicked( const QModelIndex& index )
214 {
215 if(!m_SingleClick) {
216 browseTree( index );
217 }
218 }
219
220
221
browseTree(const QModelIndex & index)222 void AudioFileBrowser::browseTree( const QModelIndex& index )
223 {
224
225 QString path = m_pDirModel->filePath( index );
226 pathLineEdit->setText( path );
227 m_pSampleWaveDisplay->updateDisplay( m_sEmptySampleFilename );
228
229 updateModelIndex(); //with this you have a navigation like konqueror
230
231 if ( m_pDirModel->isDir( index ) ){
232 m_pPlayBtn->setEnabled( false );
233 openBTN->setEnabled( false );
234 return;
235 }
236
237 QString name = path.section( '/', -1 );
238
239 QString path2 = path;
240 QString onlyPath = path;
241 if ( name != "" ){
242 onlyPath = path.replace( name, "" );
243 }
244
245 name = name.left( '.' );
246
247 QString message = "Name: " + name;
248 pathLineEdit->setText( onlyPath );
249
250 QStringList path2List = path2.split("/");
251 QString fleTxt = path2List.last();
252
253 QApplication::setOverrideCursor(Qt::WaitCursor);
254
255 if( isFileSupported( path2 ) )
256 {
257
258 filelineedit->setText( fleTxt );
259 Sample *pNewSample = Sample::load( path2 );
260
261 if ( pNewSample ) {
262 m_pNBytesLable->setText( tr( "Size: %1 bytes" ).arg( pNewSample->get_size() / 2 ) );
263 m_pSamplerateLable->setText( tr( "Samplerate: %1" ).arg( pNewSample->get_sample_rate() ) );
264 float sec = ( float )( pNewSample->get_frames() / (float)pNewSample->get_sample_rate() );
265 QString qsec;
266 qsec = QString::asprintf( "%2.2f", sec );
267 m_pLengthLable->setText( tr( "Sample length: " ) + qsec + tr( " s" ) );
268
269 delete pNewSample;
270 m_pSampleFilename = path2;
271
272 m_pSampleWaveDisplay->updateDisplay( path2 );
273 m_pPlayBtn->setEnabled( true );
274 openBTN->setEnabled( true );
275
276 //important this will only working correct if m_pSampleWaveDisplay->updateDisplay( file )
277 //is ready with painting the wav file. else the playing sample get crackled sound!!
278 if (playSamplescheckBox->isChecked()){
279 if ( sec <= 600.00){
280 on_m_pPlayBtn_clicked();
281 }else
282 {
283 QMessageBox::information ( this, "Hydrogen", tr( "Please do not preview samples which are longer than 10 minutes!" ) );
284 }
285 }
286 m_pNameLabel->setText( message );
287 } else {
288 openBTN->setEnabled( false );
289 QMessageBox::information ( this, "Hydrogen", tr( "Unable to load that sample file." ) );
290 }
291
292 }else{
293 m_pNameLabel->setText( tr( "Name:"));
294 m_pNBytesLable->setText( tr( "Size:" ) );
295 m_pSamplerateLable->setText( tr( "Samplerate:" ) );
296 m_pLengthLable->setText( tr( "Sample length:" ) );
297 m_pSampleWaveDisplay->updateDisplay( m_sEmptySampleFilename );
298 m_pPlayBtn->setEnabled( false );
299 m_pStopBtn->setEnabled( false );
300 openBTN->setEnabled( false );
301 m_pSampleFilename = "";
302 }
303 QApplication::restoreOverrideCursor();
304 }
305
306
307
on_m_pPlayBtn_clicked()308 void AudioFileBrowser::on_m_pPlayBtn_clicked()
309 {
310
311 if( QFile( m_pSampleFilename ).exists() == false ) {
312 return;
313 }
314
315 m_pStopBtn->setEnabled( true );
316
317 Sample *pNewSample = Sample::load( m_pSampleFilename );
318 if ( pNewSample ) {
319 assert(pNewSample->get_sample_rate() != 0);
320
321 int length = ( ( pNewSample->get_frames() / pNewSample->get_sample_rate() + 1) * 100 );
322 AudioEngine::get_instance()->get_sampler()->preview_sample( pNewSample, length );
323 }
324 }
325
326
327
on_m_pStopBtn_clicked()328 void AudioFileBrowser::on_m_pStopBtn_clicked()
329 {
330 Sample *pNewSample = Sample::load( m_sEmptySampleFilename );
331 AudioEngine::get_instance()->get_sampler()->preview_sample( pNewSample, 100 );
332 m_pStopBtn->setEnabled( false );
333 }
334
335
336
on_cancelBTN_clicked()337 void AudioFileBrowser::on_cancelBTN_clicked()
338 {
339 Preferences::get_instance()->__lastsampleDirectory = pathLineEdit->text();
340 m_pSelectedFile << "false" << "false" << "";
341 reject();
342 }
343
344
345
on_openBTN_clicked()346 void AudioFileBrowser::on_openBTN_clicked()
347 {
348 if( m_pTree->selectionModel()->selectedRows().size() > 0) {
349 QList<QModelIndex>::iterator i;
350 QList<QModelIndex> list = m_pTree->selectionModel()->selectedRows();
351
352 for (i = list.begin(); i != list.end(); ++i) {
353 QString path2 = (*i).data().toString();
354 if( isFileSupported( path2 ) ){
355 QString path = pathLineEdit->text();
356
357 if(! path.endsWith("/")) {
358 path = path + "/";
359 }
360
361 QString act_filename = path + path2;
362 m_pSelectedFile << act_filename ;
363 }
364 }
365 }
366
367 Preferences::get_instance()->__lastsampleDirectory = pathLineEdit->text();
368 accept();
369 }
370
371
372
on_playSamplescheckBox_clicked()373 void AudioFileBrowser::on_playSamplescheckBox_clicked()
374 {
375 Preferences::get_instance()->__playsamplesonclicking = playSamplescheckBox->isChecked();
376 }
377
378
379
getSelectedFiles()380 QStringList AudioFileBrowser::getSelectedFiles()
381 {
382 if ( useNameCheckBox->isChecked() ) {
383 m_pSelectedFile[0] = "true";
384 }
385 if ( autoVelCheckBox->isChecked() ) {
386 m_pSelectedFile[1] = "true";
387 }
388 return m_pSelectedFile;
389 }
390
391
392
on_m_pPathHometoolButton_clicked()393 void AudioFileBrowser::on_m_pPathHometoolButton_clicked()
394 {
395
396 QString path = pathLineEdit->text();
397 QStringList pathlist = path.split("/");
398
399 while( path != QDir::rootPath() ){
400
401 if( pathlist.isEmpty () ) {
402 break;
403 }
404
405 pathlist.removeLast();
406 QString updir = pathlist.join("/");
407
408 pathLineEdit->setText( updir );
409 m_pTree->setRootIndex( m_pDirModel->index( updir ) );
410 m_pTree->collapse( m_pDirModel->index( updir ) );
411 m_pTree->setExpanded( m_pDirModel->index(updir), false );
412 path = pathLineEdit->text();
413 }
414
415 pathLineEdit->setText( QDir::homePath() );
416 m_pTree->setRootIndex( m_pDirModel->index( QDir::homePath() ) );
417
418 m_pTree->collapse( m_pDirModel->index( QDir::homePath()) );
419 }
420
421
422
on_m_pPathUptoolButton_clicked()423 void AudioFileBrowser::on_m_pPathUptoolButton_clicked()
424 {
425 QString path = pathLineEdit->text();
426 QStringList pathlist = path.split("/");
427
428 if( pathlist.isEmpty () ) {
429 return;
430 }
431
432 if( path.endsWith( "/" ) ) {
433 pathlist.removeLast();
434 QString tmpupdir = pathlist.join("/");
435 m_pTree->setRootIndex( m_pDirModel->index( tmpupdir ) );
436 m_pTree->collapse( m_pDirModel->index( tmpupdir ) );
437 m_pTree->setExpanded( m_pDirModel->index( tmpupdir ), false );
438 }
439
440 pathlist.removeLast();
441
442 QString updir = pathlist.join("/");
443 if ( updir == "" ) {
444 pathLineEdit->setText( QString("/") );
445 } else {
446 pathLineEdit->setText( updir );
447 }
448
449 m_pTree->setRootIndex( m_pDirModel->index( updir ) );
450 m_pTree->collapse( m_pDirModel->index( updir ) );
451 m_pTree->setExpanded( m_pDirModel->index(updir), false );
452 }
453
454
455
on_hiddenCB_clicked()456 void AudioFileBrowser::on_hiddenCB_clicked()
457 {
458 if ( hiddenCB->isChecked() ) {
459 m_pDirModel->setFilter( QDir::AllDirs | QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden );
460 } else {
461 m_pDirModel->setFilter( QDir::AllDirs | QDir::AllEntries | QDir::NoDotAndDotDot );
462 m_pTree->setRootIndex( m_pDirModel->index( pathLineEdit->text() ) );
463 }
464 }
465