BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
moveitemcommand.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // qt-mvvm: Model-view-view-model framework for large GUI applications
4 //
5 //! @file mvvm/model/mvvm/commands/moveitemcommand.cpp
6 //! @brief Implements class CLASS?
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2020
11 //! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
16 #include "mvvm/model/itemutils.h"
17 #include "mvvm/model/path.h"
18 #include "mvvm/model/sessionitem.h"
19 #include <sstream>
20 #include <stdexcept>
21 
22 using namespace ModelView;
23 
24 namespace {
25 void check_input_data(const SessionItem* item, const SessionItem* parent);
26 std::string generate_description(const TagRow& tagrow);
27 } // namespace
28 
34  MoveItemCommandImpl(TagRow tagrow) : target_tagrow(std::move(tagrow))
35  {
36  if (target_tagrow.row < 0)
37  throw std::runtime_error("MoveItemCommand() -> Error. Uninitialized target row");
38  }
39 };
40 
42  : AbstractItemCommand(new_parent), p_impl(std::make_unique<MoveItemCommandImpl>(tagrow))
43 {
44  setResult(true);
45 
46  check_input_data(item, new_parent);
47  setDescription(generate_description(p_impl->target_tagrow));
48 
49  p_impl->target_parent_path = pathFromItem(new_parent);
50  p_impl->original_parent_path = pathFromItem(item->parent());
51  p_impl->original_tagrow = item->tagRow();
52 
53  if (Utils::IsSinglePropertyTag(*item->parent(), p_impl->original_tagrow.tag))
54  throw std::runtime_error("MoveItemCommand::MoveItemCommand() -> Single property tag.");
55 
56  if (Utils::IsSinglePropertyTag(*new_parent, p_impl->target_tagrow.tag))
57  throw std::runtime_error("MoveItemCommand::MoveItemCommand() -> Single property tag.");
58 
59  if (item->parent() == new_parent) {
60  if (p_impl->target_tagrow.row >= new_parent->itemCount(p_impl->target_tagrow.tag))
61  throw std::runtime_error(
62  "MoveCommand::MoveCommand() -> move index exceeds number of items in a tag");
63  }
64 }
65 
67 
69 {
70  // first find items
71  auto current_parent = itemFromPath(p_impl->target_parent_path);
72  auto target_parent = itemFromPath(p_impl->original_parent_path);
73 
74  // then make manipulations
75  auto taken = current_parent->takeItem(p_impl->target_tagrow);
76  target_parent->insertItem(taken, p_impl->original_tagrow);
77 
78  // adjusting new addresses
79  p_impl->target_parent_path = pathFromItem(current_parent);
80  p_impl->original_parent_path = pathFromItem(target_parent);
81 }
82 
84 {
85  // first find items
86  auto original_parent = itemFromPath(p_impl->original_parent_path);
87  auto target_parent = itemFromPath(p_impl->target_parent_path);
88 
89  // then make manipulations
90  auto taken = original_parent->takeItem(p_impl->original_tagrow);
91 
92  if (!taken)
93  throw std::runtime_error("MoveItemCommand::execute() -> Can't take an item.");
94 
95  bool succeeded = target_parent->insertItem(taken, p_impl->target_tagrow);
96  if (!succeeded)
97  throw std::runtime_error("MoveItemCommand::execute() -> Can't insert item.");
98 
99  // adjusting new addresses
100  p_impl->target_parent_path = pathFromItem(target_parent);
101  p_impl->original_parent_path = pathFromItem(original_parent);
102 }
103 
104 namespace {
105 void check_input_data(const SessionItem* item, const SessionItem* parent)
106 {
107  if (!item || !item->model())
108  throw std::runtime_error("MoveItemCommand::MoveItemCommand() -> Invalid input item");
109 
110  if (!parent || !parent->model())
111  throw std::runtime_error("MoveItemCommand::MoveItemCommand() -> Invalid parent item");
112 
113  if (item->model() != parent->model())
114  throw std::runtime_error(
115  "MoveItemCommand::MoveItemCommand() -> Items belong to different models");
116 
117  if (!item->parent())
118  throw std::runtime_error(
119  "MoveItemCommand::MoveItemCommand() -> Item doesn't have a parent");
120 }
121 
122 std::string generate_description(const TagRow& tagrow)
123 {
124  std::ostringstream ostr;
125  ostr << "Move item to tag '" << tagrow.tag << "', row:" << tagrow.row;
126  return ostr.str();
127 }
128 } // namespace
Abstract command interface to manipulate SessionItem in model context.
SessionItem * itemFromPath(const Path &path) const
void setDescription(const std::string &text)
Sets command description.
void setResult(const CommandResult &command_result)
Path pathFromItem(SessionItem *item) const
std::unique_ptr< MoveItemCommandImpl > p_impl
MoveItemCommand(SessionItem *item, SessionItem *new_parent, TagRow tagrow)
Supports navigation through SessionModel.
Definition: path.h:35
The main object representing an editable/displayable/serializable entity.
Definition: sessionitem.h:38
int itemCount(const std::string &tag) const
Returns number of items in given tag.
SessionItem * parent() const
Returns parent item. Will return nullptr if item doesn't have a parent.
SessionModel * model() const
Returns the model to which given item belongs to.
TagRow tagRow() const
Returns TagRow of this item under which it is accessible through its parent.
Aggregate to hold (tag, row) information for SessionModel.
Definition: tagrow.h:25
std::string tag
Definition: tagrow.h:27
Defines class CLASS?
Defines class CLASS?
MVVM_MODEL_EXPORT bool IsSinglePropertyTag(const SessionItem &item, const std::string &tag)
Returns true if given item has registered tag, and it belongs to single property.
Definition: itemutils.cpp:91
materialitems.h Collection of materials to populate MaterialModel.
Definition: filesystem.h:81
Defines class CLASS?
Defines class CLASS?