Browse Source

added input dialog

pull/2/head
Skycoder42 7 years ago
parent
commit
d795edb62f
  1. 2
      .travis.yml
  2. 6
      examples/mvvmcore/SampleCore/samplecoreapp.cpp
  3. 18
      examples/mvvmcore/SampleCore/sampleviewmodel.cpp
  4. 2
      examples/mvvmcore/SampleCore/sampleviewmodel.h
  5. 4
      examples/mvvmwidgets/SampleWidgets/sampleview.cpp
  6. 24
      examples/mvvmwidgets/SampleWidgets/sampleview.ui
  7. 23
      src/mvvmcore/message.cpp
  8. 12
      src/mvvmcore/message.h
  9. 9
      src/mvvmwidgets/fontcombobox.cpp
  10. 25
      src/mvvmwidgets/fontcombobox_p.h
  11. 85
      src/mvvmwidgets/inputviewfactory.cpp
  12. 41
      src/mvvmwidgets/inputviewfactory.h
  13. 19
      src/mvvmwidgets/inputviewfactory_p.h
  14. 11
      src/mvvmwidgets/mvvmwidgets.pro
  15. 5
      src/mvvmwidgets/qpmx.json
  16. 62
      src/mvvmwidgets/selectcombobox.cpp
  17. 38
      src/mvvmwidgets/selectcombobox_p.h
  18. 130
      src/mvvmwidgets/widgetspresenter.cpp
  19. 16
      src/mvvmwidgets/widgetspresenter.h
  20. 1
      src/mvvmwidgets/widgetspresenter_p.h

2
.travis.yml

@ -48,7 +48,7 @@ deploy:
file_glob: true
file: install/opt/build_*_$QT_VER.tar.xz
on:
repo: <user/repository>
repo: Skycoder42/QtMvvm
tags: true
before_cache:

6
examples/mvvmcore/SampleCore/samplecoreapp.cpp

@ -2,10 +2,14 @@
#include "sampleviewmodel.h"
#include <QtCore/QCommandLineParser>
#include <QtMvvmCore/QtMvvmCoreVersion>
SampleCoreApp::SampleCoreApp(QObject *parent) :
CoreApp(parent)
{}
{
QCoreApplication::setApplicationVersion(QStringLiteral(QTMVVMCORE_VERSION_STR));
QCoreApplication::setOrganizationName(QStringLiteral("Skycoder42"));
}
void SampleCoreApp::performRegistrations()
{

18
examples/mvvmcore/SampleCore/sampleviewmodel.cpp

@ -64,6 +64,16 @@ void SampleViewModel::setActive(bool active)
emit activeChanged(_active);
}
void SampleViewModel::getInput()
{
QtMvvm::getInput<int>(tr("Random input"),
tr("Enter a number:"),
this, [this](int res, bool ok) {
if(ok)
addEvent(QString::number(res));
}, 42);
}
void SampleViewModel::getResult()
{
showForResult<ResultViewModel>(ResCode, {
@ -81,6 +91,14 @@ void SampleViewModel::clearEvents()
});
}
void SampleViewModel::about()
{
QtMvvm::about(tr("QtMvvm sample application"),
QStringLiteral("https://github.com/Skycoder42/QtMvvm"),
tr("BSD 3 Clause"),
QStringLiteral("https://github.com/Skycoder42/QtMvvm/blob/master/LICENSE"));
}
void SampleViewModel::onInit(const QVariantHash &params)
{
qInfo() << Q_FUNC_INFO << params;

2
examples/mvvmcore/SampleCore/sampleviewmodel.h

@ -32,8 +32,10 @@ public Q_SLOTS:
void setName(QString name);
void setActive(bool active);
void getInput();
void getResult();
void clearEvents();
void about();
Q_SIGNALS:
void nameChanged(QString name);

4
examples/mvvmwidgets/SampleWidgets/sampleview.cpp

@ -22,6 +22,10 @@ SampleView::SampleView(QtMvvm::ViewModel *viewModel, QWidget *parent) :
_viewModel, &SampleViewModel::clearEvents);
connect(ui->resultButton, &QPushButton::clicked,
_viewModel, &SampleViewModel::getResult);
connect(ui->action_About, &QAction::triggered,
_viewModel, &SampleViewModel::about);
connect(ui->actionUseless_Input, &QAction::triggered,
_viewModel, &SampleViewModel::getInput);
}
SampleView::~SampleView()

24
examples/mvvmwidgets/SampleWidgets/sampleview.ui

@ -96,8 +96,32 @@
<height>23</height>
</rect>
</property>
<widget class="QMenu" name="menu_Help">
<property name="title">
<string>&amp;Help</string>
</property>
<addaction name="action_About"/>
</widget>
<widget class="QMenu" name="menu_Actions">
<property name="title">
<string>&amp;Actions</string>
</property>
<addaction name="actionUseless_Input"/>
</widget>
<addaction name="menu_Actions"/>
<addaction name="menu_Help"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="action_About">
<property name="text">
<string>&amp;About</string>
</property>
</action>
<action name="actionUseless_Input">
<property name="text">
<string>Another &amp;Input</string>
</property>
</action>
</widget>
<resources/>
<connections/>

23
src/mvvmcore/message.cpp

@ -381,21 +381,18 @@ MessageResult *QtMvvm::about(const QString &description, const QUrl &websiteUrl,
text += pBegin;
if(addQtVersion) {
auto runtimeVers = qVersion();
auto compileVers = QT_VERSION_STR;
QString qtVersion;
if(qstrcmp(runtimeVers, compileVers) == 0)
qtVersion = QString::fromUtf8(runtimeVers);
else {
qtVersion = MessageConfig::tr("%1 (Built with %2)")
.arg(QString::fromUtf8(runtimeVers))
.arg(QString::fromUtf8(runtimeVers));
QString postFix;
if(qstrcmp(runtimeVers, QT_VERSION_STR) != 0) {
postFix = MessageConfig::tr(" (Built with %1)")
.arg(QStringLiteral(QT_VERSION_STR));
}
text += MessageConfig::tr("Qt-Version: <a href=\"https://www.qt.io/\">%2</a>")
.arg(qtVersion);
text += MessageConfig::tr("Qt-Version: <a href=\"https://www.qt.io/\">%1</a>")
.arg(QString::fromUtf8(runtimeVers)) +
postFix;
}
if(!extraTopInfos.isEmpty()) {
auto withBr = addQtVersion;
foreach(auto info, extraTopInfos){
for(auto info : extraTopInfos) {
text += info + (withBr ? br : QString());
withBr = true;
}
@ -518,7 +515,7 @@ MessageResult *QtMvvm::getOpenFiles(const QString &title, const QStringList &sup
return CoreApp::showDialog(config);
}
void QtMvvm::getOpenFiles(QObject *scope, std::function<void (QList<QUrl>)> onResult, const QString &title, const QStringList &supportedMimeTypes, const QUrl &dir)
void QtMvvm::getOpenFiles(QObject *scope, const std::function<void (QList<QUrl>)> &onResult, const QString &title, const QStringList &supportedMimeTypes, const QUrl &dir)
{
auto result = getOpenFiles(title, supportedMimeTypes, dir);
if(result) {
@ -529,7 +526,7 @@ void QtMvvm::getOpenFiles(QObject *scope, std::function<void (QList<QUrl>)> onRe
}
}
void QtMvvm::getOpenFiles(std::function<void (QList<QUrl>)> onResult, const QString &title, const QStringList &supportedMimeTypes, const QUrl &dir)
void QtMvvm::getOpenFiles(const std::function<void (QList<QUrl>)> &onResult, const QString &title, const QStringList &supportedMimeTypes, const QUrl &dir)
{
getOpenFiles(CoreApp::instance(), onResult, title, supportedMimeTypes, dir);
}

12
src/mvvmcore/message.h

@ -247,25 +247,25 @@ template <typename TEdit>
inline void getInput(const QString &title,
const QString &text,
QObject *scope,
const std::function<void(TEdit)> &onResult,
const std::function<void(TEdit, bool)> &onResult,
const QVariant &defaultValue = {},
const QVariantMap &viewProperties = {},
const QString &okText = {},
const QString &cancelText = {}) {
getInput(title, text, QMetaType::typeName(qMetaTypeId<TEdit>()), scope, [onResult](QVariant v) {
onResult(v.template value<TEdit>());
onResult(v.template value<TEdit>(), v.isValid());
}, defaultValue, viewProperties, okText, cancelText);
}
template <typename TEdit>
inline void getInput(const QString &title,
const QString &text,
const std::function<void(TEdit)> &onResult,
const std::function<void(TEdit, bool)> &onResult,
const QVariant &defaultValue = {},
const QVariantMap &viewProperties = {},
const QString &okText = {},
const QString &cancelText = {}) {
getInput(title, text, QMetaType::typeName(qMetaTypeId<TEdit>()), [onResult](QVariant v) {
onResult(v.template value<TEdit>());
onResult(v.template value<TEdit>(), v.isValid());
}, defaultValue, viewProperties, okText, cancelText);
}
@ -296,11 +296,11 @@ Q_MVVMCORE_EXPORT MessageResult *getOpenFiles(const QString &title = {},
const QStringList &supportedMimeTypes = {},
const QUrl &dir = {});
Q_MVVMCORE_EXPORT void getOpenFiles(QObject *scope,
std::function<void(QList<QUrl>)> onResult,
const std::function<void(QList<QUrl>)> &onResult,
const QString &title = {},
const QStringList &supportedMimeTypes = {},
const QUrl &dir = {});
Q_MVVMCORE_EXPORT void getOpenFiles(std::function<void(QList<QUrl>)> onResult,
Q_MVVMCORE_EXPORT void getOpenFiles(const std::function<void(QList<QUrl>)> &onResult,
const QString &title = {},
const QStringList &supportedMimeTypes = {},
const QUrl &dir = {});

9
src/mvvmwidgets/fontcombobox.cpp

@ -0,0 +1,9 @@
#include "fontcombobox_p.h"
using namespace QtMvvm;
FontComboBox::FontComboBox(QWidget *parent) :
QFontComboBox(parent)
{
connect(this, &FontComboBox::currentFontChangedImp,
this, &FontComboBox::currentFontChanged);
}

25
src/mvvmwidgets/fontcombobox_p.h

@ -0,0 +1,25 @@
#ifndef QTMVVM_FONTCOMBOBOX_P_H
#define QTMVVM_FONTCOMBOBOX_P_H
#include <QtWidgets/QFontComboBox>
#include "qtmvvmwidgets_global.h"
namespace QtMvvm {
class FontComboBox : public QFontComboBox
{
Q_OBJECT
Q_PROPERTY(QFont currentFont READ currentFont WRITE setCurrentFont NOTIFY currentFontChangedImp USER true)
public:
explicit FontComboBox(QWidget *parent = nullptr);
Q_SIGNALS:
void currentFontChangedImp(const QFont &font);
};
}
#endif // QTMVVM_FONTCOMBOBOX_P_H

85
src/mvvmwidgets/inputviewfactory.cpp

@ -0,0 +1,85 @@
#include "inputviewfactory.h"
#include "inputviewfactory_p.h"
#include <QtMvvmCore/private/qtmvvm_logging_p.h>
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QSpinBox>
#include <QtWidgets/QDateTimeEdit>
#include <QtWidgets/QKeySequenceEdit>
#include "fontcombobox_p.h"
#include "selectcombobox_p.h"
#include <qurlvalidator.h>
using namespace QtMvvm;
InputViewFactory::InputViewFactory() :
d(new InputViewFactoryPrivate())
{}
InputViewFactory::~InputViewFactory() {}
QWidget *InputViewFactory::createInput(const QByteArray &type, QWidget *parent, const QVariantMap &viewProperties)
{
QWidget *widget = nullptr;
if(d->simpleWidgets.contains(type))
widget = d->simpleWidgets.value(type)(parent);
else if(type == QMetaType::typeName(QMetaType::Bool))
widget = new QCheckBox(parent);
else if(type == QMetaType::typeName(QMetaType::QString) || type == "string") {
auto edit = new QLineEdit(parent);
if(viewProperties.contains(QStringLiteral("regexp"))) {
QRegularExpression regex(viewProperties.value(QStringLiteral("regexp")).toString());
regex.setPatternOptions(static_cast<QRegularExpression::PatternOptions>(
viewProperties.value(QStringLiteral("patternOptions"),
static_cast<int>(regex.patternOptions()))
.toInt()));
edit->setValidator(new QRegularExpressionValidator(regex, edit));
}
widget = edit;
} else if(type == QMetaType::typeName(QMetaType::Int))
widget = new QSpinBox(parent);
else if(type == QMetaType::typeName(QMetaType::Double) || type == "number")
widget = new QDoubleSpinBox(parent);
else if(type == QMetaType::typeName(QMetaType::QDate))
widget = new QDateEdit(parent);
else if(type == QMetaType::typeName(QMetaType::QTime))
widget = new QTimeEdit(parent);
else if(type == QMetaType::typeName(QMetaType::QDateTime) || type == "date")
widget = new QDateTimeEdit(parent);
else if(type == QMetaType::typeName(QMetaType::QFont))
widget = new FontComboBox(parent);
else if(type == QMetaType::typeName(QMetaType::QKeySequence))
widget = new QKeySequenceEdit(parent);
else if(type == QMetaType::typeName(QMetaType::QUrl) || type == "url") {
auto edit = new QLineEdit(parent);
auto validator = new QUrlValidator(edit);
if(viewProperties.contains(QStringLiteral("allowedSchemes")))
validator->setAllowedSchemes(viewProperties.value(QStringLiteral("allowedSchemes")).toStringList());
edit->setValidator(validator);
widget = edit;
} else if(type == "selection" || type == "list")
widget = new SelectComboBox(parent);
else {
logCritical() << "Failed to find any input view for input type:" << type;
return nullptr;
}
for(auto it = viewProperties.constBegin(); it != viewProperties.constEnd(); it++)
widget->setProperty(qUtf8Printable(it.key()), it.value());
return widget;
}
void InputViewFactory::addSimpleWidget(const QByteArray &type, const std::function<QWidget *(QWidget *)> &creator)
{
Q_ASSERT_X(creator, Q_FUNC_INFO, "The passed creation function must be valid");
d->simpleWidgets.insert(type, creator);
}
// ------------- Private Implementation -------------
InputViewFactoryPrivate::InputViewFactoryPrivate() :
simpleWidgets()
{}

41
src/mvvmwidgets/inputviewfactory.h

@ -0,0 +1,41 @@
#ifndef QTMVVM_INPUTVIEWFACTORY_H
#define QTMVVM_INPUTVIEWFACTORY_H
#include <functional>
#include <QtCore/qscopedpointer.h>
#include <QtWidgets/qwidget.h>
#include "QtMvvmWidgets/qtmvvmwidgets_global.h"
namespace QtMvvm {
class InputViewFactoryPrivate;
class InputViewFactory
{
public:
InputViewFactory();
virtual ~InputViewFactory();
virtual QWidget *createInput(const QByteArray &type, QWidget *parent, const QVariantMap &viewProperties);
virtual void addSimpleWidget(const QByteArray &type, const std::function<QWidget*(QWidget*)> &creator);
template <typename TType, typename TWidget>
void addSimpleWidget();
private:
QScopedPointer<InputViewFactoryPrivate> d;
};
template<typename TType, typename TWidget>
void InputViewFactory::addSimpleWidget()
{
addSimpleWidget(QMetaType::typeName(qMetaTypeId<TType>()), [](QWidget *parent){
return new TWidget(parent);
});
}
}
#endif // QTMVVM_INPUTVIEWFACTORY_H

19
src/mvvmwidgets/inputviewfactory_p.h

@ -0,0 +1,19 @@
#ifndef QTMVVM_INPUTVIEWFACTORY_P_H
#define QTMVVM_INPUTVIEWFACTORY_P_H
#include "qtmvvmwidgets_global.h"
#include "inputviewfactory.h"
namespace QtMvvm {
class InputViewFactoryPrivate
{
public:
InputViewFactoryPrivate();
QHash<QByteArray, std::function<QWidget*(QWidget*)>> simpleWidgets;
};
}
#endif // QTMVVM_INPUTVIEWFACTORY_P_H

11
src/mvvmwidgets/mvvmwidgets.pro

@ -6,10 +6,17 @@ HEADERS += \
qtmvvmwidgets_global.h \
widgetspresenter.h \
ipresentingview.h \
widgetspresenter_p.h
widgetspresenter_p.h \
inputviewfactory.h \
inputviewfactory_p.h \
fontcombobox_p.h \
selectcombobox_p.h
SOURCES += \
widgetspresenter.cpp
widgetspresenter.cpp \
inputviewfactory.cpp \
fontcombobox.cpp \
selectcombobox.cpp
TRANSLATIONS += \
translations/qtmvvmwidgets_de.ts \

5
src/mvvmwidgets/qpmx.json

@ -4,6 +4,11 @@
"package": "de.skycoder42.dialog-master",
"provider": "qpm",
"version": "1.3.2"
},
{
"package": "de.skycoder42.qurlvalidator",
"provider": "qpm",
"version": "1.1.0"
}
],
"license": {

62
src/mvvmwidgets/selectcombobox.cpp

@ -0,0 +1,62 @@
#include "selectcombobox_p.h"
using namespace QtMvvm;
SelectComboBox::SelectComboBox(QWidget *parent) :
QComboBox(parent)
{
connect(this, &SelectComboBox::currentTextChanged,
this, &SelectComboBox::currentValueChanged);
connect(this, &SelectComboBox::editTextChanged,
this, &SelectComboBox::currentValueChanged);
}
QVariant SelectComboBox::currentValue() const
{
if(currentText() != itemText(currentIndex()))
return currentText();
else
return currentData();
}
QVariantList SelectComboBox::listElements() const
{
QVariantList res;
for(auto i = 0; i < count(); i++) {
auto key = itemText(i);
auto value = itemData(i);
if(key == value)
res.append(key);
else {
QVariantMap map;
map.insert(QStringLiteral("name"), key);
map.insert(QStringLiteral("value"), value);
res.append(map);
}
}
return res;
}
void SelectComboBox::setCurrentValue(const QVariant &data)
{
auto index = findData(data);
if(index != -1)
setCurrentIndex(index);
else
setCurrentText(data.toString());
}
void SelectComboBox::setListElements(const QVariantList &listElements)
{
clear();
for(auto item : listElements) {
if(item.type() == QVariant::String)
addItem(item.toString(), item);
else {
auto iData = item.toMap();
addItem(iData.value(QStringLiteral("name")).toString(),
iData.value(QStringLiteral("value")));
}
}
emit listElementsChanged(listElements);
}

38
src/mvvmwidgets/selectcombobox_p.h

@ -0,0 +1,38 @@
#ifndef QTMVVM_SELECTCOMBOBOX_P_H
#define QTMVVM_SELECTCOMBOBOX_P_H
#include <QtCore/QVariant>
#include <QtWidgets/QComboBox>
#include "qtmvvmwidgets_global.h"
namespace QtMvvm {
class SelectComboBox : public QComboBox
{
Q_OBJECT
Q_PROPERTY(QVariant currentValue READ currentValue WRITE setCurrentValue NOTIFY currentValueChanged USER true)
Q_PROPERTY(QVariantList listElements READ listElements WRITE setListElements NOTIFY listElementsChanged)
QVariantMap m_listElements;
public:
explicit SelectComboBox(QWidget *parent = nullptr);
QVariant currentValue() const;
QVariantList listElements() const;
public Q_SLOTS:
void setCurrentValue(const QVariant &data);
void setListElements(const QVariantList &listElements);
Q_SIGNALS:
void currentValueChanged();
void listElementsChanged(QVariantList listElements);
};
}
#endif // QTMVVM_SELECTCOMBOBOX_P_H

130
src/mvvmwidgets/widgetspresenter.cpp

@ -2,8 +2,7 @@
#include "widgetspresenter_p.h"
#include "ipresentingview.h"
#include <QtMvvmCore/private/coreapp_p.h>
#include <QtMvvmCore/private/qtmvvm_logging_p.h>
#include <QtCore/QMetaProperty>
#include <QtWidgets/QDialog>
#include <QtWidgets/QMainWindow>
@ -12,6 +11,12 @@
#include <QtWidgets/QMdiArea>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QApplication>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QDialogButtonBox>
#include <QtWidgets/QPushButton>
#include <QtMvvmCore/private/coreapp_p.h>
#include <QtMvvmCore/private/qtmvvm_logging_p.h>
#include <dialogmaster.h>
@ -92,6 +97,16 @@ void WidgetsPresenter::showDialog(const MessageConfig &config, MessageResult *re
presentOtherDialog(config, result);
}
InputViewFactory *WidgetsPresenter::inputViewFactory() const
{
return d->inputViewFactory.data();
}
void WidgetsPresenter::setInputViewFactory(InputViewFactory *inputViewFactory)
{
d->inputViewFactory.reset(inputViewFactory);
}
const QMetaObject *WidgetsPresenter::findWidgetMetaObject(const QMetaObject *viewModelMetaObject)
{
auto currentMeta = viewModelMetaObject;
@ -180,21 +195,27 @@ void WidgetsPresenter::showForeground(QWidget *view) const
view->activateWindow();
}
void WidgetsPresenter::presentMessageBox(const MessageConfig &config, MessageResult *result)
void WidgetsPresenter::presentMessageBox(const MessageConfig &config, QPointer<MessageResult> result)
{
auto qtHelp = false;
DialogMaster::MessageBoxInfo info;
//set the icon based of the type
if(config.type() == MessageConfig::SubTypeInformation)
if(config.subType() == MessageConfig::SubTypeInformation)
info = DialogMaster::createInformation();
else if(config.type() == MessageConfig::SubTypeWarning)
else if(config.subType() == MessageConfig::SubTypeWarning)
info = DialogMaster::createWarning();
else if(config.type() == MessageConfig::SubTypeCritical)
else if(config.subType() == MessageConfig::SubTypeCritical)
info = DialogMaster::createCritical();
else if(config.type() == MessageConfig::SubTypeQuestion)
else if(config.subType() == MessageConfig::SubTypeQuestion)
info = DialogMaster::createQuestion();
else if(config.type() == MessageConfig::SubTypeAbout) {
else if(config.subType() == MessageConfig::SubTypeAbout) {
info = DialogMaster::createInformation();
info.icon = QGuiApplication::windowIcon();
info.windowTitle = tr("About");
auto mIcon = QGuiApplication::windowIcon();
if(!mIcon.isNull())
info.icon = mIcon;
qtHelp = config.viewProperties().value(QStringLiteral("addQtVersion"), true).toBool();
qtHelp = config.viewProperties().value(QStringLiteral("showQtHelp"), qtHelp).toBool();//TODO document too
}
info.title = config.title();
@ -203,9 +224,13 @@ void WidgetsPresenter::presentMessageBox(const MessageConfig &config, MessageRes
auto btns = config.buttonTexts();
for(auto it = btns.constBegin(); it != btns.constEnd(); it++)
info.buttonTexts.insert(static_cast<QMessageBox::StandardButton>(it.key()), it.value());
if(qtHelp) {
info.buttons |= QMessageBox::Help;
info.buttonTexts.insert(QMessageBox::Help, tr("About &Qt"));
}
//special properties
bool checked = false;
QSharedPointer<bool> checked;
auto props = config.viewProperties(); //TODO document all these
if(!props.value(QStringLiteral("modal"), false).toBool())
info.parent = QApplication::activeWindow();
@ -215,31 +240,95 @@ void WidgetsPresenter::presentMessageBox(const MessageConfig &config, MessageRes
info.details = props.value(QStringLiteral("details")).toString();
if(props.contains(QStringLiteral("checkable"))) {
if(props.value(QStringLiteral("checkable")).toBool()) {
checked = config.defaultValue().toBool();
info.checked = &checked;
checked = QSharedPointer<bool>::create(config.defaultValue().toBool());
info.checked = checked.data();
if(props.contains(QStringLiteral("checkString")))
info.checkString = props.value(QStringLiteral("checkString")).toString();
}
}
//show the msgbox
int res = DialogMaster::messageBox(info);
if(info.checked)
result->setResult(checked);
result->complete(static_cast<MessageConfig::StandardButton>(res));
//create and show the msgbox
auto msgBox = DialogMaster::createMessageBox(info);
connect(msgBox, &QMessageBox::finished,
result, [qtHelp, checked, result](int resCode){
if(result) {
if(checked)
result->setResult(*checked);
result->complete(static_cast<MessageConfig::StandardButton>(resCode));
if(qtHelp && resCode == QMessageBox::Help)
QApplication::aboutQt();
}
});
msgBox->open();
}
void WidgetsPresenter::presentInputDialog(const MessageConfig &config, MessageResult *result)
void WidgetsPresenter::presentInputDialog(const MessageConfig &config, QPointer<MessageResult> result)
{
auto input = d->inputViewFactory->createInput(config.subType(), nullptr, config.viewProperties());
if(!input)
return;
QWidget *parent = nullptr;
if(!config.viewProperties().value(QStringLiteral("modal"), false).toBool())
parent = QApplication::activeWindow();
auto dialog = new QDialog(parent);
dialog->setAttribute(Qt::WA_DeleteOnClose);
auto layout = new QVBoxLayout(dialog);
dialog->setLayout(layout);
//set title and text
auto text = config.text();
if(text.isNull())
text = config.title();
else
dialog->setWindowTitle(config.title());//TODO as header better?
if(!text.isNull()) {
auto label = new QLabel(text, dialog);
layout->addWidget(label);
}
//add the input
input->setParent(dialog);
auto property = input->metaObject()->userProperty();
property.write(input, config.defaultValue());
layout->addWidget(input);
//add the buttons
auto btnBox = new QDialogButtonBox(dialog);
btnBox->setStandardButtons(static_cast<QDialogButtonBox::StandardButtons>(static_cast<int>(config.buttons()))); //is ok, as the buttons are the same
auto btns = config.buttonTexts();
for(auto it = btns.constBegin(); it != btns.constEnd(); it++){
auto sBtn = static_cast<QDialogButtonBox::StandardButton>(it.key());
btnBox->addButton(sBtn);
btnBox->button(sBtn)->setText(it.value());
}
layout->addWidget(btnBox);
//connect stuff
QObject::connect(btnBox, &QDialogButtonBox::clicked,
dialog, [dialog, btnBox](QAbstractButton *btn){
dialog->done(btnBox->standardButton(btn));
});
QObject::connect(dialog, &QDialog::finished,
dialog, [dialog, input, property, result](int resCode){
if(result) {
result->complete(static_cast<MessageConfig::StandardButton>(resCode),
property.read(input));
}
});
//finalize and show
dialog->adjustSize();
DialogMaster::masterDialog(dialog);
dialog->open();
}
void WidgetsPresenter::presentFileDialog(const MessageConfig &config, MessageResult *result)
void WidgetsPresenter::presentFileDialog(const MessageConfig &config, QPointer<MessageResult> result)
{
}
void WidgetsPresenter::presentOtherDialog(const MessageConfig &config, MessageResult *result)
void WidgetsPresenter::presentOtherDialog(const MessageConfig &config, QPointer<MessageResult> result)
{
Q_UNUSED(result)
throw PresenterException(QByteArrayLiteral("Unable to find a method that is able to show a dialog of type") +
@ -249,6 +338,7 @@ void WidgetsPresenter::presentOtherDialog(const MessageConfig &config, MessageRe
// ------------- Private Implementation -------------
WidgetsPresenterPrivate::WidgetsPresenterPrivate() :
inputViewFactory(new InputViewFactory()),
implicitMappings(),
explicitMappings()
{}

16
src/mvvmwidgets/widgetspresenter.h

@ -10,6 +10,7 @@
#include <QtWidgets/qwidget.h>
#include "QtMvvmWidgets/qtmvvmwidgets_global.h"
#include "QtMvvmWidgets/inputviewfactory.h"
namespace QtMvvm {
@ -19,6 +20,8 @@ class Q_MVVMWIDGETS_EXPORT WidgetsPresenter : public QObject, public IPresenter
Q_OBJECT
Q_INTERFACES(QtMvvm::IPresenter)
Q_PROPERTY(InputViewFactory* inputViewFactory READ inputViewFactory WRITE setInputViewFactory)
public:
explicit WidgetsPresenter(QObject *parent = nullptr);
~WidgetsPresenter();
@ -37,6 +40,11 @@ public:
void present(ViewModel *viewModel, const QVariantHash &params, QPointer<ViewModel> parent) override;
void showDialog(const MessageConfig &config, MessageResult *result) override;
InputViewFactory* inputViewFactory() const;
public Q_SLOTS:
void setInputViewFactory(InputViewFactory* inputViewFactory);
protected:
virtual const QMetaObject *findWidgetMetaObject(const QMetaObject *viewModelMetaObject);
virtual bool tryPresent(QWidget *view, QWidget *parentView);
@ -44,10 +52,10 @@ protected:
virtual void showForeground(QWidget *view) const;
virtual void presentMessageBox(const MessageConfig &config, MessageResult *result);
virtual void presentInputDialog(const MessageConfig &config, MessageResult *result);
virtual void presentFileDialog(const MessageConfig &config, MessageResult *result);
virtual void presentOtherDialog(const MessageConfig &config, MessageResult *result);
virtual void presentMessageBox(const MessageConfig &config, QPointer<MessageResult> result);
virtual void presentInputDialog(const MessageConfig &config, QPointer<MessageResult> result);
virtual void presentFileDialog(const MessageConfig &config, QPointer<MessageResult> result);
virtual void presentOtherDialog(const MessageConfig &config, QPointer<MessageResult> result);
private:
QScopedPointer<WidgetsPresenterPrivate> d;

1
src/mvvmwidgets/widgetspresenter_p.h

@ -16,6 +16,7 @@ public:
static WidgetsPresenter *currentPresenter();
QScopedPointer<InputViewFactory> inputViewFactory;
QSet<const QMetaObject*> implicitMappings;
QHash<QByteArray, const QMetaObject*> explicitMappings;
};

Loading…
Cancel
Save