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); }