<commit_before>#include "gamelib/core/Game.hpp"
#include <SFML/Graphics.hpp>
#include <climits>
#include "gamelib/core/GameState.hpp"
#include "gamelib/utils/log.hpp"
#include "gamelib/core/event/EventManager.hpp"
#include "gamelib/events/SFMLEvent.hpp"
#include "gamelib/core/input/InputSystem.hpp"

namespace gamelib
{
    Game::Game() :
        bgcolor(sf::Color::Black),
        closebutton(true),
        escclose(true),
        unfocusPause(true),
        _frametime(0),
        _rendertime(0),
        _updatetime(0),
        _size(640, 480),
        _maxfps(60),
        _title("Unnamed Game"),
        _repeatkeys(false),
        _vsync(true)
    {
        auto setSize = +[](const math::Vec2i* val, Game* self) {
            self->resize(sf::Vector2u(val->x, val->y));
        };
        auto setFPS = +[](const int* val, Game* self) {
            self->_maxfps = *val;
            if (self->_window.isOpen())
                self->_window.setFramerateLimit(*val);
        };
        auto setVsync = +[](const bool* val, Game* self) {
            self->_vsync = *val;
            if (self->_window.isOpen())
                self->_window.setVerticalSyncEnabled(*val);
        };
        auto setTitle = +[](const std::string* val, Game* self) {
            self->_title = *val;
            if (self->_window.isOpen())
                self->_window.setTitle(*val);
        };
        auto setRepeat = +[](const bool* val, Game* self) {
            self->_repeatkeys = *val;
            if (self->_window.isOpen())
                self->_window.setKeyRepeatEnabled(*val);
        };

        _props.registerProperty("bgcolor", bgcolor);
        _props.registerProperty("closebutton", closebutton);
        _props.registerProperty("escclose", escclose);
        _props.registerProperty("unfocusPause", unfocusPause);
        _props.registerProperty("size", _size, setSize, this);
        _props.registerProperty("maxfps", _maxfps, setFPS, this, 0, INT_MAX);
        _props.registerProperty("vsync", _vsync, setVsync, this);
        _props.registerProperty("title", _title, setTitle, this);
        _props.registerProperty("repeatkeys", _repeatkeys, setRepeat, this);
    }

    Game::~Game()
    {
        destroy();
    }

    bool Game::init()
    {
        LOG("Initializing game...");
        _window.create(sf::VideoMode(_size.x, _size.y), _title, sf::Style::Close);
        _window.setFramerateLimit(_maxfps);
        _window.setVerticalSyncEnabled(_vsync);
        _window.setKeyRepeatEnabled(_repeatkeys);
        return true;
    }

    void Game::run()
    {
        sf::Clock clock, detailclock;
        sf::Event ev;

        while (_window.isOpen())
        {
            clock.restart();
            detailclock.restart();

            auto inputsys = getSubsystem<InputSystem>();
            if (inputsys)
                inputsys->beginFrame();

            while (_window.pollEvent(ev))
            {
                if (inputsys)
                    inputsys->process(ev);

                auto evmgr = getSubsystem<EventManager>();
                if (evmgr)
                    evmgr->triggerEvent(SFMLEvent::create(ev));
            }

            if (_window.hasFocus() || !unfocusPause)
            {
                bool frozen = false;
                for (auto it = _states.rbegin(), end = _states.rend(); it != end; ++it)
                {
                    auto state = (*it).get();
                    if (state->flags & gamestate_paused)
                        continue;

                    if (!frozen || state->flags & gamestate_forceupdate)
                        state->update(_frametime);

                    if (state->flags & gamestate_freeze)
                        frozen = true;
                }

                if (escclose && inputsys && inputsys->isKeyPressed(sf::Keyboard::Escape))
                {
                    close();
                    return;
                }
            }

            _updatetime = detailclock.getElapsedTime().asMilliseconds() / 1000.f;
            detailclock.restart();

            _window.resetGLStates(); // without this things start randomly disappearing
            _window.clear(bgcolor);

            if (_vsync)
                detailclock.restart();

            for (auto& i : _states)
                i->render(_window);

            // TODO: implement own fps capping.
            // SFML caps inside window.display(), so it's impossible to get the exact render time
            if (!_vsync)
                _rendertime = detailclock.getElapsedTime().asMilliseconds() / 1000.0f;

            _window.display();

            if (_vsync)
                _rendertime = detailclock.getElapsedTime().asMilliseconds() / 1000.0f;

            // Get elapsed time
            _frametime = clock.getElapsedTime().asMilliseconds() / 1000.0f;
        }
    }

    void Game::close()
    {
        if (_window.isOpen())
        {
            _window.close();
            LOG_DEBUG("Game window closed");
        }
    }

    void Game::destroy()
    {
        close();
        if (!_states.empty())
        {
            LOG_DEBUG("Closing game states...");
            for (auto& i : _states)
                i->quit();
            _states.clear();
        }
    }

    bool Game::loadFromJson(const Json::Value& node)
    {
        return _props.loadFromJson(node);
    }

    void Game::writeToJson(Json::Value& node) const
    {
        _props.writeToJson(node);
    }

    void Game::pushState(std::unique_ptr<GameState> state)
    {
        if (!state->init(this))
        {
            LOG_ERROR("Failed to initialize game state");
            return;
        }
        _states.push_back(std::move(state));
        LOG_DEBUG("Game state added");
    }

    void Game::popState()
    {
        _states.back()->quit();
        _states.pop_back();
    }

    GameState* Game::pullState() const
    {
        return _states.back().get();
    }

    float Game::getFrametime() const
    {
        return _frametime;
    }

    float Game::getRealFrametime() const
    {
        return _rendertime + _updatetime;
    }

    float Game::getRenderTime() const
    {
        return _rendertime;
    }

    float Game::getUpdateTime() const
    {
        return _updatetime;
    }

    sf::RenderWindow& Game::getWindow()
    {
        return _window;
    }

    const PropertyContainer& Game::getProperties() const
    {
        return _props;
    }

    void Game::resize(const sf::Vector2u& size)
    {
        if (size.x <= 0 || size.y <= 0)
        {
            LOG_ERROR("Invalid window size: ", size.x, "x", size.y);
            return;
        }

        _size.fill(size.x, size.y);

        if (_window.isOpen())
        {
            auto diff = size - _window.getSize();
            auto pos = _window.getPosition();
            pos.x -= diff.x / 2;
            pos.y -= diff.y / 2;

            _window.setSize(size);
            _window.setPosition(pos);
            _window.setView(sf::View(sf::FloatRect(0, 0, size.x, size.y)));
        }

        // Don't create a new window, as it could lead to problems
        // if (size != _window.getSize())
        // {
        //     _window.close();
        //     _window.create(sf::VideoMode(size.x, size.y), game_title, sf::Style::Close);
        // }
    }
}

<commit_msg>Fix closebutton not working<commit_after>#include "gamelib/core/Game.hpp"
#include <SFML/Graphics.hpp>
#include <climits>
#include "gamelib/core/GameState.hpp"
#include "gamelib/utils/log.hpp"
#include "gamelib/core/event/EventManager.hpp"
#include "gamelib/events/SFMLEvent.hpp"
#include "gamelib/core/input/InputSystem.hpp"

namespace gamelib
{
    Game::Game() :
        bgcolor(sf::Color::Black),
        closebutton(true),
        escclose(true),
        unfocusPause(true),
        _frametime(0),
        _rendertime(0),
        _updatetime(0),
        _size(640, 480),
        _maxfps(60),
        _title("Unnamed Game"),
        _repeatkeys(false),
        _vsync(true)
    {
        auto setSize = +[](const math::Vec2i* val, Game* self) {
            self->resize(sf::Vector2u(val->x, val->y));
        };
        auto setFPS = +[](const int* val, Game* self) {
            self->_maxfps = *val;
            if (self->_window.isOpen())
                self->_window.setFramerateLimit(*val);
        };
        auto setVsync = +[](const bool* val, Game* self) {
            self->_vsync = *val;
            if (self->_window.isOpen())
                self->_window.setVerticalSyncEnabled(*val);
        };
        auto setTitle = +[](const std::string* val, Game* self) {
            self->_title = *val;
            if (self->_window.isOpen())
                self->_window.setTitle(*val);
        };
        auto setRepeat = +[](const bool* val, Game* self) {
            self->_repeatkeys = *val;
            if (self->_window.isOpen())
                self->_window.setKeyRepeatEnabled(*val);
        };

        _props.registerProperty("bgcolor", bgcolor);
        _props.registerProperty("closebutton", closebutton);
        _props.registerProperty("escclose", escclose);
        _props.registerProperty("unfocusPause", unfocusPause);
        _props.registerProperty("size", _size, setSize, this);
        _props.registerProperty("maxfps", _maxfps, setFPS, this, 0, INT_MAX);
        _props.registerProperty("vsync", _vsync, setVsync, this);
        _props.registerProperty("title", _title, setTitle, this);
        _props.registerProperty("repeatkeys", _repeatkeys, setRepeat, this);
    }

    Game::~Game()
    {
        destroy();
    }

    bool Game::init()
    {
        LOG("Initializing game...");
        _window.create(sf::VideoMode(_size.x, _size.y), _title, sf::Style::Close);
        _window.setFramerateLimit(_maxfps);
        _window.setVerticalSyncEnabled(_vsync);
        _window.setKeyRepeatEnabled(_repeatkeys);
        return true;
    }

    void Game::run()
    {
        sf::Clock clock, detailclock;
        sf::Event ev;

        while (_window.isOpen())
        {
            clock.restart();
            detailclock.restart();

            auto inputsys = getSubsystem<InputSystem>();
            if (inputsys)
                inputsys->beginFrame();

            while (_window.pollEvent(ev))
            {
                if (inputsys)
                    inputsys->process(ev);

                auto evmgr = getSubsystem<EventManager>();
                if (evmgr)
                    evmgr->triggerEvent(SFMLEvent::create(ev));

                if (closebutton && ev.type == sf::Event::Closed)
                {
                    close();
                    return;
                }
            }

            if (_window.hasFocus() || !unfocusPause)
            {
                bool frozen = false;
                for (auto it = _states.rbegin(), end = _states.rend(); it != end; ++it)
                {
                    auto state = (*it).get();
                    if (state->flags & gamestate_paused)
                        continue;

                    if (!frozen || state->flags & gamestate_forceupdate)
                        state->update(_frametime);

                    if (state->flags & gamestate_freeze)
                        frozen = true;
                }

                if (escclose && inputsys && inputsys->isKeyPressed(sf::Keyboard::Escape))
                {
                    close();
                    return;
                }
            }

            _updatetime = detailclock.getElapsedTime().asMilliseconds() / 1000.f;
            detailclock.restart();

            _window.resetGLStates(); // without this things start randomly disappearing
            _window.clear(bgcolor);

            if (_vsync)
                detailclock.restart();

            for (auto& i : _states)
                i->render(_window);

            // TODO: implement own fps capping.
            // SFML caps inside window.display(), so it's impossible to get the exact render time
            if (!_vsync)
                _rendertime = detailclock.getElapsedTime().asMilliseconds() / 1000.0f;

            _window.display();

            if (_vsync)
                _rendertime = detailclock.getElapsedTime().asMilliseconds() / 1000.0f;

            // Get elapsed time
            _frametime = clock.getElapsedTime().asMilliseconds() / 1000.0f;
        }
    }

    void Game::close()
    {
        if (_window.isOpen())
        {
            _window.close();
            LOG_DEBUG("Game window closed");
        }
    }

    void Game::destroy()
    {
        close();
        if (!_states.empty())
        {
            LOG_DEBUG("Closing game states...");
            for (auto& i : _states)
                i->quit();
            _states.clear();
        }
    }

    bool Game::loadFromJson(const Json::Value& node)
    {
        return _props.loadFromJson(node);
    }

    void Game::writeToJson(Json::Value& node) const
    {
        _props.writeToJson(node);
    }

    void Game::pushState(std::unique_ptr<GameState> state)
    {
        if (!state->init(this))
        {
            LOG_ERROR("Failed to initialize game state");
            return;
        }
        _states.push_back(std::move(state));
        LOG_DEBUG("Game state added");
    }

    void Game::popState()
    {
        _states.back()->quit();
        _states.pop_back();
    }

    GameState* Game::pullState() const
    {
        return _states.back().get();
    }

    float Game::getFrametime() const
    {
        return _frametime;
    }

    float Game::getRealFrametime() const
    {
        return _rendertime + _updatetime;
    }

    float Game::getRenderTime() const
    {
        return _rendertime;
    }

    float Game::getUpdateTime() const
    {
        return _updatetime;
    }

    sf::RenderWindow& Game::getWindow()
    {
        return _window;
    }

    const PropertyContainer& Game::getProperties() const
    {
        return _props;
    }

    void Game::resize(const sf::Vector2u& size)
    {
        if (size.x <= 0 || size.y <= 0)
        {
            LOG_ERROR("Invalid window size: ", size.x, "x", size.y);
            return;
        }

        _size.fill(size.x, size.y);

        if (_window.isOpen())
        {
            auto diff = size - _window.getSize();
            auto pos = _window.getPosition();
            pos.x -= diff.x / 2;
            pos.y -= diff.y / 2;

            _window.setSize(size);
            _window.setPosition(pos);
            _window.setView(sf::View(sf::FloatRect(0, 0, size.x, size.y)));
        }

        // Don't create a new window, as it could lead to problems
        // if (size != _window.getSize())
        // {
        //     _window.close();
        //     _window.create(sf::VideoMode(size.x, size.y), game_title, sf::Style::Close);
        // }
    }
}

<|endoftext|>


<commit_before>// Copyright (c) 2011-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "bitcoinamountfield.h"

#include "bitcoinunits.h"
#include "guiconstants.h"
#include "qvaluecombobox.h"

#include <QApplication>
#include <QAbstractSpinBox>
#include <QHBoxLayout>
#include <QKeyEvent>
#include <QLineEdit>

/** QSpinBox that uses fixed-point numbers internally and uses our own
 * formatting/parsing functions.
 */
class AmountSpinBox: public QAbstractSpinBox
{
    Q_OBJECT
public:
    explicit AmountSpinBox(QWidget *parent):
        QAbstractSpinBox(parent),
        currentUnit(BitcoinUnits::BTC),
        singleStep(100000) // satoshis
    {
        setAlignment(Qt::AlignRight);

        connect(lineEdit(), SIGNAL(textEdited(QString)), this, SIGNAL(valueChanged()));
    }

    QValidator::State validate(QString &text, int &pos) const
    {
        if(text.isEmpty())
            return QValidator::Intermediate;
        bool valid = false;
        parse(text, &valid);
        /* Make sure we return Intermediate so that fixup() is called on defocus */
        return valid ? QValidator::Intermediate : QValidator::Invalid;
    }

    void fixup(QString &input) const
    {
        bool valid = false;
        CAmount val = parse(input, &valid);
        if(valid)
        {
            input = BitcoinUnits::format(currentUnit, val, false, BitcoinUnits::separatorAlways);
            lineEdit()->setText(input);
        }
    }

    CAmount value(bool *valid_out=0) const
    {
        return parse(text(), valid_out);
    }

    void setValue(const CAmount& value)
    {
        lineEdit()->setText(BitcoinUnits::format(currentUnit, value, false, BitcoinUnits::separatorAlways));
        emit valueChanged();
    }

    void stepBy(int steps)
    {
        bool valid = false;
        CAmount val = value(&valid);
        val = val + steps * singleStep;
        val = qMin(qMax(val, CAmount(0)), BitcoinUnits::maxMoney());
        setValue(val);
    }

    StepEnabled stepEnabled() const
    {
        StepEnabled rv = 0;
        if(text().isEmpty()) // Allow step-up with empty field
            return StepUpEnabled;
        bool valid = false;
        CAmount val = value(&valid);
        if(valid)
        {
            if(val > 0)
                rv |= StepDownEnabled;
            if(val < BitcoinUnits::maxMoney())
                rv |= StepUpEnabled;
        }
        return rv;
    }

    void setDisplayUnit(int unit)
    {
        bool valid = false;
        CAmount val = value(&valid);

        currentUnit = unit;

        if(valid)
            setValue(val);
        else
            clear();
    }

    void setSingleStep(const CAmount& step)
    {
        singleStep = step;
    }

    QSize minimumSizeHint() const
    {
        if(cachedMinimumSizeHint.isEmpty())
        {
            ensurePolished();

            const QFontMetrics fm(fontMetrics());
            int h = lineEdit()->minimumSizeHint().height();
            int w = fm.width(BitcoinUnits::format(BitcoinUnits::BTC, BitcoinUnits::maxMoney(), false, BitcoinUnits::separatorAlways));
            w += 2; // cursor blinking space

            QStyleOptionSpinBox opt;
            initStyleOption(&opt);
            QSize hint(w, h);
            QSize extra(35, 6);
            opt.rect.setSize(hint + extra);
            extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt,
                                                    QStyle::SC_SpinBoxEditField, this).size();
            // get closer to final result by repeating the calculation
            opt.rect.setSize(hint + extra);
            extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt,
                                                    QStyle::SC_SpinBoxEditField, this).size();
            hint += extra;
            hint.setHeight(h);

            opt.rect = rect();

            cachedMinimumSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this)
                                    .expandedTo(QApplication::globalStrut());
        }
        return cachedMinimumSizeHint;
    }
private:
    int currentUnit;
    CAmount singleStep;
    mutable QSize cachedMinimumSizeHint;

    /**
     * Parse a string into a number of base monetary units and
     * return validity.
     * @note Must return 0 if !valid.
     */
    CAmount parse(const QString &text, bool *valid_out=0) const
    {
        CAmount val = 0;
        bool valid = BitcoinUnits::parse(currentUnit, text, &val);
        if(valid)
        {
            if(val < 0 || val > BitcoinUnits::maxMoney())
                valid = false;
        }
        if(valid_out)
            *valid_out = valid;
        return valid ? val : 0;
    }

protected:
    bool event(QEvent *event)
    {
        if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)
        {
            QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
            if (keyEvent->key() == Qt::Key_Comma)
            {
                // Translate a comma into a period
                QKeyEvent periodKeyEvent(event->type(), Qt::Key_Period, keyEvent->modifiers(), ".", keyEvent->isAutoRepeat(), keyEvent->count());
                return QAbstractSpinBox::event(&periodKeyEvent);
            }
        }
        return QAbstractSpinBox::event(event);
    }

signals:
    void valueChanged();
};

#include "bitcoinamountfield.moc"

BitcoinAmountField::BitcoinAmountField(QWidget *parent) :
    QWidget(parent),
    amount(0)
{
    amount = new AmountSpinBox(this);
    amount->setLocale(QLocale::c());
    amount->installEventFilter(this);
    amount->setMaximumWidth(170);

    QHBoxLayout *layout = new QHBoxLayout(this);
    layout->addWidget(amount);
    unit = new QValueComboBox(this);
    unit->setModel(new BitcoinUnits(this));
    layout->addWidget(unit);
    layout->addStretch(1);
    layout->setContentsMargins(0,0,0,0);

    setLayout(layout);

    setFocusPolicy(Qt::TabFocus);
    setFocusProxy(amount);

    // If one if the widgets changes, the combined content changes as well
    connect(amount, SIGNAL(valueChanged()), this, SIGNAL(valueChanged()));
    connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int)));

    // Set default based on configuration
    unitChanged(unit->currentIndex());
}

void BitcoinAmountField::clear()
{
    amount->clear();
    unit->setCurrentIndex(0);
}

void BitcoinAmountField::setEnabled(bool fEnabled)
{
    amount->setEnabled(fEnabled);
    unit->setEnabled(fEnabled);
}

bool BitcoinAmountField::validate()
{
    bool valid = false;
    value(&valid);
    setValid(valid);
    return valid;
}

void BitcoinAmountField::setValid(bool valid)
{
    if (valid)
        amount->setStyleSheet("");
    else
        amount->setStyleSheet(STYLE_INVALID);
}

bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event)
{
    if (event->type() == QEvent::FocusIn)
    {
        // Clear invalid flag on focus
        setValid(true);
    }
    return QWidget::eventFilter(object, event);
}

QWidget *BitcoinAmountField::setupTabChain(QWidget *prev)
{
    QWidget::setTabOrder(prev, amount);
    QWidget::setTabOrder(amount, unit);
    return unit;
}

CAmount BitcoinAmountField::value(bool *valid_out) const
{
    return amount->value(valid_out);
}

void BitcoinAmountField::setValue(const CAmount& value)
{
    amount->setValue(value);
}

void BitcoinAmountField::setReadOnly(bool fReadOnly)
{
    amount->setReadOnly(fReadOnly);
    unit->setEnabled(!fReadOnly);
}

void BitcoinAmountField::unitChanged(int idx)
{
    // Use description tooltip for current unit for the combobox
    unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString());

    // Determine new unit ID
    int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt();

    amount->setDisplayUnit(newUnit);
}

void BitcoinAmountField::setDisplayUnit(int newUnit)
{
    unit->setValue(newUnit);
}

void BitcoinAmountField::setSingleStep(const CAmount& step)
{
    amount->setSingleStep(step);
}
<commit_msg>[Qt] don't allow amount changes when AmountSpinBox is read-only<commit_after>// Copyright (c) 2011-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "bitcoinamountfield.h"

#include "bitcoinunits.h"
#include "guiconstants.h"
#include "qvaluecombobox.h"

#include <QApplication>
#include <QAbstractSpinBox>
#include <QHBoxLayout>
#include <QKeyEvent>
#include <QLineEdit>

/** QSpinBox that uses fixed-point numbers internally and uses our own
 * formatting/parsing functions.
 */
class AmountSpinBox: public QAbstractSpinBox
{
    Q_OBJECT

public:
    explicit AmountSpinBox(QWidget *parent):
        QAbstractSpinBox(parent),
        currentUnit(BitcoinUnits::BTC),
        singleStep(100000) // satoshis
    {
        setAlignment(Qt::AlignRight);

        connect(lineEdit(), SIGNAL(textEdited(QString)), this, SIGNAL(valueChanged()));
    }

    QValidator::State validate(QString &text, int &pos) const
    {
        if(text.isEmpty())
            return QValidator::Intermediate;
        bool valid = false;
        parse(text, &valid);
        /* Make sure we return Intermediate so that fixup() is called on defocus */
        return valid ? QValidator::Intermediate : QValidator::Invalid;
    }

    void fixup(QString &input) const
    {
        bool valid = false;
        CAmount val = parse(input, &valid);
        if(valid)
        {
            input = BitcoinUnits::format(currentUnit, val, false, BitcoinUnits::separatorAlways);
            lineEdit()->setText(input);
        }
    }

    CAmount value(bool *valid_out=0) const
    {
        return parse(text(), valid_out);
    }

    void setValue(const CAmount& value)
    {
        lineEdit()->setText(BitcoinUnits::format(currentUnit, value, false, BitcoinUnits::separatorAlways));
        emit valueChanged();
    }

    void stepBy(int steps)
    {
        bool valid = false;
        CAmount val = value(&valid);
        val = val + steps * singleStep;
        val = qMin(qMax(val, CAmount(0)), BitcoinUnits::maxMoney());
        setValue(val);
    }

    void setDisplayUnit(int unit)
    {
        bool valid = false;
        CAmount val = value(&valid);

        currentUnit = unit;

        if(valid)
            setValue(val);
        else
            clear();
    }

    void setSingleStep(const CAmount& step)
    {
        singleStep = step;
    }

    QSize minimumSizeHint() const
    {
        if(cachedMinimumSizeHint.isEmpty())
        {
            ensurePolished();

            const QFontMetrics fm(fontMetrics());
            int h = lineEdit()->minimumSizeHint().height();
            int w = fm.width(BitcoinUnits::format(BitcoinUnits::BTC, BitcoinUnits::maxMoney(), false, BitcoinUnits::separatorAlways));
            w += 2; // cursor blinking space

            QStyleOptionSpinBox opt;
            initStyleOption(&opt);
            QSize hint(w, h);
            QSize extra(35, 6);
            opt.rect.setSize(hint + extra);
            extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt,
                                                    QStyle::SC_SpinBoxEditField, this).size();
            // get closer to final result by repeating the calculation
            opt.rect.setSize(hint + extra);
            extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt,
                                                    QStyle::SC_SpinBoxEditField, this).size();
            hint += extra;
            hint.setHeight(h);

            opt.rect = rect();

            cachedMinimumSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this)
                                    .expandedTo(QApplication::globalStrut());
        }
        return cachedMinimumSizeHint;
    }

private:
    int currentUnit;
    CAmount singleStep;
    mutable QSize cachedMinimumSizeHint;

    /**
     * Parse a string into a number of base monetary units and
     * return validity.
     * @note Must return 0 if !valid.
     */
    CAmount parse(const QString &text, bool *valid_out=0) const
    {
        CAmount val = 0;
        bool valid = BitcoinUnits::parse(currentUnit, text, &val);
        if(valid)
        {
            if(val < 0 || val > BitcoinUnits::maxMoney())
                valid = false;
        }
        if(valid_out)
            *valid_out = valid;
        return valid ? val : 0;
    }

protected:
    bool event(QEvent *event)
    {
        if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)
        {
            QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
            if (keyEvent->key() == Qt::Key_Comma)
            {
                // Translate a comma into a period
                QKeyEvent periodKeyEvent(event->type(), Qt::Key_Period, keyEvent->modifiers(), ".", keyEvent->isAutoRepeat(), keyEvent->count());
                return QAbstractSpinBox::event(&periodKeyEvent);
            }
        }
        return QAbstractSpinBox::event(event);
    }

    StepEnabled stepEnabled() const
    {
        StepEnabled rv = 0;
        if (isReadOnly()) // Disable steps when AmountSpinBox is read-only
            return StepNone;
        if(text().isEmpty()) // Allow step-up with empty field
            return StepUpEnabled;
        bool valid = false;
        CAmount val = value(&valid);
        if(valid)
        {
            if(val > 0)
                rv |= StepDownEnabled;
            if(val < BitcoinUnits::maxMoney())
                rv |= StepUpEnabled;
        }
        return rv;
    }

signals:
    void valueChanged();
};

#include "bitcoinamountfield.moc"

BitcoinAmountField::BitcoinAmountField(QWidget *parent) :
    QWidget(parent),
    amount(0)
{
    amount = new AmountSpinBox(this);
    amount->setLocale(QLocale::c());
    amount->installEventFilter(this);
    amount->setMaximumWidth(170);

    QHBoxLayout *layout = new QHBoxLayout(this);
    layout->addWidget(amount);
    unit = new QValueComboBox(this);
    unit->setModel(new BitcoinUnits(this));
    layout->addWidget(unit);
    layout->addStretch(1);
    layout->setContentsMargins(0,0,0,0);

    setLayout(layout);

    setFocusPolicy(Qt::TabFocus);
    setFocusProxy(amount);

    // If one if the widgets changes, the combined content changes as well
    connect(amount, SIGNAL(valueChanged()), this, SIGNAL(valueChanged()));
    connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int)));

    // Set default based on configuration
    unitChanged(unit->currentIndex());
}

void BitcoinAmountField::clear()
{
    amount->clear();
    unit->setCurrentIndex(0);
}

void BitcoinAmountField::setEnabled(bool fEnabled)
{
    amount->setEnabled(fEnabled);
    unit->setEnabled(fEnabled);
}

bool BitcoinAmountField::validate()
{
    bool valid = false;
    value(&valid);
    setValid(valid);
    return valid;
}

void BitcoinAmountField::setValid(bool valid)
{
    if (valid)
        amount->setStyleSheet("");
    else
        amount->setStyleSheet(STYLE_INVALID);
}

bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event)
{
    if (event->type() == QEvent::FocusIn)
    {
        // Clear invalid flag on focus
        setValid(true);
    }
    return QWidget::eventFilter(object, event);
}

QWidget *BitcoinAmountField::setupTabChain(QWidget *prev)
{
    QWidget::setTabOrder(prev, amount);
    QWidget::setTabOrder(amount, unit);
    return unit;
}

CAmount BitcoinAmountField::value(bool *valid_out) const
{
    return amount->value(valid_out);
}

void BitcoinAmountField::setValue(const CAmount& value)
{
    amount->setValue(value);
}

void BitcoinAmountField::setReadOnly(bool fReadOnly)
{
    amount->setReadOnly(fReadOnly);
    unit->setEnabled(!fReadOnly);
}

void BitcoinAmountField::unitChanged(int idx)
{
    // Use description tooltip for current unit for the combobox
    unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString());

    // Determine new unit ID
    int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt();

    amount->setDisplayUnit(newUnit);
}

void BitcoinAmountField::setDisplayUnit(int newUnit)
{
    unit->setValue(newUnit);
}

void BitcoinAmountField::setSingleStep(const CAmount& step)
{
    amount->setSingleStep(step);
}
<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2016 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <inviwo/core/common/inviwoapplication.h>
#include <inviwo/core/network/processornetwork.h>
#include <inviwo/qt/editor/inviwomainwindow.h>
#include <inviwo/qt/editor/undomanager.h>
#include <inviwo/core/util/raiiutils.h>

#include <warn/push>
#include <warn/ignore/all>
#include <QAction>
#include <QEvent>
#include <QApplication>
#include <QGuiApplication>

#include <warn/pop>

namespace inviwo {

UndoManager::UndoManager(InviwoMainWindow* mainWindow) : mainWindow_(mainWindow) {
    mainWindow_->getInviwoApplication()->getProcessorNetwork()->addObserver(this);

    interactionEndCallback_ =
        mainWindow_->getInviwoApplication()->getInteractionStateManager().onInteractionEnd(
            [&]() { if (dirty_) pushState(); });

    undoAction_ = new QAction(QAction::tr("&Undo"), mainWindow_);
    undoAction_->setShortcut(QKeySequence::Undo);
    undoAction_->connect(undoAction_, &QAction::triggered, [&]() {
        undoState();
    });

    redoAction_ = new QAction(QAction::tr("&Redo"), mainWindow_);
    redoAction_->setShortcut(QKeySequence::Redo);
    redoAction_->connect(redoAction_, &QAction::triggered, [&]() {
        redoState();
    });

    updateActions();

    pushState();
}

void UndoManager::pushState() {
    if (isRestoring) return;
    if (mainWindow_->getInviwoApplication()->getProcessorNetwork()->islocked()) return;
    if (mainWindow_->getInviwoApplication()->getInteractionStateManager().isInteracting()) return;

    auto path = mainWindow_->getCurrentWorkspace();
    Serializer s(path);
    mainWindow_->getInviwoApplication()->getProcessorNetwork()->serialize(s);
    std::stringstream stream;
    s.writeFile(stream);
    auto str = stream.str();

    if (head_ >= 0 && str == undoBuffer_[head_]) return; // No Change

    ++head_;
    auto offset = std::min(std::distance(undoBuffer_.begin(), undoBuffer_.end()), head_);
    undoBuffer_.erase(undoBuffer_.begin() + offset, undoBuffer_.end());
    undoBuffer_.emplace_back(str);
    dirty_ = false;
    updateActions();

    LogInfo("Push state: " << head_ << " (" << undoBuffer_.size() << ")");
}
void UndoManager::undoState() {
    if (head_ > 0) {
        util::KeepTrueWhileInScope restore(&isRestoring);
        auto path = mainWindow_->getCurrentWorkspace();

        std::stringstream stream;
        --head_;
        stream << undoBuffer_[head_];
        Deserializer d(mainWindow_->getInviwoApplication(), stream, path);
        mainWindow_->getInviwoApplication()->getProcessorNetwork()->deserialize(d);

        dirty_ = false;
        updateActions();

        LogInfo("Undo state: " << head_ << " (" << undoBuffer_.size() << ")");
    }
}
void UndoManager::redoState() {
    if (head_ >= -1 && head_ < static_cast<DiffType>(undoBuffer_.size())-1) {

        util::KeepTrueWhileInScope restore(&isRestoring);
        auto path = mainWindow_->getCurrentWorkspace();

        std::stringstream stream;
        ++head_;
        stream << undoBuffer_[head_];
        Deserializer d(mainWindow_->getInviwoApplication(), stream, path);
        mainWindow_->getInviwoApplication()->getProcessorNetwork()->deserialize(d);

        dirty_ = false;
        updateActions();

        LogInfo("Redo state: " << head_ << " (" << undoBuffer_.size() << ")");
    }
}

QAction* UndoManager::getUndoAction() const {
    return undoAction_;
}

QAction* UndoManager::getRedoAction() const {
    return redoAction_;
}

void UndoManager::updateActions() {
    undoAction_->setEnabled(head_>0);
    redoAction_->setEnabled(head_ >= -1 && head_ < static_cast<DiffType>(undoBuffer_.size()) - 1);
}

void UndoManager::onProcessorNetworkUnlocked() {
    if (dirty_) pushState();
}

void UndoManager::onProcessorNetworkChange() {
    dirty_ = true;
    pushState();
}
void UndoManager::onProcessorNetworkDidAddProcessor(Processor* processor) {
    dirty_ = true;
    pushState();
}
void UndoManager::onProcessorNetworkDidRemoveProcessor(Processor* processor) {
    dirty_ = true;
    pushState();
}
void UndoManager::onProcessorNetworkDidAddConnection(const PortConnection& connection) {
    dirty_ = true;
    pushState();
}
void UndoManager::onProcessorNetworkDidRemoveConnection(const PortConnection& connection) {
    dirty_ = true;
    pushState();
}
void UndoManager::onProcessorNetworkDidAddLink(const PropertyLink& propertyLink) {
    dirty_ = true;
    pushState();
}
void UndoManager::onProcessorNetworkDidRemoveLink(const PropertyLink& propertyLink) {
    dirty_ = true;
    pushState();
}
}  // namespace
<commit_msg>Core: UndoManager, disable debug logging<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2016 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <inviwo/core/common/inviwoapplication.h>
#include <inviwo/core/network/processornetwork.h>
#include <inviwo/qt/editor/inviwomainwindow.h>
#include <inviwo/qt/editor/undomanager.h>
#include <inviwo/core/util/raiiutils.h>

#include <warn/push>
#include <warn/ignore/all>
#include <QAction>
#include <QEvent>
#include <QApplication>
#include <QGuiApplication>

#include <warn/pop>

namespace inviwo {

UndoManager::UndoManager(InviwoMainWindow* mainWindow) : mainWindow_(mainWindow) {
    mainWindow_->getInviwoApplication()->getProcessorNetwork()->addObserver(this);

    interactionEndCallback_ =
        mainWindow_->getInviwoApplication()->getInteractionStateManager().onInteractionEnd(
            [&]() { if (dirty_) pushState(); });

    undoAction_ = new QAction(QAction::tr("&Undo"), mainWindow_);
    undoAction_->setShortcut(QKeySequence::Undo);
    undoAction_->connect(undoAction_, &QAction::triggered, [&]() {
        undoState();
    });

    redoAction_ = new QAction(QAction::tr("&Redo"), mainWindow_);
    redoAction_->setShortcut(QKeySequence::Redo);
    redoAction_->connect(redoAction_, &QAction::triggered, [&]() {
        redoState();
    });

    updateActions();

    pushState();
}

void UndoManager::pushState() {
    if (isRestoring) return;
    if (mainWindow_->getInviwoApplication()->getProcessorNetwork()->islocked()) return;
    if (mainWindow_->getInviwoApplication()->getInteractionStateManager().isInteracting()) return;

    auto path = mainWindow_->getCurrentWorkspace();
    Serializer s(path);
    mainWindow_->getInviwoApplication()->getProcessorNetwork()->serialize(s);
    std::stringstream stream;
    s.writeFile(stream);
    auto str = stream.str();

    if (head_ >= 0 && str == undoBuffer_[head_]) return; // No Change

    ++head_;
    auto offset = std::min(std::distance(undoBuffer_.begin(), undoBuffer_.end()), head_);
    undoBuffer_.erase(undoBuffer_.begin() + offset, undoBuffer_.end());
    undoBuffer_.emplace_back(str);
    dirty_ = false;
    updateActions();

    //LogInfo("Push state: " << head_ << " (" << undoBuffer_.size() << ")");
}
void UndoManager::undoState() {
    if (head_ > 0) {
        util::KeepTrueWhileInScope restore(&isRestoring);
        auto path = mainWindow_->getCurrentWorkspace();

        std::stringstream stream;
        --head_;
        stream << undoBuffer_[head_];
        Deserializer d(mainWindow_->getInviwoApplication(), stream, path);
        mainWindow_->getInviwoApplication()->getProcessorNetwork()->deserialize(d);

        dirty_ = false;
        updateActions();

        //LogInfo("Undo state: " << head_ << " (" << undoBuffer_.size() << ")");
    }
}
void UndoManager::redoState() {
    if (head_ >= -1 && head_ < static_cast<DiffType>(undoBuffer_.size())-1) {

        util::KeepTrueWhileInScope restore(&isRestoring);
        auto path = mainWindow_->getCurrentWorkspace();

        std::stringstream stream;
        ++head_;
        stream << undoBuffer_[head_];
        Deserializer d(mainWindow_->getInviwoApplication(), stream, path);
        mainWindow_->getInviwoApplication()->getProcessorNetwork()->deserialize(d);

        dirty_ = false;
        updateActions();

        //LogInfo("Redo state: " << head_ << " (" << undoBuffer_.size() << ")");
    }
}

QAction* UndoManager::getUndoAction() const {
    return undoAction_;
}

QAction* UndoManager::getRedoAction() const {
    return redoAction_;
}

void UndoManager::updateActions() {
    undoAction_->setEnabled(head_>0);
    redoAction_->setEnabled(head_ >= -1 && head_ < static_cast<DiffType>(undoBuffer_.size()) - 1);
}

void UndoManager::onProcessorNetworkUnlocked() {
    if (dirty_) pushState();
}

void UndoManager::onProcessorNetworkChange() {
    dirty_ = true;
    pushState();
}
void UndoManager::onProcessorNetworkDidAddProcessor(Processor* processor) {
    dirty_ = true;
    pushState();
}
void UndoManager::onProcessorNetworkDidRemoveProcessor(Processor* processor) {
    dirty_ = true;
    pushState();
}
void UndoManager::onProcessorNetworkDidAddConnection(const PortConnection& connection) {
    dirty_ = true;
    pushState();
}
void UndoManager::onProcessorNetworkDidRemoveConnection(const PortConnection& connection) {
    dirty_ = true;
    pushState();
}
void UndoManager::onProcessorNetworkDidAddLink(const PropertyLink& propertyLink) {
    dirty_ = true;
    pushState();
}
void UndoManager::onProcessorNetworkDidRemoveLink(const PropertyLink& propertyLink) {
    dirty_ = true;
    pushState();
}
}  // namespace
<|endoftext|>


<commit_before>#include "qt/pivx/privacywidget.h"
#include "qt/pivx/forms/ui_privacywidget.h"
#include <QFile>
#include "qt/pivx/qtutils.h"
#include "guiutil.h"
#include "qt/pivx/coincontrolzpivdialog.h"
#include "qt/pivx/denomgenerationdialog.h"
#include <QGraphicsDropShadowEffect>
#include "qt/pivx/defaultdialog.h"
#include "qt/pivx/furlistrow.h"
#include "qt/pivx/txviewholder.h"
#include "walletmodel.h"
#include "optionsmodel.h"
#include "coincontroldialog.h"

#define DECORATION_SIZE 70
#define NUM_ITEMS 3

PrivacyWidget::PrivacyWidget(PIVXGUI* _window, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::PrivacyWidget),
    window(_window)
{
    ui->setupUi(this);

    this->setStyleSheet(_window->styleSheet());

    /* Containers */
    ui->left->setProperty("cssClass", "container");
    ui->left->setContentsMargins(0,20,0,20);
    ui->right->setProperty("cssClass", "container-right");
    ui->right->setContentsMargins(20,10,20,20);

    /* Light Font */
    QFont fontLight;
    fontLight.setWeight(QFont::Light);

    /* Title */
    ui->labelTitle->setText("Privacy");
    ui->labelTitle->setProperty("cssClass", "text-title-screen");
    ui->labelTitle->setFont(fontLight);

    /* Button Group */
    ui->pushLeft->setText("Convert");
    ui->pushLeft->setProperty("cssClass", "btn-check-left");
    ui->pushRight->setText("Mint");
    ui->pushRight->setProperty("cssClass", "btn-check-right");

    /* Subtitle */

    ui->labelSubtitle1->setText("Minting zPIV anonymizes your PIV by removing\ntransaction history, making transactions untraceable ");
    ui->labelSubtitle1->setProperty("cssClass", "text-subtitle");

    ui->labelSubtitle2->setText("Mint new zPIV or convert back to PIV");
    ui->labelSubtitle2->setProperty("cssClass", "text-subtitle");
    ui->labelSubtitle2->setContentsMargins(0,2,0,0);
    /* Amount */

    ui->labelSubtitleAmount->setText("Enter amount of PIV to mint into zPIV ");
    ui->labelSubtitleAmount->setProperty("cssClass", "text-title");

    QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect();
    shadowEffect->setColor(QColor(0, 0, 0, 22));
    shadowEffect->setXOffset(0);
    shadowEffect->setYOffset(3);
    shadowEffect->setBlurRadius(6);

    ui->lineEditAmount->setPlaceholderText("0.00 PIV ");
    ui->lineEditAmount->setProperty("cssClass", "edit-primary");
    ui->lineEditAmount->setAttribute(Qt::WA_MacShowFocusRect, 0);
    ui->lineEditAmount->setGraphicsEffect(shadowEffect);

    /* Denom */

    ui->labelTitleDenom1->setText("Denom. with value 1:");
    ui->labelTitleDenom1->setProperty("cssClass", "text-subtitle");
    ui->labelValueDenom1->setText("0x1 = 0 zPIV");
    ui->labelValueDenom1->setProperty("cssClass", "text-body2");

    ui->labelTitleDenom5->setText("Denom. with value 5:");
    ui->labelTitleDenom5->setProperty("cssClass", "text-subtitle");
    ui->labelValueDenom5->setText("0x5 = 0 zPIV");
    ui->labelValueDenom5->setProperty("cssClass", "text-body2");

    ui->labelTitleDenom10->setText("Denom. with value 10:");
    ui->labelTitleDenom10->setProperty("cssClass", "text-subtitle");
    ui->labelValueDenom10->setText("0x10 = 0 zPIV");
    ui->labelValueDenom10->setProperty("cssClass", "text-body2");

    ui->labelTitleDenom50->setText("Denom. with value 50:");
    ui->labelTitleDenom50->setProperty("cssClass", "text-subtitle");
    ui->labelValueDenom50->setText("0x50 = 0 zPIV");
    ui->labelValueDenom50->setProperty("cssClass", "text-body2");

    ui->labelTitleDenom100->setText("Denom. with value 100:");
    ui->labelTitleDenom100->setProperty("cssClass", "text-subtitle");
    ui->labelValueDenom100->setText("0x100 = 0 zPIV");
    ui->labelValueDenom100->setProperty("cssClass", "text-body2");

    ui->labelTitleDenom500->setText("Denom. with value 500:");
    ui->labelTitleDenom500->setProperty("cssClass", "text-subtitle");
    ui->labelValueDenom500->setText("0x500 = 0 zPIV");
    ui->labelValueDenom500->setProperty("cssClass", "text-body2");

    ui->labelTitleDenom1000->setText("Denom. with value 1000:");
    ui->labelTitleDenom1000->setProperty("cssClass", "text-subtitle");
    ui->labelValueDenom1000->setText("0x1000 = 0 zPIV");
    ui->labelValueDenom1000->setProperty("cssClass", "text-body2");

    ui->labelTitleDenom5000->setText("Denom. with value 5000:");
    ui->labelTitleDenom5000->setProperty("cssClass", "text-subtitle");
    ui->labelValueDenom5000->setText("0x5000 = 0 zPIV");
    ui->labelValueDenom5000->setProperty("cssClass", "text-body2");

    ui->layoutDenom->setVisible(false);

    // List

    ui->labelListHistory->setText("Last Zerocoin Movements");
    ui->labelListHistory->setProperty("cssClass", "text-title");

    //ui->emptyContainer->setVisible(false);
    ui->pushImgEmpty->setProperty("cssClass", "img-empty-privacy");

    ui->labelEmpty->setText("No transactions yet");
    ui->labelEmpty->setProperty("cssClass", "text-empty");

    // Buttons

    ui->pushButtonSave->setText("Mint to zPIV");
    ui->pushButtonSave->setProperty("cssClass", "btn-primary");

    ui->btnTotalzPIV->setTitleClassAndText("btn-title-grey", "Total zPIV 1000");
    ui->btnTotalzPIV->setSubTitleClassAndText("text-subtitle", "Show own coins denominations.");
    ui->btnTotalzPIV->setRightIconClass("btn-dropdown");

    ui->btnCoinControl->setTitleClassAndText("btn-title-grey", "Coin Control");
    ui->btnCoinControl->setSubTitleClassAndText("text-subtitle", "Select PIV outputs to mint into zPIV.");

    ui->btnDenomGeneration->setTitleClassAndText("btn-title-grey", "Denom generation");
    ui->btnDenomGeneration->setSubTitleClassAndText("text-subtitle", "Select the denomination of the coins.");

    ui->btnRescanMints->setTitleClassAndText("btn-title-grey", "Rescan mints");
    ui->btnRescanMints->setSubTitleClassAndText("text-subtitle", "Find mints in the blockchain.");

    ui->btnResetZerocoin->setTitleClassAndText("btn-title-grey", "Reset Zerocoin");
    ui->btnResetZerocoin->setSubTitleClassAndText("text-subtitle", "Reset zerocoin database.");

    connect(ui->btnTotalzPIV, SIGNAL(clicked()), this, SLOT(onTotalZpivClicked()));
    connect(ui->btnCoinControl, SIGNAL(clicked()), this, SLOT(onCoinControlClicked()));
    connect(ui->btnDenomGeneration, SIGNAL(clicked()), this, SLOT(onDenomClicked()));
    connect(ui->btnRescanMints, SIGNAL(clicked()), this, SLOT(onRescanMintsClicked()));
    connect(ui->btnResetZerocoin, SIGNAL(clicked()), this, SLOT(onResetZeroClicked()));

    // Style
    connect(window, SIGNAL(themeChanged(bool, QString&)), this, SLOT(changeTheme(bool, QString&)));

    // List
    ui->listView->setProperty("cssClass", "container");
    txHolder = new TxViewHolder(isLightTheme());
    delegate = new FurAbstractListItemDelegate(
                DECORATION_SIZE,
                txHolder,
                this
    );

    ui->listView->setItemDelegate(delegate);
    ui->listView->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE));
    ui->listView->setMinimumHeight(NUM_ITEMS * (DECORATION_SIZE + 2));
    ui->listView->setAttribute(Qt::WA_MacShowFocusRect, false);
    ui->listView->setSelectionBehavior(QAbstractItemView::SelectRows);

}

void PrivacyWidget::setWalletModel(WalletModel* _model){
    walletModel = _model;
    if(walletModel) {
        txModel = walletModel->getTransactionTableModel();
        // Set up transaction list
        filter = new TransactionFilterProxy();
        filter->setSourceModel(txModel);
        filter->sort(TransactionTableModel::Date, Qt::DescendingOrder);
        filter->setShowZcTxes(true);
        txHolder->setFilter(filter);
        ui->listView->setModel(filter);

        if (txModel->size() == 0) {
            ui->emptyContainer->setVisible(true);
            ui->listView->setVisible(false);
            // TODO: Connect waiting for tx updates..
        }else{
            // TODO: Use show list method..
            ui->emptyContainer->setVisible(false);
            ui->listView->setVisible(true);
        }

        connect(ui->pushButtonSave, SIGNAL(clicked()), this, SLOT(onMintClicked()));
    }
}

void PrivacyWidget::showList(){
    // TODO: here if there is a zc mint/spend here
    ui->emptyContainer->setVisible(false);
    ui->listView->setVisible(true);
}

void PrivacyWidget::onTotalZpivClicked(){

    bool isVisible = ui->layoutDenom->isVisible();

    if(!isVisible){
        ui->layoutDenom->setVisible(true);
    }else{
        ui->layoutDenom->setVisible(false);
    }

}

void PrivacyWidget::onMintClicked(){
    if (!walletModel || !walletModel->getOptionsModel())
        return;

    if(GetAdjustedTime() > GetSporkValue(SPORK_16_ZEROCOIN_MAINTENANCE_MODE)) {
        emit message(tr("Mint Zerocoin"), tr("Transaction sent"), CClientUIInterface::MSG_ERROR);
        return;
    }

    if(!GUIUtil::requestUnlock(walletModel, AskPassphraseDialog::Context::Mint_zPIV, true)){
        emit message("", tr("You need to unlock the wallet to be able to mint zPIV"), CClientUIInterface::MSG_INFORMATION);
        return;
    }

    bool isValid = true;
    CAmount value = GUIUtil::parseValue(
            ui->lineEditAmount->text(),
            walletModel->getOptionsModel()->getDisplayUnit(),
            &isValid
    );

    if (value <= 0) {
        setCssEditLine(ui->lineEditAmount, false, true);
        emit message("", tr("Invalid value"), CClientUIInterface::MSG_INFORMATION);
    }

    // TODO: Launch confirmation dialog here..
    std::string strError;
    if(!walletModel->mintCoins(value, CoinControlDialog::coinControl, strError)){
        emit message("", tr(strError.data()), CClientUIInterface::MSG_INFORMATION);
    }else{
        // Mint succeed
        emit message("", tr("zPIV minted successfully"), CClientUIInterface::MSG_INFORMATION);

        // clear
        ui->lineEditAmount->clear();
    }
}

void PrivacyWidget::onCoinControlClicked(){
    window->showHide(true);
    CoinControlZpivDialog* dialog = new CoinControlZpivDialog(window);
    openDialogWithOpaqueBackgroundY(dialog, window, 4.5, 5);
}

void PrivacyWidget::onDenomClicked(){
    window->showHide(true);
    DenomGenerationDialog* dialog = new DenomGenerationDialog(window);
    openDialogWithOpaqueBackgroundY(dialog, window, 4.5, 5);
}

void PrivacyWidget::onRescanMintsClicked(){
    window->showHide(true);
    DefaultDialog* dialog = new DefaultDialog(window);
    openDialogWithOpaqueBackgroundY(dialog, window, 4.5, 5);
}

void PrivacyWidget::onResetZeroClicked(){
    window->showHide(true);
    DefaultDialog* dialog = new DefaultDialog(window);
    openDialogWithOpaqueBackgroundY(dialog, window, 4.5, 5);
}

void PrivacyWidget::changeTheme(bool isLightTheme, QString& theme){
    // Change theme in all of the childs here..
    this->setStyleSheet(theme);
    static_cast<TxViewHolder*>(this->delegate->getRowFactory())->isLightTheme = isLightTheme;
    ui->listView->update();
    updateStyle(this);
}

PrivacyWidget::~PrivacyWidget()
{
    delete ui;
}
<commit_msg>privacy view, spork blocking mint + display unit<commit_after>#include "qt/pivx/privacywidget.h"
#include "qt/pivx/forms/ui_privacywidget.h"
#include <QFile>
#include "qt/pivx/qtutils.h"
#include "guiutil.h"
#include "qt/pivx/coincontrolzpivdialog.h"
#include "qt/pivx/denomgenerationdialog.h"
#include <QGraphicsDropShadowEffect>
#include "qt/pivx/defaultdialog.h"
#include "qt/pivx/furlistrow.h"
#include "qt/pivx/txviewholder.h"
#include "walletmodel.h"
#include "optionsmodel.h"
#include "coincontroldialog.h"

#define DECORATION_SIZE 70
#define NUM_ITEMS 3

PrivacyWidget::PrivacyWidget(PIVXGUI* _window, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::PrivacyWidget),
    window(_window)
{
    ui->setupUi(this);

    this->setStyleSheet(_window->styleSheet());

    /* Containers */
    ui->left->setProperty("cssClass", "container");
    ui->left->setContentsMargins(0,20,0,20);
    ui->right->setProperty("cssClass", "container-right");
    ui->right->setContentsMargins(20,10,20,20);

    /* Light Font */
    QFont fontLight;
    fontLight.setWeight(QFont::Light);

    /* Title */
    ui->labelTitle->setText("Privacy");
    ui->labelTitle->setProperty("cssClass", "text-title-screen");
    ui->labelTitle->setFont(fontLight);

    /* Button Group */
    ui->pushLeft->setText("Convert");
    ui->pushLeft->setProperty("cssClass", "btn-check-left");
    ui->pushRight->setText("Mint");
    ui->pushRight->setProperty("cssClass", "btn-check-right");

    /* Subtitle */

    ui->labelSubtitle1->setText("Minting zPIV anonymizes your PIV by removing\ntransaction history, making transactions untraceable ");
    ui->labelSubtitle1->setProperty("cssClass", "text-subtitle");

    ui->labelSubtitle2->setText("Mint new zPIV or convert back to PIV");
    ui->labelSubtitle2->setProperty("cssClass", "text-subtitle");
    ui->labelSubtitle2->setContentsMargins(0,2,0,0);
    /* Amount */

    ui->labelSubtitleAmount->setText("Enter amount of PIV to mint into zPIV ");
    ui->labelSubtitleAmount->setProperty("cssClass", "text-title");

    QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect();
    shadowEffect->setColor(QColor(0, 0, 0, 22));
    shadowEffect->setXOffset(0);
    shadowEffect->setYOffset(3);
    shadowEffect->setBlurRadius(6);

    ui->lineEditAmount->setPlaceholderText("0.00 PIV ");
    ui->lineEditAmount->setProperty("cssClass", "edit-primary");
    ui->lineEditAmount->setAttribute(Qt::WA_MacShowFocusRect, 0);
    ui->lineEditAmount->setGraphicsEffect(shadowEffect);

    /* Denom */

    ui->labelTitleDenom1->setText("Denom. with value 1:");
    ui->labelTitleDenom1->setProperty("cssClass", "text-subtitle");
    ui->labelValueDenom1->setText("0x1 = 0 zPIV");
    ui->labelValueDenom1->setProperty("cssClass", "text-body2");

    ui->labelTitleDenom5->setText("Denom. with value 5:");
    ui->labelTitleDenom5->setProperty("cssClass", "text-subtitle");
    ui->labelValueDenom5->setText("0x5 = 0 zPIV");
    ui->labelValueDenom5->setProperty("cssClass", "text-body2");

    ui->labelTitleDenom10->setText("Denom. with value 10:");
    ui->labelTitleDenom10->setProperty("cssClass", "text-subtitle");
    ui->labelValueDenom10->setText("0x10 = 0 zPIV");
    ui->labelValueDenom10->setProperty("cssClass", "text-body2");

    ui->labelTitleDenom50->setText("Denom. with value 50:");
    ui->labelTitleDenom50->setProperty("cssClass", "text-subtitle");
    ui->labelValueDenom50->setText("0x50 = 0 zPIV");
    ui->labelValueDenom50->setProperty("cssClass", "text-body2");

    ui->labelTitleDenom100->setText("Denom. with value 100:");
    ui->labelTitleDenom100->setProperty("cssClass", "text-subtitle");
    ui->labelValueDenom100->setText("0x100 = 0 zPIV");
    ui->labelValueDenom100->setProperty("cssClass", "text-body2");

    ui->labelTitleDenom500->setText("Denom. with value 500:");
    ui->labelTitleDenom500->setProperty("cssClass", "text-subtitle");
    ui->labelValueDenom500->setText("0x500 = 0 zPIV");
    ui->labelValueDenom500->setProperty("cssClass", "text-body2");

    ui->labelTitleDenom1000->setText("Denom. with value 1000:");
    ui->labelTitleDenom1000->setProperty("cssClass", "text-subtitle");
    ui->labelValueDenom1000->setText("0x1000 = 0 zPIV");
    ui->labelValueDenom1000->setProperty("cssClass", "text-body2");

    ui->labelTitleDenom5000->setText("Denom. with value 5000:");
    ui->labelTitleDenom5000->setProperty("cssClass", "text-subtitle");
    ui->labelValueDenom5000->setText("0x5000 = 0 zPIV");
    ui->labelValueDenom5000->setProperty("cssClass", "text-body2");

    ui->layoutDenom->setVisible(false);

    // List

    ui->labelListHistory->setText("Last Zerocoin Movements");
    ui->labelListHistory->setProperty("cssClass", "text-title");

    //ui->emptyContainer->setVisible(false);
    ui->pushImgEmpty->setProperty("cssClass", "img-empty-privacy");

    ui->labelEmpty->setText("No transactions yet");
    ui->labelEmpty->setProperty("cssClass", "text-empty");

    // Buttons

    ui->pushButtonSave->setText("Mint to zPIV");
    ui->pushButtonSave->setProperty("cssClass", "btn-primary");

    ui->btnTotalzPIV->setTitleClassAndText("btn-title-grey", "Total zPIV 1000");
    ui->btnTotalzPIV->setSubTitleClassAndText("text-subtitle", "Show own coins denominations.");
    ui->btnTotalzPIV->setRightIconClass("btn-dropdown");

    ui->btnCoinControl->setTitleClassAndText("btn-title-grey", "Coin Control");
    ui->btnCoinControl->setSubTitleClassAndText("text-subtitle", "Select PIV outputs to mint into zPIV.");

    ui->btnDenomGeneration->setTitleClassAndText("btn-title-grey", "Denom generation");
    ui->btnDenomGeneration->setSubTitleClassAndText("text-subtitle", "Select the denomination of the coins.");

    ui->btnRescanMints->setTitleClassAndText("btn-title-grey", "Rescan mints");
    ui->btnRescanMints->setSubTitleClassAndText("text-subtitle", "Find mints in the blockchain.");

    ui->btnResetZerocoin->setTitleClassAndText("btn-title-grey", "Reset Zerocoin");
    ui->btnResetZerocoin->setSubTitleClassAndText("text-subtitle", "Reset zerocoin database.");

    connect(ui->btnTotalzPIV, SIGNAL(clicked()), this, SLOT(onTotalZpivClicked()));
    connect(ui->btnCoinControl, SIGNAL(clicked()), this, SLOT(onCoinControlClicked()));
    connect(ui->btnDenomGeneration, SIGNAL(clicked()), this, SLOT(onDenomClicked()));
    connect(ui->btnRescanMints, SIGNAL(clicked()), this, SLOT(onRescanMintsClicked()));
    connect(ui->btnResetZerocoin, SIGNAL(clicked()), this, SLOT(onResetZeroClicked()));

    // Style
    connect(window, SIGNAL(themeChanged(bool, QString&)), this, SLOT(changeTheme(bool, QString&)));

    // List
    ui->listView->setProperty("cssClass", "container");
    txHolder = new TxViewHolder(isLightTheme());
    delegate = new FurAbstractListItemDelegate(
                DECORATION_SIZE,
                txHolder,
                this
    );

    ui->listView->setItemDelegate(delegate);
    ui->listView->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE));
    ui->listView->setMinimumHeight(NUM_ITEMS * (DECORATION_SIZE + 2));
    ui->listView->setAttribute(Qt::WA_MacShowFocusRect, false);
    ui->listView->setSelectionBehavior(QAbstractItemView::SelectRows);

}

void PrivacyWidget::setWalletModel(WalletModel* _model){
    walletModel = _model;
    if(walletModel) {
        txModel = walletModel->getTransactionTableModel();
        // Set up transaction list
        filter = new TransactionFilterProxy();
        filter->setSourceModel(txModel);
        filter->sort(TransactionTableModel::Date, Qt::DescendingOrder);
        filter->setShowZcTxes(true);
        txHolder->setDisplayUnit(walletModel->getOptionsModel()->getDisplayUnit());
        txHolder->setFilter(filter);
        ui->listView->setModel(filter);

        if (txModel->size() == 0) {
            ui->emptyContainer->setVisible(true);
            ui->listView->setVisible(false);
            // TODO: Connect waiting for tx updates..
        }else{
            // TODO: Use show list method..
            ui->emptyContainer->setVisible(false);
            ui->listView->setVisible(true);
        }

        connect(ui->pushButtonSave, SIGNAL(clicked()), this, SLOT(onMintClicked()));
        // TODO: Connect update display unit..
    }

}

void PrivacyWidget::updateDisplayUnit() {
    if (walletModel && walletModel->getOptionsModel()) {
        nDisplayUnit = walletModel->getOptionsModel()->getDisplayUnit();

        txHolder->setDisplayUnit(nDisplayUnit);
        ui->listView->update();
    }
}

void PrivacyWidget::showList(){
    // TODO: here if there is a zc mint/spend here
    ui->emptyContainer->setVisible(false);
    ui->listView->setVisible(true);
}

void PrivacyWidget::onTotalZpivClicked(){

    bool isVisible = ui->layoutDenom->isVisible();

    if(!isVisible){
        ui->layoutDenom->setVisible(true);
    }else{
        ui->layoutDenom->setVisible(false);
    }

}

void PrivacyWidget::onMintClicked(){
    if (!walletModel || !walletModel->getOptionsModel())
        return;

    if(GetAdjustedTime() > GetSporkValue(SPORK_16_ZEROCOIN_MAINTENANCE_MODE)) {
        emit message(tr("Mint Zerocoin"), tr("zPIV is currently undergoing maintenance"), CClientUIInterface::MSG_ERROR);
        return;
    }

    if(!GUIUtil::requestUnlock(walletModel, AskPassphraseDialog::Context::Mint_zPIV, true)){
        emit message("", tr("You need to unlock the wallet to be able to mint zPIV"), CClientUIInterface::MSG_INFORMATION);
        return;
    }

    bool isValid = true;
    CAmount value = GUIUtil::parseValue(
            ui->lineEditAmount->text(),
            walletModel->getOptionsModel()->getDisplayUnit(),
            &isValid
    );

    if (value <= 0) {
        setCssEditLine(ui->lineEditAmount, false, true);
        emit message("", tr("Invalid value"), CClientUIInterface::MSG_INFORMATION);
    }

    // TODO: Launch confirmation dialog here..
    std::string strError;
    if(!walletModel->mintCoins(value, CoinControlDialog::coinControl, strError)){
        emit message("", tr(strError.data()), CClientUIInterface::MSG_INFORMATION);
    }else{
        // Mint succeed
        emit message("", tr("zPIV minted successfully"), CClientUIInterface::MSG_INFORMATION);

        // clear
        ui->lineEditAmount->clear();
    }
}

void PrivacyWidget::onCoinControlClicked(){
    window->showHide(true);
    CoinControlZpivDialog* dialog = new CoinControlZpivDialog(window);
    openDialogWithOpaqueBackgroundY(dialog, window, 4.5, 5);
}

void PrivacyWidget::onDenomClicked(){
    window->showHide(true);
    DenomGenerationDialog* dialog = new DenomGenerationDialog(window);
    openDialogWithOpaqueBackgroundY(dialog, window, 4.5, 5);
}

void PrivacyWidget::onRescanMintsClicked(){
    window->showHide(true);
    DefaultDialog* dialog = new DefaultDialog(window);
    openDialogWithOpaqueBackgroundY(dialog, window, 4.5, 5);
}

void PrivacyWidget::onResetZeroClicked(){
    window->showHide(true);
    DefaultDialog* dialog = new DefaultDialog(window);
    openDialogWithOpaqueBackgroundY(dialog, window, 4.5, 5);
}

void PrivacyWidget::changeTheme(bool isLightTheme, QString& theme){
    // Change theme in all of the childs here..
    this->setStyleSheet(theme);
    static_cast<TxViewHolder*>(this->delegate->getRowFactory())->isLightTheme = isLightTheme;
    ui->listView->update();
    updateStyle(this);
}

PrivacyWidget::~PrivacyWidget()
{
    delete ui;
}
<|endoftext|>


<commit_before>#include "analysisoverlay.h"

/**
 * @brief AnalysisOverlay::AnalysisOverlay
 */
AnalysisOverlay::AnalysisOverlay() {
    // Temporary areas to show, since there's no analysis yet.
    add_area(2, cv::Point(50,50), cv::Point(150,150));
    add_area(3, cv::Point(50,50), cv::Point(150,150));
    add_area(4, cv::Point(50,50), cv::Point(150,150));
    add_area(5, cv::Point(50,50), cv::Point(150,150));
    add_area(6, cv::Point(50,50), cv::Point(150,150));
    add_area(7, cv::Point(50,50), cv::Point(150,150));
    add_area(8, cv::Point(50,50), cv::Point(150,150));
    add_area(9, cv::Point(50,50), cv::Point(150,150));
    add_area(10, cv::Point(150,150), cv::Point(250,170));
}

/**
 * @brief AnalysisOverlay::draw_overlay
 * Draws an overlay with the detected areas, on top of the specified frame.
 * @param img Frame to draw on
 * @param frame_nr Number of the frame currently shown in the video.
 */
cv::Mat AnalysisOverlay::draw_overlay(cv::Mat &frame, int frame_nr) {
    if (showing_overlay) {
        for (std::pair<cv::Point, cv::Point> area : detections[frame_nr]) {
            cv::Rect rect(area.first, area.second);
            cv::rectangle(frame, rect, cv::Scalar(255, 0, 0), 5);
        }
    }
    return frame;
}

/**
 * @brief AnalysisOverlay::add_area
 * @param frame_nr Frame associated with the area.
 * @param start Start point.
 * @param end End point.
 */
void AnalysisOverlay::add_area(int frame_nr, cv::Point start, cv::Point end) {
    std::pair <cv::Point, cv::Point> pair(start, end);
    detections[frame_nr].push_back(pair);
}

/**
 * @brief AnalysisOverlay::is_showing_overlay
 * @return Returns true if the analysis overlay is showing, else false.
 */
bool AnalysisOverlay::is_showing_overlay() {
    return showing_overlay;
}

/**
 * @brief AnalysisOverlay::toggle_showing
 */
void AnalysisOverlay::toggle_showing() {
    showing_overlay = !showing_overlay;
}
<commit_msg>Edited comment.<commit_after>#include "analysisoverlay.h"

/**
 * @brief AnalysisOverlay::AnalysisOverlay
 */
AnalysisOverlay::AnalysisOverlay() {
    // Temporary areas to show, since there's no analysis yet.
    add_area(2, cv::Point(50,50), cv::Point(150,150));
    add_area(3, cv::Point(50,50), cv::Point(150,150));
    add_area(4, cv::Point(50,50), cv::Point(150,150));
    add_area(5, cv::Point(50,50), cv::Point(150,150));
    add_area(6, cv::Point(50,50), cv::Point(150,150));
    add_area(7, cv::Point(50,50), cv::Point(150,150));
    add_area(8, cv::Point(50,50), cv::Point(150,150));
    add_area(9, cv::Point(50,50), cv::Point(150,150));
    add_area(10, cv::Point(150,150), cv::Point(250,170));
}

/**
 * @brief AnalysisOverlay::draw_overlay
 * Draws an overlay with the detected areas, on top of the specified frame.
 * @param frame Frame to draw on.
 * @param frame_nr Number of the frame currently shown in the video.
 * @return Returns the frame with the overlay.
 */
cv::Mat AnalysisOverlay::draw_overlay(cv::Mat &frame, int frame_nr) {
    if (showing_overlay) {
        for (std::pair<cv::Point, cv::Point> area : detections[frame_nr]) {
            cv::Rect rect(area.first, area.second);
            cv::rectangle(frame, rect, cv::Scalar(255, 0, 0), 5);
        }
    }
    return frame;
}

/**
 * @brief AnalysisOverlay::add_area
 * @param frame_nr Frame associated with the area.
 * @param start Start point.
 * @param end End point.
 */
void AnalysisOverlay::add_area(int frame_nr, cv::Point start, cv::Point end) {
    std::pair <cv::Point, cv::Point> pair(start, end);
    detections[frame_nr].push_back(pair);
}

/**
 * @brief AnalysisOverlay::is_showing_overlay
 * @return Returns true if the analysis overlay is showing, else false.
 */
bool AnalysisOverlay::is_showing_overlay() {
    return showing_overlay;
}

/**
 * @brief AnalysisOverlay::toggle_showing
 */
void AnalysisOverlay::toggle_showing() {
    showing_overlay = !showing_overlay;
}
<|endoftext|>


<commit_before>// trance linux.hpp - Configuration for Linux
//
// Copyright (c) 2011 - 2011 Kohei Takahashi (Flast)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#ifndef IG_TRANCE_IOSTREAMS_DETAIL_LINUX_HPP_ONCE_
#define IG_TRANCE_IOSTREAMS_DETAIL_LINUX_HPP_ONCE_

#include <trance/config.hpp>

#include <cstddef>
#include <iosfwd>

#include <boost/cstdint.hpp>

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/tuple/elem.hpp>

namespace trance
{

namespace iostreams
{

#define TRANCE_IOSTREAMS_CLEAR_MANIPS_INFO      \
  ( "trance/iostreams/detail/string_manip.hpp", \
    6,                                          \
    (                                           \
      ( clear_below, "[0J" ),                   \
      ( clear_above, "[1J" ),                   \
      ( clear      , "[2J" ),                   \
      ( clear_right, "[0K" ),                   \
      ( clear_left , "[1K" ),                   \
      ( clear_line , "[2K" ))                   \
  )                                             \

#define TRANCE_IOSTREAMS_MOVE_IMPL( _suf )      \
  TRANCE_IOSTREAMS_MANIP_LAMBDA<                \
    unsigned int,                               \
    iostreams_detail::_detail::_square_bracket, \
    iostreams_detail::_detail::_suf             \
  >                                             \

#define TRANCE_IOSTREAMS_MOVE_1DIM_MANIPS_INFO                \
  ( "trance/iostreams/detail/param_manip.hpp",                \
    4,                                                        \
    (                                                         \
      ( move_up   , (TRANCE_IOSTREAMS_MOVE_IMPL( _put_A )) ), \
      ( move_down , (TRANCE_IOSTREAMS_MOVE_IMPL( _put_B )) ), \
      ( move_right, (TRANCE_IOSTREAMS_MOVE_IMPL( _put_C )) ), \
      ( move_left , (TRANCE_IOSTREAMS_MOVE_IMPL( _put_D )) )) \
  )                                                           \

#define TRANCE_IOSTREAMS_MOVE_UPDOWN_MANIPS_INFO \
  ( "trance/iostreams/detail/string_manip.hpp",  \
    3,                                           \
    (                                            \
      ( move_down1, "D" ),                       \
      ( new_line  , "E" ),                       \
      ( move_up1  , "M" ))                       \
  )                                              \

namespace iostreams_detail
{

namespace _detail
{

#define ESC_SEQ_INITIALIZER_DEF( _unused_z, i_, _unused_param )   \
  template < typename CharTraits >                                \
  inline ::std::basic_ostream<                                    \
    TRANCE_IOSTREAMS_GET_CHAR_TYPE( i_ ),                         \
    CharTraits                                                    \
  > &                                                             \
  _esc_seq_initializer(                                           \
    ::std::basic_ostream<                                         \
      TRANCE_IOSTREAMS_GET_CHAR_TYPE( i_ ),                       \
      CharTraits                                                  \
    > &_ostr )                                                    \
  {                                                               \
      _ostr << TRANCE_IOSTREAMS_GET_CHAR_FORWARD( i_ )( '\x1b' ); \
      return _ostr;                                               \
  }                                                               \

BOOST_PP_REPEAT( TRANCE_IOSTREAMS_CHAR_TUPLE_SIZE, ESC_SEQ_INITIALIZER_DEF, _ )

#undef ESC_SEQ_INITIALIZER_DEF

// nothing to do
template < typename CharT, typename CharTraits >
inline ::std::basic_ostream< CharT, CharTraits > &
_esc_seq_finalizer( ::std::basic_ostream< CharT, CharTraits > &_ostr )
{ return _ostr; }

#define ENTRY_OPERATOR_DETAIL( _suf, _type, _forward )                     \
  template < typename CharTraits >                                         \
  ::std::basic_ostream< _type, CharTraits > &                              \
  operator()( ::std::basic_ostream< _type, CharTraits > &_ostr ) const     \
  { return _ostr << BOOST_PP_CAT( TRANCE_IOSTREAMS_, _forward )( _suf ); } \

#define ENTRY_IMPL( _entry, _char )                                  \
  struct _entry                                                      \
  {                                                                  \
      ENTRY_OPERATOR_DETAIL( _char, char    , CHAR_FORWARD     )     \
      ENTRY_OPERATOR_DETAIL( _char, wchar_t , WCHAR_T_FORWARD  )     \
      TRANCE_IOSTREAMS_ENABLE_IF_HAS_CHAR16_T(                       \
        ENTRY_OPERATOR_DETAIL( _char, char16_t, CHAR16_T_FORWARD ) ) \
      TRANCE_IOSTREAMS_ENABLE_IF_HAS_CHAR32_T(                       \
        ENTRY_OPERATOR_DETAIL( _char, char32_t, CHAR32_T_FORWARD ) ) \
  }                                                                  \

_ENTRY_IMPL( _square_bracket, '[' );

_ENTRY_IMPL( _put_A, 'A' );
_ENTRY_IMPL( _put_B, 'B' );
_ENTRY_IMPL( _put_C, 'C' );
_ENTRY_IMPL( _put_D, 'D' );

#undef ENTRY_IMPL
#undef ENTRY_OPERATOR_DETAIL

inline size_t
_find_ntz( ::boost::uint8_t _x ) TRANCE_NOEXCEPT
{
    ::std::size_t i = 0;
    for ( ; !( _x & 1 ); ++i, _x >>= 1 );
    return i;
}

template < typename Attribute >
inline ::boost::uint8_t
_mask( typename Attribute::value_type _x ) TRANCE_NOEXCEPT
{ return _x & ( ( 1u << 8 ) - 1 ); }

#define INSERT_SEMICOLON_WHEN( begin, itr ) \
  if ( begin == itr ) {} else *itr++ = ';'

template < typename CharT >
inline void
_insert_when( ::boost::uint8_t pred,
  CharT * const begin, CharT *&itr, const CharT value ) TRANCE_NOEXCEPT
{
    if ( !pred )
    { return; }

    INSERT_SEMICOLON_WHEN( begin, itr );
    *itr++ = value;
    *itr++ = '0' + _find_ntz( pred );
}

} // namespace _detail

template < typename CharT, typename Traits, typename Attribute >
inline ::std::basic_ostream< CharT, Traits > &
operator<<( ::std::basic_ostream< CharT, Traits > &_ostr,
  const _attribute_forwarder< Attribute > &_af )
{
    CharT _buf[ 16 ] = { '\x1b', '[' };
    CharT *itr = _buf + 2;
    if ( _af._m_value == Attribute::reset )
    { *itr++ = '0'; }
    else
    {
        using namespace _detail;
        typedef ::boost::uint8_t mask_t( typename Attribute::value_type );
        mask_t &mask = _mask< Attribute >;

        if ( ::boost::uint8_t _tmp = mask( _af._m_value ) )
        {
            for ( CharT c = '1'; _tmp; _tmp >>= 1, ++c )
            {
                if ( _tmp & ~1 )
                { continue; }

                INSERT_SEMICOLON_WHEN( _buf, itr );
                *itr++ = c;
            }
        }
        _insert_when( mask( _af._m_value >>  8 ), _buf, itr, '3' );
        _insert_when( mask( _af._m_value >> 16 ), _buf, itr, '4' );
    }

    *itr = 'm';
    _ostr << _buf;
    return _ostr;
}
#undef INSERT_SEMICOLON_WHEN

} // namespace iostreams_detail

} // namespace iostreams

} // namespace trance

#endif // IG_TRANCE_IOSTREAMS_DETAIL_LINUX_HPP_ONCE_

<commit_msg>Fix compile error<commit_after>// trance linux.hpp - Configuration for Linux
//
// Copyright (c) 2011 - 2011 Kohei Takahashi (Flast)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#ifndef IG_TRANCE_IOSTREAMS_DETAIL_LINUX_HPP_ONCE_
#define IG_TRANCE_IOSTREAMS_DETAIL_LINUX_HPP_ONCE_

#include <trance/config.hpp>

#include <cstddef>
#include <iosfwd>

#include <boost/cstdint.hpp>

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/tuple/elem.hpp>

namespace trance
{

namespace iostreams
{

#define TRANCE_IOSTREAMS_CLEAR_MANIPS_INFO      \
  ( "trance/iostreams/detail/string_manip.hpp", \
    6,                                          \
    (                                           \
      ( clear_below, "[0J" ),                   \
      ( clear_above, "[1J" ),                   \
      ( clear      , "[2J" ),                   \
      ( clear_right, "[0K" ),                   \
      ( clear_left , "[1K" ),                   \
      ( clear_line , "[2K" ))                   \
  )                                             \

#define TRANCE_IOSTREAMS_MOVE_IMPL( _suf )      \
  TRANCE_IOSTREAMS_MANIP_LAMBDA<                \
    unsigned int,                               \
    iostreams_detail::_detail::_square_bracket, \
    iostreams_detail::_detail::_suf             \
  >                                             \

#define TRANCE_IOSTREAMS_MOVE_1DIM_MANIPS_INFO                \
  ( "trance/iostreams/detail/param_manip.hpp",                \
    4,                                                        \
    (                                                         \
      ( move_up   , (TRANCE_IOSTREAMS_MOVE_IMPL( _put_A )) ), \
      ( move_down , (TRANCE_IOSTREAMS_MOVE_IMPL( _put_B )) ), \
      ( move_right, (TRANCE_IOSTREAMS_MOVE_IMPL( _put_C )) ), \
      ( move_left , (TRANCE_IOSTREAMS_MOVE_IMPL( _put_D )) )) \
  )                                                           \

#define TRANCE_IOSTREAMS_MOVE_UPDOWN_MANIPS_INFO \
  ( "trance/iostreams/detail/string_manip.hpp",  \
    3,                                           \
    (                                            \
      ( move_down1, "D" ),                       \
      ( new_line  , "E" ),                       \
      ( move_up1  , "M" ))                       \
  )                                              \

namespace iostreams_detail
{

namespace _detail
{

#define ESC_SEQ_INITIALIZER_DEF( _unused_z, i_, _unused_param )   \
  template < typename CharTraits >                                \
  inline ::std::basic_ostream<                                    \
    TRANCE_IOSTREAMS_GET_CHAR_TYPE( i_ ),                         \
    CharTraits                                                    \
  > &                                                             \
  _esc_seq_initializer(                                           \
    ::std::basic_ostream<                                         \
      TRANCE_IOSTREAMS_GET_CHAR_TYPE( i_ ),                       \
      CharTraits                                                  \
    > &_ostr )                                                    \
  {                                                               \
      _ostr << TRANCE_IOSTREAMS_GET_CHAR_FORWARD( i_ )( '\x1b' ); \
      return _ostr;                                               \
  }                                                               \

BOOST_PP_REPEAT( TRANCE_IOSTREAMS_CHAR_TUPLE_SIZE, ESC_SEQ_INITIALIZER_DEF, _ )

#undef ESC_SEQ_INITIALIZER_DEF

// nothing to do
template < typename CharT, typename CharTraits >
inline ::std::basic_ostream< CharT, CharTraits > &
_esc_seq_finalizer( ::std::basic_ostream< CharT, CharTraits > &_ostr )
{ return _ostr; }

#define ENTRY_OPERATOR_DETAIL( _suf, _type, _forward )                     \
  template < typename CharTraits >                                         \
  ::std::basic_ostream< _type, CharTraits > &                              \
  operator()( ::std::basic_ostream< _type, CharTraits > &_ostr ) const     \
  { return _ostr << BOOST_PP_CAT( TRANCE_IOSTREAMS_, _forward )( _suf ); } \

#define ENTRY_IMPL( _entry, _char )                                  \
  struct _entry                                                      \
  {                                                                  \
      ENTRY_OPERATOR_DETAIL( _char, char    , CHAR_FORWARD     )     \
      ENTRY_OPERATOR_DETAIL( _char, wchar_t , WCHAR_T_FORWARD  )     \
      TRANCE_IOSTREAMS_ENABLE_IF_HAS_CHAR16_T(                       \
        ENTRY_OPERATOR_DETAIL( _char, char16_t, CHAR16_T_FORWARD ) ) \
      TRANCE_IOSTREAMS_ENABLE_IF_HAS_CHAR32_T(                       \
        ENTRY_OPERATOR_DETAIL( _char, char32_t, CHAR32_T_FORWARD ) ) \
  }                                                                  \

ENTRY_IMPL( _square_bracket, '[' );

ENTRY_IMPL( _put_A, 'A' );
ENTRY_IMPL( _put_B, 'B' );
ENTRY_IMPL( _put_C, 'C' );
ENTRY_IMPL( _put_D, 'D' );

#undef ENTRY_IMPL
#undef ENTRY_OPERATOR_DETAIL

inline size_t
_find_ntz( ::boost::uint8_t _x ) TRANCE_NOEXCEPT
{
    ::std::size_t i = 0;
    for ( ; !( _x & 1 ); ++i, _x >>= 1 );
    return i;
}

template < typename Attribute >
inline ::boost::uint8_t
_mask( typename Attribute::value_type _x ) TRANCE_NOEXCEPT
{ return _x & ( ( 1u << 8 ) - 1 ); }

#define INSERT_SEMICOLON_WHEN( begin, itr ) \
  if ( begin == itr ) {} else *itr++ = ';'

template < typename CharT >
inline void
_insert_when( ::boost::uint8_t pred,
  CharT * const begin, CharT *&itr, const CharT value ) TRANCE_NOEXCEPT
{
    if ( !pred )
    { return; }

    INSERT_SEMICOLON_WHEN( begin, itr );
    *itr++ = value;
    *itr++ = '0' + _find_ntz( pred );
}

} // namespace _detail

template < typename CharT, typename Traits, typename Attribute >
inline ::std::basic_ostream< CharT, Traits > &
operator<<( ::std::basic_ostream< CharT, Traits > &_ostr,
  const _attribute_forwarder< Attribute > &_af )
{
    CharT _buf[ 16 ] = { '\x1b', '[' };
    CharT *itr = _buf + 2;
    if ( _af._m_value == Attribute::reset )
    { *itr++ = '0'; }
    else
    {
        using namespace _detail;
        typedef ::boost::uint8_t mask_t( typename Attribute::value_type );
        mask_t &mask = _mask< Attribute >;

        if ( ::boost::uint8_t _tmp = mask( _af._m_value ) )
        {
            for ( CharT c = '1'; _tmp; _tmp >>= 1, ++c )
            {
                if ( _tmp & ~1 )
                { continue; }

                INSERT_SEMICOLON_WHEN( _buf, itr );
                *itr++ = c;
            }
        }
        _insert_when( mask( _af._m_value >>  8 ), _buf, itr, '3' );
        _insert_when( mask( _af._m_value >> 16 ), _buf, itr, '4' );
    }

    *itr = 'm';
    _ostr << _buf;
    return _ostr;
}
#undef INSERT_SEMICOLON_WHEN

} // namespace iostreams_detail

} // namespace iostreams

} // namespace trance

#endif // IG_TRANCE_IOSTREAMS_DETAIL_LINUX_HPP_ONCE_

<|endoftext|>