19#include <QDragEnterEvent>
26#include <QtConcurrentRun>
28#include <boost/algorithm/string.hpp>
29#include <boost/regex.hpp>
41 :
MantidWidget(parent), m_findRunFiles(true), m_isForDirectory(false), m_allowMultipleFiles(false),
42 m_isOptional(false), m_multiEntry(false), m_buttonOpt(Text), m_fileProblem(
""), m_entryNumProblem(
""),
43 m_algorithmProperty(
""), m_fileExtensions(), m_extsAsSingleOption(true), m_liveButtonState(Hide),
44 m_showValidator(true), m_foundFiles(), m_lastFoundFiles(), m_lastDir(), m_fileFilter(), m_pool(), m_dialog(),
45 m_useNativeDialog(true) {
49 connect(
m_uiForm.fileEditor, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
fileTextChanged(
const QString &)));
55 connect(
m_uiForm.entryNum, SIGNAL(textChanged(
const QString &)),
this, SLOT(
checkEntry()));
73 setFocusPolicy(Qt::StrongFocus);
77 m_lastDir = QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString(
"defaultsave.directory"));
81 QStringList dataDirs =
82 QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString(
"datasearch.directories"))
83 .split(
";", Qt::SkipEmptyParts);
85 if (!dataDirs.isEmpty())
90 this->setAcceptDrops(
true);
91 m_uiForm.fileEditor->setAcceptDrops(
false);
133 m_uiForm.textLabel->setVisible(!text.isEmpty());
239 std::vector<std::string> extensions;
241 [](
const QString &extension) { return extension.toStdString(); });
339 const int period =
m_uiForm.entryNum->text().toInt(&isANumber);
383 m_uiForm.fileEditor->setModified(
true);
411 settings.beginGroup(
group);
413 settings.setValue(
"last_directory",
m_lastDir);
424 const QString total = number > 0 ? QString::number(number) :
"?";
426 m_uiForm.numEntries->setText(
"/" + total);
485 m_uiForm.fileEditor->setModified(
true);
505 auto searchText =
m_uiForm.fileEditor->text();
508 if (searchText.isEmpty()) {
522 m_uiForm.fileEditor->setModified(
false);
543 const std::string runNumberString =
"([0-9]+)([:+-] ?[0-9]+)? ?(:[0-9]+)?";
544 boost::regex runNumberExp(runNumberString, boost::regex::extended);
546 const std::string runListString =
"(" + runNumberString +
")(, ?(" + runNumberString +
"))*";
547 boost::regex runNumberListExp(runListString, boost::regex::extended);
550 if (boost::regex_match(searchText.toStdString(), runNumberExp)) {
554 else if (boost::regex_match(searchText.toStdString(), runNumberListExp)) {
555 QStringList runNumbers = searchText.split(
",", Qt::SkipEmptyParts);
556 QStringList newRunNumbers;
558 for (
const auto &runNumber : runNumbers)
561 searchText = newRunNumbers.join(
",");
590 return theAlgorithmBeingCancelled;
605 if (!results.
error.empty()) {
611 for (
const auto &filename : results.
filenames) {
615 setFileProblem(
"No files found. Check search paths and instrument selection.");
616 }
else if (
m_foundFiles.count() > 1 && this->allowMultipleFiles() ==
false) {
637 settings.beginGroup(
group);
638 m_lastDir = settings.value(
"last_directory",
"").toString();
641 QStringList datadirs =
642 QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString(
"datasearch.directories"))
643 .split(
";", Qt::SkipEmptyParts);
644 if (!datadirs.isEmpty())
656 QStringList fileExts;
661 std::vector<std::string> exts = ConfigService::Instance().getFacility().extensions();
662 for (
const auto &ext : exts) {
663 fileExts.append(QString::fromStdString(ext));
669 if (elements.size() == 2) {
674 QString allFiles(
"All Files (*)");
675 if (!fileExts.isEmpty()) {
681 QStringListIterator sitr(fileExts);
682 QString ext = sitr.next();
683 finalIndex.append(qMakePair(ext.toUpper(), QStringList(ext)));
684 while (sitr.hasNext()) {
686 QString key = ext.toUpper();
688 const int itemCount = finalIndex.count();
689 for (
int i = 0; i < itemCount; ++i) {
690 if (key == finalIndex[i].first) {
691 finalIndex[i].second.append(ext);
697 finalIndex.append(qMakePair(key, QStringList(ext)));
704 QString dataFiles(
"Data Files (");
705 QString individualFiles(
"");
708 QListIterator<QPair<QString, QStringList>> itr(finalIndex);
709 while (itr.hasNext()) {
710 const QStringList values = itr.next().second;
712 individualFiles +=
"*" + values.join(
" *") +
";;";
713 dataFiles +=
"*" + values.join(
" *") +
" ";
720 QListIterator<QPair<QString, QStringList>> itr(finalIndex);
721 while (itr.hasNext()) {
722 const QStringList values = itr.next().second;
723 dataFiles +=
"*" + values.join(
" *") +
";;";
726 return dataFiles + individualFiles + allFiles;
740 Mantid::API::AlgorithmManager::Instance().createUnmanaged(algName.toStdString());
741 QStringList fileExts;
744 algorithm->initialize();
745 Property *prop = algorithm->getProperty(propName.toStdString());
749 std::vector<std::string> allowed;
750 QString preferredExt;
754 preferredExt = QString::fromStdString(fileProp->
getDefaultExt());
755 }
else if (multiFileProp) {
756 allowed = multiFileProp->allowedValues();
757 preferredExt = QString::fromStdString(multiFileProp->getDefaultExt());
762 std::vector<std::string>::const_iterator iend = allowed.end();
764 for (std::vector<std::string>::const_iterator it = allowed.begin(); it != iend; ++it) {
766 QString ext = QString::fromStdString(*it);
767 fileExts.append(ext);
768 if (ext == preferredExt) {
769 fileExts.move(
index, 0);
783 QStringList filenames;
786 auto prevFileNames =
getText().split(
",", Qt::SkipEmptyParts);
787 for (
auto &prevFileName : prevFileNames)
788 prevFileName = prevFileName.trimmed();
790 if (!prevFileNames.empty() && QFileInfo(prevFileNames[0]).isAbsolute()) {
791 if (QFileInfo(prevFileNames[0]).isFile()) {
792 dir = QFileInfo(prevFileNames[0]).absoluteDir().path();
794 dir = prevFileNames[0];
806 m_dialog.setOption(QFileDialog::DontResolveSymlinks,
false);
807 m_dialog.setFileMode(QFileDialog::Directory);
810 m_dialog.setOption(QFileDialog::DontResolveSymlinks);
812 m_dialog.setFileMode(QFileDialog::ExistingFiles);
814 m_dialog.setFileMode(QFileDialog::ExistingFile);
818 filenames =
m_dialog.selectedFiles();
821 QString file = QFileDialog::getExistingDirectory(
this,
"Select directory", dir);
823 filenames.append(file);
825 filenames = QFileDialog::getOpenFileNames(
this,
"Open file", dir,
m_fileFilter,
nullptr,
826 QFileDialog::DontResolveSymlinks);
829 QFileDialog::getOpenFileName(
this,
"Open file", dir,
m_fileFilter,
nullptr, QFileDialog::DontResolveSymlinks);
831 filenames.append(file);
835 if (filenames.isEmpty()) {
838 m_lastDir = QFileInfo(filenames.front()).absoluteDir().path();
839 return filenames.join(
", ");
876 if (uFile.trimmed().isEmpty())
879 m_uiForm.fileEditor->setText(uFile);
880 m_uiForm.fileEditor->setModified(
true);
889 if (
m_uiForm.entryNum->text().isEmpty()) {
895 const int num =
m_uiForm.entryNum->text().toInt(&good);
913 const QMimeData *mimeData = de->mimeData();
915 if (!filenames.empty()) {
916 m_uiForm.fileEditor->setText(filenames[0]);
917 de->acceptProposedAction();
918 }
else if (mimeData->hasText()) {
919 QString text = mimeData->text();
921 de->acceptProposedAction();
930 const QMimeData *mimeData = de->mimeData();
931 if (mimeData->hasUrls()) {
932 auto listurl = mimeData->urls();
935 if (!listurl[0].isLocalFile())
937 de->acceptProposedAction();
938 }
else if (mimeData->hasText()) {
939 QString text = mimeData->text();
940 if (text.contains(
" = mtd[\""))
941 de->setDropAction(Qt::IgnoreAction);
943 de->acceptProposedAction();
954 m_uiForm.fileEditor->setReadOnly(readOnly);
955 m_uiForm.browseBtn->setEnabled(!readOnly);
977 if (elements.size() == 2) {
989 m_dialog.setOption(QFileDialog::DontUseNativeDialog);
990 m_dialog.setOption(QFileDialog::ReadOnly);
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
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.