Add search filter support for multiple game directories
This commit is contained in:
parent
09982c3386
commit
88ebd844e5
@ -43,7 +43,6 @@ bool GameList::SearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* e
|
|||||||
return QObject::eventFilter(obj, event);
|
return QObject::eventFilter(obj, event);
|
||||||
|
|
||||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||||
int rowCount = gamelist->tree_view->model()->rowCount();
|
|
||||||
QString edit_filter_text = gamelist->search_field->edit_filter->text().toLower();
|
QString edit_filter_text = gamelist->search_field->edit_filter->text().toLower();
|
||||||
|
|
||||||
// If the searchfield's text hasn't changed special function keys get checked
|
// If the searchfield's text hasn't changed special function keys get checked
|
||||||
@ -65,19 +64,8 @@ bool GameList::SearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* e
|
|||||||
// If there is only one result launch this game
|
// If there is only one result launch this game
|
||||||
case Qt::Key_Return:
|
case Qt::Key_Return:
|
||||||
case Qt::Key_Enter: {
|
case Qt::Key_Enter: {
|
||||||
QStandardItemModel* item_model = new QStandardItemModel(gamelist->tree_view);
|
if (gamelist->search_field->visible == 1) {
|
||||||
QModelIndex root_index = item_model->invisibleRootItem()->index();
|
QString file_path = gamelist->getLastFilterResultItem();
|
||||||
QStandardItem* child_file;
|
|
||||||
QString file_path;
|
|
||||||
int resultCount = 0;
|
|
||||||
for (int i = 0; i < rowCount; ++i) {
|
|
||||||
if (!gamelist->tree_view->isRowHidden(i, root_index)) {
|
|
||||||
++resultCount;
|
|
||||||
child_file = gamelist->item_model->item(i, 0);
|
|
||||||
file_path = child_file->data(GameListItemPath::FullPathRole).toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (resultCount == 1) {
|
|
||||||
// To avoid loading error dialog loops while confirming them using enter
|
// To avoid loading error dialog loops while confirming them using enter
|
||||||
// Also users usually want to run a diffrent game after closing one
|
// Also users usually want to run a diffrent game after closing one
|
||||||
gamelist->search_field->edit_filter->setText("");
|
gamelist->search_field->edit_filter->setText("");
|
||||||
@ -97,6 +85,9 @@ bool GameList::SearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* e
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GameList::SearchField::setFilterResult(int visible, int total) {
|
void GameList::SearchField::setFilterResult(int visible, int total) {
|
||||||
|
this->visible = visible;
|
||||||
|
this->total = total;
|
||||||
|
|
||||||
QString result_of_text = tr("of");
|
QString result_of_text = tr("of");
|
||||||
QString result_text;
|
QString result_text;
|
||||||
if (total == 1) {
|
if (total == 1) {
|
||||||
@ -108,6 +99,25 @@ void GameList::SearchField::setFilterResult(int visible, int total) {
|
|||||||
QString("%1 %2 %3 %4").arg(visible).arg(result_of_text).arg(total).arg(result_text));
|
QString("%1 %2 %3 %4").arg(visible).arg(result_of_text).arg(total).arg(result_text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString GameList::getLastFilterResultItem() {
|
||||||
|
QStandardItem* folder;
|
||||||
|
QStandardItem* child;
|
||||||
|
QString file_path;
|
||||||
|
int folderCount = item_model->rowCount();
|
||||||
|
for (int i = 0; i < folderCount; ++i) {
|
||||||
|
folder = item_model->item(i, 0);
|
||||||
|
QModelIndex folder_index = folder->index();
|
||||||
|
int childrenCount = folder->rowCount();
|
||||||
|
for (int j = 0; j < childrenCount; ++j) {
|
||||||
|
if (!tree_view->isRowHidden(j, folder_index)) {
|
||||||
|
child = folder->child(j, 0);
|
||||||
|
file_path = child->data(GameListItemPath::FullPathRole).toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return file_path;
|
||||||
|
}
|
||||||
|
|
||||||
void GameList::SearchField::clear() {
|
void GameList::SearchField::clear() {
|
||||||
edit_filter->setText("");
|
edit_filter->setText("");
|
||||||
}
|
}
|
||||||
@ -163,43 +173,55 @@ bool GameList::containsAllWords(QString haystack, QString userinput) {
|
|||||||
|
|
||||||
// Event in order to filter the gamelist after editing the searchfield
|
// Event in order to filter the gamelist after editing the searchfield
|
||||||
void GameList::onTextChanged(const QString& newText) {
|
void GameList::onTextChanged(const QString& newText) {
|
||||||
int rowCount = tree_view->model()->rowCount();
|
int folderCount = tree_view->model()->rowCount();
|
||||||
QString edit_filter_text = newText.toLower();
|
QString edit_filter_text = newText.toLower();
|
||||||
|
QStandardItem* folder;
|
||||||
|
QStandardItem* child;
|
||||||
|
int childrenTotal = 0;
|
||||||
QModelIndex root_index = item_model->invisibleRootItem()->index();
|
QModelIndex root_index = item_model->invisibleRootItem()->index();
|
||||||
|
|
||||||
// If the searchfield is empty every item is visible
|
// If the searchfield is empty every item is visible
|
||||||
// Otherwise the filter gets applied
|
// Otherwise the filter gets applied
|
||||||
if (edit_filter_text.isEmpty()) {
|
if (edit_filter_text.isEmpty()) {
|
||||||
for (int i = 0; i < rowCount; ++i) {
|
for (int i = 0; i < folderCount; ++i) {
|
||||||
tree_view->setRowHidden(i, root_index, false);
|
folder = item_model->item(i, 0);
|
||||||
|
QModelIndex folder_index = folder->index();
|
||||||
|
int childrenCount = folder->rowCount();
|
||||||
|
for (int j = 0; j < childrenCount; ++j) {
|
||||||
|
++childrenTotal;
|
||||||
|
tree_view->setRowHidden(j, folder_index, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
search_field->setFilterResult(rowCount, rowCount);
|
search_field->setFilterResult(childrenTotal, childrenTotal);
|
||||||
} else {
|
} else {
|
||||||
QStandardItem* child_file;
|
|
||||||
QString file_path, file_name, file_title, file_programmid;
|
QString file_path, file_name, file_title, file_programmid;
|
||||||
int result_count = 0;
|
int result_count = 0;
|
||||||
for (int i = 0; i < rowCount; ++i) {
|
for (int i = 0; i < folderCount; ++i) {
|
||||||
child_file = item_model->item(i, 0);
|
folder = item_model->item(i, 0);
|
||||||
file_path = child_file->data(GameListItemPath::FullPathRole).toString().toLower();
|
QModelIndex folder_index = folder->index();
|
||||||
file_name = file_path.mid(file_path.lastIndexOf("/") + 1);
|
int childrenCount = folder->rowCount();
|
||||||
file_title = child_file->data(GameListItemPath::TitleRole).toString().toLower();
|
for (int j = 0; j < childrenCount; ++j) {
|
||||||
file_programmid =
|
++childrenTotal;
|
||||||
child_file->data(GameListItemPath::ProgramIdRole).toString().toLower();
|
child = folder->child(j, 0);
|
||||||
|
file_path = child->data(GameListItemPath::FullPathRole).toString().toLower();
|
||||||
|
file_name = file_path.mid(file_path.lastIndexOf("/") + 1);
|
||||||
|
file_title = child->data(GameListItemPath::TitleRole).toString().toLower();
|
||||||
|
file_programmid = child->data(GameListItemPath::ProgramIdRole).toString().toLower();
|
||||||
|
|
||||||
// Only items which filename in combination with its title contains all words
|
// Only items which filename in combination with its title contains all words
|
||||||
// that are in the searchfield will be visible in the gamelist
|
// that are in the searchfield will be visible in the gamelist
|
||||||
// The search is case insensitive because of toLower()
|
// The search is case insensitive because of toLower()
|
||||||
// I decided not to use Qt::CaseInsensitive in containsAllWords to prevent
|
// I decided not to use Qt::CaseInsensitive in containsAllWords to prevent
|
||||||
// multiple conversions of edit_filter_text for each game in the gamelist
|
// multiple conversions of edit_filter_text for each game in the gamelist
|
||||||
if (containsAllWords(file_name.append(" ").append(file_title), edit_filter_text) ||
|
if (containsAllWords(file_name.append(" ").append(file_title), edit_filter_text) ||
|
||||||
(file_programmid.count() == 16 && edit_filter_text.contains(file_programmid))) {
|
(file_programmid.count() == 16 && edit_filter_text.contains(file_programmid))) {
|
||||||
tree_view->setRowHidden(i, root_index, false);
|
tree_view->setRowHidden(j, folder_index, false);
|
||||||
++result_count;
|
++result_count;
|
||||||
} else {
|
} else {
|
||||||
tree_view->setRowHidden(i, root_index, true);
|
tree_view->setRowHidden(j, folder_index, true);
|
||||||
|
}
|
||||||
|
search_field->setFilterResult(result_count, childrenTotal);
|
||||||
}
|
}
|
||||||
search_field->setFilterResult(result_count, rowCount);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -305,9 +327,16 @@ void GameList::DonePopulating(QStringList watch_list) {
|
|||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
}
|
}
|
||||||
tree_view->setEnabled(true);
|
tree_view->setEnabled(true);
|
||||||
int rowCount = tree_view->model()->rowCount();
|
int folderCount = tree_view->model()->rowCount();
|
||||||
search_field->setFilterResult(rowCount, rowCount);
|
int childrenTotal = 0;
|
||||||
if (rowCount > 0) {
|
for (int i = 0; i < folderCount; ++i) {
|
||||||
|
int childrenCount = item_model->item(i, 0)->rowCount();
|
||||||
|
for (int j = 0; j < childrenCount; ++j) {
|
||||||
|
++childrenTotal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
search_field->setFilterResult(childrenTotal, childrenTotal);
|
||||||
|
if (childrenTotal > 0) {
|
||||||
search_field->setFocus();
|
search_field->setFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -410,6 +439,7 @@ void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) {
|
|||||||
tree_view->setEnabled(false);
|
tree_view->setEnabled(false);
|
||||||
// Delete any rows that might already exist if we're repopulating
|
// Delete any rows that might already exist if we're repopulating
|
||||||
item_model->removeRows(0, item_model->rowCount());
|
item_model->removeRows(0, item_model->rowCount());
|
||||||
|
search_field->clear();
|
||||||
|
|
||||||
emit ShouldCancelWorker();
|
emit ShouldCancelWorker();
|
||||||
|
|
||||||
@ -453,8 +483,7 @@ static bool HasSupportedFileExtension(const std::string& file_name) {
|
|||||||
void GameList::RefreshGameDirectory() {
|
void GameList::RefreshGameDirectory() {
|
||||||
if (!UISettings::values.gamedir.isEmpty() && current_worker != nullptr) {
|
if (!UISettings::values.gamedir.isEmpty() && current_worker != nullptr) {
|
||||||
NGLOG_INFO(Frontend, "Change detected in the games directory. Reloading game list.");
|
NGLOG_INFO(Frontend, "Change detected in the games directory. Reloading game list.");
|
||||||
search_field->clear();
|
PopulateAsync(UISettings::values.gamedirs);
|
||||||
PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,8 @@ public:
|
|||||||
|
|
||||||
class SearchField : public QWidget {
|
class SearchField : public QWidget {
|
||||||
public:
|
public:
|
||||||
|
int visible;
|
||||||
|
int total;
|
||||||
void setFilterResult(int visible, int total);
|
void setFilterResult(int visible, int total);
|
||||||
void clear();
|
void clear();
|
||||||
void setFocus();
|
void setFocus();
|
||||||
@ -67,6 +69,7 @@ public:
|
|||||||
explicit GameList(GMainWindow* parent = nullptr);
|
explicit GameList(GMainWindow* parent = nullptr);
|
||||||
~GameList() override;
|
~GameList() override;
|
||||||
|
|
||||||
|
QString getLastFilterResultItem();
|
||||||
void clearFilter();
|
void clearFilter();
|
||||||
void setFilterFocus();
|
void setFilterFocus();
|
||||||
void setFilterVisible(bool visibility);
|
void setFilterVisible(bool visibility);
|
||||||
|
Loading…
Reference in New Issue
Block a user