jeudi 27 juillet 2017

Qt5: Drag and Drop when using QSortFilterProxyModel

I have a model that is sub-classed from QAbstractListModel that has different Listviews that are filtered using a sub-classed QSortFilterProxyModel for each view. The data in the view can be sorted when the user clicks a sort button.

I implemented the drag and drop inside the QSortFilterProxyModel, to change the state of the data when it is dropped into a new Listview. This works fine, however, manually sorting the items within a listview causes all other listview displaying the same data to be sorted as well, which is not what I want.

Example, View 1 shows all participants, view 2 shows participants that are active. When dragged from view 1 to view 2, the participant becomes active. If I manually sort the participants, the index of participants that are active also get sorted. This does however not happen if I automatically sort them using proxyModel->sort() method.

How can I manually rearrange the data in the proxy model without changing the index in the source model?

Example code:

MySortFilterProxyModel::MySortFilterProxyModel(bool active, QObject *parent ) :
QSortFilterProxyModel( parent ),
m_filter( "" ), 
m_active(active)
{
    setDynamicSortFilter( false );
}

void MySortFilterProxyModel::setFilter( QString filter )
{
   m_filter = filter;
   invalidateFilter();
}

Qt::ItemFlags MySortFilterProxyModel::flags( const QModelIndex &index ) const
{
    if( index.isValid() )
    {
        return ( QSortFilterProxyModel::flags( index ) | Qt::ItemIsDragEnabled |  Qt::ItemIsEditable );
    }

    return Qt::ItemIsDropEnabled |  QSortFilterProxyModel::flags( index );
 }

bool MySortFilterProxyModel::dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent )
 {


     if( !data->hasFormat( dataModel::dataMimeType() ) )
     {
        return false;
     }

     if( action == Qt::IgnoreAction )
     {
        return true;
     }

     if( column > 0 )
     {
        return false;
     }

    QByteArray encodeData = data->data(dataModel::dataMimeType());
    QDataStream stream( &encodeData, QIODevice::ReadOnly );

    while( !stream.atEnd() )
    {
      DataRecord *dr = new DataRecord();
      stream >> dr;

      dr->setActive( m_active );

      // AddData method in the dataModel removes duplicate rows and inserts the data into the correct row.
      qobject_cast< DataModel * >( sourceModel() )->addData( fdr ); 

   }
   return true;
}

Aucun commentaire:

Enregistrer un commentaire