plasma-framework/scriptengines/qml/declarative/qmlobject.cpp
Marco Martin 0b24d969fe show an error message on QML parse error
the error message is QML itself, coming from the Corona package (so there is the possibility that even the error message can't parse, in this case we have no way to show an error)

the user of the qml plasmoid still can't set a message on his own (setFailedToLaunch will probably become scriptengine only)
2013-02-12 15:57:42 +01:00

203 lines
4.5 KiB
C++

/*
* Copyright 2010 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "qmlobject.h"
#include <QQmlComponent>
#include <QQmlEngine>
#include <QQmlContext>
#include <QTimer>
#include <kdebug.h>
#include <kdeclarative.h>
#include "packageaccessmanagerfactory.h"
//#include "private/declarative/dataenginebindings_p.h"
class QmlObjectPrivate
{
public:
QmlObjectPrivate(QmlObject *parent)
: q(parent),
engine(0),
component(0),
root(0),
delay(false)
{
}
~QmlObjectPrivate()
{
}
void errorPrint();
void execute(const QString &fileName);
void scheduleExecutionEnd();
void minimumWidthChanged();
void minimumHeightChanged();
void maximumWidthChanged();
void maximumHeightChanged();
void preferredWidthChanged();
void preferredHeightChanged();
QmlObject *q;
QString qmlPath;
QQmlEngine* engine;
QQmlComponent* component;
QObject *root;
bool delay : 1;
};
void QmlObjectPrivate::errorPrint()
{
QString errorStr = "Error loading QML file.\n";
if(component->isError()){
QList<QQmlError> errors = component->errors();
foreach (const QQmlError &error, errors) {
errorStr += (error.line()>0?QString(QString::number(error.line()) + QLatin1String(": ")):QLatin1String(""))
+ error.description() + '\n';
}
}
kWarning() << component->url().toString() + '\n' + errorStr;
}
void QmlObjectPrivate::execute(const QString &fileName)
{
if (fileName.isEmpty()) {
#ifndef NDEBUG
kDebug() << "File name empty!";
#endif
return;
}
delete component;
component = new QQmlComponent(engine, q);
delete root;
root = 0;
KDeclarative kdeclarative;
kdeclarative.setDeclarativeEngine(engine);
kdeclarative.initialize();
//binds things like kconfig and icons
kdeclarative.setupBindings();
component->loadUrl(QUrl::fromLocalFile(fileName));
if (delay) {
QTimer::singleShot(0, q, SLOT(scheduleExecutionEnd()));
} else {
scheduleExecutionEnd();
}
}
void QmlObjectPrivate::scheduleExecutionEnd()
{
if (component->isReady() || component->isError()) {
q->completeInitialization();
} else {
QObject::connect(component, SIGNAL(statusChanged(QQmlComponent::Status)), q, SLOT(completeInitialization()));
}
}
QmlObject::QmlObject(QObject *parent)
: QObject(parent),
d(new QmlObjectPrivate(this))
{
d->engine = new QQmlEngine(this);
//d->engine->setNetworkAccessManagerFactory(new PackageAccessManagerFactory());
}
QmlObject::~QmlObject()
{
// QDeclarativeNetworkAccessManagerFactory *factory = d->engine->networkAccessManagerFactory();
// d->engine->setNetworkAccessManagerFactory(0);
// delete factory;
delete d;
}
void QmlObject::setQmlPath(const QString &path)
{
qDebug() << "Opening" << path;
d->qmlPath = path;
d->execute(path);
}
QString QmlObject::qmlPath() const
{
return d->qmlPath;
}
void QmlObject::setInitializationDelayed(const bool delay)
{
d->delay = delay;
}
bool QmlObject::isInitializationDelayed() const
{
return d->delay;
}
QQmlEngine* QmlObject::engine()
{
return d->engine;
}
QObject *QmlObject::rootObject() const
{
return d->root;
}
QQmlComponent *QmlObject::mainComponent() const
{
return d->component;
}
void QmlObject::completeInitialization()
{
if (d->root) {
return;
}
if (d->component->status() != QQmlComponent::Ready || d->component->isError()) {
d->errorPrint();
return;
}
d->root = d->component->create();
if (!d->root) {
d->errorPrint();
}
#ifndef NDEBUG
kDebug() << "Execution of QML done!";
#endif
emit finished();
}
#include "moc_qmlobject.cpp"