From b9df912666cf585b454d6cb816e13cb88e23cfec Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> Date: Fri, 20 Mar 2015 17:08:59 -0400 Subject: [PATCH] account: Use selectionModel Refs #68848 --- src/account.cpp | 12 ++-- src/accountmodel.cpp | 135 +++++++++++++++++++++++++++++------ src/accountmodel.h | 21 ++++-- src/codecmodel.cpp | 57 ++++++++------- src/private/accountmodel_p.h | 3 + src/tlsmethodmodel.cpp | 17 +++-- 6 files changed, 178 insertions(+), 67 deletions(-) diff --git a/src/account.cpp b/src/account.cpp index 4a55934b..76030a03 100644 --- a/src/account.cpp +++ b/src/account.cpp @@ -644,7 +644,7 @@ bool Account::isTlsRequireClientCertificate() const ///Return the account TLS security is enabled bool Account::isTlsEnabled() const { - return (d_ptr->accountDetail(DRing::Account::ConfProperties::TLS::ENABLED) IS_TRUE); + return protocol() == Account::Protocol::RING || (d_ptr->accountDetail(DRing::Account::ConfProperties::TLS::ENABLED) IS_TRUE); } ///Return the key exchange mechanism @@ -964,8 +964,8 @@ void AccountPrivate::setAccountProperties(const QHash<QString,QString>& m) ///Set a specific detail bool AccountPrivate::setAccountProperty(const QString& param, const QString& val) { - const bool accChanged = m_hAccountDetails[param] != val; const QString buf = m_hAccountDetails[param]; + const bool accChanged = buf != val; //Status can be changed regardless of the EditState //TODO make this more generic for volatile properties if (param == DRing::Account::ConfProperties::Registration::STATUS) { @@ -975,14 +975,12 @@ bool AccountPrivate::setAccountProperty(const QString& param, const QString& val emit q_ptr->propertyChanged(q_ptr,param,val,buf); } } - else { + else if (accChanged) { q_ptr->performAction(Account::EditAction::MODIFY); if (m_CurrentState == Account::EditState::MODIFIED || m_CurrentState == Account::EditState::NEW) { m_hAccountDetails[param] = val; - if (accChanged) { - emit q_ptr->changed(q_ptr); - emit q_ptr->propertyChanged(q_ptr,param,val,buf); - } + emit q_ptr->changed(q_ptr); + emit q_ptr->propertyChanged(q_ptr,param,val,buf); } } return m_CurrentState == Account::EditState::MODIFIED || m_CurrentState == Account::EditState::NEW; diff --git a/src/accountmodel.cpp b/src/accountmodel.cpp index 2cb566e2..046bbfff 100644 --- a/src/accountmodel.cpp +++ b/src/accountmodel.cpp @@ -22,12 +22,14 @@ //Qt #include <QtCore/QObject> #include <QtCore/QCoreApplication> +#include <QtCore/QItemSelectionModel> //Ring daemon #include <account_const.h> //Ring library #include "account.h" +#include "mime.h" #include "profilemodel.h" #include "protocolmodel.h" #include "private/account_p.h" @@ -41,7 +43,7 @@ QHash<QByteArray,AccountPlaceHolder*> AccountModelPrivate::m_hsPlaceHolder; AccountModel* AccountModelPrivate::m_spAccountList; AccountModelPrivate::AccountModelPrivate(AccountModel* parent) : QObject(parent),q_ptr(parent), -m_pIP2IP(nullptr),m_pProtocolModel(nullptr) +m_pIP2IP(nullptr),m_pProtocolModel(nullptr),m_pSelectionModel(nullptr),m_lMimes({RingMimes::ACCOUNT}) { } @@ -161,6 +163,14 @@ AccountModel* AccountModel::instance() return AccountModelPrivate::m_spAccountList; } +QItemSelectionModel* AccountModel::selectionModel() const +{ + if (!d_ptr->m_pSelectionModel) + d_ptr->m_pSelectionModel = new QItemSelectionModel(const_cast<AccountModel*>(this)); + + return d_ptr->m_pSelectionModel; +} + /** * The client have a different point of view when it come to the account * state. All the different errors are also handled elsewhere @@ -401,31 +411,27 @@ void AccountModel::save() } ///Move account up -bool AccountModel::moveUp( const QModelIndex& idx ) -{ - int row = idx.row(); - if(row > 0 && row <= rowCount()) { - Account* account = d_ptr->m_lAccounts[row]; - d_ptr->m_lAccounts.remove(row); - d_ptr->m_lAccounts.insert(row - 1, account); - emit dataChanged(this->index(row - 1, 0, QModelIndex()), this->index(row, 0, QModelIndex())); - emit layoutChanged(); - return true; +bool AccountModel::moveUp() +{ + if (d_ptr->m_pSelectionModel) { + const QModelIndex& idx = d_ptr->m_pSelectionModel->currentIndex(); + if (dropMimeData(mimeData({idx}), Qt::MoveAction, idx.row()-1, idx.column(),idx.parent())) { + d_ptr->m_pSelectionModel->setCurrentIndex(index(idx.row()-1,idx.column()), QItemSelectionModel::ClearAndSelect); + return true; + } } return false; } ///Move account down -bool AccountModel::moveDown( const QModelIndex& idx ) -{ - int row = idx.row(); - if(row >= 0 && row < rowCount()) { - Account* account = d_ptr->m_lAccounts[row]; - d_ptr->m_lAccounts.remove(row); - d_ptr->m_lAccounts.insert(row + 1, account); - emit dataChanged(this->index(row, 0, QModelIndex()), this->index(row + 1, 0, QModelIndex())); - emit layoutChanged(); - return true; +bool AccountModel::moveDown() +{ + if (d_ptr->m_pSelectionModel) { + const QModelIndex& idx = d_ptr->m_pSelectionModel->currentIndex(); + if (dropMimeData(mimeData({idx}), Qt::MoveAction, idx.row()+1, idx.column(),idx.parent())) { + d_ptr->m_pSelectionModel->setCurrentIndex(index(idx.row()+1,idx.column()), QItemSelectionModel::ClearAndSelect); + return true; + } } return false; } @@ -599,6 +605,11 @@ Account* AccountModel::add(const QString& alias, const Account::Protocol proto) //connect(a,SIGNAL(propertyChanged(Account*,QString,QString,QString)),d_ptr,SLOT(slotAccountChanged(Account*))); emit dataChanged(index(d_ptr->m_lAccounts.size()-1,0), index(d_ptr->m_lAccounts.size()-1,0)); + + if (d_ptr->m_pSelectionModel) { + d_ptr->m_pSelectionModel->setCurrentIndex(index(d_ptr->m_lAccounts.size()-1,0), QItemSelectionModel::ClearAndSelect); + } + return a; } @@ -679,4 +690,86 @@ void AccountModel::add(Account* acc) d_ptr->m_lAccounts << acc; } + +/***************************************************************************** + * * + * Drag and drop * + * * + ****************************************************************************/ + + +QStringList AccountModel::mimeTypes() const +{ + return d_ptr->m_lMimes; +} + +bool AccountModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) +{ + Q_UNUSED(action) + if(parent.isValid() || column > 0) { + qDebug() << "column invalid"; + return false; + } + + if (data->hasFormat(RingMimes::ACCOUNT)) { + int destinationRow = -1; + + if(row < 0) { + //drop on top + destinationRow = d_ptr->m_lAccounts.size() - 1; + } + else if(row >= d_ptr->m_lAccounts.size()) { + destinationRow = 0; + } + else if(data->hasFormat(RingMimes::VIDEO_CODEC) && row >= rowCount()) { + destinationRow = 0; + } + else { + destinationRow = row; + } + + Account* dest = getById(data->data(RingMimes::ACCOUNT)); + if (!dest) + return false; + + const QModelIndex codecIdx = dest->index(); + + beginRemoveRows(QModelIndex(), codecIdx.row(), codecIdx.row()); + Account* codecInfo = d_ptr->m_lAccounts[codecIdx.row()]; + d_ptr->m_lAccounts.removeAt(codecIdx.row()); + endRemoveRows(); + + beginInsertRows(QModelIndex(), destinationRow, destinationRow); + d_ptr->m_lAccounts.insert(destinationRow,codecInfo); + endInsertRows(); + + return true; + } + + return false; +} + +QMimeData* AccountModel::mimeData(const QModelIndexList& indexes) const +{ + QMimeData* mMimeData = new QMimeData(); + + for (const QModelIndex& index : indexes) { + if (index.isValid()) { + mMimeData->setData(RingMimes::ACCOUNT, index.data((int)Account::Role::Id).toByteArray()); + } + } + + return mMimeData; +} + +Qt::DropActions AccountModel::supportedDragActions() const +{ + return Qt::MoveAction | Qt::TargetMoveAction; +} + +Qt::DropActions AccountModel::supportedDropActions() const +{ + return Qt::MoveAction | Qt::TargetMoveAction; +} + #include <accountmodel.moc> diff --git a/src/accountmodel.h b/src/accountmodel.h index bb286177..c8cd6e2b 100644 --- a/src/accountmodel.h +++ b/src/accountmodel.h @@ -62,12 +62,19 @@ public: bool isPresenceSubscribeSupported( ) const; ProtocolModel* protocolModel ( ) const; + QItemSelectionModel* selectionModel ( ) const; + //Abstract model accessors - virtual QVariant data ( const QModelIndex& index, int role = Qt::DisplayRole ) const override; - virtual int rowCount ( const QModelIndex& parent = QModelIndex() ) const override; - virtual Qt::ItemFlags flags ( const QModelIndex& index ) const override; - virtual bool setData ( const QModelIndex& index, const QVariant &value, int role) override; - virtual QHash<int,QByteArray> roleNames( ) const override; + virtual QVariant data ( const QModelIndex& index, int role = Qt::DisplayRole ) const override; + virtual int rowCount ( const QModelIndex& parent = QModelIndex() ) const override; + virtual Qt::ItemFlags flags ( const QModelIndex& index ) const override; + virtual bool setData ( const QModelIndex& index, const QVariant &value, int role ) override; + virtual QHash<int,QByteArray> roleNames ( ) const override; + virtual QMimeData* mimeData ( const QModelIndexList &indexes ) const override; + virtual QStringList mimeTypes ( ) const override; + virtual bool dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) override; + virtual Qt::DropActions supportedDragActions() const override; + virtual Qt::DropActions supportedDropActions() const override; //Mutators Q_INVOKABLE Account* add ( const QString& alias, const Account::Protocol protocol = Account::Protocol::SIP); @@ -75,8 +82,6 @@ public: Q_INVOKABLE void remove ( Account* account ); void remove ( const QModelIndex& index ); void save ( ); - Q_INVOKABLE bool moveUp ( const QModelIndex& idx ); - Q_INVOKABLE bool moveDown ( const QModelIndex& idx ); Q_INVOKABLE void cancel ( ); //Operators @@ -99,6 +104,8 @@ public Q_SLOTS: void update (); void updateAccounts (); void registerAllAccounts(); + bool moveUp (); + bool moveDown (); Q_SIGNALS: diff --git a/src/codecmodel.cpp b/src/codecmodel.cpp index 9dfa182c..c270c675 100644 --- a/src/codecmodel.cpp +++ b/src/codecmodel.cpp @@ -193,25 +193,17 @@ bool CodecModel::setData( const QModelIndex& idx, const QVariant &value, int rol return false; } -Qt::DropActions CodecModel::supportedDragActions() const -{ - return Qt::MoveAction | Qt::TargetMoveAction; -} - -Qt::DropActions CodecModel::supportedDropActions() const -{ - return Qt::MoveAction | Qt::TargetMoveAction; -} - ///Add a new audio codec -QModelIndex CodecModel::add() { +QModelIndex CodecModel::add() +{ d_ptr->m_lCodecs << new CodecModelPrivate::CodecData; emit dataChanged(index(d_ptr->m_lCodecs.size()-1,0), index(d_ptr->m_lCodecs.size()-1,0)); return index(d_ptr->m_lCodecs.size()-1,0); } ///Remove audio codec at 'idx' -void CodecModel::remove(const QModelIndex& idx) { +void CodecModel::remove(const QModelIndex& idx) +{ if (idx.isValid()) { CodecModelPrivate::CodecData* d = d_ptr->m_lCodecs[idx.row()]; d_ptr->m_lCodecs.removeAt(idx.row()); @@ -326,18 +318,13 @@ bool CodecModelPrivate::findCodec(int id) return false; } - -QSortFilterProxyModel* CodecModel::audioCodecs() const +///Return valid payload types +int CodecModel::acceptedPayloadTypes() const { - if (!d_ptr->m_pAudioProxy) { - d_ptr->m_pAudioProxy = new QSortFilterProxyModel(const_cast<CodecModel*>(this)); - d_ptr->m_pAudioProxy->setSourceModel(const_cast<CodecModel*>(this)); - d_ptr->m_pAudioProxy->setFilterRole(CodecModel::Role::TYPE); - d_ptr->m_pAudioProxy->setFilterFixedString("AUDIO"); - } - return d_ptr->m_pAudioProxy; + return CallModel::DropPayloadType::AUDIO_CODEC | CallModel::DropPayloadType::VIDEO_CODEC; } + QSortFilterProxyModel* CodecModel::videoCodecs() const { if (!d_ptr->m_pVideoProxy) { @@ -349,6 +336,18 @@ QSortFilterProxyModel* CodecModel::videoCodecs() const return d_ptr->m_pVideoProxy; } + +QSortFilterProxyModel* CodecModel::audioCodecs() const +{ + if (!d_ptr->m_pAudioProxy) { + d_ptr->m_pAudioProxy = new QSortFilterProxyModel(const_cast<CodecModel*>(this)); + d_ptr->m_pAudioProxy->setSourceModel(const_cast<CodecModel*>(this)); + d_ptr->m_pAudioProxy->setFilterRole(CodecModel::Role::TYPE); + d_ptr->m_pAudioProxy->setFilterFixedString("AUDIO"); + } + return d_ptr->m_pAudioProxy; +} + // ======== DnD Api ========= QModelIndex CodecModelPrivate::getIndexofCodecByID(int id) @@ -361,12 +360,6 @@ QModelIndex CodecModelPrivate::getIndexofCodecByID(int id) return QModelIndex(); } -///Return valid payload types -int CodecModel::acceptedPayloadTypes() const -{ - return CallModel::DropPayloadType::AUDIO_CODEC | CallModel::DropPayloadType::VIDEO_CODEC; -} - QStringList CodecModel::mimeTypes() const { return d_ptr->m_lMimes; @@ -437,4 +430,14 @@ QMimeData* CodecModel::mimeData(const QModelIndexList& indexes) const return mMimeData; } +Qt::DropActions CodecModel::supportedDragActions() const +{ + return Qt::MoveAction | Qt::TargetMoveAction; +} + +Qt::DropActions CodecModel::supportedDropActions() const +{ + return Qt::MoveAction | Qt::TargetMoveAction; +} + #include <codecmodel.moc> diff --git a/src/private/accountmodel_p.h b/src/private/accountmodel_p.h index 687ef28e..a9cf5fe5 100644 --- a/src/private/accountmodel_p.h +++ b/src/private/accountmodel_p.h @@ -24,6 +24,7 @@ class AccountModel; class AccountListColorDelegate; class ProtocolModel; +class QItemSelectionModel; class AccountModelPrivate : public QObject { @@ -49,6 +50,8 @@ public: QList<Account*> m_pRemovedAccounts; static AccountModel* m_spAccountList ; ProtocolModel* m_pProtocolModel ; + QItemSelectionModel* m_pSelectionModel ; + QStringList m_lMimes ; //Future account cache static QHash<QByteArray,AccountPlaceHolder*> m_hsPlaceHolder; diff --git a/src/tlsmethodmodel.cpp b/src/tlsmethodmodel.cpp index 0d149816..2cf3d548 100644 --- a/src/tlsmethodmodel.cpp +++ b/src/tlsmethodmodel.cpp @@ -52,6 +52,7 @@ public: static const char* toDaemonName(TlsMethodModel::Type type); static TlsMethodModel::Type fromDaemonName(const QString& name); + bool isRing; mutable QItemSelectionModel* m_pSelectionModel; Account* m_pAccount; @@ -62,9 +63,9 @@ public Q_SLOTS: const QString TlsMethodModelPrivate::Name::DEFAULT = tr("Default", "Default TLS protocol version"); -TlsMethodModelPrivate::TlsMethodModelPrivate(Account* a) : m_pSelectionModel(nullptr), m_pAccount(a) +TlsMethodModelPrivate::TlsMethodModelPrivate(Account* a) : m_pSelectionModel(nullptr), m_pAccount(a), isRing(false) { - + isRing = a->protocol() == Account::Protocol::RING; } TlsMethodModel::TlsMethodModel(Account* a) : QAbstractListModel(QCoreApplication::instance()), @@ -90,6 +91,10 @@ QVariant TlsMethodModel::data( const QModelIndex& index, int role) const if (!index.isValid()) return QVariant(); TlsMethodModel::Type method = static_cast<TlsMethodModel::Type>(index.row()); if (role == Qt::DisplayRole) { + + if (d_ptr->isRing) + return tr("Automatic"); + switch (method) { case TlsMethodModel::Type::DEFAULT: return TlsMethodModelPrivate::Name::DEFAULT; @@ -106,7 +111,7 @@ QVariant TlsMethodModel::data( const QModelIndex& index, int role) const int TlsMethodModel::rowCount( const QModelIndex& parent ) const { - return parent.isValid()?0:4; + return parent.isValid()?0: d_ptr->isRing ? 1 : 4; } Qt::ItemFlags TlsMethodModel::flags( const QModelIndex& index ) const @@ -137,7 +142,8 @@ QItemSelectionModel* TlsMethodModel::selectionModel() const const QModelIndex& idx = toIndex(TlsMethodModelPrivate::fromDaemonName(value)); d_ptr->m_pSelectionModel->setCurrentIndex(idx,QItemSelectionModel::ClearAndSelect); - connect(d_ptr->m_pSelectionModel,&QItemSelectionModel::currentChanged,d_ptr,&TlsMethodModelPrivate::slotSelectionChanged); + if (!d_ptr->isRing) + connect(d_ptr->m_pSelectionModel,&QItemSelectionModel::currentChanged,d_ptr,&TlsMethodModelPrivate::slotSelectionChanged); } return d_ptr->m_pSelectionModel; @@ -149,7 +155,8 @@ void TlsMethodModelPrivate::slotSelectionChanged(const QModelIndex& idx) return; const char* value = toDaemonName(static_cast<TlsMethodModel::Type>(idx.row())); - m_pAccount->d_ptr->setAccountProperty(DRing::Account::ConfProperties::TLS::METHOD , value); + if (value != m_pAccount->d_ptr->accountDetail(DRing::Account::ConfProperties::TLS::METHOD)) + m_pAccount->d_ptr->setAccountProperty(DRing::Account::ConfProperties::TLS::METHOD , value); } ///Convert a TlsMethodModel::Type enum to the string expected by the daemon API -- GitLab