#include "MultiQFileDialog.h" #include "CommonMessages.h" #include #include MultiQFileDialog::MultiQFileDialog(QWidget *parent, const QString &caption, const QString &directory, bool multiSelect, const QString &filter) : QFileDialog(parent, caption, directory, filter), mShowHidden(false), mMultiSelect(multiSelect), mEnableOkButton(false) { setOption(QFileDialog::DontUseNativeDialog, false); if (multiSelect) { setOption(QFileDialog::DontUseNativeDialog, true); setFileMode(QFileDialog::Directory); setMimeTypeFilters(QStringList(QLatin1String("application/octet-stream"))); mLe = findChild(QString::fromUtf8("fileNameEdit")); QListView *l = findChild(QString::fromUtf8("listView")); if (l) { l->setSelectionMode(QListView::ExtendedSelection); if(mLe) { connect(l->selectionModel(), &QItemSelectionModel::selectionChanged, this, &MultiQFileDialog::onSelectionChanged); } } QTreeView *t = findChild(); if (t) { t->setSelectionMode(QListView::ExtendedSelection); } QLabel *label = findChild(QString::fromUtf8("fileNameLabel")); if (label) { label->hide(); } label = findChild(QString::fromUtf8("fileTypeLabel")); if (label) { label->hide(); } label = findChild(QString::fromUtf8("lookInLabel")); if (label) { label->hide(); } QDialogButtonBox *buttonBox = findChild(QString::fromUtf8("buttonBox")); if (buttonBox) { mBOpen = buttonBox->button(QDialogButtonBox::Open); } if (mBOpen) { mBOpen->setText(QCoreApplication::translate("QDialogButtonBox", "&OK")); } if (mLe) { mLe->setText(QCoreApplication::translate("ShellExtension", "Upload to MEGA")); } } QList widgets = findChildren(); for (QList::const_iterator it = widgets.cbegin(); it != widgets.cend(); ++it) { (*it)->installEventFilter(this); } installEventFilter(this); } bool MultiQFileDialog::eventFilter(QObject *obj, QEvent *e) { if (e->type() == QEvent::KeyPress) { QKeyEvent* keyEvent = dynamic_cast(e); Qt::KeyboardModifiers modifiers = QApplication::queryKeyboardModifiers(); if (modifiers.testFlag(Qt::ControlModifier) && keyEvent && keyEvent->key() == Qt::Key_H) { if (mShowHidden) { if (mMultiSelect) { setFilter(QDir::AllDirs | QDir::AllEntries | QDir::NoDotAndDotDot); } else { setFilter(QDir::AllDirs | QDir::NoDotAndDotDot); } } else { if (mMultiSelect) { setFilter(QDir::AllDirs | QDir::AllEntries | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot); } else { setFilter(QDir::AllDirs | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot); } } mShowHidden = !mShowHidden; } } // Override the OK button enabled state to respect our own logic. // We return to prevent QFileDialog from overriding us. else if ((obj == mBOpen) && (e->type() == QEvent::EnabledChange)) { bool enabled (mBOpen->isEnabled()); bool pathExists (QFileInfo::exists(mLe->text())); if (!pathExists) { pathExists = true; const QStringList items (mLe->text().split(QString::fromUtf8("\""))); auto item (items.cbegin()); while (pathExists && item != items.cend()) { if (!item->trimmed().isEmpty()) { pathExists &= QFileInfo::exists(directory().absolutePath() + QDir::separator() + *item); } item++; } } if (enabled && !mEnableOkButton && !pathExists) { mBOpen->setEnabled(false); mEnableOkButton = false; return true; } else if (!enabled && pathExists) { mEnableOkButton = true; mBOpen->setEnabled(true); return true; } else { return false; } } return QFileDialog::eventFilter(obj, e); } void MultiQFileDialog::accept() { QStringList files = selectedFiles(); if (files.isEmpty()) { return; } emit filesSelected(files); QDialog::accept(); } void MultiQFileDialog::onSelectionChanged() { int numFiles = 0; int numFolders = 0; findSelectedFilesAndFoldersCount(numFiles, numFolders); if (mBOpen) { updateOpenButtonEnabledStatus(numFiles + numFolders); } setWindowTitle(createWindowTitle(numFiles, numFolders)); } void MultiQFileDialog::findSelectedFilesAndFoldersCount(int& fileCount, int& folderCount) { QString dir (directory().absolutePath()); // Do not select a file/folder whose name is the same as the parent // upon entering a directory. QStringList files = selectedFiles(); if(files.contains(dir)) { files.removeOne(dir); for (auto& file : qAsConst(files)) { selectFile(file); } return; } for (auto& file : qAsConst(files)) { if (file != dir) { QFileInfo fi(file); if (fi.exists()) { if (fi.isDir()) { ++folderCount; } else { ++fileCount; } } } } } void MultiQFileDialog::updateOpenButtonEnabledStatus(int selectedItemCount) { mEnableOkButton = (selectedItemCount > 0); if (selectedItemCount > 0) { int nbItemsInLineEdit = findItemCountInLineEdit(); mEnableOkButton = nbItemsInLineEdit == selectedItemCount; } mBOpen->setEnabled(mEnableOkButton); } int MultiQFileDialog::findItemCountInLineEdit() { int itemCount = 0; const QStringList items (mLe->text().split(QString::fromUtf8("\""))); for (auto item (items.cbegin()); item != items.cend(); item++) { if (!item->trimmed().isEmpty()) { itemCount++; } } return itemCount; } QString MultiQFileDialog::createWindowTitle(int fileCount, int folderCount) { QString actionString = QCoreApplication::translate("ShellExtension", "Upload to MEGA"); return CommonMessages::createShellExtensionActionLabel(actionString, fileCount, folderCount); }