/
InstrumentSelector.cpp
239 lines (213 loc) · 7.51 KB
/
InstrumentSelector.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
//------------------------------------------------------
// Includes
//------------------------------------------------------
#include "MantidQtMantidWidgets/InstrumentSelector.h"
#include "MantidKernel/ConfigService.h"
#include "MantidKernel/FacilityInfo.h"
#include "MantidKernel/InstrumentInfo.h"
#include "MantidKernel/Exception.h"
#include <QMessageBox>
#include <Poco/Notification.h>
#include <Poco/NotificationCenter.h>
#include <Poco/AutoPtr.h>
#include <Poco/NObserver.h>
namespace MantidQt
{
namespace MantidWidgets
{
using namespace Mantid::Kernel;
//------------------------------------------------------
// Public member functions
//------------------------------------------------------
/**
* Default constructor
* @param parent :: A widget to act as this widget's parent (default = NULL)
* @param init :: If true then the widget will be populated with the instrument list (default = true)
*/
InstrumentSelector::InstrumentSelector(QWidget *parent, bool init)
: QComboBox(parent), m_changeObserver(*this, &InstrumentSelector::handleConfigChange),
m_techniques(), m_currentFacility(NULL), m_init(init),m_storeChanges(true)
{
setEditable(false);
if( init )
{
fillWithInstrumentsFromFacility();
connect(this, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(updateDefaultInstrument(const QString &)));
connect(this, SIGNAL(currentIndexChanged(const QString &)), this, SIGNAL(instrumentSelectionChanged(const QString &)));
Mantid::Kernel::ConfigServiceImpl& config = Mantid::Kernel::ConfigService::Instance();
config.addObserver(m_changeObserver);
}
}
/**
* Destructor for InstrumentSelector
* De-subscribes this object from the Poco NotificationCentre
*/
InstrumentSelector::~InstrumentSelector()
{
if ( m_init )
{
Mantid::Kernel::ConfigService::Instance().removeObserver(m_changeObserver);
}
}
/**
* Return the list of techniques that are supported by the instruments in the widget
* @returns A list of supported techniques
*/
QStringList InstrumentSelector::getTechniques() const
{
return m_techniques;
}
/**
* Set the list of techniques
* @param techniques :: Only those instruments that support these techniques will be shown
*/
void InstrumentSelector::setTechniques(const QStringList & techniques)
{
m_techniques = techniques;
if( count() > 0 && m_currentFacility )
{
filterByTechniquesAtFacility(techniques, *m_currentFacility);
}
}
void InstrumentSelector::handleConfigChange(Mantid::Kernel::ConfigValChangeNotification_ptr pNf)
{
QString prop = QString::fromStdString(pNf->key());
QString newV = QString::fromStdString(pNf->curValue());
QString oldV = QString::fromStdString(pNf->preValue());
if ( newV != oldV )
{
if ( ( prop == "default.facility" ) && ( newV != QString::fromStdString(m_currentFacility->name()) ) )
{
fillWithInstrumentsFromFacility(newV);
}
else if ( ( prop == "default.instrument" ) && ( newV != this->currentText() ) )
{
this->setCurrentIndex(this->findText(newV));
}
}
}
//------------------------------------------------------
// Public slot member functions
//------------------------------------------------------
/**
* Populate list with instruments from the named facility. Note the current list is cleared.
* @param name :: The name of the facility whose instruments should be placed in the list. An empty string uses the default
* facility defined in Mantid.
*/
void InstrumentSelector::fillWithInstrumentsFromFacility(const QString & name)
{
ConfigServiceImpl & mantidSettings = ConfigService::Instance();
blockSignals(true);
clear();
blockSignals(false);
try
{
if( name.isEmpty() )
{
m_currentFacility = &(mantidSettings.getFacility());
}
else
{
m_currentFacility = &(mantidSettings.getFacility(name.toStdString()));
}
}
catch (Mantid::Kernel::Exception::NotFoundError&)
{
//could not find the facility
//pick the first facility from the valid list
m_currentFacility = &(mantidSettings.getFacility(mantidSettings.getFacilityNames()[0]));
}
const std::vector<InstrumentInfo> & instruments = m_currentFacility->instruments();
std::vector<InstrumentInfo>::const_iterator iend = instruments.end();
std::set<std::string> alphabetizedNames;
for( std::vector<InstrumentInfo>::const_iterator itr = instruments.begin(); itr != iend; ++itr )
{
alphabetizedNames.insert(itr->name());
}
std::set<std::string>::const_iterator namesEnd = alphabetizedNames.end();
for( std::set<std::string>::const_iterator itr = alphabetizedNames.begin(); itr != namesEnd; ++itr )
{
QString name = QString::fromStdString(*itr);
std::string prefix = m_currentFacility->instrument(*itr).shortName();
QString shortName = QString::fromStdString(prefix);
this->addItem(name, QVariant(shortName));
}
filterByTechniquesAtFacility(m_techniques, *m_currentFacility);
QString defaultName;
try
{
defaultName = QString::fromStdString(m_currentFacility->instrument().name());
}
catch( Exception::NotFoundError &)
{
defaultName = "";
}
int index = this->findText(defaultName);
if( index < 0 )
{
index = 0;
}
// Don't affect the default instrument
this->blockSignals(true);
this->setCurrentIndex(index);
this->blockSignals(false);
}
/**
* Sets whether to update the default instrument on selection change
* @param storeChanges :: True = store change on selection change
*/
void InstrumentSelector::updateInstrumentOnSelection(const bool storeChanges)
{
m_storeChanges = storeChanges;
}
//------------------------------------------------------
// Private slot member functions
//------------------------------------------------------
/**
* Set the named instrument as the default for Mantid
* @param name :: A string containing the new instrument to set as the default
*/
void InstrumentSelector::updateDefaultInstrument(const QString & name) const
{
if( !name.isEmpty() && m_storeChanges)
{
ConfigService::Instance().setString("default.instrument", name.toStdString());
}
}
//------------------------------------------------------
// Private non-slot member functions
//------------------------------------------------------
/**
* Filter the list to only show those supporting the given technique
* @param techniques :: A string list containing the names of a techniques to filter the instrument list by
* @param facility :: A FacilityInfo object
*/
void InstrumentSelector::filterByTechniquesAtFacility(const QStringList & techniques, const Mantid::Kernel::FacilityInfo & facility)
{
if( techniques.isEmpty() ) return;
QStringList supportedInstruments;
QStringListIterator techItr(techniques);
while( techItr.hasNext() )
{
const std::vector<InstrumentInfo> instruments = facility.instruments(techItr.next().toStdString());
const size_t nInstrs = instruments.size();
for( size_t i = 0; i < nInstrs; ++i )
{
supportedInstruments.append(QString::fromStdString(instruments[i].name()));
}
}
// Remove those not supported
for( int i = 0 ; i < this->count(); )
{
if( !supportedInstruments.contains(itemText(i)) )
{
removeItem(i);
}
else
{
++i;
}
}
}
} // namespace: MantidWidgets
} // namespace: MantidQt