diff --git a/resources/ui/carla.ui b/resources/ui/carla.ui
index 6aff7a09e..56fa75916 100644
--- a/resources/ui/carla.ui
+++ b/resources/ui/carla.ui
@@ -232,6 +232,21 @@
Disk
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ Qt::ScrollBarAlwaysOn
+
+
+
+
diff --git a/source/backend/CarlaStandalone.hpp b/source/backend/CarlaStandalone.hpp
index 75ed3ed38..3d09ab7ee 100644
--- a/source/backend/CarlaStandalone.hpp
+++ b/source/backend/CarlaStandalone.hpp
@@ -152,6 +152,7 @@ struct CarlaScalePointInfo {
};
CARLA_EXPORT const char* carla_get_extended_license_text();
+CARLA_EXPORT const char* carla_get_supported_file_types();
CARLA_EXPORT unsigned int carla_get_engine_driver_count();
CARLA_EXPORT const char* carla_get_engine_driver_name(unsigned int index);
diff --git a/source/backend/standalone/CarlaStandalone.cpp b/source/backend/standalone/CarlaStandalone.cpp
index efadf450b..8c435c202 100644
--- a/source/backend/standalone/CarlaStandalone.cpp
+++ b/source/backend/standalone/CarlaStandalone.cpp
@@ -151,6 +151,35 @@ const char* carla_get_extended_license_text()
return retText;
}
+const char* carla_get_supported_file_types()
+{
+ static CarlaString retText;
+
+ if (retText.isEmpty())
+ {
+ // Base type
+ retText = "*.carxp";
+
+ // Sample kits
+#ifdef WANT_FLUIDSYNTH
+ retText += ";*.sf2";
+#endif
+#ifdef WANT_LINUXSAMPLER
+ retText += ";*.gig;*.sfz";
+#endif
+
+ // Special files provided by internal plugins
+#ifdef WANT_AUDIOFILE
+ retText += ";*.aac;*.flac;*.oga;*.ogg;*.mp3;*.wav";
+#endif
+#ifdef WANT_MIDIFILE
+ retText += ";*.mid;*.midi";
+#endif
+ }
+
+ return retText;
+}
+
// -------------------------------------------------------------------------------------------------------------------
unsigned int carla_get_engine_driver_count()
diff --git a/source/carla.py b/source/carla.py
index b81567770..dff6c69fe 100755
--- a/source/carla.py
+++ b/source/carla.py
@@ -19,8 +19,9 @@
# ------------------------------------------------------------------------------------------------------------
# Imports (Global)
-from PyQt4.QtCore import Qt, QPointF, QSize
-from PyQt4.QtGui import QApplication, QDialogButtonBox, QMainWindow, QResizeEvent
+from time import sleep
+from PyQt4.QtCore import Qt, QModelIndex, QPointF, QSize
+from PyQt4.QtGui import QApplication, QDialogButtonBox, QFileSystemModel, QMainWindow, QResizeEvent
# ------------------------------------------------------------------------------------------------------------
# Imports (Custom Stuff)
@@ -551,6 +552,8 @@ class CarlaMainW(QMainWindow):
self.fIdleTimerFast = 0
self.fIdleTimerSlow = 0
+ self.fLastLoadedPluginId = -1
+
#self._nsmAnnounce2str = ""
#self._nsmOpen1str = ""
#self._nsmOpen2str = ""
@@ -560,6 +563,17 @@ class CarlaMainW(QMainWindow):
# -------------------------------------------------------------
# Set-up GUI stuff
+ self.fDirModel = QFileSystemModel(self)
+ self.fDirModel.setNameFilters(cString(Carla.host.get_supported_file_types()).split(";"))
+ self.fDirModel.setRootPath(HOME)
+
+ self.ui.fileTreeView.setModel(self.fDirModel)
+ self.ui.fileTreeView.setRootIndex(self.fDirModel.index(HOME))
+ self.ui.fileTreeView.setColumnHidden(1, True)
+ self.ui.fileTreeView.setColumnHidden(2, True)
+ self.ui.fileTreeView.setColumnHidden(3, True)
+ self.ui.fileTreeView.setHeaderHidden(True)
+
self.ui.act_engine_start.setEnabled(False)
self.ui.act_engine_stop.setEnabled(False)
self.ui.act_plugin_remove_all.setEnabled(False)
@@ -635,6 +649,7 @@ class CarlaMainW(QMainWindow):
self.connect(self.ui.b_transport_play, SIGNAL("clicked(bool)"), SLOT("slot_transportPlayPause(bool)"))
self.connect(self.ui.b_transport_stop, SIGNAL("clicked()"), SLOT("slot_transportStop()"))
+ self.connect(self.ui.fileTreeView, SIGNAL("doubleClicked(QModelIndex)"), SLOT("slot_fileTreeDoubleClicked(QModelIndex)"))
self.connect(self.ui.miniCanvasPreview, SIGNAL("miniCanvasMoved(double, double)"), SLOT("slot_miniCanvasMoved(double, double)"))
self.connect(self.ui.graphicsView.horizontalScrollBar(), SIGNAL("valueChanged(int)"), SLOT("slot_horizontalScrollBarChanged(int)"))
@@ -686,6 +701,46 @@ class CarlaMainW(QMainWindow):
#else:
QTimer.singleShot(0, self, SLOT("slot_engineStart()"))
+ @pyqtSlot(QModelIndex)
+ def slot_fileTreeDoubleClicked(self, modelIndex):
+ filename = self.fDirModel.filePath(modelIndex)
+ print(filename)
+
+ if not os.path.exists(filename):
+ return
+ if not os.path.isfile(filename):
+ return
+
+ extension = filename.rsplit(".", 1)[-1].lower()
+
+ if extension == "carxp":
+ Carla.host.load_project(filename)
+
+ elif extension == "gig":
+ Carla.host.add_plugin(BINARY_NATIVE, PLUGIN_GIG, filename, None, os.path.basename(filename), None)
+
+ elif extension == "sf2":
+ Carla.host.add_plugin(BINARY_NATIVE, PLUGIN_SF2, filename, None, os.path.basename(filename), None)
+
+ elif extension == "sfz":
+ Carla.host.add_plugin(BINARY_NATIVE, PLUGIN_SFZ, filename, None, os.path.basename(filename), None)
+
+ elif extension in ("aac", "flac", "oga", "ogg", "mp3", "wav"):
+ self.fLastLoadedPluginId = -2
+ if Carla.host.add_plugin(BINARY_NATIVE, PLUGIN_INTERNAL, None, None, "audiofile", None):
+ while (self.fLastLoadedPluginId == -2): sleep(0.2)
+ idx = self.fLastLoadedPluginId
+ self.fLastLoadedPluginId = -1
+ Carla.host.set_custom_data(idx, CUSTOM_DATA_STRING, "file00", filename)
+
+ elif extension in ("mid", "midi"):
+ self.fLastLoadedPluginId = -2
+ if Carla.host.add_plugin(BINARY_NATIVE, PLUGIN_INTERNAL, None, None, "midifile", None):
+ while (self.fLastLoadedPluginId == -2): sleep(0.2)
+ idx = self.fLastLoadedPluginId
+ self.fLastLoadedPluginId = -1
+ Carla.host.set_custom_data(idx, CUSTOM_DATA_STRING, "file", filename)
+
@pyqtSlot(float)
def slot_canvasScaleChanged(self, scale):
self.ui.miniCanvasPreview.setViewScale(scale)
@@ -1052,6 +1107,9 @@ class CarlaMainW(QMainWindow):
if self.fPluginCount == 1:
self.ui.act_plugin_remove_all.setEnabled(True)
+ if self.fLastLoadedPluginId == -2:
+ self.fLastLoadedPluginId = pluginId
+
@pyqtSlot(int)
def slot_handlePluginRemovedCallback(self, pluginId):
if pluginId >= self.fPluginCount:
diff --git a/source/carla_backend.py b/source/carla_backend.py
index ad07963ee..9df65847e 100644
--- a/source/carla_backend.py
+++ b/source/carla_backend.py
@@ -152,6 +152,9 @@ class Host(object):
self.lib.carla_get_extended_license_text.argtypes = None
self.lib.carla_get_extended_license_text.restype = c_char_p
+ self.lib.carla_get_supported_file_types.argtypes = None
+ self.lib.carla_get_supported_file_types.restype = c_char_p
+
self.lib.carla_get_engine_driver_count.argtypes = None
self.lib.carla_get_engine_driver_count.restype = c_uint
@@ -376,6 +379,9 @@ class Host(object):
def get_extended_license_text(self):
return self.lib.carla_get_extended_license_text()
+ def get_supported_file_types(self):
+ return self.lib.carla_get_supported_file_types()
+
def get_engine_driver_count(self):
return self.lib.carla_get_engine_driver_count()