class AbstractCommand : public QObject
{
    Q_OBJECT
public:
    explicit AbstractCommand(QObject* a_parent = nullptr);
    Q_INVOKABLE virtual void execute() = 0;
    virtual bool canExecute() const = 0;
signals:
    void canExecuteChanged( bool a_canExecute );
};

AbstractCommand::AbstractCommand(QObject *a_parent)
    : QObject( a_parent )
{
}

AbstractConfigurableCommand::AbstractConfigurableCommand(QObject *a_parent)
    :   AbstractCommand( a_parent )
    , m_canExecute( false ) { }

bool AbstractConfigurableCommand::canExecute() const
{
    return m_canExecute;
}
void AbstractConfigurableCommand::setCanExecute( bool a_canExecute )
{
    if( a_canExecute != m_canExecute ) {
        m_canExecute = a_canExecute;
        emit canExecuteChanged( m_canExecute );
        emit localCanExecuteChanged( m_canExecute );
    }
}

#include 

#include "CompositeCommand.h"

/*! \brief Constructor for a empty initial composite command */
CompositeCommand::CompositeCommand( QObject *a_parent )
    : AbstractCommand ( a_parent ) {}

/*! \brief Constructor for a list of members */
CompositeCommand::CompositeCommand( QList a_members, QObject *a_parent )
    : AbstractCommand ( a_parent )
{
    foreach (AbstractCommand* member, a_members) {
        registration(member);
        m_members.append( QSharedPointer(member) );
    }
}

/*! \brief Constructor for a list of members */
CompositeCommand::CompositeCommand( QList> a_members, QObject *a_parent )
    : AbstractCommand ( a_parent )
    , m_members ( a_members )
{
    foreach (const QSharedPointer& member, m_members) {
        registration(member.data());
    }
}

/*! \brief Destructor */
CompositeCommand::~CompositeCommand()
{
    foreach (const QSharedPointer& member, m_members) {
        deregistration(member.data());
    }
}

void CompositeCommand::executeAsync()
{
    foreach (const QSharedPointer& member, m_members) {
        member->executeAsync();
    }
}

bool CompositeCommand::canExecute() const
{
    foreach (const QSharedPointer& member, m_members) {
        if (!member->canExecute()) {
            return false;
        }
    }
    return true;
}

/*! \brief When one's canExecute changes */
void CompositeCommand::onCanExecuteChanged( bool a_canExecute )
{
    bool oldstate = !a_canExecute;
    bool newstate = a_canExecute;
    foreach (const QSharedPointer& member, m_members) {
        if ( member.data() != sender() ) {
            oldstate &= member->canExecute();
            newstate &= member->canExecute();
        }
    }

    if (oldstate != newstate) {
        emit canExecuteChanged( newstate );
    }
}

/*! \brief When one's execution completes */
void CompositeCommand::onExecutionCompleted( )
{
    m_completedCount++;

    if ( m_completedCount == m_members.count( ) ) {
        m_completedCount = 0;
        emit executionCompleted();
    }
}


void CompositeCommand::registration( AbstractCommand* a_member )
{
    connect( a_member, &AbstractCommand::canExecuteChanged,
             this, &CompositeCommand::onCanExecuteChanged );
    connect( a_member, &AbstractCommand::executionCompleted,
             this, &CompositeCommand::onExecutionCompleted );
}

void CompositeCommand::deregistration( AbstractCommand* a_member )
{
    disconnect( a_member, &AbstractCommand::canExecuteChanged,
                this, &CompositeCommand::onCanExecuteChanged );
    disconnect( a_member, &AbstractCommand::executionCompleted,
                this, &CompositeCommand::onExecutionCompleted );
}

void CompositeCommand::handleCanExecuteChanged(bool a_oldCanExecute)
{
    bool newCanExecute = canExecute();
    if( a_oldCanExecute != newCanExecute )
    {
        emit canExecuteChanged( newCanExecute );
    }
}

void CompositeCommand::add(AbstractCommand* a_member)
{
    bool oldCanExecute = canExecute();

    QQmlEngine::setObjectOwnership ( a_member, QQmlEngine::CppOwnership );
    m_members.append( QSharedPointer( a_member ) );
    registration ( a_member );

    handleCanExecuteChanged(oldCanExecute);
}

void CompositeCommand::add(const QSharedPointer& a_member)
{
    bool oldCanExecute = canExecute();

    m_members.append( a_member );
    registration ( a_member.data() );

    handleCanExecuteChanged(oldCanExecute);
}

void CompositeCommand::remove(AbstractCommand* a_member)
{
    bool oldCanExecute = canExecute();

    QMutableListIterator > i( m_members );
    while (i.hasNext()) {
        QSharedPointer val = i.next();
        if ( val.data() == a_member) {
            deregistration(val.data());
            i.remove();
        }
    }

    handleCanExecuteChanged(oldCanExecute);
}

void CompositeCommand::remove(const QSharedPointer& a_member)
{
    bool oldCanExecute = canExecute();

    deregistration(a_member.data());
    m_members.removeAll( a_member );

    handleCanExecuteChanged(oldCanExecute);
}

New blog subtitle.

After a few months of maintaining ‘desinformatizia’ We took away their mystery.

Sony XPeria 10 III met Sailfish

Ik heb mezelf eindelijk een (refurbished) nieuw toestel gekocht waarmee je kan bellen en zo van die andere nuttige dingen.

Uiteraard moet daar SailfishOS van me opstaan.

En deze keer werkt echt alles dat ik nodig heb. Goede ontvangst, GPS, 4G