<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "maemopackagecontents.h"

#include "maemopackagecreationstep.h"
#include "maemotoolchain.h"

#include <qt4projectmanager/profilereader.h>
#include <qt4projectmanager/qt4buildconfiguration.h>
#include <qt4projectmanager/qt4project.h>
#include <qt4projectmanager/qt4target.h>

#include <profile.h>
#include <prowriter.h>

#include <QtCore/QCryptographicHash>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>

namespace {
    QString pathVar(const QString &var)
    {
        return var + QLatin1String(".path");
    }

    QString filesVar(const QString &var)
    {
        return var + QLatin1String(".files");
    }

    const QLatin1String InstallsVar("INSTALLS");
    const QLatin1String TargetVar("target");
}

namespace Qt4ProjectManager {
namespace Internal {

MaemoPackageContents::MaemoPackageContents(MaemoPackageCreationStep *packageStep)
    : QAbstractTableModel(packageStep),
      m_packageStep(packageStep),
      m_proFileOption(new ProFileOption),
      m_proFileReader(new ProFileReader(m_proFileOption.data())),
      m_modified(false),
      m_proFile(0)
{
}

MaemoPackageContents::~MaemoPackageContents() {}

bool MaemoPackageContents::init()
{
    return m_proFile ? true : buildModel();
}

bool MaemoPackageContents::buildModel() const
{
    m_deployables.clear();
    const Qt4ProFileNode * const proFileNode = m_packageStep
        ->qt4BuildConfiguration()->qt4Target()->qt4Project()->rootProjectNode();
    if (m_proFileName.isEmpty()) {
        m_proFileName = proFileNode->path();
        m_proDir = QFileInfo(m_proFileName).dir();
    }

    resetProFileContents();
    if (!m_proFile)
        return false;

    const QStringList elemList = m_proFileReader->values(InstallsVar, m_proFile);
    bool targetFound = false;
    foreach (const QString &elem, elemList) {
        const QStringList paths
            = m_proFileReader->values(pathVar(elem), m_proFile);
        if (paths.count() != 1) {
            qWarning("Error: Variable %s has %d values.",
                qPrintable(pathVar(elem)), paths.count());
            continue;
        }

        const QStringList files
            = m_proFileReader->values(filesVar(elem), m_proFile);
        if (files.isEmpty() && elem != TargetVar) {
            qWarning("Error: Variable %s has no RHS.",
                qPrintable(filesVar(elem)));
            continue;
        }

        if (elem == TargetVar) {
            m_deployables.prepend(Deployable(m_packageStep->localExecutableFilePath(),
                paths.first()));
            targetFound = true;
        } else {
            foreach (const QString &file, files)
                m_deployables << Deployable(cleanPath(file), paths.first());
        }
    }

    if (!targetFound) {
        const QString remoteDir = proFileNode->projectType() == LibraryTemplate
            ? QLatin1String("/usr/local/lib")
            : QLatin1String("/usr/local/bin");
        m_deployables.prepend(Deployable(m_packageStep->localExecutableFilePath(),
            remoteDir));
        QString errorString;
        if (!readProFileContents(&errorString)) {
            qWarning("Error reading .pro file: %s", qPrintable(errorString));
            return false;
        }
        addValueToProFile(pathVar(TargetVar), remoteDir);
        addValueToProFile(InstallsVar, TargetVar);
        if (!writeProFileContents(&errorString)) {
            qWarning("Error writing .pro file: %s", qPrintable(errorString));
            return false;
        }
    }

    m_modified = true;
    return true;
}

MaemoPackageContents::Deployable MaemoPackageContents::deployableAt(int row) const
{
    Q_ASSERT(row >= 0 && row < rowCount());
    return m_deployables.at(row);
}

bool MaemoPackageContents::addDeployable(const Deployable &deployable,
    QString *error)
{
    if (m_deployables.contains(deployable) || deployableAt(0) == deployable)
        return false;

    if (!readProFileContents(error))
        return false;

    QCryptographicHash elemHash(QCryptographicHash::Md5);
    elemHash.addData(deployable.localFilePath.toUtf8());
    const QString elemName = QString::fromAscii(elemHash.result().toHex());
    addFileToProFile(filesVar(elemName), deployable.localFilePath);
    addValueToProFile(pathVar(elemName), deployable.remoteDir);
    addValueToProFile(InstallsVar, elemName);

    if (!writeProFileContents(error))
        return false;

    beginInsertRows(QModelIndex(), rowCount(), rowCount());
    m_deployables << deployable;
    endInsertRows();
    return true;
}

bool MaemoPackageContents::removeDeployableAt(int row, QString *error)
{
    Q_ASSERT(row > 0 && row < rowCount());

    const Deployable &deployable = deployableAt(row);
    const QString elemToRemove = findInstallsElem(deployable);
    if (elemToRemove.isEmpty()) {
        *error = tr("Inconsistent model: Deployable not found in  .pro file.");
        return false;
    }

    if (!readProFileContents(error))
        return false;

    const QString filesVarName = filesVar(elemToRemove);
    const bool isOnlyElem
        = m_proFileReader->values(filesVarName, m_proFile).count() == 1;
    bool success
        = removeFileFromProFile(filesVarName, deployable.localFilePath);
    if (success && isOnlyElem) {
        success = removeValueFromProFile(pathVar(elemToRemove),
            deployable.remoteDir);
        if (success)
            success = removeValueFromProFile(InstallsVar, elemToRemove);
    }
    if (!success) {
        *error = tr("Could not remove deployable from .pro file.");
        return false;
    }

    if (!writeProFileContents(error))
        return false;

    beginRemoveRows(QModelIndex(), row, row);
    m_deployables.removeAt(row - 1);
    endRemoveRows();
    return true;
}

int MaemoPackageContents::rowCount(const QModelIndex &parent) const
{
    if (!m_proFile)
        buildModel();
    return parent.isValid() ? 0 : m_deployables.count();
}

int MaemoPackageContents::columnCount(const QModelIndex &parent) const
{
    return parent.isValid() ? 0 : 2;
}

QVariant MaemoPackageContents::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || index.row() >= rowCount())
        return QVariant();

    const Deployable &d = deployableAt(index.row());
    if (index.column() == 0 && role == Qt::DisplayRole)
        return d.localFilePath;
    if (role == Qt::DisplayRole || role == Qt::EditRole)
        return d.remoteDir;
    return QVariant();
}

Qt::ItemFlags MaemoPackageContents::flags(const QModelIndex &index) const
{
    Qt::ItemFlags parentFlags = QAbstractTableModel::flags(index);
    if (index.column() == 1)
        return parentFlags | Qt::ItemIsEditable;
    return parentFlags;
}

bool MaemoPackageContents::setData(const QModelIndex &index,
                                   const QVariant &value, int role)
{
    if (!index.isValid() || index.row() >= rowCount() || index.column() != 1
        || role != Qt::EditRole)
        return false;

    QString error;
    if (!readProFileContents(&error)) {
        qWarning(qPrintable(error));
        return false;
    }

    Deployable &deployable = m_deployables[index.row()];
    const QString elemToChange = findInstallsElem(deployable);
    if (elemToChange.isEmpty()) {
        qWarning("Error: Inconsistent model. "
            "INSTALLS element not found in .pro file");
        return false;
    }
    const QString pathElem = pathVar(elemToChange);
    if (!removeValueFromProFile(pathElem, deployable.remoteDir)) {
        qWarning("Error: Could not change remote path in .pro file.");
        return false;
    }
    const QString &newRemoteDir = value.toString();
    addValueToProFile(pathElem, newRemoteDir);

    if (!writeProFileContents(&error)) {
        qWarning(qPrintable(error));
        return false;
    }

    deployable.remoteDir = newRemoteDir;
    emit dataChanged(index, index);
    return true;
}

QVariant MaemoPackageContents::headerData(int section,
             Qt::Orientation orientation, int role) const
{
    if (orientation == Qt::Vertical || role != Qt::DisplayRole)
        return QVariant();
    return section == 0 ? tr("Local File Path") : tr("Remote Directory");
}

QString MaemoPackageContents::remoteExecutableFilePath() const
{
    if (!m_proFile)
        buildModel();
    return deployableAt(0).remoteDir + '/' + m_packageStep->executableFileName();
}

bool MaemoPackageContents::readProFileContents(QString *error) const
{
    if (!m_proFileLines.isEmpty())
        return true;

    QFile proFileOnDisk(m_proFileName);
    if (!proFileOnDisk.open(QIODevice::ReadOnly)) {
        *error = tr("Project file '%1' could not be opened for reading.")
            .arg(m_proFileName);
        return false;
    }
    const QString proFileContents
        = QString::fromLatin1(proFileOnDisk.readAll());
    if (proFileOnDisk.error() != QFile::NoError) {
        *error = tr("Project file '%1' could not be read.")
            .arg(m_proFileName);
        return false;
    }
    m_proFileLines = proFileContents.split('\n');
    return true;
}

bool MaemoPackageContents::writeProFileContents(QString *error) const
{
    QFile proFileOnDisk(m_proFileName);
    if (!proFileOnDisk.open(QIODevice::WriteOnly)) {
        *error = tr("Project file '%1' could not be opened for writing.")
            .arg(m_proFileName);
        resetProFileContents();
        return false;
    }

    // TODO: Disconnect and reconnect FS watcher here.
    proFileOnDisk.write(m_proFileLines.join("\n").toLatin1());
    proFileOnDisk.close();
    if (proFileOnDisk.error() != QFile::NoError) {
        *error = tr("Project file '%1' could not be written.")
            .arg(m_proFileName);
        resetProFileContents();
        return false;
    }
    m_modified = true;
    return true;
}

QString MaemoPackageContents::cleanPath(const QString &relFileName) const
{
    // I'd rather use QDir::cleanPath(), but that doesn't work well
    // enough for redundant ".." dirs.
    return QFileInfo(m_proFile->directoryName() + '/'
        + relFileName).canonicalFilePath();
}

QString MaemoPackageContents::findInstallsElem(const Deployable &deployable) const
{
    const QStringList elems = m_proFileReader->values(InstallsVar, m_proFile);
    foreach (const QString &elem, elems) {
        const QStringList elemPaths
            = m_proFileReader->values(pathVar(elem), m_proFile);
        if (elemPaths.count() != 1 || elemPaths.first() != deployable.remoteDir)
            continue;
        if (elem == TargetVar)
            return elem;
        const QStringList elemFiles
            = m_proFileReader->values(filesVar(elem), m_proFile);
        foreach (const QString &file, elemFiles) {
            if (cleanPath(file) == deployable.localFilePath)
                return elem;
        }
    }
    return QString();
}

void MaemoPackageContents::addFileToProFile(const QString &var,
    const QString &absFilePath)
{
    ProWriter::addFiles(m_proFile, &m_proFileLines, m_proDir,
        QStringList(absFilePath), var);
    parseProFile(ParseFromLines);
}

void MaemoPackageContents::addValueToProFile(const QString &var,
    const QString &value) const
{
    ProWriter::addVarValues(m_proFile, &m_proFileLines, m_proDir,
        QStringList(value), var);
    parseProFile(ParseFromLines);
}

bool MaemoPackageContents::removeFileFromProFile(const QString &var,
    const QString &absFilePath)
{
    const bool success = ProWriter::removeFiles(m_proFile, &m_proFileLines,
        m_proDir, QStringList(absFilePath),
        QStringList(var)).isEmpty();
    if (success)
        parseProFile(ParseFromLines);
    else
        resetProFileContents();
    return success;
}

bool MaemoPackageContents::removeValueFromProFile(const QString &var,
    const QString &value)
{
    const bool success = ProWriter::removeVarValues(m_proFile,
        &m_proFileLines, m_proDir, QStringList(value),
        QStringList(var)).isEmpty();
    if (success)
        parseProFile(ParseFromLines);
    else
        resetProFileContents();
    return success;
}

void MaemoPackageContents::parseProFile(ParseType type) const
{
    if (type == ParseFromLines) {
        m_proFile = m_proFileReader->parsedProFile(m_proFileName,
            m_proFileLines.join("\n"));
    } else {
        m_proFile = m_proFileReader->readProFile(m_proFileName)
            ? m_proFileReader->proFileFor(m_proFileName) : 0;
    }
}

void MaemoPackageContents::resetProFileContents() const
{
    m_proFileLines.clear();
    parseProFile(ParseFromFile);
    if (!m_proFile)
        qWarning("Fatal: Could not parse .pro file '%s'.",
            qPrintable(m_proFileName));
}

} // namespace Qt4ProjectManager
} // namespace Internal
<commit_msg>Maemo: Compile fix.<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "maemopackagecontents.h"

#include "maemopackagecreationstep.h"
#include "maemotoolchain.h"

#include <qt4projectmanager/profilereader.h>
#include <qt4projectmanager/qt4buildconfiguration.h>
#include <qt4projectmanager/qt4project.h>
#include <qt4projectmanager/qt4target.h>

#include <prowriter.h>

#include <QtCore/QCryptographicHash>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>

namespace {
    QString pathVar(const QString &var)
    {
        return var + QLatin1String(".path");
    }

    QString filesVar(const QString &var)
    {
        return var + QLatin1String(".files");
    }

    const QLatin1String InstallsVar("INSTALLS");
    const QLatin1String TargetVar("target");
}

namespace Qt4ProjectManager {
namespace Internal {

MaemoPackageContents::MaemoPackageContents(MaemoPackageCreationStep *packageStep)
    : QAbstractTableModel(packageStep),
      m_packageStep(packageStep),
      m_proFileOption(new ProFileOption),
      m_proFileReader(new ProFileReader(m_proFileOption.data())),
      m_modified(false),
      m_proFile(0)
{
}

MaemoPackageContents::~MaemoPackageContents() {}

bool MaemoPackageContents::init()
{
    return m_proFile ? true : buildModel();
}

bool MaemoPackageContents::buildModel() const
{
    m_deployables.clear();
    const Qt4ProFileNode * const proFileNode = m_packageStep
        ->qt4BuildConfiguration()->qt4Target()->qt4Project()->rootProjectNode();
    if (m_proFileName.isEmpty()) {
        m_proFileName = proFileNode->path();
        m_proDir = QFileInfo(m_proFileName).dir();
    }

    resetProFileContents();
    if (!m_proFile)
        return false;

    const QStringList elemList = m_proFileReader->values(InstallsVar, m_proFile);
    bool targetFound = false;
    foreach (const QString &elem, elemList) {
        const QStringList paths
            = m_proFileReader->values(pathVar(elem), m_proFile);
        if (paths.count() != 1) {
            qWarning("Error: Variable %s has %d values.",
                qPrintable(pathVar(elem)), paths.count());
            continue;
        }

        const QStringList files
            = m_proFileReader->values(filesVar(elem), m_proFile);
        if (files.isEmpty() && elem != TargetVar) {
            qWarning("Error: Variable %s has no RHS.",
                qPrintable(filesVar(elem)));
            continue;
        }

        if (elem == TargetVar) {
            m_deployables.prepend(Deployable(m_packageStep->localExecutableFilePath(),
                paths.first()));
            targetFound = true;
        } else {
            foreach (const QString &file, files)
                m_deployables << Deployable(cleanPath(file), paths.first());
        }
    }

    if (!targetFound) {
        const QString remoteDir = proFileNode->projectType() == LibraryTemplate
            ? QLatin1String("/usr/local/lib")
            : QLatin1String("/usr/local/bin");
        m_deployables.prepend(Deployable(m_packageStep->localExecutableFilePath(),
            remoteDir));
        QString errorString;
        if (!readProFileContents(&errorString)) {
            qWarning("Error reading .pro file: %s", qPrintable(errorString));
            return false;
        }
        addValueToProFile(pathVar(TargetVar), remoteDir);
        addValueToProFile(InstallsVar, TargetVar);
        if (!writeProFileContents(&errorString)) {
            qWarning("Error writing .pro file: %s", qPrintable(errorString));
            return false;
        }
    }

    m_modified = true;
    return true;
}

MaemoPackageContents::Deployable MaemoPackageContents::deployableAt(int row) const
{
    Q_ASSERT(row >= 0 && row < rowCount());
    return m_deployables.at(row);
}

bool MaemoPackageContents::addDeployable(const Deployable &deployable,
    QString *error)
{
    if (m_deployables.contains(deployable) || deployableAt(0) == deployable)
        return false;

    if (!readProFileContents(error))
        return false;

    QCryptographicHash elemHash(QCryptographicHash::Md5);
    elemHash.addData(deployable.localFilePath.toUtf8());
    const QString elemName = QString::fromAscii(elemHash.result().toHex());
    addFileToProFile(filesVar(elemName), deployable.localFilePath);
    addValueToProFile(pathVar(elemName), deployable.remoteDir);
    addValueToProFile(InstallsVar, elemName);

    if (!writeProFileContents(error))
        return false;

    beginInsertRows(QModelIndex(), rowCount(), rowCount());
    m_deployables << deployable;
    endInsertRows();
    return true;
}

bool MaemoPackageContents::removeDeployableAt(int row, QString *error)
{
    Q_ASSERT(row > 0 && row < rowCount());

    const Deployable &deployable = deployableAt(row);
    const QString elemToRemove = findInstallsElem(deployable);
    if (elemToRemove.isEmpty()) {
        *error = tr("Inconsistent model: Deployable not found in  .pro file.");
        return false;
    }

    if (!readProFileContents(error))
        return false;

    const QString filesVarName = filesVar(elemToRemove);
    const bool isOnlyElem
        = m_proFileReader->values(filesVarName, m_proFile).count() == 1;
    bool success
        = removeFileFromProFile(filesVarName, deployable.localFilePath);
    if (success && isOnlyElem) {
        success = removeValueFromProFile(pathVar(elemToRemove),
            deployable.remoteDir);
        if (success)
            success = removeValueFromProFile(InstallsVar, elemToRemove);
    }
    if (!success) {
        *error = tr("Could not remove deployable from .pro file.");
        return false;
    }

    if (!writeProFileContents(error))
        return false;

    beginRemoveRows(QModelIndex(), row, row);
    m_deployables.removeAt(row - 1);
    endRemoveRows();
    return true;
}

int MaemoPackageContents::rowCount(const QModelIndex &parent) const
{
    if (!m_proFile)
        buildModel();
    return parent.isValid() ? 0 : m_deployables.count();
}

int MaemoPackageContents::columnCount(const QModelIndex &parent) const
{
    return parent.isValid() ? 0 : 2;
}

QVariant MaemoPackageContents::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || index.row() >= rowCount())
        return QVariant();

    const Deployable &d = deployableAt(index.row());
    if (index.column() == 0 && role == Qt::DisplayRole)
        return d.localFilePath;
    if (role == Qt::DisplayRole || role == Qt::EditRole)
        return d.remoteDir;
    return QVariant();
}

Qt::ItemFlags MaemoPackageContents::flags(const QModelIndex &index) const
{
    Qt::ItemFlags parentFlags = QAbstractTableModel::flags(index);
    if (index.column() == 1)
        return parentFlags | Qt::ItemIsEditable;
    return parentFlags;
}

bool MaemoPackageContents::setData(const QModelIndex &index,
                                   const QVariant &value, int role)
{
    if (!index.isValid() || index.row() >= rowCount() || index.column() != 1
        || role != Qt::EditRole)
        return false;

    QString error;
    if (!readProFileContents(&error)) {
        qWarning("%s", qPrintable(error));
        return false;
    }

    Deployable &deployable = m_deployables[index.row()];
    const QString elemToChange = findInstallsElem(deployable);
    if (elemToChange.isEmpty()) {
        qWarning("Error: Inconsistent model. "
            "INSTALLS element not found in .pro file");
        return false;
    }
    const QString pathElem = pathVar(elemToChange);
    if (!removeValueFromProFile(pathElem, deployable.remoteDir)) {
        qWarning("Error: Could not change remote path in .pro file.");
        return false;
    }
    const QString &newRemoteDir = value.toString();
    addValueToProFile(pathElem, newRemoteDir);

    if (!writeProFileContents(&error)) {
        qWarning("%s", qPrintable(error));
        return false;
    }

    deployable.remoteDir = newRemoteDir;
    emit dataChanged(index, index);
    return true;
}

QVariant MaemoPackageContents::headerData(int section,
             Qt::Orientation orientation, int role) const
{
    if (orientation == Qt::Vertical || role != Qt::DisplayRole)
        return QVariant();
    return section == 0 ? tr("Local File Path") : tr("Remote Directory");
}

QString MaemoPackageContents::remoteExecutableFilePath() const
{
    if (!m_proFile)
        buildModel();
    return deployableAt(0).remoteDir + '/' + m_packageStep->executableFileName();
}

bool MaemoPackageContents::readProFileContents(QString *error) const
{
    if (!m_proFileLines.isEmpty())
        return true;

    QFile proFileOnDisk(m_proFileName);
    if (!proFileOnDisk.open(QIODevice::ReadOnly)) {
        *error = tr("Project file '%1' could not be opened for reading.")
            .arg(m_proFileName);
        return false;
    }
    const QString proFileContents
        = QString::fromLatin1(proFileOnDisk.readAll());
    if (proFileOnDisk.error() != QFile::NoError) {
        *error = tr("Project file '%1' could not be read.")
            .arg(m_proFileName);
        return false;
    }
    m_proFileLines = proFileContents.split('\n');
    return true;
}

bool MaemoPackageContents::writeProFileContents(QString *error) const
{
    QFile proFileOnDisk(m_proFileName);
    if (!proFileOnDisk.open(QIODevice::WriteOnly)) {
        *error = tr("Project file '%1' could not be opened for writing.")
            .arg(m_proFileName);
        resetProFileContents();
        return false;
    }

    // TODO: Disconnect and reconnect FS watcher here.
    proFileOnDisk.write(m_proFileLines.join("\n").toLatin1());
    proFileOnDisk.close();
    if (proFileOnDisk.error() != QFile::NoError) {
        *error = tr("Project file '%1' could not be written.")
            .arg(m_proFileName);
        resetProFileContents();
        return false;
    }
    m_modified = true;
    return true;
}

QString MaemoPackageContents::cleanPath(const QString &relFileName) const
{
    // I'd rather use QDir::cleanPath(), but that doesn't work well
    // enough for redundant ".." dirs.
    return QFileInfo(m_proFile->directoryName() + '/'
        + relFileName).canonicalFilePath();
}

QString MaemoPackageContents::findInstallsElem(const Deployable &deployable) const
{
    const QStringList elems = m_proFileReader->values(InstallsVar, m_proFile);
    foreach (const QString &elem, elems) {
        const QStringList elemPaths
            = m_proFileReader->values(pathVar(elem), m_proFile);
        if (elemPaths.count() != 1 || elemPaths.first() != deployable.remoteDir)
            continue;
        if (elem == TargetVar)
            return elem;
        const QStringList elemFiles
            = m_proFileReader->values(filesVar(elem), m_proFile);
        foreach (const QString &file, elemFiles) {
            if (cleanPath(file) == deployable.localFilePath)
                return elem;
        }
    }
    return QString();
}

void MaemoPackageContents::addFileToProFile(const QString &var,
    const QString &absFilePath)
{
    ProWriter::addFiles(m_proFile, &m_proFileLines, m_proDir,
        QStringList(absFilePath), var);
    parseProFile(ParseFromLines);
}

void MaemoPackageContents::addValueToProFile(const QString &var,
    const QString &value) const
{
    ProWriter::addVarValues(m_proFile, &m_proFileLines, m_proDir,
        QStringList(value), var);
    parseProFile(ParseFromLines);
}

bool MaemoPackageContents::removeFileFromProFile(const QString &var,
    const QString &absFilePath)
{
    const bool success = ProWriter::removeFiles(m_proFile, &m_proFileLines,
        m_proDir, QStringList(absFilePath),
        QStringList(var)).isEmpty();
    if (success)
        parseProFile(ParseFromLines);
    else
        resetProFileContents();
    return success;
}

bool MaemoPackageContents::removeValueFromProFile(const QString &var,
    const QString &value)
{
    const bool success = ProWriter::removeVarValues(m_proFile,
        &m_proFileLines, m_proDir, QStringList(value),
        QStringList(var)).isEmpty();
    if (success)
        parseProFile(ParseFromLines);
    else
        resetProFileContents();
    return success;
}

void MaemoPackageContents::parseProFile(ParseType type) const
{
    if (type == ParseFromLines) {
        m_proFile = m_proFileReader->parsedProFile(m_proFileName,
            m_proFileLines.join("\n"));
    } else {
        m_proFile = m_proFileReader->readProFile(m_proFileName)
            ? m_proFileReader->proFileFor(m_proFileName) : 0;
    }
}

void MaemoPackageContents::resetProFileContents() const
{
    m_proFileLines.clear();
    parseProFile(ParseFromFile);
    if (!m_proFile)
        qWarning("Fatal: Could not parse .pro file '%s'.",
            qPrintable(m_proFileName));
}

} // namespace Qt4ProjectManager
} // namespace Internal
<|endoftext|>


<commit_before>#ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__STUDENT_T_HPP__
#define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__STUDENT_T_HPP__

#include <stan/agrad.hpp>
#include <stan/math/error_handling.hpp>
#include <stan/math/special_functions.hpp>
#include <stan/meta/traits.hpp>
#include <stan/prob/constants.hpp>
#include <stan/prob/traits.hpp>
#include <stan/prob/internal_math.hpp>

namespace stan {

  namespace prob {

    /**
     * The log of the Student-t density for the given y, nu, mean, and
     * scale parameter.  The scale parameter must be greater
     * than 0.
     *
     * \f{eqnarray*}{
       y &\sim& t_{\nu} (\mu, \sigma^2) \\
       \log (p (y \,|\, \nu, \mu, \sigma) ) &=& \log \left( \frac{\Gamma((\nu + 1) /2)}
           {\Gamma(\nu/2)\sqrt{\nu \pi} \sigma} \left( 1 + \frac{1}{\nu} (\frac{y - \mu}{\sigma})^2 \right)^{-(\nu + 1)/2} \right) \\
       &=& \log( \Gamma( (\nu+1)/2 )) - \log (\Gamma (\nu/2) - \frac{1}{2} \log(\nu \pi) - \log(\sigma)
           -\frac{\nu + 1}{2} \log (1 + \frac{1}{\nu} (\frac{y - \mu}{\sigma})^2)
     \f}
     *
     * @param y A scalar variable.
     * @param nu Degrees of freedom.
     * @param mu The mean of the Student-t distribution.
     * @param sigma The scale parameter of the Student-t distribution.
     * @return The log of the Student-t density at y.
     * @throw std::domain_error if sigma is not greater than 0.
     * @throw std::domain_error if nu is not greater than 0.
     * @tparam T_y Type of scalar.
     * @tparam T_dof Type of degrees of freedom.
     * @tparam T_loc Type of location.
     * @tparam T_scale Type of scale.
     */
    template <bool propto, typename T_y, typename T_dof,
              typename T_loc, typename T_scale,
              class Policy>
    typename return_type<T_y,T_dof,T_loc,T_scale>::type
    student_t_log(const T_y& y, const T_dof& nu, const T_loc& mu,
                  const T_scale& sigma,
                  const Policy&) {
      static const char* function = "stan::prob::student_t_log(%1%)";

      using stan::math::check_positive;
      using stan::math::check_finite;
      using stan::math::check_not_nan;
      using stan::math::check_consistent_sizes;

      // check if any vectors are zero length
      if (!(stan::length(y)
            && stan::length(nu)
            && stan::length(mu)
	    && stan::length(sigma)))
        return 0.0;

      typename return_type<T_y,T_dof,T_loc,T_scale>::type logp = 0.0;

      // validate args (here done over var, which should be OK)
      if (!check_not_nan(function, y, "Random variable", &logp, Policy()))
        return logp;
      if(!check_finite(function, nu, "Degrees of freedom parameter", &logp, Policy()))
        return logp;
      if(!check_positive(function, nu, "Degrees of freedom parameter", &logp, Policy()))
        return logp;
      if (!check_finite(function, mu, "Location parameter",
                        &logp, Policy()))
        return logp;
      if (!check_finite(function, sigma, "Scale parameter",
                        &logp, Policy()))
        return logp;
      if (!check_positive(function, sigma, "Scale parameter",
                          &logp, Policy()))
        return logp;

      if (!(check_consistent_sizes(function,
                                   y,nu,mu,sigma,
				   "Random variable","Degrees of freedom parameter","Location parameter","Scale parameter",
                                   &logp, Policy())))
        return logp;

      // check if no variables are involved and prop-to
      if (!include_summand<propto,T_y,T_dof,T_loc,T_scale>::value)
	return 0.0;

      VectorView<const T_y> y_vec(y);
      VectorView<const T_dof> nu_vec(nu);
      VectorView<const T_loc> mu_vec(mu);
      VectorView<const T_scale> sigma_vec(sigma);
      size_t N = max_size(y, nu, mu, sigma);

      using stan::math::square;
      using boost::math::lgamma;

      using std::log;

      for (size_t n = 0; n < N; n++) {
	if (include_summand<propto,T_dof>::value)
	  logp += lgamma( (nu_vec[n] + 1.0) / 2.0) - lgamma(nu_vec[n] / 2.0);
	if (include_summand<propto>::value)
	  logp += NEG_LOG_SQRT_PI;
	if (include_summand<propto,T_dof>::value)
	  logp -= 0.5 * log(nu_vec[n]);
	if (include_summand<propto,T_scale>::value)
	  logp -= log(sigma_vec[n]);
	if (include_summand<propto,T_y,T_dof,T_loc,T_scale>::value)
	  logp -= ((nu_vec[n] + 1.0) / 2.0)
	    * log1p( square(((y_vec[n] - mu_vec[n]) / sigma_vec[n])) / nu_vec[n]);
      }
      return logp;
    }

    template <bool propto,
              typename T_y, typename T_dof, typename T_loc, typename T_scale>
    inline
    typename return_type<T_y,T_dof,T_loc,T_scale>::type
    student_t_log(const T_y& y, const T_dof& nu, const T_loc& mu,
                  const T_scale& sigma) {
      return student_t_log<propto>(y,nu,mu,sigma,stan::math::default_policy());
    }

    template <typename T_y, typename T_dof, typename T_loc, typename T_scale,
              class Policy>
    inline
    typename return_type<T_y,T_dof,T_loc,T_scale>::type
    student_t_log(const T_y& y, const T_dof& nu, const T_loc& mu,
                  const T_scale& sigma,
                  const Policy&) {
      return student_t_log<false>(y,nu,mu,sigma,Policy());
    }

    template <typename T_y, typename T_dof, typename T_loc, typename T_scale>
    inline
    typename return_type<T_y,T_dof,T_loc,T_scale>::type
    student_t_log(const T_y& y, const T_dof& nu, const T_loc& mu,
                  const T_scale& sigma) {
      return student_t_log<false>(y,nu,mu,sigma,stan::math::default_policy());
    }

      template <typename T_y, typename T_dof, typename T_loc, typename T_scale, class Policy>
      typename boost::math::tools::promote_args<T_y, T_dof, T_loc, T_scale>::type
      student_t_cdf(const T_y& y, const T_dof& nu, const T_loc& mu, const T_scale& sigma, const Policy&) {

          static const char* function = "stan::prob::student_t_cdf(%1%)";

          using stan::math::check_positive;
          using stan::math::check_finite;
          using stan::math::check_not_nan;
          using stan::math::check_consistent_sizes;

          using boost::math::tools::promote_args;

          double P(1.0);

          if (!check_not_nan(function, y, "Random variable", &P, Policy()))
              return P;

          if(!check_finite(function, nu, "Degrees of freedom parameter", &P, Policy()))
              return P;

          if(!check_positive(function, nu, "Degrees of freedom parameter", &P, Policy()))
              return P;

          if (!check_finite(function, mu, "Location parameter",
                            &P, Policy()))
              return P;

          if (!check_finite(function, sigma, "Scale parameter",
                            &P, Policy()))
              return P;
          if (!check_positive(function, sigma, "Scale parameter",
                              &P, Policy()))
              return P;

          // Wrap arguments in vectors
          VectorView<const T_y> y_vec(y);
          VectorView<const T_dof> nu_vec(nu);
          VectorView<const T_loc> mu_vec(mu);
          VectorView<const T_scale> sigma_vec(sigma);
          //size_t N = max_size(y, nu, mu, sigma);
          size_t N = max_size(y, nu);

          agrad::OperandsAndPartials<T_y, T_dof, T_loc, T_scale> operands_and_partials(y, nu, mu, sigma);

          std::fill(operands_and_partials.all_partials,
                    operands_and_partials.all_partials + operands_and_partials.nvaris, 0.0);

          using stan::math::value_of;
          using boost::math::ibeta;
          using boost::math::ibeta_derivative;

          using boost::math::digamma;
          using boost::math::beta;

          // Cache a few expensive function calls if nu is a parameter
          double digammaHalf = 0;

          DoubleVectorView<!is_constant_struct<T_dof>::value, T_dof> digamma_vec(stan::length(nu));
          DoubleVectorView<!is_constant_struct<T_dof>::value, T_dof> digammaNu_vec(stan::length(nu));
          DoubleVectorView<!is_constant_struct<T_dof>::value, T_dof> digammaNuPlusHalf_vec(stan::length(nu));
          DoubleVectorView<!is_constant_struct<T_dof>::value, T_dof> betaNuHalf_vec(stan::length(nu));

          if (!is_constant_struct<T_dof>::value) {

              digammaHalf = digamma(0.5);

              for (size_t i = 0; i < stan::length(nu); i++) {

                  const double nu_dbl = value_of(nu_vec[i]);

                  digammaNu_vec[i] = digamma(0.5 * nu_dbl);
                  digammaNuPlusHalf_vec[i] = digamma(0.5 + 0.5 * nu_dbl);
                  betaNuHalf_vec[i] = beta(0.5, 0.5 * nu_dbl);

              }

          }

          // Compute vectorized CDF and gradient
          for (size_t n = 0; n < N; n++) {

              const double sigma_inv = 1.0 / value_of(sigma_vec[n]);
              const double t = (value_of(y_vec[n]) - value_of(mu_vec[n])) * sigma_inv;
              const double nu_dbl = value_of(nu_vec[n]);
              const double q = nu_dbl / (t * t);
              const double r = 1.0 / (1.0 + q);
              double J = - 2 * r * r * q / t;

              if(q < 2)
              {

                  double z = ibeta(0.5 * nu_dbl, 0.5, 1.0 - r);

                  const double Pn = t > 0 ? 1.0 - 0.5 * z : 0.5 * z;

                  double d_ibeta = ibeta_derivative(0.5 * nu_dbl, 0.5, 1.0 - r);

                  P *= Pn;

                  if (!is_constant_struct<T_y>::value)
                      operands_and_partials.d_x1[n]
                      += (d_ibeta * J * sigma_inv) / Pn;

                  if (!is_constant_struct<T_dof>::value) {

                      double g1 = 0;
                      double g2 = 0;

                      stan::math::gradRegIncBeta(g1, g2, 0.5 * nu_dbl, 0.5, 1.0 - r,
                                     digammaNu_vec[n], digammaHalf, digammaNuPlusHalf_vec[n], betaNuHalf_vec[n]);

                      operands_and_partials.d_x2[n]
                      += 0.5 * ( d_ibeta * (r / t) * (r / t) + 0.5 * g1 ) / Pn;

                  }

                  if (!is_constant_struct<T_loc>::value)
                      operands_and_partials.d_x3[n]
                      += (- d_ibeta * J * sigma_inv) / Pn;

                  if (!is_constant_struct<T_scale>::value)
                      operands_and_partials.d_x4[n]
                      += (- d_ibeta * J * sigma_inv * t) / Pn;

              }
              else
              {

                  double z = 1.0 - ibeta(0.5, 0.5 * nu_dbl, r);

                  const double Pn = t > 0 ? 1.0 - 0.5 * z : 0.5 * z;

                  double d_ibeta = ibeta_derivative(0.5, 0.5 * nu_dbl, r);

                  P *= Pn;

                  if (!is_constant_struct<T_y>::value)
                      operands_and_partials.d_x1[n]
                      += (d_ibeta * J * sigma_inv) / Pn;

                  if (!is_constant_struct<T_dof>::value) {

                      double g1 = 0;
                      double g2 = 0;

                      stan::math::gradRegIncBeta(g1, g2, 0.5, 0.5 * nu_dbl, r,
                                     digammaHalf, digammaNu_vec[n], digammaNuPlusHalf_vec[n], betaNuHalf_vec[n]);

                      operands_and_partials.d_x2[n]
                      += 0.5 * ( - d_ibeta * (r / t) * (r / t) + 0.5 * g2 ) / Pn;

                  }

                  if (!is_constant_struct<T_loc>::value)
                      operands_and_partials.d_x3[n]
                      += (- d_ibeta * J * sigma_inv) / Pn;

                  if (!is_constant_struct<T_scale>::value)
                      operands_and_partials.d_x4[n]
                      += (- d_ibeta * J * sigma_inv * t) / Pn;

              }

              if(t > 0) operands_and_partials.d_x2[n] *= -1;

          }

          for (size_t n = 0; n < N; n++) {

              if (!is_constant_struct<T_y>::value)
                  operands_and_partials.d_x1[n] *= P;

              if (!is_constant_struct<T_dof>::value)
                  operands_and_partials.d_x2[n] *= P;

              if (!is_constant_struct<T_loc>::value)
                  operands_and_partials.d_x3[n] *= P;

              if (!is_constant_struct<T_scale>::value)
                  operands_and_partials.d_x4[n] *= P;

          }

          return operands_and_partials.to_var(P);

      }

      template <typename T_y, typename T_dof, typename T_loc, typename T_scale>
      typename boost::math::tools::promote_args<T_y,T_dof,T_loc,T_scale>::type
      student_t_cdf(const T_y& y, const T_dof& nu, const T_loc& mu, const T_scale& sigma) {
          return student_t_cdf(y, nu,  mu, sigma, stan::math::default_policy());
      }

  }
}
#endif
<commit_msg>refactoring student_t distribution<commit_after>#ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__STUDENT_T_HPP__
#define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__STUDENT_T_HPP__

#include <stan/agrad.hpp>
#include <stan/math/error_handling.hpp>
#include <stan/math/special_functions.hpp>
#include <stan/meta/traits.hpp>
#include <stan/prob/constants.hpp>
#include <stan/prob/traits.hpp>
#include <stan/prob/internal_math.hpp>

namespace stan {

  namespace prob {

    /**
     * The log of the Student-t density for the given y, nu, mean, and
     * scale parameter.  The scale parameter must be greater
     * than 0.
     *
     * \f{eqnarray*}{
       y &\sim& t_{\nu} (\mu, \sigma^2) \\
       \log (p (y \,|\, \nu, \mu, \sigma) ) &=& \log \left( \frac{\Gamma((\nu + 1) /2)}
           {\Gamma(\nu/2)\sqrt{\nu \pi} \sigma} \left( 1 + \frac{1}{\nu} (\frac{y - \mu}{\sigma})^2 \right)^{-(\nu + 1)/2} \right) \\
       &=& \log( \Gamma( (\nu+1)/2 )) - \log (\Gamma (\nu/2) - \frac{1}{2} \log(\nu \pi) - \log(\sigma)
           -\frac{\nu + 1}{2} \log (1 + \frac{1}{\nu} (\frac{y - \mu}{\sigma})^2)
     \f}
     *
     * @param y A scalar variable.
     * @param nu Degrees of freedom.
     * @param mu The mean of the Student-t distribution.
     * @param sigma The scale parameter of the Student-t distribution.
     * @return The log of the Student-t density at y.
     * @throw std::domain_error if sigma is not greater than 0.
     * @throw std::domain_error if nu is not greater than 0.
     * @tparam T_y Type of scalar.
     * @tparam T_dof Type of degrees of freedom.
     * @tparam T_loc Type of location.
     * @tparam T_scale Type of scale.
     */
    template <bool propto, typename T_y, typename T_dof,
              typename T_loc, typename T_scale,
              class Policy>
    typename return_type<T_y,T_dof,T_loc,T_scale>::type
    student_t_log(const T_y& y, const T_dof& nu, const T_loc& mu,
                  const T_scale& sigma,
                  const Policy&) {
      static const char* function = "stan::prob::student_t_log(%1%)";

      using stan::math::check_positive;
      using stan::math::check_finite;
      using stan::math::check_not_nan;
      using stan::math::check_consistent_sizes;

      // check if any vectors are zero length
      if (!(stan::length(y)
            && stan::length(nu)
            && stan::length(mu)
	    && stan::length(sigma)))
        return 0.0;

      typename return_type<T_y,T_dof,T_loc,T_scale>::type logp = 0.0;

      // validate args (here done over var, which should be OK)
      if (!check_not_nan(function, y, "Random variable", &logp, Policy()))
        return logp;
      if(!check_finite(function, nu, "Degrees of freedom parameter", &logp, Policy()))
        return logp;
      if(!check_positive(function, nu, "Degrees of freedom parameter", &logp, Policy()))
        return logp;
      if (!check_finite(function, mu, "Location parameter",
                        &logp, Policy()))
        return logp;
      if (!check_finite(function, sigma, "Scale parameter",
                        &logp, Policy()))
        return logp;
      if (!check_positive(function, sigma, "Scale parameter",
                          &logp, Policy()))
        return logp;

      if (!(check_consistent_sizes(function,
                                   y,nu,mu,sigma,
				   "Random variable","Degrees of freedom parameter","Location parameter","Scale parameter",
                                   &logp, Policy())))
        return logp;

      // check if no variables are involved and prop-to
      if (!include_summand<propto,T_y,T_dof,T_loc,T_scale>::value)
	return 0.0;

      VectorView<const T_y> y_vec(y);
      VectorView<const T_dof> nu_vec(nu);
      VectorView<const T_loc> mu_vec(mu);
      VectorView<const T_scale> sigma_vec(sigma);
      size_t N = max_size(y, nu, mu, sigma);

      using stan::math::square;
      using boost::math::lgamma;

      using std::log;

      for (size_t n = 0; n < N; n++) {
	if (include_summand<propto,T_dof>::value)
	  logp += lgamma( (nu_vec[n] + 1.0) / 2.0) - lgamma(nu_vec[n] / 2.0);
	if (include_summand<propto>::value)
	  logp += NEG_LOG_SQRT_PI;
	if (include_summand<propto,T_dof>::value)
	  logp -= 0.5 * log(nu_vec[n]);
	if (include_summand<propto,T_scale>::value)
	  logp -= log(sigma_vec[n]);
	if (include_summand<propto,T_y,T_dof,T_loc,T_scale>::value)
	  logp -= ((nu_vec[n] + 1.0) / 2.0)
	    * log1p( square(((y_vec[n] - mu_vec[n]) / sigma_vec[n])) / nu_vec[n]);
      }
      return logp;
    }

    template <bool propto,
              typename T_y, typename T_dof, typename T_loc, typename T_scale>
    inline
    typename return_type<T_y,T_dof,T_loc,T_scale>::type
    student_t_log(const T_y& y, const T_dof& nu, const T_loc& mu,
                  const T_scale& sigma) {
      return student_t_log<propto>(y,nu,mu,sigma,stan::math::default_policy());
    }

    template <typename T_y, typename T_dof, typename T_loc, typename T_scale,
              class Policy>
    inline
    typename return_type<T_y,T_dof,T_loc,T_scale>::type
    student_t_log(const T_y& y, const T_dof& nu, const T_loc& mu,
                  const T_scale& sigma,
                  const Policy&) {
      return student_t_log<false>(y,nu,mu,sigma,Policy());
    }

    template <typename T_y, typename T_dof, typename T_loc, typename T_scale>
    inline
    typename return_type<T_y,T_dof,T_loc,T_scale>::type
    student_t_log(const T_y& y, const T_dof& nu, const T_loc& mu,
                  const T_scale& sigma) {
      return student_t_log<false>(y,nu,mu,sigma,stan::math::default_policy());
    }

      template <typename T_y, typename T_dof, typename T_loc, typename T_scale, class Policy>
      typename boost::math::tools::promote_args<T_y, T_dof, T_loc, T_scale>::type
      student_t_cdf(const T_y& y, const T_dof& nu, const T_loc& mu, const T_scale& sigma, const Policy&) {

          static const char* function = "stan::prob::student_t_cdf(%1%)";

          using stan::math::check_positive;
          using stan::math::check_finite;
          using stan::math::check_not_nan;
          using stan::math::check_consistent_sizes;

          using boost::math::tools::promote_args;

          double P(1.0);

          if (!check_not_nan(function, y, "Random variable", &P, Policy()))
              return P;

          if(!check_finite(function, nu, "Degrees of freedom parameter", &P, Policy()))
              return P;

          if(!check_positive(function, nu, "Degrees of freedom parameter", &P, Policy()))
              return P;

          if (!check_finite(function, mu, "Location parameter",
                            &P, Policy()))
              return P;

          if (!check_finite(function, sigma, "Scale parameter",
                            &P, Policy()))
              return P;
          if (!check_positive(function, sigma, "Scale parameter",
                              &P, Policy()))
              return P;

          // Wrap arguments in vectors
          VectorView<const T_y> y_vec(y);
          VectorView<const T_dof> nu_vec(nu);
          VectorView<const T_loc> mu_vec(mu);
          VectorView<const T_scale> sigma_vec(sigma);
          //size_t N = max_size(y, nu, mu, sigma);
          size_t N = max_size(y, nu);

          agrad::OperandsAndPartials<T_y, T_dof, T_loc, T_scale> operands_and_partials(y, nu, mu, sigma);

          std::fill(operands_and_partials.all_partials,
                    operands_and_partials.all_partials + operands_and_partials.nvaris, 0.0);

          using stan::math::value_of;
          using boost::math::ibeta;
          using boost::math::ibeta_derivative;

          using boost::math::digamma;
          using boost::math::beta;

          // Cache a few expensive function calls if nu is a parameter
          double digammaHalf = 0;

          DoubleVectorView<!is_constant_struct<T_dof>::value,is_vector<T_dof>::value> digamma_vec(stan::length(nu));
          DoubleVectorView<!is_constant_struct<T_dof>::value,is_vector<T_dof>::value> digammaNu_vec(stan::length(nu));
          DoubleVectorView<!is_constant_struct<T_dof>::value,is_vector<T_dof>::value> digammaNuPlusHalf_vec(stan::length(nu));
          DoubleVectorView<!is_constant_struct<T_dof>::value,is_vector<T_dof>::value> betaNuHalf_vec(stan::length(nu));

          if (!is_constant_struct<T_dof>::value) {

              digammaHalf = digamma(0.5);

              for (size_t i = 0; i < stan::length(nu); i++) {

                  const double nu_dbl = value_of(nu_vec[i]);

                  digammaNu_vec[i] = digamma(0.5 * nu_dbl);
                  digammaNuPlusHalf_vec[i] = digamma(0.5 + 0.5 * nu_dbl);
                  betaNuHalf_vec[i] = beta(0.5, 0.5 * nu_dbl);

              }

          }

          // Compute vectorized CDF and gradient
          for (size_t n = 0; n < N; n++) {

              const double sigma_inv = 1.0 / value_of(sigma_vec[n]);
              const double t = (value_of(y_vec[n]) - value_of(mu_vec[n])) * sigma_inv;
              const double nu_dbl = value_of(nu_vec[n]);
              const double q = nu_dbl / (t * t);
              const double r = 1.0 / (1.0 + q);
              double J = - 2 * r * r * q / t;

              if(q < 2)
              {

                  double z = ibeta(0.5 * nu_dbl, 0.5, 1.0 - r);

                  const double Pn = t > 0 ? 1.0 - 0.5 * z : 0.5 * z;

                  double d_ibeta = ibeta_derivative(0.5 * nu_dbl, 0.5, 1.0 - r);

                  P *= Pn;

                  if (!is_constant_struct<T_y>::value)
                      operands_and_partials.d_x1[n]
                      += (d_ibeta * J * sigma_inv) / Pn;

                  if (!is_constant_struct<T_dof>::value) {

                      double g1 = 0;
                      double g2 = 0;

                      stan::math::gradRegIncBeta(g1, g2, 0.5 * nu_dbl, 0.5, 1.0 - r,
                                     digammaNu_vec[n], digammaHalf, digammaNuPlusHalf_vec[n], betaNuHalf_vec[n]);

                      operands_and_partials.d_x2[n]
                      += 0.5 * ( d_ibeta * (r / t) * (r / t) + 0.5 * g1 ) / Pn;

                  }

                  if (!is_constant_struct<T_loc>::value)
                      operands_and_partials.d_x3[n]
                      += (- d_ibeta * J * sigma_inv) / Pn;

                  if (!is_constant_struct<T_scale>::value)
                      operands_and_partials.d_x4[n]
                      += (- d_ibeta * J * sigma_inv * t) / Pn;

              }
              else
              {

                  double z = 1.0 - ibeta(0.5, 0.5 * nu_dbl, r);

                  const double Pn = t > 0 ? 1.0 - 0.5 * z : 0.5 * z;

                  double d_ibeta = ibeta_derivative(0.5, 0.5 * nu_dbl, r);

                  P *= Pn;

                  if (!is_constant_struct<T_y>::value)
                      operands_and_partials.d_x1[n]
                      += (d_ibeta * J * sigma_inv) / Pn;

                  if (!is_constant_struct<T_dof>::value) {

                      double g1 = 0;
                      double g2 = 0;

                      stan::math::gradRegIncBeta(g1, g2, 0.5, 0.5 * nu_dbl, r,
                                     digammaHalf, digammaNu_vec[n], digammaNuPlusHalf_vec[n], betaNuHalf_vec[n]);

                      operands_and_partials.d_x2[n]
                      += 0.5 * ( - d_ibeta * (r / t) * (r / t) + 0.5 * g2 ) / Pn;

                  }

                  if (!is_constant_struct<T_loc>::value)
                      operands_and_partials.d_x3[n]
                      += (- d_ibeta * J * sigma_inv) / Pn;

                  if (!is_constant_struct<T_scale>::value)
                      operands_and_partials.d_x4[n]
                      += (- d_ibeta * J * sigma_inv * t) / Pn;

              }

              if(t > 0) operands_and_partials.d_x2[n] *= -1;

          }

          for (size_t n = 0; n < N; n++) {

              if (!is_constant_struct<T_y>::value)
                  operands_and_partials.d_x1[n] *= P;

              if (!is_constant_struct<T_dof>::value)
                  operands_and_partials.d_x2[n] *= P;

              if (!is_constant_struct<T_loc>::value)
                  operands_and_partials.d_x3[n] *= P;

              if (!is_constant_struct<T_scale>::value)
                  operands_and_partials.d_x4[n] *= P;

          }

          return operands_and_partials.to_var(P);

      }

      template <typename T_y, typename T_dof, typename T_loc, typename T_scale>
      typename boost::math::tools::promote_args<T_y,T_dof,T_loc,T_scale>::type
      student_t_cdf(const T_y& y, const T_dof& nu, const T_loc& mu, const T_scale& sigma) {
          return student_t_cdf(y, nu,  mu, sigma, stan::math::default_policy());
      }

  }
}
#endif
<|endoftext|>


<commit_before>#include "groupwiseserver.h"

#include <kaboutdata.h>
#include <kapplication.h>
#include <kcmdlineargs.h>
#include <kconfig.h>
#include <kdebug.h>

#include <iostream>

static const KCmdLineOptions options[] =
{
  { "s", 0, 0 },
  { "server <hostname>", I18N_NOOP("Server"), 0 },
  { "u", 0, 0 },
  { "user <string>", I18N_NOOP("User"), 0 },
  { "p", 0, 0 },
  { "password <string>", I18N_NOOP("Password"), 0 },
  KCmdLineLastOption
};

int main( int argc, char **argv )
{
  KAboutData aboutData( "soapdebug", I18N_NOOP("Groupwise Soap Debug"), "0.1" );
  aboutData.addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" );

  KCmdLineArgs::init( argc, argv, &aboutData );
  KCmdLineArgs::addCmdLineOptions( options );

  KApplication app;

  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

  QString user = args->getOption( "user" );
  QString pass = args->getOption( "password" );
  QString url = args->getOption( "server" );

  if ( user.isEmpty() ) {
    kdError() << "Need user." << endl;
    return 1;
  }
  if ( pass.isEmpty() ) {
    kdError() << "Need password." << endl;
    return 1;
  }
  if ( url.isEmpty() ) {
    kdError() << "Need server." << endl;
    return 1;
  }

  GroupwiseServer server( url, user, pass, 0 );

  if ( !server.login() ) {
    kdError() << "Unable to login to server " << url << endl;
    return 1;
  }

#if 0
  server.dumpData();
#endif

#if 0
  server.getCategoryList();
#endif

#if 1
  server.dumpFolderList();
#endif

#if 0
  server.getDelta();
#endif

  server.logout();

  return 0;
}

<commit_msg>Test code for free/busy retrieval.<commit_after>#include "groupwiseserver.h"

#include <kaboutdata.h>
#include <kapplication.h>
#include <kcmdlineargs.h>
#include <kconfig.h>
#include <kdebug.h>

#include <iostream>

static const KCmdLineOptions options[] =
{
  { "s", 0, 0 },
  { "server <hostname>", I18N_NOOP("Server"), 0 },
  { "u", 0, 0 },
  { "user <string>", I18N_NOOP("User"), 0 },
  { "p", 0, 0 },
  { "password <string>", I18N_NOOP("Password"), 0 },
  { "f", 0, 0 },
  { "freebusy-user <string>", I18N_NOOP("Free/Busy user name"), 0 },
  KCmdLineLastOption
};

int main( int argc, char **argv )
{
  KAboutData aboutData( "soapdebug", I18N_NOOP("Groupwise Soap Debug"), "0.1" );
  aboutData.addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" );

  KCmdLineArgs::init( argc, argv, &aboutData );
  KCmdLineArgs::addCmdLineOptions( options );

  KApplication app;

  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

  QString user = args->getOption( "user" );
  QString pass = args->getOption( "password" );
  QString url = args->getOption( "server" );

#if 0
  if ( user.isEmpty() ) {
    kdError() << "Need user." << endl;
    return 1;
  }
  if ( pass.isEmpty() ) {
    kdError() << "Need password." << endl;
    return 1;
  }
  if ( url.isEmpty() ) {
    kdError() << "Need server." << endl;
    return 1;
  }
#endif

  GroupwiseServer server( url, user, pass, 0 );

  if ( !server.login() ) {
    kdError() << "Unable to login to server " << url << endl;
    return 1;
  }

#if 0
  server.dumpData();
#endif

#if 0
  server.getCategoryList();
#endif

#if 0
  server.dumpFolderList();
#endif

#if 1
  QString fbUser = args->getOption( "freebusy-user" );
  if ( fbUser.isEmpty() ) {
    kdError() << "Need user for which the freebusy data should be retrieved."
              << endl;
  } else {
    KCal::FreeBusy *fb = new KCal::FreeBusy;

    server.readFreeBusy( "user1",
      QDate( 2004, 9, 1 ), QDate( 2004, 10, 31 ), fb );
  }
#endif

#if 0
  server.getDelta();
#endif

  server.logout();

  return 0;
}

<|endoftext|>


<commit_before>#ifndef itSmoothedClassProbabilites_cpp
#define itSmoothedClassProbabilites_cpp

#include "itkSmoothedClassProbabilites.h"
#include "itkObjectFactory.h"
#include "itkImageRegionIterator.h"
#include "itkImageRegionConstIterator.h"
#include "itkImageIterator.h"
#include "itkImageConstIterator.h"
#include <itkDiscreteGaussianImageFilter.h>

#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */

namespace itk
{

template< class TImage>
void SmoothedClassProbabilites< TImage>
::GenerateData()
{
  //    typename TImage::ConstPointer input = this->GetInput();
  typename TImage::Pointer output = this->GetOutput();
  std::vector<ImageRegionConstIterator<TImage> > vec_iter;
  auto arr = this->GetIndexedInputs();

  for(auto it = arr.begin(); it != arr.end(); it ++)
  {
    typename itk::DiscreteGaussianImageFilter<TImage,TImage>::Pointer gf = itk::DiscreteGaussianImageFilter<TImage,TImage>::New();
    gf->SetInput(static_cast<TImage *>(it->GetPointer()));
    gf->SetVariance(this->m_Sigma);
    gf->Update();
    *it = gf->GetOutput();

    ImageRegionConstIterator<TImage> imageiterator(static_cast<TImage *>(it->GetPointer()),static_cast<TImage *>(it->GetPointer())->GetLargestPossibleRegion());
    vec_iter.push_back(imageiterator);
  }

  ImageRegionConstIterator<TImage> maskiter(m_MaskImage, m_MaskImage->GetLargestPossibleRegion());
  ImageRegionIterator<TImage> outputIter(output, output->GetLargestPossibleRegion());
  while (!outputIter.IsAtEnd())
  {

    if(maskiter.Value() > 0 ){
      int max_class = 0;
      double prob = 0.0;
      for(unsigned int i = 0 ; i < vec_iter.size(); i++)
      {
        if(vec_iter[i].Value() > prob)
        {
          max_class = i+1;
          prob = vec_iter[i].Value();
        }
      }
      outputIter.Set(max_class);
    }else
    {
      outputIter.Set(0);
    }

    for(unsigned int i = 0 ; i < vec_iter.size(); i++)
      ++vec_iter[i];

    ++outputIter;
    ++maskiter;
  }

}

}// end namespace

#endif // itSmoothedClassProbabilites_cpp
<commit_msg>update smoothed class proba filter<commit_after>#ifndef itSmoothedClassProbabilites_cpp
#define itSmoothedClassProbabilites_cpp

#include "itkSmoothedClassProbabilites.h"
#include "itkObjectFactory.h"
#include "itkImageRegionIterator.h"
#include "itkImageRegionConstIterator.h"
#include <itkDiscreteGaussianImageFilter.h>

#include <mitkImageCast.h>
#include <mitkIOUtil.h>

#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */
#include <sstream>
namespace itk
{

template< class TImage>
void SmoothedClassProbabilites< TImage>
::GenerateData()
{

  typename TImage::Pointer out = this->GetOutput(0);
  out->SetRegions(this->GetInput(0)->GetLargestPossibleRegion());
  out->Allocate();

  for(unsigned int i = 0 ; i < this->GetNumberOfInputs(); i++)
  {

    auto gf = itk::DiscreteGaussianImageFilter<TImage,TImage>::New();
    gf->SetInput(this->GetInput(i));
    gf->SetVariance(this->m_Sigma);
    gf->Update();

    ImageRegionConstIterator<TImage> git(gf->GetOutput(),gf->GetOutput()->GetLargestPossibleRegion());
    ImageRegionIterator<TImage> maskiter(m_MaskImage, m_MaskImage->GetLargestPossibleRegion());
    ImageRegionIterator<TImage> outputIter(out, out->GetLargestPossibleRegion());

    while (!outputIter.IsAtEnd())
    {
      if(maskiter.Value() > 0 ){

        if(git.Value() > outputIter.Value())
          outputIter.Set(i);
      }else
      {
        outputIter.Set(0);
      }

      ++git;
      ++outputIter;
      ++maskiter;
    }
  }

}

}// end namespace

#endif // itSmoothedClassProbabilites_cpp
<|endoftext|>


<commit_before>#ifndef DICOM_UPPERLAYER_HPP
#define DICOM_UPPERLAYER_HPP

#include <string>
#include <vector>
#include <memory>
#include <map>
#include <functional>
#include <initializer_list>
#include <utility>
#include <deque>

#include <boost/optional.hpp>
#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/log/trivial.hpp>

#include "upperlayer_properties.hpp"
#include "upperlayer_statemachine.hpp"

/**
 * The upperlayer namespace contains classes and functions which implement the upperlayer as
 * described in the DICOM standard chapter 8.
 * @link http://medical.nema.org/Dicom/2011/11_08pu.pdf
 */
namespace upperlayer
{

/**
 * @brief The Istate_trans_ops struct is an interface which the statemachine class uses to
 *        perform certain operations, like resetting the ARTIM timer or sending an a_abort
 */
struct Istate_trans_ops
{
      virtual void reset_artim() = 0;
      virtual void stop_artim() = 0;
      virtual void start_artim() = 0;
      virtual void ignore_next() = 0;
      virtual void queue_for_write_w_prio(std::unique_ptr<property> p) = 0;
      virtual void close_connection() = 0;
      virtual ~Istate_trans_ops() = 0;
};

/**
 * @brief The scx class implements basic functionality used both by the specialed scp and scu
 *        subclasses, like reading and writing to the connected peer. It also manages the
 *        state machine
 * @todo  write reconnect() method using unique_ptr<socket>
 *
 * upperlayer::scx provides send() and read() functions independetly if the
 * subclass for clients (scu) or servers (scp) is used.
 * It must be noted that the sole responsibility of the upperlayer::scx is to
 * keep the state machine valid. It is not involved in the association
 * negotiation. This has to be done by the user of this class (either a facade
 * or the DIMSE_PM).
 */
class scx: public Istate_trans_ops
{
   public:

      explicit scx(std::initializer_list<std::pair<TYPE, std::function<void(scx*, std::unique_ptr<property>)>>> l);
      virtual ~scx() = 0;

      /**
       * @brief sock is used by send() and receive() to access the socket of the
       *        subclasses
       * @return ref to boost::asio::ip::tcp::socket of the subclass
       *
       * for initalization reasons the socket cannot be declared in this abstract
       * class.
       */
      virtual boost::asio::ip::tcp::socket& sock() = 0;

      /**
       * @brief sock is used by the subclasses to use the ::run() member function
       * @return ref to boost::asio::io_service
       *
       * for initalization reasons the socket cannot be declared in this abstract
       * class.
       */
      virtual boost::asio::io_service& io_s() = 0;

      /**
       * @brief artim_timer returns a reference to the artim timer
       * @return ref to boost::asio::steady_timer
       */
      virtual boost::asio::steady_timer& artim_timer() = 0;

      /**
       * @brief run blocks until asynchronous operations are completed
       */
      void run();

      /**
       * @brief get_state returns the current state
       * @return
       */
      statemachine::CONN_STATE get_state();

      /**
       * @brief inject sets a handler for a received property type t.
       * @param[in] t
       * @param[in] f
       */
      void inject(TYPE t, std::function<void(scx*, std::unique_ptr<property>)> f);

      /**
       * @brief scx::do_read reads a pdu asynchronously from the peer
       *
       * The pdu is received in two steps:
       * The first async_read is passed a handler which is called when
       * exactly six bytes are received. These first six bytes contain
       * the size of the pdu _len_.
       * Then, in this first read-handler, another async_read is
       * dispatched which calls its read-handler when exactly _len_
       * bytes (ie the whole pdu) are received. This second read-handler
       * contains the code which actually processes the pdu (calls the
       * appropriate handler, manages state transitions, ...)
       */
      void do_read();

      /**
       * @brief queue_for_write takes ownership of a property and queues it for
       *        writing
       * @param[in] p
       *
       * A write queue is necessary to prevent multiple writes to the socket, which
       * may result in interleaving
       */
      void queue_for_write(std::unique_ptr<property> p);

      /**
       * @brief queue_for_write_w_prio queues a property for writing, but moves it
       *        in the front of the queue so it will be retrieved first
       * @param[in] p
       * @see queue_for_write();
       */
      void queue_for_write_w_prio(std::unique_ptr<property> p);

      /**
       * @brief reset_artim resets the artim timer
       */
      void reset_artim();

      /**
       * @brief stop_artim stops the artim timer
       */
      void stop_artim();

      /**
       * @brief start_artim starts the artim timer
       */
      void start_artim();

      /**
       * @brief ignore_next indicates whether a received pdu shall be ignored by
       *        not invoking the respective handler
       */
      void ignore_next();

      /**
       * @brief close_connection aborts all async operations on the io_service object,
       *        making io_service::run() terminate
       */
      void close_connection();

   protected:
      statemachine statem;

      /**
       * @brief artim_expired is called when the artim timer expires
       * @param error
       */
      void artim_expired(const boost::system::error_code& error);

   private:
      /**
       * @brief send takes a property and uses its property::make_pdu() function
       *        for serialization. The serialized data is sent to the peer via
       *        the socket.
       * @param[in] p
       */
      void send(property* p);

      std::deque<std::unique_ptr<property>> send_queue;
      boost::optional<std::vector<unsigned char>*> received_pdu;
      std::map<TYPE, std::function<void(scx*, std::unique_ptr<property>)>> handlers;
};

/**
 * @brief The scp class acts as a service class provider
 */
class scp: public scx
{
   public:
      scp(short port, std::initializer_list<std::pair<TYPE, std::function<void(scx*, std::unique_ptr<property>)>>> l);
      ~scp() override;
      boost::asio::ip::tcp::socket& sock() override;
      boost::asio::io_service& io_s() override;
      boost::asio::steady_timer& artim_timer() override;

   private:
      boost::asio::io_service io_service;
      boost::asio::ip::tcp::socket socket;
      boost::asio::ip::tcp::acceptor acptr;
      boost::asio::steady_timer artim;
};

/**
 * @brief The scu class acts as a service class user
 */
class scu: public scx
{
   public:
      scu(std::string host, std::string port, a_associate_rq& rq, std::initializer_list<std::pair<TYPE, std::function<void(scx*, std::unique_ptr<property>)>>> l);
      ~scu() override;
      boost::asio::ip::tcp::socket& sock() override;
      boost::asio::io_service& io_s() override;
      boost::asio::steady_timer& artim_timer() override;

   private:
      boost::asio::io_service io_service;
      boost::asio::ip::tcp::resolver resolver;
      boost::asio::ip::tcp::resolver::query query;
      boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
      boost::asio::ip::tcp::socket socket;
      boost::asio::steady_timer artim;
};

}

#endif // DICOMUPPERLAYER_HPP
<commit_msg>= delete copy constructors and assignment operators<commit_after>#ifndef DICOM_UPPERLAYER_HPP
#define DICOM_UPPERLAYER_HPP

#include <string>
#include <vector>
#include <memory>
#include <map>
#include <functional>
#include <initializer_list>
#include <utility>
#include <deque>

#include <boost/optional.hpp>
#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/log/trivial.hpp>

#include "upperlayer_properties.hpp"
#include "upperlayer_statemachine.hpp"

/**
 * The upperlayer namespace contains classes and functions which implement the upperlayer as
 * described in the DICOM standard chapter 8.
 * @link http://medical.nema.org/Dicom/2011/11_08pu.pdf
 */
namespace upperlayer
{

/**
 * @brief The Istate_trans_ops struct is an interface which the statemachine class uses to
 *        perform certain operations, like resetting the ARTIM timer or sending an a_abort
 */
struct Istate_trans_ops
{
      virtual void reset_artim() = 0;
      virtual void stop_artim() = 0;
      virtual void start_artim() = 0;
      virtual void ignore_next() = 0;
      virtual void queue_for_write_w_prio(std::unique_ptr<property> p) = 0;
      virtual void close_connection() = 0;
      virtual ~Istate_trans_ops() = 0;
};

/**
 * @brief The scx class implements basic functionality used both by the specialed scp and scu
 *        subclasses, like reading and writing to the connected peer. It also manages the
 *        state machine
 * @todo  write reconnect() method using unique_ptr<socket>
 *
 * upperlayer::scx provides send() and read() functions independetly if the
 * subclass for clients (scu) or servers (scp) is used.
 * It must be noted that the sole responsibility of the upperlayer::scx is to
 * keep the state machine valid. It is not involved in the association
 * negotiation. This has to be done by the user of this class (either a facade
 * or the DIMSE_PM).
 */
class scx: public Istate_trans_ops
{
   public:

      explicit scx(std::initializer_list<std::pair<TYPE, std::function<void(scx*, std::unique_ptr<property>)>>> l);
      scx(const scx&) = delete;
      scx& operator=(const scx&) = delete;
      virtual ~scx() = 0;

      /**
       * @brief sock is used by send() and receive() to access the socket of the
       *        subclasses
       * @return ref to boost::asio::ip::tcp::socket of the subclass
       *
       * for initalization reasons the socket cannot be declared in this abstract
       * class.
       */
      virtual boost::asio::ip::tcp::socket& sock() = 0;

      /**
       * @brief sock is used by the subclasses to use the ::run() member function
       * @return ref to boost::asio::io_service
       *
       * for initalization reasons the socket cannot be declared in this abstract
       * class.
       */
      virtual boost::asio::io_service& io_s() = 0;

      /**
       * @brief artim_timer returns a reference to the artim timer
       * @return ref to boost::asio::steady_timer
       */
      virtual boost::asio::steady_timer& artim_timer() = 0;

      /**
       * @brief run blocks until asynchronous operations are completed
       */
      void run();

      /**
       * @brief get_state returns the current state
       * @return
       */
      statemachine::CONN_STATE get_state();

      /**
       * @brief inject sets a handler for a received property type t.
       * @param[in] t
       * @param[in] f
       */
      void inject(TYPE t, std::function<void(scx*, std::unique_ptr<property>)> f);

      /**
       * @brief scx::do_read reads a pdu asynchronously from the peer
       *
       * The pdu is received in two steps:
       * The first async_read is passed a handler which is called when
       * exactly six bytes are received. These first six bytes contain
       * the size of the pdu _len_.
       * Then, in this first read-handler, another async_read is
       * dispatched which calls its read-handler when exactly _len_
       * bytes (ie the whole pdu) are received. This second read-handler
       * contains the code which actually processes the pdu (calls the
       * appropriate handler, manages state transitions, ...)
       */
      void do_read();

      /**
       * @brief queue_for_write takes ownership of a property and queues it for
       *        writing
       * @param[in] p
       *
       * A write queue is necessary to prevent multiple writes to the socket, which
       * may result in interleaving
       */
      void queue_for_write(std::unique_ptr<property> p);

      /**
       * @brief queue_for_write_w_prio queues a property for writing, but moves it
       *        in the front of the queue so it will be retrieved first
       * @param[in] p
       * @see queue_for_write();
       */
      void queue_for_write_w_prio(std::unique_ptr<property> p);

      /**
       * @brief reset_artim resets the artim timer
       */
      void reset_artim();

      /**
       * @brief stop_artim stops the artim timer
       */
      void stop_artim();

      /**
       * @brief start_artim starts the artim timer
       */
      void start_artim();

      /**
       * @brief ignore_next indicates whether a received pdu shall be ignored by
       *        not invoking the respective handler
       */
      void ignore_next();

      /**
       * @brief close_connection aborts all async operations on the io_service object,
       *        making io_service::run() terminate
       */
      void close_connection();

   protected:
      statemachine statem;

      /**
       * @brief artim_expired is called when the artim timer expires
       * @param error
       */
      void artim_expired(const boost::system::error_code& error);

   private:
      /**
       * @brief send takes a property and uses its property::make_pdu() function
       *        for serialization. The serialized data is sent to the peer via
       *        the socket.
       * @param[in] p
       */
      void send(property* p);

      std::deque<std::unique_ptr<property>> send_queue;
      boost::optional<std::vector<unsigned char>*> received_pdu;
      std::map<TYPE, std::function<void(scx*, std::unique_ptr<property>)>> handlers;
};

/**
 * @brief The scp class acts as a service class provider
 */
class scp: public scx
{
   public:
      scp(short port, std::initializer_list<std::pair<TYPE, std::function<void(scx*, std::unique_ptr<property>)>>> l);
      ~scp() override;
      scp(const scp&) = delete;
      scp& operator=(const scp&) = delete;

      boost::asio::ip::tcp::socket& sock() override;
      boost::asio::io_service& io_s() override;
      boost::asio::steady_timer& artim_timer() override;

   private:
      boost::asio::io_service io_service;
      boost::asio::ip::tcp::socket socket;
      boost::asio::ip::tcp::acceptor acptr;
      boost::asio::steady_timer artim;
};

/**
 * @brief The scu class acts as a service class user
 */
class scu: public scx
{
   public:
      scu(std::string host, std::string port, a_associate_rq& rq, std::initializer_list<std::pair<TYPE, std::function<void(scx*, std::unique_ptr<property>)>>> l);
      ~scu() override;
      scu(const scu&) = delete;
      scu& operator=(const scu&) = delete;

      boost::asio::ip::tcp::socket& sock() override;
      boost::asio::io_service& io_s() override;
      boost::asio::steady_timer& artim_timer() override;

   private:
      boost::asio::io_service io_service;
      boost::asio::ip::tcp::resolver resolver;
      boost::asio::ip::tcp::resolver::query query;
      boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
      boost::asio::ip::tcp::socket socket;
      boost::asio::steady_timer artim;
};

}

#endif // DICOMUPPERLAYER_HPP
<|endoftext|>


<commit_before>/*****************************************************************************\
 *                        ANALYSIS PERFORMANCE TOOLS                         *
 *                                  wxparaver                                *
 *              Paraver Trace Visualization and Analysis Tool                *
 *****************************************************************************
 *     ___     This library is free software; you can redistribute it and/or *
 *    /  __         modify it under the terms of the GNU LGPL as published   *
 *   /  /  _____    by the Free Software Foundation; either version 2.1      *
 *  /  /  /     \   of the License, or (at your option) any later version.   *
 * (  (  ( B S C )                                                           *
 *  \  \  \_____/   This library is distributed in 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 LGPL for more details.   *
 *                                                                           *
 * You should have received a copy of the GNU Lesser General Public License  *
 * along with this library; if not, write to the Free Software Foundation,   *
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA          *
 * The GNU LEsser General Public License is contained in the file COPYING.   *
 *                                 ---------                                 *
 *   Barcelona Supercomputing Center - Centro Nacional de Supercomputacion   *
\*****************************************************************************/

/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *\
 | @file: $HeadURL$
 | @last_commit: $Date$
 | @version:     $Revision$
\* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

////@begin includes
////@end includes

// Signal handling
#include <signal.h>
#include <stdio.h>

#include "wxparaverapp.h"
#include "connection.h"

////@begin XPM images
////@end XPM images

#ifndef WIN32
struct sigaction act;
#endif

/*!
 * Application instance implementation
 */

////@begin implement app
IMPLEMENT_APP( wxparaverApp )
////@end implement app

/*!
 * wxparaverApp type definition
 */

IMPLEMENT_CLASS( wxparaverApp, wxApp )

/*!
 * wxparaverApp event table definition
 */

BEGIN_EVENT_TABLE( wxparaverApp, wxApp )

////@begin wxparaverApp event table entries
////@end wxparaverApp event table entries

END_EVENT_TABLE()

/*!
 * Constructor for wxparaverApp
 */

wxparaverApp::wxparaverApp()
{
  Init();
}

/*!
 * Member initialisation
 */

void wxparaverApp::Init()
{
////@begin wxparaverApp member initialisation
////@end wxparaverApp member initialisation
  m_locale.Init();
}

/*!
 * Initialisation for wxparaverApp
 */

paraverMain* wxparaverApp::mainWindow = NULL;

#ifndef WIN32
volatile bool sig1 = false;
volatile bool sig2 = false;

void wxparaverApp::handler( int signalNumber )
{
  sigdelset( &act.sa_mask, SIGUSR1 );
  sigdelset( &act.sa_mask, SIGUSR2 );

//  wxMutexGuiEnter();
//  wxparaverApp::mainWindow->OnSignal( signalNumber );
//  wxMutexGuiLeave();
  if ( signalNumber == SIGUSR1 )
  {
    sig1 = true;
  }
  else
  {
    sig1 = false;
  }

  sig2 = !sig1;

//  wxIdleEvent event;
//  event.RequestMore();
//  wxTheApp->SendIdleEvents( mainWindow, event );
  mainWindow->Raise();

  sigaddset( &act.sa_mask, SIGUSR1 );
  sigaddset( &act.sa_mask, SIGUSR2 );
  sigaction( SIGUSR1, &act, NULL );
  sigaction( SIGUSR2, &act, NULL );
}

void wxparaverApp::presetUserSignals()
{

  act.sa_handler = &handler;
  act.sa_flags = 0;

  if ( sigemptyset( &act.sa_mask ) != 0 )
  {
    /* Handle error */
  }

  if ( sigaddset( &act.sa_mask, SIGUSR1 ))
  {
    /* Handle error */
  }

  if ( sigaddset( &act.sa_mask, SIGUSR2 ))
  {
    /* Handle error */
  }

  if ( sigaction( SIGUSR1, &act, NULL ) != 0 )
  {
    /* Handle error */
  }

  if ( sigaction( SIGUSR2, &act, NULL ) != 0 )
  {
    /* Handle error */
  }
}
#endif

bool wxparaverApp::OnInit()
{
  const wxString name = wxString::Format("wxparaver-%s", wxGetUserId().c_str());
  m_checker = new wxSingleInstanceChecker(name);
  if ( !m_checker->IsAnotherRunning() )
  {
    m_server = new stServer;

    if( !m_server->Create( wxT( "wxparaver" ) ) )
      wxLogDebug( wxT( "Failed to create an IPC service." ) );
  }
  else
  {
    wxLogNull logNull;

    stClient *client = new stClient;
    wxString hostName = wxT( "localhost" );
    wxConnectionBase *connection = client->MakeConnection( hostName,
                                                           wxT( "wxparaver" ),
                                                           wxT( "wxparaver" ) );
    if( connection )
    {
      connection->Execute( wxT( "BEGIN" ) );
      for( int i = 1; i < argc; ++i )
      {
        if( argv[ i ][ 0 ] != '-' )
          connection->Execute( argv[ i ] );
      }
      connection->Execute( wxT( "END" ) );
      connection->Disconnect();
      delete connection;
    }
    else
    {
      wxMessageBox( wxT( "Sorry, the existing instance may be too busy to respond." ),
                    wxT( "wxparaver" ), wxICON_INFORMATION|wxOK );
    }

    delete client;
    return false;
  }

  wxCmdLineEntryDesc argumentsParseSyntax[] =
  {
    { wxCMD_LINE_SWITCH,
      wxT("h"),
      wxT("help"),
      wxT("Show this help."),
      wxCMD_LINE_VAL_STRING,
      wxCMD_LINE_OPTION_HELP },

    { wxCMD_LINE_PARAM,
      NULL,
      NULL,
      wxT( "(trace.prv | trace.prv.gz) (configuration.cfg)" ),
      wxCMD_LINE_VAL_STRING,
      wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE },

    { wxCMD_LINE_NONE }
  };

#if wxUSE_XPM
  wxImage::AddHandler(new wxXPMHandler);
#endif
#if wxUSE_LIBPNG
  wxImage::AddHandler(new wxPNGHandler);
#endif
#if wxUSE_LIBJPEG
  wxImage::AddHandler(new wxJPEGHandler);
#endif
#if wxUSE_GIF
  wxImage::AddHandler(new wxGIFHandler);
#endif

  wxCmdLineParser paraverCommandLineParser( argumentsParseSyntax, argc, argv );
  paraverCommandLineParser.Parse();

  mainWindow = new paraverMain( NULL );

  mainWindow->Show(true);

  mainWindow->commandLineLoadings( paraverCommandLineParser );

/*
  paraverMain *mainWindow;
  mainWindow = new paraverMain( NULL );

  mainWindow->Show(true);

  mainWindow->commandLineLoadings( paraverCommandLineParser );
*/
#ifndef WIN32
  presetUserSignals();
#endif

  return true;
}

/*!
 * Cleanup for wxparaverApp
 */

int wxparaverApp::OnExit()
{
  if( m_checker != NULL )
    delete m_checker;

  if( m_server != NULL )
    delete m_server;

////@begin wxparaverApp cleanup
	return wxApp::OnExit();
////@end wxparaverApp cleanup
}

<commit_msg>*** empty log message ***<commit_after>/*****************************************************************************\
 *                        ANALYSIS PERFORMANCE TOOLS                         *
 *                                  wxparaver                                *
 *              Paraver Trace Visualization and Analysis Tool                *
 *****************************************************************************
 *     ___     This library is free software; you can redistribute it and/or *
 *    /  __         modify it under the terms of the GNU LGPL as published   *
 *   /  /  _____    by the Free Software Foundation; either version 2.1      *
 *  /  /  /     \   of the License, or (at your option) any later version.   *
 * (  (  ( B S C )                                                           *
 *  \  \  \_____/   This library is distributed in 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 LGPL for more details.   *
 *                                                                           *
 * You should have received a copy of the GNU Lesser General Public License  *
 * along with this library; if not, write to the Free Software Foundation,   *
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA          *
 * The GNU LEsser General Public License is contained in the file COPYING.   *
 *                                 ---------                                 *
 *   Barcelona Supercomputing Center - Centro Nacional de Supercomputacion   *
\*****************************************************************************/

/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *\
 | @file: $HeadURL$
 | @last_commit: $Date$
 | @version:     $Revision$
\* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

////@begin includes
////@end includes

// Signal handling
#include <signal.h>
#include <stdio.h>

#include "wxparaverapp.h"
#include "connection.h"

////@begin XPM images
////@end XPM images

#ifndef WIN32
struct sigaction act;
#endif

/*!
 * Application instance implementation
 */

////@begin implement app
IMPLEMENT_APP( wxparaverApp )
////@end implement app

/*!
 * wxparaverApp type definition
 */

IMPLEMENT_CLASS( wxparaverApp, wxApp )

/*!
 * wxparaverApp event table definition
 */

BEGIN_EVENT_TABLE( wxparaverApp, wxApp )

////@begin wxparaverApp event table entries
////@end wxparaverApp event table entries

END_EVENT_TABLE()

/*!
 * Constructor for wxparaverApp
 */

wxparaverApp::wxparaverApp()
{
  Init();
}

/*!
 * Member initialisation
 */

void wxparaverApp::Init()
{
////@begin wxparaverApp member initialisation
////@end wxparaverApp member initialisation
  m_locale.Init();
}

/*!
 * Initialisation for wxparaverApp
 */

paraverMain* wxparaverApp::mainWindow = NULL;

#ifndef WIN32
volatile bool sig1 = false;
volatile bool sig2 = false;

void wxparaverApp::handler( int signalNumber )
{
  sigdelset( &act.sa_mask, SIGUSR1 );
  sigdelset( &act.sa_mask, SIGUSR2 );

//  wxMutexGuiEnter();
//  wxparaverApp::mainWindow->OnSignal( signalNumber );
//  wxMutexGuiLeave();
  if ( signalNumber == SIGUSR1 )
  {
    sig1 = true;
  }
  else
  {
    sig1 = false;
  }

  sig2 = !sig1;

//  wxIdleEvent event;
//  event.RequestMore();
//  wxTheApp->SendIdleEvents( mainWindow, event );
  mainWindow->Raise();

  sigaddset( &act.sa_mask, SIGUSR1 );
  sigaddset( &act.sa_mask, SIGUSR2 );
  sigaction( SIGUSR1, &act, NULL );
  sigaction( SIGUSR2, &act, NULL );
}

void wxparaverApp::presetUserSignals()
{

  act.sa_handler = &handler;
  act.sa_flags = 0;

  if ( sigemptyset( &act.sa_mask ) != 0 )
  {
    /* Handle error */
  }

  if ( sigaddset( &act.sa_mask, SIGUSR1 ))
  {
    /* Handle error */
  }

  if ( sigaddset( &act.sa_mask, SIGUSR2 ))
  {
    /* Handle error */
  }

  if ( sigaction( SIGUSR1, &act, NULL ) != 0 )
  {
    /* Handle error */
  }

  if ( sigaction( SIGUSR2, &act, NULL ) != 0 )
  {
    /* Handle error */
  }
}
#endif

bool wxparaverApp::OnInit()
{
  const wxString name = wxString::Format( _( "wxparaver-%s" ), wxGetUserId().c_str());
  m_checker = new wxSingleInstanceChecker(name);
  if ( !m_checker->IsAnotherRunning() )
  {
    m_server = new stServer;

    if( !m_server->Create( wxT( "wxparaver" ) ) )
      wxLogDebug( wxT( "Failed to create an IPC service." ) );
  }
  else
  {
    wxLogNull logNull;

    stClient *client = new stClient;
    wxString hostName = wxT( "localhost" );
    wxConnectionBase *connection = client->MakeConnection( hostName,
                                                           wxT( "wxparaver" ),
                                                           wxT( "wxparaver" ) );
    if( connection )
    {
      connection->Execute( wxT( "BEGIN" ) );
      for( int i = 1; i < argc; ++i )
      {
        if( argv[ i ][ 0 ] != '-' )
          connection->Execute( argv[ i ] );
      }
      connection->Execute( wxT( "END" ) );
      connection->Disconnect();
      delete connection;
    }
    else
    {
      wxMessageBox( wxT( "Sorry, the existing instance may be too busy to respond." ),
                    wxT( "wxparaver" ), wxICON_INFORMATION|wxOK );
    }

    delete client;
    return false;
  }

  wxCmdLineEntryDesc argumentsParseSyntax[] =
  {
    { wxCMD_LINE_SWITCH,
      wxT("h"),
      wxT("help"),
      wxT("Show this help."),
      wxCMD_LINE_VAL_STRING,
      wxCMD_LINE_OPTION_HELP },

    { wxCMD_LINE_PARAM,
      NULL,
      NULL,
      wxT( "(trace.prv | trace.prv.gz) (configuration.cfg)" ),
      wxCMD_LINE_VAL_STRING,
      wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE },

    { wxCMD_LINE_NONE }
  };

#if wxUSE_XPM
  wxImage::AddHandler(new wxXPMHandler);
#endif
#if wxUSE_LIBPNG
  wxImage::AddHandler(new wxPNGHandler);
#endif
#if wxUSE_LIBJPEG
  wxImage::AddHandler(new wxJPEGHandler);
#endif
#if wxUSE_GIF
  wxImage::AddHandler(new wxGIFHandler);
#endif

  wxCmdLineParser paraverCommandLineParser( argumentsParseSyntax, argc, argv );
  paraverCommandLineParser.Parse();

  mainWindow = new paraverMain( NULL );

  mainWindow->Show(true);

  mainWindow->commandLineLoadings( paraverCommandLineParser );

/*
  paraverMain *mainWindow;
  mainWindow = new paraverMain( NULL );

  mainWindow->Show(true);

  mainWindow->commandLineLoadings( paraverCommandLineParser );
*/
#ifndef WIN32
  presetUserSignals();
#endif

  return true;
}

/*!
 * Cleanup for wxparaverApp
 */

int wxparaverApp::OnExit()
{
  if( m_checker != NULL )
    delete m_checker;

  if( m_server != NULL )
    delete m_server;

////@begin wxparaverApp cleanup
	return wxApp::OnExit();
////@end wxparaverApp cleanup
}

<|endoftext|>


<commit_before>/* defaultkeygenerationjob.cpp

    Copyright (c) 2016 Klarälvdalens Datakonsult AB

    QGpgME is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of the
    License, or (at your option) any later version.

    QGpgME 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 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

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#ifdef HAVE_CONFIG_H
 #include "config.h"
#endif

#include "defaultkeygenerationjob.h"
#include "protocol.h"
#include "keygenerationjob.h"

#include <QPointer>
#include <QEvent>

using namespace QGpgME;

namespace QGpgME {

class DefaultKeyGenerationJob::Private
{
public:
    Private()
    {}

    ~Private()
    {
        if (job) {
            job->deleteLater();
        }
    }

    QPointer<KeyGenerationJob> job;
};
}

DefaultKeyGenerationJob::DefaultKeyGenerationJob(QObject* parent)
    : Job(parent)
    , d(new DefaultKeyGenerationJob::Private())
{
}

DefaultKeyGenerationJob::~DefaultKeyGenerationJob()
{
    delete d;
}

QString DefaultKeyGenerationJob::auditLogAsHtml() const
{
    return d->job ? d->job->auditLogAsHtml() : QString();
}

GpgME::Error DefaultKeyGenerationJob::auditLogError() const
{
    return d->job ? d->job->auditLogError() : GpgME::Error();
}

void DefaultKeyGenerationJob::slotCancel()
{
    if (d->job) {
        d->job->slotCancel();
    }
}

GpgME::Error DefaultKeyGenerationJob::start(const QString &email, const QString &name)
{
    const QString args = QStringLiteral("<GnupgKeyParms format=\"internal\">\n"
                                        "%ask-passphrase\n"
                                        "key-type:      RSA\n"
                                        "key-length:    2048\n"
                                        "key-usage:     sign\n"
                                        "subkey-type:   RSA\n"
                                        "subkey-length: 2048\n"
                                        "subkey-usage:  encrypt\n"
                                        "name-email:    %1\n"
                                        "name-real:     %2\n"
                                        "</GnupgKeyParms>").arg(email, name);

    d->job = openpgp()->keyGenerationJob();
    d->job->installEventFilter(this);
    connect(d->job.data(), &KeyGenerationJob::result,
            this, &DefaultKeyGenerationJob::result);
    connect(d->job.data(), &KeyGenerationJob::done,
            this, &DefaultKeyGenerationJob::done);
    connect(d->job.data(), &KeyGenerationJob::done,
            this, &QObject::deleteLater);
    return d->job->start(args);
}

bool DefaultKeyGenerationJob::eventFilter(QObject *watched, QEvent *event)
{
    // Intercept the KeyGenerationJob's deferred delete event. We want the job
    // to live at least as long as we do so we can delegate calls to it. We will
    // delete the job manually afterwards.
    if (watched == d->job && event->type() == QEvent::DeferredDelete) {
        return true;
    }

    return Job::eventFilter(watched, event);
}

#include "defaultkeygenerationjob.moc"
<commit_msg>qt: Allow creation of default keys without name<commit_after>/* defaultkeygenerationjob.cpp

    Copyright (c) 2016 Klarälvdalens Datakonsult AB

    QGpgME is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of the
    License, or (at your option) any later version.

    QGpgME 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 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

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#ifdef HAVE_CONFIG_H
 #include "config.h"
#endif

#include "defaultkeygenerationjob.h"
#include "protocol.h"
#include "keygenerationjob.h"

#include <QPointer>
#include <QEvent>

using namespace QGpgME;

namespace QGpgME {

class DefaultKeyGenerationJob::Private
{
public:
    Private()
    {}

    ~Private()
    {
        if (job) {
            job->deleteLater();
        }
    }

    QPointer<KeyGenerationJob> job;
};
}

DefaultKeyGenerationJob::DefaultKeyGenerationJob(QObject* parent)
    : Job(parent)
    , d(new DefaultKeyGenerationJob::Private())
{
}

DefaultKeyGenerationJob::~DefaultKeyGenerationJob()
{
    delete d;
}

QString DefaultKeyGenerationJob::auditLogAsHtml() const
{
    return d->job ? d->job->auditLogAsHtml() : QString();
}

GpgME::Error DefaultKeyGenerationJob::auditLogError() const
{
    return d->job ? d->job->auditLogError() : GpgME::Error();
}

void DefaultKeyGenerationJob::slotCancel()
{
    if (d->job) {
        d->job->slotCancel();
    }
}

GpgME::Error DefaultKeyGenerationJob::start(const QString &email, const QString &name)
{
    const QString namePart = name.isEmpty() ? QString() :
                                QStringLiteral("name-real:     %1\n").arg(name);
    const QString mailPart = email.isEmpty() ? QString() :
                                QStringLiteral("name-email:    %1\n").arg(email);

    const QString args = QStringLiteral("<GnupgKeyParms format=\"internal\">\n"
                                        "%ask-passphrase\n"
                                        "key-type:      RSA\n"
                                        "key-length:    2048\n"
                                        "key-usage:     sign\n"
                                        "subkey-type:   RSA\n"
                                        "subkey-length: 2048\n"
                                        "subkey-usage:  encrypt\n"
                                        "%1"
                                        "%2"
                                        "</GnupgKeyParms>").arg(mailPart, namePart);

    d->job = openpgp()->keyGenerationJob();
    d->job->installEventFilter(this);
    connect(d->job.data(), &KeyGenerationJob::result,
            this, &DefaultKeyGenerationJob::result);
    connect(d->job.data(), &KeyGenerationJob::done,
            this, &DefaultKeyGenerationJob::done);
    connect(d->job.data(), &KeyGenerationJob::done,
            this, &QObject::deleteLater);
    return d->job->start(args);
}

bool DefaultKeyGenerationJob::eventFilter(QObject *watched, QEvent *event)
{
    // Intercept the KeyGenerationJob's deferred delete event. We want the job
    // to live at least as long as we do so we can delegate calls to it. We will
    // delete the job manually afterwards.
    if (watched == d->job && event->type() == QEvent::DeferredDelete) {
        return true;
    }

    return Job::eventFilter(watched, event);
}

#include "defaultkeygenerationjob.moc"
<|endoftext|>