Browse Source

added show for result

pull/2/head
Skycoder42 7 years ago
parent
commit
22ac3c4269
  1. 4
      src/mvvmcore/binding.cpp
  2. 3
      src/mvvmcore/binding.h
  3. 12
      src/mvvmcore/coreapp.cpp
  4. 3
      src/mvvmcore/coreapp.h
  5. 2
      src/mvvmcore/coreapp_p.h
  6. 25
      src/mvvmcore/ipresenter.cpp
  7. 18
      src/mvvmcore/ipresenter.h
  8. 187
      src/mvvmcore/message.cpp
  9. 78
      src/mvvmcore/message.h
  10. 28
      src/mvvmcore/message_p.h
  11. 8
      src/mvvmcore/mvvmcore.pro
  12. 30
      src/mvvmcore/viewmodel.cpp
  13. 33
      src/mvvmcore/viewmodel.h
  14. 2
      src/mvvmcore/viewmodel_p.h
  15. 26
      src/mvvmwidgets/widgetspresenter.cpp

4
src/mvvmcore/binding.cpp

@ -85,6 +85,10 @@ Binding QtMvvm::bind(QObject *viewModel, const QMetaProperty &viewModelProperty,
}
Binding::Binding() :
d(nullptr)
{}
Binding::Binding(QPointer<BindingPrivate> d_ptr) :
d(d_ptr)
{}

3
src/mvvmcore/binding.h

@ -26,7 +26,8 @@ public:
Q_DECLARE_FLAGS(BindingDirection, BindingDirectionFlag)
Q_FLAG(BindingDirection)
Binding(QPointer<BindingPrivate> d_ptr = nullptr);
Binding();
Binding(QPointer<BindingPrivate> d_ptr);
~Binding();
bool isValid() const;

12
src/mvvmcore/coreapp.cpp

@ -95,20 +95,28 @@ QScopedPointer<CoreAppPrivate> &CoreAppPrivate::dInstance()
return instance->d;
}
void CoreAppPrivate::showViewModel(const QMetaObject *metaObject, const QVariantHash &params, QPointer<ViewModel> parent)
void CoreAppPrivate::showViewModel(const QMetaObject *metaObject, const QVariantHash &params, QPointer<ViewModel> parent, quint32 requestCode)
{
if(presenter) {
QPointer<ViewModel> vm;
try {
auto obj = ServiceRegistryPrivate::constructInjected(metaObject);
auto vm = qobject_cast<ViewModel*>(obj);
vm = qobject_cast<ViewModel*>(obj);
if(!vm)
throw ServiceConstructionException("Invalid types - not at QtMvvm::ViewModel");
presenter->present(vm, params, parent);
if(requestCode != 0) {
QObject::connect(vm, &ViewModel::resultReady,
parent, &ViewModel::onResult,
Qt::UniqueConnection);
}
} catch(QException &e) {
logCritical() << "Failed to present viewmodel of type"
<< metaObject->className()
<< "with error:"
<< e.what();
if(vm)
vm->deleteLater();
}
} else {
logCritical() << "Failed to present viewmodel of type"

3
src/mvvmcore/coreapp.h

@ -47,7 +47,8 @@ private:
template<typename TViewModel>
inline void CoreApp::show(const QVariantHash &params) const
{
ViewModel::show<TViewModel>(params);
static_assert(std::is_base_of<ViewModel, TViewModel>::value, "TViewModel must extend QtMvvm::ViewModel");
ViewModel::showImp(&TViewModel::staticMetaObject, params, nullptr);
}
}

2
src/mvvmcore/coreapp_p.h

@ -14,7 +14,7 @@ class Q_MVVMCORE_EXPORT CoreAppPrivate
public:
static QScopedPointer<CoreAppPrivate> &dInstance();
void showViewModel(const QMetaObject *metaObject, const QVariantHash &params, QPointer<ViewModel> parent);
void showViewModel(const QMetaObject *metaObject, const QVariantHash &params, QPointer<ViewModel> parent, quint32 requestCode);
IPresenter *currentPresenter() const;

25
src/mvvmcore/ipresenter.cpp

@ -0,0 +1,25 @@
#include "ipresenter.h"
using namespace QtMvvm;
PresenterException::PresenterException(const QByteArray &what) :
_what(what)
{}
PresenterException::PresenterException(const PresenterException * const other) :
_what(other->_what)
{}
const char *PresenterException::what() const noexcept
{
return _what.constData();
}
void PresenterException::raise() const
{
throw (*this);
}
QException *PresenterException::clone() const
{
return new PresenterException(this);
}

18
src/mvvmcore/ipresenter.h

@ -1,11 +1,29 @@
#ifndef QTMVVM_IPRESENTER_H
#define QTMVVM_IPRESENTER_H
#include <QtCore/qexception.h>
#include "QtMvvmCore/qtmvvmcore_global.h"
#include "QtMvvmCore/viewmodel.h"
namespace QtMvvm {
class Q_MVVMCORE_EXPORT PresenterException : public QException
{
public:
PresenterException(const QByteArray &what);
const char *what() const noexcept override;
void raise() const override;
QException *clone() const override;
protected:
PresenterException(const PresenterException * const other);
const QByteArray _what;
};
class Q_MVVMCORE_EXPORT IPresenter
{
public:

187
src/mvvmcore/message.cpp

@ -0,0 +1,187 @@
#include "message.h"
#include "message_p.h"
using namespace QtMvvm;
MessageConfig::MessageConfig(MessageType type) :
d(new MessageConfigPrivate(type))
{
resetPositiveAction();
resetNegativeAction();
resetNeutralAction();
}
MessageConfig::MessageConfig(const MessageConfig &other) :
d(other.d)
{}
MessageConfig::~MessageConfig() {}
MessageConfig &MessageConfig::operator=(const MessageConfig &other)
{
d = other.d;
return (*this);
}
MessageConfig::MessageType MessageConfig::type() const
{
return d->type;
}
QString MessageConfig::title() const
{
return d->title;
}
QString MessageConfig::text() const
{
return d->text;
}
QString MessageConfig::positiveAction() const
{
return d->positiveAction;
}
QString MessageConfig::negativeAction() const
{
return d->negativeAction;
}
QString MessageConfig::neutralAction() const
{
return d->neutralAction;
}
QByteArray MessageConfig::inputType() const
{
return d->inputType;
}
QVariant MessageConfig::defaultValue() const
{
return d->defaultValue;
}
QVariantMap MessageConfig::editProperties() const
{
return d->editProperties;
}
void MessageConfig::setType(MessageConfig::MessageType type)
{
d->type = type;
resetPositiveAction();
resetNegativeAction();
resetNeutralAction();
}
void MessageConfig::setTitle(QString title)
{
d->title = title;
}
void MessageConfig::setText(QString text)
{
d->text = text;
}
void MessageConfig::setPositiveAction(QString positiveAction)
{
d->positiveAction = positiveAction;
}
void MessageConfig::setNegativeAction(QString negativeAction)
{
d->negativeAction = negativeAction;
}
void MessageConfig::setNeutralAction(QString neutralAction)
{
d->neutralAction = neutralAction;
}
void MessageConfig::setInputType(QByteArray inputType)
{
d->inputType = inputType;
}
void MessageConfig::setDefaultValue(QVariant defaultValue)
{
d->defaultValue = defaultValue;
}
void MessageConfig::setEditProperties(QVariantMap editProperties)
{
d->editProperties = editProperties;
}
void MessageConfig::resetPositiveAction()
{
switch (d->type) {
case Information:
case Warning:
case Critical:
case Input:
d->positiveAction = tr("Ok");
break;
case Question:
d->positiveAction = tr("Yes");
break;
default:
Q_UNREACHABLE();
break;
}
}
void MessageConfig::resetNegativeAction()
{
switch (d->type) {
case Input:
d->negativeAction = tr("Cancel");
break;
case Question:
d->negativeAction = tr("No");
break;
case Information:
case Warning:
case Critical:
d->negativeAction.clear();
break;
default:
Q_UNREACHABLE();
break;
}
}
void MessageConfig::resetNeutralAction()
{
d->neutralAction.clear();
}
// ------------- Private Implementation -------------
QtMvvm::MessageConfigPrivate::MessageConfigPrivate(MessageConfig::MessageType type) :
QSharedData(),
type(type),
title(),
text(),
positiveAction(),
negativeAction(),
neutralAction(),
inputType(),
defaultValue(),
editProperties()
{}
QtMvvm::MessageConfigPrivate::MessageConfigPrivate(const QtMvvm::MessageConfigPrivate &other) :
QSharedData(other),
type(other.type),
title(other.title),
text(other.text),
positiveAction(other.positiveAction),
negativeAction(other.negativeAction),
neutralAction(other.neutralAction),
inputType(other.inputType),
defaultValue(other.defaultValue),
editProperties(other.editProperties)
{}

78
src/mvvmcore/message.h

@ -0,0 +1,78 @@
#ifndef QTMVVM_MESSAGE_H
#define QTMVVM_MESSAGE_H
#include <QtCore/qcoreapplication.h>
#include <QtCore/qshareddata.h>
#include "QtMvvmCore/qtmvvmcore_global.h"
namespace QtMvvm {
class MessageConfigPrivate;
class Q_MVVMCORE_EXPORT MessageConfig
{
Q_GADGET
Q_DECLARE_TR_FUNCTIONS(MessageConfig)
Q_PROPERTY(MessageType type READ type WRITE setType)
Q_PROPERTY(QString title READ title WRITE setTitle)
Q_PROPERTY(QString text READ text WRITE setText)
Q_PROPERTY(QString positiveAction READ positiveAction WRITE setPositiveAction RESET resetPositiveAction)
Q_PROPERTY(QString negativeAction READ negativeAction WRITE setNegativeAction RESET resetNegativeAction)
Q_PROPERTY(QString neutralAction READ neutralAction WRITE setNeutralAction RESET resetNeutralAction)
Q_PROPERTY(QByteArray inputType READ inputType WRITE setInputType)
Q_PROPERTY(QVariant defaultValue READ defaultValue WRITE setDefaultValue)
Q_PROPERTY(QVariantMap editProperties READ editProperties WRITE setEditProperties)
public:
enum MessageType {
Information,
Question,
Warning,
Critical,
Input
};
Q_ENUM(MessageType)
MessageConfig(MessageType type = Information);
MessageConfig(const MessageConfig &other);
~MessageConfig();
MessageConfig &operator=(const MessageConfig &other);
MessageType type() const;
QString title() const;
QString text() const;
QString positiveAction() const;
QString negativeAction() const;
QString neutralAction() const;
QByteArray inputType() const;
QVariant defaultValue() const;
QVariantMap editProperties() const;
void setType(MessageType type);
void setTitle(QString title);
void setText(QString text);
void setPositiveAction(QString positiveAction);
void setNegativeAction(QString negativeAction);
void setNeutralAction(QString neutralAction);
void setInputType(QByteArray inputType);
void setDefaultValue(QVariant defaultValue);
void setEditProperties(QVariantMap editProperties);
void resetPositiveAction();
void resetNegativeAction();
void resetNeutralAction();
private:
QSharedDataPointer<MessageConfigPrivate> d;
};
}
Q_DECLARE_METATYPE(QtMvvm::MessageConfig)
Q_DECLARE_TYPEINFO(QtMvvm::MessageConfig, Q_MOVABLE_TYPE);
#endif // QTMVVM_MESSAGE_H

28
src/mvvmcore/message_p.h

@ -0,0 +1,28 @@
#ifndef QTMVVM_MESSAGE_P_H
#define QTMVVM_MESSAGE_P_H
#include "qtmvvmcore_global.h"
#include "message.h"
namespace QtMvvm {
class MessageConfigPrivate : public QSharedData
{
public:
MessageConfigPrivate(MessageConfig::MessageType type);
MessageConfigPrivate(const MessageConfigPrivate &other);
MessageConfig::MessageType type;
QString title;
QString text;
QString positiveAction;
QString negativeAction;
QString neutralAction;
QByteArray inputType;
QVariant defaultValue;
QVariantMap editProperties;
};
}
#endif // QTMVVM_MESSAGE_P_H

8
src/mvvmcore/mvvmcore.pro

@ -14,14 +14,18 @@ HEADERS += \
ipresenter.h \
qtmvvm_logging_p.h \
binding.h \
binding_p.h
binding_p.h \
message.h \
message_p.h
SOURCES += \
viewmodel.cpp \
coreapp.cpp \
serviceregistry.cpp \
qtmvvmcore_global.cpp \
binding.cpp
binding.cpp \
message.cpp \
ipresenter.cpp
TRANSLATIONS += \
translations/qtmvvmcore_de.ts \

30
src/mvvmcore/viewmodel.cpp

@ -1,6 +1,7 @@
#include "viewmodel.h"
#include "viewmodel_p.h"
#include "coreapp_p.h"
#include "qtmvvm_logging_p.h"
using namespace QtMvvm;
ViewModel::ViewModel(QObject *parent) :
@ -10,34 +11,27 @@ ViewModel::ViewModel(QObject *parent) :
ViewModel::~ViewModel() {}
ViewModel *ViewModel::parentViewModel() const
{
return qobject_cast<ViewModel*>(parent()); //TODO not working that way, parent is always the view...
}
void ViewModel::onInit(const QVariantHash &) {}
bool ViewModel::deleteOnClose() const
void ViewModel::onResult(quint32 requestCode, const QVariant &result)
{
return d->deleteOnClose;
Q_UNUSED(result)
logDebug() << "Unused result on" << metaObject()->className()
<< "with request code" << requestCode;
}
void ViewModel::setDeleteOnClose(bool deleteOnClose)
void ViewModel::showImp(const QMetaObject *mo, const QVariantHash &params, QPointer<ViewModel> parent)
{
if (d->deleteOnClose == deleteOnClose)
return;
d->deleteOnClose = deleteOnClose;
emit deleteOnCloseChanged(deleteOnClose, {});
CoreAppPrivate::dInstance()->showViewModel(mo, params, parent, 0);
}
void ViewModel::onInit(const QVariantHash &) {}
void ViewModel::showImp(const QMetaObject *mo, const QVariantHash &params, QPointer<ViewModel> parent)
void ViewModel::showResultImp(quint32 requestCode, const QMetaObject *mo, const QVariantHash &params) const
{
CoreAppPrivate::dInstance()->showViewModel(mo, params, parent);
Q_ASSERT_X(requestCode != 0, Q_FUNC_INFO, "requestCode must not be 0");
CoreAppPrivate::dInstance()->showViewModel(mo, params, const_cast<ViewModel*>(this), requestCode);
}
// ------------- Private Implementation -------------
ViewModelPrivate::ViewModelPrivate() :
deleteOnClose(true)
ViewModelPrivate::ViewModelPrivate()
{}

33
src/mvvmcore/viewmodel.h

@ -12,54 +12,53 @@
namespace QtMvvm {
class CoreApp;
class ViewModelPrivate;
class Q_MVVMCORE_EXPORT ViewModel : public QObject
{
Q_OBJECT
Q_PROPERTY(bool deleteOnClose READ deleteOnClose WRITE setDeleteOnClose NOTIFY deleteOnCloseChanged)
public:
explicit ViewModel(QObject *parent = nullptr);
~ViewModel();
virtual ViewModel *parentViewModel() const;
bool deleteOnClose() const;
template <typename TViewModel>
inline static void show(const QVariantHash &params = {});
public Q_SLOTS:
void setDeleteOnClose(bool deleteOnClose);
virtual void onInit(const QVariantHash &params);
virtual void onResult(quint32 requestCode, const QVariant &result);
Q_SIGNALS:
void deleteOnCloseChanged(bool deleteOnClose, QPrivateSignal);
void resultReady(quint32 requestCode, const QVariant &result);
protected:
template <typename TViewModel>
inline void showChild(const QVariantHash &params = {}) const;
inline void show(const QVariantHash &params = {}) const;
template <typename TViewModel>
inline void showForResult(quint32 requestCode, const QVariantHash &params = {}) const;
private:
friend class QtMvvm::CoreApp;
QScopedPointer<ViewModelPrivate> d;
static void showImp(const QMetaObject *mo, const QVariantHash &params, QPointer<ViewModel> parent);
void showResultImp(quint32 requestCode, const QMetaObject *mo, const QVariantHash &params) const;
};
// ------------- Generic Implementation -------------
template<typename TViewModel>
inline void ViewModel::show(const QVariantHash &params)
inline void ViewModel::show(const QVariantHash &params) const
{
static_assert(std::is_base_of<ViewModel, TViewModel>::value, "TViewModel must extend QtMvvm::ViewModel");
showImp(&TViewModel::staticMetaObject, params, nullptr);
showImp(&TViewModel::staticMetaObject, params, const_cast<ViewModel*>(this));
}
template<typename TViewModel>
inline void ViewModel::showChild(const QVariantHash &params) const
void ViewModel::showForResult(quint32 requestCode, const QVariantHash &params) const
{
static_assert(std::is_base_of<ViewModel, TViewModel>::value, "TViewModel must extend QtMvvm::ViewModel");
showImp(&TViewModel::staticMetaObject, params, const_cast<ViewModel*>(this));
showResultImp(requestCode, &TViewModel::staticMetaObject, params);
}
}

2
src/mvvmcore/viewmodel_p.h

@ -10,8 +10,6 @@ class ViewModelPrivate
{
public:
ViewModelPrivate();
bool deleteOnClose;
};
}

26
src/mvvmwidgets/widgetspresenter.cpp

@ -39,12 +39,8 @@ void WidgetsPresenter::present(ViewModel *viewModel, const QVariantHash &params,
{
// find and create view
auto viewMetaObject = findWidgetMetaObject(viewModel->metaObject());
if(!viewMetaObject) {
logCritical() << "Unable to find view for viewmodel of type"
<< viewModel->metaObject()->className();
viewModel->deleteLater();
return;
}
if(!viewMetaObject)
throw PresenterException("Unable to find view any matching view");
auto parentView = parent ?
qobject_cast<QWidget*>(parent->parent()) :
@ -52,11 +48,10 @@ void WidgetsPresenter::present(ViewModel *viewModel, const QVariantHash &params,
auto view = qobject_cast<QWidget*>(viewMetaObject->newInstance(Q_ARG(QtMvvm::ViewModel*, viewModel),
Q_ARG(QWidget*, parentView)));
if(!view) {
logCritical() << "Failed to create view of type"
<< viewMetaObject->className()
<< "(did you mark the constructor as Q_INVOKABLE? Required signature: \"Q_INVOKABLE Contructor(QtMvvm::ViewModel *, QWidget*);\")";
viewModel->deleteLater();
return;
throw PresenterException(QByteArrayLiteral("Failed to create view of type") +
viewMetaObject->className() +
QByteArrayLiteral("(did you mark the constructor as Q_INVOKABLE? "
"Required signature: \"Q_INVOKABLE Contructor(QtMvvm::ViewModel *, QWidget*);\")"));
}
// initialize viewmodel and view relationship
@ -75,13 +70,10 @@ void WidgetsPresenter::present(ViewModel *viewModel, const QVariantHash &params,
presented = tryPresent(view, parentView);
//handle the present result
if(presented) {
//if no lifecycle explicit on show is needed
//TODO needed?
} else {
logCritical() << "Unable to find a method that is able to present a view of type"
<< viewMetaObject->className();
if(!presented) {
view->deleteLater();
throw PresenterException(QByteArrayLiteral("Unable to find a method that is able to present a view of type") +
viewMetaObject->className());
}
}

Loading…
Cancel
Save