mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 12:32:52 +00:00
Merge pull request #7159 from bparker06/qt_filterarchives
Qt: add option to filter extensions inside archives when adding to a playlist
This commit is contained in:
commit
b86164cccb
@ -3728,6 +3728,12 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_CORE,
|
||||
"コア:")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_DATABASE,
|
||||
"データベース:")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_EXTENSIONS,
|
||||
"拡張子:")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_EXTENSIONS_PLACEHOLDER,
|
||||
"(スペースで区切る。 既定は全部の拡張子)")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_FILTER_INSIDE_ARCHIVES,
|
||||
"アーカイブの中に絞り込み")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_FOR_THUMBNAILS,
|
||||
"(サムネイルを見つかることに使う)")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST_ITEM,
|
||||
|
@ -7266,6 +7266,18 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_DATABASE,
|
||||
"Database:"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_EXTENSIONS,
|
||||
"Extensions:"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_EXTENSIONS_PLACEHOLDER,
|
||||
"(space-separated; includes all by default)"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_FILTER_INSIDE_ARCHIVES,
|
||||
"Filter inside archives"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_QT_FOR_THUMBNAILS,
|
||||
"(used to find thumbnails)"
|
||||
|
@ -1971,6 +1971,9 @@ enum msg_hash_enums
|
||||
MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_PATH,
|
||||
MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_CORE,
|
||||
MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_DATABASE,
|
||||
MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_EXTENSIONS,
|
||||
MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_EXTENSIONS_PLACEHOLDER,
|
||||
MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_FILTER_INSIDE_ARCHIVES,
|
||||
MENU_ENUM_LABEL_VALUE_QT_FOR_THUMBNAILS,
|
||||
MENU_ENUM_LABEL_VALUE_QT_CANNOT_ADD_TO_ALL_PLAYLISTS,
|
||||
MENU_ENUM_LABEL_VALUE_QT_DELETE,
|
||||
|
@ -91,6 +91,9 @@ void MainWindow::onFileDropWidgetContextMenuRequested(const QPoint &pos)
|
||||
QPoint cursorPos = QCursor::pos();
|
||||
QHash<QString, QString> contentHash = getCurrentContentHash();
|
||||
|
||||
if (m_browserAndPlaylistTabWidget->tabText(m_browserAndPlaylistTabWidget->currentIndex()) != msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_TAB_PLAYLISTS))
|
||||
return;
|
||||
|
||||
menu.reset(new QMenu(this));
|
||||
|
||||
downloadThumbnailAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_THUMBNAIL)), this));
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <QInputDialog>
|
||||
#include <QLayout>
|
||||
#include <QScreen>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include "../ui_qt.h"
|
||||
#include "flowlayout.h"
|
||||
@ -38,29 +39,86 @@ inline static bool comp_hash_label_key_lower(const QHash<QString, QString> &lhs,
|
||||
}
|
||||
|
||||
/* https://stackoverflow.com/questions/7246622/how-to-create-a-slider-with-a-non-linear-scale */
|
||||
static void addDirectoryFilesToList(QStringList &list, QDir &dir)
|
||||
bool MainWindow::addDirectoryFilesToList(QProgressDialog *dialog, QStringList &list, QDir &dir, QStringList &extensions)
|
||||
{
|
||||
PlaylistEntryDialog *playlistDialog = playlistEntryDialog();
|
||||
QStringList dirList = dir.entryList(QStringList(), QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System, QDir::Name);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dirList.count(); i++)
|
||||
{
|
||||
QString path(dir.path() + "/" + dirList.at(i));
|
||||
QByteArray pathArray = path.toUtf8();
|
||||
QFileInfo fileInfo(path);
|
||||
const char *pathData = pathArray.constData();
|
||||
|
||||
if (dialog->wasCanceled())
|
||||
return false;
|
||||
|
||||
if (i % 25 == 0)
|
||||
{
|
||||
/* Needed to update progress dialog while doing a lot of stuff on the main thread. */
|
||||
qApp->processEvents();
|
||||
}
|
||||
|
||||
if (fileInfo.isDir())
|
||||
{
|
||||
QDir fileInfoDir(path);
|
||||
bool success = addDirectoryFilesToList(dialog, list, fileInfoDir, extensions);
|
||||
|
||||
if (!success)
|
||||
return false;
|
||||
|
||||
addDirectoryFilesToList(list, fileInfoDir);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fileInfo.isFile())
|
||||
{
|
||||
bool add = false;
|
||||
|
||||
if (extensions.isEmpty())
|
||||
add = true;
|
||||
else
|
||||
{
|
||||
if (extensions.contains(fileInfo.suffix()))
|
||||
add = true;
|
||||
else
|
||||
{
|
||||
if (path_is_compressed_file(pathData))
|
||||
{
|
||||
struct string_list *list = file_archive_get_file_list(pathData, NULL);
|
||||
|
||||
if (list)
|
||||
{
|
||||
if (list->size == 1)
|
||||
{
|
||||
/* Assume archives with one file should have that file loaded directly.
|
||||
* Don't just extend this to add all files in a zip, because we might hit
|
||||
* something like MAME/FBA where only the archives themselves are valid content. */
|
||||
pathArray = (QString(pathData) + "#" + list->elems[0].data).toUtf8();
|
||||
pathData = pathArray.constData();
|
||||
|
||||
if (!extensions.isEmpty() && playlistDialog->filterInArchive())
|
||||
{
|
||||
/* If the user chose to filter extensions inside archives, and this particular file inside the archive
|
||||
* doesn't have one of the chosen extensions, then we skip it. */
|
||||
if (extensions.contains(QFileInfo(pathData).suffix()))
|
||||
add = true;
|
||||
}
|
||||
}
|
||||
|
||||
string_list_free(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (add)
|
||||
list.append(fileInfo.absoluteFilePath());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainWindow::onPlaylistFilesDropped(QStringList files)
|
||||
@ -82,6 +140,7 @@ void MainWindow::addFilesToPlaylist(QStringList files)
|
||||
QString selectedDatabase;
|
||||
QString selectedName;
|
||||
QString selectedPath;
|
||||
QStringList selectedExtensions;
|
||||
const char *currentPlaylistData = NULL;
|
||||
playlist_t *playlist = NULL;
|
||||
int i;
|
||||
@ -130,6 +189,10 @@ void MainWindow::addFilesToPlaylist(QStringList files)
|
||||
selectedPath = m_playlistEntryDialog->getSelectedPath();
|
||||
selectedCore = m_playlistEntryDialog->getSelectedCore();
|
||||
selectedDatabase = m_playlistEntryDialog->getSelectedDatabase();
|
||||
selectedExtensions = m_playlistEntryDialog->getSelectedExtensions();
|
||||
|
||||
if (!selectedExtensions.isEmpty())
|
||||
selectedExtensions.replaceInStrings(QRegularExpression("^\\."), "");
|
||||
|
||||
if (selectedDatabase.isEmpty())
|
||||
selectedDatabase = QFileInfo(currentPlaylistPath).fileName();
|
||||
@ -138,6 +201,9 @@ void MainWindow::addFilesToPlaylist(QStringList files)
|
||||
|
||||
dialog.reset(new QProgressDialog(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_GATHERING_LIST_OF_FILES), "Cancel", 0, 0, this));
|
||||
dialog->setWindowModality(Qt::ApplicationModal);
|
||||
dialog->show();
|
||||
|
||||
qApp->processEvents();
|
||||
|
||||
if (selectedName.isEmpty() || selectedPath.isEmpty() ||
|
||||
selectedDatabase.isEmpty())
|
||||
@ -166,12 +232,37 @@ void MainWindow::addFilesToPlaylist(QStringList files)
|
||||
if (fileInfo.isDir())
|
||||
{
|
||||
QDir dir(path);
|
||||
addDirectoryFilesToList(list, dir);
|
||||
bool success = addDirectoryFilesToList(dialog.data(), list, dir, selectedExtensions);
|
||||
|
||||
if (!success)
|
||||
return;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fileInfo.isFile())
|
||||
{
|
||||
bool add = false;
|
||||
|
||||
if (selectedExtensions.isEmpty())
|
||||
add = true;
|
||||
else
|
||||
{
|
||||
QByteArray pathArray = path.toUtf8();
|
||||
const char *pathData = pathArray.constData();
|
||||
|
||||
if (selectedExtensions.contains(fileInfo.suffix()))
|
||||
add = true;
|
||||
else if (playlistDialog->filterInArchive() && path_is_compressed_file(pathData))
|
||||
{
|
||||
/* We'll add it here but really just delay the check until later when the archive contents are iterated. */
|
||||
add = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (add)
|
||||
list.append(fileInfo.absoluteFilePath());
|
||||
}
|
||||
else if (files.count() == 1)
|
||||
{
|
||||
/* If adding a single file, tell user that it doesn't exist. */
|
||||
@ -202,6 +293,7 @@ void MainWindow::addFilesToPlaylist(QStringList files)
|
||||
|
||||
if (dialog->wasCanceled())
|
||||
{
|
||||
/* Cancel out of everything, the current progress will not be written to the playlist at all. */
|
||||
playlist_free(playlist);
|
||||
return;
|
||||
}
|
||||
@ -209,13 +301,19 @@ void MainWindow::addFilesToPlaylist(QStringList files)
|
||||
if (fileName.isEmpty())
|
||||
continue;
|
||||
|
||||
/* a modal QProgressDialog calls processEvents() automatically in setValue() */
|
||||
dialog->setValue(i + 1);
|
||||
|
||||
fileInfo = fileName;
|
||||
|
||||
if (files.count() == 1 && list.count() == 1 && i == 0)
|
||||
/* Make sure we're looking at a user-specified field and not just "<multiple>"
|
||||
* in case it was a folder with one file in it */
|
||||
if (files.count() == 1 && list.count() == 1 && i == 0 && playlistDialog->nameFieldEnabled())
|
||||
{
|
||||
fileBaseNameArray = selectedName.toUtf8();
|
||||
pathArray = QDir::toNativeSeparators(selectedPath).toUtf8();
|
||||
}
|
||||
/* Otherwise just use the file name itself (minus extension) for the playlist entry title */
|
||||
else
|
||||
{
|
||||
fileBaseNameArray = fileInfo.completeBaseName().toUtf8();
|
||||
@ -224,9 +322,6 @@ void MainWindow::addFilesToPlaylist(QStringList files)
|
||||
|
||||
fileNameNoExten = fileBaseNameArray.constData();
|
||||
|
||||
/* a modal QProgressDialog calls processEvents() automatically in setValue() */
|
||||
dialog->setValue(i + 1);
|
||||
|
||||
pathData = pathArray.constData();
|
||||
|
||||
if (selectedCore.isEmpty())
|
||||
@ -253,9 +348,22 @@ void MainWindow::addFilesToPlaylist(QStringList files)
|
||||
{
|
||||
if (list->size == 1)
|
||||
{
|
||||
/* assume archives with one file should have that file loaded directly */
|
||||
/* Assume archives with one file should have that file loaded directly.
|
||||
* Don't just extend this to add all files in a zip, because we might hit
|
||||
* something like MAME/FBA where only the archives themselves are valid content. */
|
||||
pathArray = QDir::toNativeSeparators(QString(pathData) + "#" + list->elems[0].data).toUtf8();
|
||||
pathData = pathArray.constData();
|
||||
|
||||
if (!selectedExtensions.isEmpty() && playlistDialog->filterInArchive())
|
||||
{
|
||||
/* If the user chose to filter extensions inside archives, and this particular file inside the archive
|
||||
* doesn't have one of the chosen extensions, then we skip it. */
|
||||
if (!selectedExtensions.contains(QFileInfo(pathData).suffix()))
|
||||
{
|
||||
string_list_free(list);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string_list_free(list);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <QSettings>
|
||||
#include <QLineEdit>
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QFormLayout>
|
||||
#include <QDialogButtonBox>
|
||||
@ -33,17 +34,20 @@ PlaylistEntryDialog::PlaylistEntryDialog(MainWindow *mainwindow, QWidget *parent
|
||||
,m_settings(mainwindow->settings())
|
||||
,m_nameLineEdit(new QLineEdit(this))
|
||||
,m_pathLineEdit(new QLineEdit(this))
|
||||
,m_extensionsLineEdit(new QLineEdit(this))
|
||||
,m_coreComboBox(new QComboBox(this))
|
||||
,m_databaseComboBox(new QComboBox(this))
|
||||
,m_extensionArchiveCheckBox(new QCheckBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_FILTER_INSIDE_ARCHIVES), this))
|
||||
{
|
||||
QFormLayout *form = new QFormLayout();
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
QVBoxLayout *databaseVBoxLayout = new QVBoxLayout();
|
||||
QHBoxLayout *pathHBoxLayout = new QHBoxLayout();
|
||||
QHBoxLayout *extensionHBoxLayout = new QHBoxLayout();
|
||||
QLabel *databaseLabel = new QLabel(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FOR_THUMBNAILS), this);
|
||||
QToolButton *pathPushButton = new QToolButton(this);
|
||||
|
||||
pathPushButton->setText("...");
|
||||
pathPushButton->setText(QStringLiteral("..."));
|
||||
|
||||
pathHBoxLayout->addWidget(m_pathLineEdit);
|
||||
pathHBoxLayout->addWidget(pathPushButton);
|
||||
@ -51,6 +55,14 @@ PlaylistEntryDialog::PlaylistEntryDialog(MainWindow *mainwindow, QWidget *parent
|
||||
databaseVBoxLayout->addWidget(m_databaseComboBox);
|
||||
databaseVBoxLayout->addWidget(databaseLabel);
|
||||
|
||||
extensionHBoxLayout->addWidget(m_extensionsLineEdit);
|
||||
extensionHBoxLayout->addWidget(m_extensionArchiveCheckBox);
|
||||
|
||||
m_extensionsLineEdit->setPlaceholderText(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_EXTENSIONS_PLACEHOLDER));
|
||||
|
||||
/* Ensure placeholder text is completely visible. */
|
||||
m_extensionsLineEdit->setMinimumWidth(QFontMetrics(m_extensionsLineEdit->font()).boundingRect(m_extensionsLineEdit->placeholderText()).width() + m_extensionsLineEdit->frameSize().width());
|
||||
|
||||
setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY));
|
||||
|
||||
form->setFormAlignment(Qt::AlignCenter);
|
||||
@ -68,6 +80,7 @@ PlaylistEntryDialog::PlaylistEntryDialog(MainWindow *mainwindow, QWidget *parent
|
||||
form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_PATH), pathHBoxLayout);
|
||||
form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_CORE), m_coreComboBox);
|
||||
form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_DATABASE), databaseVBoxLayout);
|
||||
form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLAYLIST_ENTRY_EXTENSIONS), extensionHBoxLayout);
|
||||
|
||||
qobject_cast<QVBoxLayout*>(layout())->addLayout(form);
|
||||
layout()->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding));
|
||||
@ -76,6 +89,11 @@ PlaylistEntryDialog::PlaylistEntryDialog(MainWindow *mainwindow, QWidget *parent
|
||||
connect(pathPushButton, SIGNAL(clicked()), this, SLOT(onPathClicked()));
|
||||
}
|
||||
|
||||
bool PlaylistEntryDialog::filterInArchive()
|
||||
{
|
||||
return m_extensionArchiveCheckBox->isChecked();
|
||||
}
|
||||
|
||||
void PlaylistEntryDialog::onPathClicked()
|
||||
{
|
||||
QString filePath = QFileDialog::getOpenFileName(this);
|
||||
@ -164,6 +182,11 @@ void PlaylistEntryDialog::loadPlaylistOptions()
|
||||
}
|
||||
}
|
||||
|
||||
bool PlaylistEntryDialog::nameFieldEnabled()
|
||||
{
|
||||
return m_nameLineEdit->isEnabled();
|
||||
}
|
||||
|
||||
void PlaylistEntryDialog::setEntryValues(const QHash<QString, QString> &contentHash)
|
||||
{
|
||||
QString db;
|
||||
@ -233,6 +256,18 @@ const QString PlaylistEntryDialog::getSelectedDatabase()
|
||||
return m_databaseComboBox->currentData(Qt::UserRole).toString();
|
||||
}
|
||||
|
||||
const QStringList PlaylistEntryDialog::getSelectedExtensions()
|
||||
{
|
||||
QStringList list;
|
||||
QString text = m_extensionsLineEdit->text();
|
||||
|
||||
/* Otherwise it would create a QStringList with a single blank entry... */
|
||||
if (!text.isEmpty())
|
||||
list = text.split(' ');
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void PlaylistEntryDialog::onAccepted()
|
||||
{
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
class QSettings;
|
||||
class QLineEdit;
|
||||
class QComboBox;
|
||||
class QCheckBox;
|
||||
class MainWindow;
|
||||
|
||||
class PlaylistEntryDialog : public QDialog
|
||||
@ -17,6 +18,9 @@ public:
|
||||
const QString getSelectedDatabase();
|
||||
const QString getSelectedName();
|
||||
const QString getSelectedPath();
|
||||
const QStringList getSelectedExtensions();
|
||||
bool filterInArchive();
|
||||
bool nameFieldEnabled();
|
||||
void setEntryValues(const QHash<QString, QString> &contentHash);
|
||||
public slots:
|
||||
bool showDialog(const QHash<QString, QString> &hash = QHash<QString, QString>());
|
||||
@ -32,8 +36,10 @@ private:
|
||||
QSettings *m_settings;
|
||||
QLineEdit *m_nameLineEdit;
|
||||
QLineEdit *m_pathLineEdit;
|
||||
QLineEdit *m_extensionsLineEdit;
|
||||
QComboBox *m_coreComboBox;
|
||||
QComboBox *m_databaseComboBox;
|
||||
QCheckBox *m_extensionArchiveCheckBox;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -429,6 +429,7 @@ private:
|
||||
bool updateCurrentPlaylistEntry(const QHash<QString, QString> &contentHash);
|
||||
int extractArchive(QString path);
|
||||
void removeUpdateTempFiles();
|
||||
bool addDirectoryFilesToList(QProgressDialog *dialog, QStringList &list, QDir &dir, QStringList &extensions);
|
||||
QVector<QHash<QString, QString> > getPlaylistItems(QString pathString);
|
||||
|
||||
LoadCoreWindow *m_loadCoreWindow;
|
||||
|
Loading…
x
Reference in New Issue
Block a user