<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 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 "buildmanager.h"

#include "buildprogress.h"
#include "buildstep.h"
#include "compileoutputwindow.h"
#include "projectexplorerconstants.h"
#include "projectexplorer.h"
#include "project.h"
#include "projectexplorersettings.h"
#include "taskwindow.h"

#include <coreplugin/icore.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/progressmanager/futureprogress.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>

#include <QtCore/QDir>
#include <QtCore/QTimer>

#include <qtconcurrent/QtConcurrentTools>

#include <QtGui/QHeaderView>
#include <QtGui/QIcon>
#include <QtGui/QLabel>

using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

static inline QString msgProgress(int n, int total)
{
    return BuildManager::tr("Finished %n of %1 build steps", 0, n).arg(total);
}

BuildManager::BuildManager(ProjectExplorerPlugin *parent)
    : QObject(parent)
    , m_running(false)
    , m_previousBuildStepProject(0)
    , m_canceling(false)
    , m_maxProgress(0)
    , m_progressFutureInterface(0)
{
    ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
    m_projectExplorerPlugin = parent;

    connect(&m_watcher, SIGNAL(finished()),
            this, SLOT(nextBuildQueue()));

    connect(&m_watcher, SIGNAL(progressValueChanged(int)),
            this, SLOT(progressChanged()));
    connect(&m_watcher, SIGNAL(progressRangeChanged(int, int)),
            this, SLOT(progressChanged()));

    m_outputWindow = new CompileOutputWindow(this);
    pm->addObject(m_outputWindow);

    m_taskWindow = new TaskWindow;
    pm->addObject(m_taskWindow);

    connect(m_taskWindow, SIGNAL(tasksChanged()),
            this, SIGNAL(tasksChanged()));

    connect(&m_progressWatcher, SIGNAL(canceled()),
            this, SLOT(cancel()));
}

BuildManager::~BuildManager()
{
    cancel();
    ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();

    pm->removeObject(m_taskWindow);
    delete m_taskWindow;

    pm->removeObject(m_outputWindow);
    delete m_outputWindow;
}

bool BuildManager::isBuilding() const
{
    // we are building even if we are not running yet
    return !m_buildQueue.isEmpty() || m_running;
}

void BuildManager::cancel()
{
    if (m_running) {
        m_canceling = true;
        m_watcher.cancel();
        m_watcher.waitForFinished();

        // The cancel message is added to the output window via a single shot timer
        // since the canceling is likely to have generated new addToOutputWindow signals
        // which are waiting in the event queue to be processed
        // (And we want those to be before the cancel message.)
        QTimer::singleShot(0, this, SLOT(emitCancelMessage()));

        disconnect(m_currentBuildStep, SIGNAL(addToTaskWindow(QString, int, int, QString)),
                   this, SLOT(addToTaskWindow(QString, int, int, QString)));
        disconnect(m_currentBuildStep, SIGNAL(addToOutputWindow(QString)),
                   this, SLOT(addToOutputWindow(QString)));
        decrementActiveBuildSteps(m_currentBuildStep->project());

        m_progressFutureInterface->setProgressValueAndText(m_progress*100, "Build canceled"); //TODO NBS fix in qtconcurrent
        clearBuildQueue();
    }
    return;
}

void BuildManager::emitCancelMessage()
{
    emit addToOutputWindow(tr("Canceled build."));
}

void BuildManager::clearBuildQueue()
{
    foreach (BuildStep * bs, m_buildQueue)
        decrementActiveBuildSteps(bs->project());

    m_buildQueue.clear();
    m_configurations.clear();
    m_running = false;
    m_previousBuildStepProject = 0;

    m_progressFutureInterface->reportCanceled();
    m_progressFutureInterface->reportFinished();
    m_progressWatcher.setFuture(QFuture<void>());
    delete m_progressFutureInterface;
    m_progressFutureInterface = 0;
    m_maxProgress = 0;

    emit buildQueueFinished(false);
}

void BuildManager::toggleOutputWindow()
{
    m_outputWindow->toggle(false);
}

void BuildManager::showTaskWindow()
{
    m_taskWindow->popup(false);
}

void BuildManager::toggleTaskWindow()
{
    m_taskWindow->toggle(false);
}

bool BuildManager::tasksAvailable() const
{
    return m_taskWindow->numberOfTasks() > 0;
}

void BuildManager::gotoTaskWindow()
{
    m_taskWindow->popup(true);
}

void BuildManager::startBuildQueue()
{
    if (m_buildQueue.isEmpty())
        return;
    if (!m_running) {
        // Progress Reporting
        Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager();
        m_progressFutureInterface = new QFutureInterface<void>;
        m_progressWatcher.setFuture(m_progressFutureInterface->future());
        Core::FutureProgress *progress = progressManager->addTask(m_progressFutureInterface->future(),
                                                                  tr("Build"),
                                                                  Constants::TASK_BUILD);
        connect(progress, SIGNAL(clicked()), this, SLOT(showBuildResults()));
        progress->setWidget(new BuildProgress(m_taskWindow));
        m_progress = 0;
        m_progressFutureInterface->setProgressRange(0, m_maxProgress * 100);

        m_running = true;
        m_canceling = false;
        m_progressFutureInterface->reportStarted();
        m_outputWindow->clearContents();
        m_taskWindow->clearContents();
        nextStep();
    } else {
        // Already running
        m_progressFutureInterface->setProgressRange(0, m_maxProgress * 100);
        m_progressFutureInterface->setProgressValueAndText(m_progress*100, msgProgress(m_progress, m_maxProgress));
    }
}

void BuildManager::showBuildResults()
{
    if (m_taskWindow->numberOfTasks() != 0)
        toggleTaskWindow();
    else
        toggleOutputWindow();
    //toggleTaskWindow();
}

void BuildManager::addToTaskWindow(const QString &file, int type, int line, const QString &description)
{
    m_taskWindow->addItem(BuildParserInterface::PatternType(type), description, file, line);
}

void BuildManager::addToOutputWindow(const QString &string)
{
    m_outputWindow->appendText(string);
}

void BuildManager::nextBuildQueue()
{
    if (m_canceling)
        return;

    disconnect(m_currentBuildStep, SIGNAL(addToTaskWindow(QString, int, int, QString)),
                this, SLOT(addToTaskWindow(QString, int, int, QString)));
    disconnect(m_currentBuildStep, SIGNAL(addToOutputWindow(QString)),
               this, SLOT(addToOutputWindow(QString)));

    ++m_progress;
    m_progressFutureInterface->setProgressValueAndText(m_progress*100, msgProgress(m_progress, m_maxProgress));

    bool result = m_watcher.result();
    if (!result) {
        // Build Failure
        addToOutputWindow(tr("Error while building project %1").arg(m_currentBuildStep->project()->name()));
        addToOutputWindow(tr("When executing build step '%1'").arg(m_currentBuildStep->displayName()));
        // NBS TODO fix in qtconcurrent
        m_progressFutureInterface->setProgressValueAndText(m_progress*100, tr("Error while building project %1").arg(m_currentBuildStep->project()->name()));
    }

    decrementActiveBuildSteps(m_currentBuildStep->project());
    if (result)
        nextStep();
    else
        clearBuildQueue();
}

void BuildManager::progressChanged()
{
    if (!m_progressFutureInterface)
        return;
    int range = m_watcher.progressMaximum() - m_watcher.progressMinimum();
    if (range != 0) {
        int percent = (m_watcher.progressValue() - m_watcher.progressMinimum()) * 100 / range;
        m_progressFutureInterface->setProgressValue(m_progress * 100 + percent);
    }
}

void BuildManager::nextStep()
{
    if (!m_buildQueue.empty()) {
        m_currentBuildStep = m_buildQueue.front();
        m_currentConfiguration = m_configurations.front();
        m_buildQueue.pop_front();
        m_configurations.pop_front();

        connect(m_currentBuildStep, SIGNAL(addToTaskWindow(QString, int, int, QString)),
                this, SLOT(addToTaskWindow(QString, int, int, QString)));
        connect(m_currentBuildStep, SIGNAL(addToOutputWindow(QString)),
                this, SLOT(addToOutputWindow(QString)));

        bool init = m_currentBuildStep->init(m_currentConfiguration);
        if (!init) {
            addToOutputWindow(tr("Error while building project %1").arg(m_currentBuildStep->project()->name()));
            addToOutputWindow(tr("When executing build step '%1'").arg(m_currentBuildStep->displayName()));
            cancel();
            return;
        }

        if (m_currentBuildStep->project() != m_previousBuildStepProject) {
            const QString projectName = m_currentBuildStep->project()->name();
            addToOutputWindow(tr("Running build steps for project %2...")
                              .arg(projectName));
            m_previousBuildStepProject = m_currentBuildStep->project();
        }
        m_watcher.setFuture(QtConcurrent::run(&BuildStep::run, m_currentBuildStep));
    } else {
        m_running = false;
        m_previousBuildStepProject = 0;
        m_progressFutureInterface->reportFinished();
        m_progressWatcher.setFuture(QFuture<void>());
        delete m_progressFutureInterface;
        m_progressFutureInterface = 0;
        m_maxProgress = 0;
        emit buildQueueFinished(true);
    }
}

void BuildManager::buildQueueAppend(BuildStep * bs, const QString &configuration)
{
    m_buildQueue.append(bs);
    ++m_maxProgress;
    incrementActiveBuildSteps(bs->project());
    m_configurations.append(configuration);
}

void BuildManager::buildProjects(const QList<Project *> &projects, const QList<QString> &configurations)
{
    Q_ASSERT(projects.count() == configurations.count());
    QList<QString>::const_iterator cit = configurations.constBegin();
    QList<Project *>::const_iterator it, end;
    end = projects.constEnd();

    for (it = projects.constBegin(); it != end; ++it, ++cit) {
        if (*cit != QString::null) {
            QList<BuildStep *> buildSteps = (*it)->buildSteps();
            foreach (BuildStep *bs, buildSteps) {
                buildQueueAppend(bs, *cit);
            }
        }
    }
    startBuildQueue();
    if (ProjectExplorerPlugin::instance()->projectExplorerSettings().showCompilerOutput)
        m_outputWindow->popup(false);
}

void BuildManager::cleanProjects(const QList<Project *> &projects, const QList<QString> &configurations)
{
    Q_ASSERT(projects.count() == configurations.count());
    QList<QString>::const_iterator cit = configurations.constBegin();
    QList<Project *>::const_iterator it, end;
    end = projects.constEnd();

    for (it = projects.constBegin(); it != end; ++it, ++cit) {
        QList<BuildStep *> cleanSteps = (*it)->cleanSteps();
        foreach (BuildStep *bs, cleanSteps) {
            buildQueueAppend(bs, *cit);
        }
    }
    startBuildQueue();
    if (ProjectExplorerPlugin::instance()->projectExplorerSettings().showCompilerOutput)
        m_outputWindow->popup(false);
}

void BuildManager::buildProject(Project *p, const QString &configuration)
{
    buildProjects(QList<Project *>() << p, QList<QString>() << configuration);
}

void BuildManager::cleanProject(Project *p, const QString &configuration)
{
    cleanProjects(QList<Project *>() << p, QList<QString>() << configuration);
}

void BuildManager::appendStep(BuildStep *step, const QString &configuration)
{
    buildQueueAppend(step, configuration);
    startBuildQueue();
}

bool BuildManager::isBuilding(Project *pro)
{
    QHash<Project *, int>::iterator it = m_activeBuildSteps.find(pro);
    QHash<Project *, int>::iterator end = m_activeBuildSteps.end();
    if (it == end || *it == 0)
        return false;
    else
        return true;
}

void BuildManager::incrementActiveBuildSteps(Project *pro)
{
    QHash<Project *, int>::iterator it = m_activeBuildSteps.find(pro);
    QHash<Project *, int>::iterator end = m_activeBuildSteps.end();
    if (it == end) {
        m_activeBuildSteps.insert(pro, 1);
        emit buildStateChanged(pro);
    } else if (*it == 0) {
        ++*it;
        emit buildStateChanged(pro);
    } else {
        ++*it;
    }
}

void BuildManager::decrementActiveBuildSteps(Project *pro)
{
    QHash<Project *, int>::iterator it = m_activeBuildSteps.find(pro);
    QHash<Project *, int>::iterator end = m_activeBuildSteps.end();
    if (it == end) {
        Q_ASSERT(false && "BuildManager m_activeBuildSteps says project is not building, but apparently a build step was still in the queue.");
    } else if (*it == 1) {
        --*it;
        emit buildStateChanged(pro);
    } else {
        --*it;
    }
}
<commit_msg>Fix build & run for projects without buildsteps<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 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 "buildmanager.h"

#include "buildprogress.h"
#include "buildstep.h"
#include "compileoutputwindow.h"
#include "projectexplorerconstants.h"
#include "projectexplorer.h"
#include "project.h"
#include "projectexplorersettings.h"
#include "taskwindow.h"

#include <coreplugin/icore.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/progressmanager/futureprogress.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>

#include <QtCore/QDir>
#include <QtCore/QTimer>

#include <qtconcurrent/QtConcurrentTools>

#include <QtGui/QHeaderView>
#include <QtGui/QIcon>
#include <QtGui/QLabel>

using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

static inline QString msgProgress(int n, int total)
{
    return BuildManager::tr("Finished %n of %1 build steps", 0, n).arg(total);
}

BuildManager::BuildManager(ProjectExplorerPlugin *parent)
    : QObject(parent)
    , m_running(false)
    , m_previousBuildStepProject(0)
    , m_canceling(false)
    , m_maxProgress(0)
    , m_progressFutureInterface(0)
{
    ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
    m_projectExplorerPlugin = parent;

    connect(&m_watcher, SIGNAL(finished()),
            this, SLOT(nextBuildQueue()));

    connect(&m_watcher, SIGNAL(progressValueChanged(int)),
            this, SLOT(progressChanged()));
    connect(&m_watcher, SIGNAL(progressRangeChanged(int, int)),
            this, SLOT(progressChanged()));

    m_outputWindow = new CompileOutputWindow(this);
    pm->addObject(m_outputWindow);

    m_taskWindow = new TaskWindow;
    pm->addObject(m_taskWindow);

    connect(m_taskWindow, SIGNAL(tasksChanged()),
            this, SIGNAL(tasksChanged()));

    connect(&m_progressWatcher, SIGNAL(canceled()),
            this, SLOT(cancel()));
}

BuildManager::~BuildManager()
{
    cancel();
    ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();

    pm->removeObject(m_taskWindow);
    delete m_taskWindow;

    pm->removeObject(m_outputWindow);
    delete m_outputWindow;
}

bool BuildManager::isBuilding() const
{
    // we are building even if we are not running yet
    return !m_buildQueue.isEmpty() || m_running;
}

void BuildManager::cancel()
{
    if (m_running) {
        m_canceling = true;
        m_watcher.cancel();
        m_watcher.waitForFinished();

        // The cancel message is added to the output window via a single shot timer
        // since the canceling is likely to have generated new addToOutputWindow signals
        // which are waiting in the event queue to be processed
        // (And we want those to be before the cancel message.)
        QTimer::singleShot(0, this, SLOT(emitCancelMessage()));

        disconnect(m_currentBuildStep, SIGNAL(addToTaskWindow(QString, int, int, QString)),
                   this, SLOT(addToTaskWindow(QString, int, int, QString)));
        disconnect(m_currentBuildStep, SIGNAL(addToOutputWindow(QString)),
                   this, SLOT(addToOutputWindow(QString)));
        decrementActiveBuildSteps(m_currentBuildStep->project());

        m_progressFutureInterface->setProgressValueAndText(m_progress*100, "Build canceled"); //TODO NBS fix in qtconcurrent
        clearBuildQueue();
    }
    return;
}

void BuildManager::emitCancelMessage()
{
    emit addToOutputWindow(tr("Canceled build."));
}

void BuildManager::clearBuildQueue()
{
    foreach (BuildStep * bs, m_buildQueue)
        decrementActiveBuildSteps(bs->project());

    m_buildQueue.clear();
    m_configurations.clear();
    m_running = false;
    m_previousBuildStepProject = 0;

    m_progressFutureInterface->reportCanceled();
    m_progressFutureInterface->reportFinished();
    m_progressWatcher.setFuture(QFuture<void>());
    delete m_progressFutureInterface;
    m_progressFutureInterface = 0;
    m_maxProgress = 0;

    emit buildQueueFinished(false);
}

void BuildManager::toggleOutputWindow()
{
    m_outputWindow->toggle(false);
}

void BuildManager::showTaskWindow()
{
    m_taskWindow->popup(false);
}

void BuildManager::toggleTaskWindow()
{
    m_taskWindow->toggle(false);
}

bool BuildManager::tasksAvailable() const
{
    return m_taskWindow->numberOfTasks() > 0;
}

void BuildManager::gotoTaskWindow()
{
    m_taskWindow->popup(true);
}

void BuildManager::startBuildQueue()
{
    if (m_buildQueue.isEmpty()) {
        emit buildQueueFinished(true);
        return;
    }
    if (!m_running) {
        // Progress Reporting
        Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager();
        m_progressFutureInterface = new QFutureInterface<void>;
        m_progressWatcher.setFuture(m_progressFutureInterface->future());
        Core::FutureProgress *progress = progressManager->addTask(m_progressFutureInterface->future(),
                                                                  tr("Build"),
                                                                  Constants::TASK_BUILD);
        connect(progress, SIGNAL(clicked()), this, SLOT(showBuildResults()));
        progress->setWidget(new BuildProgress(m_taskWindow));
        m_progress = 0;
        m_progressFutureInterface->setProgressRange(0, m_maxProgress * 100);

        m_running = true;
        m_canceling = false;
        m_progressFutureInterface->reportStarted();
        m_outputWindow->clearContents();
        m_taskWindow->clearContents();
        nextStep();
    } else {
        // Already running
        m_progressFutureInterface->setProgressRange(0, m_maxProgress * 100);
        m_progressFutureInterface->setProgressValueAndText(m_progress*100, msgProgress(m_progress, m_maxProgress));
    }
}

void BuildManager::showBuildResults()
{
    if (m_taskWindow->numberOfTasks() != 0)
        toggleTaskWindow();
    else
        toggleOutputWindow();
    //toggleTaskWindow();
}

void BuildManager::addToTaskWindow(const QString &file, int type, int line, const QString &description)
{
    m_taskWindow->addItem(BuildParserInterface::PatternType(type), description, file, line);
}

void BuildManager::addToOutputWindow(const QString &string)
{
    m_outputWindow->appendText(string);
}

void BuildManager::nextBuildQueue()
{
    if (m_canceling)
        return;

    disconnect(m_currentBuildStep, SIGNAL(addToTaskWindow(QString, int, int, QString)),
                this, SLOT(addToTaskWindow(QString, int, int, QString)));
    disconnect(m_currentBuildStep, SIGNAL(addToOutputWindow(QString)),
               this, SLOT(addToOutputWindow(QString)));

    ++m_progress;
    m_progressFutureInterface->setProgressValueAndText(m_progress*100, msgProgress(m_progress, m_maxProgress));

    bool result = m_watcher.result();
    if (!result) {
        // Build Failure
        addToOutputWindow(tr("Error while building project %1").arg(m_currentBuildStep->project()->name()));
        addToOutputWindow(tr("When executing build step '%1'").arg(m_currentBuildStep->displayName()));
        // NBS TODO fix in qtconcurrent
        m_progressFutureInterface->setProgressValueAndText(m_progress*100, tr("Error while building project %1").arg(m_currentBuildStep->project()->name()));
    }

    decrementActiveBuildSteps(m_currentBuildStep->project());
    if (result)
        nextStep();
    else
        clearBuildQueue();
}

void BuildManager::progressChanged()
{
    if (!m_progressFutureInterface)
        return;
    int range = m_watcher.progressMaximum() - m_watcher.progressMinimum();
    if (range != 0) {
        int percent = (m_watcher.progressValue() - m_watcher.progressMinimum()) * 100 / range;
        m_progressFutureInterface->setProgressValue(m_progress * 100 + percent);
    }
}

void BuildManager::nextStep()
{
    if (!m_buildQueue.empty()) {
        m_currentBuildStep = m_buildQueue.front();
        m_currentConfiguration = m_configurations.front();
        m_buildQueue.pop_front();
        m_configurations.pop_front();

        connect(m_currentBuildStep, SIGNAL(addToTaskWindow(QString, int, int, QString)),
                this, SLOT(addToTaskWindow(QString, int, int, QString)));
        connect(m_currentBuildStep, SIGNAL(addToOutputWindow(QString)),
                this, SLOT(addToOutputWindow(QString)));

        bool init = m_currentBuildStep->init(m_currentConfiguration);
        if (!init) {
            addToOutputWindow(tr("Error while building project %1").arg(m_currentBuildStep->project()->name()));
            addToOutputWindow(tr("When executing build step '%1'").arg(m_currentBuildStep->displayName()));
            cancel();
            return;
        }

        if (m_currentBuildStep->project() != m_previousBuildStepProject) {
            const QString projectName = m_currentBuildStep->project()->name();
            addToOutputWindow(tr("Running build steps for project %2...")
                              .arg(projectName));
            m_previousBuildStepProject = m_currentBuildStep->project();
        }
        m_watcher.setFuture(QtConcurrent::run(&BuildStep::run, m_currentBuildStep));
    } else {
        m_running = false;
        m_previousBuildStepProject = 0;
        m_progressFutureInterface->reportFinished();
        m_progressWatcher.setFuture(QFuture<void>());
        delete m_progressFutureInterface;
        m_progressFutureInterface = 0;
        m_maxProgress = 0;
        emit buildQueueFinished(true);
    }
}

void BuildManager::buildQueueAppend(BuildStep * bs, const QString &configuration)
{
    m_buildQueue.append(bs);
    ++m_maxProgress;
    incrementActiveBuildSteps(bs->project());
    m_configurations.append(configuration);
}

void BuildManager::buildProjects(const QList<Project *> &projects, const QList<QString> &configurations)
{
    Q_ASSERT(projects.count() == configurations.count());
    QList<QString>::const_iterator cit = configurations.constBegin();
    QList<Project *>::const_iterator it, end;
    end = projects.constEnd();

    for (it = projects.constBegin(); it != end; ++it, ++cit) {
        if (*cit != QString::null) {
            QList<BuildStep *> buildSteps = (*it)->buildSteps();
            foreach (BuildStep *bs, buildSteps) {
                buildQueueAppend(bs, *cit);
            }
        }
    }
    startBuildQueue();
    if (ProjectExplorerPlugin::instance()->projectExplorerSettings().showCompilerOutput)
        m_outputWindow->popup(false);
}

void BuildManager::cleanProjects(const QList<Project *> &projects, const QList<QString> &configurations)
{
    Q_ASSERT(projects.count() == configurations.count());
    QList<QString>::const_iterator cit = configurations.constBegin();
    QList<Project *>::const_iterator it, end;
    end = projects.constEnd();

    for (it = projects.constBegin(); it != end; ++it, ++cit) {
        QList<BuildStep *> cleanSteps = (*it)->cleanSteps();
        foreach (BuildStep *bs, cleanSteps) {
            buildQueueAppend(bs, *cit);
        }
    }
    startBuildQueue();
    if (ProjectExplorerPlugin::instance()->projectExplorerSettings().showCompilerOutput)
        m_outputWindow->popup(false);
}

void BuildManager::buildProject(Project *p, const QString &configuration)
{
    buildProjects(QList<Project *>() << p, QList<QString>() << configuration);
}

void BuildManager::cleanProject(Project *p, const QString &configuration)
{
    cleanProjects(QList<Project *>() << p, QList<QString>() << configuration);
}

void BuildManager::appendStep(BuildStep *step, const QString &configuration)
{
    buildQueueAppend(step, configuration);
    startBuildQueue();
}

bool BuildManager::isBuilding(Project *pro)
{
    QHash<Project *, int>::iterator it = m_activeBuildSteps.find(pro);
    QHash<Project *, int>::iterator end = m_activeBuildSteps.end();
    if (it == end || *it == 0)
        return false;
    else
        return true;
}

void BuildManager::incrementActiveBuildSteps(Project *pro)
{
    QHash<Project *, int>::iterator it = m_activeBuildSteps.find(pro);
    QHash<Project *, int>::iterator end = m_activeBuildSteps.end();
    if (it == end) {
        m_activeBuildSteps.insert(pro, 1);
        emit buildStateChanged(pro);
    } else if (*it == 0) {
        ++*it;
        emit buildStateChanged(pro);
    } else {
        ++*it;
    }
}

void BuildManager::decrementActiveBuildSteps(Project *pro)
{
    QHash<Project *, int>::iterator it = m_activeBuildSteps.find(pro);
    QHash<Project *, int>::iterator end = m_activeBuildSteps.end();
    if (it == end) {
        Q_ASSERT(false && "BuildManager m_activeBuildSteps says project is not building, but apparently a build step was still in the queue.");
    } else if (*it == 1) {
        --*it;
        emit buildStateChanged(pro);
    } else {
        --*it;
    }
}
<|endoftext|>


<commit_before>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010      Siddharth Srivastava <akssps011@gmail.com>
//

#include "RoutingPlugin.h"

#include "ui_RoutingItemWidget.h"

#include "MarbleWidget.h"
#include "routing/RoutingManager.h"
#include "routing/RoutingModel.h"
#include "MarbleDirs.h"
#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "MarbleMap.h"
#include "MarbleDataFacade.h"
#include "gps/PositionTracking.h"
#include "GeoPainter.h"
#include "ViewportParams.h"
#include "WidgetGraphicsItem.h"
#include "MarbleGraphicsGridLayout.h"
#include "global.h"

#include <QtGui/QIcon>
#include <QtCore/QRect>
#include <QtGui/QColor>
#include <QtGui/QPixmap>
#include <QtGui/QWidget>

using namespace Marble;

RoutingPlugin::RoutingPlugin( const QPointF &point )
      :AbstractFloatItem( point ),
       m_routingModel( 0 ),
       m_routingManager( 0 ),
       m_remainingTime( 0.0 ),
       m_remainingDistance( 0.0 ),
       m_routingItem( 0 ),
       m_widgetItem( 0 )
{
    setEnabled( true );
    setVisible( false );
}

RoutingPlugin::~RoutingPlugin ()
{

}

QStringList RoutingPlugin::backendTypes() const
{
    return QStringList( "routing" );
}

QString RoutingPlugin::name() const
{
    return tr( "Routing" );
}

QString RoutingPlugin::guiString() const
{
    return tr( "&Routing" );
}

QString RoutingPlugin::nameId() const
{
    return QString("routing");
}

QString RoutingPlugin::description() const
{
    return tr( "Shows the information about the route" );
}

QIcon RoutingPlugin::icon() const
{
    return QIcon();
}

void RoutingPlugin::initialize()
{
    QWidget *widget = new QWidget( 0 );
    m_routingItem = new Ui::RoutingItemWidget;
    m_routingItem->setupUi( widget );
    m_widgetItem = new WidgetGraphicsItem( this );
    m_widgetItem->setWidget( widget );
    MarbleGraphicsGridLayout *gridLayout = new MarbleGraphicsGridLayout( 1, 1 );
    gridLayout->addItem( m_widgetItem ,0 ,0 );
    setLayout( gridLayout );
}

bool RoutingPlugin::isInitialized() const
{
    return m_widgetItem;
}

void RoutingPlugin::setDestinationInformation( qreal remainingTime, qreal remainingDistance )
{
    m_remainingTime = remainingTime;
    m_remainingDistance = remainingDistance;
}

bool RoutingPlugin::eventFilter(QObject *object, QEvent *e)
{
    if( m_routingManager )    {
        return AbstractFloatItem::eventFilter( object, e );
    }

    MarbleWidget *marbleWidget = dynamic_cast<MarbleWidget*> ( object );
    m_routingManager = dataFacade()->routingManager();
    m_routingModel = m_routingManager->routingModel();

    connect( m_routingModel, SIGNAL( nextInstruction( qreal, qreal ) ),
            this, SLOT( setDestinationInformation( qreal, qreal ) ) );

    PositionTracking *tracking = marbleWidget->map()->model()->positionTracking();
    connect( tracking, SIGNAL( gpsLocation( GeoDataCoordinates, qreal ) ),
             this, SLOT( setCurrentLocation( GeoDataCoordinates, qreal ) ) );

    return AbstractFloatItem::eventFilter( object, e );
}

void RoutingPlugin::setCurrentLocation( GeoDataCoordinates position, qreal speed )
{
    m_currentPosition = position;
    bool hasRoute = m_routingModel->rowCount() != 0;
    setVisible( hasRoute );
    if ( hasRoute ) {
        showRoutingItem();
    }
}

void RoutingPlugin::showRoutingItem()
{
    if( m_remainingTime < 60 ) {
        m_routingItem->timeUnitLabel->setText( tr( "Minutes" ) );
        m_routingItem->remainingTimeLabel->setText( QString::number( m_remainingTime, 'f', 2 ) );
    }
    else {
        m_routingItem->timeUnitLabel->setText( tr( "Hours" ) );
        m_routingItem->remainingTimeLabel->setText( QString::number( m_remainingTime * MIN2HOUR, 'f', 2 ) );
    }

    if( m_remainingDistance < 1000 ) {
        m_routingItem->distanceUnitLabel->setText( tr( "Metres" ) );
        m_routingItem->remainingDistanceLabel->setText( QString::number( m_remainingDistance, 'f', 3 ) );
    }
    else {
        m_routingItem->distanceUnitLabel->setText( tr( "KM" ) );
        m_routingItem->remainingDistanceLabel->setText( QString::number( m_remainingDistance * METER2KM , 'f', 3 ) );
    }

    qreal totalDistance =  ( m_routingManager->routingModel()->totalDistance() ) ;
    if( !m_routingModel->deviatedFromRoute() && m_remainingDistance !=0 && m_remainingTime != 0 ) {
        m_routingItem->distanceCoveredProgressBar->setRange( 0, qRound( totalDistance ) );
        m_routingItem->distanceCoveredProgressBar->setValue( qRound ( totalDistance - m_remainingDistance ) );
    }
    if ( m_remainingDistance == 0 && m_remainingTime == 0 ) {
        m_routingItem->distanceCoveredProgressBar->setValue( qRound( totalDistance ) );
    }
}

Q_EXPORT_PLUGIN2( RoutingPlugin, Marble::RoutingPlugin )

#include "RoutingPlugin.moc"
<commit_msg>fix compiler warnings (init order, unused variable)<commit_after>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010      Siddharth Srivastava <akssps011@gmail.com>
//

#include "RoutingPlugin.h"

#include "ui_RoutingItemWidget.h"

#include "MarbleWidget.h"
#include "routing/RoutingManager.h"
#include "routing/RoutingModel.h"
#include "MarbleDirs.h"
#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "MarbleMap.h"
#include "MarbleDataFacade.h"
#include "gps/PositionTracking.h"
#include "GeoPainter.h"
#include "ViewportParams.h"
#include "WidgetGraphicsItem.h"
#include "MarbleGraphicsGridLayout.h"
#include "global.h"

#include <QtGui/QIcon>
#include <QtCore/QRect>
#include <QtGui/QColor>
#include <QtGui/QPixmap>
#include <QtGui/QWidget>

using namespace Marble;

RoutingPlugin::RoutingPlugin( const QPointF &point )
      :AbstractFloatItem( point ),
       m_routingManager( 0 ),
       m_routingModel( 0 ),
       m_remainingTime( 0.0 ),
       m_remainingDistance( 0.0 ),
       m_widgetItem( 0 ),
       m_routingItem( 0 )
{
    setEnabled( true );
    setVisible( false );
}

RoutingPlugin::~RoutingPlugin ()
{

}

QStringList RoutingPlugin::backendTypes() const
{
    return QStringList( "routing" );
}

QString RoutingPlugin::name() const
{
    return tr( "Routing" );
}

QString RoutingPlugin::guiString() const
{
    return tr( "&Routing" );
}

QString RoutingPlugin::nameId() const
{
    return QString("routing");
}

QString RoutingPlugin::description() const
{
    return tr( "Shows the information about the route" );
}

QIcon RoutingPlugin::icon() const
{
    return QIcon();
}

void RoutingPlugin::initialize()
{
    QWidget *widget = new QWidget( 0 );
    m_routingItem = new Ui::RoutingItemWidget;
    m_routingItem->setupUi( widget );
    m_widgetItem = new WidgetGraphicsItem( this );
    m_widgetItem->setWidget( widget );
    MarbleGraphicsGridLayout *gridLayout = new MarbleGraphicsGridLayout( 1, 1 );
    gridLayout->addItem( m_widgetItem ,0 ,0 );
    setLayout( gridLayout );
}

bool RoutingPlugin::isInitialized() const
{
    return m_widgetItem;
}

void RoutingPlugin::setDestinationInformation( qreal remainingTime, qreal remainingDistance )
{
    m_remainingTime = remainingTime;
    m_remainingDistance = remainingDistance;
}

bool RoutingPlugin::eventFilter(QObject *object, QEvent *e)
{
    if( m_routingManager )    {
        return AbstractFloatItem::eventFilter( object, e );
    }

    MarbleWidget *marbleWidget = dynamic_cast<MarbleWidget*> ( object );
    m_routingManager = dataFacade()->routingManager();
    m_routingModel = m_routingManager->routingModel();

    connect( m_routingModel, SIGNAL( nextInstruction( qreal, qreal ) ),
            this, SLOT( setDestinationInformation( qreal, qreal ) ) );

    PositionTracking *tracking = marbleWidget->map()->model()->positionTracking();
    connect( tracking, SIGNAL( gpsLocation( GeoDataCoordinates, qreal ) ),
             this, SLOT( setCurrentLocation( GeoDataCoordinates, qreal ) ) );

    return AbstractFloatItem::eventFilter( object, e );
}

void RoutingPlugin::setCurrentLocation( GeoDataCoordinates position, qreal speed )
{
    Q_UNUSED(speed);
    m_currentPosition = position;
    bool hasRoute = m_routingModel->rowCount() != 0;
    setVisible( hasRoute );
    if ( hasRoute ) {
        showRoutingItem();
    }
}

void RoutingPlugin::showRoutingItem()
{
    if( m_remainingTime < 60 ) {
        m_routingItem->timeUnitLabel->setText( tr( "Minutes" ) );
        m_routingItem->remainingTimeLabel->setText( QString::number( m_remainingTime, 'f', 2 ) );
    }
    else {
        m_routingItem->timeUnitLabel->setText( tr( "Hours" ) );
        m_routingItem->remainingTimeLabel->setText( QString::number( m_remainingTime * MIN2HOUR, 'f', 2 ) );
    }

    if( m_remainingDistance < 1000 ) {
        m_routingItem->distanceUnitLabel->setText( tr( "Metres" ) );
        m_routingItem->remainingDistanceLabel->setText( QString::number( m_remainingDistance, 'f', 3 ) );
    }
    else {
        m_routingItem->distanceUnitLabel->setText( tr( "KM" ) );
        m_routingItem->remainingDistanceLabel->setText( QString::number( m_remainingDistance * METER2KM , 'f', 3 ) );
    }

    qreal totalDistance =  ( m_routingManager->routingModel()->totalDistance() ) ;
    if( !m_routingModel->deviatedFromRoute() && m_remainingDistance !=0 && m_remainingTime != 0 ) {
        m_routingItem->distanceCoveredProgressBar->setRange( 0, qRound( totalDistance ) );
        m_routingItem->distanceCoveredProgressBar->setValue( qRound ( totalDistance - m_remainingDistance ) );
    }
    if ( m_remainingDistance == 0 && m_remainingTime == 0 ) {
        m_routingItem->distanceCoveredProgressBar->setValue( qRound( totalDistance ) );
    }
}

Q_EXPORT_PLUGIN2( RoutingPlugin, Marble::RoutingPlugin )

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


<commit_before>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010      Dennis Nienhüser <earthwings@gentoo.org>
//

#include "RoutinoPlugin.h"
#include "RoutinoRunner.h"

#include "ui_RoutinoConfigWidget.h"

namespace Marble
{

RoutinoPlugin::RoutinoPlugin( QObject *parent ) : RunnerPlugin( parent )
{
    setCapabilities( Routing );
    setSupportedCelestialBodies( QStringList() << "earth" );
    setCanWorkOffline( true );
    setName( tr( "Routino" ) );
    setNameId( "routino" );
    setDescription( tr( "Retrieves routes from routino" ) );
    setGuiString( tr( "Routino Routing" ) );
}

MarbleAbstractRunner* RoutinoPlugin::newRunner() const
{
    return new RoutinoRunner;
}

class RoutinoConfigWidget : public RunnerPlugin::ConfigWidget
{
public:
    RoutinoConfigWidget()
        : RunnerPlugin::ConfigWidget()
    {
        ui_configWidget = new Ui::RoutinoConfigWidget;
        ui_configWidget->setupUi( this );
        QStringList transports;
        //TODO: read from profiles.xml
        //TODO: translate
        transports << "foot" << "horse" << "wheelchair" << "bicycle" << "moped" << "motorbike" << "motorcar" << "goods" << "hgv" << "psv";
        foreach ( const QString &transport, transports) {
            ui_configWidget->transport->addItem(transport, transport);
        }
    }
    virtual void loadSettings( const QHash<QString, QVariant> &settings_ )
    {
        QHash<QString, QVariant> settings = settings_;

        // Check if all fields are filled and fill them with default values.
        if ( !settings.contains( "transport" ) ) {
            settings.insert( "transport", "motorcar" );
        }
        ui_configWidget->transport->setCurrentIndex(
            ui_configWidget->transport->findData( settings.value( "transport" ).toString() ) );
        if ( settings.value( "method" ).toString() == "shortest" ) {
            ui_configWidget->shortest->setChecked( true );
        } else {
            ui_configWidget->fastest->setChecked( true );
        }
    }

    virtual QHash<QString, QVariant> settings() const
    {
        QHash<QString,QVariant> settings;
        settings.insert( "transport",
                        ui_configWidget->transport->itemData( ui_configWidget->transport->currentIndex() ) );

        if ( ui_configWidget->shortest->isChecked() ) {
            settings.insert( "method", "shortest" );
        } else {
            settings.insert( "method", "fastest" );
        }
        return settings;
    }
private:
    Ui::RoutinoConfigWidget *ui_configWidget;
};

RunnerPlugin::ConfigWidget *RoutinoPlugin::configWidget() const
{
    return new RoutinoConfigWidget();
}

bool RoutinoPlugin::supportsTemplate(RoutingProfilesModel::ProfileTemplate profileTemplate) const
{
    QSet<RoutingProfilesModel::ProfileTemplate> availableTemplates;
        availableTemplates.insert( RoutingProfilesModel::CarFastestTemplate );
        availableTemplates.insert( RoutingProfilesModel::CarShortestTemplate );
        availableTemplates.insert( RoutingProfilesModel::BicycleTemplate );
        availableTemplates.insert( RoutingProfilesModel::PedestrianTemplate );
    return availableTemplates.contains( profileTemplate );
}

QHash< QString, QVariant > RoutinoPlugin::templateSettings(RoutingProfilesModel::ProfileTemplate profileTemplate) const
{
    QHash<QString, QVariant> result;
    switch ( profileTemplate ) {
        case RoutingProfilesModel::CarFastestTemplate:
            result["transport"] = "motorcar";
            result["method"] = "fastest";
            break;
        case RoutingProfilesModel::CarShortestTemplate:
            result["transport"] = "motorcar";
            result["method"] = "shortest";
            break;
        case RoutingProfilesModel::CarEcologicalTemplate:
            break;
        case RoutingProfilesModel::BicycleTemplate:
            result["transport"] = "bicycle";
            result["method"] = "shortest";
            break;
        case RoutingProfilesModel::PedestrianTemplate:
            result["transport"] = "foot";
            result["method"] = "shortest";
            break;
        case RoutingProfilesModel::LastTemplate:
            Q_ASSERT( false );
            break;
    }
    return result;
}

}

Q_EXPORT_PLUGIN2( RoutinoPlugin, Marble::RoutinoPlugin )

#include "RoutinoPlugin.moc"
<commit_msg>Fix mem leak<commit_after>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010      Dennis Nienhüser <earthwings@gentoo.org>
//

#include "RoutinoPlugin.h"
#include "RoutinoRunner.h"

#include "ui_RoutinoConfigWidget.h"

namespace Marble
{

RoutinoPlugin::RoutinoPlugin( QObject *parent ) : RunnerPlugin( parent )
{
    setCapabilities( Routing );
    setSupportedCelestialBodies( QStringList() << "earth" );
    setCanWorkOffline( true );
    setName( tr( "Routino" ) );
    setNameId( "routino" );
    setDescription( tr( "Retrieves routes from routino" ) );
    setGuiString( tr( "Routino Routing" ) );
}

MarbleAbstractRunner* RoutinoPlugin::newRunner() const
{
    return new RoutinoRunner;
}

class RoutinoConfigWidget : public RunnerPlugin::ConfigWidget
{
public:
    RoutinoConfigWidget()
        : RunnerPlugin::ConfigWidget()
    {
        ui_configWidget = new Ui::RoutinoConfigWidget;
        ui_configWidget->setupUi( this );
        QStringList transports;
        //TODO: read from profiles.xml
        //TODO: translate
        transports << "foot" << "horse" << "wheelchair" << "bicycle" << "moped" << "motorbike" << "motorcar" << "goods" << "hgv" << "psv";
        foreach ( const QString &transport, transports) {
            ui_configWidget->transport->addItem(transport, transport);
        }
    }
    virtual ~RoutinoConfigWidget()
    {
        delete ui_configWidget;
    }
    virtual void loadSettings( const QHash<QString, QVariant> &settings_ )
    {
        QHash<QString, QVariant> settings = settings_;

        // Check if all fields are filled and fill them with default values.
        if ( !settings.contains( "transport" ) ) {
            settings.insert( "transport", "motorcar" );
        }
        ui_configWidget->transport->setCurrentIndex(
            ui_configWidget->transport->findData( settings.value( "transport" ).toString() ) );
        if ( settings.value( "method" ).toString() == "shortest" ) {
            ui_configWidget->shortest->setChecked( true );
        } else {
            ui_configWidget->fastest->setChecked( true );
        }
    }

    virtual QHash<QString, QVariant> settings() const
    {
        QHash<QString,QVariant> settings;
        settings.insert( "transport",
                        ui_configWidget->transport->itemData( ui_configWidget->transport->currentIndex() ) );

        if ( ui_configWidget->shortest->isChecked() ) {
            settings.insert( "method", "shortest" );
        } else {
            settings.insert( "method", "fastest" );
        }
        return settings;
    }
private:
    Ui::RoutinoConfigWidget *ui_configWidget;
};

RunnerPlugin::ConfigWidget *RoutinoPlugin::configWidget() const
{
    return new RoutinoConfigWidget();
}

bool RoutinoPlugin::supportsTemplate(RoutingProfilesModel::ProfileTemplate profileTemplate) const
{
    QSet<RoutingProfilesModel::ProfileTemplate> availableTemplates;
        availableTemplates.insert( RoutingProfilesModel::CarFastestTemplate );
        availableTemplates.insert( RoutingProfilesModel::CarShortestTemplate );
        availableTemplates.insert( RoutingProfilesModel::BicycleTemplate );
        availableTemplates.insert( RoutingProfilesModel::PedestrianTemplate );
    return availableTemplates.contains( profileTemplate );
}

QHash< QString, QVariant > RoutinoPlugin::templateSettings(RoutingProfilesModel::ProfileTemplate profileTemplate) const
{
    QHash<QString, QVariant> result;
    switch ( profileTemplate ) {
        case RoutingProfilesModel::CarFastestTemplate:
            result["transport"] = "motorcar";
            result["method"] = "fastest";
            break;
        case RoutingProfilesModel::CarShortestTemplate:
            result["transport"] = "motorcar";
            result["method"] = "shortest";
            break;
        case RoutingProfilesModel::CarEcologicalTemplate:
            break;
        case RoutingProfilesModel::BicycleTemplate:
            result["transport"] = "bicycle";
            result["method"] = "shortest";
            break;
        case RoutingProfilesModel::PedestrianTemplate:
            result["transport"] = "foot";
            result["method"] = "shortest";
            break;
        case RoutingProfilesModel::LastTemplate:
            Q_ASSERT( false );
            break;
    }
    return result;
}

}

Q_EXPORT_PLUGIN2( RoutinoPlugin, Marble::RoutinoPlugin )

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


<commit_before>//******************************************************************************
//******************************************************************************

#include "xbridgetransactionsview.h"
// #include "../xbridgeapp.h"
// #include "xbridgetransactiondialog.h"
#include "xbridge/xbridgeexchange.h"
#include "xbridge/xuiconnector.h"
#include "xbridge/util/logger.h"

#include <QTableView>
#include <QHeaderView>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QLabel>
#include <QTextEdit>
#include <QFile>

//******************************************************************************
//******************************************************************************
XBridgeTransactionsView::XBridgeTransactionsView(QWidget *parent)
    : QWidget(parent)
    // , m_walletModel(0)
    , m_dlg(m_txModel, this)
{
    setupUi();
}

//******************************************************************************
//******************************************************************************
XBridgeTransactionsView::~XBridgeTransactionsView()
{
    xuiConnector.NotifyLogMessage.disconnect
            (boost::bind(&XBridgeTransactionsView::onLogString, this, _1));
}

//******************************************************************************
//******************************************************************************
void XBridgeTransactionsView::setupUi()
{
    QVBoxLayout * vbox = new QVBoxLayout;

    QLabel * l = new QLabel(tr("Blocknet Decentralized Exchange"), this);
    vbox->addWidget(l);

    m_transactionsProxy.setSourceModel(&m_txModel);
    m_transactionsProxy.setDynamicSortFilter(true);

    QList<XBridgeTransactionDescr::State> transactionsAccetpedStates;
    transactionsAccetpedStates << XBridgeTransactionDescr::trNew
                               << XBridgeTransactionDescr::trPending
                               << XBridgeTransactionDescr::trAccepting
                               << XBridgeTransactionDescr::trHold
                               << XBridgeTransactionDescr::trCreated
                               << XBridgeTransactionDescr::trSigned
                               << XBridgeTransactionDescr::trCommited;

    m_transactionsProxy.setAcceptedStates(transactionsAccetpedStates);

    m_transactionsList = new QTableView(this);
    m_transactionsList->setModel(&m_transactionsProxy);
    m_transactionsList->setContextMenuPolicy(Qt::CustomContextMenu);
    m_transactionsList->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_transactionsList->setSortingEnabled(true);

    connect(m_transactionsList, SIGNAL(customContextMenuRequested(QPoint)),
            this,               SLOT(onContextMenu(QPoint)));

    QHeaderView * header = m_transactionsList->horizontalHeader();
#if QT_VERSION <0x050000
    header->setResizeMode(XBridgeTransactionsModel::Total, QHeaderView::Stretch);
#else
    header->setSectionResizeMode(XBridgeTransactionsModel::Total, QHeaderView::Stretch);
#endif
#if QT_VERSION <0x050000
    header->setResizeMode(XBridgeTransactionsModel::Size, QHeaderView::Stretch);
#else
    header->setSectionResizeMode(XBridgeTransactionsModel::Size, QHeaderView::Stretch);
#endif
#if QT_VERSION <0x050000
    header->setResizeMode(XBridgeTransactionsModel::BID, QHeaderView::Stretch);
#else
    header->setSectionResizeMode(XBridgeTransactionsModel::BID, QHeaderView::Stretch);
#endif

    header->resizeSection(XBridgeTransactionsModel::Total,      80);
    header->resizeSection(XBridgeTransactionsModel::Size,       80);
    header->resizeSection(XBridgeTransactionsModel::BID,        80);
    header->resizeSection(XBridgeTransactionsModel::State,      128);
    vbox->addWidget(m_transactionsList);

    QHBoxLayout * hbox = new QHBoxLayout;

    XBridgeExchange & e = XBridgeExchange::instance();
    if (!e.isEnabled())
    {
        QPushButton * addTxBtn = new QPushButton(trUtf8("New Transaction"), this);
        // addTxBtn->setIcon(QIcon("qrc://"))
        connect(addTxBtn, SIGNAL(clicked()), this, SLOT(onNewTransaction()));
        hbox->addWidget(addTxBtn);
    }
    else
    {
        QPushButton * addTxBtn = new QPushButton(trUtf8("Exchange node"), this);
        addTxBtn->setEnabled(false);
        hbox->addWidget(addTxBtn);
    }

    hbox->addStretch();

    QPushButton * showHideButton = new QPushButton("Toggle to log", this);
    connect(showHideButton, SIGNAL(clicked()), this, SLOT(onToggleHistoricLogs()));
    hbox->addWidget(showHideButton);

    vbox->addLayout(hbox);

    m_historicTransactionsProxy.setSourceModel(&m_txModel);
    m_historicTransactionsProxy.setDynamicSortFilter(true);

    QList<XBridgeTransactionDescr::State> historicTransactionsAccetpedStates;
    historicTransactionsAccetpedStates << XBridgeTransactionDescr::trExpired
                                       << XBridgeTransactionDescr::trOffline
                                       << XBridgeTransactionDescr::trFinished
                                       << XBridgeTransactionDescr::trDropped
                                       << XBridgeTransactionDescr::trCancelled
                                       << XBridgeTransactionDescr::trInvalid;

    m_historicTransactionsProxy.setAcceptedStates(historicTransactionsAccetpedStates);

    m_historicTransactionsList = new QTableView(this);
    m_historicTransactionsList->setModel(&m_historicTransactionsProxy);
    m_historicTransactionsList->setContextMenuPolicy(Qt::CustomContextMenu);
    m_historicTransactionsList->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_historicTransactionsList->setSortingEnabled(true);

    QHeaderView * historicHeader = m_historicTransactionsList->horizontalHeader();
#if QT_VERSION <0x050000
    header->setResizeMode(XBridgeTransactionsModel::Total, QHeaderView::Stretch);
#else
    historicHeader->setSectionResizeMode(XBridgeTransactionsModel::Total, QHeaderView::Stretch);
#endif
#if QT_VERSION <0x050000
    header->setResizeMode(XBridgeTransactionsModel::Size, QHeaderView::Stretch);
#else
    historicHeader->setSectionResizeMode(XBridgeTransactionsModel::Size, QHeaderView::Stretch);
#endif
#if QT_VERSION <0x050000
    header->setResizeMode(XBridgeTransactionsModel::BID, QHeaderView::Stretch);
#else
    historicHeader->setSectionResizeMode(XBridgeTransactionsModel::BID, QHeaderView::Stretch);
#endif

    historicHeader->resizeSection(XBridgeTransactionsModel::Total,      80);
    historicHeader->resizeSection(XBridgeTransactionsModel::Size,       80);
    historicHeader->resizeSection(XBridgeTransactionsModel::BID,        80);
    historicHeader->resizeSection(XBridgeTransactionsModel::State,      128);
    vbox->addWidget(m_historicTransactionsList);

    m_logStrings = new QTextEdit(this);
    m_logStrings->setMinimumHeight(64);
    m_logStrings->setReadOnly(true);
    m_logStrings->setVisible(false);
    vbox->addWidget(m_logStrings);

    setLayout(vbox);

    xuiConnector.NotifyLogMessage.connect
            (boost::bind(&XBridgeTransactionsView::onLogString, this, _1));
}

//******************************************************************************
//******************************************************************************
QMenu * XBridgeTransactionsView::setupContextMenu(QModelIndex & index)
{
    QMenu * contextMenu = new QMenu();

    if (!m_txModel.isMyTransaction(index.row()))
    {
        QAction * acceptTransaction = new QAction(tr("&Accept transaction"), this);
        contextMenu->addAction(acceptTransaction);

        connect(acceptTransaction,   SIGNAL(triggered()),
                this,                SLOT(onAcceptTransaction()));
    }
    else
    {
        QAction * cancelTransaction = new QAction(tr("&Cancel transaction"), this);
        contextMenu->addAction(cancelTransaction);

        connect(cancelTransaction,   SIGNAL(triggered()),
                this,                SLOT(onCancelTransaction()));
    }

    if (false)
    {
        QAction * rollbackTransaction = new QAction(tr("&Rollback transaction"), this);
        contextMenu->addAction(rollbackTransaction);

        connect(rollbackTransaction, SIGNAL(triggered()),
                this,                SLOT(onRollbackTransaction()));
    }

    return contextMenu;
}

//******************************************************************************
//******************************************************************************
void XBridgeTransactionsView::onNewTransaction()
{
    m_dlg.setPendingId(uint256(), std::vector<unsigned char>());
    m_dlg.show();
}

//******************************************************************************
//******************************************************************************
void XBridgeTransactionsView::onAcceptTransaction()
{
    if (!m_contextMenuIndex.isValid())
    {
        return;
    }

    if (m_txModel.isMyTransaction(m_contextMenuIndex.row()))
    {
        return;
    }

    XBridgeTransactionDescr d = m_txModel.item(m_contextMenuIndex.row());
    if (d.state != XBridgeTransactionDescr::trPending)
    {
        return;
    }

    m_dlg.setPendingId(d.id, d.hubAddress);
    m_dlg.setFromAmount((double)d.toAmount / XBridgeTransactionDescr::COIN);
    m_dlg.setToAmount((double)d.fromAmount / XBridgeTransactionDescr::COIN);
    m_dlg.setFromCurrency(QString::fromStdString(d.toCurrency));
    m_dlg.setToCurrency(QString::fromStdString(d.fromCurrency));
    m_dlg.show();
}

//******************************************************************************
//******************************************************************************
void XBridgeTransactionsView::onCancelTransaction()
{
    if (!m_contextMenuIndex.isValid())
    {
        return;
    }

    if (QMessageBox::warning(this,
                             trUtf8("Cancel transaction"),
                             trUtf8("Are you sure?"),
                             QMessageBox::Yes | QMessageBox::Cancel,
                             QMessageBox::Cancel) != QMessageBox::Yes)
    {
        return;
    }

    if (!m_txModel.cancelTransaction(m_txModel.item(m_contextMenuIndex.row()).id))
    {
        QMessageBox::warning(this,
                             trUtf8("Cancel transaction"),
                             trUtf8("Error send cancel request"));
    }
}

//******************************************************************************
//******************************************************************************
void XBridgeTransactionsView::onRollbackTransaction()
{
    if (!m_contextMenuIndex.isValid())
    {
        return;
    }

    if (QMessageBox::warning(this,
                             trUtf8("Rollback transaction"),
                             trUtf8("Are you sure?"),
                             QMessageBox::Yes | QMessageBox::Cancel,
                             QMessageBox::Cancel) != QMessageBox::Yes)
    {
        return;
    }

    if (!m_txModel.cancelTransaction(m_txModel.item(m_contextMenuIndex.row()).id))
    {
        QMessageBox::warning(this,
                             trUtf8("Cancel transaction"),
                             trUtf8("Error send cancel request"));
    }
}

//******************************************************************************
//******************************************************************************
void XBridgeTransactionsView::onContextMenu(QPoint /*pt*/)
{
    XBridgeExchange & e = XBridgeExchange::instance();
    if (e.isEnabled())
    {
        return;
    }

    m_contextMenuIndex = m_transactionsList->selectionModel()->currentIndex();
    if (!m_contextMenuIndex.isValid())
    {
        return;
    }

    m_contextMenuIndex = m_transactionsProxy.mapToSource(m_contextMenuIndex);
    if (!m_contextMenuIndex.isValid())
    {
        return;
    }

    QMenu * contextMenu = setupContextMenu(m_contextMenuIndex);

    contextMenu->exec(QCursor::pos());
    contextMenu->deleteLater();
}

//******************************************************************************
//******************************************************************************
void XBridgeTransactionsView::onToggleHistoricLogs()
{
    QPushButton * btn = qobject_cast<QPushButton *>(sender());

    bool logsVisible = m_logStrings->isVisible();
    bool historicTrVisible = m_historicTransactionsList->isVisible();

    if(logsVisible)
        btn->setText("Toggle to log");
    else if(historicTrVisible)
        btn->setText("Toggle to history");

    m_logStrings->setVisible(!logsVisible);
    m_historicTransactionsList->setVisible(!historicTrVisible);

    if (!logsVisible)
    {
        m_logStrings->clear();

        // show, load all logs
        QFile f(QString::fromStdString(LOG::logFileName()));
        if (f.open(QIODevice::ReadOnly))
        {
            m_logStrings->insertPlainText(f.readAll());
        }
    }
}

//******************************************************************************
//******************************************************************************
void XBridgeTransactionsView::onLogString(const std::string str)
{
    const QString qstr = QString::fromStdString(str);
    m_logStrings->insertPlainText(qstr);

//    QTextCursor c = m_logStrings->textCursor();
//    c.movePosition(QTextCursor::End);
//    m_logStrings->setTextCursor(c);

//    m_logStrings->ensureCursorVisible();
}
<commit_msg>rollback tx menu item<commit_after>//******************************************************************************
//******************************************************************************

#include "xbridgetransactionsview.h"
// #include "../xbridgeapp.h"
// #include "xbridgetransactiondialog.h"
#include "xbridge/xbridgeexchange.h"
#include "xbridge/xuiconnector.h"
#include "xbridge/util/logger.h"

#include <QTableView>
#include <QHeaderView>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QLabel>
#include <QTextEdit>
#include <QFile>

//******************************************************************************
//******************************************************************************
XBridgeTransactionsView::XBridgeTransactionsView(QWidget *parent)
    : QWidget(parent)
    // , m_walletModel(0)
    , m_dlg(m_txModel, this)
{
    setupUi();
}

//******************************************************************************
//******************************************************************************
XBridgeTransactionsView::~XBridgeTransactionsView()
{
    xuiConnector.NotifyLogMessage.disconnect
            (boost::bind(&XBridgeTransactionsView::onLogString, this, _1));
}

//******************************************************************************
//******************************************************************************
void XBridgeTransactionsView::setupUi()
{
    QVBoxLayout * vbox = new QVBoxLayout;

    QLabel * l = new QLabel(tr("Blocknet Decentralized Exchange"), this);
    vbox->addWidget(l);

    m_transactionsProxy.setSourceModel(&m_txModel);
    m_transactionsProxy.setDynamicSortFilter(true);

    QList<XBridgeTransactionDescr::State> transactionsAccetpedStates;
    transactionsAccetpedStates << XBridgeTransactionDescr::trNew
                               << XBridgeTransactionDescr::trPending
                               << XBridgeTransactionDescr::trAccepting
                               << XBridgeTransactionDescr::trHold
                               << XBridgeTransactionDescr::trCreated
                               << XBridgeTransactionDescr::trSigned
                               << XBridgeTransactionDescr::trCommited;

    m_transactionsProxy.setAcceptedStates(transactionsAccetpedStates);

    m_transactionsList = new QTableView(this);
    m_transactionsList->setModel(&m_transactionsProxy);
    m_transactionsList->setContextMenuPolicy(Qt::CustomContextMenu);
    m_transactionsList->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_transactionsList->setSortingEnabled(true);

    connect(m_transactionsList, SIGNAL(customContextMenuRequested(QPoint)),
            this,               SLOT(onContextMenu(QPoint)));

    QHeaderView * header = m_transactionsList->horizontalHeader();
#if QT_VERSION <0x050000
    header->setResizeMode(XBridgeTransactionsModel::Total, QHeaderView::Stretch);
#else
    header->setSectionResizeMode(XBridgeTransactionsModel::Total, QHeaderView::Stretch);
#endif
#if QT_VERSION <0x050000
    header->setResizeMode(XBridgeTransactionsModel::Size, QHeaderView::Stretch);
#else
    header->setSectionResizeMode(XBridgeTransactionsModel::Size, QHeaderView::Stretch);
#endif
#if QT_VERSION <0x050000
    header->setResizeMode(XBridgeTransactionsModel::BID, QHeaderView::Stretch);
#else
    header->setSectionResizeMode(XBridgeTransactionsModel::BID, QHeaderView::Stretch);
#endif

    header->resizeSection(XBridgeTransactionsModel::Total,      80);
    header->resizeSection(XBridgeTransactionsModel::Size,       80);
    header->resizeSection(XBridgeTransactionsModel::BID,        80);
    header->resizeSection(XBridgeTransactionsModel::State,      128);
    vbox->addWidget(m_transactionsList);

    QHBoxLayout * hbox = new QHBoxLayout;

    XBridgeExchange & e = XBridgeExchange::instance();
    if (!e.isEnabled())
    {
        QPushButton * addTxBtn = new QPushButton(trUtf8("New Transaction"), this);
        // addTxBtn->setIcon(QIcon("qrc://"))
        connect(addTxBtn, SIGNAL(clicked()), this, SLOT(onNewTransaction()));
        hbox->addWidget(addTxBtn);
    }
    else
    {
        QPushButton * addTxBtn = new QPushButton(trUtf8("Exchange node"), this);
        addTxBtn->setEnabled(false);
        hbox->addWidget(addTxBtn);
    }

    hbox->addStretch();

    QPushButton * showHideButton = new QPushButton("Toggle to log", this);
    connect(showHideButton, SIGNAL(clicked()), this, SLOT(onToggleHistoricLogs()));
    hbox->addWidget(showHideButton);

    vbox->addLayout(hbox);

    m_historicTransactionsProxy.setSourceModel(&m_txModel);
    m_historicTransactionsProxy.setDynamicSortFilter(true);

    QList<XBridgeTransactionDescr::State> historicTransactionsAccetpedStates;
    historicTransactionsAccetpedStates << XBridgeTransactionDescr::trExpired
                                       << XBridgeTransactionDescr::trOffline
                                       << XBridgeTransactionDescr::trFinished
                                       << XBridgeTransactionDescr::trDropped
                                       << XBridgeTransactionDescr::trCancelled
                                       << XBridgeTransactionDescr::trInvalid;

    m_historicTransactionsProxy.setAcceptedStates(historicTransactionsAccetpedStates);

    m_historicTransactionsList = new QTableView(this);
    m_historicTransactionsList->setModel(&m_historicTransactionsProxy);
    m_historicTransactionsList->setContextMenuPolicy(Qt::CustomContextMenu);
    m_historicTransactionsList->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_historicTransactionsList->setSortingEnabled(true);

    QHeaderView * historicHeader = m_historicTransactionsList->horizontalHeader();
#if QT_VERSION <0x050000
    header->setResizeMode(XBridgeTransactionsModel::Total, QHeaderView::Stretch);
#else
    historicHeader->setSectionResizeMode(XBridgeTransactionsModel::Total, QHeaderView::Stretch);
#endif
#if QT_VERSION <0x050000
    header->setResizeMode(XBridgeTransactionsModel::Size, QHeaderView::Stretch);
#else
    historicHeader->setSectionResizeMode(XBridgeTransactionsModel::Size, QHeaderView::Stretch);
#endif
#if QT_VERSION <0x050000
    header->setResizeMode(XBridgeTransactionsModel::BID, QHeaderView::Stretch);
#else
    historicHeader->setSectionResizeMode(XBridgeTransactionsModel::BID, QHeaderView::Stretch);
#endif

    historicHeader->resizeSection(XBridgeTransactionsModel::Total,      80);
    historicHeader->resizeSection(XBridgeTransactionsModel::Size,       80);
    historicHeader->resizeSection(XBridgeTransactionsModel::BID,        80);
    historicHeader->resizeSection(XBridgeTransactionsModel::State,      128);
    vbox->addWidget(m_historicTransactionsList);

    m_logStrings = new QTextEdit(this);
    m_logStrings->setMinimumHeight(64);
    m_logStrings->setReadOnly(true);
    m_logStrings->setVisible(false);
    vbox->addWidget(m_logStrings);

    setLayout(vbox);

    xuiConnector.NotifyLogMessage.connect
            (boost::bind(&XBridgeTransactionsView::onLogString, this, _1));
}

//******************************************************************************
//******************************************************************************
QMenu * XBridgeTransactionsView::setupContextMenu(QModelIndex & index)
{
    QMenu * contextMenu = new QMenu();

    if (!m_txModel.isMyTransaction(index.row()))
    {
        QAction * acceptTransaction = new QAction(tr("&Accept transaction"), this);
        contextMenu->addAction(acceptTransaction);

        connect(acceptTransaction,   SIGNAL(triggered()),
                this,                SLOT(onAcceptTransaction()));
    }
    else
    {
        QAction * cancelTransaction = new QAction(tr("&Cancel transaction"), this);
        contextMenu->addAction(cancelTransaction);

        connect(cancelTransaction,   SIGNAL(triggered()),
                this,                SLOT(onCancelTransaction()));

        QAction * rollbackTransaction = new QAction(tr("&Rollback transaction"), this);
        contextMenu->addAction(rollbackTransaction);

        connect(rollbackTransaction, SIGNAL(triggered()),
                this,                SLOT(onRollbackTransaction()));
    }

    return contextMenu;
}

//******************************************************************************
//******************************************************************************
void XBridgeTransactionsView::onNewTransaction()
{
    m_dlg.setPendingId(uint256(), std::vector<unsigned char>());
    m_dlg.show();
}

//******************************************************************************
//******************************************************************************
void XBridgeTransactionsView::onAcceptTransaction()
{
    if (!m_contextMenuIndex.isValid())
    {
        return;
    }

    if (m_txModel.isMyTransaction(m_contextMenuIndex.row()))
    {
        return;
    }

    XBridgeTransactionDescr d = m_txModel.item(m_contextMenuIndex.row());
    if (d.state != XBridgeTransactionDescr::trPending)
    {
        return;
    }

    m_dlg.setPendingId(d.id, d.hubAddress);
    m_dlg.setFromAmount((double)d.toAmount / XBridgeTransactionDescr::COIN);
    m_dlg.setToAmount((double)d.fromAmount / XBridgeTransactionDescr::COIN);
    m_dlg.setFromCurrency(QString::fromStdString(d.toCurrency));
    m_dlg.setToCurrency(QString::fromStdString(d.fromCurrency));
    m_dlg.show();
}

//******************************************************************************
//******************************************************************************
void XBridgeTransactionsView::onCancelTransaction()
{
    if (!m_contextMenuIndex.isValid())
    {
        return;
    }

    if (QMessageBox::warning(this,
                             trUtf8("Cancel transaction"),
                             trUtf8("Are you sure?"),
                             QMessageBox::Yes | QMessageBox::Cancel,
                             QMessageBox::Cancel) != QMessageBox::Yes)
    {
        return;
    }

    if (!m_txModel.cancelTransaction(m_txModel.item(m_contextMenuIndex.row()).id))
    {
        QMessageBox::warning(this,
                             trUtf8("Cancel transaction"),
                             trUtf8("Error send cancel request"));
    }
}

//******************************************************************************
//******************************************************************************
void XBridgeTransactionsView::onRollbackTransaction()
{
    if (!m_contextMenuIndex.isValid())
    {
        return;
    }

    if (QMessageBox::warning(this,
                             trUtf8("Rollback transaction"),
                             trUtf8("Are you sure?"),
                             QMessageBox::Yes | QMessageBox::Cancel,
                             QMessageBox::Cancel) != QMessageBox::Yes)
    {
        return;
    }

    if (!m_txModel.cancelTransaction(m_txModel.item(m_contextMenuIndex.row()).id))
    {
        QMessageBox::warning(this,
                             trUtf8("Cancel transaction"),
                             trUtf8("Error send cancel request"));
    }
}

//******************************************************************************
//******************************************************************************
void XBridgeTransactionsView::onContextMenu(QPoint /*pt*/)
{
    XBridgeExchange & e = XBridgeExchange::instance();
    if (e.isEnabled())
    {
        return;
    }

    m_contextMenuIndex = m_transactionsList->selectionModel()->currentIndex();
    if (!m_contextMenuIndex.isValid())
    {
        return;
    }

    m_contextMenuIndex = m_transactionsProxy.mapToSource(m_contextMenuIndex);
    if (!m_contextMenuIndex.isValid())
    {
        return;
    }

    QMenu * contextMenu = setupContextMenu(m_contextMenuIndex);

    contextMenu->exec(QCursor::pos());
    contextMenu->deleteLater();
}

//******************************************************************************
//******************************************************************************
void XBridgeTransactionsView::onToggleHistoricLogs()
{
    QPushButton * btn = qobject_cast<QPushButton *>(sender());

    bool logsVisible = m_logStrings->isVisible();
    bool historicTrVisible = m_historicTransactionsList->isVisible();

    if(logsVisible)
        btn->setText("Toggle to log");
    else if(historicTrVisible)
        btn->setText("Toggle to history");

    m_logStrings->setVisible(!logsVisible);
    m_historicTransactionsList->setVisible(!historicTrVisible);

    if (!logsVisible)
    {
        m_logStrings->clear();

        // show, load all logs
        QFile f(QString::fromStdString(LOG::logFileName()));
        if (f.open(QIODevice::ReadOnly))
        {
            m_logStrings->insertPlainText(f.readAll());
        }
    }
}

//******************************************************************************
//******************************************************************************
void XBridgeTransactionsView::onLogString(const std::string str)
{
    const QString qstr = QString::fromStdString(str);
    m_logStrings->insertPlainText(qstr);

//    QTextCursor c = m_logStrings->textCursor();
//    c.movePosition(QTextCursor::End);
//    m_logStrings->setTextCursor(c);

//    m_logStrings->ensureCursorVisible();
}
<|endoftext|>


<commit_before>// -*- coding: us-ascii-unix -*-
// Copyright 2012 Lukas Kemmer
//
// Licensed under the Apache License, Version 2.0 (the "License"); you
// may not use this file except in compliance with the License. You
// may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.

#include <algorithm>
#include <cassert>
#include "geo/geo-func.hh"
#include "geo/points.hh"
#include "geo/scale.hh"
#include "geo/size.hh"
#include "util/iter.hh"

namespace faint{

Tri tri_from_points(const std::vector<PathPt>& points){
  if (points.empty()){
    return {Point(0,0), Angle::Zero(), Size(0,0)};
  }
  Point topLeft = points[0].p;
  Point bottomRight = topLeft;

  for (const PathPt& pt : points){
    if (pt.ClosesPath()){
      continue;
    }
    topLeft = min_coords(topLeft, pt.p);
    bottomRight = max_coords(bottomRight, pt.p);
    pt.IfCubicBezier(
      [&topLeft, &bottomRight](const CubicBezier& bezier){
        // Fixme: The bezier is always bounded by the end points and control
        // points, but this isn't the tightest boundary.
        topLeft = min_coords(topLeft, bezier.c, bezier.d);
        bottomRight = max_coords(bottomRight, bezier.c, bezier.d);
      });
  }

  return {
    topLeft,
    {bottomRight.x, topLeft.y},
    {topLeft.x, bottomRight.y}};
}

Tri tri_from_points(const std::vector<Point>& points){
  if (points.empty()){
    return {Point(0,0), Angle::Zero(), Size(0,0)};
  }
  const Point& p0 = points[0];
  coord x_min = p0.x;
  coord x_max = p0.x;
  coord y_min = p0.y;
  coord y_max = p0.y;

  for (size_t i = 0; i != points.size(); i++){
    const Point& pt = points[i];
    x_min = std::min(x_min, pt.x);
    x_max = std::max(x_max, pt.x);
    y_min = std::min(y_min, pt.y);
    y_max = std::max(y_max, pt.y);
  }
  return {Point(x_min, y_min), Point(x_max, y_min), Point(x_min, y_max)};
}

Points::Points()
  : m_tri(Point(0,0), Angle::Zero(), faint::Size(0,0)),
    m_cacheTri(m_tri)
{}

Points::Points(const Points& other)
  : m_tri(other.m_tri),
    m_points(other.m_points),
    m_cache(),
    m_cacheTri()
{}

Points::Points(const std::vector<PathPt>& points) :
  m_tri(tri_from_points(points)),
  m_points(points),
  m_cache(),
  m_cacheTri()
{}

void Points::AdjustBack(const PathPt& pt){
  PathPt& back(m_points.back());
  back = pt;
  m_tri = tri_from_points(m_points);
}

void Points::AdjustBack(const Point& p){
  PathPt& back(m_points.back());
  back.p = p;
  m_tri = tri_from_points(m_points);
}

void Points::Append(const PathPt& p){
  m_points.push_back(p);
  m_tri = tri_from_points(m_points);
}

void Points::Append(const Point& p){
  if (m_points.empty()){
    m_points.push_back(PathPt::MoveTo(p));
  }
  else{
    m_points.push_back(PathPt::LineTo(p));
  }
  m_tri = tri_from_points(m_points);
}

const PathPt& Points::Back() const{
  return m_points.back();
}

const PathPt& Points::BaBack() const{
  assert(m_points.size() >= 2);
  return m_points[m_points.size() - 2];
}

void Points::Clear(){
  m_points.clear();
  m_tri = Tri(Point(0,0), Angle::Zero(), faint::Size(0,0));
}

bool Points::Empty() const{
  return m_points.empty();
}

const PathPt& Points::Front() const{
  return m_points.front();
}

std::vector<PathPt> Points::GetPoints(const Tri& tri) const{
  if (m_cache.size() == m_points.size() && m_cacheTri == tri){
    return m_cache;
  }

  if (m_cache.size() != m_points.size()){
    m_cache = m_points;
  }
  Adj a = get_adj(m_tri, tri);
  coord p2y = m_tri.P2().y;
  coord ht = m_tri.Height();
  for (size_t i = 0; i != m_points.size(); i++){
    PathPt pt = m_points[i];
    if (ht != 0){
      pt.p.x += a.skew * ((p2y - pt.p.y) / ht) / a.scale_x; // assumes m_tri not rotated
    }
    pt.p.x += a.tr_x;
    pt.p.y += a.tr_y;

    if (ht != 0){
      pt.c.x += a.skew * ((p2y - pt.c.y) / ht) / a.scale_x; // assumes m_tri not rotated
    }
    pt.c.x += a.tr_x;
    pt.c.y += a.tr_y;

    if (ht != 0){
      pt.d.x += a.skew * ((p2y - pt.d.y) / ht) / a.scale_x; // assumes m_tri not rotated
    }
    pt.d.x += a.tr_x;
    pt.d.y += a.tr_y;

    pt = scale_point(pt, Scale(a.scale_x, a.scale_y), tri.P3());
    pt = rotate_point(pt, tri.GetAngle(), tri.P3());

    m_cache[i] = pt;
  }
  return m_cache;
}

std::vector<PathPt> Points::GetPoints() const{
  return m_points;
}

std::vector<Point> Points::GetPointsDumb() const{
  std::vector<Point> v;
  v.reserve(m_points.size());
  for (size_t i = 0; i != m_points.size(); i++){
    const PathPt& pt(m_points[i]);
    v.push_back(pt.p);
  }
  return v;
}

std::vector<Point> Points::GetPointsDumb(const Tri& tri) const{
  std::vector<PathPt> pts(GetPoints(tri));
  std::vector<Point> v;
  v.reserve(m_points.size());
  for (size_t i = 0; i != m_points.size(); i++){
    PathPt& pt(pts[i]);
    v.push_back(pt.p);
  }
  return v;
}

Tri Points::GetTri() const {
  return m_tri;
}

void Points::InsertPoint(const Tri& tri, const Point& p, int index){
  InsertPoint(tri, PathPt::LineTo(p), index);
}

void Points::InsertPoint(const Tri& tri, const PathPt& p, int index){
  assert(index >= 0);
  m_points = GetPoints(tri);
  m_points.insert(begin(m_points) + index, p);
  m_tri = tri_from_points(m_points);
}

void Points::InsertPointRaw(const PathPt& p, int index){
  assert(index >= 0);
  m_points.insert(begin(m_points) + index, p);
}

PathPt Points::PopBack(){
  PathPt p = m_points.back();
  m_points.pop_back();
  m_tri = tri_from_points(m_points);
  return p;
}

void Points::RemovePoint(const Tri& tri, int index){
  m_points = GetPoints(tri);
  m_points.erase(begin(m_points) + index);
  m_tri = tri_from_points(m_points);
}

void Points::RemovePointRaw(int index){
  m_points.erase(begin(m_points) + index);
}

void Points::SetPoint(const Tri& tri, const Point& p, int index){
  m_points = GetPoints(tri);
  m_points[to_size_t(index)].p = p;
  m_tri = tri_from_points(m_points);
}

void Points::SetPoint(const Tri& tri, const PathPt& p, int index){
  m_points = GetPoints(tri);
  m_points[to_size_t(index)] = p;
  m_tri = tri_from_points(m_points);
}

void Points::SetTri(const Tri& tri){
  m_tri = tri;
}

int Points::Size() const{
  return resigned(m_points.size());
}

Points points_from_coords(const std::vector<coord>& coords){
  const size_t n = coords.size();
  assert(n % 2 == 0);
  Points points;
  for (size_t i = 0; i != n; i+=2){
    coord x = coords[i];
    coord y = coords[i +1];
    points.Append(Point(x,y));
  }
  return points;
}

std::vector<PathPt> to_line_path(const std::vector<Point>& points){
  assert(points.size() > 1);
  std::vector<PathPt> path;
  path.reserve(points.size());
  path.push_back(PathPt::MoveTo(points.front()));
  for (const Point& p : but_first(points)){
    path.push_back(PathPt::LineTo(p));
  }
  return path;
}

} // namespace
<commit_msg>Simplified Points.cpp using make_vector.<commit_after>// -*- coding: us-ascii-unix -*-
// Copyright 2012 Lukas Kemmer
//
// Licensed under the Apache License, Version 2.0 (the "License"); you
// may not use this file except in compliance with the License. You
// may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.

#include <algorithm>
#include <cassert>
#include "geo/geo-func.hh"
#include "geo/points.hh"
#include "geo/scale.hh"
#include "geo/size.hh"
#include "util/iter.hh"
#include "util/make-vector.hh"

namespace faint{

static Point get_end_point(const PathPt& pt){
  return pt.p;
}

Tri tri_from_points(const std::vector<PathPt>& points){
  if (points.empty()){
    return {Point(0,0), Angle::Zero(), Size(0,0)};
  }
  Point topLeft = points[0].p;
  Point bottomRight = topLeft;

  for (const PathPt& pt : points){
    if (pt.ClosesPath()){
      continue;
    }
    topLeft = min_coords(topLeft, pt.p);
    bottomRight = max_coords(bottomRight, pt.p);
    pt.IfCubicBezier(
      [&topLeft, &bottomRight](const CubicBezier& bezier){
        // Fixme: The bezier is always bounded by the end points and control
        // points, but this isn't the tightest boundary.
        topLeft = min_coords(topLeft, bezier.c, bezier.d);
        bottomRight = max_coords(bottomRight, bezier.c, bezier.d);
      });
  }

  return {
    topLeft,
    {bottomRight.x, topLeft.y},
    {topLeft.x, bottomRight.y}};
}

Tri tri_from_points(const std::vector<Point>& points){
  if (points.empty()){
    return {Point(0,0), Angle::Zero(), Size(0,0)};
  }
  const Point& p0 = points[0];
  coord x_min = p0.x;
  coord x_max = p0.x;
  coord y_min = p0.y;
  coord y_max = p0.y;

  for (size_t i = 0; i != points.size(); i++){
    const Point& pt = points[i];
    x_min = std::min(x_min, pt.x);
    x_max = std::max(x_max, pt.x);
    y_min = std::min(y_min, pt.y);
    y_max = std::max(y_max, pt.y);
  }
  return {Point(x_min, y_min), Point(x_max, y_min), Point(x_min, y_max)};
}

Points::Points()
  : m_tri(Point(0,0), Angle::Zero(), faint::Size(0,0)),
    m_cacheTri(m_tri)
{}

Points::Points(const Points& other)
  : m_tri(other.m_tri),
    m_points(other.m_points),
    m_cache(),
    m_cacheTri()
{}

Points::Points(const std::vector<PathPt>& points) :
  m_tri(tri_from_points(points)),
  m_points(points),
  m_cache(),
  m_cacheTri()
{}

void Points::AdjustBack(const PathPt& pt){
  PathPt& back(m_points.back());
  back = pt;
  m_tri = tri_from_points(m_points);
}

void Points::AdjustBack(const Point& p){
  PathPt& back(m_points.back());
  back.p = p;
  m_tri = tri_from_points(m_points);
}

void Points::Append(const PathPt& p){
  m_points.push_back(p);
  m_tri = tri_from_points(m_points);
}

void Points::Append(const Point& p){
  if (m_points.empty()){
    m_points.push_back(PathPt::MoveTo(p));
  }
  else{
    m_points.push_back(PathPt::LineTo(p));
  }
  m_tri = tri_from_points(m_points);
}

const PathPt& Points::Back() const{
  return m_points.back();
}

const PathPt& Points::BaBack() const{
  assert(m_points.size() >= 2);
  return m_points[m_points.size() - 2];
}

void Points::Clear(){
  m_points.clear();
  m_tri = Tri(Point(0,0), Angle::Zero(), faint::Size(0,0));
}

bool Points::Empty() const{
  return m_points.empty();
}

const PathPt& Points::Front() const{
  return m_points.front();
}

std::vector<PathPt> Points::GetPoints(const Tri& tri) const{
  if (m_cache.size() == m_points.size() && m_cacheTri == tri){
    return m_cache;
  }

  if (m_cache.size() != m_points.size()){
    m_cache = m_points;
  }
  Adj a = get_adj(m_tri, tri);
  coord p2y = m_tri.P2().y;
  coord ht = m_tri.Height();
  for (size_t i = 0; i != m_points.size(); i++){
    PathPt pt = m_points[i];
    if (ht != 0){
      pt.p.x += a.skew * ((p2y - pt.p.y) / ht) / a.scale_x; // assumes m_tri not rotated
    }
    pt.p.x += a.tr_x;
    pt.p.y += a.tr_y;

    if (ht != 0){
      pt.c.x += a.skew * ((p2y - pt.c.y) / ht) / a.scale_x; // assumes m_tri not rotated
    }
    pt.c.x += a.tr_x;
    pt.c.y += a.tr_y;

    if (ht != 0){
      pt.d.x += a.skew * ((p2y - pt.d.y) / ht) / a.scale_x; // assumes m_tri not rotated
    }
    pt.d.x += a.tr_x;
    pt.d.y += a.tr_y;

    pt = scale_point(pt, Scale(a.scale_x, a.scale_y), tri.P3());
    pt = rotate_point(pt, tri.GetAngle(), tri.P3());

    m_cache[i] = pt;
  }
  return m_cache;
}

std::vector<PathPt> Points::GetPoints() const{
  return m_points;
}

std::vector<Point> Points::GetPointsDumb() const{
  return make_vector(m_points, get_end_point);
}

std::vector<Point> Points::GetPointsDumb(const Tri& tri) const{
  return make_vector(GetPoints(tri), get_end_point);
}

Tri Points::GetTri() const {
  return m_tri;
}

void Points::InsertPoint(const Tri& tri, const Point& p, int index){
  InsertPoint(tri, PathPt::LineTo(p), index);
}

void Points::InsertPoint(const Tri& tri, const PathPt& p, int index){
  assert(index >= 0);
  m_points = GetPoints(tri);
  m_points.insert(begin(m_points) + index, p);
  m_tri = tri_from_points(m_points);
}

void Points::InsertPointRaw(const PathPt& p, int index){
  assert(index >= 0);
  m_points.insert(begin(m_points) + index, p);
}

PathPt Points::PopBack(){
  PathPt p = m_points.back();
  m_points.pop_back();
  m_tri = tri_from_points(m_points);
  return p;
}

void Points::RemovePoint(const Tri& tri, int index){
  m_points = GetPoints(tri);
  m_points.erase(begin(m_points) + index);
  m_tri = tri_from_points(m_points);
}

void Points::RemovePointRaw(int index){
  m_points.erase(begin(m_points) + index);
}

void Points::SetPoint(const Tri& tri, const Point& p, int index){
  m_points = GetPoints(tri);
  m_points[to_size_t(index)].p = p;
  m_tri = tri_from_points(m_points);
}

void Points::SetPoint(const Tri& tri, const PathPt& p, int index){
  m_points = GetPoints(tri);
  m_points[to_size_t(index)] = p;
  m_tri = tri_from_points(m_points);
}

void Points::SetTri(const Tri& tri){
  m_tri = tri;
}

int Points::Size() const{
  return resigned(m_points.size());
}

Points points_from_coords(const std::vector<coord>& coords){
  const size_t n = coords.size();
  assert(n % 2 == 0);
  Points points;
  for (size_t i = 0; i != n; i+=2){
    coord x = coords[i];
    coord y = coords[i +1];
    points.Append(Point(x,y));
  }
  return points;
}

std::vector<PathPt> to_line_path(const std::vector<Point>& points){
  assert(points.size() > 1);
  std::vector<PathPt> path;
  path.reserve(points.size());
  path.push_back(PathPt::MoveTo(points.front()));
  for (const Point& p : but_first(points)){
    path.push_back(PathPt::LineTo(p));
  }
  return path;
}

} // namespace
<|endoftext|>


<commit_before>#include <iostream>

void while_Demo();

void for_Demo();

void notQuantitativeValue();

int main() {

  // 1.4.1 while
  while_Demo();
  // 1.4.2 for
  for_Demo();
  // 1.4.3 读取数量不定的输入数据
  notQuantitativeValue();

  std::cout << "Section 1.4 end" << std::endl;

  return 0;
}

/**
 *  读取数量不定的输入数据，
 *  只有输入换行符(比如：\n)或者非法字符（非数字，但直接回车不会停止）的时候才会停止接收数据，输出运算结果
 *  @EOF EOF 是 end of file 的缩写，windows环境是：ctrl+Z，unix 环境是：ctrl+D，即可模拟（？）EOF
 */
void notQuantitativeValue() {
  std::cout << "【notQuantitativeValue】=> 请每次输入一个数据，并回车（想结束输入参数的时候输入 EOF 或者输入非数字字符即可）：" << std::endl;
  int sum = 0, value = 0;
  while (std::cin >> value) { // 使用istream对象作为条件，其效果是检测流的状态
    sum += value;
  }
  std::cout << "Sum is " << sum << std::endl;
}

/**
 * for 语句 范例
 */
void for_Demo() {
  int sum = 0;
  for (int value = 0; value <= 10; ++value) {
    sum += value;
  }
  std::cout << "[for_Demo] => Sum of 1 to 10 inclusive is " << sum << std::endl;
}

/**
 * while 语句 范例
 */
void while_Demo() {
  int sum = 0, value = 1;
  while (value <= 10) {
    sum += value;
    ++value;
  } // 上面两句可以合并：sum += value++;
  std::cout << "[while_Demo] => Sum of 1 to 10 inclusive is " << sum << std::endl;
}

<commit_msg>Section 1.4 control flow<commit_after>#include <iostream>

void while_Demo();

void for_Demo();

void notQuantitativeValue();

void if_Demo();

int main() {

  // 1.4.1 while
  while_Demo();
  // 1.4.2 for
  for_Demo();

  // 需要注意点是，1.4.3 和 1.4.4 不能同时运行，因为1.4.3结束输入的时候，1.4.4就不能接收到输入数据了

  // 1.4.3 读取数量不定的输入数据
  notQuantitativeValue();
  // 1.4.4 if语句
  if_Demo();

  std::cout << "Section 1.4 end" << std::endl;

  return 0;
}

/**
 * if语句，计算连续的相同数字的个数
 */
void if_Demo() {
  int currVal = 0, val = 0;
  if (std::__1::cin >> currVal) {
    int cnt = 1;
    while (std::__1::cin >> val) {
      if (val == currVal) {
        ++cnt;
      } else {
        std::__1::cout << currVal << " occurs " << cnt << " times." << std::__1::endl;
        currVal = val;
        cnt = 1;
      }
    } // while 结束
    std::__1::cout << currVal << " occurs " << cnt << " times." << std::__1::endl;
  } // if 结束

}

/**
 *  读取数量不定的输入数据，
 *  只有输入换行符(比如：\n)或者非法字符（非数字，但直接回车不会停止）的时候才会停止接收数据，输出运算结果
 *  @EOF EOF 是 end of file 的缩写，windows环境是：ctrl+Z，unix 环境是：ctrl+D，即可模拟（？）EOF
 */
void notQuantitativeValue() {
  std::cout << "【notQuantitativeValue】=> 请每次输入一个数据，并回车（想结束输入参数的时候输入 EOF 或者输入非数字字符即可）：" << std::endl;
  int sum = 0, value = 0;
  while (std::cin >> value) { // 使用istream对象作为条件，其效果是检测流的状态
    sum += value;
  }
  std::cout << "Sum is " << sum << std::endl;
}

/**
 * for 语句 范例
 */
void for_Demo() {
  int sum = 0;
  for (int value = 0; value <= 10; ++value) {
    sum += value;
  }
  std::cout << "[for_Demo] => Sum of 1 to 10 inclusive is " << sum << std::endl;
}

/**
 * while 语句 范例
 */
void while_Demo() {
  int sum = 0, value = 1;
  while (value <= 10) {
    sum += value;
    ++value;
  } // 上面两句可以合并：sum += value++;
  std::cout << "[while_Demo] => Sum of 1 to 10 inclusive is " << sum << std::endl;
}

<|endoftext|>