aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates2')
-rw-r--r--src/quicktemplates2/qquickstackelement.cpp19
-rw-r--r--src/quicktemplates2/qquickstackelement_p_p.h4
-rw-r--r--src/quicktemplates2/qquickstackview.cpp34
-rw-r--r--src/quicktemplates2/qquickstackview_p.cpp18
-rw-r--r--src/quicktemplates2/qquickstackview_p_p.h4
5 files changed, 57 insertions, 22 deletions
diff --git a/src/quicktemplates2/qquickstackelement.cpp b/src/quicktemplates2/qquickstackelement.cpp
index aace170b..27331afe 100644
--- a/src/quicktemplates2/qquickstackelement.cpp
+++ b/src/quicktemplates2/qquickstackelement.cpp
@@ -122,17 +122,30 @@ QQuickStackElement::~QQuickStackElement()
delete context;
}
-QQuickStackElement *QQuickStackElement::fromString(const QString &str, QQuickStackView *view)
+QQuickStackElement *QQuickStackElement::fromString(const QString &str, QQuickStackView *view, QString *error)
{
+ QUrl url(str);
+ if (!url.isValid()) {
+ *error = QStringLiteral("invalid url: ") + str;
+ return nullptr;
+ }
+
QQuickStackElement *element = new QQuickStackElement;
- element->component = new QQmlComponent(qmlEngine(view), QUrl(str), view);
+ element->component = new QQmlComponent(qmlEngine(view), url, view);
element->ownComponent = true;
return element;
}
-QQuickStackElement *QQuickStackElement::fromObject(QObject *object, QQuickStackView *view)
+QQuickStackElement *QQuickStackElement::fromObject(QObject *object, QQuickStackView *view, QString *error)
{
Q_UNUSED(view);
+ QQmlComponent *component = qobject_cast<QQmlComponent *>(object);
+ QQuickItem *item = qobject_cast<QQuickItem *>(object);
+ if (!component && !item) {
+ *error = QQmlMetaType::prettyTypeName(object) + QStringLiteral(" is not supported. Must be Item or Component.");
+ return nullptr;
+ }
+
QQuickStackElement *element = new QQuickStackElement;
element->component = qobject_cast<QQmlComponent *>(object);
element->item = qobject_cast<QQuickItem *>(object);
diff --git a/src/quicktemplates2/qquickstackelement_p_p.h b/src/quicktemplates2/qquickstackelement_p_p.h
index 9cb11855..2308f47d 100644
--- a/src/quicktemplates2/qquickstackelement_p_p.h
+++ b/src/quicktemplates2/qquickstackelement_p_p.h
@@ -67,8 +67,8 @@ class QQuickStackElement : public QQuickItemViewTransitionableItem, public QQuic
public:
~QQuickStackElement();
- static QQuickStackElement *fromString(const QString &str, QQuickStackView *view);
- static QQuickStackElement *fromObject(QObject *object, QQuickStackView *view);
+ static QQuickStackElement *fromString(const QString &str, QQuickStackView *view, QString *error);
+ static QQuickStackElement *fromObject(QObject *object, QQuickStackView *view, QString *error);
bool load(QQuickStackView *parent);
void incubate(QObject *object);
diff --git a/src/quicktemplates2/qquickstackview.cpp b/src/quicktemplates2/qquickstackview.cpp
index dbc8c7bb..155f5f4d 100644
--- a/src/quicktemplates2/qquickstackview.cpp
+++ b/src/quicktemplates2/qquickstackview.cpp
@@ -490,7 +490,8 @@ void QQuickStackView::push(QQmlV4Function *args)
if (lastArg->isInt32())
operation = static_cast<Operation>(lastArg->toInt32());
- QList<QQuickStackElement *> elements = d->parseElements(args);
+ QStringList errors;
+ QList<QQuickStackElement *> elements = d->parseElements(0, args, &errors);
// Remove any items that are already in the stack, as they can't be in two places at once.
for (int i = 0; i < elements.size(); ) {
QQuickStackElement *element = elements.at(i);
@@ -500,8 +501,13 @@ void QQuickStackView::push(QQmlV4Function *args)
++i;
}
- if (elements.isEmpty()) {
- d->warn(QStringLiteral("nothing to push"));
+ if (!errors.isEmpty() || elements.isEmpty()) {
+ if (!errors.isEmpty()) {
+ for (const QString &error : qAsConst(errors))
+ d->warn(error);
+ } else {
+ d->warn(QStringLiteral("nothing to push"));
+ }
args->setReturnValue(QV4::Encode::null());
return;
}
@@ -733,9 +739,15 @@ void QQuickStackView::replace(QQmlV4Function *args)
else if (!firstArg->isInt32())
target = d->findElement(firstArg);
- QList<QQuickStackElement *> elements = d->parseElements(args, target ? 1 : 0);
- if (elements.isEmpty()) {
- d->warn(QStringLiteral("nothing to push"));
+ QStringList errors;
+ QList<QQuickStackElement *> elements = d->parseElements(target ? 1 : 0, args, &errors);
+ if (!errors.isEmpty() || elements.isEmpty()) {
+ if (!errors.isEmpty()) {
+ for (const QString &error : qAsConst(errors))
+ d->warn(error);
+ } else {
+ d->warn(QStringLiteral("nothing to push"));
+ }
args->setReturnValue(QV4::Encode::null());
return;
}
@@ -972,12 +984,16 @@ void QQuickStackView::componentComplete()
QQuickControl::componentComplete();
Q_D(QQuickStackView);
+ QScopedValueRollback<QString> rollback(d->operation, QStringLiteral("initialItem"));
QQuickStackElement *element = nullptr;
+ QString error;
if (QObject *o = d->initialItem.value<QObject *>())
- element = QQuickStackElement::fromObject(o, this);
+ element = QQuickStackElement::fromObject(o, this, &error);
else if (d->initialItem.canConvert<QString>())
- element = QQuickStackElement::fromString(d->initialItem.toString(), this);
- if (d->pushElement(element)) {
+ element = QQuickStackElement::fromString(d->initialItem.toString(), this, &error);
+ if (!error.isEmpty()) {
+ d->warn(error);
+ } else if (d->pushElement(element)) {
emit depthChanged();
d->setCurrentItem(element);
element->setStatus(QQuickStackView::Active);
diff --git a/src/quicktemplates2/qquickstackview_p.cpp b/src/quicktemplates2/qquickstackview_p.cpp
index 077c13e3..c6f9291d 100644
--- a/src/quicktemplates2/qquickstackview_p.cpp
+++ b/src/quicktemplates2/qquickstackview_p.cpp
@@ -90,7 +90,7 @@ static bool initProperties(QQuickStackElement *element, const QV4::Value &props,
return false;
}
-QList<QQuickStackElement *> QQuickStackViewPrivate::parseElements(QQmlV4Function *args, int from)
+QList<QQuickStackElement *> QQuickStackViewPrivate::parseElements(int from, QQmlV4Function *args, QStringList *errors)
{
QV4::ExecutionEngine *v4 = args->v4engine();
QV4::Scope scope(v4);
@@ -103,8 +103,9 @@ QList<QQuickStackElement *> QQuickStackViewPrivate::parseElements(QQmlV4Function
if (QV4::ArrayObject *array = arg->as<QV4::ArrayObject>()) {
int len = array->getLength();
for (int j = 0; j < len; ++j) {
+ QString error;
QV4::ScopedValue value(scope, array->getIndexed(j));
- QQuickStackElement *element = createElement(value);
+ QQuickStackElement *element = createElement(value, &error);
if (element) {
if (j < len - 1) {
QV4::ScopedValue props(scope, array->getIndexed(j + 1));
@@ -112,10 +113,13 @@ QList<QQuickStackElement *> QQuickStackViewPrivate::parseElements(QQmlV4Function
++j;
}
elements += element;
+ } else if (!error.isEmpty()) {
+ *errors += error;
}
}
} else {
- QQuickStackElement *element = createElement(arg);
+ QString error;
+ QQuickStackElement *element = createElement(arg, &error);
if (element) {
if (i < argc - 1) {
QV4::ScopedValue props(scope, (*args)[i + 1]);
@@ -123,6 +127,8 @@ QList<QQuickStackElement *> QQuickStackViewPrivate::parseElements(QQmlV4Function
++i;
}
elements += element;
+ } else if (!error.isEmpty()) {
+ *errors += error;
}
}
}
@@ -147,13 +153,13 @@ QQuickStackElement *QQuickStackViewPrivate::findElement(const QV4::Value &value)
return nullptr;
}
-QQuickStackElement *QQuickStackViewPrivate::createElement(const QV4::Value &value)
+QQuickStackElement *QQuickStackViewPrivate::createElement(const QV4::Value &value, QString *error)
{
Q_Q(QQuickStackView);
if (const QV4::String *s = value.as<QV4::String>())
- return QQuickStackElement::fromString(s->toQString(), q);
+ return QQuickStackElement::fromString(s->toQString(), q, error);
if (const QV4::QObjectWrapper *o = value.as<QV4::QObjectWrapper>())
- return QQuickStackElement::fromObject(o->object(), q);
+ return QQuickStackElement::fromObject(o->object(), q, error);
return nullptr;
}
diff --git a/src/quicktemplates2/qquickstackview_p_p.h b/src/quicktemplates2/qquickstackview_p_p.h
index 532a2b57..26d741f8 100644
--- a/src/quicktemplates2/qquickstackview_p_p.h
+++ b/src/quicktemplates2/qquickstackview_p_p.h
@@ -76,10 +76,10 @@ public:
void setCurrentItem(QQuickStackElement *element);
- QList<QQuickStackElement *> parseElements(QQmlV4Function *args, int from = 0);
+ QList<QQuickStackElement *> parseElements(int from, QQmlV4Function *args, QStringList *errors);
QQuickStackElement *findElement(QQuickItem *item) const;
QQuickStackElement *findElement(const QV4::Value &value) const;
- QQuickStackElement *createElement(const QV4::Value &value);
+ QQuickStackElement *createElement(const QV4::Value &value, QString *error);
bool pushElements(const QList<QQuickStackElement *> &elements);
bool pushElement(QQuickStackElement *element);
bool popElements(QQuickStackElement *element);