mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Add search filter support for multiple game directories
This commit is contained in:
		
							parent
							
								
									09982c3386
								
							
						
					
					
						commit
						88ebd844e5
					
				
					 2 changed files with 76 additions and 44 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue