sqlqueryresultlist searchhandler::perform_grep(QString searchtxt, sqlqueryresultlist searchlist, bool exactmatch)
{
	QVector<QString> strvec;
	sqlqueryresultlist resultlist;
	QFutureWatcher<sqlqueryresultlist> futureWatcher;
	QProgressDialog dialog;
	unsigned int n = searchlist.resultlist.size();
	if (n == 0) return resultlist;
	strvec.resize(n);
	for (unsigned int i=0; i < n; i++)
	{
		strvec.replace(i, str2qt(searchlist.resultlist[i].filepath));
	}
	dialog.setAutoReset(false);
	dialog.setLabelText(QString("Grep ").append(QString(tr("in progress"))).append(QString(" ...")));
	dialog.setCancelButtonText(tr("Cancel"));
	QObject::connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset()));
	QObject::connect(&dialog, SIGNAL(canceled()), &futureWatcher, SLOT(cancel()));
	QObject::connect(&futureWatcher, SIGNAL(progressRangeChanged(int,int)), &dialog, SLOT(setRange(int,int)));
	QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int)));
	m_grepExactMatch = exactmatch;
	(*m_grepRegExp) = QRegExp(searchtxt.QT45_TOASCII().data(), Qt::CaseInsensitive);
	m_grepRegExp->setPatternSyntax(QRegExp::RegExp2);
	futureWatcher.setFuture(QtConcurrent::mappedReduced(strvec, doGrep,
				collateGrep, QtConcurrent::SequentialReduce));
	dialog.exec();
	futureWatcher.waitForFinished();
	if (futureWatcher.isCanceled() == false)
		resultlist = futureWatcher.result();
	return resultlist;
}
QString searchhandler::search_declaration_qt(QString searchtxt)
{
	QString str;
	sqlqueryresultlist reslst = sq->search_declaration(searchtxt.QT45_TOASCII().data());
	if (reslst.resultlist.size() > 0)
	str.append(reslst.resultlist[0].filename.c_str())
		.append(":")
		.append(reslst.resultlist[0].linenum.c_str())
		.append(" ==> ")
		.append(reslst.resultlist[0].linetext.c_str());
	return str;
}
void searchhandler::perform_search(QString searchtxt,
			bool exactmatch,
			sqlquery::en_queryType qrytyp,
			QString filtertxt,
			int selectitem,
			bool updSearchMemory)
{
	if (sq->isDBOpen() == false) return;
	if (searchtxt.isEmpty()) return;
	sqlqueryresultlist sqlresultlist;
	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
	if (m_autocompBusy)
	{
		m_autocompBusy = false;
		m_autocompFutureWatcher.waitForFinished();
	}
	if (m_declarBusy)
	{
		m_declarBusy = false;
		m_declarFutureWatcher.waitForFinished();
	}
	sqlquery::en_queryType querytype = qrytyp;
	if (querytype == sqlquery::sqlresultDEFAULT) querytype = 
		(sqlquery::en_queryType)m_comboBoxQueryType->itemData(m_comboBoxQueryType->currentIndex()).toInt();
	if ((filtertxt.isEmpty()) && (m_checkBoxFilter->isChecked()))
	{
		filtertxt = m_comboBoxFilter->lineEdit()->text().trimmed();
		if (updSearchMemory) updateFilterHistory(filtertxt);
	}
	if (querytype == sqlquery::sqlresultGREP)
	{
		if (filtertxt.isEmpty()) filtertxt = "*";
		sqlresultlist = sq->search(filtertxt.QT45_TOASCII().data(),
				sqlquery::sqlresultFILEPATH, false);
	}
	else
	{
		sqlresultlist = sq->search(searchtxt.QT45_TOASCII().data(),
				querytype, exactmatch,
				filtertxt.QT45_TOASCII().data());
	}
	QApplication::restoreOverrideCursor();
	if (sqlresultlist.result_type == sqlqueryresultlist::sqlresultERROR)
	{
		QMessageBox msgBox((QWidget*)mw);
		msgBox.setText(str2qt(sqlresultlist.sqlerrmsg));
		msgBox.exec();
	}
	else
	{
		m_pushButtonGraph->setEnabled((querytype == sqlquery::sqlresultFUNC_MACRO)||
			(querytype == sqlquery::sqlresultCLASS_STRUCT));
		updateSearchHistory(searchtxt);
		if (updSearchMemory) addToSearchMemory(searchtxt, filtertxt);
		if (querytype == sqlquery::sqlresultGREP)
		{
			sqlresultlist = perform_grep(searchtxt, sqlresultlist, exactmatch);
		}
		emit searchresults(sqlresultlist, selectitem);
		QString str;
		str = QString("%1").arg(sqlresultlist.resultlist.size());
		str += " ";
		str += tr("results found");
		emit updateStatus(str, 5000);
	}
}
QStringList searchhandler::search_autocomplete_qt(QString searchtxt)
{
	return strLst2qt(sq->search_autocomplete(searchtxt.QT45_TOASCII().data()));
}