QFileDialog: block access to folders or drives on Windows
-
Hi guys,
Is there a proper way to block access to folders and/or drives ?
There is a signal, that is emitted when changing a directory, but this seems to work only if you doubleclick a folder, so i can check if the returned directory path is valid or not. But how to disable access via the address bar or the "Open" button?Thanks for help
-
@the_
Hello,
Aren't the flags working for you, namely QFileDialog::FileMode and QFileDialog::Option?Kind regards.
-
I am not sure if that will work for me, FileMode only sets the selection mode, as I need to select single files it is set to QFileDialog::ExistingFile. As i correctly understand the QFileDialog::Option there is no way to deny access to some path
Maybe I should add some more description to my problem:
The app i wrote is a reporting tool for special forms. Users are able to add attachments to each report but should not be able to access every drive, for example, if you have C: (the OS drive itself), D: (a flash drive, usb stick, whatever) and X: (a network drive), any access to C: should be denied (by doubleclicking this drive in "Computer", by entering C:<any path><anyfile> in the address bar and by selecting the drive and click the Open button in the dialog)
-
@the_
I see, what about setting a proxy model to the dialog and filtering up the restricted locations there? I think it should work in your case. -
@kshegunov
Well I had some "funny" things here about ProxyModels....I found an example on stackoverflow, which i tried to implement:
class FileFilterProxyModel : public QSortFilterProxyModel { protected: virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; }; bool FileFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent); QFileSystemModel* fileModel = qobject_cast<QFileSystemModel*>(sourceModel()); if (fileModel!=NULL && fileModel->isDir(index0)) { if(fileModel->filePath(index0).startsWith("/home/")) { qDebug() << fileModel->filePath(index0); // qDebug() << fileModel->fileName(index0); return true; } else return false; } else return false; // uncomment to execute default implementation //return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); } //... filed = new QFileDialog(this); FileFilterProxyModel *ffpm = new FileFilterProxyModel; filed->setProxyModel(ffpm); qDebug() << filed->proxyModel();
QFileDialog *filed; is defined in the header file;
When I run this on my linux box it returns
QSortFilterProxyModel(0x7c3a10) QSortFilterProxyModel(0x7c3a10)
but when I run the same code (ok not exactly the same, I changed the "/home/" to "C:" :) ) it returns
QSortFilterProxyModel(0x7c3a10) QObject(0x0)
The only difference is that Win8.1 has Qt5.4.2 and my Arch has Qt5.5.1...
Is there something wrong?
-
@the_
Hello,
If there were, I can't spot it directly. There's one thing I don't understand though, where are those addresses printed and what they're supposed to mean.When I run this on my linux box it returns
QSortFilterProxyModel(0x7c3a10) QSortFilterProxyModel(0x7c3a10)
but when I run the same code (ok not exactly the same, I changed the "/home/" to "C:" :) ) it returns
QSortFilterProxyModel(0x7c3a10) QObject(0x0)This I don't get. What do you mean by "it returns" and what's the relation to: "QSortFilterProxyModel(0x7c3a10)"?
Kind regards.
-
@the_
Not about precision, I just don't understand the meaning of it.
Is this:qDebug() << filed->proxyModel();
printing those?
Additionally, where does this piece of code:
filed = new QFileDialog(this); FileFilterProxyModel *ffpm = new FileFilterProxyModel; filed->setProxyModel(ffpm); qDebug() << filed->proxyModel();
reside?
-
The thing is, that I did not get the expected result on windows, so i checked if the proxymodel is applied correctly, which seems to be not.
The code is inside the constructor of the class that builds the ui where i want to use the QFileDialog.
mainwindow.cpp
//includes class FileFilterProxyModel : public QSortFilterProxyModel { //class goes here }; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { //... filed = new QFileDialog(this); FileFilterProxyModel *ffpm = new FileFilterProxyModel; filed->setProxyModel(ffpm); qDebug() << filed->proxyModel(); //... }
Thats for short the structure.
The part I do not understand is why on linux proxyModel() returns the one I set and on windows it returns a NULL Object. -
@the_
Hello,The thing is, that I did not get the expected result on windows, so i checked if the proxymodel is applied correctly, which seems to be not.
It should, but you may have stumbled upon a bug, however before jumping the gun let's suppose there's a subtle problem with the code (still) and try to fix that. About your
qDebug()
statement, the thing that baffled me is that you output a single address with this:qDebug() << filed->proxyModel();
but you get two objects output:
QSortFilterProxyModel(0x7c3a10) QSortFilterProxyModel(0x7c3a10)
Am I misunderstanding?
Your constructor looks okay, as far as I can tell, but you should (at least I believe you should) also disable the nativeness of the dialog, provided you haven't done already, like this:
filed->setOptions(QFileDialog::DontUseNativeDialog);
Let me know how that turns out.
Kind regards.