17#include <QStandardItemModel>
21QAbstractItemView::EditTriggers getEditTriggers() {
23 QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed | QAbstractItemView::AnyKeyPressed;
31 : QTreeView(parent), m_notifyee(nullptr), m_mainModel(0, columnHeadings.size(), this),
32 m_adaptedMainModel(m_mainModel, emptyCellStyle), m_filteredModel(
RowLocationAdapter(m_mainModel), this),
33 m_lastEdited(QModelIndex()) {
36 setSelectionMode(QAbstractItemView::ExtendedSelection);
37 setEditTriggers(getEditTriggers());
39 setContextMenuPolicy(Qt::ActionsContextMenu);
46 QTreeView::commitData(editor);
48 if (cellText != cellTextBefore) {
53 editAt(current_filtered_index);
58 QTreeView::selectionChanged(selected, deselected);
84 return QTreeView::edit(
index, trigger, event);
91 std::sort(selected.begin(), selected.end());
93 auto selectedRows = std::vector<Row>();
94 selectedRows.reserve(selected.size());
96 std::transform(selected.cbegin(), selected.cend(), std::back_inserter(selectedRows),
97 [&](
RowLocation const &location) ->
Row { return Row(location, cellsAt(location)); });
100 return extractSubtrees(selectedRows);
111 if (selectionModel()->isSelected(childIndex))
122 if (!selectionModel()->isSelected(childIndex))
123 descendantsList.append(childIndex);
137 auto implicitlySelected = QModelIndexList();
138 for (
auto &&row : selectedRows) {
139 if (isExpanded(row)) {
146 return implicitlySelected;
150 auto selection = selectionModel()->selectedRows();
153 std::vector<RowLocation> rowSelection;
154 rowSelection.reserve(selection.size());
155 std::transform(selection.begin(), selection.end(), std::back_inserter(rowSelection),
157 auto indexForMainModel = mapToMainModel(fromFilteredModel(index));
158 return rowLocation().atIndex(indexForMainModel);
178 std::sort(rowsToRemove.begin(), rowsToRemove.end());
179 for (
auto rowIt = rowsToRemove.crbegin(); rowIt < rowsToRemove.crend(); ++rowIt)
194 closePersistentEditor(cellIndex.
untyped());
213 std::vector<Cell>
const &cells) {
216 closeEditorIfCellIsUneditable(cellIndex, cells[column]);
227 auto const insertionParent = rootToRemove.
parent();
236 auto newRootIndexToRemove =
below(originalRootIndexToRemove.untyped());
242 build(parent,
index, subtree);
246 for (
auto &&subtree : subtrees)
256 assertOrThrow(replacementPoints.size() > 0,
"replaceRows: Passed an empty list of replacement points."
257 "At least one replacement point is required.");
258 auto replacementPoint = replacementPoints.cbegin();
259 auto replacement = replacements.cbegin();
261 for (; replacementPoint != replacementPoints.cend() && replacement != replacements.cend();
262 ++replacementPoint, ++replacement) {
266 if (replacementPoints.size() > replacements.size())
267 for (; replacementPoint != replacementPoints.cend(); ++replacementPoint)
269 else if (replacementPoints.size() < replacements.size())
270 for (; replacement != replacements.cend(); ++replacement)
275 m_mainModel.setHorizontalHeaderLabels(columnHeadings);
277 for (
auto i = 0; i < model()->columnCount(); ++i)
278 resizeColumnToContents(i);
296 return index.parent();
301 auto parentIndex =
index.parent();
302 return m_mainModel.rowCount(parentIndex.untyped()) == 1;
315 assertOrThrow(indexToRemove.isValid(),
"removeRowAt: Attempted to remove the invisible root item.");
326 if (rowIndexToSwitchTo.isValid()) {
327 setCurrentIndex(rowIndexToSwitchTo);
331 setCurrentIndex(rowIndexToSwitchTo);
339 auto firstChild = std::vector<int>{0};
354 "Attempted to add row with more cells than columns. Increase "
355 "the number of columns by increasing the number of headings.");
376 QTreeView::clearSelection();
377 setCurrentIndex(
index.untyped());
389 auto expandAt =
index.untyped();
390 while (expandAt.isValid()) {
391 setExpanded(expandAt,
true);
401std::pair<QModelIndexForFilteredModel, bool>
430 auto current = currentIndex();
431 setCurrentIndex(QModelIndex());
432 setCurrentIndex(current);
435 auto index = cell.first;
436 auto isNew = cell.second;
457 switch (event->key()) {
459 if (event->modifiers() & Qt::ControlModifier) {
464 case Qt::Key_Enter: {
465 if (event->modifiers() & Qt::ShiftModifier) {
476 if (event->modifiers() & Qt::ControlModifier) {
482 if (event->modifiers() & Qt::ControlModifier) {
488 if (event->modifiers() & Qt::ControlModifier) {
494 QTreeView::keyPressEvent(event);
499 return ::MantidQt::MantidWidgets::Batch::fromMainModel(mainModelIndex,
m_mainModel);
503 return ::MantidQt::MantidWidgets::Batch::fromFilteredModel(filteredModelIndex,
m_filteredModel);
510 while (!result.first && result.second.isValid() && !
isEditable(result.second))
517 while (currentIndex.isValid() && !
isEditable(currentIndex))
523 if (cursorAction == QAbstractItemView::MoveNext)
525 else if (cursorAction == QAbstractItemView::MovePrevious)
528 return QTreeView::moveCursor(cursorAction, modifiers);
532 auto shouldMakeNewRowBelow = result.first;
533 if (shouldMakeNewRowBelow) {
555 if (maybeIndexOfNewRow.is_initialized()) {
558 return QModelIndex();
561 return result.second;
void assertOrThrow(bool condition, std::string const &message)
See the developer documentation for Batch Widget at developer.mantidproject.org/BatchWidget/index....
std::map< DeltaEMode::Type, std::string > index