1 
2 #include <hydrogen/config.h>
3 #include <hydrogen/helpers/filesystem.h>
4 
5 #include <QtCore/QDir>
6 #include <QtCore/QFile>
7 #include <QtCore/QFileInfo>
8 #include <QtCore/QCoreApplication>
9 
10 // directories
11 #define LOCAL_DATA_PATH "data/"
12 #define CACHE           "cache/"
13 #define DEMOS           "demo_songs/"
14 #define DOC             "doc/"
15 #define DRUMKITS        "drumkits/"
16 #define I18N            "i18n/"
17 #define IMG             "img/"
18 #define PATTERNS        "patterns/"
19 #define PLAYLISTS       "playlists/"
20 #define PLUGINS         "plugins/"
21 #define REPOSITORIES    "repositories/"
22 #define SCRIPTS         "scripts/"
23 #define SONGS           "songs/"
24 #define TMP             "hydrogen/"
25 #define XSD             "xsd/"
26 
27 
28 // files
29 /** Sound of metronome beat */
30 #define CLICK_SAMPLE    "click.wav"
31 #define EMPTY_SAMPLE    "emptySample.wav"
32 #define EMPTY_SONG      "DefaultSong.h2song"
33 #define USR_CONFIG		"hydrogen.conf"
34 #define SYS_CONFIG		"hydrogen.default.conf"
35 #define DRUMKIT_XML     "drumkit.xml"
36 #define DRUMKIT_XSD     "drumkit.xsd"
37 #define DRUMPAT_XSD     "drumkit_pattern.xsd"
38 #define PLAYLIST_XSD     "playlist.xsd"
39 
40 #define AUTOSAVE        "autosave"
41 
42 #define UNTITLED_SONG		"untitled.h2song"
43 #define UNTITLED_PLAYLIST	"untitled.h2playlist"
44 
45 // filters
46 #define PATTERN_FILTER  "*.h2pattern"
47 #define PLAYLIST_FILTER "*.h2playlist"
48 #define SONG_FILTER     "*.h2song"
49 
50 namespace H2Core
51 {
52 
53 Logger* Filesystem::__logger = nullptr;
54 const char* Filesystem::__class_name = "Filesystem";
55 
56 const QString Filesystem::scripts_ext = ".sh";
57 const QString Filesystem::songs_ext = ".h2song";
58 const QString Filesystem::patterns_ext = ".h2pattern";
59 const QString Filesystem::playlist_ext = ".h2playlist";
60 const QString Filesystem::scripts_filter_name = "Hydrogen Scripts (*.sh)";
61 const QString Filesystem::songs_filter_name = "Hydrogen Songs (*.h2song)";
62 const QString Filesystem::patterns_filter_name = "Hydrogen Patterns (*.h2pattern)";
63 const QString Filesystem::playlists_filter_name = "Hydrogen Playlists (*.h2playlist)";
64 
65 QString Filesystem::__sys_data_path;
66 QString Filesystem::__usr_data_path;
67 QString Filesystem::__usr_cfg_path;
68 QStringList Filesystem::__ladspa_paths;
69 
70 
71 /* TODO QCoreApplication is not instantiated */
bootstrap(Logger * logger,const QString & sys_path)72 bool Filesystem::bootstrap( Logger* logger, const QString& sys_path )
73 {
74 	if( __logger==nullptr && logger!=nullptr ) {
75 		__logger = logger;
76 	} else {
77 		return false;
78 	}
79 
80 #ifdef Q_OS_MACX
81 #ifdef H2CORE_HAVE_BUNDLE
82 	// Bundle: Prepare hydrogen to use path names which are used in app bundles: http://en.wikipedia.org/wiki/Application_Bundle
83 	__sys_data_path = QCoreApplication::applicationDirPath().append( "/../Resources/data/" ) ;
84 #else
85 	__sys_data_path = QCoreApplication::applicationDirPath().append( "/data/" ) ;
86 #endif
87 	__usr_data_path = QDir::homePath().append( "/Library/Application Support/Hydrogen/data/" );
88 	__usr_cfg_path = QDir::homePath().append( "/Library/Application Support/Hydrogen/" USR_CONFIG );
89 #elif WIN32
90 	__sys_data_path = QCoreApplication::applicationDirPath().append( "/data/" ) ;
91 	__usr_data_path = QDir::homePath().append( "/.hydrogen/data/" ) ;
92 	__usr_cfg_path = QDir::homePath().append( "/.hydrogen/" USR_CONFIG ) ;
93 #else
94 	__sys_data_path = H2_SYS_PATH "/data/";
95 	__usr_data_path = QDir::homePath().append( "/" H2_USR_PATH "/data/" );
96 	__usr_cfg_path = QDir::homePath().append( "/" H2_USR_PATH "/" USR_CONFIG );
97 #endif
98 	if( sys_path!=nullptr ) __sys_data_path = sys_path;
99 
100 	if( !dir_readable( __sys_data_path ) ) {
101 		__sys_data_path = QCoreApplication::applicationDirPath().append( "/" LOCAL_DATA_PATH );
102 		ERRORLOG( QString( "will use local data path : %1" ).arg( __sys_data_path ) );
103 	}
104 
105 	char* ladspaPath = getenv( "LADSPA_PATH" );
106 	if ( ladspaPath ) {
107 		INFOLOG( "Found LADSPA_PATH environment variable" );
108 		QString sLadspaPath = QString::fromLocal8Bit( ladspaPath );
109 		int pos;
110 		while ( ( pos = sLadspaPath.indexOf( ":" ) ) != -1 ) {
111 			QString sPath = sLadspaPath.left( pos );
112 			__ladspa_paths << QFileInfo(sPath).canonicalFilePath();
113 			sLadspaPath = sLadspaPath.mid( pos + 1, sLadspaPath.length() );
114 		}
115 		__ladspa_paths << QFileInfo( sLadspaPath ).canonicalFilePath();
116 	} else {
117 #ifdef Q_OS_MACX
118 		__ladspa_paths << QFileInfo( QCoreApplication::applicationDirPath(), "/../Resources/plugins" ).canonicalFilePath();
119 		__ladspa_paths << QFileInfo( "/Library/Audio/Plug-Ins/LADSPA/" ).canonicalFilePath();
120 		__ladspa_paths << QFileInfo( QDir::homePath(), "/Library/Audio/Plug-Ins/LADSPA" ).canonicalFilePath();
121 #else
122 		__ladspa_paths << QFileInfo( "/usr/lib/ladspa" ).canonicalFilePath();
123 		__ladspa_paths << QFileInfo( "/usr/local/lib/ladspa" ).canonicalFilePath();
124 		__ladspa_paths << QFileInfo( "/usr/lib64/ladspa" ).canonicalFilePath();
125 		__ladspa_paths << QFileInfo( "/usr/local/lib64/ladspa" ).canonicalFilePath();
126 #endif
127 	}
128 	__ladspa_paths.sort();
129 	__ladspa_paths.removeDuplicates();
130 	if ( !__ladspa_paths.isEmpty() && __ladspa_paths.at( 0 ).isEmpty() ) {
131 		__ladspa_paths.removeFirst();
132 	}
133 	// we want this first
134 	__ladspa_paths << Filesystem::plugins_dir();
135 	__ladspa_paths.removeDuplicates();
136 
137 	bool ret = check_sys_paths();
138 	ret &= check_usr_paths();
139 	info();
140 	return ret;
141 }
142 
check_permissions(const QString & path,const int perms,bool silent)143 bool Filesystem::check_permissions( const QString& path, const int perms, bool silent )
144 {
145 	QFileInfo fi( path );
146 	if( ( perms & is_file ) && ( perms & is_writable ) && !fi.exists() ) {
147 		QFileInfo folder( path.left( path.lastIndexOf( "/" ) ) );
148 		if( !folder.isDir() ) {
149 			if( !silent ) ERRORLOG( QString( "%1 is not a directory" ).arg( folder.fileName() ) );
150 			return false;
151 		}
152 		if( !folder.isWritable() ) {
153 			if( !silent ) ERRORLOG( QString( "%1 is not writable" ).arg( folder.fileName() ) );
154 			return false;
155 		}
156 		return true;
157 	}
158 	if( ( perms & is_dir ) && !fi.isDir() ) {
159 		if( !silent ) ERRORLOG( QString( "%1 is not a directory" ).arg( path ) );
160 		return false;
161 	}
162 	if( ( perms & is_file ) && !fi.isFile() ) {
163 		if( !silent ) ERRORLOG( QString( "%1 is not a file" ).arg( path ) );
164 		return false;
165 	}
166 	if( ( perms & is_readable ) && !fi.isReadable() ) {
167 		if( !silent ) ERRORLOG( QString( "%1 is not readable" ).arg( path ) );
168 		return false;
169 	}
170 	if( ( perms & is_writable ) && !fi.isWritable() ) {
171 		if( !silent ) ERRORLOG( QString( "%1 is not writable" ).arg( path ) );
172 		return false;
173 	}
174 	if( ( perms & is_executable ) && !fi.isExecutable() ) {
175 		if( !silent ) ERRORLOG( QString( "%1 is not executable" ).arg( path ) );
176 		return false;
177 	}
178 	return true;
179 }
180 
file_exists(const QString & path,bool silent)181 bool Filesystem::file_exists( const QString& path, bool silent )
182 {
183 	return check_permissions( path, is_file, silent );
184 }
file_readable(const QString & path,bool silent)185 bool Filesystem::file_readable( const QString& path, bool silent )
186 {
187 	return check_permissions( path, is_file|is_readable, silent );
188 }
file_writable(const QString & path,bool silent)189 bool Filesystem::file_writable( const QString& path, bool silent )
190 {
191 	return check_permissions( path, is_file|is_readable|is_writable, silent );
192 }
file_executable(const QString & path,bool silent)193 bool Filesystem::file_executable( const QString& path, bool silent )
194 {
195 	return check_permissions( path, is_file|is_executable, silent );
196 }
dir_readable(const QString & path,bool silent)197 bool Filesystem::dir_readable(  const QString& path, bool silent )
198 {
199 	return check_permissions( path, is_dir|is_readable|is_executable, silent );
200 }
dir_writable(const QString & path,bool silent)201 bool Filesystem::dir_writable(  const QString& path, bool silent )
202 {
203 	return check_permissions( path, is_dir|is_writable, silent );
204 }
205 
mkdir(const QString & path)206 bool Filesystem::mkdir( const QString& path )
207 {
208 	if ( !QDir( "/" ).mkpath( QDir( path ).absolutePath() ) ) {
209 		ERRORLOG( QString( "unable to create directory : %1" ).arg( path ) );
210 		return false;
211 	}
212 	return true;
213 }
214 
path_usable(const QString & path,bool create,bool silent)215 bool Filesystem::path_usable( const QString& path, bool create, bool silent )
216 {
217 	if( !QDir( path ).exists() ) {
218 		if( !silent ) INFOLOG( QString( "create user directory : %1" ).arg( path ) );
219 		if( create && !QDir( "/" ).mkpath( path ) ) {
220 			if( !silent ) ERRORLOG( QString( "unable to create user directory : %1" ).arg( path ) );
221 			return false;
222 		}
223 	}
224 	return dir_readable( path, silent ) && dir_writable( path, silent );
225 }
226 
write_to_file(const QString & dst,const QString & content)227 bool Filesystem::write_to_file( const QString& dst, const QString& content )
228 {
229 	if ( !file_writable( dst ) ) {
230 		ERRORLOG( QString( "unable to write to %1" ).arg( dst ) );
231 		return false;
232 	}
233 	QFile file( dst );
234 	if ( !file.open( QIODevice::WriteOnly ) ) {
235 		ERRORLOG( QString( "unable to write to %1" ).arg( dst ) );
236 		return false;
237 	}
238 	file.write( content.toUtf8().data() );
239 	file.close();
240 
241 	return true;
242 }
243 
file_copy(const QString & src,const QString & dst,bool overwrite)244 bool Filesystem::file_copy( const QString& src, const QString& dst, bool overwrite )
245 {
246 	if( !overwrite && file_exists( dst, true ) ) {
247 		WARNINGLOG( QString( "do not overwrite %1 with %2 as it already exists" ).arg( dst ).arg( src ) );
248 		return true;
249 	}
250 	if ( !file_readable( src ) ) {
251 		ERRORLOG( QString( "unable to copy %1 to %2, %1 is not readable" ).arg( src ).arg( dst ) );
252 		return false;
253 	}
254 	if ( !file_writable( dst ) ) {
255 		ERRORLOG( QString( "unable to copy %1 to %2, %2 is not writable" ).arg( src ).arg( dst ) );
256 		return false;
257 	}
258 	INFOLOG( QString( "copy %1 to %2" ).arg( src ).arg( dst ) );
259 	return QFile::copy( src,dst );
260 }
261 
rm(const QString & path,bool recursive)262 bool Filesystem::rm( const QString& path, bool recursive )
263 {
264 	if ( check_permissions( path, is_file, true ) ) {
265 		QFile file( path );
266 		bool ret = file.remove();
267 		if( !ret ) {
268 			ERRORLOG( QString( "unable to remove file %1" ).arg( path ) );
269 		}
270 		return ret;
271 	}
272 	if ( !check_permissions( path, is_dir, true )  ) {
273 		ERRORLOG( QString( "%1 is neither a file nor a directory ?!?!" ).arg( path ) );
274 		return false;
275 	}
276 	if ( !recursive ) {
277 		QDir dir;
278 		bool ret = dir.rmdir( path );
279 		if( !ret ) {
280 			ERRORLOG( QString( "unable to remove dir %1 without recursive argument, maybe it is not empty?" ).arg( path ) );
281 		}
282 		return ret;
283 	}
284 	return rm_fr( path );
285 }
286 
rm_fr(const QString & path)287 bool Filesystem::rm_fr( const QString& path )
288 {
289 	bool ret = true;
290 	QDir dir( path );
291 	QFileInfoList entries = dir.entryInfoList( QDir::NoDotAndDotDot | QDir::AllEntries );
292 	for ( int idx = 0; ( ( idx < entries.size() ) && ret ); idx++ ) {
293 		QFileInfo entryInfo = entries[idx];
294 		if ( entryInfo.isDir() && !entryInfo.isSymLink() ) {
295 			ret = rm_fr( entryInfo.absoluteFilePath() );
296 		} else {
297 			QFile file( entryInfo.absoluteFilePath() );
298 			if ( !file.remove() ) {
299 				ERRORLOG( QString( "unable to remove %1" ).arg( entryInfo.absoluteFilePath() ) );
300 				ret = false;
301 			}
302 		}
303 	}
304 	if ( !dir.rmdir( dir.absolutePath() ) ) {
305 		ERRORLOG( QString( "unable to remove %1" ).arg( dir.absolutePath() ) );
306 		ret = false;
307 	}
308 	return ret;
309 }
310 
check_sys_paths()311 bool Filesystem::check_sys_paths()
312 {
313 	bool ret = true;
314 	if(  !dir_readable( __sys_data_path ) ) ret = false;
315 	if( !file_readable( click_file_path() ) ) ret = false;
316 	if( !file_readable( empty_song_path() ) ) ret = false;
317 	if(  !dir_readable( demos_dir() ) ) ret = false;
318 	/* if(  !dir_readable( doc_dir() ) ) ret = false; */		// FIXME
319 	if(  !dir_readable( sys_drumkits_dir() ) ) ret = false;
320 	if( !file_readable( empty_sample_path() ) ) ret = false;
321 	if( !file_readable( sys_config_path() ) ) ret = false;
322 	if(  !dir_readable( i18n_dir() ) ) ret = false;
323 	if(  !dir_readable( img_dir() ) ) ret = false;
324 	if(  !dir_readable( xsd_dir() ) ) ret = false;
325 	if( !file_readable( pattern_xsd_path() ) ) ret = false;
326 	if( !file_readable( drumkit_xsd_path() ) ) ret = false;
327 	if( !file_readable( playlist_xsd_path() ) ) ret = false;
328 
329 	if ( ret ) INFOLOG( QString( "system wide data path %1 is usable." ).arg( __sys_data_path ) );
330 	return ret;
331 }
332 
333 
check_usr_paths()334 bool Filesystem::check_usr_paths()
335 {
336 	bool ret = true;
337 	if( !path_usable( tmp_dir() ) ) ret = false;
338 	if( !path_usable( __usr_data_path ) ) ret = false;
339 	if( !path_usable( cache_dir() ) ) ret = false;
340 	if( !path_usable( repositories_cache_dir() ) ) ret = false;
341 	if( !path_usable( usr_drumkits_dir() ) ) ret = false;
342 	if( !path_usable( patterns_dir() ) ) ret = false;
343 	if( !path_usable( playlists_dir() ) ) ret = false;
344 	if( !path_usable( plugins_dir() ) ) ret = false;
345 	if( !path_usable( scripts_dir() ) ) ret = false;
346 	if( !path_usable( songs_dir() ) ) ret = false;
347 	if( !file_writable( usr_config_path() ) ) ret = false;
348 
349 	if ( ret ) INFOLOG( QString( "user path %1 is usable." ).arg( __usr_data_path ) );
350 	return ret;
351 }
352 
sys_data_path()353 QString Filesystem::sys_data_path()
354 {
355 	return __sys_data_path;
356 }
usr_data_path()357 QString Filesystem::usr_data_path()
358 {
359 	return __usr_data_path;
360 }
361 
ladspa_paths()362 QStringList Filesystem::ladspa_paths()
363 {
364 	return __ladspa_paths;
365 }
366 
367 // FILES
sys_config_path()368 QString Filesystem::sys_config_path()
369 {
370        return __sys_data_path + SYS_CONFIG;
371 }
usr_config_path()372 QString Filesystem::usr_config_path()
373 {
374        return __usr_cfg_path;
375 }
empty_sample_path()376 QString Filesystem::empty_sample_path()
377 {
378 	return __sys_data_path + EMPTY_SAMPLE;
379 }
empty_song_path()380 QString Filesystem::empty_song_path()
381 {
382 	return __sys_data_path + EMPTY_SONG;
383 }
untitled_song_file_name()384 QString Filesystem::untitled_song_file_name()
385 {
386 	return UNTITLED_SONG;
387 }
untitled_playlist_file_name()388 QString Filesystem::untitled_playlist_file_name()
389 {
390 	return UNTITLED_PLAYLIST;
391 }
click_file_path()392 QString Filesystem::click_file_path()
393 {
394 	return __sys_data_path + CLICK_SAMPLE;
395 }
usr_click_file_path()396 QString Filesystem::usr_click_file_path()
397 {
398 	if( file_readable( __usr_data_path + CLICK_SAMPLE, true ) ) return __usr_data_path + CLICK_SAMPLE;
399 	return click_file_path();
400 }
drumkit_xsd_path()401 QString Filesystem::drumkit_xsd_path( )
402 {
403 	return xsd_dir() + DRUMKIT_XSD;
404 }
pattern_xsd_path()405 QString Filesystem::pattern_xsd_path( )
406 {
407 	return xsd_dir() + DRUMPAT_XSD;
408 }
playlist_xsd_path()409 QString Filesystem::playlist_xsd_path( )
410 {
411 	return xsd_dir() + PLAYLIST_XSD;
412 }
413 
414 // DIRS
img_dir()415 QString Filesystem::img_dir()
416 {
417 	return __sys_data_path + IMG;
418 }
doc_dir()419 QString Filesystem::doc_dir()
420 {
421 	return __sys_data_path + DOC;
422 }
i18n_dir()423 QString Filesystem::i18n_dir()
424 {
425 	return __sys_data_path + I18N;
426 }
scripts_dir()427 QString Filesystem::scripts_dir()
428 {
429 	return __usr_data_path + SCRIPTS;
430 }
songs_dir()431 QString Filesystem::songs_dir()
432 {
433 	return __usr_data_path + SONGS;
434 }
song_path(const QString & sg_name)435 QString Filesystem::song_path( const QString& sg_name )
436 {
437 	return QString( songs_dir() + sg_name + songs_ext );
438 }
patterns_dir()439 QString Filesystem::patterns_dir()
440 {
441 	return __usr_data_path + PATTERNS;
442 }
patterns_dir(const QString & dk_name)443 QString Filesystem::patterns_dir( const QString& dk_name )
444 {
445 	return __usr_data_path + PATTERNS + dk_name + "/";
446 }
pattern_path(const QString & dk_name,const QString & p_name)447 QString Filesystem::pattern_path( const QString& dk_name, const QString& p_name )
448 {
449 	if ( dk_name.isEmpty() ) {
450 		return patterns_dir() + p_name + patterns_ext;
451 	} else {
452 		return patterns_dir( dk_name ) + p_name + patterns_ext;
453 	}
454 }
plugins_dir()455 QString Filesystem::plugins_dir()
456 {
457 	return __usr_data_path + PLUGINS;
458 }
sys_drumkits_dir()459 QString Filesystem::sys_drumkits_dir()
460 {
461 	return __sys_data_path + DRUMKITS;
462 }
usr_drumkits_dir()463 QString Filesystem::usr_drumkits_dir()
464 {
465 	return __usr_data_path + DRUMKITS;
466 }
playlists_dir()467 QString Filesystem::playlists_dir()
468 {
469 	return __usr_data_path + PLAYLISTS;
470 }
playlist_path(const QString & pl_name)471 QString Filesystem::playlist_path( const QString& pl_name )
472 {
473 	return patterns_dir() + pl_name + playlist_ext;
474 }
cache_dir()475 QString Filesystem::cache_dir()
476 {
477 	return __usr_data_path + CACHE;
478 }
repositories_cache_dir()479 QString Filesystem::repositories_cache_dir()
480 {
481 	return __usr_data_path + CACHE + REPOSITORIES;
482 }
demos_dir()483 QString Filesystem::demos_dir()
484 {
485 	return __sys_data_path + DEMOS;
486 }
xsd_dir()487 QString Filesystem::xsd_dir()
488 {
489 	return __sys_data_path + XSD;
490 }
tmp_dir()491 QString Filesystem::tmp_dir()
492 {
493 	return QDir::tempPath() + "/" + TMP;
494 }
tmp_file_path(const QString & base)495 QString Filesystem::tmp_file_path( const QString& base )
496 {
497 	QFileInfo f( base );
498 	QString templateName(tmp_dir() + "/");
499 	if ( f.suffix().isEmpty() ) {
500 		templateName += base;
501 	} else {
502 		templateName += f.completeBaseName() + "-XXXXXX." + f.suffix();
503 	}
504 	QTemporaryFile file( templateName.replace( " ", "_" ) );
505 	file.setAutoRemove( false );
506 	file.open();
507 	file.close();
508 	return file.fileName();
509 }
510 
511 // DRUMKITS
drumkit_list(const QString & path)512 QStringList Filesystem::drumkit_list( const QString& path )
513 {
514 	QStringList ok;
515 	QStringList possible = QDir( path ).entryList( QDir::Dirs | QDir::Readable | QDir::NoDotAndDotDot );
516 	foreach ( const QString& dk, possible ) {
517 		if ( drumkit_valid( path + dk ) ) {
518 			ok << dk;
519 		} else {
520 			ERRORLOG( QString( "drumkit %1 is not usable" ).arg( dk ) );
521 		}
522 	}
523 	return ok;
524 }
sys_drumkit_list()525 QStringList Filesystem::sys_drumkit_list( )
526 {
527 	return drumkit_list( sys_drumkits_dir() ) ;
528 }
usr_drumkit_list()529 QStringList Filesystem::usr_drumkit_list( )
530 {
531 	return drumkit_list( usr_drumkits_dir() ) ;
532 }
533 
prepare_sample_path(const QString & fname)534 QString Filesystem::prepare_sample_path( const QString& fname )
535 {
536 	int idx = get_basename_idx_under_drumkit( fname );
537 	if ( idx >= 0 ) {
538 		return fname.midRef( idx ).toString();
539 	}
540 	return fname;
541 }
542 
file_is_under_drumkit(const QString & fname)543 bool Filesystem::file_is_under_drumkit( const QString& fname )
544 {
545 	return get_basename_idx_under_drumkit( fname ) != -1;
546 }
547 
get_basename_idx_under_drumkit(const QString & fname)548 int Filesystem::get_basename_idx_under_drumkit( const QString& fname )
549 {
550 	if( fname.startsWith( usr_drumkits_dir() ) )
551 	{
552 		int start = usr_drumkits_dir().size();
553 		int index = fname.indexOf( "/", start );
554 		QString dk_name = fname.midRef( start , index - start).toString();
555 		if ( usr_drumkit_list().contains( dk_name ) ) {
556 			return index + 1;
557 		}
558 	}
559 
560 	if( fname.startsWith( sys_drumkits_dir() ) )
561 	{
562 		int start = sys_drumkits_dir().size();
563 		int index = fname.indexOf( "/", start);
564 		QString dk_name = fname.midRef( start, index - start).toString();
565 		if ( sys_drumkit_list().contains( dk_name ) ) {
566 			return index + 1;
567 		}
568 	}
569 
570 	return -1;
571 }
572 
573 
drumkit_exists(const QString & dk_name)574 bool Filesystem::drumkit_exists( const QString& dk_name )
575 {
576 	if( usr_drumkit_list().contains( dk_name ) ) return true;
577 	return sys_drumkit_list().contains( dk_name );
578 }
drumkit_usr_path(const QString & dk_name)579 QString Filesystem::drumkit_usr_path( const QString& dk_name )
580 {
581 	return usr_drumkits_dir() + dk_name;
582 }
drumkit_path_search(const QString & dk_name)583 QString Filesystem::drumkit_path_search( const QString& dk_name )
584 {
585 	if( usr_drumkit_list().contains( dk_name ) ) return usr_drumkits_dir() + dk_name;
586 	if( sys_drumkit_list().contains( dk_name ) ) return sys_drumkits_dir() + dk_name;
587 	ERRORLOG( QString( "drumkit %1 not found" ).arg( dk_name ) );
588 	return "";
589 }
drumkit_dir_search(const QString & dk_name)590 QString Filesystem::drumkit_dir_search( const QString& dk_name )
591 {
592 	if( usr_drumkit_list().contains( dk_name ) ) return usr_drumkits_dir();
593 	if( sys_drumkit_list().contains( dk_name ) ) return sys_drumkits_dir();
594 	ERRORLOG( QString( "drumkit %1 not found" ).arg( dk_name ) );
595 	return "";
596 }
drumkit_valid(const QString & dk_path)597 bool Filesystem::drumkit_valid( const QString& dk_path )
598 {
599 	return file_readable( dk_path + "/" + DRUMKIT_XML, true);
600 }
drumkit_file(const QString & dk_path)601 QString Filesystem::drumkit_file( const QString& dk_path )
602 {
603 	return dk_path + "/" + DRUMKIT_XML;
604 }
605 
606 // PATTERNS
pattern_drumkits()607 QStringList Filesystem::pattern_drumkits()
608 {
609 	return QDir( patterns_dir() ).entryList( QDir::Dirs | QDir::Readable | QDir::NoDotAndDotDot );
610 }
611 
pattern_list()612 QStringList Filesystem::pattern_list()
613 {
614 	return pattern_list( patterns_dir() );
615 }
616 
pattern_list(const QString & path)617 QStringList Filesystem::pattern_list( const QString& path)
618 {
619 	return QDir( path ).entryList( QStringList( PATTERN_FILTER ), QDir::Files | QDir::Readable | QDir::NoDotAndDotDot );
620 }
621 
622 // SONGS
song_list()623 QStringList Filesystem::song_list( )
624 {
625 	return QDir( songs_dir() ).entryList( QStringList( SONG_FILTER ), QDir::Files | QDir::Readable | QDir::NoDotAndDotDot );
626 }
627 
song_list_cleared()628 QStringList Filesystem::song_list_cleared( )
629 {
630 	QStringList result;
631 	foreach ( const QString& str, song_list() ) {
632 		if ( !str.contains( AUTOSAVE ) ) {
633 			result += str;
634 		}
635 	}
636 	return result;
637 }
638 
song_exists(const QString & sg_name)639 bool Filesystem::song_exists( const QString& sg_name )
640 {
641 	return QDir( songs_dir() ).exists( sg_name );
642 }
643 
644 // PLAYLISTS
playlist_list()645 QStringList Filesystem::playlist_list( )
646 {
647 	return QDir( playlists_dir() ).entryList( QStringList( PLAYLIST_FILTER ), QDir::Files | QDir::Readable | QDir::NoDotAndDotDot );
648 }
649 
info()650 void Filesystem::info()
651 {
652 	INFOLOG( QString( "Tmp dir                    : %1" ).arg( tmp_dir() ) );
653 	// SYS
654 	INFOLOG( QString( "Click file                 : %1" ).arg( click_file_path() ) );
655 	INFOLOG( QString( "Empty song                 : %1" ).arg( empty_song_path() ) );
656 	INFOLOG( QString( "Demos dir                  : %1" ).arg( demos_dir() ) );
657 	INFOLOG( QString( "Documentation dir          : %1" ).arg( doc_dir() ) );					// FIXME must be created even if no doc deployed
658 	INFOLOG( QString( "System drumkit dir         : %1" ).arg( sys_drumkits_dir() ) );
659 	INFOLOG( QString( "Empty sample               : %1" ).arg( empty_sample_path() ) );
660 	INFOLOG( QString( "Default config             : %1" ).arg( sys_config_path() ) );
661 	INFOLOG( QString( "Internationalization dir   : %1" ).arg( i18n_dir() ) );
662 	INFOLOG( QString( "Images dir                 : %1" ).arg( img_dir() ) );
663 	// new_tutorial
664 	INFOLOG( QString( "XSD dir                    : %1" ).arg( xsd_dir() ) );
665 	INFOLOG( QString( "drumkit pattern XSD        : %1" ).arg( pattern_xsd_path() ) );
666 	INFOLOG( QString( "drumkit XSD                : %1" ).arg( drumkit_xsd_path() ) );
667 	INFOLOG( QString( "drumkit XSD                : %1" ).arg( playlist_xsd_path() ) );
668 	// USR
669 	INFOLOG( QString( "User config                : %1" ).arg( usr_config_path() ) );			// FIXME
670 	INFOLOG( QString( "User Click file            : %1" ).arg( usr_click_file_path() ) );
671 	INFOLOG( QString( "Cache dir                  : %1" ).arg( cache_dir() ) );
672 	INFOLOG( QString( "Reporitories Cache dir     : %1" ).arg( repositories_cache_dir() ) );
673 	INFOLOG( QString( "User drumkit dir           : %1" ).arg( usr_drumkits_dir() ) );
674 	INFOLOG( QString( "Patterns dir               : %1" ).arg( patterns_dir() ) );
675 	INFOLOG( QString( "Playlist dir               : %1" ).arg( playlists_dir() ) );
676 	INFOLOG( QString( "Plugins dir                : %1" ).arg( plugins_dir() ) );
677 	INFOLOG( QString( "Scripts dir                : %1" ).arg( scripts_dir() ) );
678 	INFOLOG( QString( "Songs dir                  : %1" ).arg( songs_dir() ) );
679 }
680 
681 };
682 
683 /* vim: set softtabstop=4 noexpandtab: */
684