PDA

View Full Version : problem implementing proxy models in series



Guett_31
27th May 2013, 00:37
Here is what I’m trying to achieve:
I want to display sub parts of the File System in different windows from which I can select files.
I want that the selection automatically applies to all the files and all the sub-folders under the selection and I also want that each view displays the tree structure this way:
-Root_item(1)
-- item(1,1)
--- item(1,1,1)
--- item(1,1,2)
--- item(1,1,3)
-- item(1,2)
--- item(1,2,1)
--- item(1,2,2)
-- item(1,3)

In order to do those in an efficient way, I have decided to use proxy models so I can use only one instance of QFileSystemModel for all my views.
I use two proxy layers, one for the selection feature and anoter the "single root tree" display:
QFileSystemModel->ItemSelectionProxyModel->DisplayRootItemProxyModel->QTreeView. If I set my proxies that way everything works perfectly.

The problem occurs when I set my proxies like this:QFileSystemModel->DisplayRootItemProxyModel->ItemSelectionProxyModel->QTreeView. In that case the application fails to automatically select a few items (always the same ones) when I select a folder with a lot of files and subfolders.

I designed my two proxies from a IdentityFileSystemProxyModel base class, which is sub-classed from QIdentityProxyModel.
Here is code of the proxy base class, IdentityFileSystemProxyModel:

{
class IdentityFileSystemProxyModel : public QIdentityProxyModel
Q_OBJECT
protected:

QAbstractItemModel * m_model;
public:

IdentityFileSystemProxyModel(QObject *parent = 0);

void setSourceModel(QAbstractItemModel * sourceModel);
virtual int columnCount(const QModelIndex & parent) const;
virtual QString filePath(const QModelIndex & index) const;

signals:
void directoryLoaded(QString path);

public slots:
void directoryLoadedSlot(QString path);
};

#include "IdentityFileSystemProxyModel.h"

IdentityFileSystemProxyModel::IdentityFileSystemPr oxyModel(QObject *parent) : QIdentityProxyModel(parent)
{
}

void IdentityFileSystemProxyModel::setSourceModel(QAbst ractItemModel * sourceModel)
{
m_model = sourceModel;
QIdentityProxyModel::setSourceModel(m_model);
QObject::connect(m_model,SIGNAL(directoryLoaded(QS tring)),this,SLOT(directoryLoadedSlot(QString)));
}

int IdentityFileSystemProxyModel::columnCount(const QModelIndex & parent) const
{
return 1;
}

QString IdentityFileSystemProxyModel::filePath(const QModelIndex & index) const
{
return data(index, Qt::UserRole + 1).toString();
}

void IdentityFileSystemProxyModel::directoryLoadedSlot( QString path)
{
emit directoryLoaded(path);
}
Here is how the QFileSystemModel , the two proxies and the view are connected for QFileSystemModel->DisplayRootItem->ItemSelectionProxyModel->QTreeView:

void FileSysSelectView::setRootIndex(const QModelIndex & index)
{
//from sourceModel to rootItemModel
QModelIndex proxIdx = m_rootModel->mapFromSource(index);

m_rootModel->setHomeIndex(proxIdx);
proxIdx = m_rootModel->getHomeIndex();

//from rootItemModel to selectModel
proxIdx = m_selectModel->mapFromSource(proxIdx);

QTreeView::setRootIndex(proxIdx);
}

void FileSysSelectView::setModel(QAbstractItemModel * model)
{
m_sourceModel = static_cast<QFileSystemModel *> (model);
m_rootModel = new RootItemProxyModel();
m_selectModel = new SelectItemProxyModel();

m_rootModel->setSourceModel(m_sourceModel);
m_selectModel->setSourceModel(m_rootModel);

QTreeView::setModel(m_selectModel);
QObject::connect(m_selectModel,
SIGNAL(dataChanged(QModelIndex, QModelIndex)),
this,
SLOT(ExpandItems(QModelIndex, QModelIndex)),
Qt::DirectConnection);
}
I think the problem comes from the IdentityFileSystemProxyModel base class:
If I do QFileSystemModel->ItemSelectionProxyModel->QTreeView , I have no selection problem.
If I do QFileSystemModel->IdentityFileSystemProxyModel->ItemSelectionProxyModel->QTreeView, I have the same selection problem I mentioned earlier.
I have been unsuccessful to figure out what was wrong so far...

Attached is a compilable project that shows the problem.

Thanks in advance!