20#include <QDragEnterEvent>
27#include <QtConcurrentRun>
29#include <boost/algorithm/string.hpp>
30#include <boost/regex.hpp>
42 :
MantidWidget(parent), m_findRunFiles(true), m_isForDirectory(false), m_allowMultipleFiles(false),
43 m_isOptional(false), m_multiEntry(false), m_buttonOpt(Text), m_fileProblem(
""), m_entryNumProblem(
""),
44 m_algorithmProperty(
""), m_fileExtensions(), m_extsAsSingleOption(true), m_liveButtonState(Hide),
45 m_showValidator(true), m_foundFiles(), m_lastFoundFiles(), m_lastDir(), m_fileFilter(), m_pool(), m_dialog(),
46 m_useNativeDialog(true) {
50 connect(
m_uiForm.fileEditor, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
fileTextChanged(
const QString &)));
56 connect(
m_uiForm.entryNum, SIGNAL(textChanged(
const QString &)),
this, SLOT(
checkEntry()));
74 setFocusPolicy(Qt::StrongFocus);
78 m_lastDir = QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString(
"defaultsave.directory"));
82 QStringList dataDirs =
83 QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString(
"datasearch.directories"))
84 .split(
";", Qt::SkipEmptyParts);
86 if (!dataDirs.isEmpty())
91 this->setAcceptDrops(
true);
92 m_uiForm.fileEditor->setAcceptDrops(
false);
134 m_uiForm.textLabel->setVisible(!text.isEmpty());
240 std::vector<std::string> extensions;
242 [](
const QString &extension) { return extension.toStdString(); });
340 const int period =
m_uiForm.entryNum->text().toInt(&isANumber);
384 m_uiForm.fileEditor->setModified(
true);
416 const QString total = number > 0 ? QString::number(number) :
"?";
418 m_uiForm.numEntries->setText(
"/" + total);
477 m_uiForm.fileEditor->setModified(
true);
497 auto searchText =
m_uiForm.fileEditor->text();
500 if (searchText.isEmpty()) {
514 m_uiForm.fileEditor->setModified(
false);
535 const std::string runNumberString =
"([0-9]+)([:+-] ?[0-9]+)? ?(:[0-9]+)?";
536 boost::regex runNumberExp(runNumberString, boost::regex::extended);
538 const std::string runListString =
"(" + runNumberString +
")(, ?(" + runNumberString +
"))*";
539 boost::regex runNumberListExp(runListString, boost::regex::extended);
542 if (boost::regex_match(searchText.toStdString(), runNumberExp)) {
546 else if (boost::regex_match(searchText.toStdString(), runNumberListExp)) {
547 QStringList runNumbers = searchText.split(
",", Qt::SkipEmptyParts);
548 QStringList newRunNumbers;
550 for (
const auto &runNumber : runNumbers)
553 searchText = newRunNumbers.join(
",");
582 return theAlgorithmBeingCancelled;
597 if (!results.
error.empty()) {
603 for (
const auto &filename : results.
filenames) {
607 setFileProblem(
"No files found. Check search paths and instrument selection.");
608 }
else if (
m_foundFiles.count() > 1 && this->allowMultipleFiles() ==
false) {
624 auto lastDirectory = settings.value(
"last_directory",
"").toString();
626 if (lastDirectory.isEmpty()) {
627 QStringList datadirs =
628 QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString(
"datasearch.directories"))
629 .split(
";", Qt::SkipEmptyParts);
630 if (!datadirs.isEmpty())
631 lastDirectory = datadirs[0];
646 QStringList fileExts;
651 std::vector<std::string> exts = ConfigService::Instance().getFacility().extensions();
652 for (
const auto &ext : exts) {
653 fileExts.append(QString::fromStdString(ext));
659 if (elements.size() == 2) {
664 QString allFiles(
"All Files (*)");
665 if (!fileExts.isEmpty()) {
671 QStringListIterator sitr(fileExts);
672 QString ext = sitr.next();
673 finalIndex.append(std::make_pair(ext.toUpper(), QStringList(ext)));
674 while (sitr.hasNext()) {
676 QString key = ext.toUpper();
677 const auto it = std::find_if(finalIndex.begin(), finalIndex.end(),
678 [&key](
const std::pair<QString, QStringList> &pair) { return pair.first == key; });
679 if (it != finalIndex.end()) {
680 it->second.append(ext);
682 finalIndex.append(std::make_pair(key, QStringList(ext)));
689 QString dataFiles(
"Data Files (");
690 QString individualFiles(
"");
693 QListIterator<std::pair<QString, QStringList>> itr(finalIndex);
694 while (itr.hasNext()) {
695 const QStringList values = itr.next().second;
697 individualFiles +=
"*" + values.join(
" *") +
";;";
698 dataFiles +=
"*" + values.join(
" *") +
" ";
705 QListIterator<std::pair<QString, QStringList>> itr(finalIndex);
706 while (itr.hasNext()) {
707 const QStringList values = itr.next().second;
708 dataFiles +=
"*" + values.join(
" *") +
";;";
711 return dataFiles + individualFiles + allFiles;
725 Mantid::API::AlgorithmManager::Instance().createUnmanaged(algName.toStdString());
726 QStringList fileExts;
729 algorithm->initialize();
730 Property *prop = algorithm->getProperty(propName.toStdString());
734 std::vector<std::string> allowed;
735 QString preferredExt;
739 preferredExt = QString::fromStdString(fileProp->
getDefaultExt());
740 }
else if (multiFileProp) {
741 allowed = multiFileProp->allowedValues();
742 preferredExt = QString::fromStdString(multiFileProp->getDefaultExt());
747 std::vector<std::string>::const_iterator
iend = allowed.end();
749 for (std::vector<std::string>::const_iterator it = allowed.begin(); it !=
iend; ++it) {
751 QString ext = QString::fromStdString(*it);
752 fileExts.append(ext);
753 if (ext == preferredExt) {
754 fileExts.move(
index, 0);
768 QStringList filenames;
771 auto prevFileNames =
getText().split(
",", Qt::SkipEmptyParts);
772 for (
auto &prevFileName : prevFileNames)
773 prevFileName = prevFileName.trimmed();
775 if (!prevFileNames.empty() && QFileInfo(prevFileNames[0]).isAbsolute()) {
776 if (QFileInfo(prevFileNames[0]).isFile()) {
777 dir = QFileInfo(prevFileNames[0]).absoluteDir().path();
779 dir = prevFileNames[0];
791 m_dialog.setOption(QFileDialog::DontResolveSymlinks,
false);
792 m_dialog.setFileMode(QFileDialog::Directory);
795 m_dialog.setOption(QFileDialog::DontResolveSymlinks);
797 m_dialog.setFileMode(QFileDialog::ExistingFiles);
799 m_dialog.setFileMode(QFileDialog::ExistingFile);
803 filenames =
m_dialog.selectedFiles();
806 QString file = QFileDialog::getExistingDirectory(
this,
"Select directory", dir);
808 filenames.append(file);
810 filenames = QFileDialog::getOpenFileNames(
this,
"Open file", dir,
m_fileFilter,
nullptr,
811 QFileDialog::DontResolveSymlinks);
814 QFileDialog::getOpenFileName(
this,
"Open file", dir,
m_fileFilter,
nullptr, QFileDialog::DontResolveSymlinks);
816 filenames.append(file);
820 if (filenames.isEmpty()) {
823 m_lastDir = QFileInfo(filenames.front()).absoluteDir().path();
824 return filenames.join(
", ");
861 if (uFile.trimmed().isEmpty())
864 m_uiForm.fileEditor->setText(uFile);
865 m_uiForm.fileEditor->setModified(
true);
874 if (
m_uiForm.entryNum->text().isEmpty()) {
880 const int num =
m_uiForm.entryNum->text().toInt(&good);
898 const QMimeData *mimeData = de->mimeData();
900 if (!filenames.empty()) {
901 m_uiForm.fileEditor->setText(filenames[0]);
902 de->acceptProposedAction();
903 }
else if (mimeData->hasText()) {
904 QString text = mimeData->text();
906 de->acceptProposedAction();
915 const QMimeData *mimeData = de->mimeData();
916 if (mimeData->hasUrls()) {
917 auto listurl = mimeData->urls();
920 if (!listurl[0].isLocalFile())
922 de->acceptProposedAction();
923 }
else if (mimeData->hasText()) {
924 QString text = mimeData->text();
925 if (text.contains(
" = mtd[\""))
926 de->setDropAction(Qt::IgnoreAction);
928 de->acceptProposedAction();
939 m_uiForm.fileEditor->setReadOnly(readOnly);
940 m_uiForm.browseBtn->setEnabled(!readOnly);
962 if (elements.size() == 2) {
974 m_dialog.setOption(QFileDialog::DontUseNativeDialog);
975 m_dialog.setOption(QFileDialog::ReadOnly);
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
Immutable snapshot of the persistent state used by FileFinderWidget.
const QString & lastDirectory() const
void createWorker(const QObject *parent, const FindFilesSearchParameters ¶meters)
Create a new worker thread. This will cancel any currently running threads.
bool isSearchRunning() const
Check if a search is already in progress.
A specialized class for dealing with file properties.
const std::string & getDefaultExt() const
Returns the main file extension that's used.
A property to allow a user to specify multiple files to load.
std::vector< std::string > allowedValues() const override
Returns the set of valid values for this property, if such a set exists.
Base class for properties.
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm
std::shared_ptr< const IAlgorithm > IAlgorithm_const_sptr
shared pointer to Mantid::API::IAlgorithm (const version)
POD struct to hold details about the parameters of a file search.
bool isForRunFiles
Whether the search is for experimental run data.
std::string algorithmName
The name of the algorithm to load files with.
std::vector< std::string > extensions
any additional extensions that we want to consider
bool isOptional
Whether the search is optional (i.e. a failed search means no error).
std::string algorithmProperty
The name of the property on the algorithm to use for searching.
std::string searchText
The text to use as a hint to search for files.
POD struct to hold details about the results of a file search.
std::vector< std::string > filenames
A list of filenames that matched the search hint.
std::string valueForProperty
The value to set the algorithm property to.
std::string error
A string repsresenting the error message. Empty if the search succeded.