Skip to content
Snippets Groups Projects
Commit 3573e478 authored by Edward Brown's avatar Edward Brown
Browse files

Added python bindings and polished JobTreeView API.

- Added BuildSubtreeTest - a replacement for the messy version in JobTreeView.
- Added additional methods for dealing with Subtree objects.
- Modified interface of the copy and paste signals presenters must now
  get selection explicitly.
- Exposed Row class to python.

Re #22263
parent 1044acdb
No related branches found
No related tags found
No related merge requests found
......@@ -20,6 +20,7 @@ qRegisterMetaType<std::string>();
/***************************************************************************/
/**************** Exceptions ***********************************************/
/***************************************************************************/
%Exception std::exception(SIP_Exception) /PyName=StdException/
{
%TypeHeaderCode
......@@ -1529,10 +1530,8 @@ public:
virtual void notifyRowInserted(const RowLocation& itemIndex) = 0;
virtual void notifyRemoveRowsRequested(
const std::vector<MantidQt::MantidWidgets::Batch::RowLocation>& locationsOfRowsToRemove) = 0;
virtual void notifyCopyRowsRequested(
const std::vector<MantidQt::MantidWidgets::Batch::RowLocation>& locationsOfRowsToCopy) = 0;
virtual void notifyPasteRowsRequested(
const std::vector<MantidQt::MantidWidgets::Batch::RowLocation>& locationsOfSelectedRows) = 0;
virtual void notifyCopyRowsRequested() = 0;
virtual void notifyPasteRowsRequested() = 0;
};
class JobTreeView : public QTreeView
......@@ -1553,16 +1552,36 @@ public:
void removeRowAt(const RowLocation &location);
void removeRows(std::vector<MantidQt::MantidWidgets::Batch::RowLocation> rowsToRemove);
void replaceRows(std::vector<MantidQt::MantidWidgets::Batch::RowLocation> regionToReplace,
std::vector<MantidQt::MantidWidgets::Batch::RowLocation> replacementLocations,
std::vector<std::vector<std::string>> replacementRowText);
void replaceRows(std::vector<MantidQt::MantidWidgets::Batch::RowLocation> replacementPoints,
std::vector<std::vector<MantidQt::MantidWidgets::Batch::Row>> replacementLocations);
void appendSubtreesAt(const RowLocation& parent,
std::vector<std::vector<MantidQt::MantidWidgets::Batch::Row>> subtrees);
void appendSubtreeAt(const RowLocation& parent,
std::vector<MantidQt::MantidWidgets::Batch::Row> subtree);
void replaceSubtreeAt(const RowLocation &rootToRemove,
std::vector<MantidQt::MantidWidgets::Batch::Row> subtree);
void insertSubtreeAt(const RowLocation& parent, int index,
std::vector<MantidQt::MantidWidgets::Batch::Row> subtree);
std::vector<std::string> rowTextAt(const RowLocation &location) const;
void setRowTextAt(const RowLocation &location,
const std::vector<std::string> &rowText);
std::string textAt(RowLocation location, int column);
void setTextAt(RowLocation location, int column, const std::string &cellText);
std::vector<MantidQt::MantidWidgets::Batch::RowLocation> selectedRowLocations() const;
boost::optional<std::vector<std::vector<MantidQt::MantidWidgets::Batch::Row>>> selectedSubtrees() const;
boost::optional<std::vector<MantidQt::MantidWidgets::Batch::RowLocation>> selectedSubtreeRoots() const;
};
class Row {
%TypeHeaderCode
#include "MantidQtWidgets/Common/Batch/Row.h"
%End
public:
Row(RowLocation location, std::vector<std::string> cells);
const std::vector<std::string>& cells() const;
const RowLocation& location() const;
};
class JobTreeViewSignalAdapter : public QObject, public MantidQt::MantidWidgets::Batch::JobTreeViewSubscriber {
......@@ -1576,10 +1595,8 @@ public:
virtual void notifyRowInserted(const MantidQt::MantidWidgets::Batch::RowLocation &itemIndex);
virtual void notifyRemoveRowsRequested(
const std::vector<MantidQt::MantidWidgets::Batch::RowLocation> &locationsOfRowsToRemove);
virtual void notifyCopyRowsRequested(
const std::vector<MantidQt::MantidWidgets::Batch::RowLocation> &locationsOfRowsToCopy);
virtual void notifyPasteRowsRequested(
const std::vector<MantidQt::MantidWidgets::Batch::RowLocation> &locationsOfSelectedRows);
virtual void notifyCopyRowsRequested();
virtual void notifyPasteRowsRequested();
signals:
void cellChanged(const MantidQt::MantidWidgets::Batch::RowLocation &itemIndex, int column,
std::string newValue);
......
......@@ -86,6 +86,7 @@ set ( SRC_FILES
src/Batch/QtStandardItemTreeAdapter.cpp
src/Batch/QtTreeCursorNavigation.cpp
src/Batch/CellDelegate.cpp
src/Batch/BuildSubtree.cpp
src/DataSelector.cpp
src/DiagResults.cpp
src/DoubleSpinBox.cpp
......@@ -403,6 +404,7 @@ set ( INC_FILES
inc/MantidQtWidgets/Common/Batch/CellDelegate.h
inc/MantidQtWidgets/Common/Batch/ExtractSubtrees.h
inc/MantidQtWidgets/Common/Batch/FindSubtreeRoots.h
inc/MantidQtWidgets/Common/Batch/BuildSubtree.h
)
set ( UI_FILES
......@@ -553,6 +555,7 @@ set( TEST_FILES
test/Batch/RowLocationTest.h
test/Batch/FindSubtreeRootsTest.h
test/Batch/ExtractSubtreesTest.h
test/Batch/BuildSubtreeTest.h
test/ParseKeyValueStringTest.h
test/DataProcessorUI/QOneLevelTreeModelTest.h
......
#ifndef MANTIDQTMANTIDWIDGETS_BUILDSUBTREE_H_
#define MANTIDQTMANTIDWIDGETS_BUILDSUBTREE_H_
#include "MantidQtWidgets/Common/Batch/AssertOrThrow.h"
#include "MantidQtWidgets/Common/DllOption.h"
#include "MantidQtWidgets/Common/Batch/Row.h"
#include "MantidQtWidgets/Common/Batch/QtStandardItemTreeAdapter.h"
#include <QStandardItem>
namespace MantidQt {
namespace MantidWidgets {
namespace Batch {
class EXPORT_OPT_MANTIDQT_COMMON BuildSubtree {
public:
using SubtreeConstIterator = typename Subtree::const_iterator;
BuildSubtree(QtStandardItemMutableTreeAdapter const&adaptedModel);
void operator()(QStandardItem *parentOfSubtreeRootItem,
RowLocation const &parentOfSubtreeRoot, int index,
Subtree const &subtree);
SubtreeConstIterator buildRecursively(QStandardItem *parentItem, int index,
RowLocation const &parent, int depth,
SubtreeConstIterator current,
SubtreeConstIterator end);
private:
QtStandardItemMutableTreeAdapter const&m_adaptedModel;
};
} // namespace Batch
} // namespace MantidWidgets
} // namespace MantidQt
#endif
#ifndef MANTIDQTMANTIDWIDGETS_JOBTREEVIEW_H_
#define MANTIDQTMANTIDWIDGETS_JOBTREEVIEW_H_
#include "MantidQtWidgets/Common/Batch/ExtractSubtrees.h"
#include "MantidQtWidgets/Common/Batch/QtStandardItemTreeAdapter.h"
#include "MantidQtWidgets/Common/Batch/QtTreeCursorNavigation.h"
#include "MantidQtWidgets/Common/Batch/RowLocation.h"
#include "MantidQtWidgets/Common/Batch/ExtractSubtrees.h"
#include "MantidQtWidgets/Common/DllOption.h"
#include <boost/optional.hpp>
......@@ -20,10 +20,8 @@ public:
virtual void notifyRowInserted(RowLocation const &newRowLocation) = 0;
virtual void notifyRemoveRowsRequested(
std::vector<RowLocation> const &locationsOfRowsToRemove) = 0;
virtual void notifyCopyRowsRequested(
std::vector<RowLocation> const &locationsOfRowsToCopy) = 0;
virtual void notifyPasteRowsRequested(
std::vector<RowLocation> const &locationsOfSelectedRows) = 0;
virtual void notifyCopyRowsRequested() = 0;
virtual void notifyPasteRowsRequested() = 0;
virtual ~JobTreeViewSubscriber() = default;
};
......@@ -50,20 +48,15 @@ public:
template <typename InputIterator>
void removeRows(InputIterator begin, InputIterator end);
void replaceRows(std::vector<RowLocation> regionToReplace,
std::vector<RowLocation> replacementLocations,
std::vector<std::vector<std::string>> replacementRowText);
void replaceSubtree(RowLocation const &rootToRemove,
typename ExtractSubtrees::Subtree const &toInsert);
void replaceRows(std::vector<RowLocation> replacementPoints,
std::vector<Subtree> replacements);
typename ExtractSubtrees::Subtree::const_iterator insertSubtreeRecursive(
RowLocation const &parent, int depth,
typename ExtractSubtrees::Subtree::const_iterator current,
typename ExtractSubtrees::Subtree::const_iterator end);
void appendSubtreesAt(RowLocation const& parent, std::vector<Subtree> subtrees);
void appendSubtreeAt(RowLocation const &parent, Subtree const &subtree);
void replaceSubtreeAt(RowLocation const &rootToRemove, Subtree const &toInsert);
void insertSubtreeAt(RowLocation const &parent, int index,
typename ExtractSubtrees::Subtree const &subtree);
Subtree const &subtree);
std::vector<std::string> rowTextAt(RowLocation const &location) const;
void setRowTextAt(RowLocation const &location,
......@@ -75,6 +68,8 @@ public:
QModelIndex moveCursor(CursorAction cursorAction,
Qt::KeyboardModifiers modifiers) override;
std::vector<RowLocation> selectedRowLocations() const;
boost::optional<std::vector<Subtree>> selectedSubtrees() const;
boost::optional<std::vector<RowLocation>> selectedSubtreeRoots() const;
using QTreeView::edit;
......
......@@ -17,10 +17,8 @@ public:
void notifyRowInserted(RowLocation const &newRowLocation) override;
void notifyRemoveRowsRequested(
std::vector<RowLocation> const &locationsOfRowsToRemove) override;
void notifyCopyRowsRequested(
std::vector<RowLocation> const &locationsOfRowsToCopy) override;
void notifyPasteRowsRequested(
std::vector<RowLocation> const &locationsOfSelectedRows) override;
void notifyCopyRowsRequested() override;
void notifyPasteRowsRequested() override;
signals:
void cellChanged(MantidQt::MantidWidgets::Batch::RowLocation const &itemIndex,
int column, std::string newValue);
......@@ -29,12 +27,8 @@ signals:
void removeRowsRequested(
std::vector<MantidQt::MantidWidgets::Batch::RowLocation> const &
locationsOfRowsToRemove);
void copyRowsRequested(
std::vector<MantidQt::MantidWidgets::Batch::RowLocation> const &
locationsOfRowsToRemove);
void pasteRowsRequested(
std::vector<MantidQt::MantidWidgets::Batch::RowLocation> const &
locationsOfSelectedRows);
void copyRowsRequested();
void pasteRowsRequested();
};
}
}
......
#include "MantidQtWidgets/Common/Batch/BuildSubtree.h"
#include <tuple>
namespace MantidQt {
namespace MantidWidgets {
namespace Batch {
BuildSubtree::BuildSubtree(QtStandardItemMutableTreeAdapter const &adaptedModel)
: m_adaptedModel(adaptedModel) {}
void BuildSubtree::operator()(QStandardItem *parentOfSubtreeRootItem,
RowLocation const &parentOfSubtreeRoot, int index,
Subtree const &subtree) {
if (!subtree.empty())
buildRecursively(parentOfSubtreeRootItem, index, parentOfSubtreeRoot, 0,
subtree.cbegin(), subtree.cend());
}
auto BuildSubtree::buildRecursively(QStandardItem *parentItem, int index,
RowLocation const &parent, int depth,
SubtreeConstIterator current,
SubtreeConstIterator end) -> SubtreeConstIterator {
parentItem->insertRow(index,
m_adaptedModel.rowFromRowText((*current).cells()));
++current;
while (current != end) {
auto currentRow = (*current).location();
auto currentDepth = currentRow.depth();
if (depth < currentDepth) {
current = buildRecursively(parentItem->child(index),
currentRow.rowRelativeToParent(),
parent.child(currentRow.rowRelativeToParent()),
depth + 1, current, end);
} else if (depth > currentDepth) {
return current;
} else {
parentItem->appendRow(m_adaptedModel.rowFromRowText((*current).cells()));
++current;
}
}
return end;
}
} // namespace Batch
} // namespace MantidWidgets
} // namespace MantidQt
......@@ -4,6 +4,7 @@
#include "MantidQtWidgets/Common/Batch/ExtractSubtrees.h"
#include "MantidQtWidgets/Common/Batch/FindSubtreeRoots.h"
#include "MantidQtWidgets/Common/Batch/QtTreeCursorNavigation.h"
#include "MantidQtWidgets/Common/Batch/BuildSubtree.h"
#include <QKeyEvent>
#include <QSortFilterProxyModel>
#include <QStandardItemModel>
......@@ -40,28 +41,55 @@ bool JobTreeView::edit(const QModelIndex &index, EditTrigger trigger,
return QTreeView::edit(index, trigger, event);
}
boost::optional<std::vector<Subtree>> JobTreeView::selectedSubtrees() const {
auto rows = selectedRowLocations();
std::sort(rows.begin(), rows.end());
auto selectedRowData = std::vector<std::vector<Cell>>();
selectedRowData.reserve(rows.size());
std::transform(rows.cbegin(), rows.cend(),
std::back_inserter(selectedRowData),
[&](RowLocation const &location)
-> std::vector<Cell> { return rowTextAt(location); });
auto extractSubtrees = ExtractSubtrees();
return extractSubtrees(rows, selectedRowData);
}
boost::optional<std::vector<RowLocation>>
JobTreeView::selectedSubtreeRoots() const {
auto findSubtreeRoots = FindSubtreeRoots();
return findSubtreeRoots(selectedRowLocations());
}
std::vector<RowLocation> JobTreeView::selectedRowLocations() const {
auto selection = selectionModel()->selectedRows();
std::vector<RowLocation> rowSelection;
rowSelection.reserve(selection.size());
std::transform(selection.begin(), selection.end(),
std::back_inserter(rowSelection),
[&](QModelIndex const &index) -> RowLocation {
return rowLocationAt(index);
});
[&](QModelIndex const &index)
-> RowLocation { return rowLocationAt(index); });
return rowSelection;
}
/*
std::vector<RowSubtree> JobTreeView::selectedRows() {
}
*/
void JobTreeView::removeSelectedRequested() {
m_notifyee->notifyRemoveRowsRequested(selectedRowLocations());
}
void JobTreeView::copySelectedRequested() {
m_notifyee->notifyCopyRowsRequested(selectedRowLocations());
m_notifyee->notifyCopyRowsRequested();
}
void JobTreeView::pasteSelectedRequested() {
m_notifyee->notifyPasteRowsRequested(selectedRowLocations());
m_notifyee->notifyPasteRowsRequested();
}
void JobTreeView::removeRows(std::vector<RowLocation> rowsToRemove) {
......@@ -96,97 +124,54 @@ JobTreeView::rowTextAt(RowLocation const &location) const {
return adaptedModel().rowTextFromRow(modelIndexAt(location));
}
void JobTreeView::replaceSubtree(
RowLocation const &rootToRemove,
typename ExtractSubtrees::Subtree const &toInsert) {
void JobTreeView::replaceSubtreeAt(RowLocation const &rootToRemove,
Subtree const &toInsert) {
auto const insertionParent = rootToRemove.parent();
auto insertionIndex = rootToRemove.rowRelativeToParent();
removeRowAt(rootToRemove);
insertSubtreeAt(insertionParent, insertionIndex, toInsert);
}
typename ExtractSubtrees::Subtree::const_iterator
JobTreeView::insertSubtreeRecursive(
RowLocation const &parent, int depth,
typename ExtractSubtrees::Subtree::const_iterator current,
typename ExtractSubtrees::Subtree::const_iterator end) {
while (current != end) {
auto currentRow = (*current).first;
auto currentDepth = currentRow.depth();
if (depth < currentDepth) {
current =
insertSubtreeRecursive(parent.child(currentRow.rowRelativeToParent()),
depth + 1, current, end); // HACK?
} else if (depth > currentDepth) {
return current;
} else {
appendChildRowOf(parent, (*current).second);
++current;
}
}
return end;
void JobTreeView::insertSubtreeAt(RowLocation const &parent, int index,
Subtree const &subtree) {
auto build = BuildSubtree(adaptedModel());
auto parentIndex = modelIndexAt(parent);
build(adaptedModel().modelItemFromIndex(parentIndex), parent, index, subtree);
}
void JobTreeView::insertSubtreeAt(
RowLocation const &parent, int index,
typename ExtractSubtrees::Subtree const &subtree) {
insertChildRowOf(parent, index, subtree[0].second);
auto insertionParent = parent.child(index);
auto lastDepth = subtree[0].first.depth();
insertSubtreeRecursive(insertionParent, lastDepth, subtree.cbegin() + 1,
subtree.cend());
void JobTreeView::appendSubtreesAt(RowLocation const &parent,
std::vector<Subtree> subtrees) {
for (auto &&subtree : subtrees)
appendSubtreeAt(parent, subtree);
}
void JobTreeView::replaceRows(
std::vector<RowLocation> toRemove, std::vector<RowLocation> toInsert,
std::vector<std::vector<std::string>> textToInsert) {
try {
auto findSubtreeRoots = FindSubtreeRoots();
std::sort(toRemove.begin(), toRemove.end());
auto subtreesToRemove = findSubtreeRoots(toRemove).value();
auto selectionBase = [&]() -> QModelIndex {
if (toRemove.empty()) {
return adaptedModel().rootModelIndex();
} else {
auto firstSelectionRoot = *toRemove.begin();
return modelIndexAt(subtreesToRemove[0]).parent();
}
}();
// TODO Differentiate between nodes with no children and nodes which have
// children?
auto extractSubtrees = ExtractSubtrees();
std::sort(toInsert.begin(), toInsert.end());
auto subtreesToInsert = extractSubtrees(toInsert, textToInsert).value();
void JobTreeView::appendSubtreeAt(RowLocation const &parent,
Subtree const &subtree) {
auto parentIndex = modelIndexAt(parent);
insertSubtreeAt(parent, model()->rowCount(parentIndex), subtree);
}
auto subtreeToRemove = subtreesToRemove.cbegin();
auto subtreeToInsert = subtreesToInsert.cbegin();
void JobTreeView::replaceRows(std::vector<RowLocation> replacementPoints,
std::vector<Subtree> replacements) {
assertOrThrow(replacementPoints.size() > 0,
"replaceRows: Passed an empty list of replacement points."
"At least one replacement point is required.");
for (; subtreeToRemove != subtreesToRemove.cend() &&
subtreeToInsert != subtreesToInsert.cend();
++subtreeToRemove, ++subtreeToInsert) {
replaceSubtree(/*toRemove=*/*subtreeToRemove,
/*toInsert=*/*subtreeToInsert);
}
auto replacementPoint = replacementPoints.cbegin();
auto replacement = replacements.cbegin();
if (subtreesToRemove.size() > subtreesToInsert.size()) {
for (; subtreeToRemove != subtreesToRemove.cend(); ++subtreeToRemove)
removeRowAt(*subtreeToRemove);
} else if (subtreesToRemove.size() < subtreesToInsert.size()) {
for (auto &toInsert = *(subtreeToInsert);
subtreeToInsert != subtreesToInsert.cend(); ++subtreeToInsert) {
// appendSubtreeAt(toRemove.back().parent(), toInsert);
}
}
} catch(std::exception& ex) {
std::cout << ex.what() << std::endl;
for (; replacementPoint != replacementPoints.cend() &&
replacement != replacements.cend();
++replacementPoint, ++replacement) {
replaceSubtreeAt(*replacementPoint, *replacement);
}
if (replacementPoints.size() > replacements.size())
for (; replacementPoint != replacementPoints.cend(); ++replacementPoint)
removeRowAt(*replacementPoint);
else if (replacementPoints.size() < replacements.size())
for (; replacement != replacements.cend(); ++replacement)
appendSubtreeAt(replacementPoints.back().parent(), *replacement);
}
void JobTreeView::setHeaderLabels(QStringList const &columnHeadings) {
......@@ -223,9 +208,10 @@ QModelIndex JobTreeView::modelIndexAt(RowLocation const &location,
auto maybeIndex = modelIndexIfExistsAt(location, column);
if (maybeIndex.is_initialized())
return maybeIndex.get();
else
else {
throw std::runtime_error("modelIndexAt: Attempted to get model index for "
"row location which does not exist.");
}
}
RowLocation JobTreeView::rowLocationAt(QModelIndex const &index) const {
......
......@@ -28,14 +28,12 @@ void JobTreeViewSignalAdapter::notifyRemoveRowsRequested(
emit removeRowsRequested(locationsOfRowsToRemove);
}
void JobTreeViewSignalAdapter::notifyCopyRowsRequested(
std::vector<RowLocation> const &locationsOfRowsToCopy) {
emit copyRowsRequested(locationsOfRowsToCopy);
void JobTreeViewSignalAdapter::notifyCopyRowsRequested() {
emit copyRowsRequested();
}
void JobTreeViewSignalAdapter::notifyPasteRowsRequested(
std::vector<RowLocation> const &locationsOfSelectedRows) {
emit pasteRowsRequested(locationsOfSelectedRows);
void JobTreeViewSignalAdapter::notifyPasteRowsRequested() {
emit pasteRowsRequested();
}
}
}
......
#ifndef MANTID_MANTIDWIDGETS_BUILDSUBTREETEST_H
#define MANTID_MANTIDWIDGETS_BUILDSUBTREETEST_H
#include "MantidKernel/make_unique.h"
#include "MantidQtWidgets/Common/Batch/BuildSubtree.h"
#include <algorithm>
#include <cxxtest/TestSuite.h>
#include <gtest/gtest.h>
#include <vector>
#include <QStandardItem>
using namespace MantidQt::MantidWidgets;
using namespace MantidQt::MantidWidgets::Batch;
using namespace testing;
class BuildSubtreeTest : public CxxTest::TestSuite {
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static BuildSubtreeTest *createSuite() { return new BuildSubtreeTest; }
static void destroySuite(BuildSubtreeTest *suite) { delete suite; }
QtStandardItemMutableTreeAdapter adapt(QStandardItemModel *model) {
return QtStandardItemMutableTreeAdapter(*model);
}
std::unique_ptr<QStandardItemModel> emptyModel() const {
return Mantid::Kernel::make_unique<QStandardItemModel>();
}
std::string cell(std::string const &text) const { return text; }
template <typename... Args>
std::vector<Cell> cells(Args const &... cellText) const {
return std::vector<Cell>({cell(cellText)...});
}
void testBuildEmptySubtree() {
auto model = emptyModel();
auto adaptedModel = adapt(model.get());
auto build = BuildSubtree(adaptedModel);
auto positionRelativeToMainTree = RowLocation();
auto subtree = Subtree();
auto rootItem = Mantid::Kernel::make_unique<QStandardItem>();
build(rootItem.get(), positionRelativeToMainTree, 0, subtree);
TS_ASSERT(rootItem->rowCount() == 0);
}
void testBuildSubtreeWithRootOnly() {
auto model = emptyModel();
auto adaptedModel = adapt(model.get());
auto build = BuildSubtree(adaptedModel);
auto positionRelativeToMainTree = RowLocation();
auto subtree = Subtree({{RowLocation(), cells("Root")}});
auto rootItem = Mantid::Kernel::make_unique<QStandardItem>();
build(rootItem.get(), positionRelativeToMainTree, 0, subtree);
TS_ASSERT(rootItem->rowCount() == 1);
TS_ASSERT_EQUALS(rootItem->child(0)->text(), "Root");
}
void testBuildSubtreeWithRootAndSingleChild() {
auto model = emptyModel();
auto adaptedModel = adapt(model.get());
auto build = BuildSubtree(adaptedModel);
auto positionRelativeToMainTree = RowLocation();
auto subtree = Subtree({
Row(RowLocation(), cells("Root")),
Row(RowLocation({0}), cells("Child"))
});
auto invisibleRootItem = Mantid::Kernel::make_unique<QStandardItem>();
build(invisibleRootItem.get(), positionRelativeToMainTree, 0, subtree);
TS_ASSERT_EQUALS(invisibleRootItem->rowCount(), 1);
auto* subtreeRootItem = invisibleRootItem->child(0);
TS_ASSERT_EQUALS(subtreeRootItem->text(), "Root");
TS_ASSERT_EQUALS(subtreeRootItem->rowCount(), 1);
auto* childItem = subtreeRootItem->child(0);
TS_ASSERT_EQUALS(childItem->text(), "Child");
}
void testBuildSubtreeWithRootAndTwoChildren() {
auto model = emptyModel();
auto adaptedModel = adapt(model.get());
auto build = BuildSubtree(adaptedModel);
auto positionRelativeToMainTree = RowLocation();
auto subtree = Subtree({
Row(RowLocation(), cells("Root")),
Row(RowLocation({0}), cells("Child 1")),
Row(RowLocation({1}), cells("Child 2"))
});
auto invisibleRootItem = Mantid::Kernel::make_unique<QStandardItem>();
build(invisibleRootItem.get(), positionRelativeToMainTree, 0, subtree);
TS_ASSERT_EQUALS(invisibleRootItem->rowCount(), 1);
auto* subtreeRootItem = invisibleRootItem->child(0);
TS_ASSERT_EQUALS(subtreeRootItem->text(), "Root");
TS_ASSERT_EQUALS(subtreeRootItem->rowCount(), 2);
auto* firstChildItem = subtreeRootItem->child(0);
TS_ASSERT_EQUALS(firstChildItem->text(), "Child 1");
auto* secondChildItem = subtreeRootItem->child(1);
TS_ASSERT_EQUALS(secondChildItem->text(), "Child 2");
}
};
#endif
......@@ -13,30 +13,42 @@ from ui.batchwidget.ui_batch_widget_window import Ui_BatchWidgetWindow
def row(path):
return MantidQt.MantidWidgets.Batch.RowLocation(path)
class DataProcessorGui(QtGui.QMainWindow, Ui_BatchWidgetWindow):
def __init__(self):
super(QtGui.QMainWindow, self).__init__()
self.setupUi(self)
self.clipboardPaths = []
self.clipboardText = []
self.clipboard = None
def on_remove_runs_request(self, runs_to_remove):
self.table.removeRows(runs_to_remove)
def on_cell_updated(self, row, col, cell_content):
print("Updated row {} col {} with text {}".format(row.path(), col, cell_content))
pass
def on_row_inserted(self, rowLoc):
print("Row inserted at {}".format(rowLoc.path()))
#if rowLoc.depth() > 2 or rowLoc.rowRelativeToParent() >= 5:
# self.table.removeRowAt(rowLoc)
def on_copy_runs_request(self, runs_to_copy):
self.clipboardPaths = runs_to_copy
self.clipboardText = list(map(lambda loc: self.table.rowTextAt(loc), runs_to_copy))
def on_copy_runs_request(self):
self.clipboard = self.table.selectedSubtrees()
self.table.clearSelection()
if self.clipboard is not None:
print(self.clipboard)
else:
print ("Bad selection for copy.")
def on_paste_rows_request(self, selected_runs):
self.table.replaceRows(selected_runs, self.clipboardPaths, self.clipboardText)
def on_paste_rows_request(self):
replacement_roots = self.table.selectedSubtreeRoots()
if replacement_roots is not None and self.clipboard is not None:
if replacement_roots:
self.table.replaceRows(replacement_roots, self.clipboard)
else:
self.table.appendSubtreesAt(row([]), self.clipboard)
else:
print("Bad selection for paste")
def setup_layout(self):
self.table = MantidQt.MantidWidgets.Batch.JobTreeView(["Run(s)",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment