PDA

View Full Version : mapFromSource and parent



Infinity
29th March 2014, 20:57
Hi,

I have three models:
- main model shown in mainTreeview
- filter model 1 (with main model as source) shown in filter1Treeview
- filter model 2 (with main model as source) shown in filter2Treeview

These models seem to work correctly.

Now I want to select a row in filter2Treeview based on a selection in filter1Treeview if there is are corresponding counterparts.
That's what I got so far:


foreach(const QModelIndex &row, m_ui->currentTreeView->selectionModel()->selectedRows()) {
QModelIndex counterpartIndex = m_previewGenerator->model()->counterpart(
m_previewGenerator->currentModel()->mapToSource(row), 1);
if(counterpartIndex.isValid()) {
QModelIndex index = m_previewGenerator->previewModel()->mapFromSource(counterpartIndex);
m_ui->previewTreeView->selectionModel()->select(index, QItemSelectionModel::Rows | QItemSelectionModel::ClearAndSelect);
}
}

Using the debugger I found out that counterpartIndex seems to be right. Row, column and parent return the expected values.
The problem is that mapFromSource doesn't return the index I want. It returns an valid index and row and column have the expected values, too. The problem is the parent. It is always an invalid model index.

Here's my filter implementation:


bool FilteredFileSystemItemModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent);
if(sourceIndex.isValid()) {
if(FileSystemItem *item = reinterpret_cast<FileSystemItem *>(sourceIndex.internalPointer())) {
return item->status() == m_statusFilter
|| (item->type() == ItemType::Dir && item->children().size());
}
}
return false;
}

bool FilteredFileSystemItemModel::filterAcceptsColumn(i nt sourceColumn, const QModelIndex &) const
{
switch(m_statusFilter) {
case ItemStatus::Existing:
return sourceColumn == 0 || sourceColumn == 2;
case ItemStatus::New:
return sourceColumn == 1;
default:
return false;
}
}


I suspect what the problem is (but I don't know if I'm correct and how to solve the problem): The first column isn't present in the second filter model. The column of counterpartIndex is 1 (second column) - that's all right an can be mapped. Its parent however has the column 0. I think the is because the parent implementation in the main model only returns parents with the column 0. I implemented the parent method like this because it seems to be required according to the documentation:
"A common convention used in models that expose tree data structures is that only items in the first column have children. For that case, when reimplementing this function in a subclass the column of the returned QModelIndex would be 0."

Has anybody an idea how to solve this problem?

(The reason why I'm not simply using the QFileSystemModel is that the file system structure I'm dealing with doesn't exist on the system (yet).)

Edit: I changed the implementation of parent in the main model to create and return indexes with the column of the given index. Now everything works like I expect. But now I'm breaking the rule from the documentation. Because the parent has always the same number of columns as the child so there shouldn't be a problem (and practically there is no a problem either). But I think the way I solved the problem is not very nice nevertheless, so I'm open for other suggestions.