summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DGDOM.h1
-rw-r--r--src/Makefile.am2
-rw-r--r--src/dgxmlparser.cc5
-rw-r--r--src/directory.cc567
-rw-r--r--src/directory.h88
-rw-r--r--src/drumkitloader.cc7
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);