Fix handling showing both a parent and child survey
[survex.git] / src / model.h
blobc59e8f9e7dae648718f18fc1a3298a1b8228dd86
1 //
2 // model.h
3 //
4 // Cave survey model.
5 //
6 // Copyright (C) 2000-2003,2005 Mark R. Shinwell
7 // Copyright (C) 2001-2003,2004,2005,2006,2010,2011,2012,2013,2014,2015,2016 Olly Betts
8 //
9 // This program is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #ifndef model_h
25 #define model_h
27 #include "wx.h"
29 #include "labelinfo.h"
30 #include "vector3.h"
32 #include <ctime>
33 #include <list>
34 #include <set>
35 #include <vector>
37 using namespace std;
39 class MainFrm;
41 class PointInfo : public Point {
42 int date;
44 public:
45 PointInfo() : Point(), date(-1) { }
46 explicit PointInfo(const img_point & pt) : Point(pt), date(-1) { }
47 PointInfo(const img_point & pt, int date_) : Point(pt), date(date_) { }
48 PointInfo(const Point & p, int date_) : Point(p), date(date_) { }
49 int GetDate() const { return date; }
52 class XSect {
53 friend class MainFrm;
54 const LabelInfo* stn;
55 int date;
56 double l, r, u, d;
57 double right_bearing;
59 public:
60 XSect(const LabelInfo* stn_, int date_,
61 double l_, double r_, double u_, double d_)
62 : stn(stn_), date(date_), l(l_), r(r_), u(u_), d(d_), right_bearing(0) { }
63 double GetL() const { return l; }
64 double GetR() const { return r; }
65 double GetU() const { return u; }
66 double GetD() const { return d; }
67 double get_right_bearing() const { return right_bearing; }
68 void set_right_bearing(double right_bearing_) {
69 right_bearing = right_bearing_;
71 int GetDate() const { return date; }
72 wxString GetLabel() const { return stn->GetText(); }
73 const Point& GetPoint() const { return *stn; }
74 double GetX() const { return stn->GetX(); }
75 double GetY() const { return stn->GetY(); }
76 double GetZ() const { return stn->GetZ(); }
77 friend Vector3 operator-(const XSect& a, const XSect& b);
80 inline Vector3 operator-(const XSect& a, const XSect& b) {
81 return *(a.stn) - *(b.stn);
84 class traverse : public vector<PointInfo> {
85 public:
86 int n_legs;
87 // Bitmask of img_FLAG_SURFACE, img_FLAG_SPLAY and img_FLAG_DUPLICATE.
88 int flags;
89 double length;
90 double E, H, V;
91 wxString name;
93 explicit
94 traverse(const char* name_)
95 : n_legs(0), flags(0),
96 length(0), E(-1), H(-1), V(-1),
97 name(name_, wxConvUTF8) {
98 if (name.empty() && !name_[0]) {
99 // If name isn't valid UTF-8 then this conversion will
100 // give an empty string. In this case, assume that the
101 // label is CP1252 (the Microsoft superset of ISO8859-1).
102 static wxCSConv ConvCP1252(wxFONTENCODING_CP1252);
103 name = wxString(name_, ConvCP1252);
104 if (name.empty()) {
105 // Or if that doesn't work (ConvCP1252 doesn't like
106 // strings with some bytes in) let's just go for
107 // ISO8859-1.
108 name = wxString(name_, wxConvISO8859_1);
114 class SurveyFilter {
115 std::set<wxString, std::greater<wxString>> filters;
116 std::set<wxString, std::greater<wxString>> redundant_filters;
117 wxChar separator = 0;
119 public:
120 SurveyFilter() {}
122 void add(const wxString& survey);
124 void remove(const wxString& survey);
126 void clear() { filters.clear(); redundant_filters.clear(); }
128 bool empty() const { return filters.empty(); }
130 void SetSeparator(wxChar separator_) { separator = separator_; }
132 bool CheckVisible(const wxString& name) const;
135 /// Cave model.
136 class Model {
137 list<traverse> traverses[8];
138 list<vector<XSect>> tubes;
140 public: // FIXME
141 list<LabelInfo*> m_Labels;
143 private:
144 Vector3 m_Ext;
145 double m_DepthMin, m_DepthExt;
146 int m_DateMin, m_DateExt;
147 bool complete_dateinfo;
148 int m_NumEntrances = 0;
149 int m_NumFixedPts = 0;
150 int m_NumExportedPts = 0;
151 bool m_HasUndergroundLegs = false;
152 bool m_HasSplays = false;
153 bool m_HasDupes = false;
154 bool m_HasSurfaceLegs = false;
155 bool m_HasErrorInformation = false;
156 bool m_IsExtendedElevation = false;
158 // Character separating survey levels (often '.')
159 wxChar m_separator;
161 wxString m_Title, m_cs_proj, m_DateStamp;
163 time_t m_DateStamp_numeric;
165 Vector3 m_Offset;
167 public:
168 int Load(const wxString& file, const wxString& prefix);
170 void CentreDataset(const Vector3& vmin);
172 const Vector3& GetExtent() const { return m_Ext; }
174 const wxString& GetSurveyTitle() const { return m_Title; }
176 const wxString& GetDateString() const { return m_DateStamp; }
178 time_t GetDateStamp() const { return m_DateStamp_numeric; }
180 double GetDepthExtent() const { return m_DepthExt; }
181 double GetDepthMin() const { return m_DepthMin; }
183 bool HasCompleteDateInfo() const { return complete_dateinfo; }
184 int GetDateExtent() const { return m_DateExt; }
185 int GetDateMin() const { return m_DateMin; }
187 int GetNumFixedPts() const { return m_NumFixedPts; }
188 int GetNumExportedPts() const { return m_NumExportedPts; }
189 int GetNumEntrances() const { return m_NumEntrances; }
191 bool HasUndergroundLegs() const { return m_HasUndergroundLegs; }
192 bool HasSplays() const { return m_HasSplays; }
193 bool HasDupes() const { return m_HasDupes; }
194 bool HasSurfaceLegs() const { return m_HasSurfaceLegs; }
195 bool HasTubes() const { return !tubes.empty(); }
196 bool HasErrorInformation() const { return m_HasErrorInformation; }
198 bool IsExtendedElevation() const { return m_IsExtendedElevation; }
200 wxChar GetSeparator() const { return m_separator; }
202 const wxString& GetCSProj() const { return m_cs_proj; }
204 const Vector3& GetOffset() const { return m_Offset; }
206 list<traverse>::const_iterator
207 traverses_begin(unsigned flags, const SurveyFilter* filter) const {
208 if (flags >= sizeof(traverses)) return traverses[0].end();
209 auto it = traverses[flags].begin();
210 if (filter) {
211 while (it != traverses[flags].end() &&
212 !filter->CheckVisible(it->name)) {
213 ++it;
216 return it;
219 list<traverse>::const_iterator
220 traverses_next(unsigned flags, const SurveyFilter* filter,
221 list<traverse>::const_iterator it) const {
222 ++it;
223 if (filter) {
224 while (it != traverses[flags].end() &&
225 !filter->CheckVisible(it->name)) {
226 ++it;
229 return it;
232 list<traverse>::const_iterator traverses_end(unsigned flags) const {
233 if (flags >= sizeof(traverses)) flags = 0;
234 return traverses[flags].end();
237 list<vector<XSect>>::const_iterator tubes_begin() const {
238 return tubes.begin();
241 list<vector<XSect>>::const_iterator tubes_end() const {
242 return tubes.end();
245 list<vector<XSect>>::iterator tubes_begin() {
246 return tubes.begin();
249 list<vector<XSect>>::iterator tubes_end() {
250 return tubes.end();
253 list<LabelInfo*>::const_iterator GetLabels() const {
254 return m_Labels.begin();
257 list<LabelInfo*>::const_iterator GetLabelsEnd() const {
258 return m_Labels.end();
261 list<LabelInfo*>::const_reverse_iterator GetRevLabels() const {
262 return m_Labels.rbegin();
265 list<LabelInfo*>::const_reverse_iterator GetRevLabelsEnd() const {
266 return m_Labels.rend();
269 list<LabelInfo*>::iterator GetLabelsNC() {
270 return m_Labels.begin();
273 list<LabelInfo*>::iterator GetLabelsNCEnd() {
274 return m_Labels.end();
278 #endif