diff options
| author | André Nusser <andre.nusser@googlemail.com> | 2019-10-26 19:11:03 +0200 | 
|---|---|---|
| committer | André Nusser <andre.nusser@googlemail.com> | 2019-10-26 20:04:01 +0200 | 
| commit | 85ce939590e9f60d51952b4cc1e6af6f9820ca28 (patch) | |
| tree | 25b66ce7fbed77cb3b1d3e54065c03e67f31d125 /src | |
| parent | 6ad9b9d2ae3341bbd4914f4951070a02d3dd4d2b (diff) | |
Add default midimap functionality.
Move directory.{h,cc} to src/ for this.
Diffstat (limited to 'src')
| -rw-r--r-- | src/DGDOM.h | 1 | ||||
| -rw-r--r-- | src/Makefile.am | 2 | ||||
| -rw-r--r-- | src/dgxmlparser.cc | 5 | ||||
| -rw-r--r-- | src/directory.cc | 567 | ||||
| -rw-r--r-- | src/directory.h | 88 | ||||
| -rw-r--r-- | src/drumkitloader.cc | 7 | 
6 files changed, 670 insertions, 0 deletions
| diff --git a/src/DGDOM.h b/src/DGDOM.h index b6c52ac..474b29c 100644 --- a/src/DGDOM.h +++ b/src/DGDOM.h @@ -131,6 +131,7 @@ struct MetadataDOM  	std::string image;  	std::string image_map;  	std::vector<ClickMapDOM> clickmaps; +	std::string default_midimap_file;  };  struct DrumkitDOM diff --git a/src/Makefile.am b/src/Makefile.am index 56d44ef..93ef5ed 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,6 +22,7 @@ nodist_libdg_la_SOURCES = \  	channelmixer.cc \  	configfile.cc \  	configparser.cc \ +	directory.cc \  	domloader.cc \  	dgxmlparser.cc \  	drumgizmo.cc \ @@ -63,6 +64,7 @@ EXTRA_DIST = \  	channelmixer.h \  	configfile.h \  	configparser.h \ +	directory.h \  	cpp11fix.h \  	dgxmlparser.h \  	domloader.h \ diff --git a/src/dgxmlparser.cc b/src/dgxmlparser.cc index b924cc8..0d3cdcd 100644 --- a/src/dgxmlparser.cc +++ b/src/dgxmlparser.cc @@ -245,6 +245,11 @@ bool parseDrumkitFile(const std::string& filename, DrumkitDOM& dom, LogFunction  				               clickmap, "colour", logger, filename, true);  			}  		} +		pugi::xml_node default_midimap = metadata.child("defaultmidimap"); +		if(default_midimap != pugi::xml_node()) +		{ +			res &= attrcpy(meta.default_midimap_file, default_midimap, "src", logger, filename, true); +		}  	}  	pugi::xml_node channels = doc.child("drumkit").child("channels"); diff --git a/src/directory.cc b/src/directory.cc new file mode 100644 index 0000000..596b045 --- /dev/null +++ b/src/directory.cc @@ -0,0 +1,567 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            directory.cc + * + *  Tue Apr 23 22:01:07 CEST 2013 + *  Copyright 2013 Jonas Suhr Christensen + *  jsc@umbraculum.org + ****************************************************************************/ + +/* + *  This file is part of DrumGizmo. + * + *  DrumGizmo is free software; you can redistribute it and/or modify + *  it under the terms of the GNU Lesser General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  DrumGizmo is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU Lesser General Public License for more details. + * + *  You should have received a copy of the GNU Lesser General Public License + *  along with DrumGizmo; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "directory.h" + +#include <dirent.h> +#include <stdio.h> +#include <string> +#include <algorithm> +#include <vector> +#include <string.h> +#include <unistd.h> + +#include <platform.h> + +#if DG_PLATFORM == DG_PLATFORM_WINDOWS +#include <direct.h> +#include <windows.h> +#endif + +#include <hugin.hpp> + +#define DRUMKIT_SUFFIX ".xml" + +// http://en.wikipedia.org/wiki/Path_(computing) +#if DG_PLATFORM == DG_PLATFORM_WINDOWS +#define SEP "\\" +#else +#define SEP "/" +#endif + +Directory::Directory(std::string path) +{ +	setPath(path); +} + +Directory::~Directory() +{ +} + +std::string Directory::seperator() +{ +	return SEP; +} + +void Directory::setPath(std::string path) +{ +	//DEBUG(directory, "Setting path to '%s'\n", path.c_str()); +	this->_path = cleanPath(path); +	refresh(); +} + +size_t Directory::count() +{ +	return _files.size(); +} + +void Directory::refresh() +{ +	_files = listFiles(_path, DIRECTORY_HIDDEN); +	//_files = listFiles(_path); +} + +bool Directory::cd(std::string dir) +{ +	//TODO: Should this return true or false? +	if(dir.empty() || dir == ".") +	{ +		return true; +	} + +	//DEBUG(directory, "Changing to '%s'\n", dir.c_str()); +	if(exists(_path + SEP + dir)) +	{ +		std::string path = _path + SEP + dir; +		setPath(path); +		refresh(); +		return true; +	} +	else +	{ +		return false; +	} +} + +bool Directory::cdUp() +{ +	return this->cd(".."); +} + +std::string Directory::path() +{ +	return cleanPath(_path); +} + +Directory::EntryList Directory::entryList() +{ +	return _files; +} + +#define MAX_FILE_LENGTH 1024 +std::string Directory::cwd() +{ +	char path[MAX_FILE_LENGTH]; +	char* c = getcwd(path, MAX_FILE_LENGTH); + +	if(c) +	{ +		return c; +	} +	else +	{ +		return ""; +	} +} + +std::string Directory::cleanPath(std::string path) +{ +	//DEBUG(directory, "Cleaning path '%s'\n", path.c_str()); +	Directory::Path pathlst = parsePath(path); +	return Directory::pathToStr(pathlst); +} + +Directory::EntryList Directory::listFiles(std::string path, unsigned char filter) +{ +	DEBUG(directory, "Listing files in '%s'\n", path.c_str()); + +	Directory::EntryList entries; +	DIR *dir = opendir(path.c_str()); +	if(!dir) +	{ +		//DEBUG(directory, "Couldn't open directory '%s\n", path.c_str()); +		return entries; +	} + +	std::vector<std::string> directories; +	std::vector<std::string> files; + +	struct dirent *entry; +	while((entry = readdir(dir)) != nullptr) +	{ +		std::string name = entry->d_name; +		if(name == ".") +		{ +			continue; +		} + +		if(Directory::isRoot(path) && name == "..") +		{ +			continue; +		} + +		unsigned char entryinfo = 0; +		if(isHidden(path + SEP + name)) +		{ +			entryinfo |= DIRECTORY_HIDDEN; +		} + +		std::string entrypath = path; +		entrypath += SEP; +		entrypath += entry->d_name; +		if(Directory::isDir(entrypath)) +		{ +			if(!(entryinfo && filter)) +			{ +				if(name == "..") +				{ +					directories.push_back(entry->d_name); +				} +				else +				{ +					directories.push_back(std::string(SEP) + entry->d_name); +				} +			} +		} +		else +		{ +			int drumkit_suffix_length = strlen(DRUMKIT_SUFFIX); +			if((int)name.size() < drumkit_suffix_length) +			{ +				continue; +			} + +			if(name.substr(name.length() - drumkit_suffix_length, +			               drumkit_suffix_length) != DRUMKIT_SUFFIX) +			{ +				continue; +			} + + +			//if(!(entryinfo && filter)) { +			files.push_back(entry->d_name); +			//} +		} +	} + +#if DG_PLATFORM == DG_PLATFORM_WINDOWS +	//DEBUG(directory, "Root is %s\n", Directory::root(path).c_str()); +	//DEBUG(directory, "Current path %s is root? %d", path.c_str(), +	//      Directory::isRoot(path)); +	if(Directory::isRoot(path)) +	{ +		entries.push_back(".."); +	} +#endif + +	// sort +	for(int x = 0; x < (int)directories.size(); x++) +	{ +		for(int y = 0; y < (int)directories.size(); y++) +		{ +			if(directories[x] < directories[y]) +			{ +				std::string tmp = directories[x]; +				directories[x] = directories[y]; +				directories[y] = tmp; +			} +		} +	} + +	for(int x = 0; x < (int)files.size(); x++) +	{ +		for(int y = 0; y < (int)files.size(); y++) +		{ +			if(files[x] < files[y]) +			{ +				std::string tmp = files[x]; +				files[x] = files[y]; +				files[y] = tmp; +			} +		} +	} + + +	for(auto directory : directories) +	{ +		entries.push_back(directory); +	} + +	for(auto file : files) +	{ +		entries.push_back(file); +	} + +	closedir(dir); +	return entries; +} + +bool Directory::isRoot(std::string path) +{ +#if DG_PLATFORM == DG_PLATFORM_WINDOWS +	std::transform(path.begin(), path.end(), path.begin(), ::tolower); +	std::string root_str = Directory::root(path); +	std::transform(root_str.begin(), root_str.end(), root_str.begin(), ::tolower); + +	// TODO: This is not a correct root calculation, but works with partitions +	if(path.size() == 2) +	{ +		if(path == root_str) +		{ +			return true; +		} +		else +		{ +			return false; +		} +	} +	else +	{ +		if (path.size() == 3) +		{ +			if(path == root_str + SEP) +			{ +				return true; +			} +			return false; +		} +		else +		{ +			return false; +		} +	} +#else +	if(path == SEP) +	{ +		return true; +	} +	else +	{ +		return false; +	} +#endif +} + +std::string Directory::root() +{ +	return root(cwd()); +} + +std::string Directory::root(std::string path) +{ +#if DG_PLATFORM == DG_PLATFORM_WINDOWS +	if(path.size() < 2) +	{ +		return "c:"; // just something default when input is bad +	} +	else +	{ +		return path.substr(0, 2); +	} +#else +	return SEP; +#endif +} + +Directory::DriveList Directory::drives() +{ +	Directory::DriveList drives; +#if DG_PLATFORM == DG_PLATFORM_WINDOWS +	unsigned int d = GetLogicalDrives(); +	for(int i = 0; i < 32; ++i) +	{ +		if(d & (1 << i)) +		{ +			drive_t drive; +			char name[] = "x:"; +			name[0] = i + 'a'; + +			drive.name = name; +			drive.number = i; +			drives.push_back(drive); +		} +	} +#endif +	return drives; +} + +bool Directory::isDir() +{ +	return isDir(_path); +} + +bool Directory::isDir(std::string path) +{ +	//DEBUG(directory, "Is '%s' a directory?\n", path.c_str()); +	struct stat st; +	if(stat(path.c_str(), &st) == 0) +	{ +		if((st.st_mode & S_IFDIR) != 0) +		{ +			//DEBUG(directory, "\t...yes!\n"); +			return true; +		} +	} +	//DEBUG(directory, "\t...no!\n"); +	return false; +} + +bool Directory::fileExists(std::string filename) +{ +	return !isDir(_path + SEP + filename); +} + +bool Directory::exists(std::string path) +{ +	struct stat st; +	if(stat(path.c_str(), &st) == 0) +	{ +		return true; +	} +	else +	{ +		return false; +	} +} + +bool Directory::isHidden(std::string path) +{ +	//DEBUG(directory, "Is '%s' hidden?\n", path.c_str()); +#if DG_PLATFORM == DG_PLATFORM_WINDOWS +	// We dont want to filter out '..' pointing to root of a partition +	unsigned pos = path.find_last_of("/\\"); +	std::string entry = path.substr(pos+1); +	if(entry == "..") +	{ +		return false; +	} + +	DWORD fattribs = GetFileAttributes(path.c_str()); +	if(fattribs & FILE_ATTRIBUTE_HIDDEN) +	{ +		//DEBUG(directory, "\t...yes!\n"); +		return true; +	} +	else +	{ +		if(fattribs & FILE_ATTRIBUTE_SYSTEM) +		{ +			//DEBUG(directory, "\t...yes!\n"); +			return true; +		} +		else +		{ +			//DEBUG(directory, "\t...no!\n"); +			return false; +		} +	} +#else +	unsigned pos = path.find_last_of("/\\"); +	std::string entry = path.substr(pos+1); +	if(entry.size() > 1 && +	   entry.at(0) == '.' && +	   entry.at(1) != '.') +	{ +		//DEBUG(directory, "\t...yes!\n"); +		return true; +	} +	else +	{ +		//DEBUG(directory, "\t...no!\n"); +		return false; +	} +#endif +} + +Directory::Path Directory::parsePath(std::string path_str) +{ +	//TODO: Handle "." input and propably other special cases + +	//DEBUG(directory, "Parsing path '%s'", path_str.c_str()); +	Directory::Path path; + +	std::string current_char; +	std::string prev_char; +	std::string dir; +	for(size_t c = 0; c < path_str.size(); ++c) +	{ +		current_char = path_str.at(c); + +		if(current_char == SEP) +		{ +			if(prev_char == SEP) +			{ +				dir.clear(); +				prev_char = current_char; +				continue; +			} +			else +			{ +				if(prev_char == ".") +				{ +					prev_char = current_char; +					continue; +				} +			} +			if(!dir.empty()) +			{ +				path.push_back(dir); +			} +			dir.clear(); +			continue; +		} +		else +		{ +			if(current_char == ".") +			{ +				if(prev_char == ".") +				{ +					dir.clear(); +					if(!path.empty()) +					{ +						path.pop_back(); +					} +					continue; +				} +			} +		} +		dir += current_char; +		prev_char = current_char; +	} + +	if(!dir.empty()) +	{ +		path.push_back(dir); +	} + +	return path; +} + +std::string Directory::pathToStr(Directory::Path& path) +{ +	std::string cleaned_path; +	//DEBUG(directory, "Number of directories in path is %d\n", (int)path.size()); + +	for(auto it = path.begin(); it != path.end(); ++it) +	{ +		std::string dir = *it; +		//DEBUG(directory, "\tDir '%s'\n", dir.c_str()); +#if DG_PLATFORM == DG_PLATFORM_WINDOWS +		if(it != path.begin()) +		{ +			cleaned_path += SEP; +		} +		cleaned_path += dir; +#else +		cleaned_path += SEP + dir; +#endif +	} + +	//DEBUG(directory, "Cleaned path '%s'\n", cleaned_path.c_str()); + +	if(cleaned_path.empty()) +	{ +		cleaned_path = Directory::root(); +#if DG_PLATFORM == DG_PLATFORM_WINDOWS +		cleaned_path += SEP; +#endif +	} + +#if DG_PLATFORM == DG_PLATFORM_WINDOWS +	if(cleaned_path.size() == 2) +	{ +		cleaned_path += SEP; +	} +#endif + +	return cleaned_path; +} + +std::string Directory::pathDirectory(std::string filepath) +{ +	if(Directory::isDir(filepath)) +	{ +		return filepath; +	} + +	Directory::Path path = parsePath(filepath); +	if(path.size() > 0) +	{ +		path.pop_back(); +	} + +	return Directory::pathToStr(path); +} diff --git a/src/directory.h b/src/directory.h new file mode 100644 index 0000000..e46c5b9 --- /dev/null +++ b/src/directory.h @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            directory.h + * + *  Tue Apr 23 22:01:07 CEST 2013 + *  Copyright 2013 Jonas Suhr Christensen + *  jsc@umbraculum.org + ****************************************************************************/ + +/* + *  This file is part of DrumGizmo. + * + *  DrumGizmo is free software; you can redistribute it and/or modify + *  it under the terms of the GNU Lesser General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  DrumGizmo is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU Lesser General Public License for more details. + * + *  You should have received a copy of the GNU Lesser General Public License + *  along with DrumGizmo; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#pragma once + +#include <string> +#include <list> + +#include <libgen.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#define DIRECTORY_HIDDEN 1 + +class Directory { +public: +	typedef struct drive { +		int number; +		std::string name; +	} drive_t; + +	typedef std::list<std::string> EntryList; +	typedef std::list<drive> DriveList; + +	Directory(std::string path); +	~Directory(); + +	std::string seperator(); + +	size_t count(); +	void refresh(); +	std::string path(); +	bool cdUp(); +	bool cd(std::string dir); +	bool isDir(); +	void setPath(std::string path); +	bool fileExists(std::string file); + +	// Add filter, ie. directories or files only +	EntryList entryList(); + +	//void setSorting(); + +	static std::string cwd(); +	static std::string root(); +	static std::string root(std::string path); +	static std::string cleanPath(std::string path); +	static Directory::EntryList listFiles(std::string path, unsigned char filter = 0); +	static bool isRoot(std::string path); +	static Directory::DriveList drives(); +	static bool isDir(std::string path); +	static bool isHidden(std::string entry); +	static bool exists(std::string path); +	static std::string pathDirectory(std::string filepath); + +private: +	std::string _path; +	EntryList _files; +	DriveList _drives; + +	typedef std::list<std::string> Path; +	static Path parsePath(std::string path); +	static std::string pathToStr(Path &path); +}; diff --git a/src/drumkitloader.cc b/src/drumkitloader.cc index 91e3dd8..6a4c9f4 100644 --- a/src/drumkitloader.cc +++ b/src/drumkitloader.cc @@ -36,6 +36,7 @@  #include "dgxmlparser.h"  #include "path.h"  #include "domloader.h" +#include "directory.h"  #define REFSFILE "refs.conf" @@ -218,6 +219,12 @@ bool DrumKitLoader::loadkit(const std::string& file)  	settings.drumkit_description = kit.getDescription();  	settings.drumkit_version = kit.getVersion();  	settings.drumkit_samplerate = kit.getSamplerate(); +	// only load the default midi map if there is one and no midimap is selected yet +	if (drumkitdom.metadata.default_midimap_file != "" && settings.midimap_file == "") +	{ +		const std::string drumkit_path = Directory::pathDirectory(settings.drumkit_file); +		settings.midimap_file = drumkit_path + "/" + drumkitdom.metadata.default_midimap_file; +	}  	loadKitAudio(kit); | 
