diff --git a/src/translations/ar.po b/src/translations/ar.po
index e6d24ceee..333f180ed 100644
--- a/src/translations/ar.po
+++ b/src/translations/ar.po
@@ -1242,12 +1242,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr ""
diff --git a/src/translations/cs.po b/src/translations/cs.po
index 96c8f25af..3972c5999 100644
--- a/src/translations/cs.po
+++ b/src/translations/cs.po
@@ -1248,12 +1248,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Zkopírovat do knihovny..."
diff --git a/src/translations/da.po b/src/translations/da.po
index bd137ea00..db0938a0a 100644
--- a/src/translations/da.po
+++ b/src/translations/da.po
@@ -1251,12 +1251,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Kopiér til bibliotek..."
diff --git a/src/translations/de.po b/src/translations/de.po
index 131976e0e..1f8620524 100644
--- a/src/translations/de.po
+++ b/src/translations/de.po
@@ -1252,12 +1252,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "In die Musiksammlung kopieren..."
diff --git a/src/translations/el.po b/src/translations/el.po
index d844e3608..495109434 100644
--- a/src/translations/el.po
+++ b/src/translations/el.po
@@ -1254,12 +1254,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Αντιγραφή στην βιβλιοθήκη..."
diff --git a/src/translations/en_CA.po b/src/translations/en_CA.po
index 55dd473ca..80cae077a 100644
--- a/src/translations/en_CA.po
+++ b/src/translations/en_CA.po
@@ -1249,12 +1249,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Copy to library..."
diff --git a/src/translations/en_GB.po b/src/translations/en_GB.po
index 47799b2c7..a3566e817 100644
--- a/src/translations/en_GB.po
+++ b/src/translations/en_GB.po
@@ -1246,12 +1246,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Copy to library..."
diff --git a/src/translations/es.po b/src/translations/es.po
index 9698ce8d5..d1e5d9983 100644
--- a/src/translations/es.po
+++ b/src/translations/es.po
@@ -1260,12 +1260,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Copiar a la colección..."
diff --git a/src/translations/fi.po b/src/translations/fi.po
index 2f4704f2f..2bfb20ab7 100644
--- a/src/translations/fi.po
+++ b/src/translations/fi.po
@@ -1242,12 +1242,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Kopioi kirjastoon"
diff --git a/src/translations/fr.po b/src/translations/fr.po
index 709607ffb..c6ba40fa0 100644
--- a/src/translations/fr.po
+++ b/src/translations/fr.po
@@ -1256,12 +1256,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Copier dans la bilbiothèque..."
diff --git a/src/translations/gl.po b/src/translations/gl.po
index 65aeeaccd..e137565ab 100644
--- a/src/translations/gl.po
+++ b/src/translations/gl.po
@@ -1244,12 +1244,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Copiar para a biblioteca"
diff --git a/src/translations/it.po b/src/translations/it.po
index 7af23a11e..44e56e899 100644
--- a/src/translations/it.po
+++ b/src/translations/it.po
@@ -1257,12 +1257,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Copia nella raccolta..."
diff --git a/src/translations/kk.po b/src/translations/kk.po
index 1ba56275b..abf389e90 100644
--- a/src/translations/kk.po
+++ b/src/translations/kk.po
@@ -1244,12 +1244,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr ""
diff --git a/src/translations/nb.po b/src/translations/nb.po
index cf764846c..2abb8fb39 100644
--- a/src/translations/nb.po
+++ b/src/translations/nb.po
@@ -1248,12 +1248,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Kopier til bibliotek..."
diff --git a/src/translations/oc.po b/src/translations/oc.po
index 770161e9b..3371876f0 100644
--- a/src/translations/oc.po
+++ b/src/translations/oc.po
@@ -1242,12 +1242,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr ""
diff --git a/src/translations/pl.po b/src/translations/pl.po
index 84c64fe17..37362c931 100644
--- a/src/translations/pl.po
+++ b/src/translations/pl.po
@@ -1246,12 +1246,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Skopiuj do biblioteki..."
diff --git a/src/translations/pt.po b/src/translations/pt.po
index ad6cb0ff2..aa5d53758 100644
--- a/src/translations/pt.po
+++ b/src/translations/pt.po
@@ -1251,12 +1251,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Copiar para a biblioteca..."
diff --git a/src/translations/pt_BR.po b/src/translations/pt_BR.po
index 3dd7f78d7..f50eb2855 100644
--- a/src/translations/pt_BR.po
+++ b/src/translations/pt_BR.po
@@ -1254,12 +1254,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Copiar para biblioteca..."
diff --git a/src/translations/ro.po b/src/translations/ro.po
index c98f58b95..eb571235f 100644
--- a/src/translations/ro.po
+++ b/src/translations/ro.po
@@ -1243,12 +1243,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Copiază în bibliotecă..."
diff --git a/src/translations/ru.po b/src/translations/ru.po
index 3ed0ede2d..daee89911 100644
--- a/src/translations/ru.po
+++ b/src/translations/ru.po
@@ -1251,12 +1251,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Копировать в коллекцию..."
diff --git a/src/translations/sk.po b/src/translations/sk.po
index 221d5d404..0924822b8 100644
--- a/src/translations/sk.po
+++ b/src/translations/sk.po
@@ -1251,12 +1251,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Skopírovať do zbierky..."
diff --git a/src/translations/sv.po b/src/translations/sv.po
index 7827def5c..7e5649c38 100644
--- a/src/translations/sv.po
+++ b/src/translations/sv.po
@@ -1251,12 +1251,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr "Kopiera till bibliotek..."
diff --git a/src/translations/tr.po b/src/translations/tr.po
index 8d3b24ed8..7c015aa59 100644
--- a/src/translations/tr.po
+++ b/src/translations/tr.po
@@ -1242,12 +1242,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr ""
diff --git a/src/translations/translations.pot b/src/translations/translations.pot
index 621218415..c8afec6f4 100644
--- a/src/translations/translations.pot
+++ b/src/translations/translations.pot
@@ -1233,12 +1233,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr ""
diff --git a/src/translations/zh_CN.po b/src/translations/zh_CN.po
index 856d8cd62..41b7f8e75 100644
--- a/src/translations/zh_CN.po
+++ b/src/translations/zh_CN.po
@@ -1242,12 +1242,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr ""
diff --git a/src/translations/zh_TW.po b/src/translations/zh_TW.po
index a42debd9b..f0ff7a0f6 100644
--- a/src/translations/zh_TW.po
+++ b/src/translations/zh_TW.po
@@ -1242,12 +1242,36 @@ msgstr ""
msgid "High (1024x1024)"
msgstr ""
+msgid "Select visualisations..."
+msgstr ""
+
msgid "Close visualisation"
msgstr ""
+msgid "Select All"
+msgstr ""
+
+msgid "Select None"
+msgstr ""
+
msgid "Visualisations Settings"
msgstr ""
+msgid "Select visualisations"
+msgstr ""
+
+msgid "Visualisation mode"
+msgstr ""
+
+msgid "Random visualisation"
+msgstr ""
+
+msgid "Choose from the list"
+msgstr ""
+
+msgid "Delay between visualisations"
+msgstr ""
+
msgid "Copy to library..."
msgstr ""
diff --git a/src/visualisations/CMakeLists.txt b/src/visualisations/CMakeLists.txt
index 567077183..efc196fe8 100644
--- a/src/visualisations/CMakeLists.txt
+++ b/src/visualisations/CMakeLists.txt
@@ -4,19 +4,24 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
include_directories("../../3rdparty/libprojectm")
set(SOURCES
+ projectmpresetmodel.cpp
projectmvisualisation.cpp
visualisationcontainer.cpp
visualisationoverlay.cpp
+ visualisationselector.cpp
)
set(HEADERS
+ projectmpresetmodel.h
projectmvisualisation.h
visualisationcontainer.h
visualisationoverlay.h
+ visualisationselector.h
)
set(UI
visualisationoverlay.ui
+ visualisationselector.ui
)
qt4_wrap_cpp(MOC ${HEADERS})
diff --git a/src/visualisations/projectmpresetmodel.cpp b/src/visualisations/projectmpresetmodel.cpp
new file mode 100644
index 000000000..6c3e36cd9
--- /dev/null
+++ b/src/visualisations/projectmpresetmodel.cpp
@@ -0,0 +1,92 @@
+/* This file is part of Clementine.
+
+ Clementine is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Clementine 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Clementine. If not, see .
+*/
+
+#include "projectmpresetmodel.h"
+#include "projectmvisualisation.h"
+
+#include
+
+#include
+
+ProjectMPresetModel::ProjectMPresetModel(ProjectMVisualisation* vis, QObject *parent)
+ : QAbstractItemModel(parent),
+ vis_(vis)
+{
+}
+
+int ProjectMPresetModel::rowCount(const QModelIndex&) const {
+ if (!vis_)
+ return 0;
+ return vis_->projectm()->getPlaylistSize();
+}
+
+int ProjectMPresetModel::columnCount(const QModelIndex&) const {
+ return 1;
+}
+
+QModelIndex ProjectMPresetModel::index(int row, int column, const QModelIndex&) const {
+ return createIndex(row, column);
+}
+
+QModelIndex ProjectMPresetModel::parent(const QModelIndex &child) const {
+ return QModelIndex();
+}
+
+QVariant ProjectMPresetModel::data(const QModelIndex &index, int role) const {
+ switch (role) {
+ case Qt::DisplayRole:
+ return QString::fromStdString(vis_->projectm()->getPresetName(index.row()));
+ case Qt::CheckStateRole: {
+ bool selected = vis_->is_selected(index.row());
+ return selected ? Qt::Checked : Qt::Unchecked;
+ }
+ case Role_Url:
+ return QString::fromStdString(vis_->projectm()->getPresetURL(index.row()));
+ default:
+ return QVariant();
+ }
+}
+
+Qt::ItemFlags ProjectMPresetModel::flags(const QModelIndex &index) const {
+ if (!index.isValid())
+ return QAbstractItemModel::flags(index);
+ return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsUserCheckable |
+ Qt::ItemIsEnabled;
+}
+
+bool ProjectMPresetModel::setData(const QModelIndex &index,
+ const QVariant &value, int role) {
+ if (role == Qt::CheckStateRole) {
+ vis_->set_selected(index.row(), value.toBool());
+ return true;
+ }
+ return false;
+}
+
+void ProjectMPresetModel::SetImmediatePreset(const QModelIndex& index) {
+ vis_->projectm()->selectPreset(index.row(), true);
+}
+
+void ProjectMPresetModel::SelectAll() {
+ vis_->set_all_selected(true);
+ emit dataChanged(index(0, 0), index(rowCount()-1, 0));
+}
+
+void ProjectMPresetModel::SelectNone() {
+ vis_->set_all_selected(false);
+ emit dataChanged(index(0, 0), index(rowCount()-1, 0));
+}
+
diff --git a/src/visualisations/projectmpresetmodel.h b/src/visualisations/projectmpresetmodel.h
new file mode 100644
index 000000000..acfd76995
--- /dev/null
+++ b/src/visualisations/projectmpresetmodel.h
@@ -0,0 +1,52 @@
+/* This file is part of Clementine.
+
+ Clementine is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Clementine 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Clementine. If not, see .
+*/
+
+#ifndef PROJECTMPRESETMODEL_H
+#define PROJECTMPRESETMODEL_H
+
+#include
+
+class ProjectMVisualisation;
+
+class ProjectMPresetModel : public QAbstractItemModel {
+ Q_OBJECT
+
+public:
+ ProjectMPresetModel(ProjectMVisualisation* vis, QObject* parent = 0);
+
+ enum {
+ Role_Url = Qt::UserRole,
+ };
+
+ // QAbstractItemModel
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex &child) const;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+
+public slots:
+ void SetImmediatePreset(const QModelIndex& index);
+ void SelectAll();
+ void SelectNone();
+
+private:
+ ProjectMVisualisation* vis_;
+};
+
+#endif // PROJECTMPRESETMODEL_H
diff --git a/src/visualisations/projectmvisualisation.cpp b/src/visualisations/projectmvisualisation.cpp
index 3aeaf0b20..29f0b60c3 100644
--- a/src/visualisations/projectmvisualisation.cpp
+++ b/src/visualisations/projectmvisualisation.cpp
@@ -15,6 +15,7 @@
*/
#include "projectmvisualisation.h"
+#include "visualisationcontainer.h"
#include
#include
@@ -22,6 +23,7 @@
#include
#include
#include
+#include
#include
#include
@@ -29,6 +31,7 @@
ProjectMVisualisation::ProjectMVisualisation(QObject *parent)
: QGraphicsScene(parent),
projectm_(NULL),
+ mode_(0),
texture_size_(512)
{
connect(this, SIGNAL(sceneRectChanged(QRectF)), SLOT(SceneRectChanged(QRectF)));
@@ -43,6 +46,7 @@ void ProjectMVisualisation::drawBackground(QPainter* p, const QRectF&) {
if (!projectm_) {
projectm_.reset(new projectM("/usr/share/projectM/config.inp"));
projectm_->changeTextureSize(texture_size_);
+ Load();
}
projectm_->projectM_resetGL(sceneRect().width(), sceneRect().height());
@@ -71,3 +75,62 @@ void ProjectMVisualisation::ConsumeBuffer(GstBuffer *buffer, GstEnginePipeline*)
projectm_->pcm()->addPCM16Data(data, samples_per_channel);
gst_buffer_unref(buffer);
}
+
+void ProjectMVisualisation::set_selected(int preset, bool selected) {
+ if (selected)
+ selected_indices_.insert(preset);
+ else
+ selected_indices_.remove(preset);
+
+ Save();
+}
+
+void ProjectMVisualisation::set_all_selected(bool selected) {
+ selected_indices_.clear();
+ if (selected) {
+ int count = projectm_->getPlaylistSize();
+ for (int i=0 ; igetPlaylistSize();
+ selected_indices_.clear();
+
+ if (presets.isEmpty()) {
+ for (int i=0 ; i
#include
+#include
#include
@@ -32,6 +33,16 @@ public:
ProjectMVisualisation(QObject *parent = 0);
~ProjectMVisualisation();
+ projectM* projectm() const { return projectm_.get(); }
+
+ QSet selected_indices() const { return selected_indices_; }
+ bool is_selected(int preset) { return selected_indices_.contains(preset); }
+ void set_selected(int preset, bool selected);
+ void set_all_selected(bool selected);
+
+ int mode() const { return mode_; }
+ void set_mode(int mode);
+
// BufferConsumer
void ConsumeBuffer(GstBuffer *buffer, GstEnginePipeline*);
@@ -45,8 +56,14 @@ protected:
private slots:
void SceneRectChanged(const QRectF& rect);
+private:
+ void Load();
+ void Save();
+
private:
boost::scoped_ptr projectm_;
+ int mode_;
+ QSet selected_indices_;
int texture_size_;
};
diff --git a/src/visualisations/visualisationcontainer.cpp b/src/visualisations/visualisationcontainer.cpp
index b67fabfd1..2a7cc6829 100644
--- a/src/visualisations/visualisationcontainer.cpp
+++ b/src/visualisations/visualisationcontainer.cpp
@@ -17,6 +17,7 @@
#include "projectmvisualisation.h"
#include "visualisationcontainer.h"
#include "visualisationoverlay.h"
+#include "visualisationselector.h"
#include "engines/gstengine.h"
#include "ui/iconloader.h"
@@ -41,6 +42,8 @@ VisualisationContainer::VisualisationContainer(QWidget *parent)
engine_(NULL),
vis_(new ProjectMVisualisation(this)),
overlay_(new VisualisationOverlay),
+ selector_(new VisualisationSelector(this)),
+ overlay_proxy_(NULL),
menu_(new QMenu(this)),
fps_(kDefaultFps),
size_(kDefaultTextureSize)
@@ -73,6 +76,9 @@ VisualisationContainer::VisualisationContainer(QWidget *parent)
SizeChanged();
vis_->SetTextureSize(size_);
+ // Selector
+ selector_->SetVisualisation(vis_);
+
// Settings menu
menu_->addAction(IconLoader::Load("view-fullscreen"), tr("Toggle fullscreen"),
this, SLOT(ToggleFullscreen()));
@@ -96,6 +102,8 @@ VisualisationContainer::VisualisationContainer(QWidget *parent)
quality_menu->addActions(quality_group->actions());
connect(quality_mapper, SIGNAL(mapped(int)), SLOT(SetQuality(int)));
+ menu_->addAction(tr("Select visualisations..."), selector_, SLOT(show()));
+
menu_->addSeparator();
menu_->addAction(IconLoader::Load("application-exit"), tr("Close visualisation"),
this, SLOT(hide()));
diff --git a/src/visualisations/visualisationcontainer.h b/src/visualisations/visualisationcontainer.h
index 030f6c604..ce0c11586 100644
--- a/src/visualisations/visualisationcontainer.h
+++ b/src/visualisations/visualisationcontainer.h
@@ -25,6 +25,7 @@
class GstEngine;
class ProjectMVisualisation;
class VisualisationOverlay;
+class VisualisationSelector;
class QMenu;
class QSignalMapper;
@@ -81,6 +82,8 @@ private:
VisualisationOverlay* overlay_;
QBasicTimer update_timer_;
+ VisualisationSelector* selector_;
+
QGraphicsProxyWidget* overlay_proxy_;
QMenu* menu_;
diff --git a/src/visualisations/visualisationselector.cpp b/src/visualisations/visualisationselector.cpp
new file mode 100644
index 000000000..d071d5b6f
--- /dev/null
+++ b/src/visualisations/visualisationselector.cpp
@@ -0,0 +1,68 @@
+/* This file is part of Clementine.
+
+ Clementine is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Clementine 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Clementine. If not, see .
+*/
+
+#include "projectmpresetmodel.h"
+#include "projectmvisualisation.h"
+#include "visualisationselector.h"
+#include "ui_visualisationselector.h"
+
+#include
+
+VisualisationSelector::VisualisationSelector(QWidget *parent)
+ : QDialog(parent),
+ ui_(new Ui_VisualisationSelector),
+ vis_(NULL),
+ preset_model_(NULL)
+{
+ ui_->setupUi(this);
+
+ QPushButton* select_all =
+ ui_->buttonBox->addButton(tr("Select All"), QDialogButtonBox::ActionRole);
+ QPushButton* select_none =
+ ui_->buttonBox->addButton(tr("Select None"), QDialogButtonBox::ActionRole);
+ connect(select_all, SIGNAL(clicked()), SLOT(SelectAll()));
+ connect(select_none, SIGNAL(clicked()), SLOT(SelectNone()));
+
+ connect(ui_->mode, SIGNAL(currentIndexChanged(int)), SLOT(ModeChanged(int)));
+}
+
+VisualisationSelector::~VisualisationSelector() {
+ delete ui_;
+}
+
+void VisualisationSelector::showEvent(QShowEvent *) {
+ if (!ui_->list->model()) {
+ preset_model_ = new ProjectMPresetModel(vis_, this);
+ ui_->list->setModel(preset_model_);
+ connect(ui_->list->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ preset_model_, SLOT(SetImmediatePreset(QModelIndex)));
+
+ ui_->mode->setCurrentIndex(vis_->mode());
+ }
+}
+
+void VisualisationSelector::ModeChanged(int mode) {
+ ui_->list->setEnabled(mode == 1);
+ vis_->set_mode(mode);
+}
+
+void VisualisationSelector::SelectAll() {
+ preset_model_->SelectAll();
+}
+
+void VisualisationSelector::SelectNone() {
+ preset_model_->SelectNone();
+}
diff --git a/src/visualisations/visualisationselector.h b/src/visualisations/visualisationselector.h
new file mode 100644
index 000000000..d1c845f73
--- /dev/null
+++ b/src/visualisations/visualisationselector.h
@@ -0,0 +1,49 @@
+/* This file is part of Clementine.
+
+ Clementine is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Clementine 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Clementine. If not, see .
+*/
+
+#ifndef VISUALISATIONSELECTOR_H
+#define VISUALISATIONSELECTOR_H
+
+#include
+
+class ProjectMPresetModel;
+class ProjectMVisualisation;
+class Ui_VisualisationSelector;
+
+class VisualisationSelector : public QDialog {
+ Q_OBJECT
+public:
+ VisualisationSelector(QWidget* parent = 0);
+ ~VisualisationSelector();
+
+ void SetVisualisation(ProjectMVisualisation* vis) { vis_ = vis; }
+
+protected:
+ void showEvent(QShowEvent *);
+
+private slots:
+ void ModeChanged(int mode);
+ void SelectAll();
+ void SelectNone();
+
+private:
+ Ui_VisualisationSelector* ui_;
+ ProjectMVisualisation* vis_;
+
+ ProjectMPresetModel* preset_model_;
+};
+
+#endif // VISUALISATIONSELECTOR_H
diff --git a/src/visualisations/visualisationselector.ui b/src/visualisations/visualisationselector.ui
new file mode 100644
index 000000000..89c4c8432
--- /dev/null
+++ b/src/visualisations/visualisationselector.ui
@@ -0,0 +1,134 @@
+
+
+ VisualisationSelector
+
+
+
+ 0
+ 0
+ 595
+ 475
+
+
+
+ Select visualisations
+
+
+ -
+
+
-
+
+
+ Visualisation mode
+
+
+
+ -
+
+
-
+
+ Random visualisation
+
+
+ -
+
+ Choose from the list
+
+
+
+
+ -
+
+
+ Delay between visualisations
+
+
+
+ -
+
+
+ seconds
+
+
+ 2
+
+
+ 120
+
+
+ 15
+
+
+
+
+
+ -
+
+
+ false
+
+
+ true
+
+
+ QAbstractItemView::SelectRows
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Ok
+
+
+
+
+
+
+ mode
+ delay
+ list
+ buttonBox
+
+
+
+
+ buttonBox
+ accepted()
+ VisualisationSelector
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ VisualisationSelector
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+