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.
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 *>()) { widget->clear(); }
682 // Clear all other elements.
683 m_icatUiForm.Instrument->setCurrentIndex(0);
684 m_icatUiForm.InvestigationType->setCurrentIndex(0);
685 m_icatUiForm.advSearchCbox->setChecked(false);
686 m_icatUiForm.myDataCbox->setChecked(false);
687}
688
695 m_catalogSelector->show();
696 m_catalogSelector->raise();
697}
698
700// Methods for "Search results"
702
709void CatalogSearch::populateResultTable(int sort_section, Qt::SortOrder sort_order) {
710 // Obtain a pointer to the "searchResults" workspace where the search results
711 // are saved if it exists.
713
714 // Check to see if the workspace exists...
715 if (Mantid::API::AnalysisDataService::Instance().doesExist("__searchResults")) {
716 workspace = std::dynamic_pointer_cast<Mantid::API::ITableWorkspace>(
717 Mantid::API::AnalysisDataService::Instance().retrieve("__searchResults"));
718 } else {
719 // Otherwise an error will be thrown (in ICat4Catalog). We will reproduce
720 // that error on the ICAT form for the user.
721 m_icatUiForm.searchResultsLbl->setText("You have not input any terms to search for.");
722 return;
723 }
724
725 // If there are no results then clear search form and don't try to setup
726 // table.
727 if (workspace->rowCount() == 0) {
729 return;
730 }
731
732 // Create local variable for convenience and reusability.
733 QTableWidget *resultsTable = m_icatUiForm.searchResultsTbl;
734
735 // Set the result's table properties prior to adding data.
736 setupTable(resultsTable, workspace->rowCount(), workspace->columnCount());
737
738 // Update the label to inform the user of how many investigations have been
739 // returned from the search.
740
741 // We want to show this now as we are certain that search results exist, and
742 // not display a blank frame (bad UX).
743 m_icatUiForm.resFrame->show();
744 m_icatUiForm.searchResultsCbox->setEnabled(true);
745 m_icatUiForm.searchResultsCbox->setChecked(true);
746
747 // Add data from the workspace to the results table.
748 populateTable(resultsTable, workspace);
749
750 // Show only a portion of the title as they can be quite long.
751 resultsTable->setColumnWidth(headerIndexByName(resultsTable, "Title"), 210);
752 resultsTable->setColumnHidden(headerIndexByName(resultsTable, "DatabaseID"), true);
753 resultsTable->setColumnHidden(headerIndexByName(resultsTable, "SessionID"), true);
754
755 // Resize InvestigationID column to fit contents
756 resultsTable->resizeColumnToContents(headerIndexByName(resultsTable, "InvestigationID"));
757
758 // Sort by specified column or by descending StartDate if none specified
759 resultsTable->setSortingEnabled(true);
760 if (sort_section == 0) {
761 resultsTable->sortByColumn(headerIndexByName(resultsTable, "Start date"), Qt::DescendingOrder);
762 } else {
763 resultsTable->sortByColumn(sort_section, sort_order);
764 }
765}
766
774 auto searchResultsTable = m_icatUiForm.searchResultsTbl;
775 return searchResultsTable
776 ->item(searchResultsTable->selectionModel()->selectedRows().at(0).row(),
777 headerIndexByName(searchResultsTable, "SessionID"))
778 ->text()
779 .toStdString();
780}
781
783// SLOTS for "Search results"
785
790 int totalNumPages = m_icatUiForm.resPageEndNumTxt->text().toInt();
791 // Prevent user from pressing "next" when no more investigations exist.
792 if (m_currentPageNumber >= totalNumPages) {
793 m_currentPageNumber = totalNumPages;
794 return;
795 }
796 // Increment here as we need to validate page number above.
798 // Perform the search, and update the table with the new results using the
799 // current page num.
801}
802
808 // Prevent user from pressing "Previous" when no investigations exist.
809 if (m_currentPageNumber <= 0) {
811 return;
812 }
814}
815
820 int pageNum = m_icatUiForm.pageStartNum->text().toInt();
821 // If the user inputs a page number larger than the total
822 // amount of page numbers we do not want to do anything.
823 if (pageNum > m_icatUiForm.resPageEndNumTxt->text().toInt() || pageNum <= 0) {
824 m_icatUiForm.pageStartNum->setText(QString::number(m_currentPageNumber));
825 return;
826 }
827 m_currentPageNumber = pageNum;
829}
830
835void CatalogSearch::investigationSelected(QTableWidgetItem *item) {
837 //
838 m_icatUiForm.dataFileCbox->setEnabled(true);
839 m_icatUiForm.dataFileCbox->setChecked(true);
840 m_icatUiForm.dataFileFrame->show();
841 // Have to clear the combo-box in order to prevent the user from seeing the
842 // extensions of previous search.
843 m_icatUiForm.dataFileFilterCombo->clear();
844 m_icatUiForm.dataFileFilterCombo->addItem("No filter");
845
846 // Inform the user that the search is in progress.
847 m_icatUiForm.dataFileLbl->setText("searching for related datafiles...");
848
849 QTableWidget *searchResultsTable = m_icatUiForm.searchResultsTbl;
850
851 // Obtain the investigationID from the selected
852 QTableWidgetItem *investigationId =
853 searchResultsTable->item(item->row(), headerIndexByName(searchResultsTable, "InvestigationID"));
854
855 // Remove previous dataFile search results.
856 std::string dataFileResults = "dataFileResults";
857 clearSearch(m_icatUiForm.dataFileResultsTbl, dataFileResults);
858
859 // Update the labels in the dataFiles information frame to show relevant info
860 // to use.
862
863 // Perform the "search" and obtain the related data files for the selected
864 // investigation.
866 investigationId->text().toStdString(),
867 searchResultsTable->item(item->row(), headerIndexByName(searchResultsTable, "SessionID"))->text().toStdString());
868
869 // Populate the dataFile table from the "dataFileResults" workspace.
871}
872
874// Methods for "DataFile information"
876
882 // Obtain a pointer to the "dataFileResults" workspace where the related
883 // datafiles for the user selected investigation exist.
885
886 // Check to see if the workspace exists...
887 if (Mantid::API::AnalysisDataService::Instance().doesExist("__dataFileResults")) {
888 workspace = std::dynamic_pointer_cast<Mantid::API::ITableWorkspace>(
889 Mantid::API::AnalysisDataService::Instance().retrieve("__dataFileResults"));
890 } else {
891 return;
892 }
893
894 // If there are no results then don't try to setup table.
895 if (workspace->rowCount() == 0) {
897 m_icatUiForm.dataFileLbl->setText(QString::number(workspace->rowCount()) + " datafiles found.");
898 return;
899 }
900
901 // Create local variable for convenience and reusability.
902 QTableWidget *dataFileTable = m_icatUiForm.dataFileResultsTbl;
903
904 // Set the result's table properties prior to adding data.
905 setupTable(dataFileTable, workspace->rowCount(), workspace->columnCount());
906
907 // Update the label to inform the user of how many dataFiles relating to the
908 // selected investigation have been found.
909 m_icatUiForm.dataFileLbl->setText(QString::number(workspace->rowCount()) + " datafiles found.");
910
911 // Create the custom header with checkbox ability.
912 m_customHeader = new CheckboxHeader(Qt::Horizontal, dataFileTable);
913
914 // There is no simple way to override default QTableWidget sort.
915 // Instead, connecting header to obtain column clicked, and sorting by
916 connect(m_customHeader, SIGNAL(sectionClicked(int)), this, SLOT(sortByFileSize(int)));
917
918 // Set it prior to adding labels in populateTable.
919 dataFileTable->setHorizontalHeader(m_customHeader);
920
921 // Add data from the workspace to the results table.
922 populateTable(dataFileTable, workspace);
923
924 // As a new column is being added we do this after populateTable to prevent
925 // null errors.
926 addCheckBoxColumn(dataFileTable);
927
928 // Resize the columns to improve the viewing experience.
929 // Has been called here since we added the checkbox column after populating
930 // table.
931 dataFileTable->resizeColumnsToContents();
932
933 // Hide these columns as they're not useful for the user, but are used by the
934 // algorithms.
935 dataFileTable->setColumnHidden(headerIndexByName(dataFileTable, "Id"), true);
936 dataFileTable->setColumnHidden(headerIndexByName(dataFileTable, "Location"), true);
937 dataFileTable->setColumnHidden(headerIndexByName(dataFileTable, "File size(bytes)"), true);
938
939 // Obtain the list of extensions of all dataFiles for the chosen
940 // investigation.
941 // "File name" is the first column of "dataFileResults" so we make use of it.
942 auto extensions = getDataFileExtensions(workspace.get()->getColumn(headerIndexByName(dataFileTable, "Name")));
943
944 // Populate the "Filter type..." combo-box with all possible file extensions.
945 populateDataFileType(extensions);
946
947 // Sort by create time with the most recent being first.
948 dataFileTable->setSortingEnabled(true);
949 dataFileTable->sortByColumn(headerIndexByName(dataFileTable, "Name"), Qt::DescendingOrder);
950}
951
956void CatalogSearch::addCheckBoxColumn(QTableWidget *table) {
957 // Add a new column checkbox column.
958 table->insertColumn(0);
959 // Add a new header item to this column. This allows us to overwrite the
960 // default text!
961 table->setHorizontalHeaderItem(0, new QTableWidgetItem());
962 // Set this here (rather than on initialisation) as the customer header would
963 // be null otherwise.
964 connect(m_customHeader, SIGNAL(toggled(bool)), this, SLOT(selectAllDataFiles(bool)));
965
966 // Add a checkbox to all rows in the first column.
967 for (int row = 0; row < table->rowCount(); row++) {
968 auto *newItem = new QTableWidgetItem();
969 // Allow the widget to take on checkbox functionality.
970 newItem->setCheckState(Qt::Unchecked);
971 // Allow the user to select and check the box.
972 newItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
973 // Add a result to the table.
974 table->setItem(row, 0, newItem);
975 }
976}
977
983const std::vector<std::pair<int64_t, std::string>> CatalogSearch::selectedDataFileNames() {
984 QTableWidget *table = m_icatUiForm.dataFileResultsTbl;
985
986 // Holds the FileID, and fileName in order to perform search to download
987 // later.
988 std::vector<std::pair<int64_t, std::string>> fileInfo;
989
990 for (int row = 0; row < table->rowCount(); row++) {
991 if (table->item(row, 0)->checkState()) {
992 fileInfo.emplace_back(table->item(row, headerIndexByName(table, "Id"))->text().toLongLong(),
993 table->item(row, headerIndexByName(table, "Name"))->text().toStdString());
994 }
995 }
996 return (fileInfo);
997}
998
1003void CatalogSearch::updateDataFileLabels(QTableWidgetItem *item) {
1004 QTableWidget *searchResultsTable = m_icatUiForm.searchResultsTbl;
1005
1006 // Set the "title" label using the data from the investigation results
1007 // workspace.
1008 m_icatUiForm.dataFileTitleRes->setText(
1009 searchResultsTable->item(item->row(), headerIndexByName(searchResultsTable, "Title"))->text());
1010
1011 // Set the instrument label using data from the investigation results
1012 // workspace.
1013 m_icatUiForm.dataFileInstrumentRes->setText(
1014 searchResultsTable->item(item->row(), headerIndexByName(searchResultsTable, "Instrument"))->text());
1015
1016 // Show the related "run-range" for the specific dataFiles.
1017 m_icatUiForm.dataFileRunRangeRes->setText(
1018 searchResultsTable->item(item->row(), headerIndexByName(searchResultsTable, "Run range"))->text());
1019}
1020
1026std::unordered_set<std::string> CatalogSearch::getDataFileExtensions(const Mantid::API::Column_sptr &column) {
1027 std::unordered_set<std::string> extensions;
1028
1029 // For every filename in the column...
1030 for (unsigned row = 0; row < column->size(); row++) {
1031 // Add the file extension to the set if it does not exist.
1032 QString extension = QString::fromStdString(Poco::Path(column->cell<std::string>(row)).getExtension());
1033 extensions.insert(extension.toLower().toStdString());
1034 }
1035
1036 return (extensions);
1037}
1038
1042void CatalogSearch::populateDataFileType(const std::unordered_set<std::string> &extensions) {
1043 for (const auto &extension : extensions) {
1044 m_icatUiForm.dataFileFilterCombo->addItem(QString::fromStdString("." + extension));
1045 }
1046}
1047
1054 using namespace Mantid::Kernel;
1055
1056 QTableWidget *table = m_icatUiForm.dataFileResultsTbl;
1057 // The location of the file selected in the archives.
1058 std::string location = table->item(row, headerIndexByName(table, "Location"))->text().toStdString();
1059
1060 // Create and use the user-set ConfigInformation.
1061 std::unique_ptr<CatalogConfigService> catConfigService(makeCatalogConfigServiceAdapter(ConfigService::Instance()));
1062 UserCatalogInfo catalogInfo(ConfigService::Instance().getFacility().catalogInfo(), *catConfigService);
1063
1064 std::string fileLocation = catalogInfo.transformArchivePath(location);
1065
1066 std::ifstream hasAccessToArchives(fileLocation.c_str());
1067 if (hasAccessToArchives) {
1068 m_icatUiForm.dataFileDownloadBtn->setEnabled(false);
1069 } else {
1070 m_icatUiForm.dataFileDownloadBtn->setEnabled(true);
1071 }
1072 // Allow the user to load the datafile regardless.
1073 m_icatUiForm.dataFileLoadBtn->setEnabled(true);
1074}
1075
1077// SLOTS for: "DataFile information"
1079
1085 if (m_icatUiForm.dataFileResultsTbl->selectionModel()->selection().indexes().empty()) {
1086 m_icatUiForm.dataFileDownloadBtn->setEnabled(false);
1087 m_icatUiForm.dataFileLoadBtn->setEnabled(false);
1088 }
1089}
1090
1095 QTableWidget *table = m_icatUiForm.dataFileResultsTbl;
1096
1097 for (int row = 0; row < table->rowCount(); ++row) {
1098 // Hide row by default, in order to show only relevant ones.
1099 table->setRowHidden(row, true);
1100
1101 // As we use checkboxes in "selectedDataFileNames" to obtain the row of the
1102 // file the user wants to download
1103 // the state of these checkboxes remain when filtered. Thus we un-check them
1104 // here to prevent accidently downloading.
1105 table->item(row, 0)->setCheckState(Qt::Unchecked);
1106
1107 QTableWidgetItem *item = table->item(row, headerIndexByName(table, "Name"));
1108 // Show the relevant rows depending on file extension. 0 index is "Filter
1109 // type..." so all will be shown.
1110 // Have to convert to lowercase as ".TXT", and ".txt" should be filtered as
1111 // the same.
1112 if (index == 0 || (item->text().toLower().contains(m_icatUiForm.dataFileFilterCombo->itemText(index).toLower()))) {
1113 table->setRowHidden(row, false);
1114 }
1115 }
1116}
1117
1122 QString downloadSavePath = QFileDialog::getExistingDirectory(this, tr("Select a directory to save data files."),
1123 m_downloadSaveDir, QFileDialog::ShowDirsOnly);
1124
1125 // The user has clicked "Open" and changed the path (and not clicked cancel).
1126 if (!downloadSavePath.isEmpty()) {
1127 // Set setting prior to saving.
1128 m_downloadSaveDir = downloadSavePath;
1129 // Save settings to store for use next time.
1130 saveSettings();
1131 // Download the selected dataFiles to the chosen directory.
1134 }
1135}
1136
1141 // Get the path(s) to the file that was downloaded (via HTTP) or is stored in
1142 // the archive.
1143 std::vector<std::string> filePaths = m_icatHelper->downloadDataFiles(
1145
1146 // Create & initialize the load algorithm we will use to load the file by path
1147 // to a workspace.
1148 auto loadAlgorithm = Mantid::API::AlgorithmManager::Instance().create("Load");
1149 loadAlgorithm->initialize();
1150
1151 // For all the files downloaded (or in archive) we want to load them.
1152 for (auto &filePath : filePaths) {
1153 if (filePath.empty())
1154 return;
1155 // Set the filename (path) of the algorithm to load from.
1156 loadAlgorithm->setPropertyValue("Filename", filePath);
1157 // Sets the output workspace to be the name of the file.
1158 loadAlgorithm->setPropertyValue("OutputWorkspace", Poco::Path(Poco::Path(filePath).getFileName()).getBaseName());
1159
1160 Poco::ActiveResult<bool> result(loadAlgorithm->executeAsync());
1161 while (!result.available()) {
1162 QCoreApplication::processEvents();
1163 }
1164 }
1165}
1166
1173void CatalogSearch::selectAllDataFiles(const bool &toggled) {
1174 QTableWidget *table = m_icatUiForm.dataFileResultsTbl;
1175
1176 // Used to gain easier access to table selection.
1177 QItemSelectionModel *selectionModel = table->selectionModel();
1178
1179 // Select or deselect all rows depending on toggle.
1180 if (toggled)
1181 table->selectAll();
1182 else
1183 selectionModel->select(selectionModel->selection(), QItemSelectionModel::Deselect);
1184
1185 // Check/un-check the checkboxes of each row.
1186 for (int row = 0; row < table->rowCount(); ++row) {
1187 if (toggled)
1188 table->item(row, 0)->setCheckState(Qt::Checked);
1189 else
1190 table->item(row, 0)->setCheckState(Qt::Unchecked);
1191 }
1192}
1193
1198void CatalogSearch::dataFileCheckboxSelected(QTableWidgetItem *item) {
1199 QTableWidget *table = m_icatUiForm.dataFileResultsTbl;
1200
1201 QTableWidgetItem *checkbox = table->item(item->row(), 0);
1202
1203 for (int col = 0; col < table->columnCount(); col++) {
1204 for (int row = 0; row < table->rowCount(); ++row) {
1205 if (checkbox->checkState()) {
1206 table->item(item->row(), 0)->setCheckState(Qt::Checked);
1207 table->item(item->row(), col)->setSelected(true);
1208 } else {
1209 table->item(item->row(), 0)->setCheckState(Qt::Unchecked);
1210 // There is no easier way to deselect an item...
1211 table->item(item->row(), col)->setSelected(false);
1212 }
1213 }
1214 }
1215}
1216
1221 QTableWidget *table = m_icatUiForm.dataFileResultsTbl;
1222
1223 for (int row = 0; row < table->rowCount(); ++row) {
1224 // We Uncheck here to prevent previously selected items staying selected
1225 // and to allow dataFileCheckboxSelected() to function correctly.
1226 if (!table->item(row, 0)->isSelected()) {
1227 table->item(row, 0)->setCheckState(Qt::Unchecked);
1228 }
1229 }
1230
1231 QModelIndexList indexes = table->selectionModel()->selectedRows();
1232
1233 for (int i = 0; i < indexes.count(); ++i) {
1234 int row = indexes.at(i).row();
1235 table->item(row, 0)->setCheckState(Qt::Checked);
1238 }
1239 // Disable load/download buttons if no datafile is selected.
1241}
1242
1248 QTableWidget *table = m_icatUiForm.dataFileResultsTbl;
1249 int byteColumn = headerIndexByName(table, "File size(bytes)");
1250
1251 if (column == headerIndexByName(table, "File size")) {
1252 // Convert cell value to int within the datamodel.
1253 // This allows us to sort by the specific column.
1254 for (int row = 0; row < table->rowCount(); row++) {
1255 auto *item = new QTableWidgetItem;
1256 item->setData(Qt::EditRole, table->item(row, byteColumn)->text().toInt());
1257 table->setItem(row, byteColumn, item);
1258 }
1259 table->sortByColumn(byteColumn);
1260 }
1261}
1262
1263} // namespace MantidWidgets
1264} // namespace MantidQt
double error
Definition: IndexPeaks.cpp:133
IPeaksWorkspace_sptr workspace
Definition: IndexPeaks.cpp:114
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
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.
void dateSelected(QDate date)
Update text field when date is selected.
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.
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.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
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:228
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
CatalogConfigService * makeCatalogConfigServiceAdapter(const T &adaptee, const std::string &key="icatDownload.mountPoint")