Merge branch 'master' of github.com:cryptonomex/graphene
This commit is contained in:
commit
0b5b31ab74
12 changed files with 134 additions and 63 deletions
|
|
@ -27,19 +27,19 @@ class Account : public GrapheneObject {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Account(ObjectId id = -1, QString name = QString(), QObject* parent = nullptr)
|
Account(ObjectId id = -1, QString name = QString(), QObject* parent = nullptr)
|
||||||
: GrapheneObject(id, parent)
|
: GrapheneObject(id, parent)
|
||||||
{
|
{
|
||||||
m_account.name = name.toStdString();
|
m_account.name = name.toStdString();
|
||||||
}
|
}
|
||||||
void setAccountObject( const account_object& obj )
|
void setAccountObject(const account_object& obj)
|
||||||
{
|
{
|
||||||
auto old_name = m_account.name;
|
auto old_name = m_account.name;
|
||||||
m_account = obj;
|
m_account = obj;
|
||||||
if( old_name != m_account.name )
|
if (old_name != m_account.name)
|
||||||
Q_EMIT nameChanged();
|
Q_EMIT nameChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString name()const { return toQString(m_account.name); }
|
QString name()const { return QString::fromStdString(m_account.name); }
|
||||||
QQmlListProperty<Balance> balances();
|
QQmlListProperty<Balance> balances();
|
||||||
|
|
||||||
void setBalances(QList<Balance*> balances) {
|
void setBalances(QList<Balance*> balances) {
|
||||||
|
|
@ -52,11 +52,11 @@ public:
|
||||||
void update(const account_balance_object& balance);
|
void update(const account_balance_object& balance);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Anything greater than 1.0 means full authority.
|
* Anything greater than 1.0 means full authority.
|
||||||
* Anything between (0 and 1.0) means partial authority
|
* Anything between (0 and 1.0) means partial authority
|
||||||
* 0 means no authority.
|
* 0 means no authority.
|
||||||
*
|
*
|
||||||
* @return the percent of direct control the wallet has over the account.
|
* @return the percent of direct control the wallet has over the account.
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE double getOwnerControl( Wallet* w )const;
|
Q_INVOKABLE double getOwnerControl( Wallet* w )const;
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ void ChainDataModel::getAccountImpl(QString accountIdentifier, Account* const *
|
||||||
} else {
|
} else {
|
||||||
m_accounts.modify(itr, [this,&accountPackage](Account* a){
|
m_accounts.modify(itr, [this,&accountPackage](Account* a){
|
||||||
a->setProperty("id", ObjectId(accountPackage->account.id.instance()));
|
a->setProperty("id", ObjectId(accountPackage->account.id.instance()));
|
||||||
a->setAccountObject( accountPackage->account );
|
a->setAccountObject(accountPackage->account);
|
||||||
|
|
||||||
// Set balances
|
// Set balances
|
||||||
QList<Balance*> balances;
|
QList<Balance*> balances;
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
QString toQString( const std::string& s );
|
|
||||||
|
|
||||||
using ObjectId = qint64;
|
using ObjectId = qint64;
|
||||||
Q_DECLARE_METATYPE(ObjectId)
|
Q_DECLARE_METATYPE(ObjectId)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ OperationBase* Transaction::operationAt(int index) const {
|
||||||
|
|
||||||
void Transaction::appendOperation(OperationBase* op)
|
void Transaction::appendOperation(OperationBase* op)
|
||||||
{
|
{
|
||||||
|
op->setParent(this);
|
||||||
m_transaction.operations.push_back(op->genericOperation());
|
m_transaction.operations.push_back(op->genericOperation());
|
||||||
Q_EMIT operationsChanged();
|
Q_EMIT operationsChanged();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,9 @@ public:
|
||||||
QQmlListProperty<OperationBase> operations();
|
QQmlListProperty<OperationBase> operations();
|
||||||
|
|
||||||
OperationBase* operationAt(int index) const;
|
OperationBase* operationAt(int index) const;
|
||||||
void appendOperation(OperationBase* op);
|
|
||||||
int operationCount() const {
|
int operationCount() const {
|
||||||
return m_transaction.operations.size();
|
return m_transaction.operations.size();
|
||||||
}
|
}
|
||||||
void clearOperations() {
|
|
||||||
m_transaction.operations.clear();
|
|
||||||
Q_EMIT operationsChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setStatus(Status status)
|
void setStatus(Status status)
|
||||||
|
|
@ -37,6 +32,16 @@ public slots:
|
||||||
emit statusChanged(status);
|
emit statusChanged(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Append the operation to the transaction
|
||||||
|
* @param op The operation to append. This Transaction will take ownership of the operation.
|
||||||
|
*/
|
||||||
|
void appendOperation(OperationBase* op);
|
||||||
|
void clearOperations() {
|
||||||
|
m_transaction.operations.clear();
|
||||||
|
Q_EMIT operationsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void statusChanged(Status status);
|
void statusChanged(Status status);
|
||||||
void operationsChanged();
|
void operationsChanged();
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,9 @@
|
||||||
#include <fc/crypto/aes.hpp>
|
#include <fc/crypto/aes.hpp>
|
||||||
#include <fc/io/json.hpp>
|
#include <fc/io/json.hpp>
|
||||||
|
|
||||||
QString toQString( const std::string& s ) { QString result; result.fromStdString( s ); return result; }
|
QString toQString(public_key_type k) { return QString::fromStdString(fc::variant(k).as_string()); }
|
||||||
QString toQString( public_key_type k ) { return toQString( fc::variant(k).as_string() ); }
|
|
||||||
|
|
||||||
Wallet::Wallet( QObject* parent )
|
Wallet::Wallet(QObject* parent)
|
||||||
:QObject(parent)
|
:QObject(parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -16,10 +15,10 @@ Wallet::~Wallet()
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Wallet::open( QString file_path )
|
bool Wallet::open(QString file_path)
|
||||||
{
|
{
|
||||||
fc::path p( file_path.toStdString() );
|
fc::path p(file_path.toStdString());
|
||||||
if( !fc::exists( p ) )
|
if( !fc::exists(p) )
|
||||||
{
|
{
|
||||||
ilog( "Unable to open wallet file '${f}', it does not exist", ("f",p) );
|
ilog( "Unable to open wallet file '${f}', it does not exist", ("f",p) );
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -30,7 +29,7 @@ bool Wallet::open( QString file_path )
|
||||||
for( const auto& key : _data.encrypted_private_keys )
|
for( const auto& key : _data.encrypted_private_keys )
|
||||||
{
|
{
|
||||||
if( key.second.label != string() )
|
if( key.second.label != string() )
|
||||||
_label_to_key[toQString(key.second.label)] = toQString( key.first );
|
_label_to_key[QString::fromStdString(key.second.label)] = toQString(key.first);
|
||||||
if( key.second.encrypted_private_key.size() )
|
if( key.second.encrypted_private_key.size() )
|
||||||
_available_private_keys.insert( key.first );
|
_available_private_keys.insert( key.first );
|
||||||
}
|
}
|
||||||
|
|
@ -194,7 +193,7 @@ bool Wallet::hasPrivateKey( QString pubkey, bool include_with_brain_key )
|
||||||
auto itr = _data.encrypted_private_keys.find(pub);
|
auto itr = _data.encrypted_private_keys.find(pub);
|
||||||
if( itr == _data.encrypted_private_keys.end() )
|
if( itr == _data.encrypted_private_keys.end() )
|
||||||
return false;
|
return false;
|
||||||
if( itr->second.encrypted_private_key.size() )
|
if( itr->second.encrypted_private_key.size() )
|
||||||
return true;
|
return true;
|
||||||
if( include_with_brain_key && itr->second.brain_sequence >= 0 )
|
if( include_with_brain_key && itr->second.brain_sequence >= 0 )
|
||||||
{
|
{
|
||||||
|
|
@ -217,7 +216,7 @@ QString Wallet::getPrivateKey( QString pubkey )
|
||||||
if( itr->second.encrypted_private_key.size() == 0 )
|
if( itr->second.encrypted_private_key.size() == 0 )
|
||||||
return QString();
|
return QString();
|
||||||
auto plain = fc::aes_decrypt( _decrypted_master_key, itr->second.encrypted_private_key );
|
auto plain = fc::aes_decrypt( _decrypted_master_key, itr->second.encrypted_private_key );
|
||||||
return toQString( fc::raw::unpack<std::string>(plain) );
|
return QString::fromStdString( fc::raw::unpack<std::string>(plain) );
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Wallet::getPublicKey( QString wif_private_key )const
|
QString Wallet::getPublicKey( QString wif_private_key )const
|
||||||
|
|
@ -227,7 +226,7 @@ QString Wallet::getPublicKey( QString wif_private_key )const
|
||||||
|
|
||||||
auto pub = public_key_type(priv->get_public_key());
|
auto pub = public_key_type(priv->get_public_key());
|
||||||
|
|
||||||
return toQString( fc::variant( pub ).as_string() );
|
return QString::fromStdString( fc::variant( pub ).as_string() );
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Wallet::getActivePrivateKey( QString owner_pub_key, uint32_t seq )
|
QString Wallet::getActivePrivateKey( QString owner_pub_key, uint32_t seq )
|
||||||
|
|
@ -251,7 +250,7 @@ QString Wallet::getActivePrivateKey( QString owner_pub_key, uint32_t seq )
|
||||||
_data.encrypted_private_keys[active_pub_key].brain_sequence = seq;
|
_data.encrypted_private_keys[active_pub_key].brain_sequence = seq;
|
||||||
_available_private_keys.insert( active_pub_key );
|
_available_private_keys.insert( active_pub_key );
|
||||||
|
|
||||||
return toQString(wif);
|
return QString::fromStdString(wif);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Wallet::getOwnerPrivateKey( uint32_t seq )
|
QString Wallet::getOwnerPrivateKey( uint32_t seq )
|
||||||
|
|
@ -273,7 +272,7 @@ QString Wallet::getOwnerPrivateKey( uint32_t seq )
|
||||||
_data.encrypted_private_keys[owner_pub_key].brain_sequence = seq;
|
_data.encrypted_private_keys[owner_pub_key].brain_sequence = seq;
|
||||||
_available_private_keys.insert( owner_pub_key );
|
_available_private_keys.insert( owner_pub_key );
|
||||||
|
|
||||||
return toQString( wif );
|
return QString::fromStdString( wif );
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Wallet::getActivePublicKey( QString active_pub, uint32_t seq )
|
QString Wallet::getActivePublicKey( QString active_pub, uint32_t seq )
|
||||||
|
|
@ -294,11 +293,11 @@ QString Wallet::getKeyLabel( QString pubkey )
|
||||||
auto itr = _data.encrypted_private_keys.find( key );
|
auto itr = _data.encrypted_private_keys.find( key );
|
||||||
if( itr == _data.encrypted_private_keys.end() )
|
if( itr == _data.encrypted_private_keys.end() )
|
||||||
return QString();
|
return QString();
|
||||||
return toQString( itr->second.label );
|
return QString::fromStdString( itr->second.label );
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* The same label may not be assigned to more than one key, this method will
|
* The same label may not be assigned to more than one key, this method will
|
||||||
* fail if a key with the same label already exists.
|
* fail if a key with the same label already exists.
|
||||||
*
|
*
|
||||||
* @return true if the label was set
|
* @return true if the label was set
|
||||||
*/
|
*/
|
||||||
|
|
@ -310,7 +309,7 @@ bool Wallet::setKeyLabel( QString pubkey, QString label )
|
||||||
auto old_label = _data.encrypted_private_keys[pub].label;
|
auto old_label = _data.encrypted_private_keys[pub].label;
|
||||||
_data.encrypted_private_keys[pub].label = string();
|
_data.encrypted_private_keys[pub].label = string();
|
||||||
if( old_label.size() )
|
if( old_label.size() )
|
||||||
_label_to_key.erase( toQString( old_label ) );
|
_label_to_key.erase( QString::fromStdString( old_label ) );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -336,7 +335,7 @@ QList<QPair<QString,QString> > Wallet::getAllPublicKeys( bool only_if_private )c
|
||||||
for( const auto& item : _data.encrypted_private_keys )
|
for( const auto& item : _data.encrypted_private_keys )
|
||||||
{
|
{
|
||||||
if( only_if_private && !item.second.encrypted_private_key.size() ) continue;
|
if( only_if_private && !item.second.encrypted_private_key.size() ) continue;
|
||||||
result.push_back( qMakePair( toQString( item.first ), toQString( item.second.label ) ) );
|
result.push_back( qMakePair( toQString( item.first ), QString::fromStdString( item.second.label ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -359,9 +358,9 @@ bool Wallet::importPublicKey( QString pubkey, QString label )
|
||||||
return setKeyLabel( pubkey, label );
|
return setKeyLabel( pubkey, label );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param wifkey a private key in (WIF) Wallet Import Format
|
* @param wifkey a private key in (WIF) Wallet Import Format
|
||||||
* @pre !isLocked()
|
* @pre !isLocked()
|
||||||
**/
|
**/
|
||||||
bool Wallet::importPrivateKey( QString wifkey, QString label )
|
bool Wallet::importPrivateKey( QString wifkey, QString label )
|
||||||
{
|
{
|
||||||
|
|
@ -390,14 +389,14 @@ bool Wallet::removePublicKey( QString pubkey )
|
||||||
auto itr = _data.encrypted_private_keys.find(pub);
|
auto itr = _data.encrypted_private_keys.find(pub);
|
||||||
if( itr != _data.encrypted_private_keys.end() )
|
if( itr != _data.encrypted_private_keys.end() )
|
||||||
{
|
{
|
||||||
_label_to_key.erase( toQString(itr->second.label) );
|
_label_to_key.erase( QString::fromStdString(itr->second.label) );
|
||||||
_data.encrypted_private_keys.erase(itr);
|
_data.encrypted_private_keys.erase(itr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** removes only the private key, keeping the public key and label
|
/** removes only the private key, keeping the public key and label
|
||||||
*
|
*
|
||||||
* @pre isOpen() && !isLocked()
|
* @pre isOpen() && !isLocked()
|
||||||
**/
|
**/
|
||||||
|
|
@ -416,7 +415,7 @@ bool Wallet::removePrivateKey( QString pubkey )
|
||||||
/**
|
/**
|
||||||
* @pre !isLocked()
|
* @pre !isLocked()
|
||||||
*/
|
*/
|
||||||
vector<signature_type> Wallet::signDigest( const digest_type& d,
|
vector<signature_type> Wallet::signDigest( const digest_type& d,
|
||||||
const set<public_key_type>& keys )const
|
const set<public_key_type>& keys )const
|
||||||
{
|
{
|
||||||
vector<signature_type> result;
|
vector<signature_type> result;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ using graphene::chain::digest_type;
|
||||||
using graphene::chain::signature_type;
|
using graphene::chain::signature_type;
|
||||||
using fc::optional;
|
using fc::optional;
|
||||||
|
|
||||||
QString toQString( const std::string& s );
|
|
||||||
QString toQString( public_key_type k );
|
QString toQString( public_key_type k );
|
||||||
|
|
||||||
struct key_data
|
struct key_data
|
||||||
|
|
@ -38,12 +37,12 @@ struct wallet_file
|
||||||
map<public_key_type, key_data> encrypted_private_keys;
|
map<public_key_type, key_data> encrypted_private_keys;
|
||||||
};
|
};
|
||||||
|
|
||||||
FC_REFLECT( wallet_file,
|
FC_REFLECT( wallet_file,
|
||||||
(encrypted_brain_key)
|
(encrypted_brain_key)
|
||||||
(brain_key_digest)
|
(brain_key_digest)
|
||||||
(encrypted_master_key)
|
(encrypted_master_key)
|
||||||
(master_key_digest)
|
(master_key_digest)
|
||||||
(encrypted_private_keys)
|
(encrypted_private_keys)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -57,6 +56,8 @@ FC_REFLECT( wallet_file,
|
||||||
class Wallet : public QObject
|
class Wallet : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(bool isOpen READ isOpen NOTIFY isOpenChanged)
|
||||||
|
Q_PROPERTY(bool isLocked READ isLocked NOTIFY isLockedChanged)
|
||||||
public:
|
public:
|
||||||
Wallet( QObject* parent = nullptr );
|
Wallet( QObject* parent = nullptr );
|
||||||
~Wallet();
|
~Wallet();
|
||||||
|
|
@ -86,7 +87,7 @@ class Wallet : public QObject
|
||||||
/**
|
/**
|
||||||
* @pre !isLocked();
|
* @pre !isLocked();
|
||||||
* @post save()
|
* @post save()
|
||||||
* @return WIF private key
|
* @return WIF private key
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE QString getActivePrivateKey( QString owner_public_key, uint32_t sequence );
|
Q_INVOKABLE QString getActivePrivateKey( QString owner_public_key, uint32_t sequence );
|
||||||
Q_INVOKABLE QString getActivePublicKey( QString owner_public_key, uint32_t sequence );
|
Q_INVOKABLE QString getActivePublicKey( QString owner_public_key, uint32_t sequence );
|
||||||
|
|
@ -95,7 +96,7 @@ class Wallet : public QObject
|
||||||
* @pre !isLocked();
|
* @pre !isLocked();
|
||||||
* @pre hasBrainKey();
|
* @pre hasBrainKey();
|
||||||
* @post save()
|
* @post save()
|
||||||
* @return WIF private key
|
* @return WIF private key
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE QString getOwnerPrivateKey( uint32_t sequence );
|
Q_INVOKABLE QString getOwnerPrivateKey( uint32_t sequence );
|
||||||
Q_INVOKABLE QString getOwnerPublicKey( uint32_t sequence );
|
Q_INVOKABLE QString getOwnerPublicKey( uint32_t sequence );
|
||||||
|
|
@ -110,9 +111,9 @@ class Wallet : public QObject
|
||||||
/** imports a public key and assigns it a label */
|
/** imports a public key and assigns it a label */
|
||||||
Q_INVOKABLE bool importPublicKey( QString pubkey, QString label = QString() );
|
Q_INVOKABLE bool importPublicKey( QString pubkey, QString label = QString() );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param wifkey a private key in (WIF) Wallet Import Format
|
* @param wifkey a private key in (WIF) Wallet Import Format
|
||||||
* @pre !isLocked()
|
* @pre !isLocked()
|
||||||
**/
|
**/
|
||||||
Q_INVOKABLE bool importPrivateKey( QString wifkey, QString label = QString() );
|
Q_INVOKABLE bool importPrivateKey( QString wifkey, QString label = QString() );
|
||||||
|
|
||||||
|
|
@ -131,7 +132,7 @@ class Wallet : public QObject
|
||||||
/**
|
/**
|
||||||
* @pre !isLocked()
|
* @pre !isLocked()
|
||||||
*/
|
*/
|
||||||
vector<signature_type> signDigest( const digest_type& d,
|
vector<signature_type> signDigest( const digest_type& d,
|
||||||
const set<public_key_type>& keys )const;
|
const set<public_key_type>& keys )const;
|
||||||
|
|
||||||
const flat_set<public_key_type>& getAvailablePrivateKeys()const;
|
const flat_set<public_key_type>& getAvailablePrivateKeys()const;
|
||||||
|
|
@ -149,5 +150,3 @@ class Wallet : public QObject
|
||||||
map<QString,QString> _label_to_key;
|
map<QString,QString> _label_to_key;
|
||||||
QString _brain_key;
|
QString _brain_key;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,8 @@ Rectangle {
|
||||||
|
|
||||||
var form = formType.createObject(formContainer, params)
|
var form = formType.createObject(formContainer, params)
|
||||||
formContainer.data = [form]
|
formContainer.data = [form]
|
||||||
form.finished.connect(function(){state = "HIDDEN"})
|
form.canceled.connect(function(){state = "HIDDEN"; internal.callbackArgs = []})
|
||||||
|
form.completed.connect(function(){state = "HIDDEN"; internal.callbackArgs = arguments})
|
||||||
if (closedCallback instanceof Function)
|
if (closedCallback instanceof Function)
|
||||||
internal.callback = closedCallback
|
internal.callback = closedCallback
|
||||||
state = "SHOWN"
|
state = "SHOWN"
|
||||||
|
|
@ -89,6 +90,7 @@ Rectangle {
|
||||||
if (internal.callback instanceof Function)
|
if (internal.callback instanceof Function)
|
||||||
internal.callback()
|
internal.callback()
|
||||||
internal.callback = undefined
|
internal.callback = undefined
|
||||||
|
internal.callbackArgs = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -145,5 +147,6 @@ Rectangle {
|
||||||
QtObject {
|
QtObject {
|
||||||
id: internal
|
id: internal
|
||||||
property var callback
|
property var callback
|
||||||
|
property var callbackArgs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
51
programs/light_client/qml/FormFlipper.qml
Normal file
51
programs/light_client/qml/FormFlipper.qml
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
import QtQuick 2.5
|
||||||
|
|
||||||
|
import Graphene.Client 0.1
|
||||||
|
|
||||||
|
Flipable {
|
||||||
|
id: flipable
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
property Component frontComponent
|
||||||
|
property Component backComponent
|
||||||
|
property GrapheneApplication app
|
||||||
|
signal canceled
|
||||||
|
signal completed
|
||||||
|
|
||||||
|
property bool flipped: false
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
back = backComponent.createObject(flipable, {app: app, enabled: Qt.binding(function(){return flipped})})
|
||||||
|
front = frontComponent.createObject(flipable, {app: app, enabled: Qt.binding(function(){return !flipped})})
|
||||||
|
front.canceled.connect(function() { canceled.apply(this, arguments) })
|
||||||
|
front.completed.connect(function() {
|
||||||
|
if (back.hasOwnProperty("arguments"))
|
||||||
|
back.arguments = arguments
|
||||||
|
flipped = true
|
||||||
|
})
|
||||||
|
back.canceled.connect(function() {
|
||||||
|
if (front.hasOwnProperty("arguments"))
|
||||||
|
front.arguments = arguments
|
||||||
|
flipped = false
|
||||||
|
})
|
||||||
|
back.completed.connect(function() { completed.apply(this, arguments) })
|
||||||
|
}
|
||||||
|
|
||||||
|
transform: Rotation {
|
||||||
|
id: rotation
|
||||||
|
origin.x: flipable.width/2
|
||||||
|
origin.y: flipable.height/2
|
||||||
|
axis.x: 0; axis.y: 1; axis.z: 0 // set axis.y to 1 to rotate around y-axis
|
||||||
|
angle: 0 // the default angle
|
||||||
|
}
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
name: "back"
|
||||||
|
PropertyChanges { target: rotation; angle: 180 }
|
||||||
|
when: flipable.flipped
|
||||||
|
}
|
||||||
|
|
||||||
|
transitions: Transition {
|
||||||
|
NumberAnimation { target: rotation; property: "angle"; duration: 500 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,14 +15,21 @@ Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
property GrapheneApplication app
|
property GrapheneApplication app
|
||||||
signal finished
|
signal canceled
|
||||||
|
signal completed(TransferOperation op)
|
||||||
|
|
||||||
/// The Account object for the sender
|
/// The Account object for the sender
|
||||||
property alias senderAccount: senderPicker.account
|
property alias senderAccount: senderPicker.account
|
||||||
/// The Account object for the receiver
|
/// The Account object for the receiver
|
||||||
property alias receiverAccount: recipientPicker.account
|
property alias receiverAccount: recipientPicker.account
|
||||||
/// The operation created in this form
|
|
||||||
property var operation
|
function operation() {
|
||||||
|
if (!transferButton.enabled) return app.operationBuilder.transfer(0,0,0,0, memoField.text, 0)
|
||||||
|
|
||||||
|
return app.operationBuilder.transfer(senderPicker.account.id, recipientPicker.account.id,
|
||||||
|
amountField.value * amountField.precisionAdjustment,
|
||||||
|
amountField.maxBalance.type.id, memoField.text, 0)
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted: console.log("Made a transfer form")
|
Component.onCompleted: console.log("Made a transfer form")
|
||||||
Component.onDestruction: console.log("Destroyed a transfer form")
|
Component.onDestruction: console.log("Destroyed a transfer form")
|
||||||
|
|
@ -77,6 +84,12 @@ Rectangle {
|
||||||
|
|
||||||
property Balance maxBalance: assetField.enabled && senderPicker.showBalance >= 0?
|
property Balance maxBalance: assetField.enabled && senderPicker.showBalance >= 0?
|
||||||
senderPicker.balances[senderPicker.showBalance] : null
|
senderPicker.balances[senderPicker.showBalance] : null
|
||||||
|
property int precisionAdjustment: maxBalance? Math.pow(10, maxBalance.type.precision) : 1
|
||||||
|
|
||||||
|
// Workaround to preserve value in case form gets disabled then re-enabled
|
||||||
|
onEnabledChanged: if (!enabled) __valueBackup = value
|
||||||
|
onMaximumValueChanged: if (enabled && maximumValue > __valueBackup) value = __valueBackup
|
||||||
|
property real __valueBackup
|
||||||
}
|
}
|
||||||
ComboBox {
|
ComboBox {
|
||||||
id: assetField
|
id: assetField
|
||||||
|
|
@ -89,25 +102,21 @@ Rectangle {
|
||||||
Text {
|
Text {
|
||||||
font.pixelSize: assetField.height / 2.5
|
font.pixelSize: assetField.height / 2.5
|
||||||
text: {
|
text: {
|
||||||
var balance = amountField.maxBalance
|
if (!senderPicker.account)
|
||||||
if (!balance || !balance.type) return ""
|
return ""
|
||||||
var precisionAdjustment = Math.pow(10, balance.type.precision)
|
return qsTr("Fee:<br/>") + operation().fee / amountField.precisionAdjustment + " CORE"
|
||||||
|
|
||||||
var op = app.operationBuilder.transfer(0, 0, amountField.value * precisionAdjustment,
|
|
||||||
balance.type.id, memoField.text, 0)
|
|
||||||
|
|
||||||
return qsTr("Fee:<br/>") + op.fee / precisionAdjustment + " CORE"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Item { Layout.fillWidth: true }
|
Item { Layout.fillWidth: true }
|
||||||
Button {
|
Button {
|
||||||
text: qsTr("Cancel")
|
text: qsTr("Cancel")
|
||||||
onClicked: finished()
|
onClicked: canceled()
|
||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
|
id: transferButton
|
||||||
text: qsTr("Transfer")
|
text: qsTr("Transfer")
|
||||||
enabled: senderPicker.account && recipientPicker.account && senderPicker.account !== recipientPicker.account && amountField.value
|
enabled: senderPicker.account && recipientPicker.account && senderPicker.account !== recipientPicker.account && amountField.value
|
||||||
onClicked: console.log(amountField.value)
|
onClicked: completed(operation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,10 +60,15 @@ ApplicationWindow {
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
text: "Transfer"
|
text: "Transfer"
|
||||||
onClicked: formBox.showForm(Qt.createComponent("TransferForm.qml"), {},
|
onClicked: {
|
||||||
function() {
|
var front = Qt.createComponent("TransferForm.qml")
|
||||||
console.log("Closed form")
|
// TODO: make back into a preview and confirm dialog
|
||||||
})
|
var back = Qt.createComponent("TransferForm.qml")
|
||||||
|
formBox.showForm(Qt.createComponent("FormFlipper.qml"), {frontComponent: front, backComponent: back},
|
||||||
|
function() {
|
||||||
|
console.log("Closed form")
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TextField {
|
TextField {
|
||||||
id: nameField
|
id: nameField
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
<file>main.qml</file>
|
<file>main.qml</file>
|
||||||
<file>TransferForm.qml</file>
|
<file>TransferForm.qml</file>
|
||||||
<file>FormBox.qml</file>
|
<file>FormBox.qml</file>
|
||||||
|
<file>FormFlipper.qml</file>
|
||||||
<file>Scaling.qml</file>
|
<file>Scaling.qml</file>
|
||||||
<file>Identicon.qml</file>
|
<file>Identicon.qml</file>
|
||||||
<file>AccountPicker.qml</file>
|
<file>AccountPicker.qml</file>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue