#include <QtGui>

class QfTreeProxyModel : public QSortFilterProxyModel {
	public:
		QfTreeProxyModel (QObject *parent = 0)
			: QSortFilterProxyModel(parent)
		{
			setFilterCaseSensitivity(Qt::CaseInsensitive);
		}

	protected:
		bool filterAcceptsRow (int source_row, const QModelIndex& source_parent) const {
			QModelIndex idx = sourceModel()->index(source_row, 0, source_parent);
			if (sourceModel()->hasChildren(idx))
				return(true);
			return(QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent));
		}
};

int main (int argc, char **argv) {
	QApplication app(argc, argv);

	QWidget *window = new QWidget;
	QGridLayout *layout = new QGridLayout;
	window->setLayout(layout);

	QLineEdit *filterEdit = new QLineEdit;
	layout->addWidget(filterEdit, 0, 0, 1, 2);

	QTreeView *treeViewFull = new QTreeView;
	treeViewFull->setHeaderHidden(true);
	layout->addWidget(treeViewFull, 1, 0);

	QTreeView *treeViewFilter = new QTreeView;
	treeViewFilter->setHeaderHidden(true);
	layout->addWidget(treeViewFilter, 1, 1);

	// Setup Model and Load Data
	QStandardItemModel *model = new QStandardItemModel(0, 1);
	QStandardItem *parentItem = model->invisibleRootItem();
	for (int i = 0; i < 3; ++i) {
		QIcon iconFolder = window->style()->standardPixmap(QStyle::SP_DirOpenIcon);
		QStandardItem *item = new QStandardItem(iconFolder, QString("Item %0").arg(i));	
		parentItem->appendRow(item);

		QIcon iconItem = window->style()->standardPixmap(QStyle::SP_FileIcon);
		for (int j = 0; j < 3; ++j) {
			QStandardItem *subItem = new QStandardItem(iconItem, QString("SubItem %0%1").arg(i).arg(j));
			item->appendRow(subItem);
		}
	}

	// Setup Proxy Model
	QfTreeProxyModel *proxyModel = new QfTreeProxyModel;
	proxyModel->setDynamicSortFilter(true);
	proxyModel->setSourceModel(model);
	proxyModel->setFilterKeyColumn(0);

	treeViewFilter->setModel(proxyModel);
	treeViewFull->setModel(model);

	treeViewFilter->expandAll();
	treeViewFull->expandAll();

	QObject::connect(	filterEdit, SIGNAL(textChanged(const QString&)),
						proxyModel, SLOT(setFilterWildcard(const QString&)));

	window->show();

	return(app.exec());
}

