<commit_before>#include "overviewpage.h"
#include "ui_overviewpage.h"

#include "walletmodel.h"
#include "tekcoinunits.h"
#include "optionsmodel.h"
#include "transactiontablemodel.h"
#include "transactionfilterproxy.h"
#include "guiutil.h"
#include "guiconstants.h"

#include <QAbstractItemDelegate>
#include <QPainter>

#define DECORATION_SIZE 64
#define NUM_ITEMS 3

class TxViewDelegate : public QAbstractItemDelegate
{
    Q_OBJECT
public:
    TxViewDelegate(): QAbstractItemDelegate(), unit(tekcoinUnits::BTC)
    {

    }

    inline void paint(QPainter *painter, const QStyleOptionViewItem &option,
                      const QModelIndex &index ) const
    {
        painter->save();

        QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
        QRect mainRect = option.rect;
        QRect decorationRect(mainRect.topLeft(), QSize(DECORATION_SIZE, DECORATION_SIZE));
        int xspace = DECORATION_SIZE + 8;
        int ypad = 6;
        int halfheight = (mainRect.height() - 2*ypad)/2;
        QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight);
        QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight);
        icon.paint(painter, decorationRect);

        QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime();
        QString address = index.data(Qt::DisplayRole).toString();
        qint64 amount = index.data(TransactionTableModel::AmountRole).toLongLong();
        bool confirmed = index.data(TransactionTableModel::ConfirmedRole).toBool();
        QVariant value = index.data(Qt::ForegroundRole);
        QColor foreground = option.palette.color(QPalette::Text);

        #if QT_VERSION < 0x050000 //presstab qt5
        if(qVariantCanConvert<QColor>(value))
		#else
        if(value.canConvert<QColor>())
		#endif
        {
            foreground = qvariant_cast<QColor>(value);
        }

        painter->setPen(foreground);
        painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address);

        if(amount < 0)
        {
            foreground = COLOR_NEGATIVE;
        }
        else if(!confirmed)
        {
            foreground = COLOR_UNCONFIRMED;
        }
        else
        {
            foreground = option.palette.color(QPalette::Text);
        }
        painter->setPen(foreground);
        QString amountText = tekcoinUnits::formatWithUnit(unit, amount, true);
        if(!confirmed)
        {
            amountText = QString("[") + amountText + QString("]");
        }
        painter->drawText(amountRect, Qt::AlignRight|Qt::AlignVCenter, amountText);

        painter->setPen(option.palette.color(QPalette::Text));
        painter->drawText(amountRect, Qt::AlignLeft|Qt::AlignVCenter, GUIUtil::dateTimeStr(date));

        painter->restore();
    }

    inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        return QSize(DECORATION_SIZE, DECORATION_SIZE);
    }

    int unit;

};
#include "overviewpage.moc"

OverviewPage::OverviewPage(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::OverviewPage),
    currentBalance(-1),
    currentStake(0),
    currentUnconfirmedBalance(-1),
    currentImmatureBalance(-1),
    txdelegate(new TxViewDelegate()),
    filter(0)
{
    ui->setupUi(this);

    // Recent transactions
    ui->listTransactions->setItemDelegate(txdelegate);
    ui->listTransactions->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE));
    ui->listTransactions->setMinimumHeight(NUM_ITEMS * (DECORATION_SIZE + 2));
    ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false);

    connect(ui->listTransactions, SIGNAL(clicked(QModelIndex)), this, SLOT(handleTransactionClicked(QModelIndex)));

    // init "out of sync" warning labels
    ui->labelWalletStatus->setText("(" + tr("out of sync") + ")");
    ui->labelTransactionsStatus->setText("(" + tr("out of sync") + ")");

    QPalette  p;
    p.setColor(QPalette::WindowText,Qt::red);
    ui->label_tekcoin_Intro->setPalette(p);

    // start with displaying the "out of sync" warnings
    showOutOfSyncWarning(true);
}

void OverviewPage::handleTransactionClicked(const QModelIndex &index)
{
    if(filter)
        emit transactionClicked(filter->mapToSource(index));
}

OverviewPage::~OverviewPage()
{
    delete ui;
}

void OverviewPage::setBalance(qint64 balance, qint64 stake, qint64 unconfirmedBalance, qint64 immatureBalance)
{
    int unit = model->getOptionsModel()->getDisplayUnit();
    currentBalance = balance;
    currentStake = stake;
    currentUnconfirmedBalance = unconfirmedBalance;
    currentImmatureBalance = immatureBalance;
    ui->labelBalance->setText(tekcoinUnits::formatWithUnit(unit, balance));
    ui->labelStake->setText(tekcoinUnits::formatWithUnit(unit, stake));
    ui->labelUnconfirmed->setText(tekcoinUnits::formatWithUnit(unit, unconfirmedBalance));
    ui->labelImmature->setText(tekcoinUnits::formatWithUnit(unit, immatureBalance));

    // only show immature (newly mined) balance if it's non-zero, so as not to complicate things
    // for the non-mining users
    bool showImmature = immatureBalance != 0;
    ui->labelImmature->setVisible(showImmature);
    ui->labelImmatureText->setVisible(showImmature);
}

void OverviewPage::setNumTransactions(int count)
{
    ui->labelNumTransactions->setText(QLocale::system().toString(count));
}

void OverviewPage::setModel(WalletModel *model)
{
    this->model = model;
    if(model && model->getOptionsModel())
    {
        // Set up transaction list
        filter = new TransactionFilterProxy();
        filter->setSourceModel(model->getTransactionTableModel());
        filter->setLimit(NUM_ITEMS);
        filter->setDynamicSortFilter(true);
        filter->setSortRole(Qt::EditRole);
        filter->sort(TransactionTableModel::Status, Qt::DescendingOrder);

        ui->listTransactions->setModel(filter);
        ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress);

        // Keep up to date with wallet
        setBalance(model->getBalance(), model->getStake(), model->getUnconfirmedBalance(), model->getImmatureBalance());
        connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64, qint64)));

        setNumTransactions(model->getNumTransactions());
        connect(model, SIGNAL(numTransactionsChanged(int)), this, SLOT(setNumTransactions(int)));

        connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
    }

    // update the display unit, to not use the default ("BTC")
    updateDisplayUnit();
}

void OverviewPage::updateDisplayUnit()
{
    if(model && model->getOptionsModel())
    {
        if(currentBalance != -1)
            setBalance(currentBalance, model->getStake(), currentUnconfirmedBalance, currentImmatureBalance);

        // Update txdelegate->unit with the current unit
        txdelegate->unit = model->getOptionsModel()->getDisplayUnit();

        ui->listTransactions->update();
    }
}

void OverviewPage::showOutOfSyncWarning(bool fShow)
{
    ui->labelWalletStatus->setVisible(fShow);
    ui->labelTransactionsStatus->setVisible(fShow);
}
<commit_msg>6 recent transactions on overview page<commit_after>#include "overviewpage.h"
#include "ui_overviewpage.h"

#include "walletmodel.h"
#include "tekcoinunits.h"
#include "optionsmodel.h"
#include "transactiontablemodel.h"
#include "transactionfilterproxy.h"
#include "guiutil.h"
#include "guiconstants.h"

#include <QAbstractItemDelegate>
#include <QPainter>

#define DECORATION_SIZE 64
#define NUM_ITEMS 6

class TxViewDelegate : public QAbstractItemDelegate
{
    Q_OBJECT
public:
    TxViewDelegate(): QAbstractItemDelegate(), unit(tekcoinUnits::BTC)
    {

    }

    inline void paint(QPainter *painter, const QStyleOptionViewItem &option,
                      const QModelIndex &index ) const
    {
        painter->save();

        QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
        QRect mainRect = option.rect;
        QRect decorationRect(mainRect.topLeft(), QSize(DECORATION_SIZE, DECORATION_SIZE));
        int xspace = DECORATION_SIZE + 8;
        int ypad = 6;
        int halfheight = (mainRect.height() - 2*ypad)/2;
        QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight);
        QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight);
        icon.paint(painter, decorationRect);

        QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime();
        QString address = index.data(Qt::DisplayRole).toString();
        qint64 amount = index.data(TransactionTableModel::AmountRole).toLongLong();
        bool confirmed = index.data(TransactionTableModel::ConfirmedRole).toBool();
        QVariant value = index.data(Qt::ForegroundRole);
        QColor foreground = option.palette.color(QPalette::Text);

        #if QT_VERSION < 0x050000 //presstab qt5
        if(qVariantCanConvert<QColor>(value))
		#else
        if(value.canConvert<QColor>())
		#endif
        {
            foreground = qvariant_cast<QColor>(value);
        }

        painter->setPen(foreground);
        painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address);

        if(amount < 0)
        {
            foreground = COLOR_NEGATIVE;
        }
        else if(!confirmed)
        {
            foreground = COLOR_UNCONFIRMED;
        }
        else
        {
            foreground = option.palette.color(QPalette::Text);
        }
        painter->setPen(foreground);
        QString amountText = tekcoinUnits::formatWithUnit(unit, amount, true);
        if(!confirmed)
        {
            amountText = QString("[") + amountText + QString("]");
        }
        painter->drawText(amountRect, Qt::AlignRight|Qt::AlignVCenter, amountText);

        painter->setPen(option.palette.color(QPalette::Text));
        painter->drawText(amountRect, Qt::AlignLeft|Qt::AlignVCenter, GUIUtil::dateTimeStr(date));

        painter->restore();
    }

    inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        return QSize(DECORATION_SIZE, DECORATION_SIZE);
    }

    int unit;

};
#include "overviewpage.moc"

OverviewPage::OverviewPage(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::OverviewPage),
    currentBalance(-1),
    currentStake(0),
    currentUnconfirmedBalance(-1),
    currentImmatureBalance(-1),
    txdelegate(new TxViewDelegate()),
    filter(0)
{
    ui->setupUi(this);

    // Recent transactions
    ui->listTransactions->setItemDelegate(txdelegate);
    ui->listTransactions->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE));
    ui->listTransactions->setMinimumHeight(NUM_ITEMS * (DECORATION_SIZE + 2));
    ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false);

    connect(ui->listTransactions, SIGNAL(clicked(QModelIndex)), this, SLOT(handleTransactionClicked(QModelIndex)));

    // init "out of sync" warning labels
    ui->labelWalletStatus->setText("(" + tr("out of sync") + ")");
    ui->labelTransactionsStatus->setText("(" + tr("out of sync") + ")");

    QPalette  p;
    p.setColor(QPalette::WindowText,Qt::red);
    ui->label_tekcoin_Intro->setPalette(p);

    // start with displaying the "out of sync" warnings
    showOutOfSyncWarning(true);
}

void OverviewPage::handleTransactionClicked(const QModelIndex &index)
{
    if(filter)
        emit transactionClicked(filter->mapToSource(index));
}

OverviewPage::~OverviewPage()
{
    delete ui;
}

void OverviewPage::setBalance(qint64 balance, qint64 stake, qint64 unconfirmedBalance, qint64 immatureBalance)
{
    int unit = model->getOptionsModel()->getDisplayUnit();
    currentBalance = balance;
    currentStake = stake;
    currentUnconfirmedBalance = unconfirmedBalance;
    currentImmatureBalance = immatureBalance;
    ui->labelBalance->setText(tekcoinUnits::formatWithUnit(unit, balance));
    ui->labelStake->setText(tekcoinUnits::formatWithUnit(unit, stake));
    ui->labelUnconfirmed->setText(tekcoinUnits::formatWithUnit(unit, unconfirmedBalance));
    ui->labelImmature->setText(tekcoinUnits::formatWithUnit(unit, immatureBalance));

    // only show immature (newly mined) balance if it's non-zero, so as not to complicate things
    // for the non-mining users
    bool showImmature = immatureBalance != 0;
    ui->labelImmature->setVisible(showImmature);
    ui->labelImmatureText->setVisible(showImmature);
}

void OverviewPage::setNumTransactions(int count)
{
    ui->labelNumTransactions->setText(QLocale::system().toString(count));
}

void OverviewPage::setModel(WalletModel *model)
{
    this->model = model;
    if(model && model->getOptionsModel())
    {
        // Set up transaction list
        filter = new TransactionFilterProxy();
        filter->setSourceModel(model->getTransactionTableModel());
        filter->setLimit(NUM_ITEMS);
        filter->setDynamicSortFilter(true);
        filter->setSortRole(Qt::EditRole);
        filter->sort(TransactionTableModel::Status, Qt::DescendingOrder);

        ui->listTransactions->setModel(filter);
        ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress);

        // Keep up to date with wallet
        setBalance(model->getBalance(), model->getStake(), model->getUnconfirmedBalance(), model->getImmatureBalance());
        connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64, qint64)));

        setNumTransactions(model->getNumTransactions());
        connect(model, SIGNAL(numTransactionsChanged(int)), this, SLOT(setNumTransactions(int)));

        connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
    }

    // update the display unit, to not use the default ("BTC")
    updateDisplayUnit();
}

void OverviewPage::updateDisplayUnit()
{
    if(model && model->getOptionsModel())
    {
        if(currentBalance != -1)
            setBalance(currentBalance, model->getStake(), currentUnconfirmedBalance, currentImmatureBalance);

        // Update txdelegate->unit with the current unit
        txdelegate->unit = model->getOptionsModel()->getDisplayUnit();

        ui->listTransactions->update();
    }
}

void OverviewPage::showOutOfSyncWarning(bool fShow)
{
    ui->labelWalletStatus->setVisible(fShow);
    ui->labelTransactionsStatus->setVisible(fShow);
}
<|endoftext|>


<commit_before>#include "qrcodedialog.h"
#include "ui_qrcodedialog.h"

#include "bitcoinunits.h"
#include "guiconstants.h"
#include "guiutil.h"
#include "optionsmodel.h"

#include <QPixmap>
#include <QUrl>

#include <qrencode.h>

QRCodeDialog::QRCodeDialog(const QString &addr, const QString &label, bool enableReq, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::QRCodeDialog),
    model(0),
    address(addr)
{
    ui->setupUi(this);

    setWindowTitle(QString("%1").arg(address));

    ui->chkReqPayment->setVisible(enableReq);
    ui->lblAmount->setVisible(enableReq);
    ui->lnReqAmount->setVisible(enableReq);

    ui->lnLabel->setText(label);

    ui->btnSaveAs->setEnabled(false);

    genCode();
}

QRCodeDialog::~QRCodeDialog()
{
    delete ui;
}

void QRCodeDialog::setModel(OptionsModel *model)
{
    this->model = model;

    if (model)
        connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));

    // update the display unit, to not use the default ("BTC")
    updateDisplayUnit();
}

void QRCodeDialog::genCode()
{
    QString uri = getURI();

    if (uri != "")
    {
        ui->lblQRCode->setText("");

        QRcode *code = QRcode_encodeString(uri.toUtf8().constData(), 0, QR_ECLEVEL_L, QR_MODE_8, 1);
        if (!code)
        {
            ui->lblQRCode->setText(tr("Error encoding URI into QR Code."));
            return;
        }
        myImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32);
        myImage.fill(0xffffff);
        unsigned char *p = code->data;
        for (int y = 0; y < code->width; y++)
        {
            for (int x = 0; x < code->width; x++)
            {
                myImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff));
                p++;
            }
        }
        QRcode_free(code);

        ui->lblQRCode->setPixmap(QPixmap::fromImage(myImage).scaled(300, 300));

        ui->outUri->setPlainText(uri);
    }
}

QString QRCodeDialog::getURI()
{
    QString ret = QString("FuelCoin:%1").arg(address);
    int paramCount = 0;

    ui->outUri->clear();

    if (ui->chkReqPayment->isChecked())
    {
        if (ui->lnReqAmount->validate())
        {
            // even if we allow a non BTC unit input in lnReqAmount, we generate the URI with BTC as unit (as defined in BIP21)
            ret += QString("?amount=%1").arg(BitcoinUnits::format(BitcoinUnits::BTC, ui->lnReqAmount->value()));
            paramCount++;
        }
        else
        {
            ui->btnSaveAs->setEnabled(false);
            ui->lblQRCode->setText(tr("The entered amount is invalid, please check."));
            return QString("");
        }
    }

    if (!ui->lnLabel->text().isEmpty())
    {
        QString lbl(QUrl::toPercentEncoding(ui->lnLabel->text()));
        ret += QString("%1label=%2").arg(paramCount == 0 ? "?" : "&").arg(lbl);
        paramCount++;
    }

    if (!ui->lnMessage->text().isEmpty())
    {
        QString msg(QUrl::toPercentEncoding(ui->lnMessage->text()));
        ret += QString("%1message=%2").arg(paramCount == 0 ? "?" : "&").arg(msg);
        paramCount++;
    }

    // limit URI length to prevent a DoS against the QR-Code dialog
    if (ret.length() > MAX_URI_LENGTH)
    {
        ui->btnSaveAs->setEnabled(false);
        ui->lblQRCode->setText(tr("Resulting URI too long, try to reduce the text for label / message."));
        return QString("");
    }

    ui->btnSaveAs->setEnabled(true);
    return ret;
}

void QRCodeDialog::on_lnReqAmount_textChanged()
{
    genCode();
}

void QRCodeDialog::on_lnLabel_textChanged()
{
    genCode();
}

void QRCodeDialog::on_lnMessage_textChanged()
{
    genCode();
}

void QRCodeDialog::on_btnSaveAs_clicked()
{
    QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Images (*.png)"));
    if (!fn.isEmpty())
        myImage.scaled(EXPORT_IMAGE_SIZE, EXPORT_IMAGE_SIZE).save(fn);
}

void QRCodeDialog::on_chkReqPayment_toggled(bool fChecked)
{
    if (!fChecked)
        // if chkReqPayment is not active, don't display lnReqAmount as invalid
        ui->lnReqAmount->setValid(true);

    genCode();
}

void QRCodeDialog::updateDisplayUnit()
{
    if (model)
    {
        // Update lnReqAmount with the current unit
        ui->lnReqAmount->setDisplayUnit(model->getDisplayUnit());
    }
}
<commit_msg>Update qrcodedialog.cpp<commit_after>#include "qrcodedialog.h"
#include "ui_qrcodedialog.h"

#include "bitcoinunits.h"
#include "guiconstants.h"
#include "guiutil.h"
#include "optionsmodel.h"

#include <QPixmap>
#include <QUrl>

#include <qrencode.h>

QRCodeDialog::QRCodeDialog(const QString &addr, const QString &label, bool enableReq, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::QRCodeDialog),
    model(0),
    address(addr)
{
    ui->setupUi(this);

    setWindowTitle(QString("%1").arg(address));

    ui->chkReqPayment->setVisible(enableReq);
    ui->lblAmount->setVisible(enableReq);
    ui->lnReqAmount->setVisible(enableReq);

    ui->lnLabel->setText(label);

    ui->btnSaveAs->setEnabled(false);

    genCode();
}

QRCodeDialog::~QRCodeDialog()
{
    delete ui;
}

void QRCodeDialog::setModel(OptionsModel *model)
{
    this->model = model;

    if (model)
        connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));

    // update the display unit, to not use the default ("BTC")
    updateDisplayUnit();
}

void QRCodeDialog::genCode()
{
    QString uri = getURI();

    if (uri != "")
    {
        ui->lblQRCode->setText("");

        QRcode *code = QRcode_encodeString(uri.toUtf8().constData(), 0, QR_ECLEVEL_L, QR_MODE_8, 1);
        if (!code)
        {
            ui->lblQRCode->setText(tr("Error encoding URI into QR Code."));
            return;
        }
        myImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32);
        myImage.fill(0xffffff);
        unsigned char *p = code->data;
        for (int y = 0; y < code->width; y++)
        {
            for (int x = 0; x < code->width; x++)
            {
                myImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff));
                p++;
            }
        }
        QRcode_free(code);

        ui->lblQRCode->setPixmap(QPixmap::fromImage(myImage).scaled(300, 300));

        ui->outUri->setPlainText(uri);
    }
}

QString QRCodeDialog::getURI()
{
    QString ret = QString("Fuelcoin:%1").arg(address);
    int paramCount = 0;

    ui->outUri->clear();

    if (ui->chkReqPayment->isChecked())
    {
        if (ui->lnReqAmount->validate())
        {
            // even if we allow a non BTC unit input in lnReqAmount, we generate the URI with BTC as unit (as defined in BIP21)
            ret += QString("?amount=%1").arg(BitcoinUnits::format(BitcoinUnits::BTC, ui->lnReqAmount->value()));
            paramCount++;
        }
        else
        {
            ui->btnSaveAs->setEnabled(false);
            ui->lblQRCode->setText(tr("The entered amount is invalid, please check."));
            return QString("");
        }
    }

    if (!ui->lnLabel->text().isEmpty())
    {
        QString lbl(QUrl::toPercentEncoding(ui->lnLabel->text()));
        ret += QString("%1label=%2").arg(paramCount == 0 ? "?" : "&").arg(lbl);
        paramCount++;
    }

    if (!ui->lnMessage->text().isEmpty())
    {
        QString msg(QUrl::toPercentEncoding(ui->lnMessage->text()));
        ret += QString("%1message=%2").arg(paramCount == 0 ? "?" : "&").arg(msg);
        paramCount++;
    }

    // limit URI length to prevent a DoS against the QR-Code dialog
    if (ret.length() > MAX_URI_LENGTH)
    {
        ui->btnSaveAs->setEnabled(false);
        ui->lblQRCode->setText(tr("Resulting URI too long, try to reduce the text for label / message."));
        return QString("");
    }

    ui->btnSaveAs->setEnabled(true);
    return ret;
}

void QRCodeDialog::on_lnReqAmount_textChanged()
{
    genCode();
}

void QRCodeDialog::on_lnLabel_textChanged()
{
    genCode();
}

void QRCodeDialog::on_lnMessage_textChanged()
{
    genCode();
}

void QRCodeDialog::on_btnSaveAs_clicked()
{
    QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Images (*.png)"));
    if (!fn.isEmpty())
        myImage.scaled(EXPORT_IMAGE_SIZE, EXPORT_IMAGE_SIZE).save(fn);
}

void QRCodeDialog::on_chkReqPayment_toggled(bool fChecked)
{
    if (!fChecked)
        // if chkReqPayment is not active, don't display lnReqAmount as invalid
        ui->lnReqAmount->setValid(true);

    genCode();
}

void QRCodeDialog::updateDisplayUnit()
{
    if (model)
    {
        // Update lnReqAmount with the current unit
        ui->lnReqAmount->setDisplayUnit(model->getDisplayUnit());
    }
}
<|endoftext|>


<commit_before>/*
    This file is part of KOrganizer.
    Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>

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

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <qlayout.h>
#include <qtextbrowser.h>
#include <qtextcodec.h>
#include <qfileinfo.h>
#include <qlabel.h>

#include <kglobal.h>
#include <klocale.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <kmessagebox.h>

#include <libkcal/calendar.h>

#ifndef KORG_NOPRINTER
#include "calprinter.h"
#endif
#include "koglobals.h"
#include "koprefs.h"
#include "koeventviewerdialog.h"

#include "kowhatsnextview.h"
using namespace KOrg;
#include "kowhatsnextview.moc"

void WhatsNextTextBrowser::setSource(const QString& n)
{
  kdDebug() << "WhatsNextTextBrowser::setSource(): " << n << endl;

  if (n.startsWith("event:")) {
    emit showIncidence(n);
    return;
  } else if (n.startsWith("todo:")) {
    emit showIncidence(n);
    return;
  } else {
    QTextBrowser::setSource(n);
  }
}

KOWhatsNextView::KOWhatsNextView(Calendar *calendar, QWidget *parent,
                                 const char *name)
  : KOrg::BaseView(calendar, parent, name)
{
  QLabel *dateLabel =
      new QLabel(KGlobal::locale()->formatDate(QDate::currentDate()),this);
  dateLabel->setMargin(2);
  dateLabel->setAlignment(AlignCenter);

  mView = new WhatsNextTextBrowser(this);
  connect(mView,SIGNAL(showIncidence(const QString &)),SLOT(showIncidence(const QString &)));

  mEventViewer = 0;

  QBoxLayout *topLayout = new QVBoxLayout(this);
  topLayout->addWidget(dateLabel);
  topLayout->addWidget(mView);
}

KOWhatsNextView::~KOWhatsNextView()
{
}

int KOWhatsNextView::maxDatesHint()
{
  return 0;
}

int KOWhatsNextView::currentDateCount()
{
  return 0;
}

QPtrList<Incidence> KOWhatsNextView::selectedIncidences()
{
  QPtrList<Incidence> eventList;

  return eventList;
}

void KOWhatsNextView::printPreview(CalPrinter *calPrinter, const QDate &fd,
                               const QDate &td)
{
#ifndef KORG_NOPRINTER
  calPrinter->preview(CalPrinter::Day, fd, td);
#endif
}

void KOWhatsNextView::updateView()
{
  KIconLoader kil("korganizer");
  QString *ipath = new QString();
  kil.loadIcon("korganizer",KIcon::NoGroup,32,KIcon::DefaultState,ipath);

  mText = "
\n";
  mText += "

";
  mText += "";
  mText += " What's next?
";
  mText += "
\n
";

  QPtrList<Event> events = calendar()->events( QDate::currentDate(), true );
  if (events.count() > 0) {
    mText += "

";
    kil.loadIcon("appointment",KIcon::NoGroup,22,KIcon::DefaultState,ipath);
    mText += "
";
    mText += i18n("Events:") + "
\n";
    mText += "
\n";
    Event *ev = events.first();
    while(ev) {
      if (!ev->recurrence()->doesRecur() || ev->recursOn( QDate::currentDate())) {
        appendEvent(ev);
      }
      ev = events.next();
    }
    mText += "
\n";
  }

  QPtrList<Todo> todos = calendar()->todos();
  if (todos.count() > 0) {
    kil.loadIcon("todo",KIcon::NoGroup,22,KIcon::DefaultState,ipath);
    mText += "
";
    mText += i18n("To-Do:") + "
\n";
    mText += "
\n";
    Todo *todo = todos.first();
    while(todo) {
      if ( todo->hasDueDate() && todo->dtDue().date() == QDate::currentDate() )
		  appendTodo(todo);
      todo = todos.next();
    }
    bool gotone = false;
    int priority = 1;
    while (!gotone && priority<6) {
      todo = todos.first();
      while(todo) {
	if (!todo->isCompleted() && (todo->priority() == priority) ) {
	  appendTodo(todo);
	  gotone = true;
	}
	todo = todos.next();
      }
      priority++;
      kdDebug() << "adding the todos..." << endl;
    }
    mText += "
\n";
  }

  int replys = 0;
  events = calendar()->events(QDate::currentDate(), QDate(2975,12,6));
  if (events.count() > 0) {
    Event *ev = events.first();
    while(ev) {
      Attendee *me = ev->attendeeByMails(KOPrefs::instance()->mAdditionalMails,KOPrefs::instance()->email());
      if (me!=0) {
        if (me->status()==Attendee::NeedsAction && me->RSVP()) {
          if (replys == 0) {
            mText += "

";
            kil.loadIcon("reply",KIcon::NoGroup,22,KIcon::DefaultState,ipath);
            mText += "
";
            mText += i18n("Events and To-Dos that need a reply:") + "
\n";
            mText += "
\n";
          }
          replys++;
          appendEvent(ev,true);
        }
      }
      ev = events.next();
    }
  }
  todos = calendar()->todos();
  if (todos.count() > 0) {
    Todo *to = todos.first();
    while(to) {
      Attendee *me = to->attendeeByMails(KOPrefs::instance()->mAdditionalMails,KOPrefs::instance()->email());
      if (me!=0) {
        if (me->status()==Attendee::NeedsAction && me->RSVP()) {
          if (replys == 0) {
            mText += "

";
            kil.loadIcon("reply",KIcon::NoGroup,22,KIcon::DefaultState,ipath);
            mText += "
";
            mText += i18n("Events and To-Dos that need a reply:") + "
\n";
            mText += "
\n";
          }
          replys++;
          appendEvent(to);
        }
      }
      kdDebug () << "check for todo-replys..." << endl;
      to = todos.next();
    }
  }
  if (replys > 0 ) mText += "
\n";

  mText += "
\n
\n";

  kdDebug() << "KOWhatsNextView::updateView: text: " << mText << endl;
  mView->setText(mText);
}

void KOWhatsNextView::showDates(const QDate &, const QDate &)
{
  updateView();
}

void KOWhatsNextView::showEvents(QPtrList<Event>)
{
}

void KOWhatsNextView::changeEventDisplay(Event *, int action)
{
  switch(action) {
    case KOGlobals::EVENTADDED:
      break;
    case KOGlobals::EVENTEDITED:
      break;
    case KOGlobals::EVENTDELETED:
      break;
    default:
      kdDebug() << "KOWhatsNextView::changeEventDisplay(): Illegal action " << action << endl;
  }
}

void KOWhatsNextView::appendEvent(Incidence *ev, bool reply)
{
  kdDebug() << "KOWhatsNextView::appendEvent(): " << ev->uid() << endl;

  mText += "
";
  if (!ev->doesFloat()) {
    if (ev->type()=="Event") {
      Event *event = static_cast<Event *>(ev);
      if (reply) mText += "on " + event->dtStartDateStr() + ": ";
      mText += event->dtStartTimeStr() + " - " + event->dtEndTimeStr();
    }
  }
  mText += "	type()=="Event") mText += "href=\"event:";
  if (ev->type()=="Todo") mText += "href=\"todo:";
  mText += ev->uid() + "\">";
  mText += ev->summary();
  mText += "
\n";
}

void KOWhatsNextView::appendTodo(Incidence *ev)
{
  mText += "
uid() + "\">";
  mText += ev->summary();
  mText += "
\n";
}

void KOWhatsNextView::createEventViewer()
{
  if (!mEventViewer) {
    mEventViewer = new KOEventViewerDialog(this);
  }
}

// TODO: Create this function in CalendarView and remove it from here
void KOWhatsNextView::showIncidence(const QString &uid)
{
  kdDebug() << "KOWhatsNextView::showIncidence(): " << uid << endl;

  if (uid.startsWith("event://")) {
    Event *event = calendar()->event(uid.mid(8));
    if (!event) return;
    createEventViewer();
    mEventViewer->setEvent(event);
  } else if (uid.startsWith("todo://")) {
    Todo *todo = calendar()->todo(uid.mid(7));
    if (!todo) return;
    createEventViewer();
    mEventViewer->setTodo(todo);
  }
  mEventViewer->show();
  mEventViewer->raise();
}
<commit_msg>-  mText += " What's next?
"; +  mText += i18n(" What's next?
");<commit_after>/*
    This file is part of KOrganizer.
    Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>

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

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <qlayout.h>
#include <qtextbrowser.h>
#include <qtextcodec.h>
#include <qfileinfo.h>
#include <qlabel.h>

#include <kglobal.h>
#include <klocale.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <kmessagebox.h>

#include <libkcal/calendar.h>

#ifndef KORG_NOPRINTER
#include "calprinter.h"
#endif
#include "koglobals.h"
#include "koprefs.h"
#include "koeventviewerdialog.h"

#include "kowhatsnextview.h"
using namespace KOrg;
#include "kowhatsnextview.moc"

void WhatsNextTextBrowser::setSource(const QString& n)
{
  kdDebug() << "WhatsNextTextBrowser::setSource(): " << n << endl;

  if (n.startsWith("event:")) {
    emit showIncidence(n);
    return;
  } else if (n.startsWith("todo:")) {
    emit showIncidence(n);
    return;
  } else {
    QTextBrowser::setSource(n);
  }
}

KOWhatsNextView::KOWhatsNextView(Calendar *calendar, QWidget *parent,
                                 const char *name)
  : KOrg::BaseView(calendar, parent, name)
{
  QLabel *dateLabel =
      new QLabel(KGlobal::locale()->formatDate(QDate::currentDate()),this);
  dateLabel->setMargin(2);
  dateLabel->setAlignment(AlignCenter);

  mView = new WhatsNextTextBrowser(this);
  connect(mView,SIGNAL(showIncidence(const QString &)),SLOT(showIncidence(const QString &)));

  mEventViewer = 0;

  QBoxLayout *topLayout = new QVBoxLayout(this);
  topLayout->addWidget(dateLabel);
  topLayout->addWidget(mView);
}

KOWhatsNextView::~KOWhatsNextView()
{
}

int KOWhatsNextView::maxDatesHint()
{
  return 0;
}

int KOWhatsNextView::currentDateCount()
{
  return 0;
}

QPtrList<Incidence> KOWhatsNextView::selectedIncidences()
{
  QPtrList<Incidence> eventList;

  return eventList;
}

void KOWhatsNextView::printPreview(CalPrinter *calPrinter, const QDate &fd,
                               const QDate &td)
{
#ifndef KORG_NOPRINTER
  calPrinter->preview(CalPrinter::Day, fd, td);
#endif
}

void KOWhatsNextView::updateView()
{
  KIconLoader kil("korganizer");
  QString *ipath = new QString();
  kil.loadIcon("korganizer",KIcon::NoGroup,32,KIcon::DefaultState,ipath);

  mText = "
\n";
  mText += "

";
  mText += "";
  mText += i18n(" What's next?
");
  mText += "
\n
";

  QPtrList<Event> events = calendar()->events( QDate::currentDate(), true );
  if (events.count() > 0) {
    mText += "

";
    kil.loadIcon("appointment",KIcon::NoGroup,22,KIcon::DefaultState,ipath);
    mText += "
";
    mText += i18n("Events:") + "
\n";
    mText += "
\n";
    Event *ev = events.first();
    while(ev) {
      if (!ev->recurrence()->doesRecur() || ev->recursOn( QDate::currentDate())) {
        appendEvent(ev);
      }
      ev = events.next();
    }
    mText += "
\n";
  }

  QPtrList<Todo> todos = calendar()->todos();
  if (todos.count() > 0) {
    kil.loadIcon("todo",KIcon::NoGroup,22,KIcon::DefaultState,ipath);
    mText += "
";
    mText += i18n("To-Do:") + "
\n";
    mText += "
\n";
    Todo *todo = todos.first();
    while(todo) {
      if ( todo->hasDueDate() && todo->dtDue().date() == QDate::currentDate() )
		  appendTodo(todo);
      todo = todos.next();
    }
    bool gotone = false;
    int priority = 1;
    while (!gotone && priority<6) {
      todo = todos.first();
      while(todo) {
	if (!todo->isCompleted() && (todo->priority() == priority) ) {
	  appendTodo(todo);
	  gotone = true;
	}
	todo = todos.next();
      }
      priority++;
      kdDebug() << "adding the todos..." << endl;
    }
    mText += "
\n";
  }

  int replys = 0;
  events = calendar()->events(QDate::currentDate(), QDate(2975,12,6));
  if (events.count() > 0) {
    Event *ev = events.first();
    while(ev) {
      Attendee *me = ev->attendeeByMails(KOPrefs::instance()->mAdditionalMails,KOPrefs::instance()->email());
      if (me!=0) {
        if (me->status()==Attendee::NeedsAction && me->RSVP()) {
          if (replys == 0) {
            mText += "

";
            kil.loadIcon("reply",KIcon::NoGroup,22,KIcon::DefaultState,ipath);
            mText += "
";
            mText += i18n("Events and To-Dos that need a reply:") + "
\n";
            mText += "
\n";
          }
          replys++;
          appendEvent(ev,true);
        }
      }
      ev = events.next();
    }
  }
  todos = calendar()->todos();
  if (todos.count() > 0) {
    Todo *to = todos.first();
    while(to) {
      Attendee *me = to->attendeeByMails(KOPrefs::instance()->mAdditionalMails,KOPrefs::instance()->email());
      if (me!=0) {
        if (me->status()==Attendee::NeedsAction && me->RSVP()) {
          if (replys == 0) {
            mText += "

";
            kil.loadIcon("reply",KIcon::NoGroup,22,KIcon::DefaultState,ipath);
            mText += "
";
            mText += i18n("Events and To-Dos that need a reply:") + "
\n";
            mText += "
\n";
          }
          replys++;
          appendEvent(to);
        }
      }
      kdDebug () << "check for todo-replys..." << endl;
      to = todos.next();
    }
  }
  if (replys > 0 ) mText += "
\n";

  mText += "
\n
\n";

  kdDebug() << "KOWhatsNextView::updateView: text: " << mText << endl;
  mView->setText(mText);
}

void KOWhatsNextView::showDates(const QDate &, const QDate &)
{
  updateView();
}

void KOWhatsNextView::showEvents(QPtrList<Event>)
{
}

void KOWhatsNextView::changeEventDisplay(Event *, int action)
{
  switch(action) {
    case KOGlobals::EVENTADDED:
      break;
    case KOGlobals::EVENTEDITED:
      break;
    case KOGlobals::EVENTDELETED:
      break;
    default:
      kdDebug() << "KOWhatsNextView::changeEventDisplay(): Illegal action " << action << endl;
  }
}

void KOWhatsNextView::appendEvent(Incidence *ev, bool reply)
{
  kdDebug() << "KOWhatsNextView::appendEvent(): " << ev->uid() << endl;

  mText += "
";
  if (!ev->doesFloat()) {
    if (ev->type()=="Event") {
      Event *event = static_cast<Event *>(ev);
      if (reply) mText += "on " + event->dtStartDateStr() + ": ";
      mText += event->dtStartTimeStr() + " - " + event->dtEndTimeStr();
    }
  }
  mText += "	type()=="Event") mText += "href=\"event:";
  if (ev->type()=="Todo") mText += "href=\"todo:";
  mText += ev->uid() + "\">";
  mText += ev->summary();
  mText += "
\n";
}

void KOWhatsNextView::appendTodo(Incidence *ev)
{
  mText += "
uid() + "\">";
  mText += ev->summary();
  mText += "
\n";
}

void KOWhatsNextView::createEventViewer()
{
  if (!mEventViewer) {
    mEventViewer = new KOEventViewerDialog(this);
  }
}

// TODO: Create this function in CalendarView and remove it from here
void KOWhatsNextView::showIncidence(const QString &uid)
{
  kdDebug() << "KOWhatsNextView::showIncidence(): " << uid << endl;

  if (uid.startsWith("event://")) {
    Event *event = calendar()->event(uid.mid(8));
    if (!event) return;
    createEventViewer();
    mEventViewer->setEvent(event);
  } else if (uid.startsWith("todo://")) {
    Todo *todo = calendar()->todo(uid.mid(7));
    if (!todo) return;
    createEventViewer();
    mEventViewer->setTodo(todo);
  }
  mEventViewer->show();
  mEventViewer->raise();
}
<|endoftext|>


<commit_before>//
// Created by dar on 11/25/15.
//

#include "Renderer.h"

Renderer::Renderer(Core *core) : core(core) { }

bool Renderer::init() {
    if (!this->initWindow()) {
        printf("Failed to initialize window!\n");
    } else if (!this->initGL()) {
        printf("Unable to initialize OpenGL!\n");
    } else if (!this->initTextures()) {
        printf("Unable to initialize textures!\n");
    } else {
        initRenderers();
        initTexData();
        fbo.init(3, windowWidth, windowHeight, new float[4]{0.9, 0.9, 0.9, 1.0}, "fboshader");
        return true;
    }
    return false;
}

bool Renderer::initWindow() {
    bool success = true;

    if (SDL_Init(SDL_INIT_VIDEO) < 0) { //Initialize SDL
        printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
        success = false;
    }
    else {
        //Use OpenGL 3.3
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);

        //Create window
        gWindow = SDL_CreateWindow("C003", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, windowWidth, windowHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
        if (gWindow == NULL) {
            printf("Window could not be created! SDL Error: %s\n", SDL_GetError());
            success = false;
        }
        else {
            gContext = SDL_GL_CreateContext(gWindow); //Create context
            if (gContext == NULL) {
                printf("OpenGL context could not be created! SDL Error: %s\n", SDL_GetError());
                success = false;
            } else {
                //Use Vsync
                if (SDL_GL_SetSwapInterval(1) < 0) {
                    printf("Warning: Unable to set VSync! SDL Error: %s\n", SDL_GetError());
                }
            }
        }
    }

    return success;
}

bool Renderer::initGL() {
    viewMatrix = glm::lookAt(glm::vec3(0, 0, 0.0f), glm::vec3(0, 0, 1.0f), glm::vec3(0.0f, 1.0f, 0.0f));
    projectionMatrix = glm::ortho(0.0f, float(windowWidth), 0.0f, float(windowHeight));
    glEnable(GL_TEXTURE_2D);
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    return true;
}

bool Renderer::initTextures() {
    bool ret = true;
    if (!textureAtlas.loadTexture2D("terrain.png", true)) ret = false;
    textureAtlas.setFiltering(TEXTURE_FILTER_MAG_BILINEAR, TEXTURE_FILTER_MIN_BILINEAR_MIPMAP);
    return ret;
}

void Renderer::tick() {
    fbo.bind();
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);
    textureAtlas.bindTexture(0);
    for (Block *block : core->getMap()->getBlocks()) {
        if (block->getX() * this->core->getGeneralScale() * this->core->getBlockSize() > -(signed) windowWidth / 2.0f - this->core->getCamX() &&
            (block->getX() - 1) * this->core->getGeneralScale() * this->core->getBlockSize() < -(signed) windowWidth / 2.0f - this->core->getCamX() + (signed) windowWidth &&
            block->getY() * this->core->getGeneralScale() * this->core->getBlockSize() > -(signed) windowHeight / 2.0f - this->core->getCamY() &&
            (block->getY() - 1) * this->core->getGeneralScale() * this->core->getBlockSize() < -(signed) windowHeight / 2.0f - this->core->getCamY() + (signed) windowHeight)
            getBlockRender(block)->render(block, textureAtlas.getBoundId(), projectionMatrix, glm::translate(viewMatrix, glm::vec3(
                (int) (-(signed) windowWidth / 2.0f - this->core->getCamX()),
                (int) ((signed) windowHeight / 2.0f - this->core->getCamY()), 0.0f
            )), this->core->getBlockSize() * this->core->getGeneralScale());
    }
    int entitiesNum = 0;
    for (int i = core->getMap()->getEntities().size() - 1; i >= 0; i--) {
        Entity *entity = core->getMap()->getEntities().at(i);
        if (entity->getX() * this->core->getGeneralScale() * this->core->getBlockSize() > -(signed) windowWidth / 2.0f - this->core->getCamX() &&
            (entity->getX() - 1) * this->core->getGeneralScale() * this->core->getBlockSize() < -(signed) windowWidth / 2.0f - this->core->getCamX() + (signed) windowWidth &&
            entity->getY() * this->core->getGeneralScale() * this->core->getBlockSize() > -(signed) windowHeight / 2.0f - this->core->getCamY() &&
            (entity->getY() - 1) * this->core->getGeneralScale() * this->core->getBlockSize() < -(signed) windowHeight / 2.0f - this->core->getCamY() + (signed) windowHeight) {
            getEntityRender(entity)->render(entity, projectionMatrix, glm::translate(viewMatrix, glm::vec3(
                (int) (-(signed) windowWidth / 2.0f - this->core->getCamX()),
                (int) ((signed) windowHeight / 2.0f - this->core->getCamY()),
                0.0f)), this->core->getBlockSize() * this->core->getGeneralScale());
            fbo.getShaderProgram()->useProgram();
            if (entity != this->core->getPlayer() && entitiesNum < fbo.MAX_LIGHT_SRCS) {
                fbo.getShaderProgram()->setUniform("lightPoints[" + to_string(entitiesNum) + "]",
                                                   glm::vec2(this->core->getCamX() + (entity->getX() - 0.5 + entity->getWidth() / 2) * this->core->getBlockSize() * this->core->getGeneralScale() + (double) this->windowWidth / 2,
                                                             -this->core->getCamY() - (entity->getY() - 0.5 + entity->getHeight() / 2) * this->core->getBlockSize() * this->core->getGeneralScale() + (double) this->windowHeight / 2));
                entitiesNum++;
            }
        }
    }
    fbo.unbind();
    fbo.getShaderProgram()->useProgram();
    fbo.getShaderProgram()->setUniform("lightPointsNum", entitiesNum);
    fbo.getShaderProgram()->setUniform("scale", (float)(this->core->getBlockSize() * this->core->getGeneralScale()));
    fbo.render(0);
}

void Renderer::run() {
    this->tick();
    SDL_GL_SwapWindow(gWindow);
}

void Renderer::resize(unsigned int width, unsigned int height) {
    if (width != this->windowWidth || height != this->windowHeight) {
        this->windowWidth = width;
        this->windowHeight = height;
        glViewport(0, 0, windowWidth, windowHeight);
        viewMatrix = glm::lookAt(glm::vec3(0, 0, 0.0f), glm::vec3(0, 0, 1.0f), glm::vec3(0.0f, 1.0f, 0.0f));
        this->projectionMatrix = glm::ortho(0.0f, float(windowWidth), 0.0f, float(windowHeight));
        this->fbo.resize(this->windowWidth, this->windowHeight);
    }
}

Renderer::~Renderer() {
    SDL_DestroyWindow(this->gWindow);
    SDL_Quit();
}
<commit_msg>Adjusted light position<commit_after>//
// Created by dar on 11/25/15.
//

#include "Renderer.h"

Renderer::Renderer(Core *core) : core(core) { }

bool Renderer::init() {
    if (!this->initWindow()) {
        printf("Failed to initialize window!\n");
    } else if (!this->initGL()) {
        printf("Unable to initialize OpenGL!\n");
    } else if (!this->initTextures()) {
        printf("Unable to initialize textures!\n");
    } else {
        initRenderers();
        initTexData();
        fbo.init(3, windowWidth, windowHeight, new float[4]{0.9, 0.9, 0.9, 1.0}, "fboshader");
        return true;
    }
    return false;
}

bool Renderer::initWindow() {
    bool success = true;

    if (SDL_Init(SDL_INIT_VIDEO) < 0) { //Initialize SDL
        printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
        success = false;
    }
    else {
        //Use OpenGL 3.3
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);

        //Create window
        gWindow = SDL_CreateWindow("C003", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, windowWidth, windowHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
        if (gWindow == NULL) {
            printf("Window could not be created! SDL Error: %s\n", SDL_GetError());
            success = false;
        }
        else {
            gContext = SDL_GL_CreateContext(gWindow); //Create context
            if (gContext == NULL) {
                printf("OpenGL context could not be created! SDL Error: %s\n", SDL_GetError());
                success = false;
            } else {
                //Use Vsync
                if (SDL_GL_SetSwapInterval(1) < 0) {
                    printf("Warning: Unable to set VSync! SDL Error: %s\n", SDL_GetError());
                }
            }
        }
    }

    return success;
}

bool Renderer::initGL() {
    viewMatrix = glm::lookAt(glm::vec3(0, 0, 0.0f), glm::vec3(0, 0, 1.0f), glm::vec3(0.0f, 1.0f, 0.0f));
    projectionMatrix = glm::ortho(0.0f, float(windowWidth), 0.0f, float(windowHeight));
    glEnable(GL_TEXTURE_2D);
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    return true;
}

bool Renderer::initTextures() {
    bool ret = true;
    if (!textureAtlas.loadTexture2D("terrain.png", true)) ret = false;
    textureAtlas.setFiltering(TEXTURE_FILTER_MAG_BILINEAR, TEXTURE_FILTER_MIN_BILINEAR_MIPMAP);
    return ret;
}

void Renderer::tick() {
    fbo.bind();
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);
    textureAtlas.bindTexture(0);
    for (Block *block : core->getMap()->getBlocks()) {
        if (block->getX() * this->core->getGeneralScale() * this->core->getBlockSize() > -(signed) windowWidth / 2.0f - this->core->getCamX() &&
            (block->getX() - 1) * this->core->getGeneralScale() * this->core->getBlockSize() < -(signed) windowWidth / 2.0f - this->core->getCamX() + (signed) windowWidth &&
            block->getY() * this->core->getGeneralScale() * this->core->getBlockSize() > -(signed) windowHeight / 2.0f - this->core->getCamY() &&
            (block->getY() - 1) * this->core->getGeneralScale() * this->core->getBlockSize() < -(signed) windowHeight / 2.0f - this->core->getCamY() + (signed) windowHeight)
            getBlockRender(block)->render(block, textureAtlas.getBoundId(), projectionMatrix, glm::translate(viewMatrix, glm::vec3(
                (int) (-(signed) windowWidth / 2.0f - this->core->getCamX()),
                (int) ((signed) windowHeight / 2.0f - this->core->getCamY()), 0.0f
            )), this->core->getBlockSize() * this->core->getGeneralScale());
    }
    int entitiesNum = 0;
    for (int i = core->getMap()->getEntities().size() - 1; i >= 0; i--) {
        Entity *entity = core->getMap()->getEntities().at(i);
        if (entity->getX() * this->core->getGeneralScale() * this->core->getBlockSize() > -(signed) windowWidth / 2.0f - this->core->getCamX() &&
            (entity->getX() - 1) * this->core->getGeneralScale() * this->core->getBlockSize() < -(signed) windowWidth / 2.0f - this->core->getCamX() + (signed) windowWidth &&
            entity->getY() * this->core->getGeneralScale() * this->core->getBlockSize() > -(signed) windowHeight / 2.0f - this->core->getCamY() &&
            (entity->getY() - 1) * this->core->getGeneralScale() * this->core->getBlockSize() < -(signed) windowHeight / 2.0f - this->core->getCamY() + (signed) windowHeight) {
            getEntityRender(entity)->render(entity, projectionMatrix, glm::translate(viewMatrix, glm::vec3(
                (int) (-(signed) windowWidth / 2.0f - this->core->getCamX()),
                (int) ((signed) windowHeight / 2.0f - this->core->getCamY()),
                0.0f)), this->core->getBlockSize() * this->core->getGeneralScale());
            fbo.getShaderProgram()->useProgram();
            if (entity != this->core->getPlayer() && entitiesNum < fbo.MAX_LIGHT_SRCS) {
                fbo.getShaderProgram()->setUniform("lightPoints[" + to_string(entitiesNum) + "]",
                                                   glm::vec2(this->core->getCamX() + (entity->getX() - 1 + entity->getWidth() / 2) * this->core->getBlockSize() * this->core->getGeneralScale() + (double) this->windowWidth / 2,
                                                             -this->core->getCamY() - (entity->getY() - 1 + entity->getHeight() / 2) * this->core->getBlockSize() * this->core->getGeneralScale() + (double) this->windowHeight / 2));
                entitiesNum++;
            }
        }
    }
    fbo.unbind();
    fbo.getShaderProgram()->useProgram();
    fbo.getShaderProgram()->setUniform("lightPointsNum", entitiesNum);
    fbo.getShaderProgram()->setUniform("scale", (float) (this->core->getBlockSize() * this->core->getGeneralScale()));
    fbo.render(0);
}

void Renderer::run() {
    this->tick();
    SDL_GL_SwapWindow(gWindow);
}

void Renderer::resize(unsigned int width, unsigned int height) {
    if (width != this->windowWidth || height != this->windowHeight) {
        this->windowWidth = width;
        this->windowHeight = height;
        glViewport(0, 0, windowWidth, windowHeight);
        viewMatrix = glm::lookAt(glm::vec3(0, 0, 0.0f), glm::vec3(0, 0, 1.0f), glm::vec3(0.0f, 1.0f, 0.0f));
        this->projectionMatrix = glm::ortho(0.0f, float(windowWidth), 0.0f, float(windowHeight));
        this->fbo.resize(this->windowWidth, this->windowHeight);
    }
}

Renderer::~Renderer() {
    SDL_DestroyWindow(this->gWindow);
    SDL_Quit();
}
<|endoftext|>


<commit_before>/* RTcmix  - Copyright (C) 2005  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <rtcmix_types.h>
#include <tableutils.h>
#include <PField.h>
#include <utils.h>
#include <ugens.h>		// for warn, die

// Functions for modifying table PFields.   -JGG, 4/8/05

#define NORMALIZE_USAGE "table = modtable(table, \"normalize\" [, peak])"
#define REVERSE_USAGE "table = modtable(table, \"reverse\")"
#define SHIFT_USAGE "table = modtable(table, \"shift\", shift)"

// =============================================================================
// local utilities

static PField *_modtable_usage(const char *msg)
{
	die(NULL, "Usage: %s", msg);
	return NULL;
}

// =============================================================================
// Set up the various table modifications.

// Rescale the values in table so that the maximum absolute value is <peak>.
// If no <peak>, peak is 1.  Result depends on the sign of values in the table.
//
//    sign of values          resulting range of values
//    --------------------------------------------------------------
//    all positive            between 0 and peak
//    all negative            between 0 and -peak
//    positive and negative   between -peak and peak

static PField *
_normalize_table(PField *intable, const Arg args[], const int nargs)
{
	double peak = 1.0;
	if (nargs > 0)
		peak = (double) args[0];
	if (peak == 0.0)
		peak = 0.00001;
	const int len = intable->values();
	const double *array = (double *) *intable;
	double max = 0.0;
	for (int i = 0; i < len; i++) {
		double absval = fabs(array[i]);
		if (absval > max)
			max = absval;
	}
	max /= peak;
	if (max == 0.0)
		return intable;
	PField *factorpf = new ConstPField(1.0 / max);
	return new MultPField(intable, factorpf);
}

static PField *
_reverse_table(PField *intable, const Arg args[], const int nargs)
{
	return new ReversePField(intable);
}

static PField *
_shift_table(PField *intable, const Arg args[], const int nargs)
{
	if (nargs < 1)
		return _modtable_usage(SHIFT_USAGE);
	const int shift = (int) args[0];
	return new ShiftPField(intable, shift);
}

// =============================================================================
// The remaining functions are public, callable from scripts.

extern "C" {
	Handle modtable(const Arg args[], const int nargs);
}

// ---------------------------------------------------------------- modtable ---
static Handle _modtable_usage()
{
	die("modtable",
		"\n   usage: " NORMALIZE_USAGE
		"\nOR"
		"\n   usage: " REVERSE_USAGE
		"\nOR"
		"\n   usage: " SHIFT_USAGE
		"\n");
	return NULL;
}

Handle modtable(const Arg args[], const int nargs)
{
	if (nargs < 2)
		return _modtable_usage();

	PField *intable = (PField *) args[0];
	if (intable == NULL || !is_table(intable))
		return _modtable_usage();

	PField *outtable = NULL;
	if (args[1].isType(StringType)) {
		if (args[1] == "normalize")
			outtable = _normalize_table(intable, &args[2], nargs - 2);
		else if (args[1] == "reverse")
			outtable = _reverse_table(intable, &args[2], nargs - 2);
		else if (args[1] == "shift")
			outtable = _shift_table(intable, &args[2], nargs - 2);
		else {
			die("modtable", "Unsupported modification \"%s\".",
								(const char *) args[1]);
			return NULL;
		}
	}
	else
		return _modtable_usage();
	return (outtable == NULL) ? NULL : createPFieldHandle(outtable);
}

<commit_msg>shift comment.<commit_after>/* RTcmix  - Copyright (C) 2005  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <rtcmix_types.h>
#include <tableutils.h>
#include <PField.h>
#include <utils.h>
#include <ugens.h>		// for warn, die

// Functions for modifying table PFields.   -JGG, 4/8/05

#define NORMALIZE_USAGE "table = modtable(table, \"normalize\" [, peak])"
#define REVERSE_USAGE "table = modtable(table, \"reverse\")"
#define SHIFT_USAGE "table = modtable(table, \"shift\", shift)"

// =============================================================================
// local utilities

static PField *_modtable_usage(const char *msg)
{
	die(NULL, "Usage: %s", msg);
	return NULL;
}

// =============================================================================
// Set up the various table modifications.

// Rescale the values in table so that the maximum absolute value is <peak>.
// If no <peak>, peak is 1.  Result depends on the sign of values in the table.
//
//    sign of values          resulting range of values
//    --------------------------------------------------------------
//    all positive            between 0 and peak
//    all negative            between 0 and -peak
//    positive and negative   between -peak and peak

static PField *
_normalize_table(PField *intable, const Arg args[], const int nargs)
{
	double peak = 1.0;
	if (nargs > 0)
		peak = (double) args[0];
	if (peak == 0.0)
		peak = 0.00001;
	const int len = intable->values();
	const double *array = (double *) *intable;
	double max = 0.0;
	for (int i = 0; i < len; i++) {
		double absval = fabs(array[i]);
		if (absval > max)
			max = absval;
	}
	max /= peak;
	if (max == 0.0)
		return intable;
	PField *factorpf = new ConstPField(1.0 / max);
	return new MultPField(intable, factorpf);
}

static PField *
_reverse_table(PField *intable, const Arg args[], const int nargs)
{
	return new ReversePField(intable);
}

// Shift values of the table by <shift> array locations.  Positive values of
// <shift> shift to the right; negative values to the left.  If a value is
// shifted off the end of the array in either direction, it reenters the other
// end of the array.  Two examples:
//
//    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      original table, size = 10
//    [7, 8, 9, 0, 1, 2, 3, 4, 5, 6]      shift = 3
//    [3, 4, 5, 6, 7, 8, 9, 0, 1, 2]      shift = -3
//
// Note that the shifting is actually done on-the-fly by ShiftPField.

static PField *
_shift_table(PField *intable, const Arg args[], const int nargs)
{
	if (nargs < 1)
		return _modtable_usage(SHIFT_USAGE);
	const int shift = (int) args[0];
	return new ShiftPField(intable, shift);
}

// =============================================================================
// The remaining functions are public, callable from scripts.

extern "C" {
	Handle modtable(const Arg args[], const int nargs);
}

// ---------------------------------------------------------------- modtable ---
static Handle _modtable_usage()
{
	die("modtable",
		"\n   usage: " NORMALIZE_USAGE
		"\nOR"
		"\n   usage: " REVERSE_USAGE
		"\nOR"
		"\n   usage: " SHIFT_USAGE
		"\n");
	return NULL;
}

Handle modtable(const Arg args[], const int nargs)
{
	if (nargs < 2)
		return _modtable_usage();

	PField *intable = (PField *) args[0];
	if (intable == NULL || !is_table(intable))
		return _modtable_usage();

	PField *outtable = NULL;
	if (args[1].isType(StringType)) {
		if (args[1] == "normalize")
			outtable = _normalize_table(intable, &args[2], nargs - 2);
		else if (args[1] == "reverse")
			outtable = _reverse_table(intable, &args[2], nargs - 2);
		else if (args[1] == "shift")
			outtable = _shift_table(intable, &args[2], nargs - 2);
		else {
			die("modtable", "Unsupported modification \"%s\".",
								(const char *) args[1]);
			return NULL;
		}
	}
	else
		return _modtable_usage();
	return (outtable == NULL) ? NULL : createPFieldHandle(outtable);
}

<|endoftext|>


<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2017-2020 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "script/standard.h"

#include "pubkey.h"
#include "script/script.h"
#include "util.h"
#include "utilstrencodings.h"

typedef std::vector<unsigned char> valtype;

unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY;

CScriptID::CScriptID(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {}

const char* GetTxnOutputType(txnouttype t)
{
    switch (t)
    {
    case TX_NONSTANDARD: return "nonstandard";
    case TX_PUBKEY: return "pubkey";
    case TX_PUBKEYHASH: return "pubkeyhash";
    case TX_SCRIPTHASH: return "scripthash";
    case TX_MULTISIG: return "multisig";
    case TX_COLDSTAKE: return "coldstake";
    case TX_NULL_DATA: return "nulldata";
    case TX_ZEROCOINMINT: return "zerocoinmint";
    }
    return NULL;
}

static bool MatchPayToPubkey(const CScript& script, valtype& pubkey)
{
    if (script.size() == CPubKey::PUBLIC_KEY_SIZE + 2 && script[0] == CPubKey::PUBLIC_KEY_SIZE && script.back() == OP_CHECKSIG) {
        pubkey = valtype(script.begin() + 1, script.begin() + CPubKey::PUBLIC_KEY_SIZE + 1);
        return CPubKey::ValidSize(pubkey);
    }
    if (script.size() == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE + 2 && script[0] == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE && script.back() == OP_CHECKSIG) {
        pubkey = valtype(script.begin() + 1, script.begin() + CPubKey::COMPRESSED_PUBLIC_KEY_SIZE + 1);
        return CPubKey::ValidSize(pubkey);
    }
    return false;
}

static bool MatchPayToPubkeyHash(const CScript& script, valtype& pubkeyhash)
{
    if (script.size() == 25 && script[0] == OP_DUP && script[1] == OP_HASH160 && script[2] == 20 && script[23] == OP_EQUALVERIFY && script[24] == OP_CHECKSIG) {
        pubkeyhash = valtype(script.begin () + 3, script.begin() + 23);
        return true;
    }
    return false;
}

static bool MatchPayToColdStaking(const CScript& script, valtype& stakerPubKeyHash, valtype& ownerPubKeyHash)
{
    if (script.IsPayToColdStaking()) {
        stakerPubKeyHash = valtype(script.begin () + 6, script.begin() + 26);
        ownerPubKeyHash = valtype(script.begin () + 28, script.begin() + 48);
        return true;
    }
    return false;
}

/** Test for "small positive integer" script opcodes - OP_1 through OP_16. */
static constexpr bool IsSmallInteger(opcodetype opcode)
{
    return opcode >= OP_1 && opcode <= OP_16;
}

static bool MatchMultisig(const CScript& script, unsigned int& required, std::vector<valtype>& pubkeys)
{
    opcodetype opcode;
    valtype data;
    CScript::const_iterator it = script.begin();
    if (script.size() < 1 || script.back() != OP_CHECKMULTISIG) return false;

    if (!script.GetOp(it, opcode, data) || !IsSmallInteger(opcode)) return false;
    required = CScript::DecodeOP_N(opcode);
    while (script.GetOp(it, opcode, data) && CPubKey::ValidSize(data)) {
        pubkeys.emplace_back(std::move(data));
    }
    if (!IsSmallInteger(opcode)) return false;
    unsigned int keys = CScript::DecodeOP_N(opcode);
    if (pubkeys.size() != keys || keys < required) return false;
    return (it + 1 == script.end());
}

/**
 * Return public keys or hashes from scriptPubKey, for 'standard' transaction types.
 */
bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet)
{
    vSolutionsRet.clear();

    // Shortcut for pay-to-script-hash, which are more constrained than the other types:
    // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
    if (scriptPubKey.IsPayToScriptHash())
    {
        typeRet = TX_SCRIPTHASH;
        std::vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22);
        vSolutionsRet.push_back(hashBytes);
        return true;
    }

    // Zerocoin
    if (scriptPubKey.IsZerocoinMint()) {
        typeRet = TX_ZEROCOINMINT;
        if(scriptPubKey.size() > 150) return false;
        std::vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.end());
        vSolutionsRet.push_back(hashBytes);
        return true;
    }

    // Provably prunable, data-carrying output
    //
    // So long as script passes the IsUnspendable() test and all but the first
    // byte passes the IsPushOnly() test we don't care what exactly is in the
    // script.
    if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) {
        typeRet = TX_NULL_DATA;
        return true;
    }

    std::vector<unsigned char> data;
    if (MatchPayToPubkey(scriptPubKey, data)) {
        typeRet = TX_PUBKEY;
        vSolutionsRet.push_back(std::move(data));
        return true;
    }

    if (MatchPayToPubkeyHash(scriptPubKey, data)) {
        typeRet = TX_PUBKEYHASH;
        vSolutionsRet.push_back(std::move(data));
        return true;
    }

    std::vector<unsigned char> data1;
    if (MatchPayToColdStaking(scriptPubKey, data, data1)) {
        typeRet = TX_COLDSTAKE;
        vSolutionsRet.push_back(std::move(data));
        vSolutionsRet.push_back(std::move(data1));
        return true;
    }

    unsigned int required;
    std::vector<std::vector<unsigned char>> keys;
    if (MatchMultisig(scriptPubKey, required, keys)) {
        typeRet = TX_MULTISIG;
        vSolutionsRet.push_back({static_cast<unsigned char>(required)}); // safe as required is in range 1..16
        vSolutionsRet.insert(vSolutionsRet.end(), keys.begin(), keys.end());
        vSolutionsRet.push_back({static_cast<unsigned char>(keys.size())}); // safe as size is in range 1..16
        return true;
    }

    vSolutionsRet.clear();
    typeRet = TX_NONSTANDARD;
    return false;
}

int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions)
{
    switch (t)
    {
    case TX_NONSTANDARD:
    case TX_NULL_DATA:
    case TX_ZEROCOINMINT:
        return -1;
    case TX_PUBKEY:
        return 1;
    case TX_PUBKEYHASH:
        return 2;
    case TX_COLDSTAKE:
        return 3;
    case TX_MULTISIG:
        if (vSolutions.size() < 1 || vSolutions[0].size() < 1)
            return -1;
        return vSolutions[0][0] + 1;
    case TX_SCRIPTHASH:
        return 1; // doesn't include args needed by the script
    }
    return -1;
}

bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet, bool fColdStake)
{
    std::vector<valtype> vSolutions;
    txnouttype whichType;
    if (!Solver(scriptPubKey, whichType, vSolutions))
        return false;

    if (whichType == TX_PUBKEY) {
        CPubKey pubKey(vSolutions[0]);
        if (!pubKey.IsValid())
            return false;

        addressRet = pubKey.GetID();
        return true;

    } else if (whichType == TX_PUBKEYHASH) {
        addressRet = CKeyID(uint160(vSolutions[0]));
        return true;

    } else if (whichType == TX_SCRIPTHASH) {
        addressRet = CScriptID(uint160(vSolutions[0]));
        return true;
    } else if (whichType == TX_COLDSTAKE) {
        addressRet = CKeyID(uint160(vSolutions[!fColdStake]));
        return true;
    }
    // Multisig txns have more than one address...
    return false;
}

bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet)
{
    addressRet.clear();
    typeRet = TX_NONSTANDARD;
    std::vector<valtype> vSolutions;
    if (!Solver(scriptPubKey, typeRet, vSolutions))
        return false;
    if (typeRet == TX_NULL_DATA){
        // This is data, not addresses
        return false;
    }

    if (typeRet == TX_MULTISIG)
    {
        nRequiredRet = vSolutions.front()[0];
        for (unsigned int i = 1; i < vSolutions.size()-1; i++)
        {
            CPubKey pubKey(vSolutions[i]);
            if (!pubKey.IsValid())
                continue;

            CTxDestination address = pubKey.GetID();
            addressRet.push_back(address);
        }

        if (addressRet.empty())
            return false;

    } else if (typeRet == TX_COLDSTAKE)
    {
        if (vSolutions.size() < 2)
            return false;
        nRequiredRet = 2;
        addressRet.push_back(CKeyID(uint160(vSolutions[0])));
        addressRet.push_back(CKeyID(uint160(vSolutions[1])));
        return true;

    } else
    {
        nRequiredRet = 1;
        CTxDestination address;
        if (!ExtractDestination(scriptPubKey, address))
           return false;
        addressRet.push_back(address);
    }

    return true;
}

namespace
{
class CScriptVisitor : public boost::static_visitor<bool>
{
private:
    CScript *script;
public:
    CScriptVisitor(CScript *scriptin) { script = scriptin; }

    bool operator()(const CNoDestination &dest) const {
        script->clear();
        return false;
    }

    bool operator()(const CKeyID &keyID) const {
        script->clear();
        *script << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
        return true;
    }

    bool operator()(const CScriptID &scriptID) const {
        script->clear();
        *script << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
        return true;
    }
};
}

CScript GetScriptForDestination(const CTxDestination& dest)
{
    CScript script;

    boost::apply_visitor(CScriptVisitor(&script), dest);
    return script;
}

CScript GetScriptForRawPubKey(const CPubKey& pubKey)
{
    return CScript() << std::vector<unsigned char>(pubKey.begin(), pubKey.end()) << OP_CHECKSIG;
}

CScript GetScriptForStakeDelegation(const CKeyID& stakingKey, const CKeyID& spendingKey)
{
    CScript script;
    script << OP_DUP << OP_HASH160 << OP_ROT <<
            OP_IF << OP_CHECKCOLDSTAKEVERIFY << ToByteVector(stakingKey) <<
            OP_ELSE << ToByteVector(spendingKey) << OP_ENDIF <<
            OP_EQUALVERIFY << OP_CHECKSIG;
    return script;
}

CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys)
{
    CScript script;

    script << CScript::EncodeOP_N(nRequired);
    for (const CPubKey& key : keys)
        script << ToByteVector(key);
    script << CScript::EncodeOP_N(keys.size()) << OP_CHECKMULTISIG;
    return script;
}

bool IsValidDestination(const CTxDestination& dest) {
    return dest.which() != 0;
}
<commit_msg>Solver return false for empty scripts.<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2017-2020 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "script/standard.h"

#include "pubkey.h"
#include "script/script.h"
#include "util.h"
#include "utilstrencodings.h"

typedef std::vector<unsigned char> valtype;

unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY;

CScriptID::CScriptID(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {}

const char* GetTxnOutputType(txnouttype t)
{
    switch (t)
    {
    case TX_NONSTANDARD: return "nonstandard";
    case TX_PUBKEY: return "pubkey";
    case TX_PUBKEYHASH: return "pubkeyhash";
    case TX_SCRIPTHASH: return "scripthash";
    case TX_MULTISIG: return "multisig";
    case TX_COLDSTAKE: return "coldstake";
    case TX_NULL_DATA: return "nulldata";
    case TX_ZEROCOINMINT: return "zerocoinmint";
    }
    return NULL;
}

static bool MatchPayToPubkey(const CScript& script, valtype& pubkey)
{
    if (script.size() == CPubKey::PUBLIC_KEY_SIZE + 2 && script[0] == CPubKey::PUBLIC_KEY_SIZE && script.back() == OP_CHECKSIG) {
        pubkey = valtype(script.begin() + 1, script.begin() + CPubKey::PUBLIC_KEY_SIZE + 1);
        return CPubKey::ValidSize(pubkey);
    }
    if (script.size() == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE + 2 && script[0] == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE && script.back() == OP_CHECKSIG) {
        pubkey = valtype(script.begin() + 1, script.begin() + CPubKey::COMPRESSED_PUBLIC_KEY_SIZE + 1);
        return CPubKey::ValidSize(pubkey);
    }
    return false;
}

static bool MatchPayToPubkeyHash(const CScript& script, valtype& pubkeyhash)
{
    if (script.size() == 25 && script[0] == OP_DUP && script[1] == OP_HASH160 && script[2] == 20 && script[23] == OP_EQUALVERIFY && script[24] == OP_CHECKSIG) {
        pubkeyhash = valtype(script.begin () + 3, script.begin() + 23);
        return true;
    }
    return false;
}

static bool MatchPayToColdStaking(const CScript& script, valtype& stakerPubKeyHash, valtype& ownerPubKeyHash)
{
    if (script.IsPayToColdStaking()) {
        stakerPubKeyHash = valtype(script.begin () + 6, script.begin() + 26);
        ownerPubKeyHash = valtype(script.begin () + 28, script.begin() + 48);
        return true;
    }
    return false;
}

/** Test for "small positive integer" script opcodes - OP_1 through OP_16. */
static constexpr bool IsSmallInteger(opcodetype opcode)
{
    return opcode >= OP_1 && opcode <= OP_16;
}

static bool MatchMultisig(const CScript& script, unsigned int& required, std::vector<valtype>& pubkeys)
{
    opcodetype opcode;
    valtype data;
    CScript::const_iterator it = script.begin();
    if (script.size() < 1 || script.back() != OP_CHECKMULTISIG) return false;

    if (!script.GetOp(it, opcode, data) || !IsSmallInteger(opcode)) return false;
    required = CScript::DecodeOP_N(opcode);
    while (script.GetOp(it, opcode, data) && CPubKey::ValidSize(data)) {
        pubkeys.emplace_back(std::move(data));
    }
    if (!IsSmallInteger(opcode)) return false;
    unsigned int keys = CScript::DecodeOP_N(opcode);
    if (pubkeys.size() != keys || keys < required) return false;
    return (it + 1 == script.end());
}

/**
 * Return public keys or hashes from scriptPubKey, for 'standard' transaction types.
 */
bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet)
{
    if (scriptPubKey.empty())
        return false;

    vSolutionsRet.clear();

    // Shortcut for pay-to-script-hash, which are more constrained than the other types:
    // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
    if (scriptPubKey.IsPayToScriptHash())
    {
        typeRet = TX_SCRIPTHASH;
        std::vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22);
        vSolutionsRet.push_back(hashBytes);
        return true;
    }

    // Zerocoin
    if (scriptPubKey.IsZerocoinMint()) {
        typeRet = TX_ZEROCOINMINT;
        if(scriptPubKey.size() > 150) return false;
        std::vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.end());
        vSolutionsRet.push_back(hashBytes);
        return true;
    }

    // Provably prunable, data-carrying output
    //
    // So long as script passes the IsUnspendable() test and all but the first
    // byte passes the IsPushOnly() test we don't care what exactly is in the
    // script.
    if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) {
        typeRet = TX_NULL_DATA;
        return true;
    }

    std::vector<unsigned char> data;
    if (MatchPayToPubkey(scriptPubKey, data)) {
        typeRet = TX_PUBKEY;
        vSolutionsRet.push_back(std::move(data));
        return true;
    }

    if (MatchPayToPubkeyHash(scriptPubKey, data)) {
        typeRet = TX_PUBKEYHASH;
        vSolutionsRet.push_back(std::move(data));
        return true;
    }

    std::vector<unsigned char> data1;
    if (MatchPayToColdStaking(scriptPubKey, data, data1)) {
        typeRet = TX_COLDSTAKE;
        vSolutionsRet.push_back(std::move(data));
        vSolutionsRet.push_back(std::move(data1));
        return true;
    }

    unsigned int required;
    std::vector<std::vector<unsigned char>> keys;
    if (MatchMultisig(scriptPubKey, required, keys)) {
        typeRet = TX_MULTISIG;
        vSolutionsRet.push_back({static_cast<unsigned char>(required)}); // safe as required is in range 1..16
        vSolutionsRet.insert(vSolutionsRet.end(), keys.begin(), keys.end());
        vSolutionsRet.push_back({static_cast<unsigned char>(keys.size())}); // safe as size is in range 1..16
        return true;
    }

    vSolutionsRet.clear();
    typeRet = TX_NONSTANDARD;
    return false;
}

int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions)
{
    switch (t)
    {
    case TX_NONSTANDARD:
    case TX_NULL_DATA:
    case TX_ZEROCOINMINT:
        return -1;
    case TX_PUBKEY:
        return 1;
    case TX_PUBKEYHASH:
        return 2;
    case TX_COLDSTAKE:
        return 3;
    case TX_MULTISIG:
        if (vSolutions.size() < 1 || vSolutions[0].size() < 1)
            return -1;
        return vSolutions[0][0] + 1;
    case TX_SCRIPTHASH:
        return 1; // doesn't include args needed by the script
    }
    return -1;
}

bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet, bool fColdStake)
{
    std::vector<valtype> vSolutions;
    txnouttype whichType;
    if (!Solver(scriptPubKey, whichType, vSolutions))
        return false;

    if (whichType == TX_PUBKEY) {
        CPubKey pubKey(vSolutions[0]);
        if (!pubKey.IsValid())
            return false;

        addressRet = pubKey.GetID();
        return true;

    } else if (whichType == TX_PUBKEYHASH) {
        addressRet = CKeyID(uint160(vSolutions[0]));
        return true;

    } else if (whichType == TX_SCRIPTHASH) {
        addressRet = CScriptID(uint160(vSolutions[0]));
        return true;
    } else if (whichType == TX_COLDSTAKE) {
        addressRet = CKeyID(uint160(vSolutions[!fColdStake]));
        return true;
    }
    // Multisig txns have more than one address...
    return false;
}

bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet)
{
    addressRet.clear();
    typeRet = TX_NONSTANDARD;
    std::vector<valtype> vSolutions;
    if (!Solver(scriptPubKey, typeRet, vSolutions))
        return false;
    if (typeRet == TX_NULL_DATA){
        // This is data, not addresses
        return false;
    }

    if (typeRet == TX_MULTISIG)
    {
        nRequiredRet = vSolutions.front()[0];
        for (unsigned int i = 1; i < vSolutions.size()-1; i++)
        {
            CPubKey pubKey(vSolutions[i]);
            if (!pubKey.IsValid())
                continue;

            CTxDestination address = pubKey.GetID();
            addressRet.push_back(address);
        }

        if (addressRet.empty())
            return false;

    } else if (typeRet == TX_COLDSTAKE)
    {
        if (vSolutions.size() < 2)
            return false;
        nRequiredRet = 2;
        addressRet.push_back(CKeyID(uint160(vSolutions[0])));
        addressRet.push_back(CKeyID(uint160(vSolutions[1])));
        return true;

    } else
    {
        nRequiredRet = 1;
        CTxDestination address;
        if (!ExtractDestination(scriptPubKey, address))
           return false;
        addressRet.push_back(address);
    }

    return true;
}

namespace
{
class CScriptVisitor : public boost::static_visitor<bool>
{
private:
    CScript *script;
public:
    CScriptVisitor(CScript *scriptin) { script = scriptin; }

    bool operator()(const CNoDestination &dest) const {
        script->clear();
        return false;
    }

    bool operator()(const CKeyID &keyID) const {
        script->clear();
        *script << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
        return true;
    }

    bool operator()(const CScriptID &scriptID) const {
        script->clear();
        *script << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
        return true;
    }
};
}

CScript GetScriptForDestination(const CTxDestination& dest)
{
    CScript script;

    boost::apply_visitor(CScriptVisitor(&script), dest);
    return script;
}

CScript GetScriptForRawPubKey(const CPubKey& pubKey)
{
    return CScript() << std::vector<unsigned char>(pubKey.begin(), pubKey.end()) << OP_CHECKSIG;
}

CScript GetScriptForStakeDelegation(const CKeyID& stakingKey, const CKeyID& spendingKey)
{
    CScript script;
    script << OP_DUP << OP_HASH160 << OP_ROT <<
            OP_IF << OP_CHECKCOLDSTAKEVERIFY << ToByteVector(stakingKey) <<
            OP_ELSE << ToByteVector(spendingKey) << OP_ENDIF <<
            OP_EQUALVERIFY << OP_CHECKSIG;
    return script;
}

CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys)
{
    CScript script;

    script << CScript::EncodeOP_N(nRequired);
    for (const CPubKey& key : keys)
        script << ToByteVector(key);
    script << CScript::EncodeOP_N(keys.size()) << OP_CHECKMULTISIG;
    return script;
}

bool IsValidDestination(const CTxDestination& dest) {
    return dest.which() != 0;
}
<|endoftext|>


<commit_before>#include "includes.h"

#ifndef _WIN32
#include <sys/types.h>
#include <dirent.h>
#endif

void prepare_logdir()
{
    spdlog::drop_all();
#ifdef _WIN32
    system("if not exist logs mkdir logs");
    system("del /F /Q logs\\*");
#else
    auto rv = system("mkdir -p logs");
    if (rv != 0)
    {
        throw std::runtime_error("Failed to mkdir -p logs");
    }
    rv = system("rm -f logs/*");
    if (rv != 0)
    {
        throw std::runtime_error("Failed to rm -f logs/*");
    }
#endif
}

std::string file_contents(const std::string &filename)
{
    std::ifstream ifs(filename);
    if (!ifs)
    {
        throw std::runtime_error("Failed open file ");
    }
    return std::string((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
}

std::size_t count_lines(const std::string &filename)
{
    std::ifstream ifs(filename);
    if (!ifs)
    {
        throw std::runtime_error("Failed open file ");
    }

    std::string line;
    size_t counter = 0;
    while (std::getline(ifs, line))
        counter++;
    return counter;
}

std::size_t get_filesize(const std::string &filename)
{
    std::ifstream ifs(filename, std::ifstream::ate | std::ifstream::binary);
    if (!ifs)
    {
        throw std::runtime_error("Failed open file ");
    }

    return static_cast<std::size_t>(ifs.tellg());
}

// source: https://stackoverflow.com/a/2072890/192001
bool ends_with(std::string const &value, std::string const &ending)
{
    if (ending.size() > value.size())
    {
        return false;
    }
    return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
}

#ifdef _WIN32
// Based on: https://stackoverflow.com/a/37416569/192001
std::size_t count_files(const std::string &folder)
{
    size_t counter = 0;
    WIN32_FIND_DATA ffd;

    // Start iterating over the files in the path directory.
    HANDLE hFind = ::FindFirstFileA((folder + "\\*").c_str(), &ffd);
    if (hFind != INVALID_HANDLE_VALUE)
    {
        do // Managed to locate and create an handle to that folder.
        {
             if (ffd.cFileName[0] != '.')
                counter++;
        } while (::FindNextFile(hFind, &ffd) != 0);
        ::FindClose(hFind);
    }
    else
    {
        throw std::runtime_error("Failed open folder " + folder);
    }

    return counter;
}
#else
// Based on: https://stackoverflow.com/a/2802255/192001
std::size_t count_files(const std::string &folder)
{
    size_t counter = 0;
    DIR *dp = opendir(folder.c_str());
    if (dp == nullptr)
    {
        throw std::runtime_error("Failed open folder " + folder);
    }

    struct dirent *ep;
    while (ep = readdir(dp))
    {
        if (ep->d_name[0] != '.')
            counter++;
    }
    (void)closedir(dp);
    return counter;
}
#endif
<commit_msg>Update utils.cpp<commit_after>#include "includes.h"

#ifndef _WIN32
#include <sys/types.h>
#include <dirent.h>
#endif

void prepare_logdir()
{
    spdlog::drop_all();
#ifdef _WIN32
    system("if not exist logs mkdir logs");
    system("del /F /Q logs\\*");
#else
    auto rv = system("mkdir -p logs");
    if (rv != 0)
    {
        throw std::runtime_error("Failed to mkdir -p logs");
    }
    rv = system("rm -f logs/*");
    if (rv != 0)
    {
        throw std::runtime_error("Failed to rm -f logs/*");
    }
#endif
}

std::string file_contents(const std::string &filename)
{
    std::ifstream ifs(filename);
    if (!ifs)
    {
        throw std::runtime_error("Failed open file ");
    }
    return std::string((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
}

std::size_t count_lines(const std::string &filename)
{
    std::ifstream ifs(filename);
    if (!ifs)
    {
        throw std::runtime_error("Failed open file ");
    }

    std::string line;
    size_t counter = 0;
    while (std::getline(ifs, line))
        counter++;
    return counter;
}

std::size_t get_filesize(const std::string &filename)
{
    std::ifstream ifs(filename, std::ifstream::ate | std::ifstream::binary);
    if (!ifs)
    {
        throw std::runtime_error("Failed open file ");
    }

    return static_cast<std::size_t>(ifs.tellg());
}

// source: https://stackoverflow.com/a/2072890/192001
bool ends_with(std::string const &value, std::string const &ending)
{
    if (ending.size() > value.size())
    {
        return false;
    }
    return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
}

#ifdef _WIN32
// Based on: https://stackoverflow.com/a/37416569/192001
std::size_t count_files(const std::string &folder)
{
    size_t counter = 0;
    WIN32_FIND_DATA ffd;

    // Start iterating over the files in the folder directory.
    HANDLE hFind = ::FindFirstFileA((folder + "\\*").c_str(), &ffd);
    if (hFind != INVALID_HANDLE_VALUE)
    {
        do // Managed to locate and create an handle to that folder.
        {
             if (ffd.cFileName[0] != '.')
                counter++;
        } while (::FindNextFile(hFind, &ffd) != 0);
        ::FindClose(hFind);
    }
    else
    {
        throw std::runtime_error("Failed open folder " + folder);
    }

    return counter;
}
#else
// Based on: https://stackoverflow.com/a/2802255/192001
std::size_t count_files(const std::string &folder)
{
    size_t counter = 0;
    DIR *dp = opendir(folder.c_str());
    if (dp == nullptr)
    {
        throw std::runtime_error("Failed open folder " + folder);
    }

    struct dirent *ep;
    while (ep = readdir(dp))
    {
        if (ep->d_name[0] != '.')
            counter++;
    }
    (void)closedir(dp);
    return counter;
}
#endif
<|endoftext|>