int QSortFilterProxyModel::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QAbstractProxyModel::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        if (_id < 20)
            qt_static_metacall(this, _c, _id, _a);
        _id -= 20;
    }
#ifndef QT_NO_PROPERTIES
      else if (_c == QMetaObject::ReadProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: *reinterpret_cast< QRegExp*>(_v) = filterRegExp(); break;
        case 1: *reinterpret_cast< int*>(_v) = filterKeyColumn(); break;
        case 2: *reinterpret_cast< bool*>(_v) = dynamicSortFilter(); break;
        case 3: *reinterpret_cast< Qt::CaseSensitivity*>(_v) = filterCaseSensitivity(); break;
        case 4: *reinterpret_cast< Qt::CaseSensitivity*>(_v) = sortCaseSensitivity(); break;
        case 5: *reinterpret_cast< bool*>(_v) = isSortLocaleAware(); break;
        case 6: *reinterpret_cast< int*>(_v) = sortRole(); break;
        case 7: *reinterpret_cast< int*>(_v) = filterRole(); break;
        }
        _id -= 8;
    } else if (_c == QMetaObject::WriteProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: setFilterRegExp(*reinterpret_cast< QRegExp*>(_v)); break;
        case 1: setFilterKeyColumn(*reinterpret_cast< int*>(_v)); break;
        case 2: setDynamicSortFilter(*reinterpret_cast< bool*>(_v)); break;
        case 3: setFilterCaseSensitivity(*reinterpret_cast< Qt::CaseSensitivity*>(_v)); break;
        case 4: setSortCaseSensitivity(*reinterpret_cast< Qt::CaseSensitivity*>(_v)); break;
        case 5: setSortLocaleAware(*reinterpret_cast< bool*>(_v)); break;
        case 6: setSortRole(*reinterpret_cast< int*>(_v)); break;
        case 7: setFilterRole(*reinterpret_cast< int*>(_v)); break;
        }
        _id -= 8;
    } else if (_c == QMetaObject::ResetProperty) {
        _id -= 8;
    } else if (_c == QMetaObject::QueryPropertyDesignable) {
        _id -= 8;
    } else if (_c == QMetaObject::QueryPropertyScriptable) {
        _id -= 8;
    } else if (_c == QMetaObject::QueryPropertyStored) {
        _id -= 8;
    } else if (_c == QMetaObject::QueryPropertyEditable) {
        _id -= 8;
    } else if (_c == QMetaObject::QueryPropertyUser) {
        _id -= 8;
    }
#endif // QT_NO_PROPERTIES
    return _id;
}
void SortFilterProxyModel::setFilterString(const QString &filter)
{
    setFilterRegExp(QRegExp(filter, filterCaseSensitivity(), static_cast<QRegExp::PatternSyntax>(filterSyntax())));
}
void SortFilterProxyModel::setFilterSyntax(SortFilterProxyModel::FilterSyntax syntax)
{
    setFilterRegExp(QRegExp(filterString(), filterCaseSensitivity(), static_cast<QRegExp::PatternSyntax>(syntax)));
}
bool RelationFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex & source_parent) const
{
  if(mParentModelRow < 0){
    return false;
  }
  if(source_parent.isValid()){
    return false;
  }
  Q_ASSERT(!mParentModel.isNull());
  Q_ASSERT(sourceModel() != nullptr);
  Q_ASSERT(mParentModelRow >= 0);
  Q_ASSERT(mParentModelRow < mParentModel->rowCount());
//   if(mParentModel.isNull() || (sourceModel() == nullptr)){
//     return false;
//   }
//   if( (mParentModelRow < 0) || (mParentModelRow >= mParentModel->rowCount()) ){
//     return false;
//   }
  if(mFilterExpression.isNull()){
    return true;
  }
  /*
   * After a model reset, possibly due to changing source model,
   * filter expression possibly does not match until setFilter() is called again.
   * We don't want to constraint setup order, so do bound checking here.
   */
  if( sourceModel()->columnCount() < (mFilterExpression.greatestColumn()+1) ){
    return false;
  }
  return mFilterExpression.eval(sourceModel(), source_row, ParentModelEvalData(mParentModel, mParentModelRow), filterCaseSensitivity());
}