示例#1
0
// Re-init the LP replication target
QJsonObject LifePreserver::initReplication(QJsonObject jsin) {
   QJsonObject retObject;
   QString dset, rhost;

   QStringList keys = jsin.keys();
   if(! keys.contains("dataset") || ! keys.contains("host")){
     retObject.insert("error", "Missing dataset or host key");
     return retObject;
   }

   // Check which pool we are looking at
   dset = jsin.value("dataset").toString();
   rhost = jsin.value("host").toString();

   // Make sure we have the pool key
   if ( dset.isEmpty() || rhost.isEmpty()) {
     retObject.insert("error", "Missing dataset or host key");
     return retObject;
   }

   // TODO - This command can take a LONG TIME. Find a way to queue / background it and return an event
   // via websockets later, or block here and return when finished if this is REST
   QStringList output = General::RunCommand("lpreserver replicate init " + dset + " " + rhost).split("\n");

   // Check for any errors
   for ( int i = 0; i < output.size(); i++)
   {
      if ( output.at(i).indexOf("ERROR:") != -1 ) {
       retObject.insert("error", output.at(i));
       return retObject;
      }
   }

   QJsonObject values;
   values.insert("dataset", dset);
   values.insert("host", rhost);
   return values;
}
示例#2
0
void TestWebChannel::testInfoForObject()
{
    TestObject obj;
    obj.setObjectName("myTestObject");

    QWebChannel channel;
    const QJsonObject info = channel.d_func()->publisher->classInfoForObject(&obj, m_dummyTransport);

    QCOMPARE(info.keys(), QStringList() << "enums" << "methods" << "properties" << "signals");

    { // enums
        QJsonObject fooEnum;
        fooEnum["Asdf"] = TestObject::Asdf;
        fooEnum["Bar"] = TestObject::Bar;
        QJsonObject expected;
        expected["Foo"] = fooEnum;
        QCOMPARE(info["enums"].toObject(), expected);
    }

    { // methods & slots
        QJsonArray expected;
        {
            QJsonArray method;
            method.append(QStringLiteral("deleteLater"));
            method.append(obj.metaObject()->indexOfMethod("deleteLater()"));
            expected.append(method);
        }
        {
            QJsonArray method;
            method.append(QStringLiteral("slot1"));
            method.append(obj.metaObject()->indexOfMethod("slot1()"));
            expected.append(method);
        }
        {
            QJsonArray method;
            method.append(QStringLiteral("slot2"));
            method.append(obj.metaObject()->indexOfMethod("slot2(QString)"));
            expected.append(method);
        }
        {
            QJsonArray method;
            method.append(QStringLiteral("method1"));
            method.append(obj.metaObject()->indexOfMethod("method1()"));
            expected.append(method);
        }
        QCOMPARE(info["methods"].toArray(), expected);
    }

    { // signals
        QJsonArray expected;
        {
            QJsonArray signal;
            signal.append(QStringLiteral("destroyed"));
            signal.append(obj.metaObject()->indexOfMethod("destroyed(QObject*)"));
            expected.append(signal);
        }
        {
            QJsonArray signal;
            signal.append(QStringLiteral("sig1"));
            signal.append(obj.metaObject()->indexOfMethod("sig1()"));
            expected.append(signal);
        }
        {
            QJsonArray signal;
            signal.append(QStringLiteral("sig2"));
            signal.append(obj.metaObject()->indexOfMethod("sig2(QString)"));
            expected.append(signal);
        }
        QCOMPARE(info["signals"].toArray(), expected);
    }

    { // properties
        QJsonArray expected;
        {
            QJsonArray property;
            property.append(obj.metaObject()->indexOfProperty("objectName"));
            property.append(QStringLiteral("objectName"));
            {
                QJsonArray signal;
                signal.append(1);
                signal.append(obj.metaObject()->indexOfMethod("objectNameChanged(QString)"));
                property.append(signal);
            }
            property.append(obj.objectName());
            expected.append(property);
        }
        {
            QJsonArray property;
            property.append(obj.metaObject()->indexOfProperty("foo"));
            property.append(QStringLiteral("foo"));
            {
                QJsonArray signal;
                property.append(signal);
            }
            property.append(obj.foo());
            expected.append(property);
        }
        {
            QJsonArray property;
            property.append(obj.metaObject()->indexOfProperty("asdf"));
            property.append(QStringLiteral("asdf"));
            {
                QJsonArray signal;
                signal.append(1);
                signal.append(obj.metaObject()->indexOfMethod("asdfChanged()"));
                property.append(signal);
            }
            property.append(obj.asdf());
            expected.append(property);
        }
        {
            QJsonArray property;
            property.append(obj.metaObject()->indexOfProperty("bar"));
            property.append(QStringLiteral("bar"));
            {
                QJsonArray signal;
                signal.append(QStringLiteral("theBarHasChanged"));
                signal.append(obj.metaObject()->indexOfMethod("theBarHasChanged()"));
                property.append(signal);
            }
            property.append(obj.bar());
            expected.append(property);
        }
        QCOMPARE(info["properties"].toArray(), expected);
    }
}
示例#3
0
// Note: See MaterialEntityItem.h for default values used in practice.
std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource::parseJSONMaterial(const QJsonObject& materialJSON, const QUrl& baseUrl) {
    std::string name = "";
    std::shared_ptr<NetworkMaterial> material = std::make_shared<NetworkMaterial>();
    for (auto& key : materialJSON.keys()) {
        if (key == "name") {
            auto nameJSON = materialJSON.value(key);
            if (nameJSON.isString()) {
                name = nameJSON.toString().toStdString();
            }
        } else if (key == "model") {
            auto modelJSON = materialJSON.value(key);
            if (modelJSON.isString()) {
                material->setModel(modelJSON.toString().toStdString());
            }
        } else if (key == "emissive") {
            glm::vec3 color;
            bool isSRGB;
            bool valid = parseJSONColor(materialJSON.value(key), color, isSRGB);
            if (valid) {
                material->setEmissive(color, isSRGB);
            }
        } else if (key == "opacity") {
            auto value = materialJSON.value(key);
            if (value.isDouble()) {
                material->setOpacity(value.toDouble());
            }
        } else if (key == "unlit") {
            auto value = materialJSON.value(key);
            if (value.isBool()) {
                material->setUnlit(value.toBool());
            }
        } else if (key == "albedo") {
            glm::vec3 color;
            bool isSRGB;
            bool valid = parseJSONColor(materialJSON.value(key), color, isSRGB);
            if (valid) {
                material->setAlbedo(color, isSRGB);
            }
        } else if (key == "roughness") {
            auto value = materialJSON.value(key);
            if (value.isDouble()) {
                material->setRoughness(value.toDouble());
            }
        } else if (key == "metallic") {
            auto value = materialJSON.value(key);
            if (value.isDouble()) {
                material->setMetallic(value.toDouble());
            }
        } else if (key == "scattering") {
            auto value = materialJSON.value(key);
            if (value.isDouble()) {
                material->setScattering(value.toDouble());
            }
        } else if (key == "emissiveMap") {
            auto value = materialJSON.value(key);
            if (value.isString()) {
                material->setEmissiveMap(baseUrl.resolved(value.toString()));
            }
        } else if (key == "albedoMap") {
            auto value = materialJSON.value(key);
            if (value.isString()) {
                QString urlString = value.toString();
                bool useAlphaChannel = false;
                auto opacityMap = materialJSON.find("opacityMap");
                if (opacityMap != materialJSON.end() && opacityMap->isString() && opacityMap->toString() == urlString) {
                    useAlphaChannel = true;
                }
                material->setAlbedoMap(baseUrl.resolved(urlString), useAlphaChannel);
            }
        } else if (key == "roughnessMap") {
            auto value = materialJSON.value(key);
            if (value.isString()) {
                material->setRoughnessMap(baseUrl.resolved(value.toString()), false);
            }
        } else if (key == "glossMap") {
            auto value = materialJSON.value(key);
            if (value.isString()) {
                material->setRoughnessMap(baseUrl.resolved(value.toString()), true);
            }
        } else if (key == "metallicMap") {
            auto value = materialJSON.value(key);
            if (value.isString()) {
                material->setMetallicMap(baseUrl.resolved(value.toString()), false);
            }
        } else if (key == "specularMap") {
            auto value = materialJSON.value(key);
            if (value.isString()) {
                material->setMetallicMap(baseUrl.resolved(value.toString()), true);
            }
        } else if (key == "normalMap") {
            auto value = materialJSON.value(key);
            if (value.isString()) {
                material->setNormalMap(baseUrl.resolved(value.toString()), false);
            }
        } else if (key == "bumpMap") {
            auto value = materialJSON.value(key);
            if (value.isString()) {
                material->setNormalMap(baseUrl.resolved(value.toString()), true);
            }
        } else if (key == "occlusionMap") {
            auto value = materialJSON.value(key);
            if (value.isString()) {
                material->setOcclusionMap(baseUrl.resolved(value.toString()));
            }
        } else if (key == "scatteringMap") {
            auto value = materialJSON.value(key);
            if (value.isString()) {
                material->setScatteringMap(baseUrl.resolved(value.toString()));
            }
        } else if (key == "lightMap") {
            auto value = materialJSON.value(key);
            if (value.isString()) {
                material->setLightmapMap(baseUrl.resolved(value.toString()));
            }
        }
    }
    return std::pair<std::string, std::shared_ptr<NetworkMaterial>>(name, material);
}
bool ParupaintPanvasInputOutput::loadPPA(ParupaintPanvas * panvas, const QString & filename, QString & errorStr)
{
	Q_ASSERT(panvas);

	KZip archive(filename);
	if(!archive.open(QIODevice::ReadOnly))
		return (errorStr = "Couldn't read PPA").isEmpty();

	const QString pp3("pp3.json");
	const KArchiveDirectory * topdir = archive.directory();

	// be sure it has the files
	if(!topdir->entry(pp3))
		return (errorStr = "File is not PPA.").isEmpty();

	const KArchiveFile * json_file = dynamic_cast<const KArchiveFile*>(topdir->entry(pp3));
	if(!json_file)
		return (errorStr = "Couldn't read info file in PPA.").isEmpty();

	QJsonParseError err;
	QJsonDocument info_doc = QJsonDocument::fromJson(json_file->data(), &err);
	if(err.error != QJsonParseError::NoError)
		return (errorStr = "Couldn't read json info: " + err.errorString()).isEmpty();

	QJsonObject main_obj = info_doc.object();
	if(!main_obj.contains("canvasWidth") || !main_obj.contains("canvasHeight"))
		return (errorStr = "Width/height not specified.").isEmpty();

	// load the canvas settings
	panvas->loadJson(main_obj);

	// load the image frames
	QJsonObject layers = main_obj.value("layers").toObject();
	foreach(const QString & lk, layers.keys()) {

		const QJsonObject & lo = layers.value(lk).toObject();
		const QJsonObject & ff = lo.value("frames").toObject();
		ParupaintLayer * layer = panvas->layerAt(lk.toInt());

		foreach(const QString & fk, ff.keys()){
			const QJsonObject & fo = ff.value(fk).toObject();

			int framenum = fk.toInt();
			if(fk.contains('-')){
				framenum = fk.section('-', 0, 0).toInt();
			}

			const QString fname(QString("%1/%2.png").arg(lk.toInt()).arg(fk));
			const KArchiveFile * img_file = dynamic_cast<const KArchiveFile*>(topdir->entry(fname));
			if(!img_file) continue;

			// load the image
			QImage img(panvas->dimensions(), QImage::Format_ARGB32);
			img.loadFromData(img_file->data());

			ParupaintFrame * frame = layer->frameAt(framenum);
			frame->replaceImage(img);
		}
	}
	return true;
}
示例#5
0
void MainWindow::handleNetworkData(QNetworkReply *networkReply) {
    if (!networkReply->error()) {
        QByteArray response(networkReply->readAll());
        QJsonDocument jsonDoc = QJsonDocument::fromJson(response);

        QJsonObject result = jsonDoc.object();
        QMessageLogger().debug() <<networkReply->objectName();
        if (networkReply->objectName() == "logout") {
            if (result.value("error").toBool(true)) {
                QMessageBox msgBox;
                msgBox.setText(result["error"].toString());
                msgBox.exec();
                QMessageLogger().debug() << response;
            }
        } else if (networkReply->objectName() == "sync") {
            if (result.value("time") != QJsonValue::Undefined) {
                MainWindow::sharedData()->timestamp = (quint32)result.value("time").toDouble();
                timer->start(60000);
            } else {
                if (result.value("error") != QJsonValue::Undefined) {
                    QMessageBox msgBox;
                    msgBox.setText(result["error"].toString());
                    msgBox.exec();
                    QMessageLogger().debug() << response;
                }

                ui->trackBtn->setText("Start");
                isTracking = false;
                this->updateActionsStatus();
                ui->contractsCombo->setEnabled(true);
            }
        } else if (networkReply->objectName() == "timelog") {
            QJsonObject status = result.value("status").toObject();
            QStringList list = status.keys();
            bool success = false;
            int errorCode = 0;
            for (int i=0; i<list.count(); i++) {
                QString key = list.value(i);
                QJsonObject snap = status.value(key).toObject();
                if (snap.value("error").toInt() == 0) {
                    success = true;
                } else {
                    errorCode = snap.value("error").toInt();
                }
            }

            if (success || (errorCode == 2)) {
                trayIcon->showMessage("Screenshot", "Just uploaded screenshot and logs of keyboard and mouse.",QSystemTrayIcon::Information, 5000);
                QString imagePath = networkReply->property("imagePath").toString();
                QFile file(imagePath);
                file.remove();
                if (!isUploadingCache)
                    uploadCacheData();
            } else {
                quint32 timestamp = (quint32)networkReply->property("timestamp").toDouble();
                QString imagePath = networkReply->property("imagePath").toString();
                QByteArray jwt = networkReply->request().rawHeader("JWT");

                QSettings settings("WawJob", "WawTracker");
                settings.setValue("cache/" + QString("%1").arg(timestamp) + "/imagePath", imagePath);
                settings.setValue("cache/" + QString("%1").arg(timestamp) + "/jwt", jwt);
            }
            QFile data("logging.txt");
            if (data.open(QFile::WriteOnly | QFile::Append)) {
                QTextStream out(&data);
                out << response;
            }
            QMessageLogger().debug() << response;
        } else if (networkReply->objectName() == "timelog_cache") {
            QMessageLogger().debug() << response;
            QJsonObject status = result.value("status").toObject();
            QStringList list = status.keys();
            bool success = false;
            int errorCode = 0;
            for (int i=0; i<list.count(); i++) {
                QString key = list.value(i);
                QJsonObject snap = status.value(key).toObject();
                if (snap.value("error").toInt() == 0) {
                    success = true;
                } else {
                    errorCode = snap.value("error").toInt();
                }
            }

            if (success || (errorCode == 2)) {
                QString imagePath = networkReply->property("imagePath").toString();
                QFile file(imagePath);
                file.remove();

                QString timestamp = networkReply->property("timestamp").toString();
                QSettings settings("WawJob", "WawTracker");
                settings.remove("cache/"+timestamp);

                uploadCacheData();
            } else {
                isUploadingCache = false;
            }
        }
    } else {
        if (networkReply->objectName() == "sync") {
            stopTrack();
        } else if (networkReply->objectName() == "timelog") {
            quint32 timestamp = (quint32)networkReply->property("timestamp").toDouble();
            QString imagePath = networkReply->property("imagePath").toString();
            QByteArray jwt = networkReply->request().rawHeader("JWT");

            QSettings settings("WawJob", "WawTracker");
            settings.setValue("cache/" + QString("%1").arg(timestamp) + "/imagePath", imagePath);
            settings.setValue("cache/" + QString("%1").arg(timestamp) + "/jwt", jwt);
        }else if (networkReply->objectName() == "timelog_cache") {
            isUploadingCache = false;
        }else {
            QMessageBox msgBox;
            msgBox.setText(networkReply->errorString());
            msgBox.exec();
        }
        QMessageLogger().debug() <<networkReply->objectName() << networkReply->errorString();
        QFile data("logging.txt");
        if (data.open(QFile::WriteOnly | QFile::Append)) {
            QTextStream out(&data);
            out <<networkReply->objectName() << networkReply->errorString();
        }

    }

    networkReply->deleteLater();
}
bool DomainServerSettingsManager::handleHTTPRequest(HTTPConnection* connection, const QUrl &url) {
    if (connection->requestOperation() == QNetworkAccessManager::PostOperation && url.path() == "/settings.json") {
        // this is a POST operation to change one or more settings
        QJsonDocument postedDocument = QJsonDocument::fromJson(connection->requestContent());
        QJsonObject postedObject = postedDocument.object();
        
        // we recurse one level deep below each group for the appropriate setting
        recurseJSONObjectAndOverwriteSettings(postedObject, _settingsMap, _descriptionObject);
        
        // store whatever the current _settingsMap is to file
        persistToFile();
        
        // return success to the caller
        QString jsonSuccess = "{\"status\": \"success\"}";
        connection->respond(HTTPConnection::StatusCode200, jsonSuccess.toUtf8(), "application/json");
        
        return true;
    } else if (connection->requestOperation() == QNetworkAccessManager::GetOperation && url.path() == "/settings.json") {
        // this is a GET operation for our settings
        
        // check if there is a query parameter for settings affecting a particular type of assignment
        const QString SETTINGS_TYPE_QUERY_KEY = "type";
        QUrlQuery settingsQuery(url);
        QString typeValue = settingsQuery.queryItemValue(SETTINGS_TYPE_QUERY_KEY);
        
        QJsonObject responseObject;
        
        if (typeValue.isEmpty()) {
            // combine the description object and our current settings map
            responseObject["descriptions"] = _descriptionObject;
            responseObject["values"] = QJsonDocument::fromVariant(_settingsMap).object();
        } else {
            // convert the string type value to a QJsonValue
            QJsonValue queryType = QJsonValue(typeValue.toInt());
            
            const QString AFFECTED_TYPES_JSON_KEY = "assignment-types";
            
            // enumerate the groups in the description object to find which settings to pass
            foreach(const QString& group, _descriptionObject.keys()) {
                QJsonObject groupObject = _descriptionObject[group].toObject();
                QJsonObject groupSettingsObject = groupObject[DESCRIPTION_SETTINGS_KEY].toObject();
                
                QJsonObject groupResponseObject;
                
                
                foreach(const QString& settingKey, groupSettingsObject.keys()) {
                    QJsonObject settingObject = groupSettingsObject[settingKey].toObject();
                    
                    QJsonArray affectedTypesArray = settingObject[AFFECTED_TYPES_JSON_KEY].toArray();
                    if (affectedTypesArray.isEmpty()) {
                        affectedTypesArray = groupObject[AFFECTED_TYPES_JSON_KEY].toArray();
                    }
                    
                    if (affectedTypesArray.contains(queryType)) {
                        // this is a setting we should include in the responseObject
                        
                        // we need to check if the settings map has a value for this setting
                        QVariant variantValue;
                        QVariant settingsMapGroupValue = _settingsMap.value(group);
                        
                        if (!settingsMapGroupValue.isNull()) {
                            variantValue = settingsMapGroupValue.toMap().value(settingKey);
                        }
                        
                        if (variantValue.isNull()) {
                            // no value for this setting, pass the default
                            groupResponseObject[settingKey] = settingObject[SETTING_DEFAULT_KEY];
                        } else {
                            groupResponseObject[settingKey] = QJsonValue::fromVariant(variantValue);
                        }
                    }
                }
                
                if (!groupResponseObject.isEmpty()) {
                    // set this group's object to the constructed object
                    responseObject[group] = groupResponseObject;
                }
            }
            
        }
        
        connection->respond(HTTPConnection::StatusCode200, QJsonDocument(responseObject).toJson(), "application/json");
        return true;
    }
    
    return false;
}
示例#7
0
void ShowDetailWidget::parseSubtitles(int episode, const QByteArray &response)
{
    JsonParser parser(response);
    if (!parser.isValid()) {
        // TODO manage error
        return;
    }

    if (!QSqlDatabase::database().transaction()) {
        qCritical("Error while beginning a transaction for SQL insertion");
        return;
    }

    // remove all subtitles for an episode
    QSqlQuery query;
    query.prepare("DELETE FROM subtitle WHERE show_id=:show_id AND season=:season AND episode=:episode");
    query.bindValue(":show_id", _showId);
    query.bindValue(":season", _season);
    query.bindValue(":episode", episode);
    query.exec();

    QJsonObject subtitlesJson = parser.root().value("subtitles").toObject();
    foreach (const QString &key, subtitlesJson.keys()) {
        QJsonObject subtitleJson = subtitlesJson.value(key).toObject();
        if (subtitleJson.isEmpty())
            continue;

        QString language = subtitleJson.value("language").toString();
        QString source = subtitleJson.value("source").toString();
        QString file = subtitleJson.value("file").toString();
        QString url = subtitleJson.value("url").toString();
        int quality = subtitleJson.value("quality").toDouble();

        // TODO smash data if already exists
        query.prepare("INSERT INTO subtitle (show_id, season, episode, language, "
                      "source, file, url, quality) "
                      "VALUES (:show_id, :season, :episode, "
                      ":language, :source, :file, :url, :quality)");
        query.bindValue(":show_id", _showId);
        query.bindValue(":season", _season);
        query.bindValue(":episode", episode);
        query.bindValue(":language", language);
        query.bindValue(":source", source);
        query.bindValue(":file", file);
        query.bindValue(":url", url);
        query.bindValue(":quality", quality);
        if (!query.exec()) {
            qCritical("Insertion failed, the subtitle parsing is stopped");
            break;
        }

        // content?
        int subtitleId = query.lastInsertId().toInt();

        QJsonObject contentJson = subtitleJson.value("content").toObject();
        if (!contentJson.isEmpty()) {
            // use a QMap to keep all strings ordered as sent by the webserver
            QMap<int,QString> files;
            foreach (const QString &key, contentJson.keys()) {
                QString v = contentJson.value(key).toString();
                if (!v.isEmpty())
                    files.insert(key.toInt(), v);
            }

            QMapIterator<int,QString> i(files);
            while (i.hasNext()) {
                i.next();
                query.prepare("INSERT INTO subtitle_content (subtitle_id, file) "
                              "VALUES (:subtitle_id, :file)");
                query.bindValue(":subtitle_id", subtitleId);
                query.bindValue(":file", i.value());
                query.exec();
            }
        }
    }
示例#8
0
void PluginSettingsView::handleAddon(const QJsonObject& obj)
{
    m_addonsToRetrieve--;
    if(m_addonsToRetrieve == 0)
    {
        m_progress->setHidden(true);
    }
    using Funmap = std::map<QString, std::function<void(QJsonValue)>>;

    RemoteAddon add;
    QString smallImage, largeImage; // thank you, Microsh**, for #define small char
    const Funmap funmap
    {
        { "name",    [&] (QJsonValue v) { add.name = v.toString(); } },
        { "version", [&] (QJsonValue v) { add.version = v.toString(); } },
        { "url",     [&] (QJsonValue v) { add.latestVersionAddress = v.toString(); } },
        { "short",   [&] (QJsonValue v) { add.shortDescription = v.toString(); } },
        { "long",    [&] (QJsonValue v) { add.longDescription = v.toString(); } },
        { "small",   [&] (QJsonValue v) { smallImage = v.toString(); } },
        { "large",   [&] (QJsonValue v) { largeImage = v.toString(); } },
        { "key",     [&] (QJsonValue v) { add.key = UuidKey<iscore::Addon>(v.toString().toLatin1().constData()); } }
    };

    // Add metadata keys
    for(const auto& k : obj.keys())
    {
        auto it = funmap.find(k);
        if(it != funmap.end())
        {
            it->second(obj[k]);
        }
    }

    if(add.key.impl().is_nil() || add.name.isEmpty())
    {
        return;
    }

    // Add architecture keys
    add.architectures = addonArchitectures();
    for(auto& k : add.architectures)
    {
        auto it = obj.constFind(k.first);
        if(it != obj.constEnd())
        {
            k.second = (*it).toString();
        }
    }


    // Load images
    RemotePluginItemModel* model = static_cast<RemotePluginItemModel*>(m_remoteAddons->model());
    if(!smallImage.isEmpty())
    {
        // c.f. https://wiki.qt.io/Download_Data_from_URL
        auto dl = new iscore::FileDownloader{QUrl{smallImage}};
        connect(dl, &iscore::FileDownloader::downloaded,
                this, [=] (QByteArray arr) {
            model->updateAddon(add.key, [=] (RemoteAddon& add) {
                add.smallImage.loadFromData(arr);
            });

            dl->deleteLater();
        });
    }

    if(!largeImage.isEmpty())
    {
        // c.f. https://wiki.qt.io/Download_Data_from_URL
        auto dl = new iscore::FileDownloader{QUrl{largeImage}};
        connect(dl, &iscore::FileDownloader::downloaded,
                this, [=] (QByteArray arr) {
            model->updateAddon(add.key, [=] (RemoteAddon& add) {
                add.largeImage.loadFromData(arr);
            });

            dl->deleteLater();
        });
    }

    model->addAddon(std::move(add));
}
示例#9
0
void HttpServer::initGlobal(const QString &filepath)
{
  LOG_INFO("Processing filepath [" << filepath << "]");

  m_GlobalConfig = Utils::readJson(QDir(filepath).absolutePath());

  LOG_INFO(m_GlobalConfig["bindIp"]);
  LOG_INFO(m_GlobalConfig["bindPort"]);

  QJsonValueRef loggingValue = m_GlobalConfig["logfile"];
  if(loggingValue.isObject())
  {
    QJsonObject logging = loggingValue.toObject();
    if(logging["isEnabled"].toBool(true))
    {
      QString filename;
      if(logging["filename"].isString())
      {
        filename = logging["filename"].toString();
      }
      if(logging["writeFrequency"].isDouble())
      {
        m_LoggingUtils.initializeFile(filename, logging["writeFrequency"].toInt());
      }
      else
      {
        m_LoggingUtils.initializeFile(filename);
      }
    }
  }

  QJsonValueRef httpFilesValue = m_GlobalConfig["httpFiles"];
  if(httpFilesValue.isObject())
  {
    QJsonObject httpFiles = httpFilesValue.toObject();
    m_ShouldServeFiles = httpFiles["isEnabled"].toBool(false);
    if(m_ShouldServeFiles)
    {
      QString directory = httpFiles["directory"].toString().trimmed();
      if(directory == "$QTTP_HOME")
      {
        QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
        if(env.contains(QTTP_HOME_ENV_VAR))
        {
          m_ServeFilesDirectory = QDir::cleanPath(env.value(QTTP_HOME_ENV_VAR));
          m_ServeFilesDirectory = m_ServeFilesDirectory.absoluteFilePath("www");
          LOG_DEBUG("Using $QTTP_HOME" << m_ServeFilesDirectory.absolutePath());
        }
        else
        {
          m_ServeFilesDirectory = QDir::current().absoluteFilePath("www");
          LOG_DEBUG("QTTP_HOME not found, using current directory" << m_ServeFilesDirectory.absolutePath());
        }
      }
      else if(directory.isEmpty())
      {
        m_ServeFilesDirectory = QDir::current().absoluteFilePath("www");
        LOG_DEBUG("Default to using current directory" << m_ServeFilesDirectory.absolutePath());
      }
      else
      {
        m_ServeFilesDirectory = QDir::cleanPath(directory);
        LOG_DEBUG("Using directory in config" << m_ServeFilesDirectory.absolutePath());
      }
      if(!m_ServeFilesDirectory.exists())
      {
        LOG_ERROR("Unable to serve files from invalid directory [" << m_ServeFilesDirectory.absolutePath() << "]");
        m_ShouldServeFiles = false;
      }
    }
  }

  if(m_ShouldServeFiles)
  {
    m_FileLookup.populateFiles(m_ServeFilesDirectory);
  }

  QJsonObject headers = m_GlobalConfig["defaultHeaders"].toObject();
  QStringList keys = headers.keys();

  if(!keys.isEmpty())
  {
    Global::DEFAULT_HEADERS.clear();
    for(QString key : keys)
    {
      QString value = headers.value(key).toString();
      Global::DEFAULT_HEADERS.push_back({ key, value });
      LOG_DEBUG("Adding default-header [" << key << ", " << value << "]");
    }

    // We'll always force the QttpServer version in here.
    Global::DEFAULT_HEADERS.push_back({ "Server", QTTP_SERVER_VERSION });
  }
  else
  {
    LOG_DEBUG("Did not read headers in config file, using default headers");
  }

  QJsonObject serverConfig = m_GlobalConfig["server"].toObject();
  m_SendRequestMetadata = serverConfig["metadata"].toBool(false);
  m_StrictHttpMethod = serverConfig["strictHttpMethod"].toBool(false);

  QJsonObject processors = serverConfig["processors"].toObject();
  keys = processors.keys();
  for(QString key : keys)
  {
    bool isEnabled = processors.value(key).toBool(false);

    LOG_DEBUG("Processor [" << key << "] is " <<
              (isEnabled ? "ENABLED" : "NOT ENABLED"));

    if(isEnabled)
    {
      m_EnabledProcessors.append(key);
    }
  }

  QJsonObject swagger = m_GlobalConfig["swagger"].toObject();
  initSwagger(swagger["isEnabled"].toBool(false));

#ifndef ASSIGN_SWAGGER
#  define ASSIGN_SWAGER(X) m_ServerInfo.X = swagger[#X].toString()
#endif

  ASSIGN_SWAGER(host);
  ASSIGN_SWAGER(basePath);
  ASSIGN_SWAGER(version);
  ASSIGN_SWAGER(title);
  ASSIGN_SWAGER(description);
  ASSIGN_SWAGER(termsOfService);

  QJsonObject company = swagger["company"].toObject();
  m_ServerInfo.companyName = company["name"].toString();
  m_ServerInfo.companyUrl = company["url"].toString();

  QJsonObject contact = swagger["contact"].toObject();
  m_ServerInfo.contactEmail = contact["email"].toString();

  QJsonObject license = swagger["license"].toObject();
  m_ServerInfo.licenseName = license["name"].toString();
  m_ServerInfo.licenseUrl = license["url"].toString();

  m_ServerInfo.schemes = swagger["schemes"].toArray();
  m_ServerInfo.consumes = swagger["consumes"].toArray();
  m_ServerInfo.produces = swagger["produces"].toArray();
}
void GameDetailsWidget_t::setSubproduct( const QJsonDocument& doc, QString platform ) //FIXME: function to switch platform: create all, but hide filtered entries!
{
   //Delete old content and create new layout
    for ( auto child : widget()->children() ) delete child;
    delete widget()->layout();

    //Create new content
    QWidget*     header_widget = createSubproductWidget( doc );

    QString sp_human_name = doc.object()["human_name"].toString();
    QString sp_payee_name = doc.object()["payee"].toObject()["human_name"].toString();

    QVBoxLayout* box_layout    = new QVBoxLayout;
    QGroupBox*   downloads_box = new QGroupBox;
    downloads_box->setLayout( box_layout );
    downloads_box->setTitle( tr("Available download(s) and transfer protocol(s):") );

    //Add new content
    for ( auto dl : doc.object()["downloads"].toArray() ) {

        if ( dl.toObject()["platform"].toString() != platform && platform != "all" ) continue;

        for ( auto dl_struct : dl.toObject()["download_struct"].toArray() ) {
            
            if ( dl_struct.toObject()["message"].isNull() ) //FIXME: allow message and downloads in parallel add fat32 warning and bittorrent recommendation!
            {
                QGroupBox*          dl_box = new QGroupBox( dl_struct.toObject()["name"].toString() );
                QHBoxLayout* dl_box_layout = new QHBoxLayout;
                dl_box->setAlignment( Qt::AlignHCenter );
                dl_box->setLayout( dl_box_layout );

                QJsonObject dl = dl_struct.toObject()["url"].toObject();
                for ( auto dl_type : dl.keys() )
                {
                    QIcon        dl_icon( QString(":/platforms/%1.png").arg(dl_type) ); //TODO: use QPixmapCache?
                    QPushButton* dl_button = new QPushButton( );

                    dl_button->setFlat(true);
                    dl_button->setText( dl_type );
                    dl_button->setIcon( dl_icon );
                    dl_box_layout->addWidget( dl_button );
    
                    connect( dl_button, &QPushButton::clicked, [=] () { 
                        QString gamekey    = doc.object()["gamekey"].toString();
                        QString subproduct = doc.object()["machine_name"].toString();
                        QString protocol   = dl_type;
                        QString url        = dl[dl_type].toString();

                        HumbleDownloader::get().enqueue( gamekey,subproduct,platform,protocol,url );
                    } );
                }

                downloads_box->layout()->addWidget( dl_box );
            }
            else {
                QLabel* message_label = new QLabel( dl_struct.toObject()["message"].toString() );
                downloads_box->layout()->addWidget( message_label );
            }
        }
    }
    widget()->setLayout( new QVBoxLayout );
    widget()->layout()->addWidget( header_widget );
    widget()->layout()->addWidget( downloads_box );
    widget()->layout()->setSizeConstraint( QLayout::SetFixedSize );
}
示例#11
0
// Save system-wide settings
QJsonObject LifePreserver::saveSettings(QJsonObject jsin) {
   QJsonObject retObject;
   QString warn, email, emailopts, recursive;

   QStringList keys = jsin.keys();
   if(! keys.contains("duwarn") && ! keys.contains("email") && ! keys.contains("emailopts") && !keys.contains("recursive")){
     retObject.insert("error", "Requires duwarn, email, emailopts or recursive to be set!");
     return retObject;
   }

   QJsonObject values;
   QStringList output;

   // Get the settings
   if ( keys.contains("duwarn") ) {
     warn = jsin.value("duwarn").toString();
     output = General::RunCommand("lpreserver set duwarn " + warn).split("\n");
     // Check for any errors
     for ( int i = 0; i < output.size(); i++)
     {
        if ( output.at(i).indexOf("ERROR:") != -1 ) {
         retObject.insert("error", output.at(i));
         return retObject;
        }
     }
     values.insert("duwarn", warn);
   }
   if ( keys.contains("email") ) {
     email = jsin.value("email").toString();
     output = General::RunCommand("lpreserver set email " + email).split("\n");
     // Check for any errors
     for ( int i = 0; i < output.size(); i++)
     {
        if ( output.at(i).indexOf("ERROR:") != -1 ) {
         retObject.insert("error", output.at(i));
         return retObject;
        }
     }
     values.insert("email", email);
   }
   if ( keys.contains("emailopts") ) {
     emailopts = jsin.value("emailopts").toString();
     output = General::RunCommand("lpreserver set emailopts " + emailopts.toUpper()).split("\n");
     // Check for any errors
     for ( int i = 0; i < output.size(); i++)
     {
        if ( output.at(i).indexOf("ERROR:") != -1 ) {
         retObject.insert("error", output.at(i));
         return retObject;
        }
     }
     values.insert("emailopts", emailopts);
   }
   if ( keys.contains("recursive") ) {
     recursive = jsin.value("recursive").toString();
     QString recset = "ON";
     if ( recursive.toUpper() == "FALSE" )
       recset = "OFF";
     output = General::RunCommand("lpreserver set recursive " + recset).split("\n");
     // Check for any errors
     for ( int i = 0; i < output.size(); i++)
     {
        if ( output.at(i).indexOf("ERROR:") != -1 ) {
         retObject.insert("error", output.at(i));
         return retObject;
        }
     }
     values.insert("recursive", recursive);
   }

   return values;
}
示例#12
0
// Build list of scheduled cron snapshot jobs
QJsonObject LifePreserver::listCron() {
   QJsonObject retObject;

   QStringList output = General::RunCommand("lpreserver cronsnap list").split("\n");
   output << General::RunCommand("lpreserver cronscrub list").split("\n");
   QList<QStringList> snaps;
   
   // Parse the output
   bool inSnapSection = false;
   bool inScrubSection = false;
   for ( int i = 0; i < output.size(); i++)
   {
      if ( output.at(i).indexOf("-----------------") != -1 ) {
         inSnapSection = true;
         continue;
      }

      if (!inSnapSection)
         continue;

      if ( output.at(i).indexOf("Pools scheduled for scrub") != -1 ) {
         inScrubSection = true;
	 continue;
      }

      if ( output.at(i).isEmpty() || output.at(i).indexOf("-----------------") != -1 )
	  continue;

      if ( inSnapSection && ! inScrubSection ) {
        // Breakdown this cron job
        QString pool = output.at(i).section("-", 0, 0).simplified();
        QString freq = output.at(i).section("-", 1, 1).simplified();
        QString keep = output.at(i).section("-", 2, 2).simplified().replace("total: ", "");

        QJsonObject values;
        values.insert("schedule", freq);
        values.insert("keep", keep);
        retObject.insert(pool, values);
      } else if (inSnapSection && inScrubSection ) {
        // Add a cron scrub
        QString pool = output.at(i).section("-", 0, 0).simplified();
        QString freq = output.at(i).section("-", 1, 1).simplified().replace(" ", "");
	qDebug() << "Found scrub:" << pool << freq;

        QJsonObject values;
        QStringList keys = retObject.keys();
        if( keys.contains(pool)){
          // We have an existing pool object, add it
          values = retObject[pool].toObject();
          retObject.remove(pool);
          values.insert("scrub", freq);
          retObject.insert(pool, values);
	} else {
          // Add a new pool object with the scrub
          values.insert("scrub", freq);
          retObject.insert(pool, values);
	}
      }
   }

   return retObject;
}
示例#13
0
// Add a new replication target
QJsonObject LifePreserver::addReplication(QJsonObject jsin) {
   QJsonObject retObject;
   QString host, user, port, password, ldataset, rdataset, frequency;

   QStringList keys = jsin.keys();
   if (! keys.contains("host")
     || ! keys.contains("user")
     || ! keys.contains("port")
     || ! keys.contains("password")
     || ! keys.contains("dataset")
     || ! keys.contains("remotedataset")
     || ! keys.contains("frequency") ) {
     retObject.insert("error", "Missing required keys");
     return retObject;
   }

   // Get the key values
   host = jsin.value("host").toString();
   user = jsin.value("user").toString();
   port = jsin.value("port").toString();
   password = jsin.value("password").toString();
   ldataset = jsin.value("dataset").toString();
   rdataset = jsin.value("remotedataset").toString();
   frequency = jsin.value("frequency").toString();

   // Make sure we have the dataset / snap key(s)
   if ( host.isEmpty()
     || user.isEmpty()
     || port.isEmpty()
     || password.isEmpty()
     || ldataset.isEmpty()
     || rdataset.isEmpty()
     || frequency.isEmpty() ) {
     retObject.insert("error", "Empty dataset or snap keys ");
     return retObject;
   }

   // Run the command with the SSHPASS env variable set
   QStringList output;
   output = General::RunCommand("lpreserver", QStringList() << "replicate" << "add"
	<< host
	<< user
	<< port
	<< ldataset
	<< rdataset
	<< frequency, "", QStringList() << "SSHPASS="******"\n");

   // Check for any errors
   for ( int i = 0; i < output.size(); i++)
   {
      if ( output.at(i).indexOf("ERROR:") != -1 ) {
       retObject.insert("error", output.at(i));
       return retObject;
      }
   }

   // Got to the end, return the good json
   QJsonObject values;
   values.insert("host", host);
   values.insert("user", user);
   values.insert("port", port);
   values.insert("ldataset", ldataset);
   values.insert("rdataset", rdataset);
   values.insert("frequency", frequency);

   return values;
}
void QPlaceDetailsReplyImpl::replyFinished()
{
    if (m_reply->error() != QNetworkReply::NoError) {
        switch (m_reply->error()) {
        case QNetworkReply::OperationCanceledError:
            setError(CancelError, "Request canceled.");
            break;
        case QNetworkReply::ContentNotFoundError:
            setError(PlaceDoesNotExistError,
                     QString::fromLatin1("The id, %1, does not reference an existing place")
                     .arg(m_placeId));
            break;
        default:
            setError(CommunicationError, "Network error.");
        }
        return;
    }

    QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll());
    if (!document.isObject()) {
        setError(ParseError, QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, PARSE_ERROR));
        return;
    }

    QJsonObject object = document.object();

    QPlace place;

    place.setPlaceId(object.value(QLatin1String("placeId")).toString());

    //const QUrl view = object.value(QLatin1String("view")).toString();

    place.setName(object.value(QLatin1String("name")).toString());

    //if (object.contains(QLatin1String("distance")))
    //    double distance = object.value(QLatin1String("distance")).toDouble();

    //if (object.contains(QLatin1String("alternativeNames"))) {
    //    QJsonArray alternativeNames = object.value(QLatin1String("alternativeNames")).toArray();
    //}

    QGeoLocation location;

    QJsonObject locationObject = object.value(QLatin1String("location")).toObject();

    //if (locationObject.contains(QLatin1String("locationId")))
    //    const QString locationId = locationObject.value(QLatin1String("locationId")).toString();

    QJsonArray position = locationObject.value(QLatin1String("position")).toArray();
    location.setCoordinate(QGeoCoordinate(position.at(0).toDouble(), position.at(1).toDouble()));

    QGeoAddress address;

    QJsonObject addressObject = locationObject.value(QLatin1String("address")).toObject();

    address.setText(addressObject.value(QLatin1String("text")).toString());

    address.setCountry(addressObject.value(QLatin1String("country")).toString());
    address.setCountryCode(addressObject.value(QLatin1String("countryCode")).toString());

    QString house;
    QString street;

    if (addressObject.contains(QLatin1String("house")))
        house = addressObject.value(QLatin1String("house")).toString();
    if (addressObject.contains(QLatin1String("street")))
        street = addressObject.value(QLatin1String("street")).toString();

    if (countryTableContains(address.countryCode())) {
        if (!house.isEmpty() && !street.startsWith(house))
            street = house + QLatin1Char(' ') + street;
    } else {
        if (!house.isEmpty() && !street.endsWith(house))
            street += QLatin1Char(' ') + house;
    }

    address.setStreet(street);

    if (addressObject.contains(QLatin1String("city")))
        address.setCity(addressObject.value(QLatin1String("city")).toString());
    if (addressObject.contains(QLatin1String("district")))
        address.setDistrict(addressObject.value(QLatin1String("district")).toString());
    if (addressObject.contains(QLatin1String("state")))
        address.setState(addressObject.value(QLatin1String("state")).toString());
    if (addressObject.contains(QLatin1String("county")))
        address.setCounty(addressObject.value(QLatin1String("county")).toString());
    if (addressObject.contains(QLatin1String("postalCode")))
        address.setPostalCode(addressObject.value(QLatin1String("postalCode")).toString());

    location.setAddress(address);

    if (locationObject.contains(QLatin1String("bbox"))) {
        QJsonArray bbox = locationObject.value(QLatin1String("bbox")).toArray();
        QGeoRectangle box(QGeoCoordinate(bbox.at(3).toDouble(), bbox.at(0).toDouble()),
                            QGeoCoordinate(bbox.at(1).toDouble(), bbox.at(2).toDouble()));
        location.setBoundingBox(box);
    }

    place.setLocation(location);

    place.setCategories(parseCategories(object.value(QLatin1String("categories")).toArray(),
                                        m_engine));

    place.setIcon(m_engine->icon(object.value(QLatin1String("icon")).toString(),
                                 place.categories()));

    if (object.contains(QLatin1String("contacts"))) {
        QJsonObject contactsObject = object.value(QLatin1String("contacts")).toObject();

        if (contactsObject.contains(QLatin1String("phone"))) {
            place.setContactDetails(QPlaceContactDetail::Phone,
                                    parseContactDetails(contactsObject.value(QLatin1String("phone")).toArray()));
        }
        if (contactsObject.contains(QLatin1String("fax"))) {
            place.setContactDetails(QPlaceContactDetail::Fax,
                                    parseContactDetails(contactsObject.value(QLatin1String("fax")).toArray()));
        }
        if (contactsObject.contains(QLatin1String("website"))) {
            place.setContactDetails(QPlaceContactDetail::Website,
                                    parseContactDetails(contactsObject.value(QLatin1String("website")).toArray()));
        }
        if (contactsObject.contains(QLatin1String("email"))) {
            place.setContactDetails(QPlaceContactDetail::Email,
                                    parseContactDetails(contactsObject.value(QLatin1String("email")).toArray()));
        }
    }

    //if (object.contains(QLatin1String("verifiedByOwner")))
    //    bool verifiedByOwner = object.value(QLatin1String("verifiedByOwner")).toBool();

    if (object.contains(QLatin1String("attribution")))
        place.setAttribution(object.value(QLatin1String("attribution")).toString());

    if (object.contains(QLatin1String("supplier"))) {
        place.setSupplier(parseSupplier(object.value(QLatin1String("supplier")).toObject(),
                                        m_engine));
    }

    if (object.contains(QLatin1String("ratings"))) {
        QJsonObject ratingsObject = object.value(QLatin1String("ratings")).toObject();

        QPlaceRatings ratings;
        ratings.setAverage(ratingsObject.value(QLatin1String("average")).toDouble());
        ratings.setCount(ratingsObject.value(QLatin1String("count")).toDouble());
        ratings.setMaximum(5.0);

        place.setRatings(ratings);
    }

    if (object.contains(QLatin1String("extended"))) {
        QJsonObject extendedObject = object.value(QLatin1String("extended")).toObject();

        foreach (const QString &key, extendedObject.keys()) {
            QJsonObject attributeObject = extendedObject.value(key).toObject();

            QPlaceAttribute attribute;

            attribute.setLabel(attributeObject.value(QLatin1String("label")).toString());
            attribute.setText(attributeObject.value(QLatin1String("text")).toString());

            if (key == QLatin1String("payment"))
                place.setExtendedAttribute(QPlaceAttribute::Payment, attribute);
            else if (key == QLatin1String("openingHours"))
                place.setExtendedAttribute(QPlaceAttribute::OpeningHours, attribute);
            else
                place.setExtendedAttribute(key, attribute);
        }
    }
示例#15
0
void Controller::readNVO3(QString type) {
    if (type == "BrVN") {
        QJsonObject result = ps->readJson("./data/brvnid");
        QJsonObject obj = result["brvnid"].toObject();
        QStringList keys = obj.keys();
        for (int i=0;i<keys.length();i++) {
            QStringList row;
            row<<keys[i];
            row<<obj[keys[i]].toString();
            emit nvo3DataConfirmed(row);
        }
    } else if (type == "LocalVNIP") {
        QJsonObject result = ps->readJson("./data/vnidip");
        QJsonObject obj = result["vnidip"].toObject();
        QStringList keys = obj.keys();
        for (int i=0;i<keys.length();i++) {
            QStringList row;
            row<<keys[i];
            row<<obj[keys[i]].toArray()[0].toString();
            emit nvo3DataConfirmed(row);
        }
    } else if (type == "VNIP") {
        //read Local VNIP
        QJsonObject result = ps->readJson("./data/vnidip");
        QJsonObject obj = result["vnidip"].toObject();
        QStringList keys = obj.keys();
        for (int i=0;i<keys.length();i++) {
            QStringList row;
            row<<keys[i];
            row<<obj[keys[i]].toArray()[0].toString();
            emit nvo3DataConfirmed(row);
        }
        //read Global VNIP
        result = ps->readJson("./data/ip_write");
        obj = result["vnidip"].toObject();
        keys = obj.keys();
        for (int i=0;i<keys.length();i++) {
            QJsonArray array = obj[keys[i]].toArray();
            for (int j=0;j<array.size();j++) {
                QStringList row;
                row<<keys[i];
                row<<array[j].toString();
                emit nvo3DataConfirmed(row);
            }
        }
    } else if (type == "VNMACIP") {
        QJsonObject vnidMac = ps->readJson("./data/mac_write");
        QJsonObject macIp = ps->readJson("./data/mac_ip");
        QJsonObject vnidMacObj = vnidMac["vnidmac"].toObject();
        QJsonObject macIpObj = macIp["macip"].toObject();
        QStringList keys = vnidMacObj.keys();
        QStringList ips = macIpObj.keys();
        for (int i=0;i<keys.length();i++) {
            QStringList row;
            row<<keys[i];
            QString mac = vnidMacObj[keys[i]].toArray()[0].toString();
            row<<mac;
            for (int j=0;j<ips.length();j++){
                if (macIpObj[ips[j]].toArray()[0].toString() == mac) {
                    row<<ips[j];
                    emit nvo3DataConfirmed(row);
                    break;
                }
            }
        }
        QJsonObject localMac = ps->readJson("./data/vnid-mac");
        QJsonObject localIp = ps->readJson("./data/vnidip");
        QJsonObject localMacObj = localMac["vnidmac"].toObject();
        QJsonObject localIpObj = localIp["vnidip"].toObject();
        keys = localMacObj.keys();
        for (int i=0;i<keys.length();i++) {
            QString ip = localIpObj[keys[i]].toArray()[0].toString();
            if (!ip.isEmpty()) {
                QStringList row;
                row << keys[i];
                row << localMacObj[keys[i]].toArray()[0].toString();
                row << ip;
                emit nvo3DataConfirmed(row);
                break;
            }
        }
    } else if (type == "NVE") {
        QJsonObject result = ps->readJson("./data/test_encap_write");
        QJsonObject obj = result["ipencap"].toObject();
        QStringList keys = obj.keys();
        for (int i=0;i<keys.length();i++) {
            QStringList row;
            row<<keys[i];
            row<<obj[keys[i]].toArray()[0].toString();
            emit nvo3DataConfirmed(row);
        }
    }
}
示例#16
0
TextPalette::TextPalette(QWidget* parent)
   : QWidget(parent)
      {
      setWindowFlags(Qt::Tool);
      setupUi(this);

      pCommon = new Palette;
      pCommon->setMag(0.8);
      pCommon->setGrid(33, 60);
      pCommon->setReadOnly(true);

      pSmufl = new Palette;
      pSmufl->setMag(0.8);
      pSmufl->setGrid(33, 60);
      pSmufl->setReadOnly(true);

      pUnicode = new Palette;
      pUnicode->setMag(0.8);
      pUnicode->setGrid(33, 60);
      pUnicode->setReadOnly(true);

      PaletteScrollArea* psa = new PaletteScrollArea(pCommon);
      psa->setRestrictHeight(false);

      tabWidget->clear();
      tabWidget->addTab(psa, tr("Common Symbols"));

      psa = new PaletteScrollArea(pSmufl);
      psa->setRestrictHeight(false);

      QSplitter* ws = new QSplitter;
      lws = new QListWidget;

      ScoreFont* scoreFont = ScoreFont::fontFactory("Bravura");
      QFile fi(scoreFont->fontPath() + "ranges.json");
      if (!fi.open(QIODevice::ReadOnly))
            qDebug("ScoreFont: open ranges file <%s> failed", qPrintable(fi.fileName()));
      QJsonParseError error;
      QJsonObject o = QJsonDocument::fromJson(fi.readAll(), &error).object();
      if (error.error != QJsonParseError::NoError)
            qDebug("Json parse error in <%s>(offset: %d): %s", qPrintable(fi.fileName()),
               error.offset, qPrintable(error.errorString()));
	int i = 0;
      QStringList smuflRangeNames;
      for (auto s : o.keys()) {
            QJsonObject range = o.value(s).toObject();
            QString desc = range.value("description").toString();
            QJsonArray glyphs = range.value("glyphs").toArray();
            if (glyphs.size() > 0) {
                  for (QJsonValue g : glyphs)
                        smuflMap[i].append(g.toString());
                  smuflRangeNames.append(desc);
                  i++;
                  }
            }

      lws->addItems(smuflRangeNames);
      lws->setCurrentRow(0);

      ws->addWidget(lws);
      ws->addWidget(psa);

      tabWidget->addTab(ws, tr("Musical Symbols"));

      psa = new PaletteScrollArea(pUnicode);
      psa->setRestrictHeight(false);

      QSplitter* wu = new QSplitter;
      lwu = new QListWidget;
      lwu->setSortingEnabled(true);
      for (i = 0; i < unicodeRangeNames.length(); i++) {
            QListWidgetItem* newItem = new QListWidgetItem(qApp->translate("accidental", unicodeRangeNames.at(i).toUtf8().constData()));
            newItem->setData(Qt::UserRole, i);
            lwu->addItem(newItem);
            if (i == 0)
                  lwu->setCurrentItem(newItem);
            }

      wu->addWidget(lwu);
      wu->addWidget(psa);

      tabWidget->addTab(wu, tr("Unicode Symbols"));

      connect(lws, SIGNAL(currentRowChanged(int)), SLOT(populateSmufl()));
      connect(lwu, SIGNAL(currentRowChanged(int)), SLOT(populateUnicode()));

	// others are done in setFont
      populateSmufl();

      setFocusPolicy(Qt::NoFocus);
      }
示例#17
0
QNetworkReply *Parse::query(QString endPoint, QUrlQuery extraParams)
{
    if (!isReady()) return NULL;

    if (extraParams.isEmpty())
        setEndPoint(endPoint);
    else setEndPoint( endPoint + "?" + extraParams.toString() ); //TODO improve me : not use endpoint to give url encoded params

    ensureEndPointHasPrefix("classes");

    m_conn = connect(this, &BaaS::replyFinished, [=](QJsonDocument json, QNetworkReply *reply){
        disconnect(m_conn);
        if (isLastRequestSuccessful()){
                //structure to return from parse
                QHash<int, QByteArray> roles = QHash<int, QByteArray>();
                QVector<QVariantMap> data = QVector<QVariantMap>();

                Q_ASSERT(json.isObject());
                QJsonObject obj = json.object();
                QJsonValue tmp = obj.value("results");

                if (tmp.isArray()){
                    QJsonArray res = tmp.toArray();
                    for ( QJsonValue elem: res){
                        if (elem.isObject()){
                            obj = elem.toObject();

                            //Update roles
                            QStringList keys = obj.keys();
                            for (QString roleName : keys )
                            {
                                if ( roles.key( roleName.toUtf8(), -1) == -1)
                                    roles[roles.size()] = roleName.toUtf8();
                            }
                            //Add values
                            data.push_back( obj.toVariantMap());


                        }
                    }

                    emit querySucceeded(roles, data, reply);
                }
                //else if (tmp.isObject()){
                    //obj = tmp.toObject();//Update roles
                else {
                    QStringList keys = obj.keys();
                    for (QString roleName : keys )
                    {
                        if ( roles.key( roleName.toUtf8(), -1) == -1)
                            roles[roles.size()] = roleName.toUtf8();
                    }
                    //Add values
                    data.push_back( obj.toVariantMap());
                    emit querySucceeded(roles, data, reply);
                }
        }
    } );

    initHeaders();
    return request( BaaS::GET);

}
示例#18
0
QVariantMap HifiConfigVariantMap::mergeCLParametersWithJSONConfig(const QStringList& argumentList) {
    
    QVariantMap mergedMap;
    
    // Add anything in the CL parameter list to the variant map.
    // Take anything with a dash in it as a key, and the values after it as the value.
    
    const QString DASHED_KEY_REGEX_STRING = "(^-{1,2})([\\w-]+)";
    QRegExp dashedKeyRegex(DASHED_KEY_REGEX_STRING);
    
    int keyIndex = argumentList.indexOf(dashedKeyRegex);
    int nextKeyIndex = 0;
    
    // check if there is a config file to read where we can pull config info not passed on command line
    const QString CONFIG_FILE_OPTION = "--config";
    
    while (keyIndex != -1) {
        if (argumentList[keyIndex] != CONFIG_FILE_OPTION) {
            // we have a key - look forward to see how many values associate to it
            QString key = dashedKeyRegex.cap(2);
            
            nextKeyIndex = argumentList.indexOf(dashedKeyRegex, keyIndex + 1);
            
            if (nextKeyIndex == keyIndex + 1) {
                // there's no value associated with this option, it's a boolean
                // so add it to the variant map with NULL as value
                mergedMap.insertMulti(key, QVariant());
            } else {
                int maxIndex = (nextKeyIndex == -1) ? argumentList.size() : nextKeyIndex;
                
                // there's at least one value associated with the option
                // pull the first value to start
                QString value = argumentList[keyIndex + 1];
                
                // for any extra values, append them, with a space, to the value string
                for (int i = keyIndex + 2; i < maxIndex; i++) {
                    value +=  " " + argumentList[i];
                }
                
                // add the finalized value to the merged map
                mergedMap.insert(key, value);
            }
            
            keyIndex = nextKeyIndex;
        } else {
            keyIndex = argumentList.indexOf(dashedKeyRegex, keyIndex + 1);
        }
    }
    
    int configIndex = argumentList.indexOf(CONFIG_FILE_OPTION);
    
    if (configIndex != -1) {
        // we have a config file - try and read it
        QString configFilePath = argumentList[configIndex + 1];
        QFile configFile(configFilePath);
        
        if (configFile.exists()) {
            qDebug() << "Reading JSON config file at" << configFilePath;
            configFile.open(QIODevice::ReadOnly);
            
            QJsonDocument configDocument = QJsonDocument::fromJson(configFile.readAll());
            QJsonObject rootObject = configDocument.object();
            
            // enumerate the keys of the configDocument object
            foreach(const QString& key, rootObject.keys()) {
                
                if (!mergedMap.contains(key)) {
                    // no match in existing list, add it
                    mergedMap.insert(key, QVariant(rootObject[key]));
                }
            }
        } else {
示例#19
0
void Config::init(QString file_name) {
    this->file_name = file_name;

	QFile file;
    file.setFileName(this->file_name);
	file.open(QIODevice::ReadOnly | QIODevice::Text);
	
    QByteArray data = file.readAll();
	
	file.close();

    QJsonParseError error;

    json = QJsonDocument::fromJson(data, &error);

    if (!json.isObject()) {
        return;
    }

    QJsonObject obj = json.object();

    QStringList keys = obj.keys();

    if (!keys.contains("config") || !obj["config"].isObject()) {
        return;
    }

    obj = obj["config"].toObject();

    keys = obj.keys(); //movList idxs

    for (int i = 0; i < keys.size(); ++i) {
        QString key = keys.at(i);

        if (!obj[key].isObject()) {
            continue;
        }

        QJsonObject coll_item = obj[key].toObject();
        QStringList coll_keys = coll_item.keys();

        if (coll_keys.contains("text") && coll_item["text"].isString()) {
            this->text[key] = coll_item["text"].toString();
        }

        if (coll_keys.contains("video") && coll_item["video"].isArray()) {
            QJsonArray videos = coll_item["video"].toArray();
            QStringList v_list;

            for (int j = 0; j < videos.size(); ++j) {
                if (!videos.at(j).isString()) {
                    continue;
                }

                v_list.append(videos.at(j).toString());
            }

            this->video[key] = v_list;
        }
    }

    return;
}
void MainWindow::updateLookUpHashResultUI(QJsonObject jo, QString url) {

    QString hash = url.mid(url.lastIndexOf("/") + 1).toUpper();

    if(jo.contains(hash) && jo[hash].toString().toUpper().compare(HASH_NOT_FOUND) == 0) {
        // Hash not found
        QString htmlResult = StringProvider::HTML_TEMPLATE_SCAN_HASH_NOT_FOUND;
        htmlResult = htmlResult.replace("@hash", hash);

        // Update UI webview
        ui->wvLookUpHash->setHtml(htmlResult);
    } else {
        // Found a result
        QJsonObject joScanResult = jo["scan_results"].toObject();

        // Found hash result ==> bind result data to webview

        QJsonObject joFileInfo = jo["file_info"].toObject();

        QString md5 = joFileInfo["md5"].toString();
        QString sha1 = joFileInfo["sha1"].toString();
        QString sha256 = joFileInfo["sha256"].toString();
        QString fileType = joFileInfo["file_type_extension"].toString();
        QString fileDescription = joFileInfo["file_type_description"].toString();
        QString displayName = joFileInfo["display_name"].toString();
        QString uploadTimestamp = joFileInfo["upload_timestamp"].toString();
        qint64 fileSize = joFileInfo["file_size"].toInt();
        QString startTime = joScanResult["start_time"].toString();

        // Bind data for list engines

        QString htmlEnginesResult;
        QJsonObject joScanDetails = joScanResult["scan_details"].toObject();
        QStringList engineNames = joScanDetails.keys();
        int totalEngines = joScanResult["total_avs"].toInt();
        int detectedEngines = 0;
        foreach (QString engineName, engineNames) {
            QJsonObject joEngine = joScanDetails[engineName].toObject();
            QString status = "normal";
            if(joEngine["scan_result_i"].toInt() == 1) {
                status = "issue";
                detectedEngines ++;
            }
            QString threat = joEngine["threat_found"].toString();
            QString definitionDate = joEngine["def_time"].toString();
            int scanTime = joEngine["scan_time"].toInt();



            QString temp(StringProvider::HTML_TEMPLATE_ENGINE_ITEM);
            temp.replace("@scanTime", QString::number(scanTime));
            temp.replace("@definitionDate", DateTimeProvider::formatStringDate(definitionDate, DATE_TIME_FORMAT_2));
            temp.replace("@threat", threat);
            temp.replace("@status", status);
            temp.replace("@engine", engineName);

            htmlEnginesResult += temp;
        }

        // Bind data for file info
        QString htmlResult = StringProvider::HTML_TEMPLATE_SCAN_FILE_RESULT;

        qDebug() << "totalEngines = " << totalEngines << ", detectedEngines = " << detectedEngines;

        // Format the detected engines 2 digit
        if(detectedEngines >= 0 && detectedEngines <= 9) {
            htmlResult.replace("@number", QString("%1%2").arg("&nbsp;", QString::number(detectedEngines)));
        } else {
            htmlResult.replace("@number", QString::number(detectedEngines));
        }

        if(detectedEngines == 0) {
            htmlResult.replace("@imageName", "engine_not_found_threat.png");
        } else {
            htmlResult.replace("@imageName", "engine_found_threat.png");
        }

        htmlResult.replace("@firstUploaded", uploadTimestamp);
        htmlResult.replace("@lastScanned", fileDescription);
        htmlResult.replace("@fileName", displayName.mid(displayName.lastIndexOf("/") + 1));
        htmlResult.replace("@fileType", fileType);
        htmlResult.replace("@fileSize", QString::number(fileSize));

        htmlResult.replace("@number", QString::number(detectedEngines));
        htmlResult.replace("@total", QString::number(totalEngines));
        htmlResult.replace("@date", startTime);
        htmlResult.replace("@md5", md5);
        htmlResult.replace("@sha1", sha1);
        htmlResult.replace("@sha256", sha256);
        htmlResult.replace("@listEngines", htmlEnginesResult);

        // Update UI webview
        ui->wvLookUpHash->setHtml(htmlResult);

    }
示例#21
0
//---------------------------------------------------------------------------------
void
MagicRules::initialize(const QString& p_jsonFile)
{
    // Read the JSON file
    QString val;
    QFile file;
    file.setFileName(p_jsonFile);
    file.open(QIODevice::ReadOnly | QIODevice::Text);
    val = file.readAll();
    file.close();

    // Read document
    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(val.toUtf8(), &error);
    if (error.error != QJsonParseError::NoError)
    {
        qCritical() << QString("Error while reading file: %1\nError: %2").arg(p_jsonFile, error.errorString());
        return;
    }

    // Parse each magic type and add to the rules
    QJsonArray magicTypesArray = doc.object().value("magic_types").toArray();
    QJsonObject currentType;
    MagicTypeDefinition* typeDef = 0;
    MagicTypePriorityDefinition* prioDef = 0;
    QJsonArray tempArray;
    QJsonObject tempObject;
    QJsonObject tempObject2;
    for (int i = 0; i < magicTypesArray.size(); ++i)
    {
        currentType = magicTypesArray.at(i).toObject();

        // Add type definition
        typeDef = new MagicTypeDefinition();

        // Translations
        tempObject = currentType["translations"].toObject();
        for (int j = 0; j < tempObject.keys().size(); ++j)
        {
            typeDef->translations[tempObject.keys().at(j)] = tempObject[tempObject.keys().at(j)].toString();
        }

        // Types
        tempArray = currentType["types"].toArray();
        for (int j = 0; j < tempArray.size(); ++j)
        {
            typeDef->types.push_back(tempArray.at(j).toString());
        }

        // Priorities
        tempObject = currentType["priorities"].toObject();
        for (int j = 0; j < tempObject.keys().size(); ++j)
        {
            tempObject2 = tempObject[tempObject.keys().at(j)].toObject();

            prioDef = new MagicTypePriorityDefinition();

            // Starting magic
            if (tempObject2.contains("starting_magic"))
            {
                prioDef->startingMagic = tempObject2.value("starting_magic").toString().toInt();
            }

            // Free spells
            if (tempObject2.contains("free_spells"))
            {
                prioDef->freeSpells = tempObject2.value("free_spells").toString().toInt();
            }

            // Free skills
            if (tempObject2.contains("free_skills"))
            {
                prioDef->freeSkills.first = tempObject2.value("free_skills").toArray().at(0).toString().toInt();
                prioDef->freeSkills.second = tempObject2.value("free_skills").toArray().at(1).toString().toInt();
            }

            // Forced skill group
            if (tempObject2.contains("free_skill_groups"))
            {
                prioDef->freeSkillGroup.first = tempObject2.value("free_skill_groups").toArray().at(0).toString().toInt();
                prioDef->freeSkillGroup.second = tempObject2.value("free_skill_groups").toArray().at(1).toString().toInt();
            }

            // Store priority
            typeDef->priorities[tempObject.keys().at(j).toInt()] = prioDef;
        }

        // Make sure the definition doesn't already exist
        if (_typeDefinitions.contains(currentType["unique_id"].toString()))
        {
            qCritical() << "Magic type \"" << currentType["unique_id"].toString() << "\" already exists. Parsing aborted.";
            return;
        }

        _typeDefinitions[currentType["unique_id"].toString()] = typeDef;
    }// END magic types

    // Parse spell category strings
    QJsonArray categoryArray = doc.object().value("spell_categories").toArray();
    QJsonObject currentCat;
    SpellDefinition* spellCat = NULL;
    MagicAbilityDefinition* category = NULL;
    MagicAbilityDefinition* abilityDef = NULL;
    QString tempString;
    QString uniqueId = "";
    for (int i = 0; i < categoryArray.size(); ++i)
    {
        currentCat = categoryArray.at(i).toObject();

        uniqueId = currentCat["unique_id"].toString();

        // Make sure the definition doesn't already exist
        if (_spellCategoryDefinitions.contains(uniqueId))
        {
            qCritical() << "Spell category \"" << uniqueId << "\" already exists. Parsing aborted.";
            return;
        }

        // Get correct category
        category = _rootItem->children[MAGICABILITYTYPE_SPELL];

        // Add spell definition
        abilityDef = new MagicAbilityDefinition(category);
        abilityDef->id = uniqueId;
        abilityDef->abilityType = MAGICABILITYTYPE_SPELL;
        spellCat = new SpellDefinition();
        abilityDef->spell = spellCat;
        abilityDef->spell->isSpellCategory = true;
        category->children.push_back(abilityDef);

        // Translations
        tempObject = currentCat["translations"].toObject();
        for (int j = 0; j < tempObject.keys().size(); ++j)
        {
            abilityDef->translations[tempObject.keys().at(j)] = tempObject[tempObject.keys().at(j)].toString();
        }

        _definitions[uniqueId] = abilityDef;
        _spellCategoryDefinitions[uniqueId] = spellCat;
    }

    // Parse each spell and add to the rules
    QJsonArray spellsArray = doc.object().value("spells").toArray();
    QJsonObject currentSpell;
    SpellDefinition* spellDef = 0;
    for (int i = 0; i < spellsArray.size(); ++i)
    {
        currentSpell = spellsArray.at(i).toObject();

        uniqueId = currentSpell["unique_id"].toString();

        // Make sure the definition doesn't already exist
        if (_spellDefinitions.contains(uniqueId))
        {
            qCritical() << "Spell \"" << uniqueId << "\" already exists. Parsing aborted.";
            return;
        }

        // Add spell definition
        abilityDef = new MagicAbilityDefinition();
        abilityDef->id = uniqueId;
        abilityDef->abilityType = MAGICABILITYTYPE_SPELL;
        spellDef = new SpellDefinition();
        abilityDef->spell = spellDef;

        // Translations
        tempObject = currentSpell["translations"].toObject();
        for (int j = 0; j < tempObject.keys().size(); ++j)
        {
            abilityDef->translations[tempObject.keys().at(j)] = tempObject[tempObject.keys().at(j)].toString();
        }

        // Category
        spellDef->category = currentSpell["category"].toString();
        if (!_spellCategoryDefinitions.contains(spellDef->category))
        {
            qCritical() << "Spell \"" << currentSpell["unique_id"].toString() << "\" of non existing category \""
                           << spellDef->category << "\". Parsing aborted.";
            return;
        }

        // Get correct spell category and add to it
        category = _definitions[spellDef->category];
        abilityDef->parent = category;
        category->children.push_back(abilityDef);

        // Type
        tempString = currentSpell["type"].toString();
        if (tempString == "P")
        {
            spellDef->type = SPELLTYPE_PHYSICAL;
        }
        else if (tempString == "M")
        {
            spellDef->type = SPELLTYPE_MAGICAL;
        }

        // Range
        tempString = currentSpell["range"].toString();
        if (tempString == "T")
        {
            spellDef->range = SPELLRANGE_TOUCH;
        }
        else if (tempString == "LOS")
        {
            spellDef->range = SPELLRANGE_LOS;
        }
        else if (tempString == "LOS(A)")
        {
            spellDef->range = SPELLRANGE_LOS_AREA;
        }

        // Damage (optional)
        if (currentSpell.contains("damage"))
        {
            tempString = currentSpell["damage"].toString();
            if (tempString == "P")
            {
                spellDef->damageType = SPELLDAMAGE_PHYSICAL;
            }
            else if (tempString == "M")
            {
                spellDef->damageType = SPELLDAMAGE_MENTAL;
            }
        }

        // Duration
        tempString = currentSpell["duration"].toString();
        if (tempString == "I")
        {
            spellDef->duration = SPELLDURATION_INSTANT;
        }
        else if (tempString == "S")
        {
            spellDef->duration = SPELLDURATION_SUSTAINED;
        }
        else if (tempString == "P")
        {
            spellDef->duration = SPELLDURATION_PERMANENT;
        }

        // Drain
        spellDef->drain = currentSpell["drain"].toString();

        // Descriptors (optional)
        if (currentSpell.contains("descriptors"))
        {
            QVariantList list = currentSpell["descriptors"].toArray().toVariantList();
            QListIterator<QVariant> i(list);
            while (i.hasNext())
            {
                spellDef->descriptors << i.next().toString();
            }
        }

        // Does this spell require a custom choice?
        if (currentSpell.contains("requires_custom"))
        {
            abilityDef->requiresCustom = currentSpell["requires_custom"].toString() == "true";
            if (currentSpell.contains("custom_choices"))
            {
                QJsonObject obj = currentSpell["custom_choices"].toObject();
                abilityDef->customChoices = new CustomChoice(&obj);
            }
        }

        // Is this spell affected by the essence value?
        if (currentSpell.contains("essence_effect"))
        {
            spellDef->essenceEffect = currentSpell["essence_effect"].toString() == "true";
        }

        _definitions[uniqueId] = abilityDef;
        _spellDefinitions[uniqueId] = spellDef;
    }// END spells

    // Parse each adept power and add to the rules
    QJsonArray powersArray = doc.object().value("adept_powers").toArray();
    QJsonObject currentPower;
    AdeptPowerDefinition* powerDef = 0;
    for (int i = 0; i < powersArray.size(); ++i)
    {
        currentPower = powersArray.at(i).toObject();

        uniqueId = currentPower["unique_id"].toString();

        // Make sure the definition doesn't already exist
        if (_adeptPowerDefinitions.contains(uniqueId))
        {
            qCritical() << "Adept Power \"" << uniqueId << "\" already exists. Parsing aborted.";
            return;
        }

        // Add type definition
        abilityDef = new MagicAbilityDefinition();
        abilityDef->id = uniqueId;
        abilityDef->abilityType = MAGICABILITYTYPE_ADEPT_POWER;
        powerDef = new AdeptPowerDefinition();
        abilityDef->adeptPower = powerDef;

        // Get correct spell category and add to it
        category = _rootItem->children[MAGICABILITYTYPE_ADEPT_POWER];
        abilityDef->parent = category;
        category->children.push_back(abilityDef);

        // Translations
        tempObject = currentPower["translations"].toObject();
        for (int j = 0; j < tempObject.keys().size(); ++j)
        {
            abilityDef->translations[tempObject.keys().at(j)] = tempObject[tempObject.keys().at(j)].toString();
        }

        // Cost
        if (currentPower.contains("cost_per_level"))
        {
            powerDef->costType = COSTTYPE_PER_LEVEL;
            powerDef->costArray.push_back(currentPower["cost_per_level"].toString().toDouble());
        }
        else if (currentPower.contains("cost"))
        {
            QJsonValue::Type type = currentPower["cost"].type();

            // Normal cost or array
            if (type != QJsonValue::Array)
            {
                powerDef->costType = COSTTYPE_NORMAL;
                powerDef->costArray.push_back(currentPower["cost"].toString().toDouble());
            }
            else
            {
                powerDef->costType = COSTTYPE_ARRAY;
                tempArray = currentPower["cost"].toArray();

                // Add each array entry
                for (int j = 0; j < tempArray.size(); ++j)
                {
                    powerDef->costArray.push_back(tempArray[j].toString().toDouble());
                }
            }
        }

        // Activation (optional)
        if (currentPower.contains("activation"))
        {
            tempString = currentPower["activation"].toString();
            if (tempString == "interrupt")
            {
                powerDef->activationType = ACTIVATIONTYPE_INTERRUPT;
            }
            else if (tempString == "free")
            {
                powerDef->activationType = ACTIVATIONTYPE_FREE;
            }
            else if (tempString == "simple")
            {
                powerDef->activationType = ACTIVATIONTYPE_SIMPLE;
            }
        }

        // Does this power require a custom choice?
        if (currentPower.contains("requires_custom"))
        {
            abilityDef->requiresCustom = currentPower["requires_custom"].toString() == "true";
            if (currentPower.contains("custom_choices"))
            {
                QJsonObject obj = currentPower["custom_choices"].toObject();
                abilityDef->customChoices = new CustomChoice(&obj);
            }
        }

        // Does this power have effects?
        if (currentPower.contains("effects"))
        {
            tempArray = currentPower["effects"].toArray();
            for (int j = 0; j < tempArray.size(); ++j)
            {
                QJsonValueRef obj = tempArray[j];
                EffectSource source;
                source.magicAbility = abilityDef;
                abilityDef->effects.push_back(new Effect(&obj, source));
            }
        }

        _definitions[uniqueId] = abilityDef;
        _adeptPowerDefinitions[uniqueId] = powerDef;
    } // END adept powers

    // Parse each complex form and add to the rules
    QJsonArray formsArray = doc.object().value("complex_forms").toArray();
    QJsonObject currentForm;
    ComplexFormDefinition* formDef = 0;
    for (int i = 0; i < formsArray.size(); ++i)
    {
        currentForm = formsArray.at(i).toObject();

        uniqueId = currentForm["unique_id"].toString();

        // Make sure the definition doesn't already exist
        if (_complexFormDefinitions.contains(uniqueId))
        {
            qCritical() << "Complex Form \"" << uniqueId << "\" already exists. Parsing aborted.";
            return;
        }

        // Add form definition
        abilityDef = new MagicAbilityDefinition();
        abilityDef->id = uniqueId;
        abilityDef->abilityType = MAGICABILITYTYPE_COMPLEX_FORM;
        formDef = new ComplexFormDefinition();
        abilityDef->complexForm = formDef;

        // Get correct spell category and add to it
        category = _rootItem->children[MAGICABILITYTYPE_COMPLEX_FORM];
        abilityDef->parent = category;
        category->children.push_back(abilityDef);

        // Translations
        tempObject = currentForm["translations"].toObject();
        for (int j = 0; j < tempObject.keys().size(); ++j)
        {
            abilityDef->translations[tempObject.keys().at(j)] = tempObject[tempObject.keys().at(j)].toString();
        }

        // Target
        tempString = currentForm["target"].toString();
        if (tempString == "persona")
        {
            formDef->targetType = TARGETTYPE_PERSONA;
        }
        else if (tempString == "device")
        {
            formDef->targetType = TARGETTYPE_DEVICE;
        }
        else if (tempString == "file")
        {
            formDef->targetType = TARGETTYPE_FILE;
        }
        else if (tempString == "sprite")
        {
            formDef->targetType = TARGETTYPE_SPRITE;
        }

        // Duration
        tempString = currentForm["duration"].toString();
        if (tempString == "I")
        {
            formDef->duration = SPELLDURATION_INSTANT;
        }
        else if (tempString == "S")
        {
            formDef->duration = SPELLDURATION_SUSTAINED;
        }
        else if (tempString == "P")
        {
            formDef->duration = SPELLDURATION_PERMANENT;
        }

        // Fading Value
        formDef->fadingValue = currentForm["fading_value"].toString();

        // Does this form require a custom choice?
        if (currentForm.contains("requires_custom"))
        {
            abilityDef->requiresCustom = currentForm["requires_custom"].toString() == "true";
            if (currentForm.contains("custom_choices"))
            {
                QJsonObject obj = currentForm["custom_choices"].toObject();
                abilityDef->customChoices = new CustomChoice(&obj);
            }
        }

        _definitions[uniqueId] = abilityDef;
        _complexFormDefinitions[uniqueId] = formDef;
    } // END complex forms
}