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);
83 QStringList dataDirs =
85 .split(
";", Qt::SkipEmptyParts);
87 if (!dataDirs.isEmpty())
92 this->setAcceptDrops(
true);
93 m_uiForm.fileEditor->setAcceptDrops(
false);
135 m_uiForm.textLabel->setVisible(!text.isEmpty());
241 std::vector<std::string> extensions;
243 [](
const QString &extension) { return extension.toStdString(); });
341 const int period =
m_uiForm.entryNum->text().toInt(&isANumber);
385 m_uiForm.fileEditor->setModified(
true);
413 settings.beginGroup(group);
415 settings.setValue(
"last_directory",
m_lastDir);
426 const QString total = number > 0 ? QString::number(number) :
"?";
427 {
m_uiForm.numEntries->setText(
"/" + total); }
485 m_uiForm.fileEditor->setModified(
true);
505 auto searchText =
m_uiForm.fileEditor->text();
508 if (searchText.isEmpty()) {
519 m_uiForm.fileEditor->setModified(
false);
540 const std::string runNumberString =
"([0-9]+)([:+-] ?[0-9]+)? ?(:[0-9]+)?";
541 boost::regex runNumberExp(runNumberString, boost::regex::extended);
543 const std::string runListString =
"(" + runNumberString +
")(, ?(" + runNumberString +
"))*";
544 boost::regex runNumberListExp(runListString, boost::regex::extended);
547 if (boost::regex_match(searchText.toStdString(), runNumberExp)) {
551 else if (boost::regex_match(searchText.toStdString(), runNumberListExp)) {
552 QStringList runNumbers = searchText.split(
",", Qt::SkipEmptyParts);
553 QStringList newRunNumbers;
555 for (
auto &runNumber : runNumbers)
558 searchText = newRunNumbers.join(
",");
587 return theAlgorithmBeingCancelled;
602 if (!results.
error.empty()) {
608 for (
const auto &filename : results.
filenames) {
612 setFileProblem(
"No files found. Check search paths and instrument selection.");
613 }
else if (
m_foundFiles.count() > 1 && this->allowMultipleFiles() ==
false) {
634 settings.beginGroup(group);
635 m_lastDir = settings.value(
"last_directory",
"").toString();
638 QStringList datadirs =
640 .split(
";", Qt::SkipEmptyParts);
641 if (!datadirs.isEmpty())
653 QStringList fileExts;
659 for (
auto &ext : exts) {
660 fileExts.append(QString::fromStdString(ext));
666 if (elements.size() == 2) {
671 QString allFiles(
"All Files (*)");
672 if (!fileExts.isEmpty()) {
678 QStringListIterator sitr(fileExts);
679 QString ext = sitr.next();
680 finalIndex.append(qMakePair(ext.toUpper(), QStringList(ext)));
681 while (sitr.hasNext()) {
683 QString key = ext.toUpper();
685 const int itemCount = finalIndex.count();
686 for (
int i = 0; i < itemCount; ++i) {
687 if (key == finalIndex[i].first) {
688 finalIndex[i].second.append(ext);
694 finalIndex.append(qMakePair(key, QStringList(ext)));
701 QString dataFiles(
"Data Files (");
702 QString individualFiles(
"");
705 QListIterator<QPair<QString, QStringList>> itr(finalIndex);
706 while (itr.hasNext()) {
707 const QStringList values = itr.next().second;
709 individualFiles +=
"*" + values.join(
" *") +
";;";
710 dataFiles +=
"*" + values.join(
" *") +
" ";
717 QListIterator<QPair<QString, QStringList>> itr(finalIndex);
718 while (itr.hasNext()) {
719 const QStringList values = itr.next().second;
720 dataFiles +=
"*" + values.join(
" *") +
";;";
723 return dataFiles + individualFiles + allFiles;
738 QStringList fileExts;
741 algorithm->initialize();
742 Property *prop = algorithm->getProperty(propName.toStdString());
746 std::vector<std::string> allowed;
747 QString preferredExt;
751 preferredExt = QString::fromStdString(fileProp->
getDefaultExt());
752 }
else if (multiFileProp) {
753 allowed = multiFileProp->allowedValues();
754 preferredExt = QString::fromStdString(multiFileProp->getDefaultExt());
759 std::vector<std::string>::const_iterator iend = allowed.end();
761 for (std::vector<std::string>::const_iterator it = allowed.begin(); it != iend; ++it) {
763 QString ext = QString::fromStdString(*it);
764 fileExts.append(ext);
765 if (ext == preferredExt) {
766 fileExts.move(
index, 0);
780 QStringList filenames;
783 auto prevFileNames =
getText().split(
",", Qt::SkipEmptyParts);
784 for (
auto &prevFileName : prevFileNames)
785 prevFileName = prevFileName.trimmed();
787 if (!prevFileNames.empty() && QFileInfo(prevFileNames[0]).isAbsolute()) {
788 if (QFileInfo(prevFileNames[0]).isFile()) {
789 dir = QFileInfo(prevFileNames[0]).absoluteDir().path();
791 dir = prevFileNames[0];
803 m_dialog.setOption(QFileDialog::DontResolveSymlinks,
false);
804 m_dialog.setFileMode(QFileDialog::Directory);
807 m_dialog.setOption(QFileDialog::DontResolveSymlinks);
809 m_dialog.setFileMode(QFileDialog::ExistingFiles);
811 m_dialog.setFileMode(QFileDialog::ExistingFile);
815 filenames =
m_dialog.selectedFiles();
818 QString file = QFileDialog::getExistingDirectory(
this,
"Select directory", dir);
820 filenames.append(file);
822 filenames = QFileDialog::getOpenFileNames(
this,
"Open file", dir,
m_fileFilter,
nullptr,
823 QFileDialog::DontResolveSymlinks);
826 QFileDialog::getOpenFileName(
this,
"Open file", dir,
m_fileFilter,
nullptr, QFileDialog::DontResolveSymlinks);
828 filenames.append(file);
832 if (filenames.isEmpty()) {
835 m_lastDir = QFileInfo(filenames.front()).absoluteDir().path();
836 return filenames.join(
", ");
873 if (uFile.trimmed().isEmpty())
876 m_uiForm.fileEditor->setText(uFile);
877 m_uiForm.fileEditor->setModified(
true);
886 if (
m_uiForm.entryNum->text().isEmpty()) {
892 const int num =
m_uiForm.entryNum->text().toInt(&good);
910 const QMimeData *mimeData = de->mimeData();
912 if (!filenames.empty()) {
913 m_uiForm.fileEditor->setText(filenames[0]);
914 de->acceptProposedAction();
915 }
else if (mimeData->hasText()) {
916 QString text = mimeData->text();
918 de->acceptProposedAction();
927 const QMimeData *mimeData = de->mimeData();
928 if (mimeData->hasUrls()) {
929 auto listurl = mimeData->urls();
932 if (!listurl[0].isLocalFile())
934 de->acceptProposedAction();
935 }
else if (mimeData->hasText()) {
936 QString text = mimeData->text();
937 if (text.contains(
" = mtd[\""))
938 de->setDropAction(Qt::IgnoreAction);
940 de->acceptProposedAction();
951 m_uiForm.fileEditor->setReadOnly(readOnly);
952 m_uiForm.browseBtn->setEnabled(!readOnly);
974 if (elements.size() == 2) {
986 m_dialog.setOption(QFileDialog::DontUseNativeDialog);
987 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.
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.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
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.