Loader.cpp Example File
loader/src/Loader.cpp
#include "Loader.hpp"
using namespace bb::cascades;
static QDeclarativeEngine* qmlEngine(QObject *object)
{
QDeclarativeContext *context = QDeclarativeEngine::contextForObject(object);
return (context ? context->engine() : 0);
}
Loader::Loader(bb::cascades::Container *parent)
: CustomControl(parent)
, m_control(0)
, m_component(0)
, m_ownsComponent(false)
{
setVisible(false);
}
Loader::~Loader()
{
}
QUrl Loader::source() const
{
return m_source;
}
void Loader::setSource(const QUrl &url)
{
if (m_source == url)
return;
clear();
m_source = url;
if (m_source.isEmpty()) {
emit sourceChanged();
emit statusChanged();
emit progressChanged();
emit controlChanged();
return;
}
m_component = new QDeclarativeComponent(qmlEngine(this), m_source, this);
m_ownsComponent = true;
load();
}
QDeclarativeComponent* Loader::sourceComponent() const
{
return m_component;
}
void Loader::setSourceComponent(QDeclarativeComponent *component)
{
if (m_component == component)
return;
clear();
m_component = component;
m_ownsComponent = false;
if (!m_component) {
emit sourceChanged();
emit statusChanged();
emit progressChanged();
emit controlChanged();
return;
}
load();
}
void Loader::resetSourceComponent()
{
setSourceComponent(0);
}
Loader::Status Loader::status() const
{
if (m_component)
return static_cast<Loader::Status>(m_component->status());
if (m_control)
return Ready;
return (m_source.isEmpty() ? Null : Error);
}
qreal Loader::progress() const
{
if (m_control)
return 1.0;
if (m_component)
return m_component->progress();
return 0.0;
}
bb::cascades::Control* Loader::control() const
{
return m_control;
}
void Loader::sourceLoaded()
{
if (m_component) {
if (!m_component->errors().isEmpty()) {
emit statusChanged();
emit progressChanged();
emit sourceChanged();
emit controlChanged();
return;
}
QDeclarativeContext *creationContext = m_component->creationContext();
if (!creationContext)
creationContext = QDeclarativeEngine::contextForObject(this);
QDeclarativeContext *ctxt = new QDeclarativeContext(creationContext);
ctxt->setContextObject(this);
QObject *object = m_component->create(ctxt);
if (object) {
m_control = qobject_cast<bb::cascades::Control*>(object);
if (m_control) {
setRoot(m_control);
setVisible(true);
} else {
qmlInfo(this) << tr("Loader does not support loading non-visual elements.");
delete object;
delete ctxt;
}
} else {
delete object;
delete ctxt;
m_source = QUrl();
}
emit sourceChanged();
emit statusChanged();
emit progressChanged();
emit controlChanged();
emit loaded();
}
}
void Loader::clear()
{
if (m_ownsComponent) {
m_component->deleteLater();
m_component = 0;
m_ownsComponent = false;
}
m_source = QUrl();
if (m_control) {
setRoot(0);
setVisible(false);
m_control->deleteLater();
m_control = 0;
}
}
void Loader::load()
{
if (!m_component)
return;
if (!m_component->isLoading()) {
sourceLoaded();
} else {
bool ok = connect(m_component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),
this, SLOT(sourceLoaded()));
Q_ASSERT(ok);
ok = connect(m_component, SIGNAL(progressChanged(qreal)),
this, SIGNAL(progressChanged()));
Q_ASSERT(ok);
emit statusChanged();
emit progressChanged();
emit sourceChanged();
emit controlChanged();
}
}