diff --git a/src/mvvmquick/mvvmquick.pro b/src/mvvmquick/mvvmquick.pro index 07d9251..350ed4e 100644 --- a/src/mvvmquick/mvvmquick.pro +++ b/src/mvvmquick/mvvmquick.pro @@ -1,13 +1,14 @@ TARGET = QtMvvmQuick -QT = core gui widgets mvvmcore +QT = core gui widgets mvvmcore mvvmcore-private HEADERS += \ qtmvvmquick_global.h \ - quickpresenter.h + quickpresenter.h \ + quickpresenter_p.h SOURCES += \ - quickpresenter.cpp + quickpresenter.cpp TRANSLATIONS += \ translations/qtmvvmquick_de.ts \ diff --git a/src/mvvmquick/quickpresenter.cpp b/src/mvvmquick/quickpresenter.cpp index 59e5bc9..edb9180 100644 --- a/src/mvvmquick/quickpresenter.cpp +++ b/src/mvvmquick/quickpresenter.cpp @@ -1,14 +1,30 @@ #include "quickpresenter.h" +#include "quickpresenter_p.h" + +#include +#include + +#include +#include + using namespace QtMvvm; QuickPresenter::QuickPresenter(QObject *parent) : QObject(parent), - IPresenter() + IPresenter(), + d(new QuickPresenterPrivate()) {} -void QuickPresenter::registerViewExplicitly(const QMetaObject *viewModelType, const QUrl &viewUrl) +QuickPresenter::~QuickPresenter() {} + +void QuickPresenter::addViewSearchDir(const QString &dirUrl) { + QuickPresenterPrivate::currentPresenter()->d->searchDirs.prepend(dirUrl); +} +void QuickPresenter::registerViewExplicitly(const QMetaObject *viewModelType, const QUrl &viewUrl) +{ + QuickPresenterPrivate::currentPresenter()->d->explicitMappings.insert(viewModelType, viewUrl); } void QuickPresenter::present(QtMvvm::ViewModel *viewModel, const QVariantHash ¶ms, QPointer parent) @@ -23,5 +39,63 @@ void QuickPresenter::showDialog(const QtMvvm::MessageConfig &config, QtMvvm::Mes QUrl QuickPresenter::findViewUrl(const QMetaObject *viewModelType) { + auto currentMeta = viewModelType; + while(currentMeta && currentMeta->inherits(&ViewModel::staticMetaObject)) { + if(d->explicitMappings.contains(currentMeta)) + return d->explicitMappings.value(currentMeta); + else { + QByteArray cName = currentMeta->className(); + auto lIndex = cName.lastIndexOf("ViewModel"); + if(lIndex > 0) + cName.truncate(lIndex); + for(auto dir : qAsConst(d->searchDirs)) { + QDir searchDir(dir, + QStringLiteral("%1*.qml").arg(QString::fromLatin1(cName)), + QDir::NoSort, + QDir::Files | QDir::NoDotAndDotDot | QDir::Readable); + QDirIterator iterator(searchDir, QDirIterator::Subdirectories); + if(iterator.hasNext()) { + iterator.next(); + QUrl resUrl; + if(dir.startsWith(QStringLiteral(":"))) { + resUrl.setScheme(QStringLiteral("qrc")); + resUrl.setPath(iterator.filePath().mid(1)); //skip the beginning colon + logDebug() << "TEST:" << QUrl::fromLocalFile(iterator.filePath()); + } else + resUrl = QUrl::fromLocalFile(iterator.filePath()); + logDebug() << "Found URL for viewmodel" + << viewModelType->className() + << "as:" << resUrl; + return resUrl; + } + } + } + + currentMeta = currentMeta->superClass(); + } + + return QUrl(); +} + +// ------------- Private Implementation ------------- + +QuickPresenterPrivate::QuickPresenterPrivate() : + explicitMappings(), + searchDirs({QStringLiteral(":/qtmvvm/views")}) +{} + +QuickPresenter *QuickPresenterPrivate::currentPresenter() +{ + auto presenter = static_cast(CoreAppPrivate::dInstance()->currentPresenter()); + if(!presenter) { + presenter = new QuickPresenter(); + CoreApp::setMainPresenter(presenter); + } +#ifndef Q_NO_DEBUG + Q_ASSERT_X(dynamic_cast(CoreAppPrivate::dInstance()->currentPresenter()), + Q_FUNC_INFO, + "Cannot register views if the current presenter does not extend QtMvvm::QuickPresenter"); +#endif + return presenter; } diff --git a/src/mvvmquick/quickpresenter.h b/src/mvvmquick/quickpresenter.h index ed0803e..2eb4ecf 100644 --- a/src/mvvmquick/quickpresenter.h +++ b/src/mvvmquick/quickpresenter.h @@ -2,6 +2,8 @@ #define QTMVVM_QUICKPRESENTER_H #include +#include +#include #include #include @@ -10,6 +12,7 @@ namespace QtMvvm { +class QuickPresenterPrivate; class Q_MVVMQUICK_EXPORT QuickPresenter : public QObject, public IPresenter { Q_OBJECT @@ -17,10 +20,12 @@ class Q_MVVMQUICK_EXPORT QuickPresenter : public QObject, public IPresenter public: explicit QuickPresenter(QObject *parent = nullptr); + ~QuickPresenter(); template static void registerAsPresenter(); + static void addViewSearchDir(const QString &dirUrl); template static void registerViewExplicitly(const QUrl &viewUrl); static void registerViewExplicitly(const QMetaObject *viewModelType, const QUrl &viewUrl); @@ -30,6 +35,9 @@ public: protected: virtual QUrl findViewUrl(const QMetaObject *viewModelType); + +private: + QScopedPointer d; }; template diff --git a/src/mvvmquick/quickpresenter_p.h b/src/mvvmquick/quickpresenter_p.h new file mode 100644 index 0000000..7cb139c --- /dev/null +++ b/src/mvvmquick/quickpresenter_p.h @@ -0,0 +1,24 @@ +#ifndef QTMVVM_QUICKPRESENTER_P_H +#define QTMVVM_QUICKPRESENTER_P_H + +#include + +#include "qtmvvmquick_global.h" +#include "quickpresenter.h" + +namespace QtMvvm { + +class QuickPresenterPrivate +{ +public: + QuickPresenterPrivate(); + + QHash explicitMappings; + QStringList searchDirs; + + static QuickPresenter *currentPresenter(); +}; + +} + +#endif // QTMVVM_QUICKPRESENTER_P_H diff --git a/src/mvvmwidgets/widgetspresenter.cpp b/src/mvvmwidgets/widgetspresenter.cpp index ed3e5e8..f695933 100644 --- a/src/mvvmwidgets/widgetspresenter.cpp +++ b/src/mvvmwidgets/widgetspresenter.cpp @@ -41,7 +41,7 @@ void WidgetsPresenter::registerViewExplicitly(const QMetaObject *viewModelType, { Q_ASSERT_X(viewModelType->inherits(&ViewModel::staticMetaObject), Q_FUNC_INFO, "viewModelType must be a QtMvvm::ViewModel class"); Q_ASSERT_X(viewType->inherits(&QWidget::staticMetaObject), Q_FUNC_INFO, "viewType must be a QWidget class"); - WidgetsPresenterPrivate::currentPresenter()->d->explicitMappings.insert(viewModelType->className(), viewType); + WidgetsPresenterPrivate::currentPresenter()->d->explicitMappings.insert(viewModelType, viewType); } void WidgetsPresenter::present(ViewModel *viewModel, const QVariantHash ¶ms, QPointer parent) @@ -112,10 +112,10 @@ const QMetaObject *WidgetsPresenter::findWidgetMetaObject(const QMetaObject *vie { auto currentMeta = viewModelMetaObject; while(currentMeta && currentMeta->inherits(&ViewModel::staticMetaObject)) { - QByteArray cName = currentMeta->className(); - if(d->explicitMappings.contains(cName)) - return d->explicitMappings.value(cName); + if(d->explicitMappings.contains(currentMeta)) + return d->explicitMappings.value(currentMeta); else { + QByteArray cName = currentMeta->className(); auto lIndex = cName.lastIndexOf("ViewModel"); if(lIndex > 0) cName.truncate(lIndex); @@ -401,15 +401,15 @@ WidgetsPresenterPrivate::WidgetsPresenterPrivate() : WidgetsPresenter *WidgetsPresenterPrivate::currentPresenter() { -#ifndef Q_NO_DEBUG - Q_ASSERT_X(dynamic_cast(CoreAppPrivate::dInstance()->currentPresenter()), - Q_FUNC_INFO, - "Cannot register widgets if the current presenter does not extend QtMvvm::WidgetsPresenter"); -#endif auto presenter = static_cast(CoreAppPrivate::dInstance()->currentPresenter()); if(!presenter) { presenter = new WidgetsPresenter(); CoreApp::setMainPresenter(presenter); } +#ifndef Q_NO_DEBUG + Q_ASSERT_X(dynamic_cast(CoreAppPrivate::dInstance()->currentPresenter()), + Q_FUNC_INFO, + "Cannot register widgets if the current presenter does not extend QtMvvm::WidgetsPresenter"); +#endif return presenter; } diff --git a/src/mvvmwidgets/widgetspresenter_p.h b/src/mvvmwidgets/widgetspresenter_p.h index 3987591..d884c4e 100644 --- a/src/mvvmwidgets/widgetspresenter_p.h +++ b/src/mvvmwidgets/widgetspresenter_p.h @@ -18,7 +18,7 @@ public: QScopedPointer inputViewFactory; QSet implicitMappings; - QHash explicitMappings; + QHash explicitMappings; }; }