<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 "metadexdialog.h"
#include "ui_metadexdialog.h"

#include "omnicore_qtutils.h"

#include "clientmodel.h"
#include "walletmodel.h"

#include "omnicore/createpayload.h"
#include "omnicore/errors.h"
#include "omnicore/mdex.h"
#include "omnicore/omnicore.h"
#include "omnicore/parse_string.h"
#include "omnicore/pending.h"
#include "omnicore/sp.h"

#include "amount.h"
#include "sync.h"
#include "uint256.h"
#include "wallet_ismine.h"

#include <boost/lexical_cast.hpp>

#include <stdint.h>
#include <map>
#include <sstream>
#include <string>
#include <vector>

#include <QAbstractItemView>
#include <QDialog>
#include <QDateTime>
#include <QFont>
#include <QHeaderView>
#include <QMessageBox>
#include <QString>
#include <QTableWidgetItem>
#include <QWidget>

using std::ostringstream;
using std::string;

using namespace mastercore;

MetaDExDialog::MetaDExDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::MetaDExDialog),
    clientModel(0),
    walletModel(0),
    global_metadex_market(3)
{
    ui->setupUi(this);

    //prep lists
    ui->buyList->setColumnCount(3);
    ui->sellList->setColumnCount(3);
    ui->buyList->verticalHeader()->setVisible(false);
    #if QT_VERSION < 0x050000
        ui->buyList->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
    #else
        ui->buyList->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    #endif
    ui->buyList->setShowGrid(false);
    ui->buyList->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->buyList->setSelectionMode(QAbstractItemView::NoSelection);
    ui->buyList->setFocusPolicy(Qt::NoFocus);
    ui->buyList->setAlternatingRowColors(true);
    ui->sellList->verticalHeader()->setVisible(false);
    #if QT_VERSION < 0x050000
        ui->sellList->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
    #else
        ui->sellList->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    #endif
    ui->sellList->setShowGrid(false);
    ui->sellList->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->sellList->setSelectionMode(QAbstractItemView::NoSelection);
    ui->sellList->setFocusPolicy(Qt::NoFocus);
    ui->sellList->setAlternatingRowColors(true);

    connect(ui->switchButton, SIGNAL(clicked()), this, SLOT(switchButtonClicked()));
    connect(ui->buyButton, SIGNAL(clicked()), this, SLOT(buyTrade()));
    connect(ui->sellButton, SIGNAL(clicked()), this, SLOT(sellTrade()));
    connect(ui->sellAddressCombo, SIGNAL(activated(int)), this, SLOT(sellAddressComboBoxChanged(int)));
    connect(ui->buyAddressCombo, SIGNAL(activated(int)), this, SLOT(buyAddressComboBoxChanged(int)));
    connect(ui->sellAmountLE, SIGNAL(textEdited(const QString &)), this, SLOT(recalcSellTotal()));
    connect(ui->sellPriceLE, SIGNAL(textEdited(const QString &)), this, SLOT(recalcSellTotal()));
    connect(ui->buyAmountLE, SIGNAL(textEdited(const QString &)), this, SLOT(recalcBuyTotal()));
    connect(ui->buyPriceLE, SIGNAL(textEdited(const QString &)), this, SLOT(recalcBuyTotal()));
    connect(ui->sellList, SIGNAL(cellClicked(int,int)), this, SLOT(sellClicked(int,int)));
    connect(ui->buyList, SIGNAL(cellClicked(int,int)), this, SLOT(buyClicked(int,int)));

    FullRefresh();

}

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

void MetaDExDialog::setClientModel(ClientModel *model)
{
    this->clientModel = model;
    if (NULL != model) {
        connect(model, SIGNAL(refreshOmniState()), this, SLOT(OrderRefresh()));
        connect(model, SIGNAL(refreshOmniBalance()), this, SLOT(BalanceOrderRefresh()));
        connect(model, SIGNAL(reinitOmniState()), this, SLOT(FullRefresh()));
    }
}

void MetaDExDialog::setWalletModel(WalletModel *model)
{
    // use wallet model to get visibility into BTC balance changes for fees
    this->walletModel = model;
    if (model != NULL) {
       connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(UpdateBalances()));
    }
}

void MetaDExDialog::PopulateAddresses()
{
    LOCK(cs_tally);

    uint32_t propertyId = global_metadex_market;
    bool testeco = false;
    if (propertyId >= TEST_ECO_PROPERTY_1) testeco = true;

    // get currently selected addresses
    QString currentSetBuyAddress = ui->buyAddressCombo->currentText();
    QString currentSetSellAddress = ui->sellAddressCombo->currentText();

    // clear address selectors
    ui->buyAddressCombo->clear();
    ui->sellAddressCombo->clear();

    // populate buy and sell addresses
    for (std::map<string, CMPTally>::iterator my_it = mp_tally_map.begin(); my_it != mp_tally_map.end(); ++my_it) {
        string address = (my_it->first).c_str();
        unsigned int id;
        (my_it->second).init();
        while (0 != (id = (my_it->second).next())) {
            if (id == propertyId) {
                if (!getUserAvailableMPbalance(address, propertyId)) continue; // ignore this address, has no available balance to spend
                if (IsMyAddress(address) == ISMINE_SPENDABLE) ui->sellAddressCombo->addItem((my_it->first).c_str()); // only include wallet addresses
            }
            if (id == OMNI_PROPERTY_MSC && !testeco) {
                if (!getUserAvailableMPbalance(address, OMNI_PROPERTY_MSC)) continue;
                if (IsMyAddress(address) == ISMINE_SPENDABLE) ui->buyAddressCombo->addItem((my_it->first).c_str());
            }
            if (id == OMNI_PROPERTY_TMSC && testeco) {
                if (!getUserAvailableMPbalance(address, OMNI_PROPERTY_TMSC)) continue;
                if (IsMyAddress(address) == ISMINE_SPENDABLE) ui->buyAddressCombo->addItem((my_it->first).c_str());
            }
        }
    }

    // attempt to set buy and sell addresses back to values before refresh - may not be possible if it's a new market
    int sellIdx = ui->sellAddressCombo->findText(currentSetSellAddress);
    if (sellIdx != -1) { ui->sellAddressCombo->setCurrentIndex(sellIdx); }
    int buyIdx = ui->buyAddressCombo->findText(currentSetBuyAddress);
    if (buyIdx != -1) { ui->buyAddressCombo->setCurrentIndex(buyIdx); }

    // update balances
    UpdateBalances();
}

void MetaDExDialog::BalanceOrderRefresh()
{
    // balances have been updated, there may be a new address
    PopulateAddresses();
    // refresh orders
    OrderRefresh();
}

void MetaDExDialog::OrderRefresh()
{
    UpdateOffers();<commit_msg>UI: Fix crash due to locking (thanks @dexX7)<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 "metadexdialog.h"
#include "ui_metadexdialog.h"

#include "omnicore_qtutils.h"

#include "clientmodel.h"
#include "walletmodel.h"

#include "omnicore/createpayload.h"
#include "omnicore/errors.h"
#include "omnicore/mdex.h"
#include "omnicore/omnicore.h"
#include "omnicore/parse_string.h"
#include "omnicore/pending.h"
#include "omnicore/sp.h"

#include "amount.h"
#include "sync.h"
#include "uint256.h"
#include "wallet_ismine.h"

#include <boost/lexical_cast.hpp>

#include <stdint.h>
#include <map>
#include <sstream>
#include <string>
#include <vector>

#include <QAbstractItemView>
#include <QDialog>
#include <QDateTime>
#include <QFont>
#include <QHeaderView>
#include <QMessageBox>
#include <QString>
#include <QTableWidgetItem>
#include <QWidget>

using std::ostringstream;
using std::string;

using namespace mastercore;

MetaDExDialog::MetaDExDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::MetaDExDialog),
    clientModel(0),
    walletModel(0),
    global_metadex_market(3)
{
    ui->setupUi(this);

    //prep lists
    ui->buyList->setColumnCount(3);
    ui->sellList->setColumnCount(3);
    ui->buyList->verticalHeader()->setVisible(false);
    #if QT_VERSION < 0x050000
        ui->buyList->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
    #else
        ui->buyList->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    #endif
    ui->buyList->setShowGrid(false);
    ui->buyList->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->buyList->setSelectionMode(QAbstractItemView::NoSelection);
    ui->buyList->setFocusPolicy(Qt::NoFocus);
    ui->buyList->setAlternatingRowColors(true);
    ui->sellList->verticalHeader()->setVisible(false);
    #if QT_VERSION < 0x050000
        ui->sellList->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
    #else
        ui->sellList->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    #endif
    ui->sellList->setShowGrid(false);
    ui->sellList->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->sellList->setSelectionMode(QAbstractItemView::NoSelection);
    ui->sellList->setFocusPolicy(Qt::NoFocus);
    ui->sellList->setAlternatingRowColors(true);

    connect(ui->switchButton, SIGNAL(clicked()), this, SLOT(switchButtonClicked()));
    connect(ui->buyButton, SIGNAL(clicked()), this, SLOT(buyTrade()));
    connect(ui->sellButton, SIGNAL(clicked()), this, SLOT(sellTrade()));
    connect(ui->sellAddressCombo, SIGNAL(activated(int)), this, SLOT(sellAddressComboBoxChanged(int)));
    connect(ui->buyAddressCombo, SIGNAL(activated(int)), this, SLOT(buyAddressComboBoxChanged(int)));
    connect(ui->sellAmountLE, SIGNAL(textEdited(const QString &)), this, SLOT(recalcSellTotal()));
    connect(ui->sellPriceLE, SIGNAL(textEdited(const QString &)), this, SLOT(recalcSellTotal()));
    connect(ui->buyAmountLE, SIGNAL(textEdited(const QString &)), this, SLOT(recalcBuyTotal()));
    connect(ui->buyPriceLE, SIGNAL(textEdited(const QString &)), this, SLOT(recalcBuyTotal()));
    connect(ui->sellList, SIGNAL(cellClicked(int,int)), this, SLOT(sellClicked(int,int)));
    connect(ui->buyList, SIGNAL(cellClicked(int,int)), this, SLOT(buyClicked(int,int)));

    FullRefresh();

}

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

void MetaDExDialog::setClientModel(ClientModel *model)
{
    this->clientModel = model;
    if (NULL != model) {
        connect(model, SIGNAL(refreshOmniState()), this, SLOT(OrderRefresh()));
        connect(model, SIGNAL(refreshOmniBalance()), this, SLOT(BalanceOrderRefresh()));
        connect(model, SIGNAL(reinitOmniState()), this, SLOT(FullRefresh()));
    }
}

void MetaDExDialog::setWalletModel(WalletModel *model)
{
    // use wallet model to get visibility into BTC balance changes for fees
    this->walletModel = model;
    if (model != NULL) {
       connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(UpdateBalances()));
    }
}

void MetaDExDialog::PopulateAddresses()
{
    { // restrict scope of lock to address updates only (don't hold for balance update too)
        LOCK(cs_tally);

        uint32_t propertyId = global_metadex_market;
        bool testeco = false;
        if (propertyId >= TEST_ECO_PROPERTY_1) testeco = true;

        // get currently selected addresses
        QString currentSetBuyAddress = ui->buyAddressCombo->currentText();
        QString currentSetSellAddress = ui->sellAddressCombo->currentText();

        // clear address selectors
        ui->buyAddressCombo->clear();
        ui->sellAddressCombo->clear();

        // populate buy and sell addresses
        for (std::map<string, CMPTally>::iterator my_it = mp_tally_map.begin(); my_it != mp_tally_map.end(); ++my_it) {
            string address = (my_it->first).c_str();
            unsigned int id;
            (my_it->second).init();
            while (0 != (id = (my_it->second).next())) {
                if (id == propertyId) {
                    if (!getUserAvailableMPbalance(address, propertyId)) continue; // ignore this address, has no available balance to spend
                    if (IsMyAddress(address) == ISMINE_SPENDABLE) ui->sellAddressCombo->addItem((my_it->first).c_str()); // only include wallet addresses
                }
                if (id == OMNI_PROPERTY_MSC && !testeco) {
                    if (!getUserAvailableMPbalance(address, OMNI_PROPERTY_MSC)) continue;
                    if (IsMyAddress(address) == ISMINE_SPENDABLE) ui->buyAddressCombo->addItem((my_it->first).c_str());
                }
                if (id == OMNI_PROPERTY_TMSC && testeco) {
                    if (!getUserAvailableMPbalance(address, OMNI_PROPERTY_TMSC)) continue;
                    if (IsMyAddress(address) == ISMINE_SPENDABLE) ui->buyAddressCombo->addItem((my_it->first).c_str());
                }
            }
        }

        // attempt to set buy and sell addresses back to values before refresh - may not be possible if it's a new market
        int sellIdx = ui->sellAddressCombo->findText(currentSetSellAddress);
        if (sellIdx != -1) { ui->sellAddressCombo->setCurrentIndex(sellIdx); }
        int buyIdx = ui->buyAddressCombo->findText(currentSetBuyAddress);
        if (buyIdx != -1) { ui->buyAddressCombo->setCurrentIndex(buyIdx); }
    }

    // update balances
    UpdateBalances();
}

void MetaDExDialog::BalanceOrderRefresh()
{
    // balances have been updated, there may be a new address
    PopulateAddresses();
    // refresh orders
    OrderRefresh();
}

void MetaDExDialog::OrderRefresh()
{
    UpdateOffers();
{'fraction_non_alphanumeric': 0.1423680881149066, 'fraction_numerical': 0.005730445784029173, 'mean_word_length': 4.198452611218569, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 205, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4520107', 'n_tokens_mistral': 4451, 'n_tokens_neox': 4264, 'n_words': 784}