| [5809313] | 1 | // | 
|---|
| [156dc16] | 2 | //  mainfrm.cc | 
|---|
| [5809313] | 3 | // | 
|---|
 | 4 | //  Main frame handling for Aven. | 
|---|
 | 5 | // | 
|---|
| [b72f4b5] | 6 | //  Copyright (C) 2000-2002,2005,2006 Mark R. Shinwell | 
|---|
| [4f70ebc] | 7 | //  Copyright (C) 2001-2003,2004,2005,2006,2010,2011,2012,2013,2014 Olly Betts | 
|---|
| [887c26e] | 8 | //  Copyright (C) 2005 Martin Green | 
|---|
| [5809313] | 9 | // | 
|---|
 | 10 | //  This program is free software; you can redistribute it and/or modify | 
|---|
 | 11 | //  it under the terms of the GNU General Public License as published by | 
|---|
 | 12 | //  the Free Software Foundation; either version 2 of the License, or | 
|---|
 | 13 | //  (at your option) any later version. | 
|---|
 | 14 | // | 
|---|
 | 15 | //  This program is distributed in the hope that it will be useful, | 
|---|
 | 16 | //  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
 | 17 | //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
 | 18 | //  GNU General Public License for more details. | 
|---|
 | 19 | // | 
|---|
 | 20 | //  You should have received a copy of the GNU General Public License | 
|---|
 | 21 | //  along with this program; if not, write to the Free Software | 
|---|
| [5940815] | 22 | //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA | 
|---|
| [5809313] | 23 | // | 
|---|
 | 24 |  | 
|---|
| [cbfa50d] | 25 | #ifdef HAVE_CONFIG_H | 
|---|
 | 26 | #include <config.h> | 
|---|
 | 27 | #endif | 
|---|
 | 28 |  | 
|---|
| [6bec10c] | 29 | #include "cavernlog.h" | 
|---|
| [5809313] | 30 | #include "mainfrm.h" | 
|---|
 | 31 | #include "aven.h" | 
|---|
| [6e65d9e] | 32 | #include "aboutdlg.h" | 
|---|
| [706b033] | 33 |  | 
|---|
| [93c3f97] | 34 | #include "message.h" | 
|---|
| [a405bc1] | 35 | #include "img_hosted.h" | 
|---|
| [41adebb] | 36 | #include "namecompare.h" | 
|---|
| [ce403f1] | 37 | #include "printwx.h" | 
|---|
| [045e2af] | 38 | #include "filename.h" | 
|---|
| [e577f89] | 39 | #include "useful.h" | 
|---|
| [706b033] | 40 |  | 
|---|
| [2d9ed8ad] | 41 | #include <wx/confbase.h> | 
|---|
| [f302cbaa] | 42 | #include <wx/filename.h> | 
|---|
| [ee41e88] | 43 | #include <wx/image.h> | 
|---|
| [0580c6a] | 44 | #include <wx/imaglist.h> | 
|---|
| [b88b171] | 45 | #include <wx/process.h> | 
|---|
| [0580c6a] | 46 | #include <wx/regex.h> | 
|---|
| [203d2a7] | 47 |  | 
|---|
| [42bd3576] | 48 | #include <cstdlib> | 
|---|
| [5809313] | 49 | #include <float.h> | 
|---|
| [63dc4eb] | 50 | #include <functional> | 
|---|
| [576e5a9] | 51 | #include <map> | 
|---|
| [156dc16] | 52 | #include <stack> | 
|---|
| [7a2e1ed] | 53 | #include <vector> | 
|---|
| [0c76ad9] | 54 |  | 
|---|
| [0580c6a] | 55 | using namespace std; | 
|---|
| [5809313] | 56 |  | 
|---|
| [dcbcae0] | 57 | const static int img2aven_tab[] = { | 
|---|
 | 58 | #include "img2aven.h" | 
|---|
 | 59 | }; | 
|---|
 | 60 |  | 
|---|
 | 61 | inline int | 
|---|
 | 62 | img2aven(int flags) | 
|---|
 | 63 | { | 
|---|
| [9140f41] | 64 |     flags &= (sizeof(img2aven_tab) / sizeof(img2aven_tab[0]) - 1); | 
|---|
| [dcbcae0] | 65 |     return img2aven_tab[flags]; | 
|---|
 | 66 | } | 
|---|
 | 67 |  | 
|---|
| [b1de3e0] | 68 | class AvenSplitterWindow : public wxSplitterWindow { | 
|---|
 | 69 |     MainFrm *parent; | 
|---|
 | 70 |  | 
|---|
 | 71 |     public: | 
|---|
 | 72 |         AvenSplitterWindow(MainFrm *parent_) | 
|---|
| [b4fe9fb] | 73 |             : wxSplitterWindow(parent_, -1, wxDefaultPosition, wxDefaultSize, | 
|---|
 | 74 |                                wxSP_3D | wxSP_LIVE_UPDATE), | 
|---|
 | 75 |               parent(parent_) | 
|---|
 | 76 |         { | 
|---|
| [b1de3e0] | 77 |         } | 
|---|
 | 78 |  | 
|---|
| [41f7a27] | 79 |         void OnSplitterDClick(wxSplitterEvent &) { | 
|---|
| [b1de3e0] | 80 |             parent->ToggleSidePanel(); | 
|---|
 | 81 |         } | 
|---|
| [f433fda] | 82 |  | 
|---|
| [b1de3e0] | 83 |     private: | 
|---|
 | 84 |         DECLARE_EVENT_TABLE() | 
|---|
 | 85 | }; | 
|---|
 | 86 |  | 
|---|
 | 87 | BEGIN_EVENT_TABLE(AvenSplitterWindow, wxSplitterWindow) | 
|---|
 | 88 |     EVT_SPLITTER_DCLICK(-1, AvenSplitterWindow::OnSplitterDClick) | 
|---|
 | 89 | END_EVENT_TABLE() | 
|---|
 | 90 |  | 
|---|
| [9521a42] | 91 | class EditMarkDlg : public wxDialog { | 
|---|
 | 92 |     wxTextCtrl * easting, * northing, * altitude; | 
|---|
| [49ce5b0] | 93 |     wxTextCtrl * angle, * tilt_angle, * scale, * time; | 
|---|
| [9521a42] | 94 | public: | 
|---|
 | 95 |     EditMarkDlg(wxWindow* parent, const PresentationMark & p) | 
|---|
| [fbc1d32] | 96 |         : wxDialog(parent, 500, wmsg(/*Edit Waypoint*/404)) | 
|---|
| [9521a42] | 97 |     { | 
|---|
| [5627cbb] | 98 |         easting = new wxTextCtrl(this, 601, wxString::Format(wxT("%.3f"), p.GetX())); | 
|---|
 | 99 |         northing = new wxTextCtrl(this, 602, wxString::Format(wxT("%.3f"), p.GetY())); | 
|---|
 | 100 |         altitude = new wxTextCtrl(this, 603, wxString::Format(wxT("%.3f"), p.GetZ())); | 
|---|
 | 101 |         angle = new wxTextCtrl(this, 604, wxString::Format(wxT("%.3f"), p.angle)); | 
|---|
 | 102 |         tilt_angle = new wxTextCtrl(this, 605, wxString::Format(wxT("%.3f"), p.tilt_angle)); | 
|---|
 | 103 |         scale = new wxTextCtrl(this, 606, wxString::Format(wxT("%.3f"), p.scale)); | 
|---|
| [49ce5b0] | 104 |         if (p.time > 0.0) { | 
|---|
| [5627cbb] | 105 |             time = new wxTextCtrl(this, 607, wxString::Format(wxT("%.3f"), p.time)); | 
|---|
| [49ce5b0] | 106 |         } else if (p.time < 0.0) { | 
|---|
| [5627cbb] | 107 |             time = new wxTextCtrl(this, 607, wxString::Format(wxT("*%.3f"), -p.time)); | 
|---|
| [49ce5b0] | 108 |         } else { | 
|---|
| [5627cbb] | 109 |             time = new wxTextCtrl(this, 607, wxT("0")); | 
|---|
| [49ce5b0] | 110 |         } | 
|---|
 | 111 |  | 
|---|
| [9521a42] | 112 |         wxBoxSizer * coords = new wxBoxSizer(wxHORIZONTAL); | 
|---|
| [5627cbb] | 113 |         coords->Add(new wxStaticText(this, 610, wxT("(")), 0, wxALIGN_CENTRE_VERTICAL); | 
|---|
| [9521a42] | 114 |         coords->Add(easting, 1); | 
|---|
| [5627cbb] | 115 |         coords->Add(new wxStaticText(this, 611, wxT(",")), 0, wxALIGN_CENTRE_VERTICAL); | 
|---|
| [9521a42] | 116 |         coords->Add(northing, 1); | 
|---|
| [5627cbb] | 117 |         coords->Add(new wxStaticText(this, 612, wxT(",")), 0, wxALIGN_CENTRE_VERTICAL); | 
|---|
| [9521a42] | 118 |         coords->Add(altitude, 1); | 
|---|
| [5627cbb] | 119 |         coords->Add(new wxStaticText(this, 613, wxT(")")), 0, wxALIGN_CENTRE_VERTICAL); | 
|---|
| [9521a42] | 120 |         wxBoxSizer* vert = new wxBoxSizer(wxVERTICAL); | 
|---|
 | 121 |         vert->Add(coords, 0, wxALL, 8); | 
|---|
 | 122 |         wxBoxSizer * r2 = new wxBoxSizer(wxHORIZONTAL); | 
|---|
| [fbc1d32] | 123 |         r2->Add(new wxStaticText(this, 614, wmsg(/*Bearing*/259) + wxT(": ")), 0, wxALIGN_CENTRE_VERTICAL); | 
|---|
| [9521a42] | 124 |         r2->Add(angle); | 
|---|
 | 125 |         vert->Add(r2, 0, wxALL, 8); | 
|---|
 | 126 |         wxBoxSizer * r3 = new wxBoxSizer(wxHORIZONTAL); | 
|---|
| [fbc1d32] | 127 |         r3->Add(new wxStaticText(this, 615, wmsg(/*Elevation*/118) + wxT(": ")), 0, wxALIGN_CENTRE_VERTICAL); | 
|---|
| [9521a42] | 128 |         r3->Add(tilt_angle); | 
|---|
 | 129 |         vert->Add(r3, 0, wxALL, 8); | 
|---|
 | 130 |         wxBoxSizer * r4 = new wxBoxSizer(wxHORIZONTAL); | 
|---|
| [fbc1d32] | 131 |         r4->Add(new wxStaticText(this, 616, wmsg(/*Scale*/154) + wxT(": ")), 0, wxALIGN_CENTRE_VERTICAL); | 
|---|
| [9521a42] | 132 |         r4->Add(scale); | 
|---|
| [857408e] | 133 |         r4->Add(new wxStaticText(this, 617, wmsg(/* (unused in perspective view)*/278)), | 
|---|
| [9521a42] | 134 |                 0, wxALIGN_CENTRE_VERTICAL); | 
|---|
 | 135 |         vert->Add(r4, 0, wxALL, 8); | 
|---|
 | 136 |  | 
|---|
 | 137 |         wxBoxSizer * r5 = new wxBoxSizer(wxHORIZONTAL); | 
|---|
| [857408e] | 138 |         r5->Add(new wxStaticText(this, 616, wmsg(/*Time: */279)), 0, wxALIGN_CENTRE_VERTICAL); | 
|---|
| [49ce5b0] | 139 |         r5->Add(time); | 
|---|
| [857408e] | 140 |         r5->Add(new wxStaticText(this, 617, wmsg(/* secs (0 = auto; *6 = 6 times auto)*/282)), | 
|---|
| [49ce5b0] | 141 |                 0, wxALIGN_CENTRE_VERTICAL); | 
|---|
 | 142 |         vert->Add(r5, 0, wxALL, 8); | 
|---|
 | 143 |  | 
|---|
 | 144 |         wxBoxSizer * buttons = new wxBoxSizer(wxHORIZONTAL); | 
|---|
| [73b3388] | 145 |         wxButton* cancel = new wxButton(this, wxID_CANCEL); | 
|---|
| [49ce5b0] | 146 |         buttons->Add(cancel, 0, wxALL, 8); | 
|---|
| [73b3388] | 147 |         wxButton* ok = new wxButton(this, wxID_OK); | 
|---|
| [9521a42] | 148 |         ok->SetDefault(); | 
|---|
| [49ce5b0] | 149 |         buttons->Add(ok, 0, wxALL, 8); | 
|---|
 | 150 |         vert->Add(buttons, 0, wxALL|wxALIGN_RIGHT); | 
|---|
| [9521a42] | 151 |  | 
|---|
 | 152 |         SetAutoLayout(true); | 
|---|
 | 153 |         SetSizer(vert); | 
|---|
 | 154 |  | 
|---|
 | 155 |         vert->Fit(this); | 
|---|
 | 156 |         vert->SetSizeHints(this); | 
|---|
| [128fac4] | 157 |     } | 
|---|
| [9521a42] | 158 |     PresentationMark GetMark() const { | 
|---|
| [d67450e] | 159 |         double a, t, s, T; | 
|---|
| [318ac31] | 160 |         Vector3 v(atof(easting->GetValue().mb_str()), | 
|---|
 | 161 |                   atof(northing->GetValue().mb_str()), | 
|---|
 | 162 |                   atof(altitude->GetValue().mb_str())); | 
|---|
 | 163 |         a = atof(angle->GetValue().mb_str()); | 
|---|
 | 164 |         t = atof(tilt_angle->GetValue().mb_str()); | 
|---|
 | 165 |         s = atof(scale->GetValue().mb_str()); | 
|---|
| [49ce5b0] | 166 |         wxString str = time->GetValue(); | 
|---|
| [e60254e] | 167 |         if (!str.empty() && str[0u] == '*') str[0u] = '-'; | 
|---|
| [318ac31] | 168 |         T = atof(str.mb_str()); | 
|---|
| [d67450e] | 169 |         return PresentationMark(v, a, t, s, T); | 
|---|
| [9521a42] | 170 |     } | 
|---|
 | 171 |  | 
|---|
 | 172 | private: | 
|---|
 | 173 |     DECLARE_EVENT_TABLE() | 
|---|
 | 174 | }; | 
|---|
 | 175 |  | 
|---|
| [3fdeb44d] | 176 | // Write a value without trailing zeros after the decimal point. | 
|---|
 | 177 | static void write_double(double d, FILE * fh) { | 
|---|
 | 178 |     char buf[64]; | 
|---|
 | 179 |     sprintf(buf, "%.21f", d); | 
|---|
| [c988ae4] | 180 |     char * p = strchr(buf, ','); | 
|---|
 | 181 |     if (p) *p = '.'; | 
|---|
| [3fdeb44d] | 182 |     size_t l = strlen(buf); | 
|---|
 | 183 |     while (l > 1 && buf[l - 1] == '0') --l; | 
|---|
 | 184 |     if (l > 1 && buf[l - 1] == '.') --l; | 
|---|
 | 185 |     fwrite(buf, l, 1, fh); | 
|---|
 | 186 | } | 
|---|
 | 187 |  | 
|---|
| [1c6b20d7] | 188 | class AvenPresList : public wxListCtrl { | 
|---|
 | 189 |     MainFrm * mainfrm; | 
|---|
| [1690fa9] | 190 |     GfxCore * gfx; | 
|---|
| [9521a42] | 191 |     vector<PresentationMark> entries; | 
|---|
| [1690fa9] | 192 |     long current_item; | 
|---|
 | 193 |     bool modified; | 
|---|
| [bd7607c] | 194 |     bool force_save_as; | 
|---|
| [1690fa9] | 195 |     wxString filename; | 
|---|
| [f433fda] | 196 |  | 
|---|
| [1690fa9] | 197 |     public: | 
|---|
| [1c6b20d7] | 198 |         AvenPresList(MainFrm * mainfrm_, wxWindow * parent, GfxCore * gfx_) | 
|---|
| [1690fa9] | 199 |             : wxListCtrl(parent, listctrl_PRES, wxDefaultPosition, wxDefaultSize, | 
|---|
| [9521a42] | 200 |                          wxLC_REPORT|wxLC_VIRTUAL), | 
|---|
| [bd7607c] | 201 |               mainfrm(mainfrm_), gfx(gfx_), current_item(-1), modified(false), | 
|---|
 | 202 |               force_save_as(true) | 
|---|
| [1690fa9] | 203 |             { | 
|---|
| [5627cbb] | 204 |                 InsertColumn(0, wmsg(/*Easting*/378)); | 
|---|
 | 205 |                 InsertColumn(1, wmsg(/*Northing*/379)); | 
|---|
 | 206 |                 InsertColumn(2, wmsg(/*Altitude*/335)); | 
|---|
| [1690fa9] | 207 |             } | 
|---|
 | 208 |  | 
|---|
 | 209 |         void OnBeginLabelEdit(wxListEvent& event) { | 
|---|
 | 210 |             event.Veto(); // No editting allowed | 
|---|
 | 211 |         } | 
|---|
 | 212 |         void OnDeleteItem(wxListEvent& event) { | 
|---|
 | 213 |             long item = event.GetIndex(); | 
|---|
 | 214 |             if (current_item == item) { | 
|---|
 | 215 |                 current_item = -1; | 
|---|
 | 216 |             } else if (current_item > item) { | 
|---|
 | 217 |                 --current_item; | 
|---|
 | 218 |             } | 
|---|
| [9521a42] | 219 |             entries.erase(entries.begin() + item); | 
|---|
 | 220 |             SetItemCount(entries.size()); | 
|---|
| [1690fa9] | 221 |             modified = true; | 
|---|
 | 222 |         } | 
|---|
| [41f7a27] | 223 |         void OnDeleteAllItems(wxListEvent&) { | 
|---|
| [1690fa9] | 224 |             entries.clear(); | 
|---|
| [9521a42] | 225 |             SetItemCount(entries.size()); | 
|---|
| [5627cbb] | 226 |             filename = wxString(); | 
|---|
| [1690fa9] | 227 |             modified = false; | 
|---|
| [bd7607c] | 228 |             force_save_as = true; | 
|---|
| [1690fa9] | 229 |         } | 
|---|
 | 230 |         void OnListKeyDown(wxListEvent& event) { | 
|---|
 | 231 |             switch (event.GetKeyCode()) { | 
|---|
 | 232 |                 case WXK_DELETE: { | 
|---|
 | 233 |                     long item = GetNextItem(-1, wxLIST_NEXT_ALL, | 
|---|
 | 234 |                                             wxLIST_STATE_SELECTED); | 
|---|
 | 235 |                     while (item != -1) { | 
|---|
 | 236 |                         DeleteItem(item); | 
|---|
 | 237 |                         // - 1 because the indices were shifted by DeleteItem() | 
|---|
 | 238 |                         item = GetNextItem(item - 1, wxLIST_NEXT_ALL, | 
|---|
 | 239 |                                            wxLIST_STATE_SELECTED); | 
|---|
 | 240 |                     } | 
|---|
 | 241 |                     break; | 
|---|
 | 242 |                 } | 
|---|
 | 243 |                 default: | 
|---|
| [c8f929b] | 244 |                     //printf("event.GetIndex() = %ld %d\n", event.GetIndex(), event.GetKeyCode()); | 
|---|
| [1690fa9] | 245 |                     event.Skip(); | 
|---|
 | 246 |             } | 
|---|
 | 247 |         } | 
|---|
 | 248 |         void OnActivated(wxListEvent& event) { | 
|---|
 | 249 |             // Jump to this view. | 
|---|
 | 250 |             long item = event.GetIndex(); | 
|---|
| [9521a42] | 251 |             gfx->SetView(entries[item]); | 
|---|
| [1690fa9] | 252 |         } | 
|---|
 | 253 |         void OnFocused(wxListEvent& event) { | 
|---|
 | 254 |             current_item = event.GetIndex(); | 
|---|
 | 255 |         } | 
|---|
| [9521a42] | 256 |         void OnRightClick(wxListEvent& event) { | 
|---|
 | 257 |             long item = event.GetIndex(); | 
|---|
| [f7d52a1] | 258 |             if (item < 0) { | 
|---|
 | 259 |                 AddMark(item, gfx->GetView()); | 
|---|
 | 260 |                 item = 0; | 
|---|
 | 261 |             } | 
|---|
| [9521a42] | 262 |             EditMarkDlg edit(mainfrm, entries[item]); | 
|---|
 | 263 |             if (edit.ShowModal() == wxID_OK) { | 
|---|
 | 264 |                 entries[item] = edit.GetMark(); | 
|---|
 | 265 |             } | 
|---|
 | 266 |         } | 
|---|
| [1690fa9] | 267 |         void OnChar(wxKeyEvent& event) { | 
|---|
| [c8f929b] | 268 |             switch (event.GetKeyCode()) { | 
|---|
 | 269 |                 case WXK_INSERT: | 
|---|
| [a6e8d45] | 270 |                     if (event.GetModifiers() == wxMOD_CONTROL) { | 
|---|
| [c8f929b] | 271 |                         if (current_item != -1 && | 
|---|
 | 272 |                             size_t(current_item) < entries.size()) { | 
|---|
 | 273 |                             AddMark(current_item, entries[current_item]); | 
|---|
 | 274 |                         } | 
|---|
 | 275 |                     } else { | 
|---|
 | 276 |                         AddMark(current_item); | 
|---|
 | 277 |                     } | 
|---|
 | 278 |                     break; | 
|---|
 | 279 |                 case WXK_DELETE: | 
|---|
 | 280 |                     // Already handled in OnListKeyDown. | 
|---|
 | 281 |                     break; | 
|---|
 | 282 |                 case WXK_UP: case WXK_DOWN: | 
|---|
 | 283 |                     event.Skip(); | 
|---|
 | 284 |                     break; | 
|---|
 | 285 |                 default: | 
|---|
 | 286 |                     gfx->OnKeyPress(event); | 
|---|
| [5e31bd2] | 287 |             } | 
|---|
| [1690fa9] | 288 |         } | 
|---|
 | 289 |         void AddMark(long item = -1) { | 
|---|
 | 290 |             AddMark(item, gfx->GetView()); | 
|---|
 | 291 |         } | 
|---|
 | 292 |         void AddMark(long item, const PresentationMark & mark) { | 
|---|
| [9521a42] | 293 |             if (item == -1) item = entries.size(); | 
|---|
 | 294 |             entries.insert(entries.begin() + item, mark); | 
|---|
 | 295 |             SetItemCount(entries.size()); | 
|---|
| [1690fa9] | 296 |             modified = true; | 
|---|
 | 297 |         } | 
|---|
| [9521a42] | 298 |         virtual wxString OnGetItemText(long item, long column) const { | 
|---|
| [5627cbb] | 299 |             if (item < 0 || item >= (long)entries.size()) return wxString(); | 
|---|
| [9521a42] | 300 |             const PresentationMark & p = entries[item]; | 
|---|
 | 301 |             double v; | 
|---|
 | 302 |             switch (column) { | 
|---|
| [d67450e] | 303 |                 case 0: v = p.GetX(); break; | 
|---|
 | 304 |                 case 1: v = p.GetY(); break; | 
|---|
 | 305 |                 case 2: v = p.GetZ(); break; | 
|---|
| [9521a42] | 306 | #if 0 | 
|---|
 | 307 |                 case 3: v = p.angle; break; | 
|---|
 | 308 |                 case 4: v = p.tilt_angle; break; | 
|---|
 | 309 |                 case 5: v = p.scale; break; | 
|---|
| [49ce5b0] | 310 |                 case 6: v = p.time; break; | 
|---|
| [9521a42] | 311 | #endif | 
|---|
| [5627cbb] | 312 |                 default: return wxString(); | 
|---|
| [9521a42] | 313 |             } | 
|---|
| [5627cbb] | 314 |             return wxString::Format(wxT("%ld"), (long)v); | 
|---|
| [9521a42] | 315 |         } | 
|---|
| [1690fa9] | 316 |         void Save(bool use_default_name) { | 
|---|
 | 317 |             wxString fnm = filename; | 
|---|
| [bd7607c] | 318 |             if (!use_default_name || force_save_as) { | 
|---|
| [1c6b20d7] | 319 |                 AvenAllowOnTop ontop(mainfrm); | 
|---|
| [1690fa9] | 320 | #ifdef __WXMOTIF__ | 
|---|
| [5627cbb] | 321 |                 wxString ext(wxT("*.fly")); | 
|---|
| [1690fa9] | 322 | #else | 
|---|
| [5627cbb] | 323 |                 wxString ext = wmsg(/*Aven presentations*/320); | 
|---|
| [52f67931] | 324 |                 ext += wxT("|*.fly"); | 
|---|
| [1690fa9] | 325 | #endif | 
|---|
| [5627cbb] | 326 |                 wxFileDialog dlg(this, wmsg(/*Select an output filename*/319), | 
|---|
 | 327 |                                  wxString(), fnm, ext, | 
|---|
 | 328 |                                  wxFD_SAVE|wxFD_OVERWRITE_PROMPT); | 
|---|
| [1690fa9] | 329 |                 if (dlg.ShowModal() != wxID_OK) return; | 
|---|
 | 330 |                 fnm = dlg.GetPath(); | 
|---|
 | 331 |             } | 
|---|
 | 332 |  | 
|---|
| [36c4cf1] | 333 | #ifdef __WXMSW__ | 
|---|
 | 334 |             FILE * fh_pres = _wfopen(fnm.fn_str(), L"w"); | 
|---|
 | 335 | #else | 
|---|
| [318ac31] | 336 |             FILE * fh_pres = fopen(fnm.mb_str(), "w"); | 
|---|
| [36c4cf1] | 337 | #endif | 
|---|
| [1690fa9] | 338 |             if (!fh_pres) { | 
|---|
| [0804fbe] | 339 |                 wxGetApp().ReportError(wxString::Format(wmsg(/*Error writing to file “%s”*/110), fnm.c_str())); | 
|---|
| [1690fa9] | 340 |                 return; | 
|---|
 | 341 |             } | 
|---|
| [9521a42] | 342 |             vector<PresentationMark>::const_iterator i; | 
|---|
| [1690fa9] | 343 |             for (i = entries.begin(); i != entries.end(); ++i) { | 
|---|
 | 344 |                 const PresentationMark &p = *i; | 
|---|
| [d67450e] | 345 |                 write_double(p.GetX(), fh_pres); | 
|---|
| [e02a6a6] | 346 |                 PUTC(' ', fh_pres); | 
|---|
| [d67450e] | 347 |                 write_double(p.GetY(), fh_pres); | 
|---|
| [e02a6a6] | 348 |                 PUTC(' ', fh_pres); | 
|---|
| [d67450e] | 349 |                 write_double(p.GetZ(), fh_pres); | 
|---|
| [e02a6a6] | 350 |                 PUTC(' ', fh_pres); | 
|---|
| [3fdeb44d] | 351 |                 write_double(p.angle, fh_pres); | 
|---|
| [e02a6a6] | 352 |                 PUTC(' ', fh_pres); | 
|---|
| [3fdeb44d] | 353 |                 write_double(p.tilt_angle, fh_pres); | 
|---|
| [e02a6a6] | 354 |                 PUTC(' ', fh_pres); | 
|---|
| [3fdeb44d] | 355 |                 write_double(p.scale, fh_pres); | 
|---|
| [49ce5b0] | 356 |                 if (p.time != 0.0) { | 
|---|
| [e02a6a6] | 357 |                     PUTC(' ', fh_pres); | 
|---|
| [49ce5b0] | 358 |                     write_double(p.time, fh_pres); | 
|---|
 | 359 |                 } | 
|---|
| [e02a6a6] | 360 |                 PUTC('\n', fh_pres); | 
|---|
| [1690fa9] | 361 |             } | 
|---|
 | 362 |             fclose(fh_pres); | 
|---|
 | 363 |             filename = fnm; | 
|---|
 | 364 |             modified = false; | 
|---|
| [bd7607c] | 365 |             force_save_as = false; | 
|---|
 | 366 |         } | 
|---|
 | 367 |         void New(const wxString &fnm) { | 
|---|
 | 368 |             DeleteAllItems(); | 
|---|
| [d3172cc] | 369 |             wxFileName::SplitPath(fnm, NULL, NULL, &filename, NULL, wxPATH_NATIVE); | 
|---|
| [5627cbb] | 370 |             filename += wxT(".fly"); | 
|---|
| [bd7607c] | 371 |             force_save_as = true; | 
|---|
| [1690fa9] | 372 |         } | 
|---|
 | 373 |         bool Load(const wxString &fnm) { | 
|---|
| [36c4cf1] | 374 | #ifdef __WXMSW__ | 
|---|
 | 375 |             FILE * fh_pres = _wfopen(fnm.fn_str(), L"r"); | 
|---|
 | 376 | #else | 
|---|
| [318ac31] | 377 |             FILE * fh_pres = fopen(fnm.mb_str(), "r"); | 
|---|
| [36c4cf1] | 378 | #endif | 
|---|
| [9b540e6] | 379 |             if (!fh_pres) { | 
|---|
 | 380 |                 wxString m; | 
|---|
| [ee7511a] | 381 |                 m.Printf(wmsg(/*Couldn’t open file “%s”*/93), fnm.c_str()); | 
|---|
| [9b540e6] | 382 |                 wxGetApp().ReportError(m); | 
|---|
 | 383 |                 return false; | 
|---|
 | 384 |             } | 
|---|
| [1690fa9] | 385 |             DeleteAllItems(); | 
|---|
 | 386 |             long item = 0; | 
|---|
 | 387 |             while (!feof(fh_pres)) { | 
|---|
 | 388 |                 char buf[4096]; | 
|---|
 | 389 |                 size_t i = 0; | 
|---|
 | 390 |                 while (i < sizeof(buf) - 1) { | 
|---|
| [e02a6a6] | 391 |                     int ch = GETC(fh_pres); | 
|---|
| [1690fa9] | 392 |                     if (ch == EOF || ch == '\n' || ch == '\r') break; | 
|---|
 | 393 |                     buf[i++] = ch; | 
|---|
 | 394 |                 } | 
|---|
 | 395 |                 if (i) { | 
|---|
 | 396 |                     buf[i] = 0; | 
|---|
| [49ce5b0] | 397 |                     double x, y, z, a, t, s, T; | 
|---|
 | 398 |                     int c = sscanf(buf, "%lf %lf %lf %lf %lf %lf %lf", &x, &y, &z, &a, &t, &s, &T); | 
|---|
 | 399 |                     if (c < 6) { | 
|---|
| [c988ae4] | 400 |                         char *p = buf; | 
|---|
 | 401 |                         while ((p = strchr(p, '.'))) *p++ = ','; | 
|---|
 | 402 |                         c = sscanf(buf, "%lf %lf %lf %lf %lf %lf %lf", &x, &y, &z, &a, &t, &s, &T); | 
|---|
 | 403 |                         if (c < 6) { | 
|---|
 | 404 |                             DeleteAllItems(); | 
|---|
| [0804fbe] | 405 |                             wxGetApp().ReportError(wxString::Format(wmsg(/*Error in format of presentation file “%s”*/323), fnm.c_str())); | 
|---|
| [c988ae4] | 406 |                             return false; | 
|---|
 | 407 |                         } | 
|---|
| [1690fa9] | 408 |                     } | 
|---|
| [49ce5b0] | 409 |                     if (c == 6) T = 0; | 
|---|
| [d67450e] | 410 |                     AddMark(item, PresentationMark(Vector3(x, y, z), a, t, s, T)); | 
|---|
| [9b540e6] | 411 |                     ++item; | 
|---|
| [1690fa9] | 412 |                 } | 
|---|
 | 413 |             } | 
|---|
 | 414 |             fclose(fh_pres); | 
|---|
 | 415 |             filename = fnm; | 
|---|
 | 416 |             modified = false; | 
|---|
| [bd7607c] | 417 |             force_save_as = false; | 
|---|
| [1690fa9] | 418 |             return true; | 
|---|
 | 419 |         } | 
|---|
 | 420 |         bool Modified() const { return modified; } | 
|---|
 | 421 |         bool Empty() const { return entries.empty(); } | 
|---|
 | 422 |         PresentationMark GetPresMark(int which) { | 
|---|
 | 423 |             long item = current_item; | 
|---|
 | 424 |             if (which == MARK_FIRST) { | 
|---|
 | 425 |                 item = 0; | 
|---|
 | 426 |             } else if (which == MARK_NEXT) { | 
|---|
| [9521a42] | 427 |                 ++item; | 
|---|
| [128fac4] | 428 |             } else if (which == MARK_PREV) { | 
|---|
 | 429 |                 --item; | 
|---|
| [1690fa9] | 430 |             } | 
|---|
| [128fac4] | 431 |             if (item == -1 || item == (long)entries.size()) | 
|---|
 | 432 |                 return PresentationMark(); | 
|---|
| [1690fa9] | 433 |             if (item != current_item) { | 
|---|
 | 434 |                 // Move the focus | 
|---|
 | 435 |                 if (current_item != -1) { | 
|---|
 | 436 |                     wxListCtrl::SetItemState(current_item, wxLIST_STATE_FOCUSED, | 
|---|
 | 437 |                                              0); | 
|---|
 | 438 |                 } | 
|---|
 | 439 |                 wxListCtrl::SetItemState(item, wxLIST_STATE_FOCUSED, | 
|---|
 | 440 |                                          wxLIST_STATE_FOCUSED); | 
|---|
 | 441 |             } | 
|---|
| [9521a42] | 442 |             return entries[item]; | 
|---|
| [1690fa9] | 443 |         } | 
|---|
 | 444 |  | 
|---|
 | 445 |     private: | 
|---|
 | 446 |  | 
|---|
| [1c6b20d7] | 447 |         DECLARE_NO_COPY_CLASS(AvenPresList) | 
|---|
| [1690fa9] | 448 |         DECLARE_EVENT_TABLE() | 
|---|
 | 449 | }; | 
|---|
| [f433fda] | 450 |  | 
|---|
| [9521a42] | 451 | BEGIN_EVENT_TABLE(EditMarkDlg, wxDialog) | 
|---|
 | 452 | END_EVENT_TABLE() | 
|---|
 | 453 |  | 
|---|
| [1c6b20d7] | 454 | BEGIN_EVENT_TABLE(AvenPresList, wxListCtrl) | 
|---|
 | 455 |     EVT_LIST_BEGIN_LABEL_EDIT(listctrl_PRES, AvenPresList::OnBeginLabelEdit) | 
|---|
 | 456 |     EVT_LIST_DELETE_ITEM(listctrl_PRES, AvenPresList::OnDeleteItem) | 
|---|
 | 457 |     EVT_LIST_DELETE_ALL_ITEMS(listctrl_PRES, AvenPresList::OnDeleteAllItems) | 
|---|
 | 458 |     EVT_LIST_KEY_DOWN(listctrl_PRES, AvenPresList::OnListKeyDown) | 
|---|
 | 459 |     EVT_LIST_ITEM_ACTIVATED(listctrl_PRES, AvenPresList::OnActivated) | 
|---|
 | 460 |     EVT_LIST_ITEM_FOCUSED(listctrl_PRES, AvenPresList::OnFocused) | 
|---|
| [9521a42] | 461 |     EVT_LIST_ITEM_RIGHT_CLICK(listctrl_PRES, AvenPresList::OnRightClick) | 
|---|
| [1c6b20d7] | 462 |     EVT_CHAR(AvenPresList::OnChar) | 
|---|
| [1690fa9] | 463 | END_EVENT_TABLE() | 
|---|
 | 464 |  | 
|---|
| [137bf99] | 465 | BEGIN_EVENT_TABLE(MainFrm, wxFrame) | 
|---|
| [d1628e8e] | 466 |     EVT_TEXT(textctrl_FIND, MainFrm::OnFind) | 
|---|
 | 467 |     EVT_TEXT_ENTER(textctrl_FIND, MainFrm::OnGotoFound) | 
|---|
| [42c7efe] | 468 |     EVT_MENU(wxID_FIND, MainFrm::OnGotoFound) | 
|---|
| [8e1a10e] | 469 |     EVT_MENU(button_HIDE, MainFrm::OnHide) | 
|---|
| [429465a] | 470 |     EVT_UPDATE_UI(button_HIDE, MainFrm::OnHideUpdate) | 
|---|
| [bc60689] | 471 |     EVT_IDLE(MainFrm::OnIdle) | 
|---|
| [2a02de2] | 472 |  | 
|---|
| [42c7efe] | 473 |     EVT_MENU(wxID_OPEN, MainFrm::OnOpen) | 
|---|
 | 474 |     EVT_MENU(wxID_PRINT, MainFrm::OnPrint) | 
|---|
| [ce403f1] | 475 |     EVT_MENU(menu_FILE_PAGE_SETUP, MainFrm::OnPageSetup) | 
|---|
| [045e2af] | 476 |     EVT_MENU(menu_FILE_SCREENSHOT, MainFrm::OnScreenshot) | 
|---|
| [42c7efe] | 477 | //    EVT_MENU(wxID_PREFERENCES, MainFrm::OnFilePreferences) | 
|---|
| [223f1ad] | 478 |     EVT_MENU(menu_FILE_EXPORT, MainFrm::OnExport) | 
|---|
| [42c7efe] | 479 |     EVT_MENU(wxID_EXIT, MainFrm::OnQuit) | 
|---|
| [732b9b0] | 480 |     EVT_MENU_RANGE(wxID_FILE1, wxID_FILE9, MainFrm::OnMRUFile) | 
|---|
| [137bf99] | 481 |  | 
|---|
| [1690fa9] | 482 |     EVT_MENU(menu_PRES_NEW, MainFrm::OnPresNew) | 
|---|
 | 483 |     EVT_MENU(menu_PRES_OPEN, MainFrm::OnPresOpen) | 
|---|
 | 484 |     EVT_MENU(menu_PRES_SAVE, MainFrm::OnPresSave) | 
|---|
 | 485 |     EVT_MENU(menu_PRES_SAVE_AS, MainFrm::OnPresSaveAs) | 
|---|
 | 486 |     EVT_MENU(menu_PRES_MARK, MainFrm::OnPresMark) | 
|---|
| [128fac4] | 487 |     EVT_MENU(menu_PRES_FREWIND, MainFrm::OnPresFRewind) | 
|---|
 | 488 |     EVT_MENU(menu_PRES_REWIND, MainFrm::OnPresRewind) | 
|---|
 | 489 |     EVT_MENU(menu_PRES_REVERSE, MainFrm::OnPresReverse) | 
|---|
 | 490 |     EVT_MENU(menu_PRES_PLAY, MainFrm::OnPresPlay) | 
|---|
 | 491 |     EVT_MENU(menu_PRES_FF, MainFrm::OnPresFF) | 
|---|
 | 492 |     EVT_MENU(menu_PRES_FFF, MainFrm::OnPresFFF) | 
|---|
 | 493 |     EVT_MENU(menu_PRES_PAUSE, MainFrm::OnPresPause) | 
|---|
| [42c7efe] | 494 |     EVT_MENU(wxID_STOP, MainFrm::OnPresStop) | 
|---|
| [6a4cdcb6] | 495 |     EVT_MENU(menu_PRES_EXPORT_MOVIE, MainFrm::OnPresExportMovie) | 
|---|
| [1690fa9] | 496 |  | 
|---|
 | 497 |     EVT_UPDATE_UI(menu_PRES_NEW, MainFrm::OnPresNewUpdate) | 
|---|
 | 498 |     EVT_UPDATE_UI(menu_PRES_OPEN, MainFrm::OnPresOpenUpdate) | 
|---|
 | 499 |     EVT_UPDATE_UI(menu_PRES_SAVE, MainFrm::OnPresSaveUpdate) | 
|---|
 | 500 |     EVT_UPDATE_UI(menu_PRES_SAVE_AS, MainFrm::OnPresSaveAsUpdate) | 
|---|
 | 501 |     EVT_UPDATE_UI(menu_PRES_MARK, MainFrm::OnPresMarkUpdate) | 
|---|
| [128fac4] | 502 |     EVT_UPDATE_UI(menu_PRES_FREWIND, MainFrm::OnPresFRewindUpdate) | 
|---|
 | 503 |     EVT_UPDATE_UI(menu_PRES_REWIND, MainFrm::OnPresRewindUpdate) | 
|---|
 | 504 |     EVT_UPDATE_UI(menu_PRES_REVERSE, MainFrm::OnPresReverseUpdate) | 
|---|
 | 505 |     EVT_UPDATE_UI(menu_PRES_PLAY, MainFrm::OnPresPlayUpdate) | 
|---|
 | 506 |     EVT_UPDATE_UI(menu_PRES_FF, MainFrm::OnPresFFUpdate) | 
|---|
 | 507 |     EVT_UPDATE_UI(menu_PRES_FFF, MainFrm::OnPresFFFUpdate) | 
|---|
 | 508 |     EVT_UPDATE_UI(menu_PRES_PAUSE, MainFrm::OnPresPauseUpdate) | 
|---|
| [42c7efe] | 509 |     EVT_UPDATE_UI(wxID_STOP, MainFrm::OnPresStopUpdate) | 
|---|
| [6a4cdcb6] | 510 |     EVT_UPDATE_UI(menu_PRES_EXPORT_MOVIE, MainFrm::OnPresExportMovieUpdate) | 
|---|
| [5ffa439] | 511 |  | 
|---|
| [137bf99] | 512 |     EVT_CLOSE(MainFrm::OnClose) | 
|---|
| [4b1fc48] | 513 |     EVT_SET_FOCUS(MainFrm::OnSetFocus) | 
|---|
| [137bf99] | 514 |  | 
|---|
| [7ebc3d1] | 515 |     EVT_MENU(menu_ROTATION_TOGGLE, MainFrm::OnToggleRotation) | 
|---|
| [137bf99] | 516 |     EVT_MENU(menu_ROTATION_SPEED_UP, MainFrm::OnSpeedUp) | 
|---|
 | 517 |     EVT_MENU(menu_ROTATION_SLOW_DOWN, MainFrm::OnSlowDown) | 
|---|
 | 518 |     EVT_MENU(menu_ROTATION_REVERSE, MainFrm::OnReverseDirectionOfRotation) | 
|---|
 | 519 |     EVT_MENU(menu_ROTATION_STEP_CCW, MainFrm::OnStepOnceAnticlockwise) | 
|---|
 | 520 |     EVT_MENU(menu_ROTATION_STEP_CW, MainFrm::OnStepOnceClockwise) | 
|---|
 | 521 |     EVT_MENU(menu_ORIENT_MOVE_NORTH, MainFrm::OnMoveNorth) | 
|---|
 | 522 |     EVT_MENU(menu_ORIENT_MOVE_EAST, MainFrm::OnMoveEast) | 
|---|
 | 523 |     EVT_MENU(menu_ORIENT_MOVE_SOUTH, MainFrm::OnMoveSouth) | 
|---|
 | 524 |     EVT_MENU(menu_ORIENT_MOVE_WEST, MainFrm::OnMoveWest) | 
|---|
 | 525 |     EVT_MENU(menu_ORIENT_SHIFT_LEFT, MainFrm::OnShiftDisplayLeft) | 
|---|
 | 526 |     EVT_MENU(menu_ORIENT_SHIFT_RIGHT, MainFrm::OnShiftDisplayRight) | 
|---|
 | 527 |     EVT_MENU(menu_ORIENT_SHIFT_UP, MainFrm::OnShiftDisplayUp) | 
|---|
 | 528 |     EVT_MENU(menu_ORIENT_SHIFT_DOWN, MainFrm::OnShiftDisplayDown) | 
|---|
 | 529 |     EVT_MENU(menu_ORIENT_PLAN, MainFrm::OnPlan) | 
|---|
 | 530 |     EVT_MENU(menu_ORIENT_ELEVATION, MainFrm::OnElevation) | 
|---|
 | 531 |     EVT_MENU(menu_ORIENT_HIGHER_VP, MainFrm::OnHigherViewpoint) | 
|---|
 | 532 |     EVT_MENU(menu_ORIENT_LOWER_VP, MainFrm::OnLowerViewpoint) | 
|---|
| [42c7efe] | 533 |     EVT_MENU(wxID_ZOOM_IN, MainFrm::OnZoomIn) | 
|---|
 | 534 |     EVT_MENU(wxID_ZOOM_OUT, MainFrm::OnZoomOut) | 
|---|
| [137bf99] | 535 |     EVT_MENU(menu_ORIENT_DEFAULTS, MainFrm::OnDefaults) | 
|---|
 | 536 |     EVT_MENU(menu_VIEW_SHOW_LEGS, MainFrm::OnShowSurveyLegs) | 
|---|
| [8666fc7] | 537 |     EVT_MENU(menu_SPLAYS_HIDE, MainFrm::OnHideSplays) | 
|---|
 | 538 |     EVT_MENU(menu_SPLAYS_SHOW_NORMAL, MainFrm::OnShowSplaysNormal) | 
|---|
 | 539 |     EVT_MENU(menu_SPLAYS_SHOW_FADED, MainFrm::OnShowSplaysFaded) | 
|---|
| [137bf99] | 540 |     EVT_MENU(menu_VIEW_SHOW_CROSSES, MainFrm::OnShowCrosses) | 
|---|
| [fe444b8] | 541 |     EVT_MENU(menu_VIEW_SHOW_ENTRANCES, MainFrm::OnShowEntrances) | 
|---|
 | 542 |     EVT_MENU(menu_VIEW_SHOW_FIXED_PTS, MainFrm::OnShowFixedPts) | 
|---|
 | 543 |     EVT_MENU(menu_VIEW_SHOW_EXPORTED_PTS, MainFrm::OnShowExportedPts) | 
|---|
| [137bf99] | 544 |     EVT_MENU(menu_VIEW_SHOW_NAMES, MainFrm::OnShowStationNames) | 
|---|
 | 545 |     EVT_MENU(menu_VIEW_SHOW_OVERLAPPING_NAMES, MainFrm::OnDisplayOverlappingNames) | 
|---|
| [da6c802] | 546 |     EVT_MENU(menu_VIEW_COLOUR_BY_DEPTH, MainFrm::OnColourByDepth) | 
|---|
| [d4650b3] | 547 |     EVT_MENU(menu_VIEW_COLOUR_BY_DATE, MainFrm::OnColourByDate) | 
|---|
| [c61aa79] | 548 |     EVT_MENU(menu_VIEW_COLOUR_BY_ERROR, MainFrm::OnColourByError) | 
|---|
| [137bf99] | 549 |     EVT_MENU(menu_VIEW_SHOW_SURFACE, MainFrm::OnShowSurface) | 
|---|
| [c1cf79d] | 550 |     EVT_MENU(menu_VIEW_GRID, MainFrm::OnViewGrid) | 
|---|
| [f4c5932] | 551 |     EVT_MENU(menu_VIEW_BOUNDING_BOX, MainFrm::OnViewBoundingBox) | 
|---|
| [6abab84] | 552 |     EVT_MENU(menu_VIEW_PERSPECTIVE, MainFrm::OnViewPerspective) | 
|---|
| [d67450e] | 553 |     EVT_MENU(menu_VIEW_SMOOTH_SHADING, MainFrm::OnViewSmoothShading) | 
|---|
| [a517825] | 554 |     EVT_MENU(menu_VIEW_TEXTURED, MainFrm::OnViewTextured) | 
|---|
| [c60062d] | 555 |     EVT_MENU(menu_VIEW_FOG, MainFrm::OnViewFog) | 
|---|
| [db452ae] | 556 |     EVT_MENU(menu_VIEW_SMOOTH_LINES, MainFrm::OnViewSmoothLines) | 
|---|
| [b13aee4] | 557 |     EVT_MENU(menu_VIEW_FULLSCREEN, MainFrm::OnViewFullScreen) | 
|---|
| [33b2094] | 558 |     EVT_MENU(menu_VIEW_SHOW_TUBES, MainFrm::OnToggleTubes) | 
|---|
| [7a36b67] | 559 |     EVT_MENU(menu_IND_COMPASS, MainFrm::OnViewCompass) | 
|---|
 | 560 |     EVT_MENU(menu_IND_CLINO, MainFrm::OnViewClino) | 
|---|
| [97ea48d] | 561 |     EVT_MENU(menu_IND_COLOUR_KEY, MainFrm::OnToggleColourKey) | 
|---|
| [7a36b67] | 562 |     EVT_MENU(menu_IND_SCALE_BAR, MainFrm::OnToggleScalebar) | 
|---|
 | 563 |     EVT_MENU(menu_CTL_SIDE_PANEL, MainFrm::OnViewSidePanel) | 
|---|
 | 564 |     EVT_MENU(menu_CTL_METRIC, MainFrm::OnToggleMetric) | 
|---|
 | 565 |     EVT_MENU(menu_CTL_DEGREES, MainFrm::OnToggleDegrees) | 
|---|
| [d171c0c] | 566 |     EVT_MENU(menu_CTL_PERCENT, MainFrm::OnTogglePercent) | 
|---|
| [137bf99] | 567 |     EVT_MENU(menu_CTL_REVERSE, MainFrm::OnReverseControls) | 
|---|
| [1fd2edb] | 568 |     EVT_MENU(menu_CTL_CANCEL_DIST_LINE, MainFrm::OnCancelDistLine) | 
|---|
| [42c7efe] | 569 |     EVT_MENU(wxID_ABOUT, MainFrm::OnAbout) | 
|---|
| [137bf99] | 570 |  | 
|---|
| [42c7efe] | 571 |     EVT_UPDATE_UI(wxID_PRINT, MainFrm::OnPrintUpdate) | 
|---|
| [045e2af] | 572 |     EVT_UPDATE_UI(menu_FILE_SCREENSHOT, MainFrm::OnScreenshotUpdate) | 
|---|
| [223f1ad] | 573 |     EVT_UPDATE_UI(menu_FILE_EXPORT, MainFrm::OnExportUpdate) | 
|---|
| [546a6f3] | 574 |     EVT_UPDATE_UI(menu_ROTATION_TOGGLE, MainFrm::OnToggleRotationUpdate) | 
|---|
| [137bf99] | 575 |     EVT_UPDATE_UI(menu_ROTATION_SPEED_UP, MainFrm::OnSpeedUpUpdate) | 
|---|
 | 576 |     EVT_UPDATE_UI(menu_ROTATION_SLOW_DOWN, MainFrm::OnSlowDownUpdate) | 
|---|
 | 577 |     EVT_UPDATE_UI(menu_ROTATION_REVERSE, MainFrm::OnReverseDirectionOfRotationUpdate) | 
|---|
 | 578 |     EVT_UPDATE_UI(menu_ROTATION_STEP_CCW, MainFrm::OnStepOnceAnticlockwiseUpdate) | 
|---|
 | 579 |     EVT_UPDATE_UI(menu_ROTATION_STEP_CW, MainFrm::OnStepOnceClockwiseUpdate) | 
|---|
 | 580 |     EVT_UPDATE_UI(menu_ORIENT_MOVE_NORTH, MainFrm::OnMoveNorthUpdate) | 
|---|
 | 581 |     EVT_UPDATE_UI(menu_ORIENT_MOVE_EAST, MainFrm::OnMoveEastUpdate) | 
|---|
 | 582 |     EVT_UPDATE_UI(menu_ORIENT_MOVE_SOUTH, MainFrm::OnMoveSouthUpdate) | 
|---|
 | 583 |     EVT_UPDATE_UI(menu_ORIENT_MOVE_WEST, MainFrm::OnMoveWestUpdate) | 
|---|
 | 584 |     EVT_UPDATE_UI(menu_ORIENT_SHIFT_LEFT, MainFrm::OnShiftDisplayLeftUpdate) | 
|---|
 | 585 |     EVT_UPDATE_UI(menu_ORIENT_SHIFT_RIGHT, MainFrm::OnShiftDisplayRightUpdate) | 
|---|
 | 586 |     EVT_UPDATE_UI(menu_ORIENT_SHIFT_UP, MainFrm::OnShiftDisplayUpUpdate) | 
|---|
 | 587 |     EVT_UPDATE_UI(menu_ORIENT_SHIFT_DOWN, MainFrm::OnShiftDisplayDownUpdate) | 
|---|
 | 588 |     EVT_UPDATE_UI(menu_ORIENT_PLAN, MainFrm::OnPlanUpdate) | 
|---|
 | 589 |     EVT_UPDATE_UI(menu_ORIENT_ELEVATION, MainFrm::OnElevationUpdate) | 
|---|
 | 590 |     EVT_UPDATE_UI(menu_ORIENT_HIGHER_VP, MainFrm::OnHigherViewpointUpdate) | 
|---|
 | 591 |     EVT_UPDATE_UI(menu_ORIENT_LOWER_VP, MainFrm::OnLowerViewpointUpdate) | 
|---|
| [42c7efe] | 592 |     EVT_UPDATE_UI(wxID_ZOOM_IN, MainFrm::OnZoomInUpdate) | 
|---|
 | 593 |     EVT_UPDATE_UI(wxID_ZOOM_OUT, MainFrm::OnZoomOutUpdate) | 
|---|
| [137bf99] | 594 |     EVT_UPDATE_UI(menu_ORIENT_DEFAULTS, MainFrm::OnDefaultsUpdate) | 
|---|
 | 595 |     EVT_UPDATE_UI(menu_VIEW_SHOW_LEGS, MainFrm::OnShowSurveyLegsUpdate) | 
|---|
| [9cb97b7] | 596 |     EVT_UPDATE_UI(menu_VIEW_SPLAYS, MainFrm::OnSplaysUpdate) | 
|---|
| [8666fc7] | 597 |     EVT_UPDATE_UI(menu_SPLAYS_HIDE, MainFrm::OnHideSplaysUpdate) | 
|---|
 | 598 |     EVT_UPDATE_UI(menu_SPLAYS_SHOW_NORMAL, MainFrm::OnShowSplaysNormalUpdate) | 
|---|
 | 599 |     EVT_UPDATE_UI(menu_SPLAYS_SHOW_FADED, MainFrm::OnShowSplaysFadedUpdate) | 
|---|
| [137bf99] | 600 |     EVT_UPDATE_UI(menu_VIEW_SHOW_CROSSES, MainFrm::OnShowCrossesUpdate) | 
|---|
| [fe444b8] | 601 |     EVT_UPDATE_UI(menu_VIEW_SHOW_ENTRANCES, MainFrm::OnShowEntrancesUpdate) | 
|---|
 | 602 |     EVT_UPDATE_UI(menu_VIEW_SHOW_FIXED_PTS, MainFrm::OnShowFixedPtsUpdate) | 
|---|
 | 603 |     EVT_UPDATE_UI(menu_VIEW_SHOW_EXPORTED_PTS, MainFrm::OnShowExportedPtsUpdate) | 
|---|
| [137bf99] | 604 |     EVT_UPDATE_UI(menu_VIEW_SHOW_NAMES, MainFrm::OnShowStationNamesUpdate) | 
|---|
 | 605 |     EVT_UPDATE_UI(menu_VIEW_SHOW_SURFACE, MainFrm::OnShowSurfaceUpdate) | 
|---|
 | 606 |     EVT_UPDATE_UI(menu_VIEW_SHOW_OVERLAPPING_NAMES, MainFrm::OnDisplayOverlappingNamesUpdate) | 
|---|
| [da6c802] | 607 |     EVT_UPDATE_UI(menu_VIEW_COLOUR_BY_DEPTH, MainFrm::OnColourByDepthUpdate) | 
|---|
| [d4650b3] | 608 |     EVT_UPDATE_UI(menu_VIEW_COLOUR_BY_DATE, MainFrm::OnColourByDateUpdate) | 
|---|
| [c61aa79] | 609 |     EVT_UPDATE_UI(menu_VIEW_COLOUR_BY_ERROR, MainFrm::OnColourByErrorUpdate) | 
|---|
| [c1cf79d] | 610 |     EVT_UPDATE_UI(menu_VIEW_GRID, MainFrm::OnViewGridUpdate) | 
|---|
| [f4c5932] | 611 |     EVT_UPDATE_UI(menu_VIEW_BOUNDING_BOX, MainFrm::OnViewBoundingBoxUpdate) | 
|---|
| [6abab84] | 612 |     EVT_UPDATE_UI(menu_VIEW_PERSPECTIVE, MainFrm::OnViewPerspectiveUpdate) | 
|---|
| [d67450e] | 613 |     EVT_UPDATE_UI(menu_VIEW_SMOOTH_SHADING, MainFrm::OnViewSmoothShadingUpdate) | 
|---|
| [a517825] | 614 |     EVT_UPDATE_UI(menu_VIEW_TEXTURED, MainFrm::OnViewTexturedUpdate) | 
|---|
| [c60062d] | 615 |     EVT_UPDATE_UI(menu_VIEW_FOG, MainFrm::OnViewFogUpdate) | 
|---|
| [db452ae] | 616 |     EVT_UPDATE_UI(menu_VIEW_SMOOTH_LINES, MainFrm::OnViewSmoothLinesUpdate) | 
|---|
| [b13aee4] | 617 |     EVT_UPDATE_UI(menu_VIEW_FULLSCREEN, MainFrm::OnViewFullScreenUpdate) | 
|---|
| [33b2094] | 618 |     EVT_UPDATE_UI(menu_VIEW_SHOW_TUBES, MainFrm::OnToggleTubesUpdate) | 
|---|
| [7a36b67] | 619 |     EVT_UPDATE_UI(menu_IND_COMPASS, MainFrm::OnViewCompassUpdate) | 
|---|
 | 620 |     EVT_UPDATE_UI(menu_IND_CLINO, MainFrm::OnViewClinoUpdate) | 
|---|
| [97ea48d] | 621 |     EVT_UPDATE_UI(menu_IND_COLOUR_KEY, MainFrm::OnToggleColourKeyUpdate) | 
|---|
| [7a36b67] | 622 |     EVT_UPDATE_UI(menu_IND_SCALE_BAR, MainFrm::OnToggleScalebarUpdate) | 
|---|
 | 623 |     EVT_UPDATE_UI(menu_CTL_INDICATORS, MainFrm::OnIndicatorsUpdate) | 
|---|
 | 624 |     EVT_UPDATE_UI(menu_CTL_SIDE_PANEL, MainFrm::OnViewSidePanelUpdate) | 
|---|
 | 625 |     EVT_UPDATE_UI(menu_CTL_REVERSE, MainFrm::OnReverseControlsUpdate) | 
|---|
 | 626 |     EVT_UPDATE_UI(menu_CTL_CANCEL_DIST_LINE, MainFrm::OnCancelDistLineUpdate) | 
|---|
 | 627 |     EVT_UPDATE_UI(menu_CTL_METRIC, MainFrm::OnToggleMetricUpdate) | 
|---|
 | 628 |     EVT_UPDATE_UI(menu_CTL_DEGREES, MainFrm::OnToggleDegreesUpdate) | 
|---|
| [d171c0c] | 629 |     EVT_UPDATE_UI(menu_CTL_PERCENT, MainFrm::OnTogglePercentUpdate) | 
|---|
| [5809313] | 630 | END_EVENT_TABLE() | 
|---|
 | 631 |  | 
|---|
| [63dc4eb] | 632 | class LabelCmp : public greater<const LabelInfo*> { | 
|---|
| [ff9f695] | 633 |     wxChar separator; | 
|---|
| [156dc16] | 634 | public: | 
|---|
| [ff9f695] | 635 |     LabelCmp(wxChar separator_) : separator(separator_) {} | 
|---|
| [156dc16] | 636 |     bool operator()(const LabelInfo* pt1, const LabelInfo* pt2) { | 
|---|
| [2f36993] | 637 |         return name_cmp(pt1->GetText(), pt2->GetText(), separator) < 0; | 
|---|
| [156dc16] | 638 |     } | 
|---|
 | 639 | }; | 
|---|
 | 640 |  | 
|---|
| [63dc4eb] | 641 | class LabelPlotCmp : public greater<const LabelInfo*> { | 
|---|
| [ff9f695] | 642 |     wxChar separator; | 
|---|
| [291ca5d] | 643 | public: | 
|---|
| [ff9f695] | 644 |     LabelPlotCmp(wxChar separator_) : separator(separator_) {} | 
|---|
| [291ca5d] | 645 |     bool operator()(const LabelInfo* pt1, const LabelInfo* pt2) { | 
|---|
| [5a24583] | 646 |         int n = pt1->get_flags() - pt2->get_flags(); | 
|---|
| [291ca5d] | 647 |         if (n) return n > 0; | 
|---|
| [5a24583] | 648 |         wxString l1 = pt1->GetText().AfterLast(separator); | 
|---|
 | 649 |         wxString l2 = pt2->GetText().AfterLast(separator); | 
|---|
| [f11f2af] | 650 |         n = name_cmp(l1, l2, separator); | 
|---|
 | 651 |         if (n) return n < 0; | 
|---|
| [2a94924] | 652 |         // Prefer non-2-nodes... | 
|---|
 | 653 |         // FIXME; implement | 
|---|
| [f11f2af] | 654 |         // if leaf names are the same, prefer shorter labels as we can | 
|---|
 | 655 |         // display more of them | 
|---|
| [5a24583] | 656 |         n = pt1->GetText().length() - pt2->GetText().length(); | 
|---|
| [f11f2af] | 657 |         if (n) return n < 0; | 
|---|
| [2a94924] | 658 |         // make sure that we don't ever compare different labels as equal | 
|---|
| [5a24583] | 659 |         return name_cmp(pt1->GetText(), pt2->GetText(), separator) < 0; | 
|---|
| [291ca5d] | 660 |     } | 
|---|
 | 661 | }; | 
|---|
 | 662 |  | 
|---|
| [f6fe808] | 663 | #if wxUSE_DRAG_AND_DROP | 
|---|
| [5901b62] | 664 | class DnDFile : public wxFileDropTarget { | 
|---|
 | 665 |     public: | 
|---|
 | 666 |         DnDFile(MainFrm *parent) : m_Parent(parent) { } | 
|---|
 | 667 |         virtual bool OnDropFiles(wxCoord, wxCoord, | 
|---|
 | 668 |                         const wxArrayString &filenames); | 
|---|
 | 669 |  | 
|---|
 | 670 |     private: | 
|---|
 | 671 |         MainFrm * m_Parent; | 
|---|
 | 672 | }; | 
|---|
 | 673 |  | 
|---|
 | 674 | bool | 
|---|
 | 675 | DnDFile::OnDropFiles(wxCoord, wxCoord, const wxArrayString &filenames) | 
|---|
 | 676 | { | 
|---|
 | 677 |     // Load a survey file by drag-and-drop. | 
|---|
 | 678 |     assert(filenames.GetCount() > 0); | 
|---|
 | 679 |  | 
|---|
 | 680 |     if (filenames.GetCount() != 1) { | 
|---|
| [5627cbb] | 681 |         wxGetApp().ReportError(wmsg(/*You may only view one 3d file at a time.*/336)); | 
|---|
| [6d1bc83] | 682 |         return false; | 
|---|
| [5901b62] | 683 |     } | 
|---|
| [421b7d2] | 684 |  | 
|---|
| [5901b62] | 685 |     m_Parent->OpenFile(filenames[0]); | 
|---|
| [6d1bc83] | 686 |     return true; | 
|---|
| [5901b62] | 687 | } | 
|---|
| [f6fe808] | 688 | #endif | 
|---|
| [5901b62] | 689 |  | 
|---|
| [137bf99] | 690 | MainFrm::MainFrm(const wxString& title, const wxPoint& pos, const wxSize& size) : | 
|---|
| [ad3d0a2] | 691 |     wxFrame(NULL, 101, title, pos, size, wxDEFAULT_FRAME_STYLE), | 
|---|
| [486c619] | 692 |     m_SashPosition(-1), | 
|---|
| [429465a] | 693 |     m_Gfx(NULL), m_NumEntrances(0), m_NumFixedPts(0), m_NumExportedPts(0), | 
|---|
| [5fe7292] | 694 |     m_NumHighlighted(0), | 
|---|
 | 695 |     m_HasUndergroundLegs(false), m_HasSplays(false), m_HasSurfaceLegs(false), | 
|---|
| [bc60689] | 696 |     m_HasErrorInformation(false), m_IsExtendedElevation(false), | 
|---|
 | 697 |     pending_find(false) | 
|---|
| [9c3d91e] | 698 | #ifdef PREFDLG | 
|---|
 | 699 |     , m_PrefsDlg(NULL) | 
|---|
 | 700 | #endif | 
|---|
| [5809313] | 701 | { | 
|---|
| [8a05a7a] | 702 |     icon_path = wxString(wmsg_cfgpth()); | 
|---|
| [95fa391] | 703 |     icon_path += wxCONFIG_PATH_SEPARATOR; | 
|---|
| [5627cbb] | 704 |     icon_path += wxT("icons"); | 
|---|
| [95fa391] | 705 |     icon_path += wxCONFIG_PATH_SEPARATOR; | 
|---|
 | 706 |  | 
|---|
| [cfd6c44] | 707 | #ifdef _WIN32 | 
|---|
| [003d953] | 708 |     // The peculiar name is so that the icon is the first in the file | 
|---|
| [b1de3e0] | 709 |     // (required by Microsoft Windows for this type of icon) | 
|---|
| [5627cbb] | 710 |     SetIcon(wxIcon(wxT("aaaaaAven"))); | 
|---|
| [95fa391] | 711 | #else | 
|---|
| [469485f] | 712 |     SetIcon(wxIcon(icon_path + APP_IMAGE, wxBITMAP_TYPE_PNG)); | 
|---|
| [cfd6c44] | 713 | #endif | 
|---|
 | 714 |  | 
|---|
| [9d3d8cc] | 715 |     CreateMenuBar(); | 
|---|
 | 716 |     CreateToolBar(); | 
|---|
| [7c29c976] | 717 |     CreateStatusBar(2, wxST_SIZEGRIP); | 
|---|
| [9d3d8cc] | 718 |     CreateSidePanel(); | 
|---|
| [f433fda] | 719 |  | 
|---|
| [7c29c976] | 720 |     int widths[2] = { -1 /* variable width */, -1 }; | 
|---|
 | 721 |     GetStatusBar()->SetStatusWidths(2, widths); | 
|---|
| [9d3d8cc] | 722 |  | 
|---|
| [0580c6a] | 723 | #ifdef __X__ // wxMotif or wxX11 | 
|---|
| [9d3d8cc] | 724 |     int x; | 
|---|
 | 725 |     int y; | 
|---|
 | 726 |     GetSize(&x, &y); | 
|---|
 | 727 |     // X seems to require a forced resize. | 
|---|
 | 728 |     SetSize(-1, -1, x, y); | 
|---|
 | 729 | #endif | 
|---|
 | 730 |  | 
|---|
| [0edb0d0] | 731 | #if wxUSE_DRAG_AND_DROP | 
|---|
| [5901b62] | 732 |     SetDropTarget(new DnDFile(this)); | 
|---|
| [f6fe808] | 733 | #endif | 
|---|
| [9d3d8cc] | 734 | } | 
|---|
 | 735 |  | 
|---|
 | 736 | void MainFrm::CreateMenuBar() | 
|---|
 | 737 | { | 
|---|
 | 738 |     // Create the menus and the menu bar. | 
|---|
| [137bf99] | 739 |  | 
|---|
 | 740 |     wxMenu* filemenu = new wxMenu; | 
|---|
| [42c7efe] | 741 |     // wxID_OPEN stock label lacks the ellipses | 
|---|
| [ee7511a] | 742 |     filemenu->Append(wxID_OPEN, wmsg(/*&Open…\tCtrl+O*/220)); | 
|---|
| [137bf99] | 743 |     filemenu->AppendSeparator(); | 
|---|
| [42c7efe] | 744 |     // wxID_PRINT stock label lacks the ellipses | 
|---|
| [ee7511a] | 745 |     filemenu->Append(wxID_PRINT, wmsg(/*&Print…\tCtrl+P*/380)); | 
|---|
 | 746 |     filemenu->Append(menu_FILE_PAGE_SETUP, wmsg(/*P&age Setup…*/381)); | 
|---|
| [ce403f1] | 747 |     filemenu->AppendSeparator(); | 
|---|
| [ee7511a] | 748 |     filemenu->Append(menu_FILE_SCREENSHOT, wmsg(/*&Screenshot…*/201)); | 
|---|
 | 749 |     filemenu->Append(menu_FILE_EXPORT, wmsg(/*&Export as…*/382)); | 
|---|
| [b72f4b5] | 750 | #ifndef __WXMAC__ | 
|---|
 | 751 |     // On wxMac the "Quit" menu item will be moved elsewhere, so we suppress | 
|---|
 | 752 |     // this separator. | 
|---|
| [223f1ad] | 753 |     filemenu->AppendSeparator(); | 
|---|
| [b72f4b5] | 754 | #endif | 
|---|
| [42c7efe] | 755 |     filemenu->Append(wxID_EXIT); | 
|---|
| [137bf99] | 756 |  | 
|---|
| [cf8c84b] | 757 |     m_history.UseMenu(filemenu); | 
|---|
 | 758 |     m_history.Load(*wxConfigBase::Get()); | 
|---|
 | 759 |  | 
|---|
| [137bf99] | 760 |     wxMenu* rotmenu = new wxMenu; | 
|---|
| [ee7511a] | 761 |     rotmenu->AppendCheckItem(menu_ROTATION_TOGGLE, wmsg(/*Au&to-Rotate\tSpace*/231)); | 
|---|
| [137bf99] | 762 |     rotmenu->AppendSeparator(); | 
|---|
| [d86459c] | 763 |     rotmenu->Append(menu_ROTATION_SPEED_UP, wmsg(/*Speed &Up*/232)); | 
|---|
 | 764 |     rotmenu->Append(menu_ROTATION_SLOW_DOWN, wmsg(/*Slow &Down*/233)); | 
|---|
| [137bf99] | 765 |     rotmenu->AppendSeparator(); | 
|---|
| [d86459c] | 766 |     rotmenu->Append(menu_ROTATION_REVERSE, wmsg(/*&Reverse Direction*/234)); | 
|---|
| [137bf99] | 767 |     rotmenu->AppendSeparator(); | 
|---|
| [d86459c] | 768 |     rotmenu->Append(menu_ROTATION_STEP_CCW, wmsg(/*Step Once &Anticlockwise*/235)); | 
|---|
 | 769 |     rotmenu->Append(menu_ROTATION_STEP_CW, wmsg(/*Step Once &Clockwise*/236)); | 
|---|
| [137bf99] | 770 |  | 
|---|
 | 771 |     wxMenu* orientmenu = new wxMenu; | 
|---|
| [d86459c] | 772 |     orientmenu->Append(menu_ORIENT_MOVE_NORTH, wmsg(/*View &North*/240)); | 
|---|
 | 773 |     orientmenu->Append(menu_ORIENT_MOVE_EAST, wmsg(/*View &East*/241)); | 
|---|
 | 774 |     orientmenu->Append(menu_ORIENT_MOVE_SOUTH, wmsg(/*View &South*/242)); | 
|---|
 | 775 |     orientmenu->Append(menu_ORIENT_MOVE_WEST, wmsg(/*View &West*/243)); | 
|---|
| [137bf99] | 776 |     orientmenu->AppendSeparator(); | 
|---|
| [d86459c] | 777 |     orientmenu->Append(menu_ORIENT_SHIFT_LEFT, wmsg(/*Shift Survey &Left*/244)); | 
|---|
 | 778 |     orientmenu->Append(menu_ORIENT_SHIFT_RIGHT, wmsg(/*Shift Survey &Right*/245)); | 
|---|
 | 779 |     orientmenu->Append(menu_ORIENT_SHIFT_UP, wmsg(/*Shift Survey &Up*/246)); | 
|---|
 | 780 |     orientmenu->Append(menu_ORIENT_SHIFT_DOWN, wmsg(/*Shift Survey &Down*/247)); | 
|---|
| [137bf99] | 781 |     orientmenu->AppendSeparator(); | 
|---|
| [d86459c] | 782 |     orientmenu->Append(menu_ORIENT_PLAN, wmsg(/*&Plan View*/248)); | 
|---|
 | 783 |     orientmenu->Append(menu_ORIENT_ELEVATION, wmsg(/*Ele&vation*/249)); | 
|---|
| [137bf99] | 784 |     orientmenu->AppendSeparator(); | 
|---|
| [d86459c] | 785 |     orientmenu->Append(menu_ORIENT_HIGHER_VP, wmsg(/*&Higher Viewpoint*/250)); | 
|---|
 | 786 |     orientmenu->Append(menu_ORIENT_LOWER_VP, wmsg(/*L&ower Viewpoint*/251)); | 
|---|
| [137bf99] | 787 |     orientmenu->AppendSeparator(); | 
|---|
| [42c7efe] | 788 |     // Default labels for wxID_ZOOM_IN and wxID_ZOOM_OUT don't have accels. | 
|---|
 | 789 |     orientmenu->Append(wxID_ZOOM_IN, wmsg(/*&Zoom In\t]*/252)); | 
|---|
 | 790 |     orientmenu->Append(wxID_ZOOM_OUT, wmsg(/*Zoo&m Out\t[*/253)); | 
|---|
| [137bf99] | 791 |     orientmenu->AppendSeparator(); | 
|---|
| [d86459c] | 792 |     orientmenu->Append(menu_ORIENT_DEFAULTS, wmsg(/*Restore De&fault View*/254)); | 
|---|
| [1690fa9] | 793 |  | 
|---|
| [203d2a7] | 794 |     wxMenu* presmenu = new wxMenu; | 
|---|
| [d86459c] | 795 |     presmenu->Append(menu_PRES_NEW, wmsg(/*&New Presentation*/311)); | 
|---|
| [ee7511a] | 796 |     presmenu->Append(menu_PRES_OPEN, wmsg(/*&Open Presentation…*/312)); | 
|---|
| [d86459c] | 797 |     presmenu->Append(menu_PRES_SAVE, wmsg(/*&Save Presentation*/313)); | 
|---|
| [ee7511a] | 798 |     presmenu->Append(menu_PRES_SAVE_AS, wmsg(/*Sa&ve Presentation As…*/314)); | 
|---|
| [203d2a7] | 799 |     presmenu->AppendSeparator(); | 
|---|
| [d86459c] | 800 |     presmenu->Append(menu_PRES_MARK, wmsg(/*&Mark*/315)); | 
|---|
| [a2a8d23] | 801 |     presmenu->AppendCheckItem(menu_PRES_PLAY, wmsg(/*Pla&y*/316)); | 
|---|
| [ee7511a] | 802 |     presmenu->Append(menu_PRES_EXPORT_MOVIE, wmsg(/*&Export as Movie…*/317)); | 
|---|
| [1690fa9] | 803 |  | 
|---|
| [203d2a7] | 804 |     wxMenu* viewmenu = new wxMenu; | 
|---|
| [edb6576] | 805 | #ifndef PREFDLG | 
|---|
| [d86459c] | 806 |     viewmenu->AppendCheckItem(menu_VIEW_SHOW_NAMES, wmsg(/*Station &Names\tCtrl+N*/270)); | 
|---|
| [ee7511a] | 807 |     viewmenu->AppendCheckItem(menu_VIEW_SHOW_TUBES, wmsg(/*Passage &Tubes\tCtrl+T*/346)); | 
|---|
| [d86459c] | 808 |     viewmenu->AppendCheckItem(menu_VIEW_SHOW_CROSSES, wmsg(/*&Crosses\tCtrl+X*/271)); | 
|---|
 | 809 |     viewmenu->AppendCheckItem(menu_VIEW_GRID, wmsg(/*&Grid\tCtrl+G*/297)); | 
|---|
 | 810 |     viewmenu->AppendCheckItem(menu_VIEW_BOUNDING_BOX, wmsg(/*&Bounding Box\tCtrl+B*/318)); | 
|---|
| [edb6576] | 811 |     viewmenu->AppendSeparator(); | 
|---|
| [d86459c] | 812 |     viewmenu->AppendCheckItem(menu_VIEW_SHOW_LEGS, wmsg(/*&Underground Survey Legs\tCtrl+L*/272)); | 
|---|
 | 813 |     viewmenu->AppendCheckItem(menu_VIEW_SHOW_SURFACE, wmsg(/*&Surface Survey Legs\tCtrl+F*/291)); | 
|---|
| [8666fc7] | 814 |  | 
|---|
 | 815 |     wxMenu* splaymenu = new wxMenu; | 
|---|
| [82ae44a] | 816 |     splaymenu->AppendCheckItem(menu_SPLAYS_HIDE, wmsg(/*&Hide*/407)); | 
|---|
 | 817 |     splaymenu->AppendCheckItem(menu_SPLAYS_SHOW_FADED, wmsg(/*&Fade*/408)); | 
|---|
 | 818 |     splaymenu->AppendCheckItem(menu_SPLAYS_SHOW_NORMAL, wmsg(/*&Show*/409)); | 
|---|
| [9cb97b7] | 819 |     viewmenu->Append(menu_VIEW_SPLAYS, wmsg(/*Spla&y Legs*/406), splaymenu); | 
|---|
| [8666fc7] | 820 |  | 
|---|
| [edb6576] | 821 |     viewmenu->AppendSeparator(); | 
|---|
| [d86459c] | 822 |     viewmenu->AppendCheckItem(menu_VIEW_SHOW_OVERLAPPING_NAMES, wmsg(/*&Overlapping Names*/273)); | 
|---|
 | 823 |     viewmenu->AppendCheckItem(menu_VIEW_COLOUR_BY_DEPTH, wmsg(/*Colour by &Depth*/292)); | 
|---|
 | 824 |     viewmenu->AppendCheckItem(menu_VIEW_COLOUR_BY_DATE, wmsg(/*Colour by D&ate*/293)); | 
|---|
 | 825 |     viewmenu->AppendCheckItem(menu_VIEW_COLOUR_BY_ERROR, wmsg(/*Colour by E&rror*/289)); | 
|---|
| [edb6576] | 826 |     viewmenu->AppendSeparator(); | 
|---|
| [d86459c] | 827 |     viewmenu->AppendCheckItem(menu_VIEW_SHOW_ENTRANCES, wmsg(/*Highlight &Entrances*/294)); | 
|---|
 | 828 |     viewmenu->AppendCheckItem(menu_VIEW_SHOW_FIXED_PTS, wmsg(/*Highlight &Fixed Points*/295)); | 
|---|
 | 829 |     viewmenu->AppendCheckItem(menu_VIEW_SHOW_EXPORTED_PTS, wmsg(/*Highlight E&xported Points*/296)); | 
|---|
| [edb6576] | 830 |     viewmenu->AppendSeparator(); | 
|---|
 | 831 | #else | 
|---|
| [d86459c] | 832 |     viewmenu-> Append(menu_VIEW_CANCEL_DIST_LINE, wmsg(/*&Cancel Measuring Line\tEscape*/281)); | 
|---|
| [edb6576] | 833 | #endif | 
|---|
| [d86459c] | 834 |     viewmenu->AppendCheckItem(menu_VIEW_PERSPECTIVE, wmsg(/*&Perspective*/237)); | 
|---|
 | 835 | // FIXME: enable this    viewmenu->AppendCheckItem(menu_VIEW_SMOOTH_SHADING, wmsg(/*&Smooth Shading*/?!?); | 
|---|
 | 836 |     viewmenu->AppendCheckItem(menu_VIEW_TEXTURED, wmsg(/*Textured &Walls*/238)); | 
|---|
| [ee7511a] | 837 |     viewmenu->AppendCheckItem(menu_VIEW_FOG, wmsg(/*Fade Distant Ob&jects*/239)); | 
|---|
| [5c2bff7] | 838 |     viewmenu->AppendCheckItem(menu_VIEW_SMOOTH_LINES, wmsg(/*Smoot&hed Survey Legs*/298)); | 
|---|
| [6abab84] | 839 |     viewmenu->AppendSeparator(); | 
|---|
| [85c83ac5] | 840 | #ifdef __WXMAC__ | 
|---|
 | 841 |     // F11 on OS X is used by the desktop (for speaker volume and/or window | 
|---|
 | 842 |     // navigation).  The standard OS X shortcut for full screen mode is | 
|---|
 | 843 |     // Shift-Command-F which in wxWidgets terms is Shift+Ctrl+F. | 
|---|
 | 844 |     wxString wxmac_fullscreen = wmsg(/*Full Screen &Mode\tF11*/356); | 
|---|
 | 845 |     wxmac_fullscreen.Replace(wxT("\tF11"), wxT("\rShift+Ctrl+F"), false); | 
|---|
 | 846 |     viewmenu->AppendCheckItem(menu_VIEW_FULLSCREEN, wxmac_fullscreen); | 
|---|
 | 847 | #else | 
|---|
| [ee7511a] | 848 |     viewmenu->AppendCheckItem(menu_VIEW_FULLSCREEN, wmsg(/*Full Screen &Mode\tF11*/356)); | 
|---|
| [85c83ac5] | 849 | #endif | 
|---|
| [edb6576] | 850 | #ifdef PREFDLG | 
|---|
| [203d2a7] | 851 |     viewmenu->AppendSeparator(); | 
|---|
| [ee7511a] | 852 |     viewmenu-> Append(wxID_PREFERENCES, wmsg(/*&Preferences…*/347)); | 
|---|
| [edb6576] | 853 | #endif | 
|---|
 | 854 |  | 
|---|
 | 855 | #ifndef PREFDLG | 
|---|
 | 856 |     wxMenu* ctlmenu = new wxMenu; | 
|---|
| [d86459c] | 857 |     ctlmenu->AppendCheckItem(menu_CTL_REVERSE, wmsg(/*&Reverse Sense\tCtrl+R*/280)); | 
|---|
| [edb6576] | 858 |     ctlmenu->AppendSeparator(); | 
|---|
| [d86459c] | 859 |     ctlmenu->Append(menu_CTL_CANCEL_DIST_LINE, wmsg(/*&Cancel Measuring Line\tEscape*/281)); | 
|---|
| [edb6576] | 860 |     ctlmenu->AppendSeparator(); | 
|---|
 | 861 |     wxMenu* indmenu = new wxMenu; | 
|---|
| [d86459c] | 862 |     indmenu->AppendCheckItem(menu_IND_COMPASS, wmsg(/*&Compass*/274)); | 
|---|
 | 863 |     indmenu->AppendCheckItem(menu_IND_CLINO, wmsg(/*C&linometer*/275)); | 
|---|
| [97ea48d] | 864 |     indmenu->AppendCheckItem(menu_IND_COLOUR_KEY, wmsg(/*Colour &Key*/276)); | 
|---|
| [d86459c] | 865 |     indmenu->AppendCheckItem(menu_IND_SCALE_BAR, wmsg(/*&Scale Bar*/277)); | 
|---|
 | 866 |     ctlmenu->Append(menu_CTL_INDICATORS, wmsg(/*&Indicators*/299), indmenu); | 
|---|
 | 867 |     ctlmenu->AppendCheckItem(menu_CTL_SIDE_PANEL, wmsg(/*&Side Panel*/337)); | 
|---|
| [edb6576] | 868 |     ctlmenu->AppendSeparator(); | 
|---|
| [d86459c] | 869 |     ctlmenu->AppendCheckItem(menu_CTL_METRIC, wmsg(/*&Metric*/342)); | 
|---|
 | 870 |     ctlmenu->AppendCheckItem(menu_CTL_DEGREES, wmsg(/*&Degrees*/343)); | 
|---|
| [d171c0c] | 871 |     ctlmenu->AppendCheckItem(menu_CTL_PERCENT, wmsg(/*&Percent*/430)); | 
|---|
| [edb6576] | 872 | #endif | 
|---|
| [137bf99] | 873 |  | 
|---|
| [c988ae4] | 874 |     wxMenuBar* menubar = new wxMenuBar(); | 
|---|
| [d86459c] | 875 |     menubar->Append(filemenu, wmsg(/*&File*/210)); | 
|---|
 | 876 |     menubar->Append(rotmenu, wmsg(/*&Rotation*/211)); | 
|---|
 | 877 |     menubar->Append(orientmenu, wmsg(/*&Orientation*/212)); | 
|---|
 | 878 |     menubar->Append(viewmenu, wmsg(/*&View*/213)); | 
|---|
| [5de0cac] | 879 | #ifndef PREFDLG | 
|---|
| [d86459c] | 880 |     menubar->Append(ctlmenu, wmsg(/*&Controls*/214)); | 
|---|
| [5de0cac] | 881 | #endif | 
|---|
| [d86459c] | 882 |     menubar->Append(presmenu, wmsg(/*&Presentation*/216)); | 
|---|
| [b72f4b5] | 883 | #ifndef __WXMAC__ | 
|---|
 | 884 |     // On wxMac the "About" menu item will be moved elsewhere, so we suppress | 
|---|
 | 885 |     // this menu since it will then be empty. | 
|---|
| [c5dd692] | 886 |     wxMenu* helpmenu = new wxMenu; | 
|---|
 | 887 |     helpmenu->Append(wxID_ABOUT); | 
|---|
 | 888 |  | 
|---|
| [d86459c] | 889 |     menubar->Append(helpmenu, wmsg(/*&Help*/215)); | 
|---|
| [b72f4b5] | 890 | #endif | 
|---|
| [137bf99] | 891 |     SetMenuBar(menubar); | 
|---|
| [9d3d8cc] | 892 | } | 
|---|
| [137bf99] | 893 |  | 
|---|
| [95fa391] | 894 | // ICON must be a literal string. | 
|---|
| [5627cbb] | 895 | #define TOOLBAR_BITMAP(ICON) wxBitmap(icon_path + wxT(ICON".png"), wxBITMAP_TYPE_PNG) | 
|---|
| [95fa391] | 896 |  | 
|---|
| [9d3d8cc] | 897 | void MainFrm::CreateToolBar() | 
|---|
 | 898 | { | 
|---|
 | 899 |     // Create the toolbar. | 
|---|
| [137bf99] | 900 |  | 
|---|
| [9d3d8cc] | 901 |     wxToolBar* toolbar = wxFrame::CreateToolBar(); | 
|---|
| [137bf99] | 902 |  | 
|---|
| [b65c13f] | 903 | #ifndef __WXGTK20__ | 
|---|
| [d94f5db] | 904 |     toolbar->SetMargins(5, 5); | 
|---|
 | 905 | #endif | 
|---|
 | 906 |  | 
|---|
| [9b540e6] | 907 |     // FIXME: TRANSLATE tooltips | 
|---|
| [92a97f3] | 908 |     toolbar->AddTool(wxID_OPEN, wxT("Open"), TOOLBAR_BITMAP("open"), wxT("Open a survey file for viewing")); | 
|---|
| [5627cbb] | 909 |     toolbar->AddTool(menu_PRES_OPEN, wxT("Open presentation"), TOOLBAR_BITMAP("open-pres"), wxT("Open a presentation")); | 
|---|
| [2d9ed8ad] | 910 |     toolbar->AddSeparator(); | 
|---|
| [5627cbb] | 911 |     toolbar->AddCheckTool(menu_ROTATION_TOGGLE, wxT("Toggle rotation"), TOOLBAR_BITMAP("rotation"), wxNullBitmap, wxT("Toggle rotation")); | 
|---|
 | 912 |     toolbar->AddTool(menu_ORIENT_PLAN, wxT("Plan"), TOOLBAR_BITMAP("plan"), wxT("Switch to plan view")); | 
|---|
 | 913 |     toolbar->AddTool(menu_ORIENT_ELEVATION, wxT("Elevation"), TOOLBAR_BITMAP("elevation"), wxT("Switch to elevation view")); | 
|---|
 | 914 |     toolbar->AddTool(menu_ORIENT_DEFAULTS, wxT("Default view"), TOOLBAR_BITMAP("defaults"), wxT("Restore default view")); | 
|---|
| [2d9ed8ad] | 915 |     toolbar->AddSeparator(); | 
|---|
| [5627cbb] | 916 |     toolbar->AddCheckTool(menu_VIEW_SHOW_NAMES, wxT("Names"), TOOLBAR_BITMAP("names"), wxNullBitmap, wxT("Show station names")); | 
|---|
 | 917 |     toolbar->AddCheckTool(menu_VIEW_SHOW_CROSSES, wxT("Crosses"), TOOLBAR_BITMAP("crosses"), wxNullBitmap, wxT("Show crosses on stations")); | 
|---|
 | 918 |     toolbar->AddCheckTool(menu_VIEW_SHOW_ENTRANCES, wxT("Entrances"), TOOLBAR_BITMAP("entrances"), wxNullBitmap, wxT("Highlight entrances")); | 
|---|
 | 919 |     toolbar->AddCheckTool(menu_VIEW_SHOW_FIXED_PTS, wxT("Fixed points"), TOOLBAR_BITMAP("fixed-pts"), wxNullBitmap, wxT("Highlight fixed points")); | 
|---|
 | 920 |     toolbar->AddCheckTool(menu_VIEW_SHOW_EXPORTED_PTS, wxT("Exported points"), TOOLBAR_BITMAP("exported-pts"), wxNullBitmap, wxT("Highlight exported stations")); | 
|---|
| [2d9ed8ad] | 921 |     toolbar->AddSeparator(); | 
|---|
| [5627cbb] | 922 |     toolbar->AddCheckTool(menu_VIEW_SHOW_LEGS, wxT("Underground legs"), TOOLBAR_BITMAP("ug-legs"), wxNullBitmap, wxT("Show underground surveys")); | 
|---|
 | 923 |     toolbar->AddCheckTool(menu_VIEW_SHOW_SURFACE, wxT("Surface legs"), TOOLBAR_BITMAP("surface-legs"), wxNullBitmap, wxT("Show surface surveys")); | 
|---|
 | 924 |     toolbar->AddCheckTool(menu_VIEW_SHOW_TUBES, wxT("Tubes"), TOOLBAR_BITMAP("tubes"), wxNullBitmap, wxT("Show passage tubes")); | 
|---|
| [128fac4] | 925 |     toolbar->AddSeparator(); | 
|---|
| [5627cbb] | 926 |     toolbar->AddCheckTool(menu_PRES_FREWIND, wxT("Fast Rewind"), TOOLBAR_BITMAP("pres-frew"), wxNullBitmap, wxT("Very Fast Rewind")); | 
|---|
 | 927 |     toolbar->AddCheckTool(menu_PRES_REWIND, wxT("Rewind"), TOOLBAR_BITMAP("pres-rew"), wxNullBitmap, wxT("Fast Rewind")); | 
|---|
 | 928 |     toolbar->AddCheckTool(menu_PRES_REVERSE, wxT("Backwards"), TOOLBAR_BITMAP("pres-go-back"), wxNullBitmap, wxT("Play Backwards")); | 
|---|
 | 929 |     toolbar->AddCheckTool(menu_PRES_PAUSE, wxT("Pause"), TOOLBAR_BITMAP("pres-pause"), wxNullBitmap, wxT("Pause")); | 
|---|
 | 930 |     toolbar->AddCheckTool(menu_PRES_PLAY, wxT("Go"), TOOLBAR_BITMAP("pres-go"), wxNullBitmap, wxT("Play")); | 
|---|
 | 931 |     toolbar->AddCheckTool(menu_PRES_FF, wxT("FF"), TOOLBAR_BITMAP("pres-ff"), wxNullBitmap, wxT("Fast Forward")); | 
|---|
 | 932 |     toolbar->AddCheckTool(menu_PRES_FFF, wxT("Very FF"), TOOLBAR_BITMAP("pres-fff"), wxNullBitmap, wxT("Very Fast Forward")); | 
|---|
| [42c7efe] | 933 |     toolbar->AddTool(wxID_STOP, wxT("Stop"), TOOLBAR_BITMAP("pres-stop"), wxT("Stop")); | 
|---|
| [fd6e0d5] | 934 |  | 
|---|
| [203d2a7] | 935 |     toolbar->AddSeparator(); | 
|---|
| [5627cbb] | 936 |     m_FindBox = new wxTextCtrl(toolbar, textctrl_FIND, wxString(), wxDefaultPosition, | 
|---|
| [429465a] | 937 |                                wxDefaultSize, wxTE_PROCESS_ENTER); | 
|---|
| [fd6e0d5] | 938 |     toolbar->AddControl(m_FindBox); | 
|---|
| [1ada489] | 939 |     toolbar->AddTool(wxID_FIND, wmsg(/*Find*/332), TOOLBAR_BITMAP("find")/*, "Search for station name"*/); | 
|---|
 | 940 |     toolbar->AddTool(button_HIDE, wmsg(/*Hide*/333), TOOLBAR_BITMAP("hideresults")/*, "Hide search results"*/); | 
|---|
| [fd6e0d5] | 941 |  | 
|---|
| [2d9ed8ad] | 942 |     toolbar->Realize(); | 
|---|
| [9d3d8cc] | 943 | } | 
|---|
| [2d9ed8ad] | 944 |  | 
|---|
| [9d3d8cc] | 945 | void MainFrm::CreateSidePanel() | 
|---|
 | 946 | { | 
|---|
| [b1de3e0] | 947 |     m_Splitter = new AvenSplitterWindow(this); | 
|---|
| [421b7d2] | 948 |  | 
|---|
| [203d2a7] | 949 |     m_Notebook = new wxNotebook(m_Splitter, 400, wxDefaultPosition, | 
|---|
| [b63cf6cc] | 950 |                                 wxDefaultSize, | 
|---|
| [4e98397] | 951 |                                 wxBK_BOTTOM | wxBK_LEFT); | 
|---|
| [203d2a7] | 952 |     m_Notebook->Show(false); | 
|---|
| [f433fda] | 953 |  | 
|---|
| [1be3a88] | 954 |     wxPanel * panel = new wxPanel(m_Notebook); | 
|---|
 | 955 |     m_Tree = new AvenTreeCtrl(this, panel); | 
|---|
| [156dc16] | 956 |  | 
|---|
| [429465a] | 957 | //    m_RegexpCheckBox = new wxCheckBox(find_panel, -1, | 
|---|
| [ee7511a] | 958 | //                                    msg(/*Regular expression*/)); | 
|---|
| [2c30188] | 959 |  | 
|---|
 | 960 |     wxBoxSizer *panel_sizer = new wxBoxSizer(wxVERTICAL); | 
|---|
 | 961 |     panel_sizer->Add(m_Tree, 1, wxALL | wxEXPAND, 2); | 
|---|
| [1be3a88] | 962 |     panel->SetAutoLayout(true); | 
|---|
 | 963 |     panel->SetSizer(panel_sizer); | 
|---|
 | 964 | //    panel_sizer->Fit(panel); | 
|---|
 | 965 | //    panel_sizer->SetSizeHints(panel); | 
|---|
| [156dc16] | 966 |  | 
|---|
| [5876fcb] | 967 |     m_Control = new GUIControl(); | 
|---|
 | 968 |     m_Gfx = new GfxCore(this, m_Splitter, m_Control); | 
|---|
 | 969 |     m_Control->SetView(m_Gfx); | 
|---|
| [156dc16] | 970 |  | 
|---|
| [203d2a7] | 971 |     // Presentation panel: | 
|---|
| [1be3a88] | 972 |     wxPanel * prespanel = new wxPanel(m_Notebook); | 
|---|
| [203d2a7] | 973 |  | 
|---|
| [1be3a88] | 974 |     m_PresList = new AvenPresList(this, prespanel, m_Gfx); | 
|---|
| [f433fda] | 975 |  | 
|---|
| [203d2a7] | 976 |     wxBoxSizer *pres_panel_sizer = new wxBoxSizer(wxVERTICAL); | 
|---|
 | 977 |     pres_panel_sizer->Add(m_PresList, 1, wxALL | wxEXPAND, 2); | 
|---|
| [1be3a88] | 978 |     prespanel->SetAutoLayout(true); | 
|---|
 | 979 |     prespanel->SetSizer(pres_panel_sizer); | 
|---|
| [1690fa9] | 980 |  | 
|---|
| [203d2a7] | 981 |     // Overall tabbed structure: | 
|---|
| [c5032bb0] | 982 |     // FIXME: this assumes images are 15x15 | 
|---|
 | 983 |     wxImageList* image_list = new wxImageList(15, 15); | 
|---|
| [8a05a7a] | 984 |     wxString path = wxString(wmsg_cfgpth()); | 
|---|
| [5627cbb] | 985 |     path += wxCONFIG_PATH_SEPARATOR; | 
|---|
 | 986 |     path += wxT("icons") ; | 
|---|
 | 987 |     path += wxCONFIG_PATH_SEPARATOR; | 
|---|
 | 988 |     image_list->Add(wxBitmap(path + wxT("survey-tree.png"), wxBITMAP_TYPE_PNG)); | 
|---|
 | 989 |     image_list->Add(wxBitmap(path + wxT("pres-tree.png"), wxBITMAP_TYPE_PNG)); | 
|---|
| [203d2a7] | 990 |     m_Notebook->SetImageList(image_list); | 
|---|
| [5627cbb] | 991 |     m_Notebook->AddPage(panel, wmsg(/*Surveys*/376), true, 0); | 
|---|
 | 992 |     m_Notebook->AddPage(prespanel, wmsg(/*Presentation*/377), false, 1); | 
|---|
| [203d2a7] | 993 |  | 
|---|
| [e9b97eb] | 994 |     m_Splitter->Initialize(m_Gfx); | 
|---|
| [068b4f2] | 995 | } | 
|---|
| [137bf99] | 996 |  | 
|---|
| [bc73093] | 997 | bool MainFrm::LoadData(const wxString& file, wxString prefix) | 
|---|
| [b88b171] | 998 | { | 
|---|
| [137bf99] | 999 |     // Load survey data from file, centre the dataset around the origin, | 
|---|
| [f4fae12] | 1000 |     // and prepare the data for drawing. | 
|---|
| [137bf99] | 1001 |  | 
|---|
| [c9427d2] | 1002 | #if 0 | 
|---|
 | 1003 |     wxStopWatch timer; | 
|---|
 | 1004 |     timer.Start(); | 
|---|
 | 1005 | #endif | 
|---|
| [b88b171] | 1006 |  | 
|---|
| [bc73093] | 1007 |     // Load the processed survey data. | 
|---|
| [318ac31] | 1008 |     img* survey = img_open_survey(file.mb_str(), prefix.mb_str()); | 
|---|
| [137bf99] | 1009 |     if (!survey) { | 
|---|
| [4d7d209] | 1010 |         wxString m = wxString::Format(wmsg(img_error2msg(img_error())), file.c_str()); | 
|---|
| [421b7d2] | 1011 |         wxGetApp().ReportError(m); | 
|---|
 | 1012 |         return false; | 
|---|
| [137bf99] | 1013 |     } | 
|---|
| [1d0cd97] | 1014 |  | 
|---|
| [eef68f9] | 1015 |     m_IsExtendedElevation = survey->is_extended_elevation; | 
|---|
| [156dc16] | 1016 |  | 
|---|
| [9f176bd] | 1017 |     m_Tree->DeleteAllItems(); | 
|---|
 | 1018 |  | 
|---|
| [1d0cd97] | 1019 |     // Create a list of all the leg vertices, counting them and finding the | 
|---|
 | 1020 |     // extent of the survey at the same time. | 
|---|
 | 1021 |  | 
|---|
 | 1022 |     m_NumFixedPts = 0; | 
|---|
 | 1023 |     m_NumExportedPts = 0; | 
|---|
 | 1024 |     m_NumEntrances = 0; | 
|---|
| [f433fda] | 1025 |     m_HasUndergroundLegs = false; | 
|---|
| [5fe7292] | 1026 |     m_HasSplays = false; | 
|---|
| [f433fda] | 1027 |     m_HasSurfaceLegs = false; | 
|---|
| [c61aa79] | 1028 |     m_HasErrorInformation = false; | 
|---|
| [1d0cd97] | 1029 |  | 
|---|
| [1690fa9] | 1030 |     // FIXME: discard existing presentation? ask user about saving if we do! | 
|---|
| [156dc16] | 1031 |  | 
|---|
| [1d0cd97] | 1032 |     // Delete any existing list entries. | 
|---|
| [0e6ee74] | 1033 |     m_Labels.clear(); | 
|---|
| [1d0cd97] | 1034 |  | 
|---|
| [a6f081c] | 1035 |     Double xmin = DBL_MAX; | 
|---|
| [1d0cd97] | 1036 |     Double xmax = -DBL_MAX; | 
|---|
| [a6f081c] | 1037 |     Double ymin = DBL_MAX; | 
|---|
| [1d0cd97] | 1038 |     Double ymax = -DBL_MAX; | 
|---|
| [78c67a6] | 1039 |     Double zmin = DBL_MAX; | 
|---|
| [1d0cd97] | 1040 |     Double zmax = -DBL_MAX; | 
|---|
| [78c67a6] | 1041 |  | 
|---|
 | 1042 |     m_DepthMin = DBL_MAX; | 
|---|
 | 1043 |     Double depthmax = -DBL_MAX; | 
|---|
 | 1044 |  | 
|---|
| [1ee204e] | 1045 |     m_DateMin = INT_MAX; | 
|---|
| [2043961] | 1046 |     int datemax = -1; | 
|---|
| [a74b014] | 1047 |     complete_dateinfo = true; | 
|---|
| [1d0cd97] | 1048 |  | 
|---|
| [3ddcad8] | 1049 |     traverses.clear(); | 
|---|
 | 1050 |     surface_traverses.clear(); | 
|---|
| [ee05463] | 1051 |     tubes.clear(); | 
|---|
| [3ddcad8] | 1052 |  | 
|---|
 | 1053 |     // Ultimately we probably want different types (subclasses perhaps?) for | 
|---|
 | 1054 |     // underground and surface data, so we don't need to store LRUD for surface | 
|---|
 | 1055 |     // stuff. | 
|---|
| [c61aa79] | 1056 |     traverse * current_traverse = NULL; | 
|---|
 | 1057 |     traverse * current_surface_traverse = NULL; | 
|---|
| [ee05463] | 1058 |     vector<XSect> * current_tube = NULL; | 
|---|
| [1d0cd97] | 1059 |  | 
|---|
| [576e5a9] | 1060 |     map<wxString, LabelInfo *> labelmap; | 
|---|
 | 1061 |     list<LabelInfo*>::const_iterator last_mapped_label = m_Labels.begin(); | 
|---|
 | 1062 |  | 
|---|
| [1d0cd97] | 1063 |     int result; | 
|---|
| [3ddcad8] | 1064 |     img_point prev_pt = {0,0,0}; | 
|---|
 | 1065 |     bool current_polyline_is_surface = false; | 
|---|
| [8666fc7] | 1066 |     bool current_polyline_is_splay = false; | 
|---|
| [3ddcad8] | 1067 |     bool pending_move = false; | 
|---|
| [c61aa79] | 1068 |     // When a traverse is split between surface and underground, we split it | 
|---|
 | 1069 |     // into contiguous traverses of each, but we need to track these so we can | 
|---|
 | 1070 |     // assign the error statistics to all of them.  So we keep counts of how | 
|---|
 | 1071 |     // many surface_traverses and traverses we've generated for the current | 
|---|
 | 1072 |     // traverse. | 
|---|
 | 1073 |     size_t n_traverses = 0; | 
|---|
 | 1074 |     size_t n_surface_traverses = 0; | 
|---|
| [1d0cd97] | 1075 |     do { | 
|---|
| [e9bd2800] | 1076 | #if 0 | 
|---|
| [3ddcad8] | 1077 |         if (++items % 200 == 0) { | 
|---|
| [b63cf6cc] | 1078 |             long pos = ftell(survey->fh); | 
|---|
 | 1079 |             int progress = int((double(pos) / double(file_size)) * 100.0); | 
|---|
| [0580c6a] | 1080 |             // SetProgress(progress); | 
|---|
| [b63cf6cc] | 1081 |         } | 
|---|
| [e9bd2800] | 1082 | #endif | 
|---|
| [203d2a7] | 1083 |  | 
|---|
| [421b7d2] | 1084 |         img_point pt; | 
|---|
 | 1085 |         result = img_read_item(survey, &pt); | 
|---|
 | 1086 |         switch (result) { | 
|---|
 | 1087 |             case img_MOVE: | 
|---|
| [c61aa79] | 1088 |                 n_traverses = n_surface_traverses = 0; | 
|---|
| [3ddcad8] | 1089 |                 pending_move = true; | 
|---|
 | 1090 |                 prev_pt = pt; | 
|---|
 | 1091 |                 break; | 
|---|
| [421b7d2] | 1092 |  | 
|---|
| [3ddcad8] | 1093 |             case img_LINE: { | 
|---|
| [421b7d2] | 1094 |                 // Update survey extents. | 
|---|
| [a6f081c] | 1095 |                 if (pt.x < xmin) xmin = pt.x; | 
|---|
| [421b7d2] | 1096 |                 if (pt.x > xmax) xmax = pt.x; | 
|---|
| [a6f081c] | 1097 |                 if (pt.y < ymin) ymin = pt.y; | 
|---|
| [421b7d2] | 1098 |                 if (pt.y > ymax) ymax = pt.y; | 
|---|
| [78c67a6] | 1099 |                 if (pt.z < zmin) zmin = pt.z; | 
|---|
| [421b7d2] | 1100 |                 if (pt.z > zmax) zmax = pt.z; | 
|---|
 | 1101 |  | 
|---|
| [1ee204e] | 1102 |                 int date = survey->days1; | 
|---|
 | 1103 |                 if (date != -1) { | 
|---|
 | 1104 |                     date += (survey->days2 - date) / 2; | 
|---|
| [d4650b3] | 1105 |                     if (date < m_DateMin) m_DateMin = date; | 
|---|
 | 1106 |                     if (date > datemax) datemax = date; | 
|---|
| [a74b014] | 1107 |                 } else { | 
|---|
 | 1108 |                     complete_dateinfo = false; | 
|---|
| [d4650b3] | 1109 |                 } | 
|---|
 | 1110 |  | 
|---|
| [5fe7292] | 1111 |                 if (survey->flags & img_FLAG_SPLAY) | 
|---|
 | 1112 |                     m_HasSplays = true; | 
|---|
| [3ddcad8] | 1113 |                 bool is_surface = (survey->flags & img_FLAG_SURFACE); | 
|---|
| [8666fc7] | 1114 |                 bool is_splay = (survey->flags & img_FLAG_SPLAY); | 
|---|
| [78c67a6] | 1115 |                 if (!is_surface) { | 
|---|
 | 1116 |                     if (pt.z < m_DepthMin) m_DepthMin = pt.z; | 
|---|
 | 1117 |                     if (pt.z > depthmax) depthmax = pt.z; | 
|---|
 | 1118 |                 } | 
|---|
| [8666fc7] | 1119 |                 if (pending_move || current_polyline_is_surface != is_surface || current_polyline_is_splay != is_splay) { | 
|---|
| [57a3cd4] | 1120 |                     if (!current_polyline_is_surface && current_traverse) { | 
|---|
| [ee05463] | 1121 |                         //FixLRUD(*current_traverse); | 
|---|
| [57a3cd4] | 1122 |                     } | 
|---|
| [ad661cc] | 1123 |  | 
|---|
| [3ddcad8] | 1124 |                     // Start new traverse (surface or underground). | 
|---|
| [f433fda] | 1125 |                     if (is_surface) { | 
|---|
 | 1126 |                         m_HasSurfaceLegs = true; | 
|---|
| [c61aa79] | 1127 |                         surface_traverses.push_back(traverse()); | 
|---|
| [faae79c] | 1128 |                         current_surface_traverse = &surface_traverses.back(); | 
|---|
| [c61aa79] | 1129 |                         ++n_surface_traverses; | 
|---|
| [f433fda] | 1130 |                     } else { | 
|---|
 | 1131 |                         m_HasUndergroundLegs = true; | 
|---|
| [c61aa79] | 1132 |                         traverses.push_back(traverse()); | 
|---|
| [3ddcad8] | 1133 |                         current_traverse = &traverses.back(); | 
|---|
| [8666fc7] | 1134 |                         current_traverse->isSplay = is_splay; | 
|---|
| [c61aa79] | 1135 |                         ++n_traverses; | 
|---|
| [78c67a6] | 1136 |                         // The previous point was at a surface->ug transition. | 
|---|
| [ad661cc] | 1137 |                         if (current_polyline_is_surface) { | 
|---|
| [8666fc7] | 1138 |                             if (prev_pt.z < m_DepthMin) m_DepthMin = prev_pt.z; | 
|---|
 | 1139 |                             if (prev_pt.z > depthmax) depthmax = prev_pt.z; | 
|---|
 | 1140 |                         } | 
|---|
| [3ddcad8] | 1141 |                     } | 
|---|
| [8666fc7] | 1142 |  | 
|---|
 | 1143 |                     current_polyline_is_surface = is_surface; | 
|---|
 | 1144 |                     current_polyline_is_splay = is_splay; | 
|---|
| [ad661cc] | 1145 |  | 
|---|
| [3ddcad8] | 1146 |                     if (pending_move) { | 
|---|
| [faae79c] | 1147 |                         // Update survey extents.  We only need to do this if | 
|---|
 | 1148 |                         // there's a pending move, since for a surface <-> | 
|---|
 | 1149 |                         // underground transition, we'll already have handled | 
|---|
 | 1150 |                         // this point. | 
|---|
| [3ddcad8] | 1151 |                         if (prev_pt.x < xmin) xmin = prev_pt.x; | 
|---|
 | 1152 |                         if (prev_pt.x > xmax) xmax = prev_pt.x; | 
|---|
 | 1153 |                         if (prev_pt.y < ymin) ymin = prev_pt.y; | 
|---|
 | 1154 |                         if (prev_pt.y > ymax) ymax = prev_pt.y; | 
|---|
| [78c67a6] | 1155 |                         if (prev_pt.z < zmin) zmin = prev_pt.z; | 
|---|
| [3ddcad8] | 1156 |                         if (prev_pt.z > zmax) zmax = prev_pt.z; | 
|---|
| [faae79c] | 1157 |                     } | 
|---|
| [3ddcad8] | 1158 |  | 
|---|
| [faae79c] | 1159 |                     if (is_surface) { | 
|---|
| [d4650b3] | 1160 |                         current_surface_traverse->push_back(PointInfo(prev_pt)); | 
|---|
| [faae79c] | 1161 |                     } else { | 
|---|
| [d4650b3] | 1162 |                         current_traverse->push_back(PointInfo(prev_pt)); | 
|---|
| [f433fda] | 1163 |                     } | 
|---|
| [421b7d2] | 1164 |                 } | 
|---|
 | 1165 |  | 
|---|
| [3ddcad8] | 1166 |                 if (is_surface) { | 
|---|
| [d4650b3] | 1167 |                     current_surface_traverse->push_back(PointInfo(pt, date)); | 
|---|
| [3ddcad8] | 1168 |                 } else { | 
|---|
| [d4650b3] | 1169 |                     current_traverse->push_back(PointInfo(pt, date)); | 
|---|
| [3ddcad8] | 1170 |                 } | 
|---|
 | 1171 |  | 
|---|
 | 1172 |                 prev_pt = pt; | 
|---|
 | 1173 |                 pending_move = false; | 
|---|
| [421b7d2] | 1174 |                 break; | 
|---|
 | 1175 |             } | 
|---|
 | 1176 |  | 
|---|
| [3ddcad8] | 1177 |             case img_LABEL: { | 
|---|
| [de402d4] | 1178 |                 wxString s(survey->label, wxConvUTF8); | 
|---|
 | 1179 |                 if (s.empty()) { | 
|---|
 | 1180 |                     // If label isn't valid UTF-8 then this conversion will | 
|---|
| [457da16] | 1181 |                     // give an empty string.  In this case, assume that the | 
|---|
 | 1182 |                     // label is CP1252 (the Microsoft superset of ISO8859-1). | 
|---|
| [de402d4] | 1183 |                     static wxCSConv ConvCP1252(wxFONTENCODING_CP1252); | 
|---|
 | 1184 |                     s = wxString(survey->label, ConvCP1252); | 
|---|
| [d43fa84] | 1185 |                     if (s.empty()) { | 
|---|
| [457da16] | 1186 |                         // Or if that doesn't work (ConvCP1252 doesn't like | 
|---|
 | 1187 |                         // strings with some bytes in) let's just go for | 
|---|
 | 1188 |                         // ISO8859-1. | 
|---|
 | 1189 |                         s = wxString(survey->label, wxConvISO8859_1); | 
|---|
| [d43fa84] | 1190 |                     } | 
|---|
| [de402d4] | 1191 |                 } | 
|---|
| [dcbcae0] | 1192 |                 int flags = img2aven(survey->flags); | 
|---|
| [de402d4] | 1193 |                 LabelInfo* label = new LabelInfo(pt, s, flags); | 
|---|
| [421b7d2] | 1194 |                 if (label->IsEntrance()) { | 
|---|
 | 1195 |                     m_NumEntrances++; | 
|---|
 | 1196 |                 } | 
|---|
 | 1197 |                 if (label->IsFixedPt()) { | 
|---|
 | 1198 |                     m_NumFixedPts++; | 
|---|
 | 1199 |                 } | 
|---|
 | 1200 |                 if (label->IsExportedPt()) { | 
|---|
 | 1201 |                     m_NumExportedPts++; | 
|---|
 | 1202 |                 } | 
|---|
 | 1203 |                 m_Labels.push_back(label); | 
|---|
 | 1204 |                 break; | 
|---|
 | 1205 |             } | 
|---|
 | 1206 |  | 
|---|
| [ee05463] | 1207 |             case img_XSECT: { | 
|---|
 | 1208 |                 if (!current_tube) { | 
|---|
 | 1209 |                     // Start new current_tube. | 
|---|
 | 1210 |                     tubes.push_back(vector<XSect>()); | 
|---|
 | 1211 |                     current_tube = &tubes.back(); | 
|---|
 | 1212 |                 } | 
|---|
 | 1213 |  | 
|---|
| [576e5a9] | 1214 |                 LabelInfo * lab; | 
|---|
| [5627cbb] | 1215 |                 wxString label(survey->label, wxConvUTF8); | 
|---|
| [576e5a9] | 1216 |                 map<wxString, LabelInfo *>::const_iterator p; | 
|---|
 | 1217 |                 p = labelmap.find(label); | 
|---|
 | 1218 |                 if (p != labelmap.end()) { | 
|---|
 | 1219 |                     lab = p->second; | 
|---|
 | 1220 |                 } else { | 
|---|
 | 1221 |                     // Initialise labelmap lazily - we may have no | 
|---|
 | 1222 |                     // cross-sections. | 
|---|
 | 1223 |                     list<LabelInfo*>::const_iterator i; | 
|---|
 | 1224 |                     if (labelmap.empty()) { | 
|---|
 | 1225 |                         i = m_Labels.begin(); | 
|---|
 | 1226 |                     } else { | 
|---|
 | 1227 |                         i = last_mapped_label; | 
|---|
 | 1228 |                         ++i; | 
|---|
 | 1229 |                     } | 
|---|
 | 1230 |                     while (i != m_Labels.end() && (*i)->GetText() != label) { | 
|---|
 | 1231 |                         labelmap[(*i)->GetText()] = *i; | 
|---|
 | 1232 |                         ++i; | 
|---|
 | 1233 |                     } | 
|---|
 | 1234 |                     last_mapped_label = i; | 
|---|
 | 1235 |                     if (i == m_Labels.end()) { | 
|---|
 | 1236 |                         // Unattached cross-section - ignore for now. | 
|---|
 | 1237 |                         printf("unattached cross-section\n"); | 
|---|
 | 1238 |                         if (current_tube->size() <= 1) | 
|---|
 | 1239 |                             tubes.resize(tubes.size() - 1); | 
|---|
 | 1240 |                         current_tube = NULL; | 
|---|
 | 1241 |                         if (!m_Labels.empty()) | 
|---|
 | 1242 |                             --last_mapped_label; | 
|---|
 | 1243 |                         break; | 
|---|
 | 1244 |                     } | 
|---|
 | 1245 |                     lab = *i; | 
|---|
 | 1246 |                     labelmap[label] = lab; | 
|---|
| [d7d7fa7] | 1247 |                 } | 
|---|
| [ee05463] | 1248 |  | 
|---|
| [1ee204e] | 1249 |                 int date = survey->days1; | 
|---|
 | 1250 |                 if (date != -1) { | 
|---|
 | 1251 |                     date += (survey->days2 - date) / 2; | 
|---|
| [d4650b3] | 1252 |                     if (date < m_DateMin) m_DateMin = date; | 
|---|
 | 1253 |                     if (date > datemax) datemax = date; | 
|---|
 | 1254 |                 } | 
|---|
 | 1255 |  | 
|---|
| [576e5a9] | 1256 |                 current_tube->push_back(XSect(*lab, date, survey->l, survey->r, survey->u, survey->d)); | 
|---|
| [ee05463] | 1257 |                 break; | 
|---|
 | 1258 |             } | 
|---|
 | 1259 |  | 
|---|
| [d7d7fa7] | 1260 |             case img_XSECT_END: | 
|---|
 | 1261 |                 // Finish off current_tube. | 
|---|
 | 1262 |                 // If there's only one cross-section in the tube, just | 
|---|
 | 1263 |                 // discard it for now.  FIXME: we should handle this | 
|---|
 | 1264 |                 // when we come to skinning the tubes. | 
|---|
| [ae2e3c0] | 1265 |                 if (current_tube && current_tube->size() <= 1) | 
|---|
| [d7d7fa7] | 1266 |                     tubes.resize(tubes.size() - 1); | 
|---|
 | 1267 |                 current_tube = NULL; | 
|---|
 | 1268 |                 break; | 
|---|
 | 1269 |  | 
|---|
| [c61aa79] | 1270 |             case img_ERROR_INFO: { | 
|---|
| [ed58edc] | 1271 |                 if (survey->E == 0.0) { | 
|---|
 | 1272 |                     // Currently cavern doesn't spot all articulating traverses | 
|---|
 | 1273 |                     // so we assume that any traverse with no error isn't part | 
|---|
 | 1274 |                     // of a loop.  FIXME: fix cavern! | 
|---|
 | 1275 |                     break; | 
|---|
 | 1276 |                 } | 
|---|
| [c61aa79] | 1277 |                 m_HasErrorInformation = true; | 
|---|
 | 1278 |                 list<traverse>::reverse_iterator t; | 
|---|
 | 1279 |                 t = surface_traverses.rbegin(); | 
|---|
 | 1280 |                 while (n_surface_traverses) { | 
|---|
 | 1281 |                     assert(t != surface_traverses.rend()); | 
|---|
 | 1282 |                     t->n_legs = survey->n_legs; | 
|---|
 | 1283 |                     t->length = survey->length; | 
|---|
 | 1284 |                     t->E = survey->E; | 
|---|
 | 1285 |                     t->H = survey->H; | 
|---|
 | 1286 |                     t->V = survey->V; | 
|---|
 | 1287 |                     --n_surface_traverses; | 
|---|
 | 1288 |                     ++t; | 
|---|
 | 1289 |                 } | 
|---|
 | 1290 |                 t = traverses.rbegin(); | 
|---|
 | 1291 |                 while (n_traverses) { | 
|---|
 | 1292 |                     assert(t != traverses.rend()); | 
|---|
 | 1293 |                     t->n_legs = survey->n_legs; | 
|---|
 | 1294 |                     t->length = survey->length; | 
|---|
 | 1295 |                     t->E = survey->E; | 
|---|
 | 1296 |                     t->H = survey->H; | 
|---|
 | 1297 |                     t->V = survey->V; | 
|---|
 | 1298 |                     --n_traverses; | 
|---|
 | 1299 |                     ++t; | 
|---|
 | 1300 |                 } | 
|---|
 | 1301 |                 break; | 
|---|
 | 1302 |             } | 
|---|
 | 1303 |  | 
|---|
| [3ddcad8] | 1304 |             case img_BAD: { | 
|---|
| [421b7d2] | 1305 |                 m_Labels.clear(); | 
|---|
 | 1306 |  | 
|---|
 | 1307 |                 // FIXME: Do we need to reset all these? - Olly | 
|---|
 | 1308 |                 m_NumFixedPts = 0; | 
|---|
 | 1309 |                 m_NumExportedPts = 0; | 
|---|
 | 1310 |                 m_NumEntrances = 0; | 
|---|
| [f433fda] | 1311 |                 m_HasUndergroundLegs = false; | 
|---|
| [5fe7292] | 1312 |                 m_HasSplays = false; | 
|---|
| [f433fda] | 1313 |                 m_HasSurfaceLegs = false; | 
|---|
| [421b7d2] | 1314 |  | 
|---|
 | 1315 |                 img_close(survey); | 
|---|
 | 1316 |  | 
|---|
| [4d7d209] | 1317 |                 wxString m = wxString::Format(wmsg(img_error2msg(img_error())), file.c_str()); | 
|---|
| [421b7d2] | 1318 |                 wxGetApp().ReportError(m); | 
|---|
| [dc1a546] | 1319 |  | 
|---|
| [421b7d2] | 1320 |                 return false; | 
|---|
 | 1321 |             } | 
|---|
 | 1322 |  | 
|---|
 | 1323 |             default: | 
|---|
 | 1324 |                 break; | 
|---|
 | 1325 |         } | 
|---|
| [1d0cd97] | 1326 |     } while (result != img_STOP); | 
|---|
| [c1cf79d] | 1327 |  | 
|---|
| [57a3cd4] | 1328 |     if (!current_polyline_is_surface && current_traverse) { | 
|---|
| [ee05463] | 1329 |         //FixLRUD(*current_traverse); | 
|---|
| [57a3cd4] | 1330 |     } | 
|---|
 | 1331 |  | 
|---|
| [d7d7fa7] | 1332 |     // Finish off current_tube. | 
|---|
 | 1333 |     // If there's only one cross-section in the tube, just | 
|---|
 | 1334 |     // discard it for now.  FIXME: we should handle this | 
|---|
 | 1335 |     // when we come to skinning the tubes. | 
|---|
| [ae2e3c0] | 1336 |     if (current_tube && current_tube->size() <= 1) | 
|---|
| [d7d7fa7] | 1337 |         tubes.resize(tubes.size() - 1); | 
|---|
| [ee05463] | 1338 |  | 
|---|
| [ee1ec59] | 1339 |     separator = survey->separator; | 
|---|
| [5627cbb] | 1340 |     m_Title = wxString(survey->title, wxConvUTF8); | 
|---|
| [f10cf8f] | 1341 |     m_DateStamp_numeric = survey->datestamp_numeric; | 
|---|
| [42bd3576] | 1342 |     if (strcmp(survey->datestamp, "?") == 0) { | 
|---|
 | 1343 |         m_DateStamp = wmsg(/*Date and time not available.*/108); | 
|---|
 | 1344 |     } else if (survey->datestamp[0] == '@') { | 
|---|
| [f10cf8f] | 1345 |         const struct tm * tm = localtime(&m_DateStamp_numeric); | 
|---|
| [4f70ebc] | 1346 |         char buf[256]; | 
|---|
 | 1347 |         strftime(buf, 256, msg(/*%a,%Y.%m.%d %H:%M:%S %Z*/107), tm); | 
|---|
 | 1348 |         m_DateStamp = wxString(buf, wxConvUTF8); | 
|---|
| [42bd3576] | 1349 |     } | 
|---|
 | 1350 |     if (m_DateStamp.empty()) { | 
|---|
 | 1351 |         m_DateStamp = wxString(survey->datestamp, wxConvUTF8); | 
|---|
 | 1352 |     } | 
|---|
| [1d0cd97] | 1353 |     img_close(survey); | 
|---|
| [137bf99] | 1354 |  | 
|---|
| [1d0cd97] | 1355 |     // Check we've actually loaded some legs or stations! | 
|---|
| [f433fda] | 1356 |     if (!m_HasUndergroundLegs && !m_HasSurfaceLegs && m_Labels.empty()) { | 
|---|
| [0804fbe] | 1357 |         wxString m = wxString::Format(wmsg(/*No survey data in 3d file “%s”*/202), file.c_str()); | 
|---|
| [421b7d2] | 1358 |         wxGetApp().ReportError(m); | 
|---|
 | 1359 |         return false; | 
|---|
| [1d0cd97] | 1360 |     } | 
|---|
| [137bf99] | 1361 |  | 
|---|
| [3ddcad8] | 1362 |     if (traverses.empty() && surface_traverses.empty()) { | 
|---|
| [421b7d2] | 1363 |         // No legs, so get survey extents from stations | 
|---|
 | 1364 |         list<LabelInfo*>::const_iterator i; | 
|---|
 | 1365 |         for (i = m_Labels.begin(); i != m_Labels.end(); ++i) { | 
|---|
| [5a24583] | 1366 |             if ((*i)->GetX() < xmin) xmin = (*i)->GetX(); | 
|---|
 | 1367 |             if ((*i)->GetX() > xmax) xmax = (*i)->GetX(); | 
|---|
 | 1368 |             if ((*i)->GetY() < ymin) ymin = (*i)->GetY(); | 
|---|
 | 1369 |             if ((*i)->GetY() > ymax) ymax = (*i)->GetY(); | 
|---|
| [78c67a6] | 1370 |             if ((*i)->GetZ() < zmin) zmin = (*i)->GetZ(); | 
|---|
| [5a24583] | 1371 |             if ((*i)->GetZ() > zmax) zmax = (*i)->GetZ(); | 
|---|
| [421b7d2] | 1372 |         } | 
|---|
| [137bf99] | 1373 |     } | 
|---|
 | 1374 |  | 
|---|
| [78c67a6] | 1375 |     m_Ext.assign(xmax - xmin, ymax - ymin, zmax - zmin); | 
|---|
| [1d0cd97] | 1376 |  | 
|---|
| [1ee204e] | 1377 |     if (datemax < m_DateMin) m_DateMin = datemax; | 
|---|
| [d4650b3] | 1378 |     m_DateExt = datemax - m_DateMin; | 
|---|
 | 1379 |  | 
|---|
| [a6f081c] | 1380 |     // Centre the dataset around the origin. | 
|---|
| [78c67a6] | 1381 |     CentreDataset(Vector3(xmin, ymin, zmin)); | 
|---|
 | 1382 |  | 
|---|
 | 1383 |     if (depthmax < m_DepthMin) { | 
|---|
 | 1384 |         m_DepthMin = 0; | 
|---|
 | 1385 |         m_DepthExt = 0; | 
|---|
 | 1386 |     } else { | 
|---|
 | 1387 |         m_DepthExt = depthmax - m_DepthMin; | 
|---|
 | 1388 |         m_DepthMin -= m_Offsets.GetZ(); | 
|---|
 | 1389 |     } | 
|---|
| [a6f081c] | 1390 |  | 
|---|
| [c9427d2] | 1391 | #if 0 | 
|---|
 | 1392 |     printf("time to load = %.3f\n", (double)timer.Time()); | 
|---|
 | 1393 | #endif | 
|---|
 | 1394 |  | 
|---|
| [1d0cd97] | 1395 |     // Update window title. | 
|---|
| [1d7f0fd] | 1396 |     SetTitle(m_Title + " - "APP_NAME); | 
|---|
| [1d0cd97] | 1397 |  | 
|---|
 | 1398 |     return true; | 
|---|
| [f626e1f] | 1399 | } | 
|---|
 | 1400 |  | 
|---|
| [d4650b3] | 1401 | #if 0 | 
|---|
| [57a3cd4] | 1402 | // Run along a newly read in traverse and make up plausible LRUD where | 
|---|
 | 1403 | // it is missing. | 
|---|
 | 1404 | void | 
|---|
| [c61aa79] | 1405 | MainFrm::FixLRUD(traverse & centreline) | 
|---|
| [57a3cd4] | 1406 | { | 
|---|
 | 1407 |     assert(centreline.size() > 1); | 
|---|
 | 1408 |  | 
|---|
 | 1409 |     Double last_size = 0; | 
|---|
| [d4650b3] | 1410 |     vector<PointInfo>::iterator i = centreline.begin(); | 
|---|
| [57a3cd4] | 1411 |     while (i != centreline.end()) { | 
|---|
| [4c9e87b] | 1412 |         // Get the coordinates of this vertex. | 
|---|
| [db36155] | 1413 |         Point & pt_v = *i++; | 
|---|
| [57a3cd4] | 1414 |         Double size; | 
|---|
 | 1415 |  | 
|---|
 | 1416 |         if (i != centreline.end()) { | 
|---|
 | 1417 |             Double h = sqrd(i->GetX() - pt_v.GetX()) + | 
|---|
 | 1418 |                        sqrd(i->GetY() - pt_v.GetY()); | 
|---|
 | 1419 |             Double v = sqrd(i->GetZ() - pt_v.GetZ()); | 
|---|
 | 1420 |             if (h + v > 30.0 * 30.0) { | 
|---|
 | 1421 |                 Double scale = 30.0 / sqrt(h + v); | 
|---|
 | 1422 |                 h *= scale; | 
|---|
 | 1423 |                 v *= scale; | 
|---|
 | 1424 |             } | 
|---|
 | 1425 |             size = sqrt(h + v / 9); | 
|---|
 | 1426 |             size /= 4; | 
|---|
 | 1427 |             if (i == centreline.begin() + 1) { | 
|---|
 | 1428 |                 // First segment. | 
|---|
 | 1429 |                 last_size = size; | 
|---|
 | 1430 |             } else { | 
|---|
 | 1431 |                 // Intermediate segment. | 
|---|
 | 1432 |                 swap(size, last_size); | 
|---|
 | 1433 |                 size += last_size; | 
|---|
 | 1434 |                 size /= 2; | 
|---|
 | 1435 |             } | 
|---|
 | 1436 |         } else { | 
|---|
 | 1437 |             // Last segment. | 
|---|
 | 1438 |             size = last_size; | 
|---|
 | 1439 |         } | 
|---|
 | 1440 |  | 
|---|
 | 1441 |         Double & l = pt_v.l; | 
|---|
 | 1442 |         Double & r = pt_v.r; | 
|---|
 | 1443 |         Double & u = pt_v.u; | 
|---|
 | 1444 |         Double & d = pt_v.d; | 
|---|
 | 1445 |  | 
|---|
 | 1446 |         if (l == 0 && r == 0 && u == 0 && d == 0) { | 
|---|
 | 1447 |             l = r = u = d = -size; | 
|---|
 | 1448 |         } else { | 
|---|
 | 1449 |             if (l < 0 && r < 0) { | 
|---|
 | 1450 |                 l = r = -size; | 
|---|
 | 1451 |             } else if (l < 0) { | 
|---|
 | 1452 |                 l = -(2 * size - r); | 
|---|
 | 1453 |                 if (l >= 0) l = -0.01; | 
|---|
 | 1454 |             } else if (r < 0) { | 
|---|
 | 1455 |                 r = -(2 * size - l); | 
|---|
 | 1456 |                 if (r >= 0) r = -0.01; | 
|---|
 | 1457 |             } | 
|---|
 | 1458 |             if (u < 0 && d < 0) { | 
|---|
 | 1459 |                 u = d = -size; | 
|---|
 | 1460 |             } else if (u < 0) { | 
|---|
 | 1461 |                 u = -(2 * size - d); | 
|---|
 | 1462 |                 if (u >= 0) u = -0.01; | 
|---|
 | 1463 |             } else if (d < 0) { | 
|---|
 | 1464 |                 d = -(2 * size - u); | 
|---|
 | 1465 |                 if (d >= 0) d = -0.01; | 
|---|
 | 1466 |             } | 
|---|
 | 1467 |         } | 
|---|
 | 1468 |     } | 
|---|
 | 1469 | } | 
|---|
| [d4650b3] | 1470 | #endif | 
|---|
| [57a3cd4] | 1471 |  | 
|---|
| [156dc16] | 1472 | void MainFrm::FillTree() | 
|---|
 | 1473 | { | 
|---|
| [91c9bea] | 1474 |     // Create the root of the tree. | 
|---|
 | 1475 |     wxTreeItemId treeroot = m_Tree->AddRoot(wxFileNameFromPath(m_File)); | 
|---|
| [156dc16] | 1476 |  | 
|---|
| [91c9bea] | 1477 |     // Fill the tree of stations and prefixes. | 
|---|
| [156dc16] | 1478 |     stack<wxTreeItemId> previous_ids; | 
|---|
| [5627cbb] | 1479 |     wxString current_prefix; | 
|---|
| [91c9bea] | 1480 |     wxTreeItemId current_id = treeroot; | 
|---|
| [156dc16] | 1481 |  | 
|---|
| [86cdcf2] | 1482 |     list<LabelInfo*>::iterator pos = m_Labels.begin(); | 
|---|
| [156dc16] | 1483 |     while (pos != m_Labels.end()) { | 
|---|
| [421b7d2] | 1484 |         LabelInfo* label = *pos++; | 
|---|
| [156dc16] | 1485 |  | 
|---|
| [d309e17] | 1486 |         if (label->IsAnon()) continue; | 
|---|
 | 1487 |  | 
|---|
| [421b7d2] | 1488 |         // Determine the current prefix. | 
|---|
| [ee1ec59] | 1489 |         wxString prefix = label->GetText().BeforeLast(separator); | 
|---|
| [9d3d8cc] | 1490 |  | 
|---|
| [421b7d2] | 1491 |         // Determine if we're still on the same prefix. | 
|---|
 | 1492 |         if (prefix == current_prefix) { | 
|---|
 | 1493 |             // no need to fiddle with branches... | 
|---|
 | 1494 |         } | 
|---|
 | 1495 |         // If not, then see if we've descended to a new prefix. | 
|---|
| [4252768] | 1496 |         else if (prefix.length() > current_prefix.length() && | 
|---|
| [003d953] | 1497 |                  prefix.StartsWith(current_prefix) && | 
|---|
| [4252768] | 1498 |                  (prefix[current_prefix.length()] == separator || | 
|---|
| [5627cbb] | 1499 |                   current_prefix.empty())) { | 
|---|
| [421b7d2] | 1500 |             // We have, so start as many new branches as required. | 
|---|
| [4252768] | 1501 |             int current_prefix_length = current_prefix.length(); | 
|---|
| [421b7d2] | 1502 |             current_prefix = prefix; | 
|---|
| [05b5d5b] | 1503 |             size_t next_dot = current_prefix_length; | 
|---|
 | 1504 |             if (!next_dot) --next_dot; | 
|---|
| [421b7d2] | 1505 |             do { | 
|---|
| [44ed489] | 1506 |                 size_t prev_dot = next_dot + 1; | 
|---|
 | 1507 |  | 
|---|
| [421b7d2] | 1508 |                 // Extract the next bit of prefix. | 
|---|
| [44ed489] | 1509 |                 next_dot = prefix.find(separator, prev_dot + 1); | 
|---|
| [421b7d2] | 1510 |  | 
|---|
| [44ed489] | 1511 |                 wxString bit = prefix.substr(prev_dot, next_dot - prev_dot); | 
|---|
| [5627cbb] | 1512 |                 assert(!bit.empty()); | 
|---|
| [421b7d2] | 1513 |  | 
|---|
 | 1514 |                 // Add the current tree ID to the stack. | 
|---|
 | 1515 |                 previous_ids.push(current_id); | 
|---|
 | 1516 |  | 
|---|
 | 1517 |                 // Append the new item to the tree and set this as the current branch. | 
|---|
 | 1518 |                 current_id = m_Tree->AppendItem(current_id, bit); | 
|---|
| [44ed489] | 1519 |                 m_Tree->SetItemData(current_id, new TreeData(prefix.substr(0, next_dot))); | 
|---|
 | 1520 |             } while (next_dot != wxString::npos); | 
|---|
| [421b7d2] | 1521 |         } | 
|---|
 | 1522 |         // Otherwise, we must have moved up, and possibly then down again. | 
|---|
 | 1523 |         else { | 
|---|
| [dc8d2eb] | 1524 |             size_t count = 0; | 
|---|
| [4252768] | 1525 |             bool ascent_only = (prefix.length() < current_prefix.length() && | 
|---|
| [421b7d2] | 1526 |                                 current_prefix.StartsWith(prefix) && | 
|---|
| [4252768] | 1527 |                                 (current_prefix[prefix.length()] == separator || | 
|---|
| [5627cbb] | 1528 |                                  prefix.empty())); | 
|---|
| [421b7d2] | 1529 |             if (!ascent_only) { | 
|---|
| [7d9e02b] | 1530 |                 // Find out how much of the current prefix and the new prefix | 
|---|
 | 1531 |                 // are the same. | 
|---|
 | 1532 |                 // Note that we require a match of a whole number of parts | 
|---|
 | 1533 |                 // between dots! | 
|---|
| [17de0e2] | 1534 |                 size_t n = min(prefix.length(), current_prefix.length()); | 
|---|
 | 1535 |                 size_t i; | 
|---|
 | 1536 |                 for (i = 0; i < n && prefix[i] == current_prefix[i]; ++i) { | 
|---|
| [b4fe9fb] | 1537 |                     if (prefix[i] == separator) count = i + 1; | 
|---|
| [421b7d2] | 1538 |                 } | 
|---|
| [b4fe9fb] | 1539 |             } else { | 
|---|
| [4252768] | 1540 |                 count = prefix.length() + 1; | 
|---|
| [421b7d2] | 1541 |             } | 
|---|
 | 1542 |  | 
|---|
| [7d9e02b] | 1543 |             // Extract the part of the current prefix after the bit (if any) | 
|---|
 | 1544 |             // which has matched. | 
|---|
| [421b7d2] | 1545 |             // This gives the prefixes to ascend over. | 
|---|
| [4252768] | 1546 |             wxString prefixes_ascended = current_prefix.substr(count); | 
|---|
| [421b7d2] | 1547 |  | 
|---|
 | 1548 |             // Count the number of prefixes to ascend over. | 
|---|
| [ee1ec59] | 1549 |             int num_prefixes = prefixes_ascended.Freq(separator); | 
|---|
| [421b7d2] | 1550 |  | 
|---|
 | 1551 |             // Reverse up over these prefixes. | 
|---|
 | 1552 |             for (int i = 1; i <= num_prefixes; i++) { | 
|---|
 | 1553 |                 previous_ids.pop(); | 
|---|
 | 1554 |             } | 
|---|
| [8734409] | 1555 |             current_id = previous_ids.top(); | 
|---|
 | 1556 |             previous_ids.pop(); | 
|---|
| [421b7d2] | 1557 |  | 
|---|
 | 1558 |             if (!ascent_only) { | 
|---|
 | 1559 |                 // Add branches for this new part. | 
|---|
| [44ed489] | 1560 |                 size_t next_dot = count - 1; | 
|---|
 | 1561 |                 do { | 
|---|
 | 1562 |                     size_t prev_dot = next_dot + 1; | 
|---|
 | 1563 |  | 
|---|
| [421b7d2] | 1564 |                     // Extract the next bit of prefix. | 
|---|
| [44ed489] | 1565 |                     next_dot = prefix.find(separator, prev_dot + 1); | 
|---|
| [421b7d2] | 1566 |  | 
|---|
| [44ed489] | 1567 |                     wxString bit = prefix.substr(prev_dot, next_dot - prev_dot); | 
|---|
| [5627cbb] | 1568 |                     assert(!bit.empty()); | 
|---|
| [421b7d2] | 1569 |  | 
|---|
 | 1570 |                     // Add the current tree ID to the stack. | 
|---|
 | 1571 |                     previous_ids.push(current_id); | 
|---|
 | 1572 |  | 
|---|
| [44ed489] | 1573 |                     // Append the new item to the tree and set this as the current branch. | 
|---|
| [421b7d2] | 1574 |                     current_id = m_Tree->AppendItem(current_id, bit); | 
|---|
| [44ed489] | 1575 |                     m_Tree->SetItemData(current_id, new TreeData(prefix.substr(0, next_dot))); | 
|---|
 | 1576 |                 } while (next_dot != wxString::npos); | 
|---|
| [421b7d2] | 1577 |             } | 
|---|
 | 1578 |  | 
|---|
 | 1579 |             current_prefix = prefix; | 
|---|
 | 1580 |         } | 
|---|
 | 1581 |  | 
|---|
 | 1582 |         // Now add the leaf. | 
|---|
| [ee1ec59] | 1583 |         wxString bit = label->GetText().AfterLast(separator); | 
|---|
| [5627cbb] | 1584 |         assert(!bit.empty()); | 
|---|
| [421b7d2] | 1585 |         wxTreeItemId id = m_Tree->AppendItem(current_id, bit); | 
|---|
 | 1586 |         m_Tree->SetItemData(id, new TreeData(label)); | 
|---|
| [91c9bea] | 1587 |         label->tree_id = id; | 
|---|
 | 1588 |         // Set the colour for an item in the survey tree. | 
|---|
 | 1589 |         if (label->IsEntrance()) { | 
|---|
 | 1590 |             // Entrances are green (like entrance blobs). | 
|---|
| [18886d7] | 1591 |             m_Tree->SetItemTextColour(id, wxColour(0, 255, 40)); | 
|---|
| [91c9bea] | 1592 |         } else if (label->IsSurface()) { | 
|---|
 | 1593 |             // Surface stations are dark green. | 
|---|
 | 1594 |             m_Tree->SetItemTextColour(id, wxColour(49, 158, 79)); | 
|---|
 | 1595 |         } | 
|---|
| [156dc16] | 1596 |     } | 
|---|
| [91c9bea] | 1597 |  | 
|---|
 | 1598 |     m_Tree->Expand(treeroot); | 
|---|
 | 1599 |     m_Tree->SetEnabled(); | 
|---|
| [156dc16] | 1600 | } | 
|---|
 | 1601 |  | 
|---|
| [d67450e] | 1602 | void MainFrm::CentreDataset(const Vector3 & vmin) | 
|---|
| [a6f081c] | 1603 | { | 
|---|
 | 1604 |     // Centre the dataset around the origin. | 
|---|
 | 1605 |  | 
|---|
| [d67450e] | 1606 |     m_Offsets = vmin + (m_Ext * 0.5); | 
|---|
| [a6f081c] | 1607 |  | 
|---|
| [c61aa79] | 1608 |     list<traverse>::iterator t = traverses.begin(); | 
|---|
| [3ddcad8] | 1609 |     while (t != traverses.end()) { | 
|---|
| [faae79c] | 1610 |         assert(t->size() > 1); | 
|---|
| [d4650b3] | 1611 |         vector<PointInfo>::iterator pos = t->begin(); | 
|---|
| [3ddcad8] | 1612 |         while (pos != t->end()) { | 
|---|
| [db36155] | 1613 |             Point & point = *pos++; | 
|---|
| [d67450e] | 1614 |             point -= m_Offsets; | 
|---|
| [3ddcad8] | 1615 |         } | 
|---|
 | 1616 |         ++t; | 
|---|
 | 1617 |     } | 
|---|
 | 1618 |  | 
|---|
 | 1619 |     t = surface_traverses.begin(); | 
|---|
 | 1620 |     while (t != surface_traverses.end()) { | 
|---|
| [faae79c] | 1621 |         assert(t->size() > 1); | 
|---|
| [d4650b3] | 1622 |         vector<PointInfo>::iterator pos = t->begin(); | 
|---|
| [3ddcad8] | 1623 |         while (pos != t->end()) { | 
|---|
| [db36155] | 1624 |             Point & point = *pos++; | 
|---|
| [d67450e] | 1625 |             point -= m_Offsets; | 
|---|
| [3ddcad8] | 1626 |         } | 
|---|
 | 1627 |         ++t; | 
|---|
| [a6f081c] | 1628 |     } | 
|---|
 | 1629 |  | 
|---|
| [ee05463] | 1630 |     list<vector<XSect> >::iterator i = tubes.begin(); | 
|---|
 | 1631 |     while (i != tubes.end()) { | 
|---|
 | 1632 |         assert(i->size() > 1); | 
|---|
 | 1633 |         vector<XSect>::iterator pos = i->begin(); | 
|---|
 | 1634 |         while (pos != i->end()) { | 
|---|
| [d4650b3] | 1635 |             Point & point = *pos++; | 
|---|
| [d67450e] | 1636 |             point -= m_Offsets; | 
|---|
| [ee05463] | 1637 |         } | 
|---|
 | 1638 |         ++i; | 
|---|
 | 1639 |     } | 
|---|
 | 1640 |  | 
|---|
| [a6f081c] | 1641 |     list<LabelInfo*>::iterator lpos = m_Labels.begin(); | 
|---|
 | 1642 |     while (lpos != m_Labels.end()) { | 
|---|
| [d4650b3] | 1643 |         Point & point = **lpos++; | 
|---|
| [d67450e] | 1644 |         point -= m_Offsets; | 
|---|
| [a6f081c] | 1645 |     } | 
|---|
 | 1646 | } | 
|---|
 | 1647 |  | 
|---|
| [732b9b0] | 1648 | void MainFrm::OnMRUFile(wxCommandEvent& event) | 
|---|
 | 1649 | { | 
|---|
 | 1650 |     wxString f(m_history.GetHistoryFile(event.GetId() - wxID_FILE1)); | 
|---|
 | 1651 |     if (!f.empty()) OpenFile(f); | 
|---|
 | 1652 | } | 
|---|
 | 1653 |  | 
|---|
| [bc73093] | 1654 | void MainFrm::AddToFileHistory(const wxString & file) | 
|---|
 | 1655 | { | 
|---|
 | 1656 |     if (wxIsAbsolutePath(file)) { | 
|---|
 | 1657 |         m_history.AddFileToHistory(file); | 
|---|
 | 1658 |     } else { | 
|---|
 | 1659 |         wxString abs = wxGetCwd(); | 
|---|
 | 1660 |         abs += wxCONFIG_PATH_SEPARATOR; | 
|---|
 | 1661 |         abs += file; | 
|---|
 | 1662 |         m_history.AddFileToHistory(abs); | 
|---|
 | 1663 |     } | 
|---|
 | 1664 |     wxConfigBase *b = wxConfigBase::Get(); | 
|---|
 | 1665 |     m_history.Save(*b); | 
|---|
 | 1666 |     b->Flush(); | 
|---|
 | 1667 | } | 
|---|
 | 1668 |  | 
|---|
| [dde4fe7] | 1669 | void MainFrm::OpenFile(const wxString& file, wxString survey) | 
|---|
| [137bf99] | 1670 | { | 
|---|
| [4b1fc48] | 1671 |     wxBusyCursor hourglass; | 
|---|
| [bc73093] | 1672 |  | 
|---|
 | 1673 |     // Check if this is an unprocessed survey data file. | 
|---|
 | 1674 |     if (file.length() > 4 && file[file.length() - 4] == '.') { | 
|---|
 | 1675 |         wxString ext(file, file.length() - 3, 3); | 
|---|
 | 1676 |         ext.MakeLower(); | 
|---|
 | 1677 |         if (ext == wxT("svx") || ext == wxT("dat") || ext == wxT("mak")) { | 
|---|
| [fb5887c] | 1678 |             CavernLogWindow * log = new CavernLogWindow(this, m_Splitter); | 
|---|
 | 1679 |             wxWindow * win = m_Splitter->GetWindow1(); | 
|---|
 | 1680 |             m_Splitter->ReplaceWindow(win, log); | 
|---|
 | 1681 |             if (m_Splitter->GetWindow2() == NULL) { | 
|---|
 | 1682 |                 if (win != m_Gfx) win->Destroy(); | 
|---|
 | 1683 |             } else { | 
|---|
 | 1684 |                 if (m_Splitter->IsSplit()) m_Splitter->Unsplit(); | 
|---|
 | 1685 |             } | 
|---|
 | 1686 |  | 
|---|
 | 1687 |             int result = log->process(file); | 
|---|
 | 1688 |             if (result < 0) { | 
|---|
 | 1689 |                 // Error running cavern or processing data. | 
|---|
| [bc73093] | 1690 |                 return; | 
|---|
 | 1691 |             } | 
|---|
| [fb5887c] | 1692 |  | 
|---|
| [bc73093] | 1693 |             AddToFileHistory(file); | 
|---|
 | 1694 |             wxString file3d(file, 0, file.length() - 3); | 
|---|
 | 1695 |             file3d.append(wxT("3d")); | 
|---|
 | 1696 |             if (!LoadData(file3d, survey)) | 
|---|
 | 1697 |                 return; | 
|---|
| [fb5887c] | 1698 |             if (result == 0) { | 
|---|
 | 1699 |                 InitialiseAfterLoad(file); | 
|---|
 | 1700 |             } | 
|---|
| [bc73093] | 1701 |             return; | 
|---|
| [eb5b48df] | 1702 |         } | 
|---|
| [137bf99] | 1703 |     } | 
|---|
| [bc73093] | 1704 |  | 
|---|
 | 1705 |     if (!LoadData(file, survey)) | 
|---|
 | 1706 |         return; | 
|---|
 | 1707 |     AddToFileHistory(file); | 
|---|
 | 1708 |     InitialiseAfterLoad(file); | 
|---|
 | 1709 | } | 
|---|
 | 1710 |  | 
|---|
 | 1711 | void MainFrm::InitialiseAfterLoad(const wxString & file) | 
|---|
 | 1712 | { | 
|---|
| [486c619] | 1713 |     if (m_SashPosition < 0) { | 
|---|
 | 1714 |         // Calculate sane default width for side panel. | 
|---|
 | 1715 |         int x; | 
|---|
 | 1716 |         int y; | 
|---|
 | 1717 |         GetClientSize(&x, &y); | 
|---|
 | 1718 |         if (x < 600) | 
|---|
 | 1719 |             x /= 3; | 
|---|
 | 1720 |         else if (x < 1000) | 
|---|
 | 1721 |             x = 200; | 
|---|
 | 1722 |         else | 
|---|
 | 1723 |             x /= 5; | 
|---|
 | 1724 |         m_SashPosition = x; | 
|---|
 | 1725 |     } | 
|---|
| [bc73093] | 1726 |  | 
|---|
| [fb5887c] | 1727 |     // Do this before we potentially delete the log window which may own the | 
|---|
 | 1728 |     // wxString which parameter file refers to! | 
|---|
| [bc73093] | 1729 |     bool same_file = (file == m_File); | 
|---|
 | 1730 |     if (!same_file) | 
|---|
 | 1731 |         m_File = file; | 
|---|
 | 1732 |  | 
|---|
| [b775443] | 1733 |     // Sort the labels ready for filling the tree. | 
|---|
 | 1734 |     m_Labels.sort(LabelCmp(separator)); | 
|---|
 | 1735 |  | 
|---|
 | 1736 |     // Fill the tree of stations and prefixes. | 
|---|
 | 1737 |     FillTree(); | 
|---|
 | 1738 |  | 
|---|
 | 1739 |     // Sort labels so that entrances are displayed in preference, | 
|---|
 | 1740 |     // then fixed points, then exported points, then other points. | 
|---|
 | 1741 |     // | 
|---|
 | 1742 |     // Also sort by leaf name so that we'll tend to choose labels | 
|---|
 | 1743 |     // from different surveys, rather than labels from surveys which | 
|---|
 | 1744 |     // are earlier in the list. | 
|---|
 | 1745 |     m_Labels.sort(LabelPlotCmp(separator)); | 
|---|
 | 1746 |  | 
|---|
 | 1747 |     if (!m_FindBox->GetValue().empty()) { | 
|---|
 | 1748 |         // Highlight any stations matching the current search. | 
|---|
| [bc60689] | 1749 |         DoFind(); | 
|---|
| [b775443] | 1750 |     } | 
|---|
 | 1751 |  | 
|---|
| [fb5887c] | 1752 |     wxWindow * win = NULL; | 
|---|
 | 1753 |     if (m_Splitter->GetWindow2() == NULL) { | 
|---|
 | 1754 |         win = m_Splitter->GetWindow1(); | 
|---|
 | 1755 |         if (win == m_Gfx) win = NULL; | 
|---|
 | 1756 |     } | 
|---|
 | 1757 |  | 
|---|
| [486c619] | 1758 |     if (!IsFullScreen()) { | 
|---|
 | 1759 |         m_Splitter->SplitVertically(m_Notebook, m_Gfx, m_SashPosition); | 
|---|
 | 1760 |     } else { | 
|---|
 | 1761 |         was_showing_sidepanel_before_fullscreen = true; | 
|---|
 | 1762 |     } | 
|---|
| [fb5887c] | 1763 |  | 
|---|
| [bc73093] | 1764 |     m_Gfx->Initialise(same_file); | 
|---|
| [486c619] | 1765 |     if (!IsFullScreen()) { | 
|---|
 | 1766 |         m_Notebook->Show(true); | 
|---|
 | 1767 |     } | 
|---|
| [bc73093] | 1768 |  | 
|---|
 | 1769 |     m_Gfx->Show(true); | 
|---|
 | 1770 |     m_Gfx->SetFocus(); | 
|---|
| [fb5887c] | 1771 |  | 
|---|
 | 1772 |     if (win) win->Destroy(); | 
|---|
| [137bf99] | 1773 | } | 
|---|
 | 1774 |  | 
|---|
 | 1775 | // | 
|---|
 | 1776 | //  UI event handlers | 
|---|
 | 1777 | // | 
|---|
 | 1778 |  | 
|---|
| [c988ae4] | 1779 | // For Unix we want "*.svx;*.SVX" while for Windows we only want "*.svx". | 
|---|
 | 1780 | #ifdef _WIN32 | 
|---|
 | 1781 | # define CASE(X) | 
|---|
 | 1782 | #else | 
|---|
 | 1783 | # define CASE(X) ";"X | 
|---|
| [496a208] | 1784 | #endif | 
|---|
 | 1785 |  | 
|---|
| [137bf99] | 1786 | void MainFrm::OnOpen(wxCommandEvent&) | 
|---|
 | 1787 | { | 
|---|
| [1c6b20d7] | 1788 |     AvenAllowOnTop ontop(this); | 
|---|
| [137bf99] | 1789 | #ifdef __WXMOTIF__ | 
|---|
| [5627cbb] | 1790 |     wxString filetypes = wxT("*.3d"); | 
|---|
| [137bf99] | 1791 | #else | 
|---|
| [c988ae4] | 1792 |     wxString filetypes; | 
|---|
| [d9cd8ae] | 1793 |     filetypes.Printf(wxT("%s|*.3d;*.svx;*.plt;*.plf;*.dat;*.mak;*.adj;*.sht;*.una;*.xyz" | 
|---|
 | 1794 |                      CASE("*.3D;*.SVX;*.PLT;*.PLF;*.DAT;*.MAK;*.ADJ;*.SHT;*.UNA;*.XYZ") | 
|---|
| [71de189] | 1795 |                      "|%s|*.3d"CASE("*.3D") | 
|---|
| [c988ae4] | 1796 |                      "|%s|*.svx"CASE("*.SVX") | 
|---|
 | 1797 |                      "|%s|*.plt;*.plf"CASE("*.PLT;*.PLF") | 
|---|
 | 1798 |                      "|%s|*.dat;*.mak"CASE("*.DAT;*.MAK") | 
|---|
| [d9cd8ae] | 1799 |                      "|%s|*.adj;*.sht;*.una;*.xyz"CASE("*.ADJ;*.SHT;*.UNA;*.XYZ") | 
|---|
| [5627cbb] | 1800 |                      "|%s|%s"), | 
|---|
| [6e63fd3] | 1801 |                      wmsg(/*All survey files*/229).c_str(), | 
|---|
| [5627cbb] | 1802 |                      wmsg(/*Survex 3d files*/207).c_str(), | 
|---|
| [6e63fd3] | 1803 |                      wmsg(/*Survex svx files*/329).c_str(), | 
|---|
| [5627cbb] | 1804 |                      wmsg(/*Compass PLT files*/324).c_str(), | 
|---|
| [6e63fd3] | 1805 |                      wmsg(/*Compass DAT and MAK files*/330).c_str(), | 
|---|
| [5627cbb] | 1806 |                      wmsg(/*CMAP XYZ files*/325).c_str(), | 
|---|
 | 1807 |                      wmsg(/*All files*/208).c_str(), | 
|---|
| [c988ae4] | 1808 |                      wxFileSelectorDefaultWildcardStr); | 
|---|
| [5627cbb] | 1809 | #endif | 
|---|
| [6e63fd3] | 1810 |     wxFileDialog dlg(this, wmsg(/*Select a survey file to view*/206), | 
|---|
| [5627cbb] | 1811 |                      wxString(), wxString(), | 
|---|
| [c988ae4] | 1812 |                      filetypes, wxFD_OPEN|wxFD_FILE_MUST_EXIST); | 
|---|
| [137bf99] | 1813 |     if (dlg.ShowModal() == wxID_OK) { | 
|---|
| [421b7d2] | 1814 |         OpenFile(dlg.GetPath()); | 
|---|
| [137bf99] | 1815 |     } | 
|---|
 | 1816 | } | 
|---|
 | 1817 |  | 
|---|
| [045e2af] | 1818 | void MainFrm::OnScreenshot(wxCommandEvent&) | 
|---|
 | 1819 | { | 
|---|
| [1c6b20d7] | 1820 |     AvenAllowOnTop ontop(this); | 
|---|
| [f302cbaa] | 1821 |     wxString baseleaf; | 
|---|
 | 1822 |     wxFileName::SplitPath(m_File, NULL, NULL, &baseleaf, NULL, wxPATH_NATIVE); | 
|---|
| [5627cbb] | 1823 |     wxFileDialog dlg(this, wmsg(/*Save Screenshot*/321), wxString(), | 
|---|
| [f302cbaa] | 1824 |                      baseleaf + wxT(".png"), | 
|---|
| [5627cbb] | 1825 |                      wxT("*.png"), wxFD_SAVE|wxFD_OVERWRITE_PROMPT); | 
|---|
| [045e2af] | 1826 |     if (dlg.ShowModal() == wxID_OK) { | 
|---|
 | 1827 |         static bool png_handled = false; | 
|---|
 | 1828 |         if (!png_handled) { | 
|---|
| [4a0e6b35] | 1829 | #if 0 // FIXME : enable this to allow other export formats... | 
|---|
| [ee41e88] | 1830 |             ::wxInitAllImageHandlers(); | 
|---|
 | 1831 | #else | 
|---|
| [045e2af] | 1832 |             wxImage::AddHandler(new wxPNGHandler); | 
|---|
| [ee41e88] | 1833 | #endif | 
|---|
| [045e2af] | 1834 |             png_handled = true; | 
|---|
 | 1835 |         } | 
|---|
 | 1836 |         if (!m_Gfx->SaveScreenshot(dlg.GetPath(), wxBITMAP_TYPE_PNG)) { | 
|---|
| [0804fbe] | 1837 |             wxGetApp().ReportError(wxString::Format(wmsg(/*Error writing to file “%s”*/110), dlg.GetPath().c_str())); | 
|---|
| [045e2af] | 1838 |         } | 
|---|
 | 1839 |     } | 
|---|
 | 1840 | } | 
|---|
 | 1841 |  | 
|---|
 | 1842 | void MainFrm::OnScreenshotUpdate(wxUpdateUIEvent& event) | 
|---|
 | 1843 | { | 
|---|
 | 1844 |     event.Enable(!m_File.empty()); | 
|---|
 | 1845 | } | 
|---|
 | 1846 |  | 
|---|
| [02c7c1a] | 1847 | void MainFrm::OnFilePreferences(wxCommandEvent&) | 
|---|
 | 1848 | { | 
|---|
| [edb6576] | 1849 | #ifdef PREFDLG | 
|---|
| [203d2a7] | 1850 |     m_PrefsDlg = new PrefsDlg(m_Gfx, this); | 
|---|
| [02c7c1a] | 1851 |     m_PrefsDlg->Show(true); | 
|---|
| [edb6576] | 1852 | #endif | 
|---|
| [02c7c1a] | 1853 | } | 
|---|
| [8000d8f] | 1854 |  | 
|---|
| [ce403f1] | 1855 | void MainFrm::OnPrint(wxCommandEvent&) | 
|---|
 | 1856 | { | 
|---|
| [f10cf8f] | 1857 |     m_Gfx->OnPrint(m_File, m_Title, m_DateStamp, m_DateStamp_numeric); | 
|---|
| [ce403f1] | 1858 | } | 
|---|
 | 1859 |  | 
|---|
 | 1860 | void MainFrm::OnPageSetup(wxCommandEvent&) | 
|---|
 | 1861 | { | 
|---|
| [e0ffc2c] | 1862 |     wxPageSetupDialog dlg(this, wxGetApp().GetPageSetupDialogData()); | 
|---|
 | 1863 |     if (dlg.ShowModal() == wxID_OK) { | 
|---|
 | 1864 |         wxGetApp().SetPageSetupDialogData(dlg.GetPageSetupData()); | 
|---|
 | 1865 |     } | 
|---|
| [ce403f1] | 1866 | } | 
|---|
 | 1867 |  | 
|---|
| [223f1ad] | 1868 | void MainFrm::OnExport(wxCommandEvent&) | 
|---|
 | 1869 | { | 
|---|
| [f10cf8f] | 1870 |     m_Gfx->OnExport(m_File, m_Title, m_DateStamp, m_DateStamp_numeric); | 
|---|
| [223f1ad] | 1871 | } | 
|---|
 | 1872 |  | 
|---|
| [137bf99] | 1873 | void MainFrm::OnQuit(wxCommandEvent&) | 
|---|
 | 1874 | { | 
|---|
| [1690fa9] | 1875 |     if (m_PresList->Modified()) { | 
|---|
| [1c6b20d7] | 1876 |         AvenAllowOnTop ontop(this); | 
|---|
| [1690fa9] | 1877 |         // FIXME: better to ask "Do you want to save your changes?" and offer [Save] [Discard] [Cancel] | 
|---|
| [5627cbb] | 1878 |         if (wxMessageBox(wmsg(/*The current presentation has been modified.  Abandon unsaved changes?*/327), | 
|---|
 | 1879 |                          wmsg(/*Modified Presentation*/326), | 
|---|
| [1690fa9] | 1880 |                          wxOK|wxCANCEL|wxICON_QUESTION) == wxCANCEL) { | 
|---|
 | 1881 |             return; | 
|---|
 | 1882 |         } | 
|---|
 | 1883 |     } | 
|---|
| [3db0798] | 1884 |     wxConfigBase *b = wxConfigBase::Get(); | 
|---|
 | 1885 |     if (IsFullScreen()) { | 
|---|
| [5627cbb] | 1886 |         b->Write(wxT("width"), -2); | 
|---|
 | 1887 |         b->DeleteEntry(wxT("height")); | 
|---|
| [3db0798] | 1888 |     } else if (IsMaximized()) { | 
|---|
| [5627cbb] | 1889 |         b->Write(wxT("width"), -1); | 
|---|
 | 1890 |         b->DeleteEntry(wxT("height")); | 
|---|
| [3db0798] | 1891 |     } else { | 
|---|
 | 1892 |         int width, height; | 
|---|
 | 1893 |         GetSize(&width, &height); | 
|---|
| [5627cbb] | 1894 |         b->Write(wxT("width"), width); | 
|---|
 | 1895 |         b->Write(wxT("height"), height); | 
|---|
| [3db0798] | 1896 |     } | 
|---|
 | 1897 |     b->Flush(); | 
|---|
| [137bf99] | 1898 |     exit(0); | 
|---|
 | 1899 | } | 
|---|
 | 1900 |  | 
|---|
 | 1901 | void MainFrm::OnClose(wxCloseEvent&) | 
|---|
 | 1902 | { | 
|---|
| [3db0798] | 1903 |     wxCommandEvent dummy; | 
|---|
 | 1904 |     OnQuit(dummy); | 
|---|
| [137bf99] | 1905 | } | 
|---|
 | 1906 |  | 
|---|
 | 1907 | void MainFrm::OnAbout(wxCommandEvent&) | 
|---|
 | 1908 | { | 
|---|
| [1c6b20d7] | 1909 |     AvenAllowOnTop ontop(this); | 
|---|
| [cf5e9ee] | 1910 |     AboutDlg dlg(this, icon_path); | 
|---|
| [796aee3] | 1911 |     dlg.Centre(); | 
|---|
 | 1912 |     dlg.ShowModal(); | 
|---|
| [137bf99] | 1913 | } | 
|---|
| [c6d95d8] | 1914 |  | 
|---|
| [7c29c976] | 1915 | void MainFrm::UpdateStatusBar() | 
|---|
 | 1916 | { | 
|---|
 | 1917 |     if (!here_text.empty()) { | 
|---|
 | 1918 |         GetStatusBar()->SetStatusText(here_text); | 
|---|
 | 1919 |         GetStatusBar()->SetStatusText(dist_text, 1); | 
|---|
 | 1920 |     } else if (!coords_text.empty()) { | 
|---|
 | 1921 |         GetStatusBar()->SetStatusText(coords_text); | 
|---|
| [0633bcc] | 1922 |         GetStatusBar()->SetStatusText(distfree_text, 1); | 
|---|
| [7c29c976] | 1923 |     } else { | 
|---|
| [5627cbb] | 1924 |         GetStatusBar()->SetStatusText(wxString()); | 
|---|
 | 1925 |         GetStatusBar()->SetStatusText(wxString(), 1); | 
|---|
| [7c29c976] | 1926 |     } | 
|---|
 | 1927 | } | 
|---|
 | 1928 |  | 
|---|
| [1fd2edb] | 1929 | void MainFrm::ClearTreeSelection() | 
|---|
 | 1930 | { | 
|---|
 | 1931 |     m_Tree->UnselectAll(); | 
|---|
| [19026f3] | 1932 |     m_Gfx->SetThere(); | 
|---|
| [6b061db] | 1933 |     ShowInfo(NULL); | 
|---|
| [1fd2edb] | 1934 | } | 
|---|
 | 1935 |  | 
|---|
| [156dc16] | 1936 | void MainFrm::ClearCoords() | 
|---|
 | 1937 | { | 
|---|
| [4b031c0] | 1938 |     if (!coords_text.empty()) { | 
|---|
| [5627cbb] | 1939 |         coords_text = wxString(); | 
|---|
| [4b031c0] | 1940 |         UpdateStatusBar(); | 
|---|
 | 1941 |     } | 
|---|
| [156dc16] | 1942 | } | 
|---|
 | 1943 |  | 
|---|
| [d67450e] | 1944 | void MainFrm::SetCoords(const Vector3 &v) | 
|---|
| [d877aa2] | 1945 | { | 
|---|
| [ccb83b7] | 1946 |     Double x = v.GetX(); | 
|---|
 | 1947 |     Double y = v.GetY(); | 
|---|
 | 1948 |     Double z = v.GetZ(); | 
|---|
 | 1949 |     int units; | 
|---|
| [d877aa2] | 1950 |     if (m_Gfx->GetMetric()) { | 
|---|
| [ccb83b7] | 1951 |         units = /*m*/424; | 
|---|
| [d877aa2] | 1952 |     } else { | 
|---|
| [ccb83b7] | 1953 |         x /= METRES_PER_FOOT; | 
|---|
 | 1954 |         y /= METRES_PER_FOOT; | 
|---|
 | 1955 |         z /= METRES_PER_FOOT; | 
|---|
 | 1956 |         units = /*ft*/428; | 
|---|
| [d877aa2] | 1957 |     } | 
|---|
| [ccb83b7] | 1958 |     coords_text.Printf(wmsg(/*%.2f E, %.2f N*/338), x, y); | 
|---|
 | 1959 |     coords_text += wxString::Format(wxT(", %s %.2f%s"), | 
|---|
 | 1960 |                                     wmsg(/*Altitude*/335).c_str(), | 
|---|
 | 1961 |                                     z, wmsg(units).c_str()); | 
|---|
| [5627cbb] | 1962 |     distfree_text = wxString(); | 
|---|
| [7c29c976] | 1963 |     UpdateStatusBar(); | 
|---|
| [d877aa2] | 1964 | } | 
|---|
 | 1965 |  | 
|---|
| [0633bcc] | 1966 | const LabelInfo * MainFrm::GetTreeSelection() const { | 
|---|
 | 1967 |     wxTreeItemData* sel_wx; | 
|---|
 | 1968 |     if (!m_Tree->GetSelectionData(&sel_wx)) return NULL; | 
|---|
 | 1969 |  | 
|---|
| [44ed489] | 1970 |     const TreeData* data = static_cast<const TreeData*>(sel_wx); | 
|---|
| [0633bcc] | 1971 |     if (!data->IsStation()) return NULL; | 
|---|
 | 1972 |  | 
|---|
 | 1973 |     return data->GetLabel(); | 
|---|
 | 1974 | } | 
|---|
 | 1975 |  | 
|---|
| [156dc16] | 1976 | void MainFrm::SetCoords(Double x, Double y) | 
|---|
 | 1977 | { | 
|---|
| [7c29c976] | 1978 |     wxString & s = coords_text; | 
|---|
| [33b2094] | 1979 |     if (m_Gfx->GetMetric()) { | 
|---|
| [5627cbb] | 1980 |         s.Printf(wmsg(/*%.2f E, %.2f N*/338), x, y); | 
|---|
| [7a89dc2] | 1981 |     } else { | 
|---|
| [5627cbb] | 1982 |         s.Printf(wmsg(/*%.2f E, %.2f N*/338), | 
|---|
| [3d4bee1] | 1983 |                  x / METRES_PER_FOOT, y / METRES_PER_FOOT); | 
|---|
| [7a89dc2] | 1984 |     } | 
|---|
| [0633bcc] | 1985 |  | 
|---|
| [c00c6713] | 1986 |     wxString & t = distfree_text; | 
|---|
| [5627cbb] | 1987 |     t = wxString(); | 
|---|
| [c00c6713] | 1988 |     const LabelInfo* label; | 
|---|
 | 1989 |     if (m_Gfx->ShowingMeasuringLine() && (label = GetTreeSelection())) { | 
|---|
| [0633bcc] | 1990 |         Vector3 delta(x - m_Offsets.GetX() - label->GetX(), | 
|---|
 | 1991 |                       y - m_Offsets.GetY() - label->GetY(), 0); | 
|---|
 | 1992 |         Double dh = sqrt(delta.GetX()*delta.GetX() + delta.GetY()*delta.GetY()); | 
|---|
 | 1993 |         Double brg = deg(atan2(delta.GetX(), delta.GetY())); | 
|---|
 | 1994 |         if (brg < 0) brg += 360; | 
|---|
 | 1995 |  | 
|---|
 | 1996 |         wxString from_str; | 
|---|
| [5627cbb] | 1997 |         from_str.Printf(wmsg(/*From %s*/339), label->GetText().c_str()); | 
|---|
| [0633bcc] | 1998 |  | 
|---|
| [ccb83b7] | 1999 |         int brg_unit; | 
|---|
| [0633bcc] | 2000 |         if (m_Gfx->GetDegrees()) { | 
|---|
| [ccb83b7] | 2001 |             brg_unit = /*°*/344; | 
|---|
| [0633bcc] | 2002 |         } else { | 
|---|
 | 2003 |             brg *= 400.0 / 360.0; | 
|---|
| [ccb83b7] | 2004 |             brg_unit = /*grad*/345; | 
|---|
| [0633bcc] | 2005 |         } | 
|---|
 | 2006 |  | 
|---|
| [ccb83b7] | 2007 |         int units; | 
|---|
| [0633bcc] | 2008 |         if (m_Gfx->GetMetric()) { | 
|---|
| [ccb83b7] | 2009 |             units = /*m*/424; | 
|---|
| [0633bcc] | 2010 |         } else { | 
|---|
| [ccb83b7] | 2011 |             dh /= METRES_PER_FOOT; | 
|---|
 | 2012 |             units = /*ft*/428; | 
|---|
| [0633bcc] | 2013 |         } | 
|---|
| [ccb83b7] | 2014 |         t.Printf(wmsg(/*%s: H %.2f%s, Brg %03d%s*/374), | 
|---|
 | 2015 |                  from_str.c_str(), dh, wmsg(units).c_str(), | 
|---|
 | 2016 |                  int(brg), wmsg(brg_unit).c_str()); | 
|---|
| [0633bcc] | 2017 |     } | 
|---|
 | 2018 |  | 
|---|
| [7c29c976] | 2019 |     UpdateStatusBar(); | 
|---|
| [156dc16] | 2020 | } | 
|---|
 | 2021 |  | 
|---|
| [7a89dc2] | 2022 | void MainFrm::SetAltitude(Double z) | 
|---|
| [156dc16] | 2023 | { | 
|---|
| [ccb83b7] | 2024 |     double alt = z; | 
|---|
 | 2025 |     int units; | 
|---|
| [33b2094] | 2026 |     if (m_Gfx->GetMetric()) { | 
|---|
| [ccb83b7] | 2027 |         units = /*m*/424; | 
|---|
| [7a89dc2] | 2028 |     } else { | 
|---|
| [ccb83b7] | 2029 |         alt /= METRES_PER_FOOT; | 
|---|
 | 2030 |         units = /*ft*/428; | 
|---|
| [7a89dc2] | 2031 |     } | 
|---|
| [ccb83b7] | 2032 |     coords_text.Printf(wxT("%s %.2f%s"), wmsg(/*Altitude*/335).c_str(), | 
|---|
 | 2033 |                        alt, wmsg(units).c_str()); | 
|---|
| [0633bcc] | 2034 |  | 
|---|
| [c00c6713] | 2035 |     wxString & t = distfree_text; | 
|---|
| [5627cbb] | 2036 |     t = wxString(); | 
|---|
| [c00c6713] | 2037 |     const LabelInfo* label; | 
|---|
 | 2038 |     if (m_Gfx->ShowingMeasuringLine() && (label = GetTreeSelection())) { | 
|---|
| [0633bcc] | 2039 |         Double dz = z - m_Offsets.GetZ() - label->GetZ(); | 
|---|
 | 2040 |  | 
|---|
 | 2041 |         wxString from_str; | 
|---|
| [5627cbb] | 2042 |         from_str.Printf(wmsg(/*From %s*/339), label->GetText().c_str()); | 
|---|
| [0633bcc] | 2043 |  | 
|---|
| [ccb83b7] | 2044 |         if (!m_Gfx->GetMetric()) { | 
|---|
 | 2045 |             dz /= METRES_PER_FOOT; | 
|---|
| [0633bcc] | 2046 |         } | 
|---|
| [ccb83b7] | 2047 |         t.Printf(wmsg(/*%s: V %.2f%s*/375), from_str.c_str(), | 
|---|
 | 2048 |                  dz, wmsg(units).c_str()); | 
|---|
| [0633bcc] | 2049 |     } | 
|---|
 | 2050 |  | 
|---|
| [7c29c976] | 2051 |     UpdateStatusBar(); | 
|---|
| [2a3d328] | 2052 | } | 
|---|
 | 2053 |  | 
|---|
| [0633bcc] | 2054 | void MainFrm::ShowInfo(const LabelInfo *here) | 
|---|
| [7a89dc2] | 2055 | { | 
|---|
 | 2056 |     assert(m_Gfx); | 
|---|
| [f433fda] | 2057 |  | 
|---|
| [0633bcc] | 2058 |     if (!here) { | 
|---|
| [7c29c976] | 2059 |         m_Gfx->SetHere(); | 
|---|
| [570d62c3] | 2060 |         m_Tree->SetHere(wxTreeItemId()); | 
|---|
| [1235f9b] | 2061 |         // Don't clear "There" mark here. | 
|---|
| [4b031c0] | 2062 |         if (here_text.empty() && dist_text.empty()) return; | 
|---|
| [5627cbb] | 2063 |         here_text = wxString(); | 
|---|
 | 2064 |         dist_text = wxString(); | 
|---|
| [7c29c976] | 2065 |         UpdateStatusBar(); | 
|---|
 | 2066 |         return; | 
|---|
 | 2067 |     } | 
|---|
 | 2068 |  | 
|---|
| [0633bcc] | 2069 |     Vector3 v = *here + m_Offsets; | 
|---|
| [7c29c976] | 2070 |     wxString & s = here_text; | 
|---|
| [ccb83b7] | 2071 |     Double x = v.GetX(); | 
|---|
 | 2072 |     Double y = v.GetY(); | 
|---|
 | 2073 |     Double z = v.GetZ(); | 
|---|
 | 2074 |     int units; | 
|---|
| [33b2094] | 2075 |     if (m_Gfx->GetMetric()) { | 
|---|
| [ccb83b7] | 2076 |         units = /*m*/424; | 
|---|
| [7a89dc2] | 2077 |     } else { | 
|---|
| [ccb83b7] | 2078 |         x /= METRES_PER_FOOT; | 
|---|
 | 2079 |         y /= METRES_PER_FOOT; | 
|---|
 | 2080 |         z /= METRES_PER_FOOT; | 
|---|
 | 2081 |         units = /*ft*/428; | 
|---|
| [7a89dc2] | 2082 |     } | 
|---|
| [ccb83b7] | 2083 |     s.Printf(wmsg(/*%.2f E, %.2f N*/338), x, y); | 
|---|
 | 2084 |     s += wxString::Format(wxT(", %s %.2f%s"), wmsg(/*Altitude*/335).c_str(), | 
|---|
 | 2085 |                           z, wmsg(units).c_str()); | 
|---|
| [5627cbb] | 2086 |     s += wxT(": "); | 
|---|
| [5a24583] | 2087 |     s += here->GetText(); | 
|---|
| [0633bcc] | 2088 |     m_Gfx->SetHere(*here); | 
|---|
| [570d62c3] | 2089 |     m_Tree->SetHere(here->tree_id); | 
|---|
| [7a89dc2] | 2090 |  | 
|---|
| [c00c6713] | 2091 |     const LabelInfo* label; | 
|---|
 | 2092 |     if (m_Gfx->ShowingMeasuringLine() && (label = GetTreeSelection())) { | 
|---|
| [0633bcc] | 2093 |         Vector3 delta = *here - *label; | 
|---|
| [d67450e] | 2094 |  | 
|---|
| [0633bcc] | 2095 |         Double d_horiz = sqrt(delta.GetX()*delta.GetX() + delta.GetY()*delta.GetY()); | 
|---|
 | 2096 |         Double dr = delta.magnitude(); | 
|---|
| [d67450e] | 2097 |  | 
|---|
| [0633bcc] | 2098 |         Double brg = deg(atan2(delta.GetX(), delta.GetY())); | 
|---|
 | 2099 |         if (brg < 0) brg += 360; | 
|---|
| [421b7d2] | 2100 |  | 
|---|
| [0633bcc] | 2101 |         wxString from_str; | 
|---|
| [5627cbb] | 2102 |         from_str.Printf(wmsg(/*From %s*/339), label->GetText().c_str()); | 
|---|
| [203d2a7] | 2103 |  | 
|---|
| [0633bcc] | 2104 |         wxString hv_str; | 
|---|
| [19a5798] | 2105 |         z = v.GetZ(); | 
|---|
| [0633bcc] | 2106 |         if (m_Gfx->GetMetric()) { | 
|---|
| [ccb83b7] | 2107 |             units = /*m*/424; | 
|---|
| [0633bcc] | 2108 |         } else { | 
|---|
| [ccb83b7] | 2109 |             d_horiz /= METRES_PER_FOOT; | 
|---|
 | 2110 |             dr /= METRES_PER_FOOT; | 
|---|
 | 2111 |             z /= METRES_PER_FOOT; | 
|---|
 | 2112 |             units = /*ft*/428; | 
|---|
| [0633bcc] | 2113 |         } | 
|---|
| [ccb83b7] | 2114 |         wxString len_unit = wmsg(units); | 
|---|
 | 2115 |         hv_str.Printf(wmsg(/*H %.2f%s, V %.2f%s*/340), | 
|---|
 | 2116 |                       d_horiz, len_unit.c_str(), z, len_unit.c_str()); | 
|---|
 | 2117 |         int brg_unit; | 
|---|
| [0633bcc] | 2118 |         if (m_Gfx->GetDegrees()) { | 
|---|
| [ccb83b7] | 2119 |             brg_unit = /*°*/344; | 
|---|
| [7a89dc2] | 2120 |         } else { | 
|---|
| [0633bcc] | 2121 |             brg *= 400.0 / 360.0; | 
|---|
| [ccb83b7] | 2122 |             brg_unit = /*grad*/345; | 
|---|
| [421b7d2] | 2123 |         } | 
|---|
| [0633bcc] | 2124 |         wxString & d = dist_text; | 
|---|
| [ccb83b7] | 2125 |         d.Printf(wmsg(/*%s: %s, Dist %.2f%s, Brg %03d%s*/341), | 
|---|
 | 2126 |                  from_str.c_str(), hv_str.c_str(), | 
|---|
 | 2127 |                  dr, len_unit.c_str(), int(brg), wmsg(brg_unit).c_str()); | 
|---|
| [0633bcc] | 2128 |         m_Gfx->SetThere(*label); | 
|---|
 | 2129 |     } else { | 
|---|
| [5627cbb] | 2130 |         dist_text = wxString(); | 
|---|
| [0633bcc] | 2131 |         m_Gfx->SetThere(); | 
|---|
| [156dc16] | 2132 |     } | 
|---|
| [7c29c976] | 2133 |     UpdateStatusBar(); | 
|---|
| [7a89dc2] | 2134 | } | 
|---|
 | 2135 |  | 
|---|
| [8734409] | 2136 | void MainFrm::DisplayTreeInfo(const wxTreeItemData* item) | 
|---|
| [7a89dc2] | 2137 | { | 
|---|
| [8734409] | 2138 |     const TreeData* data = static_cast<const TreeData*>(item); | 
|---|
| [887c26e] | 2139 |     if (data && data->IsStation()) { | 
|---|
 | 2140 |         const LabelInfo * label = data->GetLabel(); | 
|---|
 | 2141 |         ShowInfo(label); | 
|---|
 | 2142 |         m_Gfx->SetHere(*label); | 
|---|
 | 2143 |     } else { | 
|---|
| [7c29c976] | 2144 |         ShowInfo(NULL); | 
|---|
| [156dc16] | 2145 |     } | 
|---|
 | 2146 | } | 
|---|
 | 2147 |  | 
|---|
| [44ed489] | 2148 | void MainFrm::TreeItemSelected(const wxTreeItemData* item, bool zoom) | 
|---|
| [156dc16] | 2149 | { | 
|---|
| [44ed489] | 2150 |     const TreeData* data = static_cast<const TreeData*>(item); | 
|---|
| [156dc16] | 2151 |     if (data && data->IsStation()) { | 
|---|
| [8734409] | 2152 |         const LabelInfo* label = data->GetLabel(); | 
|---|
| [44ed489] | 2153 |         if (zoom) m_Gfx->CentreOn(*label); | 
|---|
| [82c3731] | 2154 |         m_Gfx->SetThere(*label); | 
|---|
| [5627cbb] | 2155 |         dist_text = wxString(); | 
|---|
| [7c29c976] | 2156 |         // FIXME: Need to update dist_text (From ... etc) | 
|---|
| [887c26e] | 2157 |         // But we don't currently know where "here" is at this point in the | 
|---|
 | 2158 |         // code! | 
|---|
| [0580c6a] | 2159 |     } else { | 
|---|
| [5627cbb] | 2160 |         dist_text = wxString(); | 
|---|
| [0580c6a] | 2161 |         m_Gfx->SetThere(); | 
|---|
| [156dc16] | 2162 |     } | 
|---|
| [44ed489] | 2163 |     if (!data) { | 
|---|
 | 2164 |         // Must be the root. | 
|---|
| [5627cbb] | 2165 |         m_FindBox->SetValue(wxString()); | 
|---|
| [44ed489] | 2166 |         if (zoom) { | 
|---|
 | 2167 |             wxCommandEvent dummy; | 
|---|
 | 2168 |             OnDefaults(dummy); | 
|---|
 | 2169 |         } | 
|---|
 | 2170 |     } else if (data && !data->IsStation()) { | 
|---|
| [5627cbb] | 2171 |         m_FindBox->SetValue(data->GetSurvey() + wxT(".*")); | 
|---|
| [44ed489] | 2172 |         if (zoom) { | 
|---|
 | 2173 |             wxCommandEvent dummy; | 
|---|
 | 2174 |             OnGotoFound(dummy); | 
|---|
 | 2175 |         } | 
|---|
 | 2176 |     } | 
|---|
| [7c29c976] | 2177 |     UpdateStatusBar(); | 
|---|
| [156dc16] | 2178 | } | 
|---|
 | 2179 |  | 
|---|
| [97a414f] | 2180 | void MainFrm::OnPresNew(wxCommandEvent&) | 
|---|
| [156dc16] | 2181 | { | 
|---|
| [1690fa9] | 2182 |     if (m_PresList->Modified()) { | 
|---|
| [1c6b20d7] | 2183 |         AvenAllowOnTop ontop(this); | 
|---|
| [1690fa9] | 2184 |         // FIXME: better to ask "Do you want to save your changes?" and offer [Save] [Discard] [Cancel] | 
|---|
| [5627cbb] | 2185 |         if (wxMessageBox(wmsg(/*The current presentation has been modified.  Abandon unsaved changes?*/327), | 
|---|
 | 2186 |                          wmsg(/*Modified Presentation*/326), | 
|---|
| [1690fa9] | 2187 |                          wxOK|wxCANCEL|wxICON_QUESTION) == wxCANCEL) { | 
|---|
 | 2188 |             return; | 
|---|
 | 2189 |         } | 
|---|
| [156dc16] | 2190 |     } | 
|---|
| [bd7607c] | 2191 |     m_PresList->New(m_File); | 
|---|
| [24961e2] | 2192 |     if (!ShowingSidePanel()) ToggleSidePanel(); | 
|---|
| [c8f929b] | 2193 |     // Select the presentation page in the notebook. | 
|---|
 | 2194 |     m_Notebook->SetSelection(1); | 
|---|
| [156dc16] | 2195 | } | 
|---|
 | 2196 |  | 
|---|
| [97a414f] | 2197 | void MainFrm::OnPresOpen(wxCommandEvent&) | 
|---|
| [156dc16] | 2198 | { | 
|---|
| [1c6b20d7] | 2199 |     AvenAllowOnTop ontop(this); | 
|---|
| [1690fa9] | 2200 |     if (m_PresList->Modified()) { | 
|---|
 | 2201 |         // FIXME: better to ask "Do you want to save your changes?" and offer [Save] [Discard] [Cancel] | 
|---|
| [5627cbb] | 2202 |         if (wxMessageBox(wmsg(/*The current presentation has been modified.  Abandon unsaved changes?*/327), | 
|---|
 | 2203 |                          wmsg(/*Modified Presentation*/326), | 
|---|
| [1690fa9] | 2204 |                          wxOK|wxCANCEL|wxICON_QUESTION) == wxCANCEL) { | 
|---|
 | 2205 |             return; | 
|---|
 | 2206 |         } | 
|---|
 | 2207 |     } | 
|---|
| [156dc16] | 2208 | #ifdef __WXMOTIF__ | 
|---|
| [5627cbb] | 2209 |     wxFileDialog dlg(this, wmsg(/*Select a presentation to open*/322), wxString(), wxString(), | 
|---|
 | 2210 |                      wxT("*.fly"), wxFD_OPEN); | 
|---|
| [156dc16] | 2211 | #else | 
|---|
| [5627cbb] | 2212 |     wxFileDialog dlg(this, wmsg(/*Select a presentation to open*/322), wxString(), wxString(), | 
|---|
 | 2213 |                      wxString::Format(wxT("%s|*.fly|%s|%s"), | 
|---|
 | 2214 |                                wmsg(/*Aven presentations*/320).c_str(), | 
|---|
 | 2215 |                                wmsg(/*All files*/208).c_str(), | 
|---|
 | 2216 |                                wxFileSelectorDefaultWildcardStr), | 
|---|
 | 2217 |                      wxFD_OPEN|wxFD_FILE_MUST_EXIST); | 
|---|
| [156dc16] | 2218 | #endif | 
|---|
 | 2219 |     if (dlg.ShowModal() == wxID_OK) { | 
|---|
| [1690fa9] | 2220 |         if (!m_PresList->Load(dlg.GetPath())) { | 
|---|
 | 2221 |             return; | 
|---|
 | 2222 |         } | 
|---|
| [97a414f] | 2223 |         // FIXME : keep a history of loaded/saved presentations, like we do for | 
|---|
 | 2224 |         // loaded surveys... | 
|---|
| [c8f929b] | 2225 |         // Select the presentation page in the notebook. | 
|---|
 | 2226 |         m_Notebook->SetSelection(1); | 
|---|
| [156dc16] | 2227 |     } | 
|---|
 | 2228 | } | 
|---|
| [5ffa439] | 2229 |  | 
|---|
| [97a414f] | 2230 | void MainFrm::OnPresSave(wxCommandEvent&) | 
|---|
| [8000d8f] | 2231 | { | 
|---|
| [1690fa9] | 2232 |     m_PresList->Save(true); | 
|---|
| [8000d8f] | 2233 | } | 
|---|
 | 2234 |  | 
|---|
| [97a414f] | 2235 | void MainFrm::OnPresSaveAs(wxCommandEvent&) | 
|---|
| [5ffa439] | 2236 | { | 
|---|
| [1690fa9] | 2237 |     m_PresList->Save(false); | 
|---|
| [5ffa439] | 2238 | } | 
|---|
 | 2239 |  | 
|---|
| [97a414f] | 2240 | void MainFrm::OnPresMark(wxCommandEvent&) | 
|---|
| [5ffa439] | 2241 | { | 
|---|
| [1690fa9] | 2242 |     m_PresList->AddMark(); | 
|---|
| [5ffa439] | 2243 | } | 
|---|
 | 2244 |  | 
|---|
| [128fac4] | 2245 | void MainFrm::OnPresFRewind(wxCommandEvent&) | 
|---|
 | 2246 | { | 
|---|
 | 2247 |     m_Gfx->PlayPres(-100); | 
|---|
 | 2248 | } | 
|---|
 | 2249 |  | 
|---|
 | 2250 | void MainFrm::OnPresRewind(wxCommandEvent&) | 
|---|
 | 2251 | { | 
|---|
 | 2252 |     m_Gfx->PlayPres(-10); | 
|---|
 | 2253 | } | 
|---|
 | 2254 |  | 
|---|
 | 2255 | void MainFrm::OnPresReverse(wxCommandEvent&) | 
|---|
 | 2256 | { | 
|---|
 | 2257 |     m_Gfx->PlayPres(-1); | 
|---|
 | 2258 | } | 
|---|
 | 2259 |  | 
|---|
 | 2260 | void MainFrm::OnPresPlay(wxCommandEvent&) | 
|---|
| [5ffa439] | 2261 | { | 
|---|
| [128fac4] | 2262 |     m_Gfx->PlayPres(1); | 
|---|
 | 2263 | } | 
|---|
 | 2264 |  | 
|---|
 | 2265 | void MainFrm::OnPresFF(wxCommandEvent&) | 
|---|
 | 2266 | { | 
|---|
 | 2267 |     m_Gfx->PlayPres(10); | 
|---|
 | 2268 | } | 
|---|
 | 2269 |  | 
|---|
 | 2270 | void MainFrm::OnPresFFF(wxCommandEvent&) | 
|---|
 | 2271 | { | 
|---|
 | 2272 |     m_Gfx->PlayPres(100); | 
|---|
 | 2273 | } | 
|---|
 | 2274 |  | 
|---|
 | 2275 | void MainFrm::OnPresPause(wxCommandEvent&) | 
|---|
 | 2276 | { | 
|---|
 | 2277 |     m_Gfx->PlayPres(0); | 
|---|
 | 2278 | } | 
|---|
 | 2279 |  | 
|---|
 | 2280 | void MainFrm::OnPresStop(wxCommandEvent&) | 
|---|
 | 2281 | { | 
|---|
 | 2282 |     m_Gfx->PlayPres(0, false); | 
|---|
| [5ffa439] | 2283 | } | 
|---|
 | 2284 |  | 
|---|
| [97a414f] | 2285 | void MainFrm::OnPresExportMovie(wxCommandEvent&) | 
|---|
| [6a4cdcb6] | 2286 | { | 
|---|
| [1c6b20d7] | 2287 |     AvenAllowOnTop ontop(this); | 
|---|
| [97a414f] | 2288 |     // FIXME : Taking the leaf of the currently loaded presentation as the | 
|---|
 | 2289 |     // default might make more sense? | 
|---|
| [f302cbaa] | 2290 |     wxString baseleaf; | 
|---|
 | 2291 |     wxFileName::SplitPath(m_File, NULL, NULL, &baseleaf, NULL, wxPATH_NATIVE); | 
|---|
| [6e63fd3] | 2292 |     wxFileDialog dlg(this, wmsg(/*Export Movie*/331), wxString(), | 
|---|
| [f302cbaa] | 2293 |                      baseleaf + wxT(".mpg"), | 
|---|
| [5627cbb] | 2294 |                      wxT("MPEG|*.mpg|AVI|*.avi|QuickTime|*.mov|WMV|*.wmv;*.asf"), | 
|---|
| [4e98397] | 2295 |                      wxFD_SAVE|wxFD_OVERWRITE_PROMPT); | 
|---|
| [97a414f] | 2296 |     if (dlg.ShowModal() == wxID_OK) { | 
|---|
| [091069f] | 2297 |         // Error is reported by GfxCore. | 
|---|
 | 2298 |         (void)m_Gfx->ExportMovie(dlg.GetPath()); | 
|---|
| [6a4cdcb6] | 2299 |     } | 
|---|
 | 2300 | } | 
|---|
 | 2301 |  | 
|---|
| [1690fa9] | 2302 | PresentationMark MainFrm::GetPresMark(int which) | 
|---|
| [5ffa439] | 2303 | { | 
|---|
| [1690fa9] | 2304 |     return m_PresList->GetPresMark(which); | 
|---|
| [5ffa439] | 2305 | } | 
|---|
 | 2306 |  | 
|---|
| [1690fa9] | 2307 | //void MainFrm::OnFileOpenTerrainUpdate(wxUpdateUIEvent& event) | 
|---|
 | 2308 | //{ | 
|---|
 | 2309 | //    event.Enable(!m_File.empty()); | 
|---|
 | 2310 | //} | 
|---|
 | 2311 |  | 
|---|
 | 2312 | void MainFrm::OnPresNewUpdate(wxUpdateUIEvent& event) | 
|---|
| [5ffa439] | 2313 | { | 
|---|
| [1366db2] | 2314 |     event.Enable(!m_File.empty()); | 
|---|
| [5ffa439] | 2315 | } | 
|---|
 | 2316 |  | 
|---|
| [1690fa9] | 2317 | void MainFrm::OnPresOpenUpdate(wxUpdateUIEvent& event) | 
|---|
| [5ffa439] | 2318 | { | 
|---|
| [1690fa9] | 2319 |     event.Enable(!m_File.empty()); | 
|---|
| [5ffa439] | 2320 | } | 
|---|
 | 2321 |  | 
|---|
| [1690fa9] | 2322 | void MainFrm::OnPresSaveUpdate(wxUpdateUIEvent& event) | 
|---|
| [5ffa439] | 2323 | { | 
|---|
| [1690fa9] | 2324 |     event.Enable(!m_PresList->Empty()); | 
|---|
| [5ffa439] | 2325 | } | 
|---|
 | 2326 |  | 
|---|
| [1690fa9] | 2327 | void MainFrm::OnPresSaveAsUpdate(wxUpdateUIEvent& event) | 
|---|
| [5ffa439] | 2328 | { | 
|---|
| [1690fa9] | 2329 |     event.Enable(!m_PresList->Empty()); | 
|---|
| [5ffa439] | 2330 | } | 
|---|
 | 2331 |  | 
|---|
| [1690fa9] | 2332 | void MainFrm::OnPresMarkUpdate(wxUpdateUIEvent& event) | 
|---|
| [5ffa439] | 2333 | { | 
|---|
| [1690fa9] | 2334 |     event.Enable(!m_File.empty()); | 
|---|
 | 2335 | } | 
|---|
 | 2336 |  | 
|---|
| [128fac4] | 2337 | void MainFrm::OnPresFRewindUpdate(wxUpdateUIEvent& event) | 
|---|
 | 2338 | { | 
|---|
 | 2339 |     event.Enable(m_Gfx && m_Gfx->GetPresentationMode()); | 
|---|
 | 2340 |     event.Check(m_Gfx && m_Gfx->GetPresentationSpeed() < -10); | 
|---|
 | 2341 | } | 
|---|
 | 2342 |  | 
|---|
 | 2343 | void MainFrm::OnPresRewindUpdate(wxUpdateUIEvent& event) | 
|---|
 | 2344 | { | 
|---|
 | 2345 |     event.Enable(m_Gfx && m_Gfx->GetPresentationMode()); | 
|---|
 | 2346 |     event.Check(m_Gfx && m_Gfx->GetPresentationSpeed() == -10); | 
|---|
 | 2347 | } | 
|---|
 | 2348 |  | 
|---|
 | 2349 | void MainFrm::OnPresReverseUpdate(wxUpdateUIEvent& event) | 
|---|
 | 2350 | { | 
|---|
 | 2351 |     event.Enable(m_Gfx && m_Gfx->GetPresentationMode()); | 
|---|
 | 2352 |     event.Check(m_Gfx && m_Gfx->GetPresentationSpeed() == -1); | 
|---|
 | 2353 | } | 
|---|
 | 2354 |  | 
|---|
 | 2355 | void MainFrm::OnPresPlayUpdate(wxUpdateUIEvent& event) | 
|---|
| [1690fa9] | 2356 | { | 
|---|
 | 2357 |     event.Enable(!m_PresList->Empty()); | 
|---|
| [128fac4] | 2358 |     event.Check(m_Gfx && m_Gfx->GetPresentationMode() && | 
|---|
 | 2359 |                 m_Gfx->GetPresentationSpeed() == 1); | 
|---|
 | 2360 | } | 
|---|
 | 2361 |  | 
|---|
 | 2362 | void MainFrm::OnPresFFUpdate(wxUpdateUIEvent& event) | 
|---|
 | 2363 | { | 
|---|
 | 2364 |     event.Enable(m_Gfx && m_Gfx->GetPresentationMode()); | 
|---|
 | 2365 |     event.Check(m_Gfx && m_Gfx->GetPresentationSpeed() == 10); | 
|---|
 | 2366 | } | 
|---|
 | 2367 |  | 
|---|
 | 2368 | void MainFrm::OnPresFFFUpdate(wxUpdateUIEvent& event) | 
|---|
 | 2369 | { | 
|---|
 | 2370 |     event.Enable(m_Gfx && m_Gfx->GetPresentationMode()); | 
|---|
 | 2371 |     event.Check(m_Gfx && m_Gfx->GetPresentationSpeed() > 10); | 
|---|
 | 2372 | } | 
|---|
 | 2373 |  | 
|---|
 | 2374 | void MainFrm::OnPresPauseUpdate(wxUpdateUIEvent& event) | 
|---|
 | 2375 | { | 
|---|
 | 2376 |     event.Enable(m_Gfx && m_Gfx->GetPresentationMode()); | 
|---|
 | 2377 |     event.Check(m_Gfx && m_Gfx->GetPresentationSpeed() == 0); | 
|---|
 | 2378 | } | 
|---|
 | 2379 |  | 
|---|
 | 2380 | void MainFrm::OnPresStopUpdate(wxUpdateUIEvent& event) | 
|---|
 | 2381 | { | 
|---|
 | 2382 |     event.Enable(m_Gfx && m_Gfx->GetPresentationMode()); | 
|---|
| [5ffa439] | 2383 | } | 
|---|
| [2a02de2] | 2384 |  | 
|---|
| [6a4cdcb6] | 2385 | void MainFrm::OnPresExportMovieUpdate(wxUpdateUIEvent& event) | 
|---|
 | 2386 | { | 
|---|
 | 2387 |     event.Enable(!m_PresList->Empty()); | 
|---|
 | 2388 | } | 
|---|
 | 2389 |  | 
|---|
| [b4fe9fb] | 2390 | void MainFrm::OnFind(wxCommandEvent&) | 
|---|
| [2a02de2] | 2391 | { | 
|---|
| [bc60689] | 2392 |     pending_find = true; | 
|---|
 | 2393 | } | 
|---|
 | 2394 |  | 
|---|
 | 2395 | void MainFrm::OnIdle(wxIdleEvent&) | 
|---|
 | 2396 | { | 
|---|
 | 2397 |     if (pending_find) { | 
|---|
 | 2398 |         DoFind(); | 
|---|
 | 2399 |     } | 
|---|
 | 2400 | } | 
|---|
 | 2401 |  | 
|---|
 | 2402 | void MainFrm::DoFind() | 
|---|
 | 2403 | { | 
|---|
 | 2404 |     pending_find = false; | 
|---|
| [e98af57] | 2405 |     wxBusyCursor hourglass; | 
|---|
| [44ed489] | 2406 |     // Find stations specified by a string or regular expression pattern. | 
|---|
| [9d3d8cc] | 2407 |  | 
|---|
| [0580c6a] | 2408 |     wxString pattern = m_FindBox->GetValue(); | 
|---|
| [d1628e8e] | 2409 |     if (pattern.empty()) { | 
|---|
 | 2410 |         // Hide any search result highlights. | 
|---|
 | 2411 |         list<LabelInfo*>::iterator pos = m_Labels.begin(); | 
|---|
 | 2412 |         while (pos != m_Labels.end()) { | 
|---|
 | 2413 |             LabelInfo* label = *pos++; | 
|---|
| [5a24583] | 2414 |             label->clear_flags(LFLAG_HIGHLIGHTED); | 
|---|
| [c8aff97] | 2415 |         } | 
|---|
| [d1628e8e] | 2416 |         m_NumHighlighted = 0; | 
|---|
| [0c76ad9] | 2417 |     } else { | 
|---|
| [d1628e8e] | 2418 |         int re_flags = wxRE_NOSUB; | 
|---|
 | 2419 |  | 
|---|
 | 2420 |         if (true /* case insensitive */) { | 
|---|
 | 2421 |             re_flags |= wxRE_ICASE; | 
|---|
| [0c76ad9] | 2422 |         } | 
|---|
 | 2423 |  | 
|---|
| [d1628e8e] | 2424 |         bool substring = true; | 
|---|
 | 2425 |         if (false /*m_RegexpCheckBox->GetValue()*/) { | 
|---|
 | 2426 |             re_flags |= wxRE_EXTENDED; | 
|---|
 | 2427 |         } else if (true /* simple glob-style */) { | 
|---|
 | 2428 |             wxString pat; | 
|---|
 | 2429 |             for (size_t i = 0; i < pattern.size(); i++) { | 
|---|
| [5627cbb] | 2430 |                wxChar ch = pattern[i]; | 
|---|
| [d1628e8e] | 2431 |                // ^ only special at start; $ at end.  But this is simpler... | 
|---|
 | 2432 |                switch (ch) { | 
|---|
 | 2433 |                 case '^': case '$': case '.': case '[': case '\\': | 
|---|
| [5627cbb] | 2434 |                   pat += wxT('\\'); | 
|---|
| [d1628e8e] | 2435 |                   pat += ch; | 
|---|
 | 2436 |                   break; | 
|---|
 | 2437 |                 case '*': | 
|---|
| [5627cbb] | 2438 |                   pat += wxT(".*"); | 
|---|
| [d1628e8e] | 2439 |                   substring = false; | 
|---|
 | 2440 |                   break; | 
|---|
 | 2441 |                 case '?': | 
|---|
| [5627cbb] | 2442 |                   pat += wxT('.'); | 
|---|
| [d1628e8e] | 2443 |                   substring = false; | 
|---|
 | 2444 |                   break; | 
|---|
 | 2445 |                 default: | 
|---|
 | 2446 |                   pat += ch; | 
|---|
 | 2447 |                } | 
|---|
 | 2448 |             } | 
|---|
 | 2449 |             pattern = pat; | 
|---|
 | 2450 |             re_flags |= wxRE_BASIC; | 
|---|
 | 2451 |         } else { | 
|---|
 | 2452 |             wxString pat; | 
|---|
 | 2453 |             for (size_t i = 0; i < pattern.size(); i++) { | 
|---|
| [5627cbb] | 2454 |                wxChar ch = pattern[i]; | 
|---|
| [d1628e8e] | 2455 |                // ^ only special at start; $ at end.  But this is simpler... | 
|---|
 | 2456 |                switch (ch) { | 
|---|
 | 2457 |                 case '^': case '$': case '*': case '.': case '[': case '\\': | 
|---|
| [5627cbb] | 2458 |                   pat += wxT('\\'); | 
|---|
| [d1628e8e] | 2459 |                } | 
|---|
 | 2460 |                pat += ch; | 
|---|
 | 2461 |             } | 
|---|
 | 2462 |             pattern = pat; | 
|---|
 | 2463 |             re_flags |= wxRE_BASIC; | 
|---|
 | 2464 |         } | 
|---|
| [421b7d2] | 2465 |  | 
|---|
| [d1628e8e] | 2466 |         if (!substring) { | 
|---|
 | 2467 |             // FIXME "0u" required to avoid compilation error with g++-3.0 | 
|---|
| [5627cbb] | 2468 |             if (pattern.empty() || pattern[0u] != '^') pattern = wxT('^') + pattern; | 
|---|
| [d1628e8e] | 2469 |             // FIXME: this fails to cope with "\$" at the end of pattern... | 
|---|
| [5627cbb] | 2470 |             if (pattern[pattern.size() - 1] != '$') pattern += wxT('$'); | 
|---|
| [d1628e8e] | 2471 |         } | 
|---|
| [2a02de2] | 2472 |  | 
|---|
| [d1628e8e] | 2473 |         wxRegEx regex; | 
|---|
 | 2474 |         if (!regex.Compile(pattern, re_flags)) { | 
|---|
 | 2475 |             wxBell(); | 
|---|
 | 2476 |             return; | 
|---|
 | 2477 |         } | 
|---|
| [2a02de2] | 2478 |  | 
|---|
| [d1628e8e] | 2479 |         int found = 0; | 
|---|
| [1be3a88] | 2480 |  | 
|---|
| [d1628e8e] | 2481 |         list<LabelInfo*>::iterator pos = m_Labels.begin(); | 
|---|
 | 2482 |         while (pos != m_Labels.end()) { | 
|---|
 | 2483 |             LabelInfo* label = *pos++; | 
|---|
 | 2484 |  | 
|---|
| [5a24583] | 2485 |             if (regex.Matches(label->GetText())) { | 
|---|
 | 2486 |                 label->set_flags(LFLAG_HIGHLIGHTED); | 
|---|
| [d1628e8e] | 2487 |                 ++found; | 
|---|
 | 2488 |             } else { | 
|---|
| [5a24583] | 2489 |                 label->clear_flags(LFLAG_HIGHLIGHTED); | 
|---|
| [d1628e8e] | 2490 |             } | 
|---|
| [1be3a88] | 2491 |         } | 
|---|
 | 2492 |  | 
|---|
| [d1628e8e] | 2493 |         m_NumHighlighted = found; | 
|---|
 | 2494 |  | 
|---|
 | 2495 |         // Re-sort so highlighted points get names in preference | 
|---|
 | 2496 |         if (found) m_Labels.sort(LabelPlotCmp(separator)); | 
|---|
 | 2497 |     } | 
|---|
| [421b7d2] | 2498 |  | 
|---|
| [429465a] | 2499 |     m_Gfx->UpdateBlobs(); | 
|---|
| [fa42426] | 2500 |     m_Gfx->ForceRefresh(); | 
|---|
| [9d3d8cc] | 2501 |  | 
|---|
| [d1628e8e] | 2502 |     if (!m_NumHighlighted) { | 
|---|
| [857408e] | 2503 |         GetToolBar()->SetToolShortHelp(button_HIDE, wmsg(/*No matches were found.*/328)); | 
|---|
| [a2f4720] | 2504 |     } else { | 
|---|
| [857408e] | 2505 |         GetToolBar()->SetToolShortHelp(button_HIDE, wxString::Format(wmsg(/*Hide %d found stations*/334).c_str(), m_NumHighlighted)); | 
|---|
| [9d3d8cc] | 2506 |     } | 
|---|
| [2a02de2] | 2507 | } | 
|---|
 | 2508 |  | 
|---|
| [d1628e8e] | 2509 | void MainFrm::OnGotoFound(wxCommandEvent&) | 
|---|
| [2a02de2] | 2510 | { | 
|---|
| [d1628e8e] | 2511 |     if (!m_NumHighlighted) { | 
|---|
| [5627cbb] | 2512 |         wxGetApp().ReportError(wmsg(/*No matches were found.*/328)); | 
|---|
| [d1628e8e] | 2513 |         return; | 
|---|
 | 2514 |     } | 
|---|
 | 2515 |  | 
|---|
 | 2516 |     Double xmin = DBL_MAX; | 
|---|
 | 2517 |     Double xmax = -DBL_MAX; | 
|---|
 | 2518 |     Double ymin = DBL_MAX; | 
|---|
 | 2519 |     Double ymax = -DBL_MAX; | 
|---|
 | 2520 |     Double zmin = DBL_MAX; | 
|---|
 | 2521 |     Double zmax = -DBL_MAX; | 
|---|
 | 2522 |  | 
|---|
| [fa42426] | 2523 |     list<LabelInfo*>::iterator pos = m_Labels.begin(); | 
|---|
 | 2524 |     while (pos != m_Labels.end()) { | 
|---|
 | 2525 |         LabelInfo* label = *pos++; | 
|---|
| [d1628e8e] | 2526 |  | 
|---|
| [5a24583] | 2527 |         if (label->get_flags() & LFLAG_HIGHLIGHTED) { | 
|---|
 | 2528 |             if (label->GetX() < xmin) xmin = label->GetX(); | 
|---|
 | 2529 |             if (label->GetX() > xmax) xmax = label->GetX(); | 
|---|
 | 2530 |             if (label->GetY() < ymin) ymin = label->GetY(); | 
|---|
 | 2531 |             if (label->GetY() > ymax) ymax = label->GetY(); | 
|---|
 | 2532 |             if (label->GetZ() < zmin) zmin = label->GetZ(); | 
|---|
 | 2533 |             if (label->GetZ() > zmax) zmax = label->GetZ(); | 
|---|
| [d1628e8e] | 2534 |         } | 
|---|
| [fa42426] | 2535 |     } | 
|---|
| [d1628e8e] | 2536 |  | 
|---|
 | 2537 |     m_Gfx->SetViewTo(xmin, xmax, ymin, ymax, zmin, zmax); | 
|---|
 | 2538 |     m_Gfx->SetFocus(); | 
|---|
 | 2539 | } | 
|---|
 | 2540 |  | 
|---|
 | 2541 | void MainFrm::OnHide(wxCommandEvent&) | 
|---|
 | 2542 | { | 
|---|
| [5627cbb] | 2543 |     m_FindBox->SetValue(wxString()); | 
|---|
| [857408e] | 2544 |     GetToolBar()->SetToolShortHelp(button_HIDE, wmsg(/*Hide*/333)); | 
|---|
| [2a02de2] | 2545 | } | 
|---|
| [39e460c9] | 2546 |  | 
|---|
| [429465a] | 2547 | void MainFrm::OnHideUpdate(wxUpdateUIEvent& ui) | 
|---|
 | 2548 | { | 
|---|
 | 2549 |     ui.Enable(m_NumHighlighted != 0); | 
|---|
 | 2550 | } | 
|---|
 | 2551 |  | 
|---|
| [9059368] | 2552 | void MainFrm::OnViewSidePanel(wxCommandEvent&) | 
|---|
| [b1de3e0] | 2553 | { | 
|---|
 | 2554 |     ToggleSidePanel(); | 
|---|
 | 2555 | } | 
|---|
 | 2556 |  | 
|---|
 | 2557 | void MainFrm::ToggleSidePanel() | 
|---|
| [9059368] | 2558 | { | 
|---|
 | 2559 |     // Toggle display of the side panel. | 
|---|
 | 2560 |  | 
|---|
 | 2561 |     assert(m_Gfx); | 
|---|
 | 2562 |  | 
|---|
 | 2563 |     if (m_Splitter->IsSplit()) { | 
|---|
| [421b7d2] | 2564 |         m_SashPosition = m_Splitter->GetSashPosition(); // save width of panel | 
|---|
| [1690fa9] | 2565 |         m_Splitter->Unsplit(m_Notebook); | 
|---|
| [b63cf6cc] | 2566 |     } else { | 
|---|
| [203d2a7] | 2567 |         m_Notebook->Show(true); | 
|---|
| [b1de3e0] | 2568 |         m_Gfx->Show(true); | 
|---|
| [203d2a7] | 2569 |         m_Splitter->SplitVertically(m_Notebook, m_Gfx, m_SashPosition); | 
|---|
| [9059368] | 2570 |     } | 
|---|
 | 2571 | } | 
|---|
 | 2572 |  | 
|---|
 | 2573 | void MainFrm::OnViewSidePanelUpdate(wxUpdateUIEvent& ui) | 
|---|
 | 2574 | { | 
|---|
| [f48d6949] | 2575 |     ui.Enable(!m_File.empty()); | 
|---|
| [203d2a7] | 2576 |     ui.Check(ShowingSidePanel()); | 
|---|
| [9059368] | 2577 | } | 
|---|
| [203d2a7] | 2578 |  | 
|---|
 | 2579 | bool MainFrm::ShowingSidePanel() | 
|---|
 | 2580 | { | 
|---|
 | 2581 |     return m_Splitter->IsSplit(); | 
|---|
 | 2582 | } | 
|---|
| [fdfa926] | 2583 |  | 
|---|
 | 2584 | void MainFrm::ViewFullScreen() { | 
|---|
 | 2585 |     ShowFullScreen(!IsFullScreen()); | 
|---|
| [486c619] | 2586 |     if (IsFullScreen()) | 
|---|
 | 2587 |         was_showing_sidepanel_before_fullscreen = ShowingSidePanel(); | 
|---|
 | 2588 |     if (was_showing_sidepanel_before_fullscreen) | 
|---|
 | 2589 |         ToggleSidePanel(); | 
|---|
| [fdfa926] | 2590 | } | 
|---|