diff --git a/qmlui/inputoutputmanager.cpp b/qmlui/inputoutputmanager.cpp
index 83809a3e5f..f338fe9722 100644
--- a/qmlui/inputoutputmanager.cpp
+++ b/qmlui/inputoutputmanager.cpp
@@ -29,6 +29,7 @@
#include "outputpatch.h"
#include "inputpatch.h"
#include "universe.h"
+#include "qlcfile.h"
#include "tardis.h"
#include "doc.h"
@@ -560,33 +561,9 @@ int InputOutputManager::outputPatchesCount(int universe) const
* Input Profiles
*********************************************************************/
-QVariant InputOutputManager::universeInputProfiles(int universe)
+QString InputOutputManager::profileUserFolder()
{
- QVariantList profilesList;
- QStringList profileNames = m_ioMap->profileNames();
- profileNames.sort();
- QDir pSysPath = m_ioMap->systemProfileDirectory();
-
- foreach (QString name, profileNames)
- {
- QLCInputProfile *ip = m_ioMap->profile(name);
- if (ip != nullptr)
- {
- QString type = ip->typeToString(ip->type());
- QVariantMap profileMap;
- profileMap.insert("universe", universe);
- profileMap.insert("name", name);
- profileMap.insert("line", name);
- profileMap.insert("plugin", type);
- if (ip->path().startsWith(pSysPath.absolutePath()))
- profileMap.insert("isUser", false);
- else
- profileMap.insert("isUser", true);
- profilesList.append(profileMap);
- }
- }
-
- return QVariant::fromValue(profilesList);
+ return m_ioMap->userProfileDirectory().absolutePath();
}
void InputOutputManager::createInputProfile()
@@ -626,6 +603,23 @@ bool InputOutputManager::editInputProfile(QString name)
return true;
}
+bool InputOutputManager::saveInputProfile()
+{
+ if (m_editProfile == nullptr)
+ return false;
+
+ QDir dir(InputOutputMap::userProfileDirectory());
+ QString absPath = QString("%1/%2-%3%4").arg(dir.absolutePath())
+ .arg(m_editProfile->manufacturer())
+ .arg(m_editProfile->model())
+ .arg(KExtInputProfile);
+
+ m_editProfile->saveXML(absPath);
+ m_profileEditor->setModified(false);
+
+ return true;
+}
+
void InputOutputManager::finishInputProfile()
{
if (m_editProfile != nullptr)
@@ -641,6 +635,35 @@ void InputOutputManager::finishInputProfile()
}
}
+QVariant InputOutputManager::universeInputProfiles(int universe)
+{
+ QVariantList profilesList;
+ QStringList profileNames = m_ioMap->profileNames();
+ profileNames.sort();
+ QDir pSysPath = m_ioMap->systemProfileDirectory();
+
+ foreach (QString name, profileNames)
+ {
+ QLCInputProfile *ip = m_ioMap->profile(name);
+ if (ip != nullptr)
+ {
+ QString type = ip->typeToString(ip->type());
+ QVariantMap profileMap;
+ profileMap.insert("universe", universe);
+ profileMap.insert("name", name);
+ profileMap.insert("line", name);
+ profileMap.insert("plugin", type);
+ if (ip->path().startsWith(pSysPath.absolutePath()))
+ profileMap.insert("isUser", false);
+ else
+ profileMap.insert("isUser", true);
+ profilesList.append(profileMap);
+ }
+ }
+
+ return QVariant::fromValue(profilesList);
+}
+
/*********************************************************************
* Beats
*********************************************************************/
diff --git a/qmlui/inputoutputmanager.h b/qmlui/inputoutputmanager.h
index c51745d504..3c11c60cd5 100644
--- a/qmlui/inputoutputmanager.h
+++ b/qmlui/inputoutputmanager.h
@@ -53,6 +53,8 @@ class InputOutputManager : public PreviewContext
Q_PROPERTY(QString beatType READ beatType WRITE setBeatType NOTIFY beatTypeChanged)
Q_PROPERTY(int bpmNumber READ bpmNumber WRITE setBpmNumber NOTIFY bpmNumberChanged)
+ Q_PROPERTY(QString profileUserFolder READ profileUserFolder CONSTANT)
+
public:
InputOutputManager(QQuickView *view, Doc *doc, QObject *parent = 0);
@@ -147,10 +149,13 @@ protected slots:
* Input Profiles
*********************************************************************/
public:
- Q_INVOKABLE QVariant universeInputProfiles(int universe);
+ QString profileUserFolder();
+
Q_INVOKABLE void createInputProfile();
Q_INVOKABLE bool editInputProfile(QString name);
+ Q_INVOKABLE bool saveInputProfile();
Q_INVOKABLE void finishInputProfile();
+ Q_INVOKABLE QVariant universeInputProfiles(int universe);
private:
InputProfileEditor *m_profileEditor;
diff --git a/qmlui/inputprofileeditor.cpp b/qmlui/inputprofileeditor.cpp
index 5a5edb21e0..59404a11ea 100644
--- a/qmlui/inputprofileeditor.cpp
+++ b/qmlui/inputprofileeditor.cpp
@@ -60,7 +60,7 @@ QString InputProfileEditor::manufacturer() const
void InputProfileEditor::setManufacturer(const QString &newManufacturer)
{
- if (m_profile == nullptr)
+ if (m_profile == nullptr || m_profile->manufacturer() == newManufacturer)
return;
m_profile->setManufacturer(newManufacturer);
@@ -75,7 +75,7 @@ QString InputProfileEditor::model() const
void InputProfileEditor::setModel(const QString &newModel)
{
- if (m_profile == nullptr)
+ if (m_profile == nullptr || m_profile->model() == newModel)
return;
m_profile->setModel(newModel);
@@ -90,7 +90,7 @@ int InputProfileEditor::type()
void InputProfileEditor::setType(const int &newType)
{
- if (m_profile == nullptr)
+ if (m_profile == nullptr || m_profile->type() == newType)
return;
m_profile->setType(QLCInputProfile::Type(newType));
diff --git a/qmlui/qml/fixtureeditor/qmldir b/qmlui/qml/fixtureeditor/qmldir
index dda90f89dd..1696a64b84 100644
--- a/qmlui/qml/fixtureeditor/qmldir
+++ b/qmlui/qml/fixtureeditor/qmldir
@@ -7,6 +7,7 @@ ColorToolFull 0.1 ../ColorToolFull.qml
ContextMenuEntry 0.1 ../ContextMenuEntry.qml
CustomCheckBox 0.1 ../CustomCheckBox.qml
CustomComboBox 0.1 ../CustomComboBox.qml
+CustomPopupDialog 0.1 ../popup/CustomPopupDialog.qml
CustomScrollBar 0.1 ../CustomScrollBar.qml
CustomSpinBox 0.1 ../CustomSpinBox.qml
CustomTextEdit 0.1 ../CustomTextEdit.qml
diff --git a/qmlui/qml/inputoutput/InputProfileEditor.qml b/qmlui/qml/inputoutput/InputProfileEditor.qml
index 02a07a6a80..088fa4b495 100644
--- a/qmlui/qml/inputoutput/InputProfileEditor.qml
+++ b/qmlui/qml/inputoutput/InputProfileEditor.qml
@@ -29,6 +29,49 @@ ColumnLayout
{
id: peContainer
+ property bool isEditing: false
+
+ function showWarning()
+ {
+ messagePopup.message = qsTr("You are trying to edit a bundled input profile.
" +
+ "If you modify and save it, a new file will be stored in
" +
+ ioManager.profileUserFolder + "
and will override the bundled file.")
+ messagePopup.standardButtons = Dialog.Ok
+ messagePopup.open()
+ }
+
+ function showSaveFirst()
+ {
+ messagePopup.message = qsTr("Do you wish to save the current profile first?\nChanges will be lost if you don't save them.")
+ messagePopup.standardButtons = Dialog.Yes | Dialog.No | Dialog.Cancel
+ messagePopup.open()
+ }
+
+ CustomPopupDialog
+ {
+ id: messagePopup
+ standardButtons: Dialog.Ok
+ title: qsTr("!! Warning !!")
+
+ onClicked:
+ {
+ if (role === Dialog.Yes)
+ {
+ // todo save
+ }
+ else if (role === Dialog.No)
+ {
+ ioManager.finishInputProfile()
+ isEditing = false
+ close()
+ }
+ else if (role === Dialog.Ok || role === Dialog.Cancel)
+ {
+ close()
+ }
+ }
+ }
+
Rectangle
{
implicitWidth: peContainer.width
diff --git a/qmlui/qml/inputoutput/ProfilesList.qml b/qmlui/qml/inputoutput/ProfilesList.qml
index 0120e490d4..f0c7f148c0 100644
--- a/qmlui/qml/inputoutput/ProfilesList.qml
+++ b/qmlui/qml/inputoutput/ProfilesList.qml
@@ -31,7 +31,6 @@ Rectangle
color: "transparent"
property int universeIndex: 0
- property bool isEditing: false
onUniverseIndexChanged:
{
@@ -72,26 +71,26 @@ Rectangle
{
width: height
height: topBar.height - 2
- visible: isEditing
- enabled: isEditing && profileEditor.modified
+ visible: profEditor.isEditing
+ enabled: profEditor.isEditing && profileEditor.modified
imgSource: "qrc:/filesave.svg"
tooltip: qsTr("Save this profile")
- onClicked: { }
+ onClicked: ioManager.saveInputProfile()
}
IconButton
{
width: height
height: topBar.height - 2
- visible: isEditing
+ visible: profEditor.isEditing
checkable: true
imgSource: "qrc:/wizard.svg"
tooltip: qsTr("Toggle the automatic detection procedure")
onToggled:
{
- if (isEditing)
+ if (profEditor.isEditing)
profileEditor.toggleDetection()
}
}
@@ -101,18 +100,18 @@ Rectangle
width: height
height: topBar.height - 2
imgSource: "qrc:/add.svg"
- tooltip: isEditing ? qsTr("Add a new channel") : qsTr("Create a new input profile")
+ tooltip: profEditor.isEditing ? qsTr("Add a new channel") : qsTr("Create a new input profile")
onClicked:
{
- if (isEditing)
+ if (profEditor.isEditing)
{
}
else
{
ioManager.createInputProfile()
- isEditing = true
+ profEditor.isEditing = true
}
}
}
@@ -122,19 +121,21 @@ Rectangle
width: height
height: topBar.height - 2
imgSource: "qrc:/edit.svg"
- tooltip: isEditing ? qsTr("Edit the selected channel") : qsTr("Edit the selected input profile")
+ tooltip: profEditor.isEditing ? qsTr("Edit the selected channel") : qsTr("Edit the selected input profile")
enabled: profListView.selectedIndex >= 0
onClicked:
{
- if (isEditing)
+ if (profEditor.isEditing)
{
}
else
{
ioManager.editInputProfile(profListView.selectedName)
- isEditing = true
+ profEditor.isEditing = true
+ if (profListView.selectedIsUser == false)
+ profEditor.showWarning()
}
}
}
@@ -144,8 +145,8 @@ Rectangle
width: height
height: topBar.height - 2
imgSource: "qrc:/remove.svg"
- tooltip: isEditing ? qsTr("Delete the selected channel") : qsTr("Delete the selected input profile(s)")
- enabled: profListView.selectedIndex >= 0
+ tooltip: profEditor.isEditing ? qsTr("Delete the selected channel") : qsTr("Delete the selected input profile(s)")
+ enabled: profListView.selectedIndex >= 0 && profListView.selectedIsUser
onClicked: { }
}
@@ -156,15 +157,21 @@ Rectangle
{
width: height
height: topBar.height - 2
- visible: isEditing
+ visible: profEditor.isEditing
border.color: UISettings.bgMedium
useFontawesome: true
label: FontAwesome.fa_times
onClicked:
{
- // todo popup for unsaved changes
- ioManager.finishInputProfile()
- isEditing = false
+ if (profileEditor.modified)
+ {
+ profEditor.showSaveFirst()
+ }
+ else
+ {
+ ioManager.finishInputProfile()
+ profEditor.isEditing = false
+ }
}
}
}
@@ -177,10 +184,11 @@ Rectangle
Layout.fillHeight: true
z: 1
boundsBehavior: Flickable.StopAtBounds
- visible: !isEditing
+ visible: !profEditor.isEditing
property int selectedIndex: -1
property string selectedName
+ property bool selectedIsUser: false
delegate:
Item
@@ -202,6 +210,7 @@ Rectangle
{
profListView.selectedIndex = index
profListView.selectedName = profileItem.lineName
+ profListView.selectedIsUser = modelData.isUser
}
onReleased:
@@ -269,6 +278,7 @@ Rectangle
InputProfileEditor
{
+ id: profEditor
width: profilesContainer.width
Layout.fillHeight: true
visible: isEditing
diff --git a/qmlui/qml/inputoutput/qmldir b/qmlui/qml/inputoutput/qmldir
index 27225cf5d4..9043f321ba 100644
--- a/qmlui/qml/inputoutput/qmldir
+++ b/qmlui/qml/inputoutput/qmldir
@@ -4,6 +4,7 @@ singleton FontAwesome 1.0 ../FontAwesomeVariables.qml
ContextMenuEntry 0.1 ../ContextMenuEntry.qml
CustomCheckBox 0.1 ../CustomCheckBox.qml
CustomComboBox 0.1 ../CustomComboBox.qml
+CustomPopupDialog 0.1 ../popup/CustomPopupDialog.qml
CustomSpinBox 0.1 ../CustomSpinBox.qml
CustomScrollBar 0.1 ../CustomScrollBar.qml
CustomTextEdit 0.1 ../CustomTextEdit.qml