Add custom browsing for executable files that checks permissions

This commit is contained in:
baldurk
2016-11-21 16:46:19 +01:00
parent b2464e1c64
commit a85eb017a3
3 changed files with 87 additions and 2 deletions
+66
View File
@@ -23,6 +23,7 @@
******************************************************************************/
#include "QRDUtils.h"
#include <QFileSystemModel>
#include <QGuiApplication>
#include <QJsonDocument>
#include <QMenu>
@@ -339,6 +340,7 @@ QString RDDialog::getOpenFileName(QWidget *parent, const QString &caption, const
QFileDialog::Options options)
{
QFileDialog fd(parent, caption, dir, filter);
fd.setFileMode(QFileDialog::ExistingFile);
fd.setAcceptMode(QFileDialog::AcceptOpen);
fd.setOptions(options);
show(&fd);
@@ -356,6 +358,35 @@ QString RDDialog::getOpenFileName(QWidget *parent, const QString &caption, const
return QString();
}
QString RDDialog::getExecutableFileName(QWidget *parent, const QString &caption, const QString &dir,
QFileDialog::Options options)
{
QString filter;
#if defined(Q_OS_WIN32)
// can't filter by executable bit on windows, but we have extensions
filter = "Executables (*.exe);;All Files (*.*)";
#endif
QFileDialog fd(parent, caption, dir, filter);
fd.setOptions(options);
fd.setAcceptMode(QFileDialog::AcceptOpen);
fd.setFileMode(QFileDialog::ExistingFile);
QFileFilterModel *proxy = new QFileFilterModel(parent);
proxy->setRequirePermissions(QDir::Executable);
fd.setProxyModel(proxy);
show(&fd);
if(fd.result() == QFileDialog::Accepted)
{
QStringList files = fd.selectedFiles();
if(!files.isEmpty())
return files[0];
}
return QString();
}
QString RDDialog::getSaveFileName(QWidget *parent, const QString &caption, const QString &dir,
const QString &filter, QString *selectedFilter,
QFileDialog::Options options)
@@ -377,3 +408,38 @@ QString RDDialog::getSaveFileName(QWidget *parent, const QString &caption, const
return QString();
}
bool QFileFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
QModelIndex idx = sourceModel()->index(source_row, 0, source_parent);
QFileSystemModel *fs = qobject_cast<QFileSystemModel *>(sourceModel());
if(!fs)
{
qCritical() << "Expected a QFileSystemModel as the source model!";
return true;
}
if(fs->isDir(idx))
return true;
QFile::Permissions permissions =
(QFile::Permissions)sourceModel()->data(idx, QFileSystemModel::FilePermissions).toInt();
if((m_requireMask & QDir::Readable) && !(permissions & QFile::ReadUser))
return false;
if((m_requireMask & QDir::Writable) && !(permissions & QFile::WriteUser))
return false;
if((m_requireMask & QDir::Executable) && !(permissions & QFile::ExeUser))
return false;
if((m_excludeMask & QDir::Readable) && (permissions & QFile::ReadUser))
return false;
if((m_excludeMask & QDir::Writable) && (permissions & QFile::WriteUser))
return false;
if((m_excludeMask & QDir::Executable) && (permissions & QFile::ExeUser))
return false;
return true;
}
+20
View File
@@ -28,6 +28,7 @@
#include <QFileDialog>
#include <QMessageBox>
#include <QSemaphore>
#include <QSortFilterProxyModel>
#include "renderdoc_replay.h"
// total hack, expose the same basic interface as on renderdoc side.
@@ -248,6 +249,21 @@ public:
}
};
class QFileFilterModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
explicit QFileFilterModel(QObject *parent = Q_NULLPTR) : QSortFilterProxyModel(parent) {}
void setRequirePermissions(QDir::Filters mask) { m_requireMask = mask; }
void setExcludePermissions(QDir::Filters mask) { m_excludeMask = mask; }
protected:
virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
private:
QDir::Filters m_requireMask, m_excludeMask;
};
class QMenu;
// helper for doing a manual blocking invoke of a dialog
@@ -304,6 +320,10 @@ struct RDDialog
QString *selectedFilter = NULL,
QFileDialog::Options options = QFileDialog::Options());
static QString getExecutableFileName(QWidget *parent = NULL, const QString &caption = QString(),
const QString &dir = QString(),
QFileDialog::Options options = QFileDialog::Options());
static QString getSaveFileName(QWidget *parent = NULL, const QString &caption = QString(),
const QString &dir = QString(), const QString &filter = QString(),
QString *selectedFilter = NULL,
+1 -2
View File
@@ -283,8 +283,7 @@ void CaptureDialog::on_exePathBrowse_clicked()
// if(m_Core.Renderer.Remote == null)
{
QString filename = RDDialog::getOpenFileName(this, tr("Choose executable"), initDir,
"Executable files (*.exe);;All files (*.*)");
QString filename = RDDialog::getExecutableFileName(this, tr("Choose executable"), initDir);
if(filename != "")
setExecutableFilename(filename);