HistoryView.cpp 6.63 KB
Newer Older
1
2
3
4
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/HistoryView.h"
Hahn, Steven's avatar
Hahn, Steven committed
5
6
#include <iterator>
#include <algorithm>
7

8
9
10
11
12
13
namespace Mantid {
namespace API {

HistoryView::HistoryView(const WorkspaceHistory &wsHist)
    : m_wsHist(wsHist), m_historyItems() {
  // add all of the top level algorithms to the view by default
14
  const auto algorithms = wsHist.getAlgorithmHistories();
15
16
  m_historyItems =
      std::vector<HistoryItem>(algorithms.begin(), algorithms.end());
17
18
19
20
21
}

/**
 * Unroll an algorithm history to export its child algorithms.
 *
22
 * This places each of the child algorithm histories into the
23
24
25
26
27
 * HistoryView object. The parent is retained as a marker so we can
 * "roll" the history back up if we want. This method does nothing if
 * the history object has no children
 *
 * @param index :: index of the history object to unroll
28
29
 * @throws std::out_of_range if the index is larger than the number of history
 *items.
30
 */
31
32
void HistoryView::unroll(size_t index) {
  if (index >= m_historyItems.size()) {
33
34
35
    throw std::out_of_range("HistoryView::unroll() - Index out of range");
  }

36
  // advance to the item at the index
37
  auto it = m_historyItems.begin();
38
  std::advance(it, index);
39
  unroll(it);
40
41
}

Hahn, Steven's avatar
Hahn, Steven committed
42
43
44
45
46
#if defined(__GNUC__) && !defined(__clang__)
#define GCC_VERSION                                                            \
  (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif

47
48
49
/**
 * Unroll an algorithm history to export its child algorithms.
 *
50
 * This places each of the child algorithm histories into the
51
52
53
54
 * HistoryView object. The parent is retained as a marker so we can
 * "roll" the history back up if we want. This method does nothing if
 * the history object has no children
 *
55
56
 * @param it :: iterator to the list of history item objects at the position to
 *unroll
57
 */
58
void HistoryView::unroll(std::vector<HistoryItem>::iterator &it) {
59
60
61
  const auto history = it->getAlgorithmHistory();
  const auto childHistories = history->getChildHistories();

62
63
  if (!it->isUnrolled() && childHistories.size() > 0) {
    // mark this record as being ignored by the script builder
64
    it->unrolled(true);
65

66
    // insert each of the records, in order, at this position
67
68
69
70
    std::vector<HistoryItem> tmpHistory;
    tmpHistory.reserve(childHistories.size());
    for (const auto &item : childHistories) {
      tmpHistory.emplace_back(item);
71
    }
Hahn, Steven's avatar
Hahn, Steven committed
72
    // since we are using a std::vector, do all insertions at the same time.
Hahn, Steven's avatar
Hahn, Steven committed
73
74
#if !defined(GCC_VERSION) || GCC_VERSION >= 409000
    ++it; // move iterator forward to insertion position
75
    it = m_historyItems.insert(it, tmpHistory.begin(), tmpHistory.end());
Hahn, Steven's avatar
Hahn, Steven committed
76
77
78
#else
    // workaround for GCC < 4.9
    // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55817
79
    ++it;
Hahn, Steven's avatar
Hahn, Steven committed
80
81
    for (auto itItem = tmpHistory.rbegin(); itItem != tmpHistory.rend();
         ++itItem) {
82
      it = m_historyItems.insert(it, *itItem);
Hahn, Steven's avatar
Hahn, Steven committed
83
84
    }
#endif
85
86
  } else
    ++it;
87
88
}

89
90
91
/**
 * Unroll the entire algorithm history.
 *
92
93
94
95
 * This is method will unroll the entire history for every algorithm by calling
 *unroll
 * on each element in the list. Every child algorithm with be visible after
 *calling this method.
96
 */
97
void HistoryView::unrollAll() {
98
99
  auto it = m_historyItems.begin();
  while (it != m_historyItems.end()) {
100
101
    // iterator passed by reference to prevent iterator invalidation.
    // iterator incremented within function.
102
103
104
105
    unroll(it);
  }
}

106
107
108
/**
 * Roll the entire algorithm history back up.
 *
109
110
111
112
 * This is method will roll up the entire history for every algorithm by calling
 *roll
 * on each element in the list. Only top level algorithms with be visible after
 *calling this method.
113
 */
114
void HistoryView::rollAll() {
115
116
  auto it = m_historyItems.begin();
  while (it != m_historyItems.end()) {
117
    // iterator incremented within function.
118
119
120
121
    roll(it);
  }
}

122
/**
123
124
 * Roll an unrolled algorithm history item and remove its children from the
 *view.
125
126
 *
 * This removes each of the child algorithm histories (if any) and marks
127
128
 * the parent as being "rolled up". Note that this will recursively "roll up"
 *any child
129
130
131
132
 * history objects that are also unrolled. This method does nothing if
 * the history object has no children.
 *
 * @param index :: index of the history object to unroll
133
134
 * @throws std::out_of_range if the index is larger than the number of history
 *items.
135
 */
136
137
void HistoryView::roll(size_t index) {
  if (index >= m_historyItems.size()) {
138
139
140
    throw std::out_of_range("HistoryView::roll() - Index out of range");
  }

141
  // advance to the item at the index
142
  auto it = m_historyItems.begin();
143
  std::advance(it, index);
144
  roll(it);
145
146
}

Hahn, Steven's avatar
Hahn, Steven committed
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/**
 * Check if our children are unrolled and if so roll them back up.
 *
 * @param it :: iterator pointing to the item whose children will be rolled up.
 */
void HistoryView::rollChildren(std::vector<HistoryItem>::iterator it) {
  const size_t numChildren = it->numberOfChildren();
  ++it;
  for (size_t i = 0; i < numChildren; ++i) {
    if (it->isUnrolled())
      roll(it);
  }
}

161
/**
162
163
 * Roll an unrolled algorithm history item and remove its children from the
 *view.
164
165
 *
 * This removes each of the child algorithm histories (if any) and marks
166
167
 * the parent as being "rolled up". Note that this will recursively "roll up"
 *any child
168
169
170
 * history objects that are also unrolled. This method does nothing if
 * the history object has no children.
 *
171
172
 * @param it :: iterator to the list of history item objects at the positon to
 *roll
173
 */
174
void HistoryView::roll(std::vector<HistoryItem>::iterator &it) {
175
176
177

  // the number of records after this position
  const size_t numChildren = it->numberOfChildren();
178
179
  if (it->isUnrolled() && numChildren > 0) {
    // mark this record as not being ignored by the script builder
180
    it->unrolled(false);
Hahn, Steven's avatar
Hahn, Steven committed
181
182
183
184
    this->rollChildren(it);
    // Then just remove the children from the list
    ++it;
    m_historyItems.erase(it, it + numChildren);
185
186
  } else
    ++it;
187
188
}

189
190
191
192
193
194
195
/**
 * Filter the list of history items to remove any anlgorithms whos start
 * time is outside of the given range.
 *
 * @param start Start of time range
 * @param end End of time range
 */
196
197
void HistoryView::filterBetweenExecDate(Mantid::Kernel::DateAndTime start,
                                        Mantid::Kernel::DateAndTime end) {
Hahn, Steven's avatar
Hahn, Steven committed
198
199
200
201
202
203
204
205
  auto lastItem = std::remove_if(
      m_historyItems.begin(), m_historyItems.end(),
      [&start, &end](const HistoryItem &item) {
        Mantid::Kernel::DateAndTime algExecutionDate =
            item.getAlgorithmHistory()->executionDate();
        return algExecutionDate < start || algExecutionDate > end;
      });
  m_historyItems.erase(lastItem, m_historyItems.end());
206
207
208
209
}

} // namespace API
} // namespace Mantid