Mantid
Loading...
Searching...
No Matches
CatalogSearch.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
16
17#include <Poco/ActiveResult.h>
18#include <Poco/Path.h>
19
20#include <QDesktopWidget>
21#include <QFileDialog>
22#include <QSettings>
23#include <QStyle>
24#include <QUrl>
25
26#include <fstream>
27
28namespace MantidQt {
29namespace MantidWidgets {
30
35 : QWidget(parent), m_icatHelper(new CatalogHelper()), m_catalogSelector(new CatalogSelector()),
36 m_currentPageNumber(1) {
37 initLayout();
38 // Load saved settings from store.
40}
41
50 // Draw the GUI from .ui header generated file.
51 m_icatUiForm.setupUi(this);
52
53 // What facilities is the user logged in to?
54 m_icatUiForm.facilityName->setText(QString::fromStdString(
55 "Currently logged into " + Mantid::Kernel::ConfigService::Instance().getFacility().name()));
56
57 // Only want to show labels when an error occurs.
59
60 // Hide advanced input fields until "Advanced search" is checked.
62
63 // Show the search frame by default.
64 m_icatUiForm.searchCbox->setChecked(true);
66
67 // Prevents a user seeing empty tables.
68 m_icatUiForm.searchResultsCbox->setEnabled(false);
69 m_icatUiForm.dataFileCbox->setEnabled(false);
70 m_icatUiForm.resFrame->hide();
71 m_icatUiForm.dataFileFrame->hide();
72
73 // Disable download and load buttons until a user has selected a datafile.
74 m_icatUiForm.dataFileDownloadBtn->setEnabled(false);
75 m_icatUiForm.dataFileLoadBtn->setEnabled(false);
76
77 // We create the calendar here to allow only one instance of it to occur.
78 m_calendar = new QCalendarWidget(qobject_cast<QWidget *>(this->parent()));
79
80 // When the user has selected a date from the calendar we want to set the
81 // related date input field.
82 connect(m_calendar, SIGNAL(clicked(QDate)), this, SLOT(dateSelected(QDate)));
83 // Show related help page when a user clicks on the "Help" button.
84 connect(m_icatUiForm.helpBtn, SIGNAL(clicked()), this, SLOT(helpClicked()));
85 // Show "Search" frame when user clicks "Catalog search" check box.
86 connect(m_icatUiForm.searchCbox, SIGNAL(clicked()), this, SLOT(showCatalogSearch()));
87 // Show advanced search options if "Advanced search" is checked.
88 connect(m_icatUiForm.advSearchCbox, SIGNAL(clicked()), this, SLOT(advancedSearchChecked()));
89 // Open calendar when start or end date is selected
90 connect(m_icatUiForm.startDatePicker, SIGNAL(clicked()), this, SLOT(openCalendar()));
91 connect(m_icatUiForm.endDatePicker, SIGNAL(clicked()), this, SLOT(openCalendar()));
92 // Clear all fields when reset button is pressed.
93 connect(m_icatUiForm.resetBtn, SIGNAL(clicked()), this, SLOT(onReset()));
94 // Show "Search results" frame when user tries to "Search".
95 connect(m_icatUiForm.searchBtn, SIGNAL(clicked()), this, SLOT(searchClicked()));
96 // Show "Search results" frame when user clicks related check box.
97 connect(m_icatUiForm.searchResultsCbox, SIGNAL(clicked()), this, SLOT(showSearchResults()));
98 // When the user has double clicked on an investigation they wish to view
99 // datafiles for then load the relevant datafiles.
100 connect(m_icatUiForm.searchResultsTbl, SIGNAL(itemDoubleClicked(QTableWidgetItem *)), this,
101 SLOT(investigationSelected(QTableWidgetItem *)));
102 // Show "DataFile frame" when the user selects an investigation.
103 connect(m_icatUiForm.dataFileCbox, SIGNAL(clicked()), this, SLOT(showDataFileInfo()));
104 // When the user has selected a filter type then perform the filter for the
105 // specified type.
106 connect(m_icatUiForm.dataFileFilterCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(doFilter(int)));
107 // When the user clicks "download to..." then open a dialog and download the
108 // file(s) to that location.
109 connect(m_icatUiForm.dataFileDownloadBtn, SIGNAL(clicked()), this, SLOT(downloadDataFiles()));
110 // When the user clicks the "load" button then load their selected datafiles
111 // into a workspace.
112 connect(m_icatUiForm.dataFileLoadBtn, SIGNAL(clicked()), this, SLOT(loadDataFiles()));
113 // When a checkbox is selected in a row we want to select (highlight) the
114 // entire row.
115 connect(m_icatUiForm.dataFileResultsTbl, SIGNAL(itemClicked(QTableWidgetItem *)), this,
116 SLOT(dataFileCheckboxSelected(QTableWidgetItem *)));
117 // When several rows are selected we want to check the related checkboxes.
118 connect(m_icatUiForm.dataFileResultsTbl, SIGNAL(itemSelectionChanged()), this, SLOT(dataFileRowSelected()));
119 // When the user clicks "< Prev" populate the results table with the previous
120 // 100 results.
121 connect(m_icatUiForm.resPrevious, SIGNAL(clicked()), this, SLOT(prevPageClicked()));
122 // When the user clicks "Next >" populate the results table with the next 100
123 // results.
124 connect(m_icatUiForm.resNext, SIGNAL(clicked()), this, SLOT(nextPageClicked()));
125 // When the user is done editing & presses enter we retrieve the results for
126 // that specific page in paging.
127 connect(m_icatUiForm.pageStartNum, SIGNAL(editingFinished()), SLOT(goToInputPage()));
128 // Open the catalog/facility selection widget when 'Select a catalog' is
129 // clicked.
130 connect(m_icatUiForm.catalogSelection, SIGNAL(clicked()), SLOT(openFacilitySelection()));
131
132 // No need for error handling as that's dealt with in the algorithm being
133 // used.
135 // Although this is an advanced option performing it here allows it to be
136 // performed once only.
138
139 // As the methods have been created, and elements are in GUI I have opted to
140 // hide
141 // these elements for testing purposes as multiple facilities or paging has
142 // not yet been implemented.
143 // They will be implemented in separate tickets in the next release.
144 m_icatUiForm.facilityLogin->hide();
145
146 // Limit input to: A number, 1 hyphen or colon followed by another number.
147 // E.g. 444-444, -444, 444-
148 QRegExp re("[0-9]*(-|:){1}[0-9]*");
149 m_icatUiForm.RunRange->setValidator(new QRegExpValidator(re, this));
150 // Limit the page number input field to only digits.
151 m_icatUiForm.pageStartNum->setValidator(new QIntValidator(0, 999, this));
152
153 // Resize to minimum width/height to improve UX.
154 this->resize(minimumSizeHint());
155 // Centre the GUI on screen.
156 this->setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, this->window()->size(),
157 QDesktopWidget().availableGeometry()));
158}
159
164
170 MantidDesktopServices::openUrl(QUrl("http://www.mantidproject.org/Catalog_Search"));
171}
172
177 if (m_icatUiForm.searchCbox->isChecked()) {
178 m_icatUiForm.searchFrame->show();
179 } else {
180 m_icatUiForm.searchFrame->hide();
181 }
182}
183
189 if (m_icatUiForm.searchResultsCbox->isChecked()) {
190 m_icatUiForm.resFrame->show();
191 } else {
192 m_icatUiForm.resFrame->hide();
193 }
194}
195
200 if (m_icatUiForm.dataFileCbox->isChecked()) {
201 m_icatUiForm.dataFileFrame->show();
202 } else {
203 m_icatUiForm.dataFileFrame->hide();
204 }
205}
206
210void CatalogSearch::emboldenTableHeaders(QTableWidget *table) {
211 QFont font;
212 font.setBold(true);
213 for (int i = 0; i < table->columnCount(); ++i) {
214 table->horizontalHeaderItem(i)->setFont(font);
215 }
216}
217
224void CatalogSearch::setupTable(QTableWidget *table, const size_t &numOfRows, const size_t &numOfColumns) {
225 table->setRowCount(static_cast<int>(numOfRows));
226 table->setColumnCount(static_cast<int>(numOfColumns));
227
228 // Improve the appearance of table to make it easier to read.
229 table->setAlternatingRowColors(true);
230 table->setStyleSheet("alternate-background-color: rgb(216, 225, 255)");
231 table->setSortingEnabled(false);
232 table->verticalHeader()->setVisible(false);
233
234 // Set the height on each row to 20 for UX improvement.
235 for (size_t i = 0; i < numOfRows; ++i) {
236 table->setRowHeight(static_cast<int>(i), 20);
237 }
238}
239
246 // NOTE: This method freezes up the ICAT search GUI. We will need to do this
247 // adding in another thread.
248
249 // This will contain the list of column names.
250 QStringList columnHeaders;
251 columnHeaders.reserve(static_cast<int>(workspace->columnCount()));
252
253 // Add the data from the workspace to the search results table.
254 for (size_t col = 0; col < workspace->columnCount(); col++) {
255 // Get the column name to display as the header of table widget
256 Mantid::API::Column_sptr column = workspace->getColumn(col);
257 columnHeaders.push_back(QString::fromStdString(column->name()));
258
259 for (size_t row = 0; row < workspace->rowCount(); ++row) {
260 // Prints the value from the row to the ostringstream to use later.
261 std::ostringstream ostr;
262 column->print(row, ostr);
263
264 // Add a result to the table.
265 QTableWidgetItem *newItem = new QTableWidgetItem(QString::fromStdString(ostr.str()));
266 table->setItem(static_cast<int>(row), static_cast<int>(col), newItem);
267
268 // Allow the row to be selected, and enabled.
269 newItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
270 newItem->setToolTip(QString::fromStdString(ostr.str()));
271 }
272 }
273 // Set the table widgets header labels from the table workspace.
274 table->setHorizontalHeaderLabels(columnHeaders);
275 // Make the headers of the table bold.
277}
278
284void CatalogSearch::clearSearch(QTableWidget *table, const std::string &workspace) {
285 // Remove workspace if it exists.
286 if (Mantid::API::AnalysisDataService::Instance().doesExist(workspace)) {
287 Mantid::API::AnalysisDataService::Instance().remove(workspace);
288 }
289
290 // In order to reset fields for the table
291 setupTable(table, 0, 0);
292}
293
298 m_icatUiForm.searchCbox->setChecked(false);
299 m_icatUiForm.searchFrame->hide();
300}
301
306 m_icatUiForm.searchResultsLbl->setText("0 investigations found.");
307 m_icatUiForm.searchResultsCbox->setEnabled(false);
308 m_icatUiForm.searchResultsCbox->setChecked(false);
309 m_icatUiForm.searchResultsTbl->clear();
310 m_icatUiForm.resFrame->hide();
311}
312
317 m_icatUiForm.dataFileCbox->setEnabled(false);
318 m_icatUiForm.dataFileCbox->setChecked(false);
319 m_icatUiForm.dataFileLbl->clear();
320 m_icatUiForm.dataFileFrame->hide();
321}
322
329int CatalogSearch::headerIndexByName(QTableWidget *table, const std::string &searchFor) {
330 QAbstractItemModel *model = table->model();
331
332 // For every column in the table
333 for (int col = 0; col < table->columnCount(); col++) {
334 // Is the column name the same as the searchFor string?
335 if (searchFor.compare(model->headerData(col, Qt::Horizontal, Qt::DisplayRole).toString().toStdString()) == 0) {
336 // Yes? Return the index of the column.
337 return (col);
338 }
339 }
340 // This indicates that the column was not found.
341 return (-1);
342}
343
348 QSettings settings;
349 settings.beginGroup("/ICatSettings");
350 settings.setValue("lastDownloadPath", m_downloadSaveDir);
351 settings.endGroup();
352}
353
358 QSettings settings;
359 settings.beginGroup("/ICatSettings");
360
361 QString lastdir = settings.value("lastDownloadPath").toString();
362
363 // The user has not previously selected a directory to save ICAT downloads to.
364 if (lastdir.isEmpty()) {
365 lastdir = QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString("defaultsave.directory"));
366 }
367 // Initalise the member variable to the last saved directory.
368 m_downloadSaveDir = lastdir;
369 settings.endGroup();
370}
371
375
381 // Obtain the list of instruments to display in the drop-box.
382 std::vector<std::string> instrumentList =
384
385 // This option allows the user to select no instruments (thus searching over
386 // them all).
387 m_icatUiForm.Instrument->insertItem(-1, "");
388 m_icatUiForm.Instrument->setCurrentIndex(0);
389
390 QString userInstrument = QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getInstrument().name());
391
392 for (unsigned i = 0; i < instrumentList.size(); i++) {
393 QString instrument = QString::fromStdString(instrumentList.at(i));
394 m_icatUiForm.Instrument->addItem(instrument);
395
396 if (userInstrument.compare(instrument) == 0) {
397 m_icatUiForm.Instrument->setCurrentIndex(i + 1);
398 }
399 }
400}
401
406 // Obtain the list of investigation types to display in the list-box.
407 std::vector<std::string> invesTypeList =
409
410 std::vector<std::string>::const_iterator citr;
411 for (citr = invesTypeList.begin(); citr != invesTypeList.end(); ++citr) {
412 // Add each instrument to the instrument box.
413 m_icatUiForm.InvestigationType->addItem(QString::fromStdString(*citr));
414 }
415
416 // Sort the list-box by investigation type.
417 m_icatUiForm.InvestigationType->model()->sort(0);
418 // Make the default investigation type empty so the user has to select one.
419 m_icatUiForm.InvestigationType->insertItem(-1, "");
420 m_icatUiForm.InvestigationType->setCurrentIndex(0);
421}
422
428const std::map<std::string, std::string> CatalogSearch::getSearchFields() {
429 std::map<std::string, std::string> searchFieldInput;
430
431 // Left side of form.
432 searchFieldInput.emplace("InvestigationName", m_icatUiForm.InvestigationName->text().toStdString());
433 searchFieldInput.emplace("Instrument", m_icatUiForm.Instrument->currentText().toStdString());
434 if (m_icatUiForm.RunRange->text().size() > 2) {
435 searchFieldInput.emplace("RunRange", m_icatUiForm.RunRange->text().toStdString());
436 }
437 searchFieldInput.emplace("InvestigatorSurname", m_icatUiForm.InvestigatorSurname->text().toStdString());
438 searchFieldInput.emplace("DataFileName", m_icatUiForm.DataFileName->text().toStdString());
439 searchFieldInput.emplace("InvestigationId", m_icatUiForm.InvestigationId->text().toStdString());
440
441 // Right side of form.
442 if (m_icatUiForm.StartDate->text().size() > 2) {
443 searchFieldInput.emplace("StartDate", m_icatUiForm.StartDate->text().toStdString());
444 }
445 if (m_icatUiForm.EndDate->text().size() > 2) {
446 searchFieldInput.emplace("EndDate", m_icatUiForm.EndDate->text().toStdString());
447 }
448 searchFieldInput.emplace("Keywords", m_icatUiForm.Keywords->text().toStdString());
449 searchFieldInput.emplace("SampleName", m_icatUiForm.SampleName->text().toStdString());
450 searchFieldInput.emplace("InvestigationType", m_icatUiForm.InvestigationType->currentText().toStdString());
451
452 // Since we check if the field is empty in the algorithm, there's no need to
453 // check if advanced was clicked.
454 // If the "My data only" field is checked. We return the state of the checkbox
455 // (1 is true, 0 is false).
456 searchFieldInput.emplace("MyData", boost::lexical_cast<std::string>(m_icatUiForm.myDataCbox->isChecked()));
457
458 return (searchFieldInput);
459}
460
464
469 // Set min/max dates to prevent user selecting unusual dates.
470 m_calendar->setMinimumDate(QDate(1950, 1, 1));
471 m_calendar->setMaximumDate(QDate(2050, 1, 1));
472
473 // Centre the calendar on screen.
474 m_calendar->setGeometry(
475 QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, QSize(445, 205), QDesktopWidget().availableGeometry()));
476
477 // Improve UX, then display the m_calendar.
478 m_calendar->setGridVisible(true);
479 m_calendar->setWindowTitle("Calendar picker");
480 m_calendar->show();
481
482 // Set the name of the date button the user pressed to open the calendar with.
483 m_dateButtonName = sender()->objectName();
484}
485
491 // As openCalendar slot is used for both start and end date we need to perform
492 // a check
493 // to see which button was pressed, and then updated the related input field.
494 if (m_dateButtonName.compare("startDatePicker") == 0) {
495 m_icatUiForm.StartDate->setText(date.toString("dd/MM/yyyy"));
496 } else {
497 m_icatUiForm.EndDate->setText(date.toString("dd/MM/yyyy"));
498 }
499 m_calendar->close();
500}
501
507 std::string startDateInput = m_icatUiForm.StartDate->text().toStdString();
508 std::string endDateInput = m_icatUiForm.EndDate->text().toStdString();
509
510 // Return false if the user has not input any dates. This prevents any null
511 // errors occurring.
512 if (startDateInput.size() <= 2 || endDateInput.size() <= 2)
513 return false;
514
515 bool ret = m_icatHelper->getTimevalue(startDateInput) > m_icatHelper->getTimevalue(endDateInput);
516 // If startDate > endDate we want to throw an error and inform the user (red
517 // star(*)).
518 if (ret) {
519 correctedToolTip("Start date cannot be greater than end date.", m_icatUiForm.StartDate_err);
520 m_icatUiForm.StartDate_err->show();
521 } else {
522 m_icatUiForm.StartDate_err->hide();
523 }
524
525 return ret;
526}
527
528void CatalogSearch::correctedToolTip(const std::string &text, QLabel *label) {
529#ifdef Q_OS_WIN
530 label->setToolTip(QString::fromStdString("<span style=\"color: black;\">" + text + "</span>"));
531#else
532 label->setToolTip(QString::fromStdString("<span style=\"color: white;\">" + text + "</span>"));
533#endif
534}
535
540 if (m_icatUiForm.advSearchCbox->isChecked()) {
541 m_icatUiForm.advNameLbl->show();
542 m_icatUiForm.InvestigatorSurname->show();
543 m_icatUiForm.advDatafileLbl->show();
544 m_icatUiForm.DataFileName->show();
545 m_icatUiForm.advSampleLbl->show();
546 m_icatUiForm.SampleName->show();
547 m_icatUiForm.advTypeLbl->show();
548 m_icatUiForm.InvestigationType->show();
549 } else {
550 m_icatUiForm.advNameLbl->hide();
551 m_icatUiForm.InvestigatorSurname->hide();
552 m_icatUiForm.advDatafileLbl->hide();
553 m_icatUiForm.DataFileName->hide();
554 m_icatUiForm.advSampleLbl->hide();
555 m_icatUiForm.SampleName->hide();
556 m_icatUiForm.advTypeLbl->hide();
557 m_icatUiForm.InvestigationType->hide();
558 }
559}
560
566 auto name = sender()->objectName();
567 // This allows us to perform paging on each search separately
568 // as we call this method in three separate SLOTS (two paging & search
569 // button).
570 if (name.compare("searchBtn") == 0)
572
574
575 std::map<std::string, std::string> inputFields = getSearchFields();
576 // Contains the error label names, and the related error message.
577 std::map<std::string, std::string> errors = m_icatHelper->validateProperties(inputFields);
578
579 // Has any errors occurred?
580 if (!errors.empty() || validateDates()) {
581 // Clear form to prevent previous search results showing if an error occurs.
583 showErrorLabels(errors);
584 m_icatUiForm.searchResultsLbl->setText("An error has occurred in the search form.");
585 // Stop here to prevent the search being carried out below.
586 return;
587 }
588
589 // Performed here to allow the user to login while the search GUI is open,
590 // and see results of all facilities/catalogs that they are logged in to.
592
593 // Since there are no longer errors we hide the error labels.
595
596 // We want to disable/hide these as a search is in progress, but no results
597 // have been obtained.
598 m_icatUiForm.resFrame->hide();
599 m_icatUiForm.searchResultsCbox->setEnabled(false);
600 m_icatUiForm.searchResultsCbox->setChecked(false);
601
602 // Update the label to inform the user that searching is in progress.
603 m_icatUiForm.searchResultsLbl->setText("searching investigations...");
604
605 // Get previous sorting parameters
606 QTableWidget *resultsTable = m_icatUiForm.searchResultsTbl;
607 int sort_section = resultsTable->horizontalHeader()->sortIndicatorSection();
608 Qt::SortOrder sort_order = resultsTable->horizontalHeader()->sortIndicatorOrder();
609
610 // Remove previous search results.
611 std::string searchResults = "searchResults";
612
613 clearSearch(resultsTable, searchResults);
614
616 // Obtain the number of results for paging.
617 int64_t numrows = m_icatHelper->getNumberOfSearchResults(inputFields, sessionIDs);
618
619 // Setup values used for paging.
620 int limit = 100;
621 // Have to cast either numrows or limit to double for ceil to work correctly.
622 double totalNumPages = ceil(static_cast<double>(numrows) / limit);
623 int offset = (m_currentPageNumber - 1) * limit;
624
625 // Set paging labels.
626 m_icatUiForm.pageStartNum->setText(QString::number(m_currentPageNumber));
627 m_icatUiForm.resPageEndNumTxt->setText(QString::number(totalNumPages));
628
629 // Perform a search using paging (E.g. return only n from m).
630 m_icatHelper->executeSearch(inputFields, offset, limit, sessionIDs);
631
632 // Update the label to inform the user of how many investigations have been
633 // returned from the search.
634 m_icatUiForm.searchResultsLbl->setText(QString::number(numrows) + " investigations found.");
635
636 // Populate the result table from the searchResult workspace.
637 populateResultTable(sort_section, sort_order);
638}
639
645void CatalogSearch::showErrorLabels(std::map<std::string, std::string> &errors) {
646 for (auto &error : errors) {
647 QLabel *label = m_icatUiForm.searchFrame->findChild<QLabel *>(QString::fromStdString(error.first));
648
649 if (label) {
650 // Update the tooltip of the element and then show it.
651 correctedToolTip(error.second, label);
652 label->show();
653 }
654 }
655}
656
661 // Left side of form.
662 m_icatUiForm.InvestigationName_err->setVisible(false);
663 m_icatUiForm.Instrument_err->setVisible(false);
664 m_icatUiForm.RunRange_err->setVisible(false);
665 m_icatUiForm.InvestigationId_err->setVisible(false);
666 m_icatUiForm.InvestigatorSurname_err->setVisible(false);
667 m_icatUiForm.InvestigationAbstract_err->setVisible(false);
668 // Right side of form.
669 m_icatUiForm.StartDate_err->setVisible(false);
670 m_icatUiForm.EndDate_err->setVisible(false);
671 m_icatUiForm.Keywords_err->setVisible(false);
672 m_icatUiForm.SampleName_err->setVisible(false);
673 m_icatUiForm.InvestigationType_err->setVisible(false);
674}
675
680 // Clear the QLineEdit boxes.
681 foreach (QLineEdit *widget, this->findChildren<QLineEdit *>()) {
682 widget->clear();
683 }
684 // Clear all other elements.
685 m_icatUiForm.Instrument->setCurrentIndex(0);
686 m_icatUiForm.InvestigationType->setCurrentIndex(0);
687 m_icatUiForm.advSearchCbox->setChecked(false);
688 m_icatUiForm.myDataCbox->setChecked(false);
689}
690
700
702// Methods for "Search results"
704
711void CatalogSearch::populateResultTable(int sort_section, Qt::SortOrder sort_order) {
712 // Obtain a pointer to the "searchResults" workspace where the search results
713 // are saved if it exists.
715
716 // Check to see if the workspace exists...
717 if (Mantid::API::AnalysisDataService::Instance().doesExist("__searchResults")) {
718 workspace = std::dynamic_pointer_cast<Mantid::API::ITableWorkspace>(
719 Mantid::API::AnalysisDataService::Instance().retrieve("__searchResults"));
720 } else {
721 // Otherwise an error will be thrown (in ICat4Catalog). We will reproduce
722 // that error on the ICAT form for the user.
723 m_icatUiForm.searchResultsLbl->setText("You have not input any terms to search for.");
724 return;
725 }
726
727 // If there are no results then clear search form and don't try to setup
728 // table.
729 if (workspace->rowCount() == 0) {
731 return;
732 }
733
734 // Create local variable for convenience and reusability.
735 QTableWidget *resultsTable = m_icatUiForm.searchResultsTbl;
736
737 // Set the result's table properties prior to adding data.
738 setupTable(resultsTable, workspace->rowCount(), workspace->columnCount());
739
740 // Update the label to inform the user of how many investigations have been
741 // returned from the search.
742
743 // We want to show this now as we are certain that search results exist, and
744 // not display a blank frame (bad UX).
745 m_icatUiForm.resFrame->show();
746 m_icatUiForm.searchResultsCbox->setEnabled(true);
747 m_icatUiForm.searchResultsCbox->setChecked(true);
748
749 // Add data from the workspace to the results table.
750 populateTable(resultsTable, workspace);
751
752 // Show only a portion of the title as they can be quite long.
753 resultsTable->setColumnWidth(headerIndexByName(resultsTable, "Title"), 210);
754 resultsTable->setColumnHidden(headerIndexByName(resultsTable, "DatabaseID"), true);
755 resultsTable->setColumnHidden(headerIndexByName(resultsTable, "SessionID"), true);
756
757 // Resize InvestigationID column to fit contents
758 resultsTable->resizeColumnToContents(headerIndexByName(resultsTable, "InvestigationID"));
759
760 // Sort by specified column or by descending StartDate if none specified
761 resultsTable->setSortingEnabled(true);
762 if (sort_section == 0) {
763 resultsTable->sortByColumn(headerIndexByName(resultsTable, "Start date"), Qt::DescendingOrder);
764 } else {
765 resultsTable->sortByColumn(sort_section, sort_order);
766 }
767}
768
776 auto searchResultsTable = m_icatUiForm.searchResultsTbl;
777 return searchResultsTable
778 ->item(searchResultsTable->selectionModel()->selectedRows().at(0).row(),
779 headerIndexByName(searchResultsTable, "SessionID"))
780 ->text()
781 .toStdString();
782}
783
785// SLOTS for "Search results"
787
792 int totalNumPages = m_icatUiForm.resPageEndNumTxt->text().toInt();
793 // Prevent user from pressing "next" when no more investigations exist.
794 if (m_currentPageNumber >= totalNumPages) {
795 m_currentPageNumber = totalNumPages;
796 return;
797 }
798 // Increment here as we need to validate page number above.
800 // Perform the search, and update the table with the new results using the
801 // current page num.
803}
804
810 // Prevent user from pressing "Previous" when no investigations exist.
811 if (m_currentPageNumber <= 0) {
813 return;
814 }
816}
817
822 int pageNum = m_icatUiForm.pageStartNum->text().toInt();
823 // If the user inputs a page number larger than the total
824 // amount of page numbers we do not want to do anything.
825 if (pageNum > m_icatUiForm.resPageEndNumTxt->text().toInt() || pageNum <= 0) {
826 m_icatUiForm.pageStartNum->setText(QString::number(m_currentPageNumber));
827 return;
828 }
829 m_currentPageNumber = pageNum;
831}
832
837void CatalogSearch::investigationSelected(QTableWidgetItem *item) {
839 //
840 m_icatUiForm.dataFileCbox->setEnabled(true);
841 m_icatUiForm.dataFileCbox->setChecked(true);
842 m_icatUiForm.dataFileFrame->show();
843 // Have to clear the combo-box in order to prevent the user from seeing the
844 // extensions of previous search.
845 m_icatUiForm.dataFileFilterCombo->clear();
846 m_icatUiForm.dataFileFilterCombo->addItem("No filter");
847
848 // Inform the user that the search is in progress.
849 m_icatUiForm.dataFileLbl->setText("searching for related datafiles...");
850
851 QTableWidget *searchResultsTable = m_icatUiForm.searchResultsTbl;
852
853 // Obtain the investigationID from the selected
854 QTableWidgetItem *investigationId =
855 searchResultsTable->item(item->row(), headerIndexByName(searchResultsTable, "InvestigationID"));
856
857 // Remove previous dataFile search results.
858 std::string dataFileResults = "dataFileResults";
859 clearSearch(m_icatUiForm.dataFileResultsTbl, dataFileResults);
860
861 // Update the labels in the dataFiles information frame to show relevant info
862 // to use.
864
865 // Perform the "search" and obtain the related data files for the selected
866 // investigation.
868 investigationId->text().toStdString(),
869 searchResultsTable->item(item->row(), headerIndexByName(searchResultsTable, "SessionID"))->text().toStdString());
870
871 // Populate the dataFile table from the "dataFileResults" workspace.
873}
874
876// Methods for "DataFile information"
878
884 // Obtain a pointer to the "dataFileResults" workspace where the related
885 // datafiles for the user selected investigation exist.
887
888 // Check to see if the workspace exists...
889 if (Mantid::API::AnalysisDataService::Instance().doesExist("__dataFileResults")) {
890 workspace = std::dynamic_pointer_cast<Mantid::API::ITableWorkspace>(
891 Mantid::API::AnalysisDataService::Instance().retrieve("__dataFileResults"));
892 } else {
893 return;
894 }
895
896 // If there are no results then don't try to setup table.
897 if (workspace->rowCount() == 0) {
899 m_icatUiForm.dataFileLbl->setText(QString::number(workspace->rowCount()) + " datafiles found.");
900 return;
901 }
902
903 // Create local variable for convenience and reusability.
904 QTableWidget *dataFileTable = m_icatUiForm.dataFileResultsTbl;
905
906 // Set the result's table properties prior to adding data.
907 setupTable(dataFileTable, workspace->rowCount(), workspace->columnCount());
908
909 // Update the label to inform the user of how many dataFiles relating to the
910 // selected investigation have been found.
911 m_icatUiForm.dataFileLbl->setText(QString::number(workspace->rowCount()) + " datafiles found.");
912
913 // Create the custom header with checkbox ability.
914 m_customHeader = new CheckboxHeader(Qt::Horizontal, dataFileTable);
915
916 // There is no simple way to override default QTableWidget sort.
917 // Instead, connecting header to obtain column clicked, and sorting by
918 connect(m_customHeader, SIGNAL(sectionClicked(int)), this, SLOT(sortByFileSize(int)));
919
920 // Set it prior to adding labels in populateTable.
921 dataFileTable->setHorizontalHeader(m_customHeader);
922
923 // Add data from the workspace to the results table.
924 populateTable(dataFileTable, workspace);
925
926 // As a new column is being added we do this after populateTable to prevent
927 // null errors.
928 addCheckBoxColumn(dataFileTable);
929
930 // Resize the columns to improve the viewing experience.
931 // Has been called here since we added the checkbox column after populating
932 // table.
933 dataFileTable->resizeColumnsToContents();
934
935 // Hide these columns as they're not useful for the user, but are used by the
936 // algorithms.
937 dataFileTable->setColumnHidden(headerIndexByName(dataFileTable, "Id"), true);
938 dataFileTable->setColumnHidden(headerIndexByName(dataFileTable, "Location"), true);
939 dataFileTable->setColumnHidden(headerIndexByName(dataFileTable, "File size(bytes)"), true);
940
941 // Obtain the list of extensions of all dataFiles for the chosen
942 // investigation.
943 // "File name" is the first column of "dataFileResults" so we make use of it.
944 auto extensions = getDataFileExtensions(workspace.get()->getColumn(headerIndexByName(dataFileTable, "Name")));
945
946 // Populate the "Filter type..." combo-box with all possible file extensions.
947 populateDataFileType(extensions);
948
949 // Sort by create time with the most recent being first.
950 dataFileTable->setSortingEnabled(true);
951 dataFileTable->sortByColumn(headerIndexByName(dataFileTable, "Name"), Qt::DescendingOrder);
952}
953
958void CatalogSearch::addCheckBoxColumn(QTableWidget *table) {
959 // Add a new column checkbox column.
960 table->insertColumn(0);
961 // Add a new header item to this column. This allows us to overwrite the
962 // default text!
963 table->setHorizontalHeaderItem(0, new QTableWidgetItem());
964 // Set this here (rather than on initialisation) as the customer header would
965 // be null otherwise.
966 connect(m_customHeader, SIGNAL(toggled(bool)), this, SLOT(selectAllDataFiles(bool)));
967
968 // Add a checkbox to all rows in the first column.
969 for (int row = 0; row < table->rowCount(); row++) {
970 auto *newItem = new QTableWidgetItem();
971 // Allow the widget to take on checkbox functionality.
972 newItem->setCheckState(Qt::Unchecked);
973 // Allow the user to select and check the box.
974 newItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
975 // Add a result to the table.
976 table->setItem(row, 0, newItem);
977 }
978}
979
985const std::vector<std::pair<int64_t, std::string>> CatalogSearch::selectedDataFileNames() {
986 QTableWidget *table = m_icatUiForm.dataFileResultsTbl;
987
988 // Holds the FileID, and fileName in order to perform search to download
989 // later.
990 std::vector<std::pair<int64_t, std::string>> fileInfo;
991
992 for (int row = 0; row < table->rowCount(); row++) {
993 if (table->item(row, 0)->checkState()) {
994 fileInfo.emplace_back(table->item(row, headerIndexByName(table, "Id"))->text().toLongLong(),
995 table->item(row, headerIndexByName(table, "Name"))->text().toStdString());
996 }
997 }
998 return (fileInfo);
999}
1000
1005void CatalogSearch::updateDataFileLabels(QTableWidgetItem *item) {
1006 QTableWidget *searchResultsTable = m_icatUiForm.searchResultsTbl;
1007
1008 // Set the "title" label using the data from the investigation results
1009 // workspace.
1010 m_icatUiForm.dataFileTitleRes->setText(
1011 searchResultsTable->item(item->row(), headerIndexByName(searchResultsTable, "Title"))->text());
1012
1013 // Set the instrument label using data from the investigation results
1014 // workspace.
1015 m_icatUiForm.dataFileInstrumentRes->setText(
1016 searchResultsTable->item(item->row(), headerIndexByName(searchResultsTable, "Instrument"))->text());
1017
1018 // Show the related "run-range" for the specific dataFiles.
1019 m_icatUiForm.dataFileRunRangeRes->setText(
1020 searchResultsTable->item(item->row(), headerIndexByName(searchResultsTable, "Run range"))->text());
1021}
1022
1028std::unordered_set<std::string> CatalogSearch::getDataFileExtensions(const Mantid::API::Column_sptr &column) {
1029 std::unordered_set<std::string> extensions;
1030
1031 // For every filename in the column...
1032 for (unsigned row = 0; row < column->size(); row++) {
1033 // Add the file extension to the set if it does not exist.
1034 QString extension = QString::fromStdString(Poco::Path(column->cell<std::string>(row)).getExtension());
1035 extensions.insert(extension.toLower().toStdString());
1036 }
1037
1038 return (extensions);
1039}
1040
1044void CatalogSearch::populateDataFileType(const std::unordered_set<std::string> &extensions) {
1045 for (const auto &extension : extensions) {
1046 m_icatUiForm.dataFileFilterCombo->addItem(QString::fromStdString("." + extension));
1047 }
1048}
1049
1056 using namespace Mantid::Kernel;
1057
1058 QTableWidget *table = m_icatUiForm.dataFileResultsTbl;
1059 // The location of the file selected in the archives.
1060 std::string location = table->item(row, headerIndexByName(table, "Location"))->text().toStdString();
1061
1062 // Create and use the user-set ConfigInformation.
1063 std::unique_ptr<CatalogConfigService> catConfigService(makeCatalogConfigServiceAdapter(ConfigService::Instance()));
1064 UserCatalogInfo catalogInfo(ConfigService::Instance().getFacility().catalogInfo(), *catConfigService);
1065
1066 std::string fileLocation = catalogInfo.transformArchivePath(location);
1067
1068 std::ifstream hasAccessToArchives(fileLocation.c_str());
1069 if (hasAccessToArchives) {
1070 m_icatUiForm.dataFileDownloadBtn->setEnabled(false);
1071 } else {
1072 m_icatUiForm.dataFileDownloadBtn->setEnabled(true);
1073 }
1074 // Allow the user to load the datafile regardless.
1075 m_icatUiForm.dataFileLoadBtn->setEnabled(true);
1076}
1077
1079// SLOTS for: "DataFile information"
1081
1087 if (m_icatUiForm.dataFileResultsTbl->selectionModel()->selection().indexes().empty()) {
1088 m_icatUiForm.dataFileDownloadBtn->setEnabled(false);
1089 m_icatUiForm.dataFileLoadBtn->setEnabled(false);
1090 }
1091}
1092
1097 QTableWidget *table = m_icatUiForm.dataFileResultsTbl;
1098
1099 for (int row = 0; row < table->rowCount(); ++row) {
1100 // Hide row by default, in order to show only relevant ones.
1101 table->setRowHidden(row, true);
1102
1103 // As we use checkboxes in "selectedDataFileNames" to obtain the row of the
1104 // file the user wants to download
1105 // the state of these checkboxes remain when filtered. Thus we un-check them
1106 // here to prevent accidently downloading.
1107 table->item(row, 0)->setCheckState(Qt::Unchecked);
1108
1109 QTableWidgetItem *item = table->item(row, headerIndexByName(table, "Name"));
1110 // Show the relevant rows depending on file extension. 0 index is "Filter
1111 // type..." so all will be shown.
1112 // Have to convert to lowercase as ".TXT", and ".txt" should be filtered as
1113 // the same.
1114 if (index == 0 || (item->text().toLower().contains(m_icatUiForm.dataFileFilterCombo->itemText(index).toLower()))) {
1115 table->setRowHidden(row, false);
1116 }
1117 }
1118}
1119
1124 QString downloadSavePath = QFileDialog::getExistingDirectory(this, tr("Select a directory to save data files."),
1125 m_downloadSaveDir, QFileDialog::ShowDirsOnly);
1126
1127 // The user has clicked "Open" and changed the path (and not clicked cancel).
1128 if (!downloadSavePath.isEmpty()) {
1129 // Set setting prior to saving.
1130 m_downloadSaveDir = downloadSavePath;
1131 // Save settings to store for use next time.
1132 saveSettings();
1133 // Download the selected dataFiles to the chosen directory.
1136 }
1137}
1138
1143 // Get the path(s) to the file that was downloaded (via HTTP) or is stored in
1144 // the archive.
1145 std::vector<std::string> filePaths = m_icatHelper->downloadDataFiles(
1147
1148 // Create & initialize the load algorithm we will use to load the file by path
1149 // to a workspace.
1150 auto loadAlgorithm = Mantid::API::AlgorithmManager::Instance().create("Load");
1151 loadAlgorithm->initialize();
1152
1153 // For all the files downloaded (or in archive) we want to load them.
1154 for (auto &filePath : filePaths) {
1155 if (filePath.empty())
1156 return;
1157 // Set the filename (path) of the algorithm to load from.
1158 loadAlgorithm->setPropertyValue("Filename", filePath);
1159 // Sets the output workspace to be the name of the file.
1160 loadAlgorithm->setPropertyValue("OutputWorkspace", Poco::Path(Poco::Path(filePath).getFileName()).getBaseName());
1161
1162 Poco::ActiveResult<bool> result(loadAlgorithm->executeAsync());
1163 while (!result.available()) {
1164 QCoreApplication::processEvents();
1165 }
1166 }
1167}
1168
1175void CatalogSearch::selectAllDataFiles(const bool &toggled) {
1176 QTableWidget *table = m_icatUiForm.dataFileResultsTbl;
1177
1178 // Used to gain easier access to table selection.
1179 QItemSelectionModel *selectionModel = table->selectionModel();
1180
1181 // Select or deselect all rows depending on toggle.
1182 if (toggled)
1183 table->selectAll();
1184 else
1185 selectionModel->select(selectionModel->selection(), QItemSelectionModel::Deselect);
1186
1187 // Check/un-check the checkboxes of each row.
1188 for (int row = 0; row < table->rowCount(); ++row) {
1189 if (toggled)
1190 table->item(row, 0)->setCheckState(Qt::Checked);
1191 else
1192 table->item(row, 0)->setCheckState(Qt::Unchecked);
1193 }
1194}
1195
1200void CatalogSearch::dataFileCheckboxSelected(QTableWidgetItem *item) {
1201 QTableWidget *table = m_icatUiForm.dataFileResultsTbl;
1202
1203 QTableWidgetItem *checkbox = table->item(item->row(), 0);
1204
1205 for (int col = 0; col < table->columnCount(); col++) {
1206 for (int row = 0; row < table->rowCount(); ++row) {
1207 if (checkbox->checkState()) {
1208 table->item(item->row(), 0)->setCheckState(Qt::Checked);
1209 table->item(item->row(), col)->setSelected(true);
1210 } else {
1211 table->item(item->row(), 0)->setCheckState(Qt::Unchecked);
1212 // There is no easier way to deselect an item...
1213 table->item(item->row(), col)->setSelected(false);
1214 }
1215 }
1216 }
1217}
1218
1223 QTableWidget *table = m_icatUiForm.dataFileResultsTbl;
1224
1225 for (int row = 0; row < table->rowCount(); ++row) {
1226 // We Uncheck here to prevent previously selected items staying selected
1227 // and to allow dataFileCheckboxSelected() to function correctly.
1228 if (!table->item(row, 0)->isSelected()) {
1229 table->item(row, 0)->setCheckState(Qt::Unchecked);
1230 }
1231 }
1232
1233 QModelIndexList indexes = table->selectionModel()->selectedRows();
1234
1235 for (int i = 0; i < indexes.count(); ++i) {
1236 int row = indexes.at(i).row();
1237 table->item(row, 0)->setCheckState(Qt::Checked);
1240 }
1241 // Disable load/download buttons if no datafile is selected.
1243}
1244
1250 QTableWidget *table = m_icatUiForm.dataFileResultsTbl;
1251 int byteColumn = headerIndexByName(table, "File size(bytes)");
1252
1253 if (column == headerIndexByName(table, "File size")) {
1254 // Convert cell value to int within the datamodel.
1255 // This allows us to sort by the specific column.
1256 for (int row = 0; row < table->rowCount(); row++) {
1257 auto *item = new QTableWidgetItem;
1258 item->setData(Qt::EditRole, table->item(row, byteColumn)->text().toInt());
1259 table->setItem(row, byteColumn, item);
1260 }
1261 table->sortByColumn(byteColumn);
1262 }
1263}
1264
1265} // namespace MantidWidgets
1266} // namespace MantidQt
std::string name
Definition Run.cpp:60
double error
IPeaksWorkspace_sptr workspace
std::map< DeltaEMode::Type, std::string > index
This class provides a wrapper around QDesktopServices to fix a bug in opening URLs in firefox when tc...
static bool openUrl(const QUrl &url)
Opens a url in the appropriate web browser.
const std::vector< std::string > getInvestigationTypeList(const std::vector< std::string > &sessionIDs)
Obtain the list of instruments that are available.
int64_t getNumberOfSearchResults(const std::map< std::string, std::string > &userInputFields, const std::vector< std::string > &sessionIDs)
Obtain the number of search results to be returned by the query of the user.
const std::vector< std::string > downloadDataFiles(const std::vector< std::pair< int64_t, std::string > > &userSelectedFiles, const std::string &downloadPath, const std::string &sessionID)
Download dataFile (via HTTP or copy if access to archive) and return the path to it.
const std::vector< std::string > getInstrumentList(const std::vector< std::string > &sessionIDs)
Obtain the list of instruments that are available for the given session information.
void executeSearch(const std::map< std::string, std::string > &userInputs, const int &offset, const int &limit, const std::vector< std::string > &sessionIDs)
Run the search algorithm with the given user input.
time_t getTimevalue(const std::string &inputDate)
Creates a time_t value from an input date ("23/06/2003") for comparison.
const std::map< std::string, std::string > validateProperties(const std::map< std::string, std::string > &inputFields)
Validate each input field against the related algorithm property.
void executeGetDataFiles(const std::string &investigationId, const std::string &sessionID)
Search for all related dataFiles for the specified investigation.
void showCatalogSearch()
When checked, show the Catalog search frame.
void showDataFileInfo()
When checked, show the data file info frame.
void correctedToolTip(const std::string &toolTip, QLabel *label)
void selectAllDataFiles(const bool &toggled)
Selects/deselects ALL rows in dataFile table.
CatalogSelector * m_catalogSelector
Access methods of catalog selector GUI, e.g. selected facilities.
void emboldenTableHeaders(QTableWidget *table)
Make the headers in the provided table bold.
void showSearchResults()
Shows/Hides the "Search results" frame when search results combo box is checked.
void updateDataFileLabels(QTableWidgetItem *item)
Updates the dataFile text boxes with relevant info about the selected dataFile.
void clearSearchFrame()
Clear the "search" frame when an investigation has been selected.
void disableDatafileButtons()
Disable load/download buttons if no datafile is selected.
void goToInputPage()
Populate's result table depending page number input by user.
CatalogHelper * m_icatHelper
The helper class that accesses ICAT algorithmic functionality.
void populateResultTable(int sort_section, Qt::SortOrder sort_order)
Outputs the results of the query into a table.
void populateInvestigationTypeBox()
Populate the investigation type list-box.
QString m_dateButtonName
The name of the date button the user pressed to open the calendar.
void setupTable(QTableWidget *table, const size_t &numOfRows, const size_t &numOfColumns)
Setup table prior to adding data to it, such hiding vertical header.
void investigationSelected(QTableWidgetItem *item)
Checks that the investigation is selected and performs investigationClicked.
std::string selectedInvestigationSession()
Obtain the sessionID for the selected investigation.
void loadDataFiles()
Loads the selected dataFiles into workspaces.
void sortByFileSize(int column)
Sort table by file size when certain column is clicked (E.g.
void onFacilityLogin()
When the facility login button is clicked.
QCalendarWidget * m_calendar
The calendar widget that will allow the user to select start and end date/times.
void clearSearch(QTableWidget *table, const std::string &workspace)
Removes data associated with previous search.
void onReset()
Reset all fields when "Reset" is clicked.
void showErrorLabels(std::map< std::string, std::string > &errors)
Show the error message labels, including the error message on the tooltips.
void openCalendar()
Open the DateTime Calendar to select date.
CatalogSearch(QWidget *parent=nullptr)
Default constructor.
const std::vector< std::pair< int64_t, std::string > > selectedDataFileNames()
Obtain the file details (file ID and name) for the file to download.
const std::map< std::string, std::string > getSearchFields()
Obtain the users' text input for each search field.
QString m_downloadSaveDir
The directory to save the downloaded dataFiles.
void disableDownloadButtonIfArchives(int row)
Disable the download button if user can access the files locally from the archives.
void dataFileRowSelected()
Select/Deselect row & check-box when a row is selected.
void populateTable(QTableWidget *table, const Mantid::API::ITableWorkspace_sptr &workspace)
Populate the provided table with data from the provided workspace.
void doFilter(const int &index)
Performs filterDataFileType() for specified filer type.
void helpClicked()
When the help button is clicked.
bool validateDates()
Checks if start date is greater than end date.
std::unordered_set< std::string > getDataFileExtensions(const Mantid::API::Column_sptr &column)
Obtain all file extensions from the provided column (dataFileResults -> File name).
void clearDataFileFrame()
Clear "dataFileFrame" when the user tries to search again.
void loadSettings()
Read settings from store.
void populateDataFileType(const std::unordered_set< std::string > &extensions)
Add the list of file extensions to the "Filter type..." drop-down.
void clearSearchResultFrame()
Clear the "search results" frame if no results are returned from search.
void populateInstrumentBox()
Populate the instrument list-box.
void hideErrorLabels()
Hide the error message labels.
Ui::CatalogSearch m_icatUiForm
The form generated by QT Designer.
void populateDataFileTable()
Populates the table from the results of investigationSelected();.
void nextPageClicked()
Populate the result table, and update the page number.
void addCheckBoxColumn(QTableWidget *table)
Add a row of checkboxes to the first column of a table.
void prevPageClicked()
Populate the result table, and update the page number.
void downloadDataFiles()
Downloads selected datFiles to a specified location.
void openFacilitySelection()
Enables user to select specific facilities that they want to search the catalogs of.
void dateSelected(const std::string &buttonName)
int m_currentPageNumber
The current page the user is on in the results window. Used for paging.
int headerIndexByName(QTableWidget *table, const std::string &searchFor)
Obtain the index of the column in a table that contains a specified name.
void searchClicked()
When the "Search" button is clicked, display "Search results" frame.
void saveSettings()
Save the current state of ICAT for next time.
void advancedSearchChecked()
Show the advanced field when checked.
virtual void initLayout()
Initialise the layout.
CheckboxHeader * m_customHeader
The custom table header with checkbox functionality.
void dataFileCheckboxSelected(QTableWidgetItem *item)
Select/Deselect row when a checkbox is selected.
void populateFacilitySelection()
Populate the ListWidget with the facilities of the catalogs the user is logged in to.
std::vector< std::string > getSelectedCatalogSessions()
Obtain the session information for the facilities selected.
This class subclasses and overwrites QHeaderView methods to enable checkboxes to exist in the table h...
virtual std::string transformArchivePath(const std::string &path) const
Transform's the archive path based on operating system used.
UserCatalogInfo : Takes catalog info from the facility (via CatalogInfo), but provides the ability to...
The AlgorithmProgressDialogPresenter keeps track of the running algorithms and displays a progress ba...
std::shared_ptr< Column > Column_sptr
Definition Column.h:232
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
CatalogConfigService * makeCatalogConfigServiceAdapter(const T &adaptee, const std::string &key="icatDownload.mountPoint")