blob: 2f41ab6ba03d9579de8ecbaeb7776ada15872c1a [file] [log] [blame]
/*
* Copyright 2013 Canonical Ltd.
* Copyright 2011 Wolfgang Koller - http://www.gofg.at/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cordova.h"
#include <QtGui>
#include <QApplication>
#include <QQuickView>
#include <QQuickItem>
#include <QQmlContext>
Cordova::Cordova(const QDir &wwwDir, QQuickItem *item, QObject *parent)
: QObject(parent), _item(item), _www(wwwDir),
_config(_www.absoluteFilePath("../config.xml")) {
qDebug() << "Work directory: " << _www.absolutePath();
if (_config.content().contains(QRegExp("^(http://)"))) {
_mainUrl = QString(_config.content());
} else if (!_www.exists(_config.content())) {
qCritical() << _config.content() << "does not exist";
} else {
_mainUrl = QUrl::fromLocalFile(_www.absoluteFilePath(_config.content()))
.toString();
}
qDebug() << "Main URL: " << _mainUrl;
}
void Cordova::appLoaded() {
initPlugins();
for (QSharedPointer<CPlugin> &plugin: _plugins) {
plugin->onAppLoaded();
}
}
QString Cordova::get_app_dir() {
return _www.absolutePath();
}
struct Splash {
double rating;
QString path;
};
QString Cordova::getSplashscreenPath() {
double ratio = (double)_item->width() / _item->height();
QDir dir(get_app_dir());
if (!dir.cd("splashscreen"))
return "";
QList<Splash> images;
for (QFileInfo info: dir.entryInfoList()) {
QImage image(info.absoluteFilePath());
if (image.isNull())
continue;
Splash t;
t.path = info.absoluteFilePath();
t.rating = std::abs((image.width() / (double)_item->width()) * ((image.width() / image.height()) / ratio) - 1);
images.push_back(t);
}
std::min_element(images.begin(), images.end(), [](Splash &f, Splash &s) {
return f.rating < s.rating;
});
if (!images.empty())
return images.first().path;
return "";
}
const CordovaInternal::Config& Cordova::config() const {
return _config;}
void Cordova::initPlugins() {
static bool alreadyLoaded = false;
if (alreadyLoaded)
return;
QList<QDir> searchPath = {get_app_dir()};
_plugins.clear();
for (QDir pluginsDir: searchPath) {
for (const QString &fileName: pluginsDir.entryList(QDir::Files)) {
QString path = pluginsDir.absoluteFilePath(fileName);
qDebug() << "Testing" << path;
if (!QLibrary::isLibrary(path))
continue;
CordovaGetPluginInstances loader = (CordovaGetPluginInstances) QLibrary::resolve(path, "cordovaGetPluginInstances");
if (!loader) {
qCritical() << "Missing cordovaGetPluginInstances symbol in" << path;
continue;
}
auto plugins = (*loader)(this);
for (QSharedPointer<CPlugin> plugin: plugins) {
qDebug() << "Enable plugin" << plugin->fullName();
emit pluginWantsToBeAdded(plugin->fullName(), plugin.data(), plugin->shortName());
}
_plugins += plugins;
}
}
alreadyLoaded = true;
}
void Cordova::loadFinished(bool ok) {
Q_UNUSED(ok)
initPlugins();
}
void Cordova::execQML(const QString &src) {
emit qmlExecNeeded(src);
}
void Cordova::execJS(const QString &js) {
emit javaScriptExecNeeded(js);
}
QString Cordova::mainUrl() const {
return _mainUrl;
}
QObject *Cordova::topLevelEventsReceiver() {
return dynamic_cast<QQuickWindow*>(_item->window());
}
QQuickItem *Cordova::rootObject() {
return _item->parentItem();
}
void Cordova::setTitle(const QString &title) {
dynamic_cast<QQuickWindow*>(_item->window())->setTitle(title);
}
void Cordova::pushViewState(const QString &state) {
if (_states.empty()) {
rootObject()->setState(state);
}
_states.push_front(state);
}
void Cordova::popViewState(const QString &state) {
if (!_states.removeOne(state))
qDebug() << "WARNING: incorrect view states order";
if (_states.empty()) {
rootObject()->setState("main");
} else {
rootObject()->setState(_states.front());
}
}