Newer
Older
#include "MantidQtCustomInterfaces/QReflTableModel.h"
#include "MantidAPI/ITableWorkspace.h"
#include "MantidAPI/TableRow.h"
namespace MantidQt
{
namespace CustomInterfaces
{
using namespace Mantid::API;
const QString QReflTableModel::RUNS = "Run(s)";
const QString QReflTableModel::ANGLE = "Angle";
const QString QReflTableModel::TRANSMISSION = "Transmission Run(s)";
const QString QReflTableModel::QMIN = "Q min";
const QString QReflTableModel::QMAX = "Q max";
const QString QReflTableModel::DQQ = "dQ/Q";
const QString QReflTableModel::SCALE = "Scale";
const QString QReflTableModel::GROUP = "Group";
const QString QReflTableModel::OPTIONS = "Options";
const int QReflTableModel::COL_RUNS(0);
const int QReflTableModel::COL_ANGLE(1);
const int QReflTableModel::COL_TRANSMISSION(2);
const int QReflTableModel::COL_QMIN(3);
const int QReflTableModel::COL_QMAX(4);
const int QReflTableModel::COL_DQQ(5);
const int QReflTableModel::COL_SCALE(6);
const int QReflTableModel::COL_GROUP(7);
//----------------------------------------------------------------------------------------------
/** Constructor
@param tableWorkspace : The table workspace to wrap
QReflTableModel::QReflTableModel(ITableWorkspace_sptr tableWorkspace) : m_dataCachePeakIndex(-1), m_tWS(tableWorkspace)
m_columnNameMap.insert(std::make_pair(COL_RUNS, RUNS));
m_columnNameMap.insert(std::make_pair(COL_ANGLE, ANGLE));
m_columnNameMap.insert(std::make_pair(COL_TRANSMISSION, TRANSMISSION));
m_columnNameMap.insert(std::make_pair(COL_QMIN, QMIN));
m_columnNameMap.insert(std::make_pair(COL_QMAX, QMAX));
m_columnNameMap.insert(std::make_pair(COL_DQQ, DQQ));
m_columnNameMap.insert(std::make_pair(COL_SCALE, SCALE));
m_columnNameMap.insert(std::make_pair(COL_GROUP, GROUP));
m_columnNameMap.insert(std::make_pair(COL_OPTIONS, OPTIONS));
}
//----------------------------------------------------------------------------------------------
/** Destructor
*/
QReflTableModel::~QReflTableModel()
{
}
/**
Invalidate the cache for a row
@param row : the row the cache needs to be invalidated for
*/
void QReflTableModel::invalidateDataCache(const int row) const
{
//If the row is in the cache, invalidate the cache.
if(row == m_dataCachePeakIndex || row == -1)
/**
Load data into the cache if required
@param row : to check and load if required
*/
void QReflTableModel::updateDataCache(const int row) const
{
// if the index is what is already cached just return
if (row == m_dataCachePeakIndex)
return;
TableRow tableRow = m_tWS->getRow(row);
// generate the cache
m_dataCache.clear();
m_dataCache.push_back(QString::fromStdString(tableRow.cell<std::string>(COL_RUNS)));
m_dataCache.push_back(QString::fromStdString(tableRow.cell<std::string>(COL_ANGLE)));
m_dataCache.push_back(QString::fromStdString(tableRow.cell<std::string>(COL_TRANSMISSION)));
m_dataCache.push_back(QString::fromStdString(tableRow.cell<std::string>(COL_QMIN)));
m_dataCache.push_back(QString::fromStdString(tableRow.cell<std::string>(COL_QMAX)));
m_dataCache.push_back(QString::fromStdString(tableRow.cell<std::string>(COL_DQQ)));
m_dataCache.push_back(QString::number(tableRow.cell<double>(COL_SCALE)));
m_dataCache.push_back(QString::number(tableRow.cell<int>(COL_GROUP)));
m_dataCache.push_back(QString::fromStdString(tableRow.cell<std::string>(COL_OPTIONS)));
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
m_dataCachePeakIndex = row;
}
/**
Update the model.
*/
void QReflTableModel::update()
{
emit layoutChanged(); //This should tell the view that the data has changed.
}
/**
@return the row count.
*/
int QReflTableModel::rowCount(const QModelIndex &) const
{
return static_cast<int>(m_tWS->rowCount());
}
/**
@return the number of columns in the model.
*/
int QReflTableModel::columnCount(const QModelIndex &) const
{
return static_cast<int>(m_columnNameMap.size());
}
/**
Find the column name at a given column index.
@param colIndex : Index to find column name for.
*/
QString QReflTableModel::findColumnName(const int colIndex) const
{
ColumnIndexNameMap::const_iterator foundColName = m_columnNameMap.find(colIndex);
if(foundColName == m_columnNameMap.end())
{
throw std::runtime_error("Unknown column requested");
}
return foundColName->second;
}
/**
Overrident data method, allows consuming view to extract data for an index and role.
@param index : For which to extract the data
@param role : Role mode
*/
QVariant QReflTableModel::data(const QModelIndex &index, int role) const
{
if(role == Qt::TextAlignmentRole)
if(index.column() == COL_OPTIONS)
return Qt::AlignLeft;
else
return Qt::AlignRight;
else if(role != Qt::DisplayRole && role != Qt::EditRole)
const int colNumber = index.column();
const int rowNumber = index.row();
this->updateDataCache(rowNumber);
return m_dataCache[colNumber];
}
/**
Overrident setData method, allows view to set data for an index and role.
@param index : For which to extract the data
@param role : Role mode
@returns booean true if sucessful, false if unsucessful.
*/
bool QReflTableModel::setData ( const QModelIndex & index, const QVariant & value, int role)
{
//Users may mistakenly enter whitespace. Let's strip it for them.
QString str = value.toString().trimmed();
if (index.isValid() && role == Qt::EditRole)
{
const int colNumber = index.column();
const int rowNumber = index.row();
switch(colNumber)
case COL_GROUP:
m_tWS->Int(rowNumber, COL_GROUP) = str.toInt(); break;
case COL_SCALE:
m_tWS->Double(rowNumber, COL_SCALE) = str.toDouble(); break;
default:
m_tWS->String(rowNumber, colNumber) = str.toStdString(); break;
invalidateDataCache(rowNumber);
emit dataChanged(index, index);
return true;
}
return false;
}
/**
Get the heading for a given section, orientation and role.
@param section : Column index
@param orientation : Heading orientation
@param role : Role mode of table.
@return HeaderData.
*/
QVariant QReflTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if(role == Qt::WhatsThisRole && orientation == Qt::Horizontal)
switch(section)
{
case COL_RUNS:
return QString(
"<b>Sample runs to be processed.</b><br />"
"<i>required</i><br />"
"Runs may be given as run numbers or workspace names. "
"Multiple runs may be added together by separating them with a '+'. "
"<br /><br /><b>Example:</b> <samp>1234+1235+1236</samp>"
);
case COL_ANGLE:
return QString(
"<b>Angle used during the run.</b><br />"
"<i>optional</i><br />"
"Unit: degrees<br />"
"If left blank, this is set to the last value for 'THETA' in the run's sample log. "
"If multiple runs were given in the Run(s) column, the first listed run's sample log will be used. "
"<br /><br /><b>Example:</b> <samp>0.7</samp>"
);
case COL_TRANSMISSION:
return QString(
"<b>Transmission run(s) to use to normalise the sample runs.</b><br />"
"<i>optional</i><br />"
"To specify two transmission runs, separate them with a comma. "
"If left blank, the sample runs will be normalised by monitor only."
"<br /><br /><b>Example:</b> <samp>1234,12345</samp>"
);
case COL_QMIN:
return QString(
"<b>Minimum value of Q to be used</b><br />"
"<i>optional</i><br />"
"Unit: Å<sup>-1</sup><br />"
"Data with a value of Q lower than this will be discarded. "
"If left blank, this is set to the lowest Q value found. "
"This is useful for discarding noisy data. "
"<br /><br /><b>Example:</b> <samp>0.1</samp>"
);
case COL_QMAX:
return QString(
"<b>Maximum value of Q to be used</b><br />"
"<i>optional</i><br />"
"Unit: Å<sup>-1</sup><br />"
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
"Data with a value of Q higher than this will be discarded. "
"If left blank, this is set to the highest Q value found. "
"This is useful for discarding noisy data. "
"<br /><br /><b>Example:</b> <samp>0.9</samp>"
);
case COL_DQQ:
return QString(
"<b>Resolution used when rebinning</b><br />"
"<i>optional</i><br />"
"If left blank, this is calculated for you using the CalculateResolution algorithm. "
"<br /><br /><b>Example:</b> <samp>0.9</samp>"
);
case COL_SCALE:
return QString(
"<b>Scaling factor</b><br />"
"<i>required</i><br />"
"The created IvsQ workspaces will be Scaled by <samp>1/i</samp> where <samp>i</samp> is the value of this column."
"<br /><br /><b>Example:</b> <samp>1</samp>"
);
case COL_GROUP:
return QString(
"<b>Grouping for stitching</b><br />"
"<i>required</i><br />"
"The value of this column determines which other rows this row's output will be stitched with. "
"All rows with the same group number are stitched together. "
);
case COL_OPTIONS:
return QString(
"<b>Override <samp>ReflectometryReductionOneAuto</samp> properties</b><br />"
"<i>optional</i><br />"
"This column allows you to override the properties used when executing <samp>ReflectometryReductionOneAuto</samp>. "
"Options are given as key=value pairs, separated by commas. "
"Values containing commas must be quoted."
"<br /><br /><b>Example:</b> <samp>StrictSpectrumChecking=0, RegionOfDirectBeam=\"0,2\", Params=\"1,2,3\"</samp>"
);
default:
return QVariant();
}
else if(role == Qt::DisplayRole)
if(orientation == Qt::Horizontal)
return findColumnName(section);
if(orientation == Qt::Vertical)
return QString::number(section + 1);
return QVariant();
}
/**
Provide flags on an index by index basis
@param index: To generate a flag for.
*/
Qt::ItemFlags QReflTableModel::flags(const QModelIndex &index) const
{
if (!index.isValid()) return 0;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
/**
Insert the given number of rows at the specified position
@param row : The row to insert before
@param count : The number of rows to insert
@param parent : The parent index
*/
bool QReflTableModel::insertRows(int row, int count, const QModelIndex& parent)
{
if(count < 1)
return true;
if(row < 0)
return false;
beginInsertRows(parent, row, row + count - 1);
for(int i = 0; i < count; ++i)
m_tWS->insertRow(row + i);
endInsertRows();
invalidateDataCache(-1);
return true;
}
/**
Remove the given number of rows from the specified position
@param row : The row index to remove from
@param count : The number of rows to remove
@param parent : The parent index
*/
bool QReflTableModel::removeRows(int row, int count, const QModelIndex& parent)
{
if(count < 1)
return true;
if(row < 0)
return false;
beginRemoveRows(parent, row, row + count - 1);
for(int i = 0; i < count; ++i)
m_tWS->removeRow(row);
endRemoveRows();
invalidateDataCache(-1);
return true;
}
} // namespace CustomInterfaces
} // namespace Mantid