Mantid
Loading...
Searching...
No Matches
JobTreeView.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#include <QKeyEvent>
17#include <QStandardItemModel>
18#include <algorithm>
19
20namespace {
21QAbstractItemView::EditTriggers getEditTriggers() {
22 auto trigger =
23 QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed | QAbstractItemView::AnyKeyPressed;
24 return trigger;
25}
26} // namespace
27
29
30JobTreeView::JobTreeView(QStringList const &columnHeadings, Cell const &emptyCellStyle, QWidget *parent)
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()) {
34 setModel(&m_mainModel);
35 setHeaderLabels(columnHeadings);
36 setSelectionMode(QAbstractItemView::ExtendedSelection);
37 setEditTriggers(getEditTriggers());
38 setItemDelegate(new CellDelegate(this, *this, m_filteredModel, m_mainModel));
39 setContextMenuPolicy(Qt::ActionsContextMenu);
41}
42
43void JobTreeView::commitData(QWidget *editor) {
44 auto current_filtered_index = fromFilteredModel(currentIndex());
46 QTreeView::commitData(editor);
48 if (cellText != cellTextBefore) {
49 resizeColumnToContents(m_lastEdited.column());
50 m_hasEditorOpen = false;
52 cellText);
53 editAt(current_filtered_index);
54 }
55}
56
57void JobTreeView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) {
58 QTreeView::selectionChanged(selected, deselected);
59 if (!m_notifyee)
60 return;
62}
63
64void JobTreeView::filterRowsBy(std::unique_ptr<RowPredicate> predicate) {
65 m_filteredModel.setPredicate(std::move(predicate));
66 expandAll();
67}
68
70 m_filteredModel.setPredicate(std::unique_ptr<RowPredicate>(predicate));
71 expandAll();
72}
73
77}
78
80
81bool JobTreeView::edit(const QModelIndex &index, EditTrigger trigger, QEvent *event) {
83 m_hasEditorOpen = true;
84 return QTreeView::edit(index, trigger, event);
85}
86
88
89boost::optional<std::vector<Subtree>> JobTreeView::selectedSubtrees() const {
90 auto selected = selectedRowLocations();
91 std::sort(selected.begin(), selected.end());
92
93 auto selectedRows = std::vector<Row>();
94 selectedRows.reserve(selected.size());
95
96 std::transform(selected.cbegin(), selected.cend(), std::back_inserter(selectedRows),
97 [&](RowLocation const &location) -> Row { return Row(location, cellsAt(location)); });
98
99 auto extractSubtrees = ExtractSubtrees();
100 return extractSubtrees(selectedRows);
101}
102
103boost::optional<std::vector<RowLocation>> JobTreeView::selectedSubtreeRoots() const {
104 auto findSubtreeRoots = FindSubtreeRoots();
105 return findSubtreeRoots(selectedRowLocations());
106}
107
108bool JobTreeView::hasNoSelectedDescendants(QModelIndex const &index) const {
109 for (auto row = 0; row < m_filteredModel.rowCount(index); ++row) {
110 auto childIndex = m_filteredModel.index(row, 0, index);
111 if (selectionModel()->isSelected(childIndex))
112 return false;
113 else if (!hasNoSelectedDescendants(childIndex))
114 return false;
115 }
116 return true;
117}
118
119void JobTreeView::appendAllUnselectedDescendants(QModelIndexList &descendantsList, QModelIndex const &index) const {
120 for (auto row = 0; row < m_filteredModel.rowCount(index); ++row) {
121 auto childIndex = m_filteredModel.index(row, 0, index);
122 if (!selectionModel()->isSelected(childIndex))
123 descendantsList.append(childIndex);
124 appendAllUnselectedDescendants(descendantsList, childIndex);
125 }
126}
127
128void JobTreeView::setHintsForColumn(int column, std::unique_ptr<HintStrategy> hintStrategy) {
129 setItemDelegateForColumn(column, new HintingLineEditFactory(itemDelegate(), std::move(hintStrategy)));
130}
131
132void JobTreeView::setHintsForColumn(int column, HintStrategy *hintStrategy) {
133 setHintsForColumn(column, std::unique_ptr<HintStrategy>(hintStrategy));
134}
135
136QModelIndexList JobTreeView::findImplicitlySelected(QModelIndexList const &selectedRows) const {
137 auto implicitlySelected = QModelIndexList();
138 for (auto &&row : selectedRows) {
139 if (isExpanded(row)) {
141 appendAllUnselectedDescendants(implicitlySelected, row);
142 } else {
143 appendAllUnselectedDescendants(implicitlySelected, row);
144 }
145 }
146 return implicitlySelected;
147}
148
149std::vector<RowLocation> JobTreeView::selectedRowLocations() const {
150 auto selection = selectionModel()->selectedRows();
151 selection.append(findImplicitlySelected(selection));
152
153 std::vector<RowLocation> rowSelection;
154 rowSelection.reserve(selection.size());
155 std::transform(selection.begin(), selection.end(), std::back_inserter(rowSelection),
156 [&](QModelIndex const &index) -> RowLocation {
157 auto indexForMainModel = mapToMainModel(fromFilteredModel(index));
158 return rowLocation().atIndex(indexForMainModel);
159 });
160 return rowSelection;
161}
162
164
166
168
170
172
174
176
177void JobTreeView::removeRows(std::vector<RowLocation> rowsToRemove) {
178 std::sort(rowsToRemove.begin(), rowsToRemove.end());
179 for (auto rowIt = rowsToRemove.crbegin(); rowIt < rowsToRemove.crend(); ++rowIt)
180 removeRowAt(*rowIt);
181}
182
183Cell JobTreeView::cellAt(RowLocation location, int column) const {
184 auto const cellIndex = rowLocation().indexAt(location, column);
185 return m_adaptedMainModel.cellFromCellIndex(cellIndex);
186}
187
189 return hasEditorOpen() && fromFilteredModel(currentIndex()) == cellIndex;
190}
191
193 if (cellIndex.isValid() && isBeingEdited(cellIndex))
194 closePersistentEditor(cellIndex.untyped());
195}
196
198 if (!cell.isEditable())
200}
201
202void JobTreeView::setCellAt(RowLocation location, int column, Cell const &cell) {
203 auto const cellIndex = rowLocation().indexAt(location, column);
204 m_adaptedMainModel.setCellAtCellIndex(cellIndex, cell);
205 closeEditorIfCellIsUneditable(cellIndex, cell);
206}
207
208std::vector<Cell> JobTreeView::cellsAt(RowLocation const &location) const {
209 return m_adaptedMainModel.cellsAtRow(rowLocation().indexAt(location));
210}
211
213 std::vector<Cell> const &cells) {
214 m_adaptedMainModel.enumerateCellsInRow(firstCellOnRow, m_mainModel.columnCount(),
215 [&](QModelIndexForMainModel const &cellIndex, int column) -> void {
216 closeEditorIfCellIsUneditable(cellIndex, cells[column]);
217 });
218}
219
220void JobTreeView::setCellsAt(RowLocation const &location, std::vector<Cell> const &cells) {
221 auto firstCellOnRow = rowLocation().indexAt(location);
222 m_adaptedMainModel.setCellsAtRow(firstCellOnRow, cells);
223 closeAnyOpenEditorsOnUneditableCells(firstCellOnRow, cells);
224}
225
226void JobTreeView::replaceSubtreeAt(RowLocation const &rootToRemove, Subtree const &toInsert) {
227 auto const insertionParent = rootToRemove.parent();
228 auto insertionIndex = rootToRemove.rowRelativeToParent();
229 // Insert the new row first (to avoid possibility of an empty table, which
230 // will cause problems because it is not allowed and will insert an empty
231 // group which we don't want)
232 insertSubtreeAt(insertionParent, insertionIndex, toInsert);
233 // Now find the new index of the root we're replacing and remove it. It is
234 // now the sibling below.
235 auto originalRootIndexToRemove = rowLocation().indexAt(rootToRemove);
236 auto newRootIndexToRemove = below(originalRootIndexToRemove.untyped());
237 removeRowAt(rowLocation().atIndex(fromMainModel(newRootIndexToRemove)));
238}
239
240void JobTreeView::insertSubtreeAt(RowLocation const &parent, int index, Subtree const &subtree) {
242 build(parent, index, subtree);
243}
244
245void JobTreeView::appendSubtreesAt(RowLocation const &parent, std::vector<Subtree> subtrees) {
246 for (auto &&subtree : subtrees)
247 appendSubtreeAt(parent, subtree);
248}
249
250void JobTreeView::appendSubtreeAt(RowLocation const &parent, Subtree const &subtree) {
251 auto parentIndex = rowLocation().indexAt(parent);
252 insertSubtreeAt(parent, m_mainModel.rowCount(parentIndex.untyped()), subtree);
253}
254
255void JobTreeView::replaceRows(std::vector<RowLocation> replacementPoints, std::vector<Subtree> replacements) {
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();
260
261 for (; replacementPoint != replacementPoints.cend() && replacement != replacements.cend();
262 ++replacementPoint, ++replacement) {
263 replaceSubtreeAt(*replacementPoint, *replacement);
264 }
265
266 if (replacementPoints.size() > replacements.size())
267 for (; replacementPoint != replacementPoints.cend(); ++replacementPoint)
268 removeRowAt(*replacementPoint);
269 else if (replacementPoints.size() < replacements.size())
270 for (; replacement != replacements.cend(); ++replacement)
271 appendSubtreeAt(replacementPoints.back().parent(), *replacement);
272}
273
274void JobTreeView::setHeaderLabels(QStringList const &columnHeadings) {
275 m_mainModel.setHorizontalHeaderLabels(columnHeadings);
276
277 for (auto i = 0; i < model()->columnCount(); ++i)
278 resizeColumnToContents(i);
279}
280
281void JobTreeView::subscribe(JobTreeViewSubscriber *subscriber) { m_notifyee = subscriber; }
282
284
286 return areOnSameRow(mapToMainModel(fromFilteredModel(currentIndex())).untyped(), indexToRemove.untyped()) &&
288}
289
290QModelIndex JobTreeView::siblingIfExistsElseParent(QModelIndex const &index) const {
291 if (hasRowAbove(index)) {
292 return above(index);
293 } else if (hasRowBelow(index)) {
294 return below(index);
295 } else {
296 return index.parent();
297 }
298}
299
301 auto parentIndex = index.parent();
302 return m_mainModel.rowCount(parentIndex.untyped()) == 1;
303}
304
306 return isOnlyChildOfRoot(rowLocation().indexAt(index));
307}
308
310 return !index.parent().isValid() && isOnlyChild(index);
311}
312
314 auto indexToRemove = rowLocation().indexAt(location);
315 assertOrThrow(indexToRemove.isValid(), "removeRowAt: Attempted to remove the invisible root item.");
316 // We can't delete the only child of the invisible root
317 // for the main model unless we use removeAllRows()
318 if (isOnlyChildOfRoot(indexToRemove)) {
320 return;
321 }
322
323 if (rowRemovalWouldBeIneffective(indexToRemove)) {
324 // implies that indexToRemove corresponds to an index in the filtered model.
325 auto rowIndexToSwitchTo = siblingIfExistsElseParent(mapToFilteredModel(indexToRemove).untyped());
326 if (rowIndexToSwitchTo.isValid()) {
327 setCurrentIndex(rowIndexToSwitchTo);
328 } else {
329 resetFilter();
330 rowIndexToSwitchTo = siblingIfExistsElseParent(mapToFilteredModel(indexToRemove).untyped());
331 setCurrentIndex(rowIndexToSwitchTo);
332 }
333 }
334 m_adaptedMainModel.removeRowFrom(indexToRemove);
335}
336
339 auto firstChild = std::vector<int>{0};
340 while (!isOnlyChildOfRoot(firstChild)) {
341 removeRowAt(firstChild);
342 }
344}
345
347 auto const child = m_adaptedMainModel.insertEmptyChildRow(rowLocation().indexAt(parent), beforeRow);
349 return rowLocation().atIndex(child);
350}
351
352RowLocation JobTreeView::insertChildRowOf(RowLocation const &parent, int beforeRow, std::vector<Cell> const &cells) {
353 assertOrThrow(static_cast<int>(cells.size()) <= m_mainModel.columnCount(),
354 "Attempted to add row with more cells than columns. Increase "
355 "the number of columns by increasing the number of headings.");
356 auto child = m_adaptedMainModel.insertChildRow(rowLocation().indexAt(parent), beforeRow,
357 paddedCellsToWidth(cells, g_deadCell, m_mainModel.columnCount()));
359 return rowLocation().atIndex(child);
360}
361
362Cell const JobTreeView::g_deadCell = Cell("", "white", 0, "transparent", 0, false);
363
366}
367
368RowLocation JobTreeView::appendChildRowOf(RowLocation const &parent, std::vector<Cell> const &cells) {
369 auto parentIndex = rowLocation().indexAt(parent);
370 return rowLocation().atIndex(
371 m_adaptedMainModel.appendChildRow(parentIndex, paddedCellsToWidth(cells, g_deadCell, m_mainModel.columnCount())));
372}
373
375 if (isEditable(index.untyped())) {
376 QTreeView::clearSelection();
377 setCurrentIndex(index.untyped());
378 edit(index.untyped());
379 }
380}
381
382void JobTreeView::clearSelection() { QTreeView::clearSelection(); }
383
384void JobTreeView::expandAll() { QTreeView::expandAll(); }
385
386void JobTreeView::collapseAll() { QTreeView::collapseAll(); }
387
389 auto expandAt = index.untyped();
390 while (expandAt.isValid()) {
391 setExpanded(expandAt, true);
392 expandAt = m_filteredModel.parent(expandAt);
393 }
394 return index;
395}
396
398
400
401std::pair<QModelIndexForFilteredModel, bool>
403 if (hasRowBelow(index.untyped())) {
404 return std::make_pair(fromFilteredModel(below(index.untyped())), false);
405 } else {
406 auto indexForModel = mapToMainModel(index);
407 resetFilter();
408 auto newIndex = m_adaptedMainModel.appendEmptySiblingRow(indexForModel);
409 return std::make_pair(mapToFilteredModel(newIndex), true);
410 }
411}
412
414 return QModelIndexForMainModel(m_filteredModel.mapToSource(filteredModelIndex.untyped()));
415}
416
418 return QModelIndexForFilteredModel(m_filteredModel.mapFromSource(mainModelIndex.untyped()));
419}
420
422 resetFilter();
423 auto const parent = mapToMainModel(fromFilteredModel(currentIndex()));
424 auto const child = m_adaptedMainModel.appendEmptyChildRow(parent);
425 m_notifyee->notifyRowInserted(rowLocation().atIndex(child));
427}
428
430 auto current = currentIndex();
431 setCurrentIndex(QModelIndex());
432 setCurrentIndex(current);
433 if (current != m_mainModel.index(-1, -1)) {
434 auto const cell = findOrMakeCellBelow(fromFilteredModel(current));
435 auto index = cell.first;
436 auto isNew = cell.second;
437
438 if (isNew) {
440 }
441 editAt(index);
442 }
443}
444
446 if (hasRowAbove(currentIndex()))
447 editAt(fromFilteredModel(above(currentIndex())));
448}
449
451 m_filteredModel.setDynamicSortFilter(false);
452 m_filteredModel.setSourceModel(&m_mainModel);
453 setModel(&m_filteredModel);
454}
455
456void JobTreeView::keyPressEvent(QKeyEvent *event) {
457 switch (event->key()) {
458 case Qt::Key_I:
459 if (event->modifiers() & Qt::ControlModifier) {
461 }
462 break;
463 case Qt::Key_Return:
464 case Qt::Key_Enter: {
465 if (event->modifiers() & Qt::ShiftModifier) {
467 } else {
469 }
470 break;
471 }
472 case Qt::Key_Delete:
474 break;
475 case Qt::Key_C: {
476 if (event->modifiers() & Qt::ControlModifier) {
478 }
479 break;
480 }
481 case Qt::Key_V: {
482 if (event->modifiers() & Qt::ControlModifier) {
484 }
485 break;
486 }
487 case Qt::Key_X: {
488 if (event->modifiers() & Qt::ControlModifier) {
490 }
491 break;
492 }
493 default:
494 QTreeView::keyPressEvent(event);
495 }
496}
497
498QModelIndexForMainModel JobTreeView::fromMainModel(QModelIndex const &mainModelIndex) const {
499 return ::MantidQt::MantidWidgets::Batch::fromMainModel(mainModelIndex, m_mainModel);
500}
501
502QModelIndexForFilteredModel JobTreeView::fromFilteredModel(QModelIndex const &filteredModelIndex) const {
503 return ::MantidQt::MantidWidgets::Batch::fromFilteredModel(filteredModelIndex, m_filteredModel);
504}
505
506bool JobTreeView::isEditable(QModelIndex const &index) const { return index.flags() & Qt::ItemIsEditable; }
507
509 auto result = navigation().moveCursorNext(startingPoint);
510 while (!result.first && result.second.isValid() && !isEditable(result.second))
511 result = navigation().moveCursorNext(result.second);
512 return result;
513}
514
515QModelIndex JobTreeView::movePreviousUntilEditable(QModelIndex const &startingPoint) {
516 auto currentIndex = navigation().moveCursorPrevious(startingPoint);
517 while (currentIndex.isValid() && !isEditable(currentIndex))
518 currentIndex = navigation().moveCursorPrevious(currentIndex);
519 return currentIndex;
520}
521
522QModelIndex JobTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) {
523 if (cursorAction == QAbstractItemView::MoveNext)
524 return applyNavigationResult(moveNextUntilEditable(currentIndex()));
525 else if (cursorAction == QAbstractItemView::MovePrevious)
526 return movePreviousUntilEditable(currentIndex());
527 else
528 return QTreeView::moveCursor(cursorAction, modifiers);
529}
530
532 auto shouldMakeNewRowBelow = result.first;
533 if (shouldMakeNewRowBelow) {
534 // `newCellIndex` is the model index of the cell in the new row with a
535 // column which matches
536 // the column currently selected by the user. To correctly get the
537 // RowLocation we need the
538 // model index of the first cell in the new row.
540 auto newRowIndex = fromMainModel(firstCellOnRowOf(newCellIndex.untyped()));
541
542 // Resetting the filter ensures that the new row is visible and has a
543 // corresponding index in
544 // the filtered model.
545 resetFilter();
546
547 auto newRowLocation = rowLocation().atIndex(newRowIndex);
548 m_notifyee->notifyRowInserted(newRowLocation);
549
550 // The subscriber is entitled to remove the row at `newRowIndex` when we
551 // call
552 // `notifyRowInserted` hence we have to assume they did and try to get the
553 // index again.
554 auto maybeIndexOfNewRow = rowLocation().indexIfExistsAt(newRowLocation);
555 if (maybeIndexOfNewRow.is_initialized()) {
556 return expanded(mapToFilteredModel(maybeIndexOfNewRow.get())).untyped();
557 } else {
558 return QModelIndex();
559 }
560 } else {
561 return result.second;
562 }
563}
564
565int JobTreeView::currentColumn() const { return currentIndex().column(); }
566
567} // namespace MantidQt::MantidWidgets::Batch
void assertOrThrow(bool condition, std::string const &message)
See the developer documentation for Batch Widget at developer.mantidproject.org/BatchWidget/index....
Definition: AssertOrThrow.h:15
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
std::string const & contentText() const
Definition: Cell.cpp:23
void setPredicate(std::unique_ptr< RowPredicate > predicate)
virtual void notifyRowInserted(RowLocation const &newRowLocation)=0
virtual void notifyRemoveRowsRequested(std::vector< RowLocation > const &locationsOfRowsToRemove)=0
virtual void notifyCellTextChanged(RowLocation const &itemIndex, int column, std::string const &oldValue, std::string const &newValue)=0
QtTreeCursorNavigation navigation() const
void appendAllUnselectedDescendants(QModelIndexList &selectedRows, QModelIndex const &index) const
void appendSubtreesAt(RowLocation const &parent, std::vector< Subtree > subtrees) override
RowLocation appendChildRowOf(RowLocation const &parent) override
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override
Definition: JobTreeView.cpp:57
bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event) override
Definition: JobTreeView.cpp:81
JobTreeView(QStringList const &columnHeadings, Cell const &defaultCellStyle, QWidget *parent=nullptr)
Definition: JobTreeView.cpp:30
QModelIndexForFilteredModel fromFilteredModel(QModelIndex const &filteredModelIndex) const
QModelIndex siblingIfExistsElseParent(QModelIndex const &index) const
void closeAnyOpenEditorsOnUneditableCells(QModelIndexForMainModel const &firstCellOnRow, std::vector< Cell > const &cells)
QModelIndexForFilteredModel mapToFilteredModel(QModelIndexForMainModel const &mainModelIndex) const
QModelIndex movePreviousUntilEditable(QModelIndex const &startingPoint)
QModelIndexList findImplicitlySelected(QModelIndexList const &selectedRows) const
bool isOnlyChildOfRoot(RowLocation const &location) const override
void closeEditorIfCellIsUneditable(QModelIndexForMainModel const &cellIndex, Cell const &cell)
bool rowRemovalWouldBeIneffective(QModelIndexForMainModel const &indexToRemove) const
QtStandardItemTreeModelAdapter m_adaptedMainModel
Definition: JobTreeView.h:144
std::vector< RowLocation > selectedRowLocations() const override
QModelIndexForFilteredModel expanded(QModelIndexForFilteredModel const &index)
void setHeaderLabels(QStringList const &columnHeadings)
void insertSubtreeAt(RowLocation const &parent, int index, Subtree const &subtree) override
Cell cellAt(RowLocation location, int column) const override
QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) override
bool hasNoSelectedDescendants(QModelIndex const &index) const
QModelIndex applyNavigationResult(QtTreeCursorNavigationResult const &result)
QtTreeCursorNavigationResult moveNextUntilEditable(QModelIndex const &startingPoint)
void subscribe(JobTreeViewSubscriber *subscriber) override
boost::optional< std::vector< Subtree > > selectedSubtrees() const override
Definition: JobTreeView.cpp:89
bool isBeingEdited(QModelIndexForFilteredModel const &cellIndex) const
void removeRowAt(RowLocation const &location) override
bool isOnlyChild(QModelIndexForMainModel const &index) const
bool isEditable(const QModelIndex &index) const
void closeEditorIfOpenAtCell(QModelIndexForFilteredModel const &cellIndex)
RowLocationAdapter rowLocation() const
QModelIndexForMainModel mapToMainModel(QModelIndexForFilteredModel const &filteredModelIndex) const
void replaceRows(std::vector< RowLocation > replacementPoints, std::vector< Subtree > replacements) override
boost::optional< std::vector< RowLocation > > selectedSubtreeRoots() const override
void replaceSubtreeAt(RowLocation const &rootToRemove, Subtree const &toInsert) override
void appendSubtreeAt(RowLocation const &parent, Subtree const &subtree) override
RowLocation insertChildRowOf(RowLocation const &parent, int beforeRow, std::vector< Cell > const &rowText) override
std::pair< QModelIndexForFilteredModel, bool > findOrMakeCellBelow(QModelIndexForFilteredModel const &index)
QModelIndexForMainModel fromMainModel(QModelIndex const &mainModelIndex) const
void setHintsForColumn(int column, std::unique_ptr< HintStrategy > hintStrategy) override
void setCellsAt(RowLocation const &location, std::vector< Cell > const &rowText) override
void editAt(QModelIndexForFilteredModel const &index)
void filterRowsBy(std::unique_ptr< RowPredicate > predicate) override
Definition: JobTreeView.cpp:64
std::vector< Cell > cellsAt(RowLocation const &location) const override
void keyPressEvent(QKeyEvent *event) override
void setCellAt(RowLocation location, int column, Cell const &cellText) override
void removeRows(std::vector< RowLocation > rowsToRemove) override
void setCellAtCellIndex(QModelIndexForMainModel const &index, Cell const &newCellProperties)
QModelIndexForMainModel appendEmptyChildRow(QModelIndexForMainModel const &parent)
QModelIndexForMainModel appendChildRow(QModelIndexForMainModel const &parent, std::vector< Cell > const &cells)
void setCellsAtRow(QModelIndexForMainModel const &rowIndex, std::vector< Cell > const &cells)
QModelIndexForMainModel appendEmptySiblingRow(QModelIndexForMainModel const &index)
std::vector< Cell > cellsAtRow(QModelIndexForMainModel const &firstCellIndex) const
QModelIndexForMainModel insertChildRow(QModelIndexForMainModel const &parent, int row, std::vector< Cell > const &cells)
QModelIndexForMainModel insertEmptyChildRow(QModelIndexForMainModel const &parent, int column)
void enumerateCellsInRow(QModelIndexForMainModel const &startIndex, int columns, Action const &action) const
Enumerates the first columnCount number of cells to the right of startAtCell, moving left to right.
Cell cellFromCellIndex(QModelIndexForMainModel const &index) const
QtTreeCursorNavigationResult moveCursorNext(QModelIndex const &currentIndex) const
QModelIndex moveCursorPrevious(QModelIndex const &currentIndex) const
RowLocation atIndex(QModelIndexForMainModel const &index) const
boost::optional< QModelIndexForMainModel > indexIfExistsAt(RowLocation const &location, int column=0) const
QModelIndexForMainModel indexAt(RowLocation const &location, int column=0) const
HintStrategy : Provides an interface for generating hints to be used by a HintingLineEdit.
Definition: HintStrategy.h:19
HintingLineEditFactory : A QStyledItemDelegate that produces HintingLineEdits using the given hint st...
std::pair< bool, QModelIndex > QtTreeCursorNavigationResult
EXPORT_OPT_MANTIDQT_COMMON std::vector< Cell > paddedCellsToWidth(std::vector< Cell > const &cells, Cell const &paddingCell, int paddedWidth)
Definition: Cell.cpp:95
bool hasRowAbove(QModelIndex const &index)
std::vector< Row > Subtree
Definition: Subtree.h:18
QModelIndex firstCellOnRowOf(QModelIndex const &index)
bool hasRowBelow(QModelIndex const &index)
QModelIndex above(QModelIndex const &index)
QModelIndex below(QModelIndex const &index)
bool areOnSameRow(QModelIndex const &a, QModelIndex const &b)