因此,由于这里没有做任何职位,我在此提出我自己的解决办法(也使用文字过滤):
void ContractorsFilter::onCustomFilterChanged( const QString& text )
{
try
{
struct MatchFilter
{
// data
QString filter_;
Companies& filtered_recipients_;
// methods
MatchFilter( const QString& _filter, Companies& _recipients )
: filter_( _filter )
, filtered_recipients_( _recipients )
{
filtered_recipients_.clear();
}
void operator()( const Companies::value_type& val ) const
{
bool isFound = false;
std::vector< ContractorData >::const_iterator con_i( val.second.begin() ), con_e( val.second.end() );
for( ; con_i != con_e; ++con_i )
{
const QString contractorName = (*con_i).name;
if( contractorName.contains( filter_, Qt::CaseInsensitive ) )
{
filtered_recipients_[ val.first ].push_back( (*con_i) );
isFound = true;
}
}
const QString companyName = val.first.name;
if( companyName.contains( filter_, Qt::CaseInsensitive ) )
{
filtered_recipients_[ val.first ].push_back( ContractorData() );
}
}
};
struct FillView
{
// data
QFont boldFont;
QBrush whiteBrush;
QStandardItemModel* model_;
// methods
FillView( QStandardItemModel* model )
: model_( model )
{
model_->clear();
}
void operator ()( const Companies::value_type& val ) const
{
struct AppendContractors
{
// data
QStandardItem* parent_;
// methods
AppendContractors( QStandardItem* _parent = 0 )
: parent_( _parent )
{}
bool isEmpty( const ContractorData& contractor ) const
{
return contractor.id.isEmpty();
}
void operator()( const std::vector< ContractorData >::value_type& contractor ) const
{
if( !isEmpty( contractor ) )
{
QStandardItem *item = 0;
QList< QStandardItem* > line;
line << ( item = new QStandardItem( QIcon( ACCOUNT_ITEM_ICON ), contractor.name ) );
item->setSizeHint( QSize( 0, 25 ) );
parent_->appendRow( line );
}
}
};
QStandardItem *parentItem = model_->invisibleRootItem();
// добавляем новую компанию + контрагента
QList< QStandardItem* > line;
line << ( parentItem = new QStandardItem( QIcon( COMPANY_ITEM_ICON ), val.first.name ) );
parentItem->setSizeHint( QSize( 0, 25 ) );
model_->appendRow( line );
std::for_each( val.second.begin(), val.second.end(), AppendContractors( parentItem ) );
}
};
// удаляем символ(ы), которые не фильтруются
// формируется новая таблица, которая и будет использоваться моделью для отображения
std::for_each( data_.begin(), data_.end(),
MatchFilter( text, filter_data_ ) );
// вывод отфильтрованных контрагентов
std::for_each( filter_data_.begin(), filter_data_.end(),
FillView( model_ ) );
ui_.treeView->expandAll();
}
catch( const std::exception& e )
{
Core::errLog( "ContractorsFilter::onCustomFilterChanged", e.what() );
throw;
}
}
PS: 类别<代码>Companies
typedef std::map< CompanyData, ContractorsData, LessData< CompanyData > > Companies;
CompanyData,ContractorsData
为简单结构......
有一个天!