diff --git a/bin/qsettingstranslator.py b/bin/qsettingstranslator.py
index b533628..88166f8 100755
--- a/bin/qsettingstranslator.py
+++ b/bin/qsettingstranslator.py
@@ -21,6 +21,8 @@ def create_settings_ts(infile, outfile):
strings.append(elem.attrib["tooltip"])
if "tr" in elem.attrib and elem.attrib["tr"].lower() == "true":
strings.append(elem.text)
+ if "ztr" in elem.attrib and elem.attrib["ztr"].lower() == "true": # lazy translations
+ strings.append(elem.text)
if "trdefault" in elem.attrib and elem.attrib["trdefault"].lower() == "true":
strings.append(elem.attrib["default"])
# legaxy keys, because of a typo...
diff --git a/examples/mvvmcore/SampleCore/settings.xml b/examples/mvvmcore/SampleCore/settings.xml
index d089987..8a034c5 100644
--- a/examples/mvvmcore/SampleCore/settings.xml
+++ b/examples/mvvmcore/SampleCore/settings.xml
@@ -11,18 +11,21 @@
default="true">
property
bool
+ true
property
Enter a nice name
+ Your current name: %1
+ title="Open &system settings"
+ tooltip="Pressing this action will open the system settings">
Trigger Action
You can use this to trigger whatever kind of action you need
@@ -38,6 +41,7 @@
Variant B
Variant C
+ Current value: %1
@@ -45,9 +49,11 @@
+ tooltip="The value must be between 0 and 1"
+ default="0.0">
0.0
1.0
+ Current value: %L1
7
+ Current value: %1
@@ -90,7 +97,9 @@
+ default="42">
+ Is set to %n unit(s)
+
getDelegate(entry.type, entry.properties);
+ auto url = _factory->getDelegate(entry.type, entry.properties);
if(group.title.isEmpty()) // unnamed groups are presented first
_entries.insert(rIndex++, EntryInfo{entry, url});
else
@@ -83,6 +84,19 @@ QVariant SettingsEntryModel::data(const QModelIndex &index, int role) const
return entry.group.title;
case SearchKeysRole:
return entry.searchKeys;
+ case PreviewRole:
+ if(entry.properties.contains(QStringLiteral("qtmvvm_preview"))) {
+ auto preview = entry.properties.value(QStringLiteral("qtmvvm_preview"));
+ if(preview.type() == QVariant::Bool)
+ return preview.toBool() ? entry.tooltip : QString{};
+ else if(preview.type() == QVariant::String) {
+ return _factory->format(entry.type,
+ preview.toString(),
+ _viewModel->loadValue(entry.key, entry.defaultValue),
+ entry.properties);
+ }
+ }
+ return QString{};
default:
return QVariant();
}
@@ -101,7 +115,7 @@ bool SettingsEntryModel::setData(const QModelIndex &index, const QVariant &value
return false;
_viewModel->saveValue(_entries.value(index.row()).key, value);
- emit dataChanged(index, index, {SettingsValueRole});
+ emit dataChanged(index, index, {SettingsValueRole, PreviewRole});
return true;
}
@@ -115,7 +129,8 @@ QHash SettingsEntryModel::roleNames() const
{ToolTipRole, "tooltip"},
{DelegateUrlRole, "delegateUrl"},
{SettingsValueRole, "inputValue"},
- {PropertiesRole, "properties"}
+ {PropertiesRole, "properties"},
+ {PreviewRole, "preview"}
};
}
@@ -133,7 +148,7 @@ void SettingsEntryModel::entryChanged(const QString &key)
for(auto i = 0; i < _entries.size(); i++) {
if(_entries[i].key == key) {
auto mIndex = index(i);
- emit dataChanged(mIndex, mIndex, {SettingsValueRole});
+ emit dataChanged(mIndex, mIndex, {SettingsValueRole, PreviewRole});
break;
}
}
diff --git a/src/imports/mvvmquick/settingsentrymodel.h b/src/imports/mvvmquick/settingsentrymodel.h
index eaf280a..95167fa 100644
--- a/src/imports/mvvmquick/settingsentrymodel.h
+++ b/src/imports/mvvmquick/settingsentrymodel.h
@@ -24,7 +24,9 @@ public:
DelegateUrlRole,
SettingsValueRole,
PropertiesRole,
- SearchKeysRole
+ SearchKeysRole,
+
+ PreviewRole
};
Q_ENUM(Roles)
@@ -53,6 +55,7 @@ private:
};
SettingsViewModel *_viewModel = nullptr;
+ InputViewFactory *_factory = nullptr;
QList _entries;
};
diff --git a/src/mvvmquick/BoolDelegate.qml b/src/mvvmquick/BoolDelegate.qml
index 8e6012b..acdd4f3 100644
--- a/src/mvvmquick/BoolDelegate.qml
+++ b/src/mvvmquick/BoolDelegate.qml
@@ -1,6 +1,7 @@
import QtQuick 2.10
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
+import de.skycoder42.QtMvvm.Quick 1.1
CheckDelegate {
id: _boolDelegate
@@ -20,6 +21,11 @@ CheckDelegate {
inputValue = checked;
}
+ ToolTip.visible: pressed && tooltip != ""
+ ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
+ ToolTip.text: tooltip
+ onPressAndHold: QuickPresenter.hapticLongPress()
+
contentItem: GridLayout {
columns: 2
rows: 2
@@ -35,11 +41,11 @@ CheckDelegate {
}
Label {
- id: _textLabel
- visible: tooltip
+ id: _peviewLabel
+ visible: preview
Layout.row: 1
Layout.column: 0
- text: tooltip
+ text: preview
wrapMode: Text.WordWrap
Layout.fillWidth: true
}
diff --git a/src/mvvmquick/ListDelegate.qml b/src/mvvmquick/ListDelegate.qml
index a548db6..5277820 100644
--- a/src/mvvmquick/ListDelegate.qml
+++ b/src/mvvmquick/ListDelegate.qml
@@ -1,6 +1,7 @@
import QtQuick 2.10
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
+import de.skycoder42.QtMvvm.Quick 1.1
ItemDelegate {
id: _listDelegate
@@ -9,6 +10,11 @@ ItemDelegate {
signal showInput(string key, string title, string type, var defaultValue, var properties);
+ ToolTip.visible: pressed && tooltip != ""
+ ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
+ ToolTip.text: tooltip
+ onPressAndHold: QuickPresenter.hapticLongPress()
+
contentItem: ColumnLayout {
Label {
id: _titleLabel
@@ -19,9 +25,9 @@ ItemDelegate {
}
Label {
- id: _textLabel
- visible: tooltip
- text: tooltip
+ id: _previewLabel
+ visible: preview
+ text: preview
wrapMode: Text.WordWrap
Layout.fillWidth: true
}
diff --git a/src/mvvmquick/MsgDelegate.qml b/src/mvvmquick/MsgDelegate.qml
index 43d354b..24ea166 100644
--- a/src/mvvmquick/MsgDelegate.qml
+++ b/src/mvvmquick/MsgDelegate.qml
@@ -1,6 +1,7 @@
import QtQuick 2.10
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
+import de.skycoder42.QtMvvm.Quick 1.1
ItemDelegate {
id: _msgDelegate
@@ -9,6 +10,11 @@ ItemDelegate {
signal showInput(string key, string title, string type, var defaultValue, var properties);
+ ToolTip.visible: pressed && tooltip != ""
+ ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
+ ToolTip.text: tooltip
+ onPressAndHold: QuickPresenter.hapticLongPress()
+
contentItem: ColumnLayout {
Label {
id: _titleLabel
@@ -19,9 +25,9 @@ ItemDelegate {
}
Label {
- id: _textLabel
- visible: tooltip
- text: tooltip
+ id: _previewLabel
+ visible: preview
+ text: preview
wrapMode: Text.WordWrap
Layout.fillWidth: true
}
diff --git a/src/mvvmquick/SwitchDelegate.qml b/src/mvvmquick/SwitchDelegate.qml
index 29fc15c..ce98814 100644
--- a/src/mvvmquick/SwitchDelegate.qml
+++ b/src/mvvmquick/SwitchDelegate.qml
@@ -1,6 +1,7 @@
import QtQuick 2.10
import QtQuick.Controls 2.3 as Controls
import QtQuick.Layouts 1.3
+import de.skycoder42.QtMvvm.Quick 1.1
Controls.SwitchDelegate {
id: _boolDelegate
@@ -20,6 +21,11 @@ Controls.SwitchDelegate {
inputValue = checked;
}
+ Controls.ToolTip.visible: pressed && tooltip != ""
+ Controls.ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
+ Controls.ToolTip.text: tooltip
+ onPressAndHold: QuickPresenter.hapticLongPress()
+
contentItem: GridLayout {
columns: 2
rows: 2
@@ -35,11 +41,11 @@ Controls.SwitchDelegate {
}
Controls.Label {
- id: _textLabel
- visible: tooltip
+ id: _previewLabel
+ visible: preview
Layout.row: 1
Layout.column: 0
- text: tooltip
+ text: preview
wrapMode: Text.WordWrap
Layout.fillWidth: true
}
diff --git a/src/mvvmquick/formatters_p.h b/src/mvvmquick/formatters_p.h
new file mode 100644
index 0000000..50e9cc8
--- /dev/null
+++ b/src/mvvmquick/formatters_p.h
@@ -0,0 +1,41 @@
+#ifndef QTMVVM_FORMATTERS_P_H
+#define QTMVVM_FORMATTERS_P_H
+
+#include
+
+#include "inputviewfactory.h"
+
+namespace QtMvvm {
+
+class IntFormatter : public Formatter
+{
+public:
+ QString format(const QString &formatString, const QVariant &value, const QVariantMap &viewProperties) const override {
+ if(viewProperties.value(QStringLiteral("qtmvvm_ztr"), formatString.contains(QStringLiteral("%n"))).toBool())
+ return QCoreApplication::translate("qtmvvm_settings_xml", qUtf8Printable(formatString), nullptr, value.toInt());
+ else
+ return formatString.arg(value.toInt());
+ }
+};
+
+class ListFormatter : public Formatter
+{
+public:
+ QString format(const QString &formatString, const QVariant &value, const QVariantMap &viewProperties) const override {
+ if(viewProperties.contains(QStringLiteral("listElements"))) {
+ for(const auto &element : viewProperties.value(QStringLiteral("listElements")).toList()) {
+ if(element.type() != QVariant::Map)
+ continue;
+ auto eMap = element.toMap();
+ if(eMap.value(QStringLiteral("value")) == value)
+ return formatString.arg(eMap.value(QStringLiteral("name")).toString());
+ }
+ }
+
+ return formatString.arg(value.toString());
+ }
+};
+
+}
+
+#endif // QTMVVM_FORMATTERS_P_H
diff --git a/src/mvvmquick/inputviewfactory.cpp b/src/mvvmquick/inputviewfactory.cpp
index 23c5993..2b50daa 100644
--- a/src/mvvmquick/inputviewfactory.cpp
+++ b/src/mvvmquick/inputviewfactory.cpp
@@ -8,6 +8,8 @@
#include
+#include "formatters_p.h"
+
using namespace QtMvvm;
InputViewFactory::InputViewFactory(QObject *parent) :
@@ -24,32 +26,8 @@ QUrl InputViewFactory::getInputUrl(const QByteArray &type, const QVariantMap &vi
Q_UNUSED(viewProperties)
if(d->inputAliases.contains(type))
url = getInputUrl(d->inputAliases.value(type), viewProperties);
- if(d->simpleInputs.contains(type))
+ else if(d->simpleInputs.contains(type))
url = d->simpleInputs.value(type);
- else if(type == QMetaType::typeName(QMetaType::Bool))
- url = QStringLiteral("qrc:/qtmvvm/inputs/CheckBox.qml");
- else if(type == "switch")
- url = QStringLiteral("qrc:/qtmvvm/inputs/Switch.qml");
- else if(type == QMetaType::typeName(QMetaType::QString) || type == "string")
- url = QStringLiteral("qrc:/qtmvvm/inputs/TextField.qml");
- else if(type == QMetaType::typeName(QMetaType::Int))
- url = QStringLiteral("qrc:/qtmvvm/inputs/SpinBox.qml");
- else if(type == QMetaType::typeName(QMetaType::Double))
- url = QStringLiteral("qrc:/qtmvvm/inputs/DoubleSpinBox.qml");
-// else if(type == QMetaType::typeName(QMetaType::QDate))
-// url = QUrl();
-// else if(type == QMetaType::typeName(QMetaType::QTime))
-// url = QUrl();
-// else if(type == QMetaType::typeName(QMetaType::QDateTime) || type == "date")
-// url = QUrl();
- else if(type == QMetaType::typeName(QMetaType::QFont))
- url = QStringLiteral("qrc:/qtmvvm/inputs/FontEdit.qml");
- else if(type == QMetaType::typeName(QMetaType::QUrl) || type == "url")
- url = QStringLiteral("qrc:/qtmvvm/inputs/UrlField.qml");
- else if(type == "selection" || type == "list")
- url = QStringLiteral("qrc:/qtmvvm/inputs/ListEdit.qml");
- else if(type == "radiolist")
- url = QStringLiteral("qrc:/qtmvvm/inputs/RadioListEdit.qml");
else {
logCritical() << "Failed to find any input view for input type:" << type;
return QUrl();
@@ -66,12 +44,8 @@ QUrl InputViewFactory::getDelegate(const QByteArray &type, const QVariantMap &vi
Q_UNUSED(viewProperties)
if(d->delegateAliases.contains(type))
url = getDelegate(d->delegateAliases.value(type), viewProperties);
- if(d->simpleDelegates.contains(type))
+ else if(d->simpleDelegates.contains(type))
url = d->simpleDelegates.value(type);
- else if(type == QMetaType::typeName(QMetaType::Bool))
- url = QStringLiteral("qrc:/qtmvvm/delegates/BoolDelegate.qml");
- else if(type == "switch")
- url = QStringLiteral("qrc:/qtmvvm/delegates/SwitchDelegate.qml");
else if((type == "selection" || type == "list") &&
!viewProperties.value(QStringLiteral("editable"), false).toBool())
url = QStringLiteral("qrc:/qtmvvm/delegates/ListDelegate.qml");
@@ -82,6 +56,16 @@ QUrl InputViewFactory::getDelegate(const QByteArray &type, const QVariantMap &vi
return url;
}
+QString QtMvvm::InputViewFactory::format(const QByteArray &type, const QString &formatString, const QVariant &value, const QVariantMap &viewProperties)
+{
+ if(d->formatterAliases.contains(type))
+ return format(d->formatterAliases.value(type), formatString, value, viewProperties);
+ else if(d->formatters.contains(type))
+ return d->formatters.value(type)->format(formatString, value, viewProperties);
+ else
+ return formatString.arg(value.toString());
+}
+
void InputViewFactory::addSimpleInput(const QByteArray &type, const QUrl &qmlFileUrl)
{
d->simpleInputs.insert(type, qmlFileUrl);
@@ -92,6 +76,11 @@ void InputViewFactory::addSimpleDelegate(const QByteArray &type, const QUrl &qml
d->simpleDelegates.insert(type, qmlFileUrl);
}
+void InputViewFactory::addFormatter(const QByteArray &type, Formatter *formatter)
+{
+ d->formatters.insert(type, QSharedPointer{formatter});
+}
+
void InputViewFactory::addInputAlias(const QByteArray &alias, const QByteArray &targetType)
{
d->inputAliases.insert(alias, targetType);
@@ -101,3 +90,49 @@ void InputViewFactory::addDelegateAlias(const QByteArray &alias, const QByteArra
{
d->delegateAliases.insert(alias, targetType);
}
+
+void QtMvvm::InputViewFactory::addFormatterAlias(const QByteArray &alias, const QByteArray &targetType)
+{
+ d->formatterAliases.insert(alias, targetType);
+}
+
+
+
+Formatter::Formatter() = default;
+
+Formatter::~Formatter() = default;
+
+
+
+InputViewFactoryPrivate::InputViewFactoryPrivate() :
+ simpleInputs{
+ {QMetaType::typeName(QMetaType::Bool), QStringLiteral("qrc:/qtmvvm/inputs/CheckBox.qml")},
+ {"switch", QStringLiteral("qrc:/qtmvvm/inputs/Switch.qml")},
+ {QMetaType::typeName(QMetaType::QString), QStringLiteral("qrc:/qtmvvm/inputs/TextField.qml")},
+ {"string", QStringLiteral("qrc:/qtmvvm/inputs/TextField.qml")},
+ {QMetaType::typeName(QMetaType::Int), QStringLiteral("qrc:/qtmvvm/inputs/SpinBox.qml")},
+ {QMetaType::typeName(QMetaType::Double), QStringLiteral("qrc:/qtmvvm/inputs/DoubleSpinBox.qml")},
+// {QMetaType::typeName(QMetaType::QDate), QStringLiteral("qrc:/qtmvvm/inputs/.qml")},
+// {QMetaType::typeName(QMetaType::QTime), QStringLiteral("qrc:/qtmvvm/inputs/.qml")},
+// {QMetaType::typeName(QMetaType::QDateTime), QStringLiteral("qrc:/qtmvvm/inputs/.qml")},
+// {"date", QStringLiteral("qrc:/qtmvvm/inputs/.qml")},
+ {QMetaType::typeName(QMetaType::QFont), QStringLiteral("qrc:/qtmvvm/inputs/FontEdit.qml")},
+ {QMetaType::typeName(QMetaType::QUrl), QStringLiteral("qrc:/qtmvvm/inputs/UrlField.qml")},
+ {"selection", QStringLiteral("qrc:/qtmvvm/inputs/ListEdit.qml")},
+ {"list", QStringLiteral("qrc:/qtmvvm/inputs/ListEdit.qml")},
+ {"radiolist", QStringLiteral("qrc:/qtmvvm/inputs/RadioListEdit.qml")}
+ },
+ simpleDelegates{
+ {QMetaType::typeName(QMetaType::Bool), QStringLiteral("qrc:/qtmvvm/delegates/BoolDelegate.qml")},
+ {"switch", QStringLiteral("qrc:/qtmvvm/inputs/SwitchDelegate.qml")}
+ },
+ formatters{
+ {QMetaType::typeName(QMetaType::Int), QSharedPointer::create()},
+ {QMetaType::typeName(QMetaType::Double), QSharedPointer>::create()},
+ }
+{
+ auto listFormatter = QSharedPointer::create();
+ formatters.insert("selection", listFormatter);
+ formatters.insert("list", listFormatter);
+ formatters.insert("radiolist", listFormatter);
+}
diff --git a/src/mvvmquick/inputviewfactory.h b/src/mvvmquick/inputviewfactory.h
index a0bd5bf..96f359f 100644
--- a/src/mvvmquick/inputviewfactory.h
+++ b/src/mvvmquick/inputviewfactory.h
@@ -5,11 +5,34 @@
#include
#include
#include
+#include
#include "QtMvvmQuick/qtmvvmquick_global.h"
namespace QtMvvm {
+class Q_MVVMQUICK_EXPORT Formatter
+{
+ Q_DISABLE_COPY(Formatter)
+
+public:
+ Formatter();
+ virtual ~Formatter();
+
+ virtual QString format(const QString &formatString,
+ const QVariant &value,
+ const QVariantMap &viewProperties) const = 0;
+};
+
+template
+class SimpleFormatter : public Formatter
+{
+public:
+ inline QString format(const QString &formatString,
+ const QVariant &value,
+ const QVariantMap &viewProperties) const override;
+};
+
class InputViewFactoryPrivate;
//! A factory class to generate input edit views by their type names
class Q_MVVMQUICK_EXPORT InputViewFactory : public QObject
@@ -26,6 +49,11 @@ public:
//! Find the input list delegate URL of the given input type
Q_INVOKABLE virtual QUrl getDelegate(const QByteArray &type, const QVariantMap &viewProperties);
+ Q_REVISION(1) Q_INVOKABLE QString format(const QByteArray &type,
+ const QString &formatString,
+ const QVariant &value,
+ const QVariantMap &viewProperties);
+
//! Adds a new QML file to create views for the given type
template
inline void addSimpleInput(const QUrl &qmlFileUrl);
@@ -38,6 +66,10 @@ public:
//! @copybrief addSimpleDelegate(const QUrl &)
Q_INVOKABLE virtual void addSimpleDelegate(const QByteArray &type, const QUrl &qmlFileUrl);
+ template
+ inline void addFormatter(Formatter *formatter);
+ void addFormatter(const QByteArray &type, Formatter *formatter);
+
//! Adds a type name alias for views
template
inline void addInputAlias();
@@ -50,6 +82,10 @@ public:
//! @copybrief addDelegateAlias()
Q_INVOKABLE virtual void addDelegateAlias(const QByteArray &alias, const QByteArray &targetType);
+ template
+ inline void addFormatterAlias();
+ Q_REVISION(1) Q_INVOKABLE void addFormatterAlias(const QByteArray &alias, const QByteArray &targetType);
+
private:
QScopedPointer d;
};
@@ -66,6 +102,12 @@ void InputViewFactory::addSimpleDelegate(const QUrl &qmlFileUrl)
addSimpleDelegate(QMetaType::typeName(qMetaTypeId()), qmlFileUrl);
}
+template
+void InputViewFactory::addFormatter(Formatter *formatter)
+{
+ addFormatter(QMetaType::typeName(qMetaTypeId()), formatter);
+}
+
template
inline void InputViewFactory::addInputAlias()
{
@@ -78,6 +120,21 @@ void InputViewFactory::addDelegateAlias()
addDelegateAlias(QMetaType::typeName(qMetaTypeId()), QMetaType::typeName(qMetaTypeId()));
}
+template
+void InputViewFactory::addFormatterAlias()
+{
+ addFormatterAlias(QMetaType::typeName(qMetaTypeId()), QMetaType::typeName(qMetaTypeId()));
+}
+
+
+
+template
+QString SimpleFormatter::format(const QString &formatString, const QVariant &value, const QVariantMap &viewProperties) const
+{
+ Q_UNUSED(viewProperties);
+ return formatString.arg(value.template value());
+}
+
}
#endif // QTMVVM_INPUTVIEWFACTORY_H
diff --git a/src/mvvmquick/inputviewfactory_p.h b/src/mvvmquick/inputviewfactory_p.h
index 55901d8..052f961 100644
--- a/src/mvvmquick/inputviewfactory_p.h
+++ b/src/mvvmquick/inputviewfactory_p.h
@@ -9,10 +9,14 @@ namespace QtMvvm {
class InputViewFactoryPrivate
{
public:
+ InputViewFactoryPrivate();
+
QHash simpleInputs;
QHash simpleDelegates;
+ QHash> formatters;
QHash inputAliases;
QHash delegateAliases;
+ QHash formatterAliases;
};
}
diff --git a/src/mvvmquick/mvvmquick.pro b/src/mvvmquick/mvvmquick.pro
index f920d71..29d5c06 100644
--- a/src/mvvmquick/mvvmquick.pro
+++ b/src/mvvmquick/mvvmquick.pro
@@ -7,7 +7,8 @@ HEADERS += \
quickpresenter.h \
quickpresenter_p.h \
inputviewfactory.h \
- inputviewfactory_p.h
+ inputviewfactory_p.h \
+ formatters_p.h
SOURCES += \
quickpresenter.cpp \