1 /***************************************************************************
2 tqslwiz.cpp - description
3 -------------------
4 begin : Tue Nov 5 2002
5 copyright : (C) 2002 by ARRL
6 author : Jon Bloom
7 email : jbloom@arrl.org
8 revision : $Id: tqslwiz.cpp,v 1.6 2013/03/01 13:12:57 k1mu Exp $
9 ***************************************************************************/
10
11 #include "tqslwiz.h"
12 #include <wx/tokenzr.h>
13 #ifdef HAVE_CONFIG_H
14 #include "sysconfig.h"
15 #endif
16
17 #include <string>
18 using std::string;
19
20 #include "wxutil.h"
21 #include "tqsltrace.h"
22 #include "winstrdefs.h"
23
24 extern int get_address_field(const char *callsign, const char *field, string& result);
25
26 #define TQSL_LOCATION_FIELD_UPPER 1
27 #define TQSL_LOCATION_FIELD_MUSTSEL 2
28 #define TQSL_LOCATION_FIELD_SELNXT 4
29
30 BEGIN_EVENT_TABLE(TQSLWizard, wxWizard)
31 EVT_WIZARD_PAGE_CHANGED(-1, TQSLWizard::OnPageChanged)
32 END_EVENT_TABLE()
33
34 BEGIN_EVENT_TABLE(TQSLWizCertPage, TQSLWizPage)
35 EVT_COMBOBOX(-1, TQSLWizCertPage::OnComboBoxEvent)
36 EVT_CHECKBOX(-1, TQSLWizCertPage::OnCheckBoxEvent)
37 EVT_WIZARD_PAGE_CHANGING(wxID_ANY, TQSLWizCertPage::OnPageChanging)
38 #if wxMAJOR_VERSION < 3 && (wxMAJOR_VERSION != 2 && wxMINOR_VERSION != 9)
39 EVT_SIZE(TQSLWizCertPage::OnSize)
40 #endif
41 END_EVENT_TABLE()
42
43 static char callsign[TQSL_CALLSIGN_MAX];
44
45 void
OnPageChanged(wxWizardEvent & ev)46 TQSLWizard::OnPageChanged(wxWizardEvent& ev) {
47 tqslTrace("TQSLWizard::OnPageChanged", NULL);
48 (reinterpret_cast<TQSLWizPage *>(GetCurrentPage()))->SetFocus();
49 ExtWizard::OnPageChanged(ev);
50 }
51
TQSLWizard(tQSL_Location locp,wxWindow * parent,wxHtmlHelpController * help,const wxString & title,bool expired)52 TQSLWizard::TQSLWizard(tQSL_Location locp, wxWindow *parent, wxHtmlHelpController *help,
53 const wxString& title, bool expired)
54 : ExtWizard(parent, help, title), loc(locp), _curpage(-1) {
55 tqslTrace("TQSLWizard::TQSLWizard", "locp=0x%lx, parent=0x%lx, title=%s, expired=%d", reinterpret_cast<void *>(locp), reinterpret_cast<void *>(parent), S(title), expired);
56
57 callsign[0] = '\0';
58 char buf[256];
59 if (!tqsl_getStationLocationCaptureName(locp, buf, sizeof buf)) {
60 wxString s = wxString::FromUTF8(buf);
61 SetLocationName(s);
62 }
63 tqsl_setStationLocationCertFlags(locp, expired ? TQSL_SELECT_CERT_WITHKEYS | TQSL_SELECT_CERT_EXPIRED : TQSL_SELECT_CERT_WITHKEYS);
64 tqsl_setStationLocationCapturePage(locp, 1);
65 }
66
67 TQSLWizPage *
GetPage(bool final)68 TQSLWizard::GetPage(bool final) {
69 tqslTrace("TQSLWizard::GetPage", "final=%d", final);
70 int page_num;
71 if (final)
72 page_num = 0;
73 else if (tqsl_getStationLocationCapturePage(loc, &page_num))
74 return 0;
75 tqslTrace("TQSLWizard::GetPage", "page_num = %d", page_num);
76 if (_pages[page_num]) {
77 if (page_num == 0)
78 (reinterpret_cast<TQSLWizFinalPage *>(_pages[0]))->prev = GetCurrentTQSLPage();
79 return _pages[page_num];
80 }
81 if (page_num == 0)
82 _pages[page_num] = new TQSLWizFinalPage(this, loc, GetCurrentTQSLPage());
83 else
84 _pages[page_num] = new TQSLWizCertPage(this, loc);
85 _curpage = page_num;
86 if (page_num == 0)
87 (reinterpret_cast<TQSLWizFinalPage *>(_pages[0]))->prev = GetCurrentTQSLPage();
88 return _pages[page_num];
89 }
90
OnSize(wxSizeEvent & ev)91 void TQSLWizCertPage::OnSize(wxSizeEvent& ev) {
92 #if wxMAJOR_VERSION < 3 && (wxMAJOR_VERSION != 2 && wxMINOR_VERSION != 9)
93 TQSLWizPage::OnSize(ev);
94 #endif
95 UpdateFields();
96 }
97
98 TQSLWizPage *
GetPrev() const99 TQSLWizCertPage::GetPrev() const {
100 tqslTrace("TQSLWizCertPage::GetPrev", NULL);
101 int rval;
102
103 tqsl_setStationLocationCapturePage(loc, loc_page);
104 if (tqsl_hasPrevStationLocationCapture(loc, &rval) || !rval) {
105 return 0;
106 }
107 tqsl_prevStationLocationCapture(loc);
108 return GetParent()->GetPage();
109 }
110
111 TQSLWizPage *
GetNext() const112 TQSLWizCertPage::GetNext() const {
113 tqslTrace("TQSLWizCertPage::GetNext", NULL);
114 TQSLWizPage *newp;
115 bool final = false;
116 int rval;
117
118 tqsl_setStationLocationCapturePage(loc, loc_page);
119 if (!tqsl_hasNextStationLocationCapture(loc, &rval) && rval) {
120 tqsl_nextStationLocationCapture(loc);
121 } else {
122 final = true;
123 }
124 newp = GetParent()->GetPage(final);
125 if (!final) {
126 reinterpret_cast<TQSLWizCertPage*>(newp)->UpdateFields();
127 }
128 return newp;
129 }
130
131 void
UpdateFields(int noupdate_field)132 TQSLWizCertPage::UpdateFields(int noupdate_field) {
133 tqslTrace("TQSLWizCertPage::UpdateFields", "noupdate_field=%d", noupdate_field);
134 wxSize text_size = getTextSize(this);
135
136 validate();
137 if (noupdate_field >= 0)
138 tqsl_updateStationLocationCapture(loc);
139 for (int i = noupdate_field+1; i < static_cast<int>(controls.size()); i++) {
140 int changed;
141 int in_type;
142 char gabbi_name[40];
143 tqsl_getLocationFieldChanged(loc, i, &changed);
144 tqsl_getLocationFieldInputType(loc, i, &in_type);
145 tqsl_getLocationFieldDataGABBI(loc, i, gabbi_name, sizeof gabbi_name);
146
147 ForcedMap::iterator it;
148 it = forced.find(gabbi_name);
149 if (it != forced.end()) { // Something set
150 if (it->second != callsign) { // For a different call
151 if (in_type == TQSL_LOCATION_FIELD_DDLIST || in_type == TQSL_LOCATION_FIELD_LIST) {
152 tqsl_setLocationFieldIndex(loc, i, 0);
153 (reinterpret_cast<wxComboBox *>(controls[i]))->SetSelection(0);
154 } else {
155 tqsl_setLocationFieldCharData(loc, i, "");
156 (reinterpret_cast<wxTextCtrl *>(controls[i]))->SetValue(wxT(""));
157 }
158 forced.erase(it);
159 }
160 }
161 char buf[256];
162 string s;
163 tqsl_getLocationFieldCharData(loc, i, buf, sizeof buf);
164 if (strlen(buf) == 0) { // Empty
165 if (strcmp(gabbi_name, "GRIDSQUARE") == 0) {
166 if (get_address_field(callsign, "grid", s) == 0) { // Got something
167 tqsl_setLocationFieldCharData(loc, i, s.c_str());
168 (reinterpret_cast<wxTextCtrl *>(controls[i]))->SetValue(wxString::FromUTF8(s.c_str()));
169 forced[gabbi_name] = callsign;
170 }
171 }
172 if (strcmp(gabbi_name, "US_STATE") == 0 ||
173 strcmp(gabbi_name, "JA_PREFECTURE") == 0 ||
174 strcmp(gabbi_name, "RU_OBAST") == 0 ||
175 strcmp(gabbi_name, "CA_PROVINCE") == 0 ||
176 strcmp(gabbi_name, "CN_PROVINCE") == 0 ||
177 strcmp(gabbi_name, "FI_KUNTA") == 0 ||
178 strcmp(gabbi_name, "AU_STATE") == 0) {
179 if (get_address_field(callsign, "state", s) == 0 || get_address_field(callsign, "pas", s) == 0) {
180 tqsl_setLocationFieldCharData(loc, i, s.c_str());
181 int new_sel;
182 tqsl_getLocationFieldIndex(loc, i, &new_sel);
183 (reinterpret_cast<wxComboBox *>(controls[i]))->SetSelection(new_sel);
184 forced[gabbi_name] = callsign;
185 UpdateFields(i);
186 }
187 }
188
189 if (strcmp(gabbi_name, "US_COUNTY") == 0 ||
190 strcmp(gabbi_name, "JA_CITY_GUN_KU") == 0) {
191 if (get_address_field(callsign, "county", s) == 0 || get_address_field(callsign, "sas", s) == 0) {
192 tqsl_setLocationFieldCharData(loc, i, s.c_str());
193 int new_sel;
194 tqsl_getLocationFieldIndex(loc, i, &new_sel);
195 (reinterpret_cast<wxComboBox *>(controls[i]))->SetSelection(new_sel);
196 forced[gabbi_name] = callsign;
197 UpdateFields(i);
198 }
199 }
200 }
201 if (noupdate_field >= 0 && !changed && in_type != TQSL_LOCATION_FIELD_BADZONE)
202 continue;
203 if (in_type == TQSL_LOCATION_FIELD_DDLIST || in_type == TQSL_LOCATION_FIELD_LIST) {
204 // Update this list
205 char gabbi_name[40];
206 tqsl_getLocationFieldDataGABBI(loc, i, gabbi_name, sizeof gabbi_name);
207 int selected;
208 bool defaulted = false;
209 tqsl_getLocationFieldIndex(loc, i, &selected);
210 int new_sel = 0;
211 wxString old_sel = (reinterpret_cast<wxComboBox *>(controls[i]))->GetStringSelection();
212 if (old_sel.IsEmpty() && strcmp(gabbi_name, "CALL") == 0) {
213 old_sel = (reinterpret_cast<TQSLWizard*>(GetParent()))->GetDefaultCallsign();
214 if (!old_sel.IsEmpty())
215 defaulted = true; // Set from default
216 }
217 (reinterpret_cast<wxComboBox *>(controls[i]))->Clear();
218 int nitems;
219 tqsl_getNumLocationFieldListItems(loc, i, &nitems);
220 for (int j = 0; j < nitems && j < 2000; j++) {
221 char item[200];
222 tqsl_getLocationFieldListItem(loc, i, j, item, sizeof(item));
223 // Translate the first [None] entry if it exists
224 #ifdef tqsltranslate
225 __("[None]");
226 #endif
227 wxString item_text = wxString::FromUTF8(item);
228 if (item_text == old_sel)
229 new_sel = j;
230 if (j == 0)
231 item_text = wxGetTranslation(item_text);
232 (reinterpret_cast<wxComboBox *>(controls[i]))->Append(item_text);
233 }
234 if (noupdate_field < 0 && !defaulted)
235 new_sel = selected;
236 if (nitems > new_sel)
237 (reinterpret_cast<wxComboBox *>(controls[i]))->SetSelection(new_sel);
238 tqsl_setLocationFieldIndex(loc, i, new_sel);
239 if (nitems > new_sel)
240 (reinterpret_cast<wxComboBox *>(controls[i]))->SetSelection(new_sel);
241 (reinterpret_cast<wxComboBox *>(controls[i]))->Enable(nitems > 1);
242 } else if (in_type == TQSL_LOCATION_FIELD_TEXT) {
243 int len;
244 tqsl_getLocationFieldDataLength(loc, i, &len);
245 int w, h;
246 (reinterpret_cast<wxTextCtrl *>(controls[i]))->GetSize(&w, &h);
247 (reinterpret_cast<wxTextCtrl *>(controls[i]))->SetSize((len+1)*text_size.GetWidth(), h);
248 if (noupdate_field < 0) {
249 char buf[256];
250 tqsl_getLocationFieldCharData(loc, i, buf, sizeof buf);
251 (reinterpret_cast<wxTextCtrl *>(controls[i]))->SetValue(wxString::FromUTF8(buf));
252 }
253 } else if (in_type == TQSL_LOCATION_FIELD_BADZONE) {
254 int len;
255 tqsl_getLocationFieldDataLength(loc, i, &len);
256 int w, h;
257 (reinterpret_cast<wxStaticText *>(controls[i]))->GetSize(&w, &h);
258 (reinterpret_cast<wxStaticText *>(controls[i]))->SetSize((len+1)*text_size.GetWidth(), h);
259 char buf[256];
260 tqsl_getLocationFieldCharData(loc, i, buf, sizeof buf);
261 if (strlen(buf) > 0)
262 valMsg = wxGetTranslation(wxString::FromUTF8(buf));
263 else
264 valMsg = wxT("");
265 (reinterpret_cast<wxStaticText *>(controls[i]))->SetLabel(valMsg);
266 }
267 }
268 if (noupdate_field >= 0)
269 tqsl_updateStationLocationCapture(loc);
270 }
271
272 void
OnComboBoxEvent(wxCommandEvent & event)273 TQSLWizCertPage::OnComboBoxEvent(wxCommandEvent& event) {
274 tqslTrace("TQSLWizCertPage::OnComboBoxEvent", NULL);
275 int control_idx = event.GetId() - TQSL_ID_LOW;
276 if (control_idx < 0 || control_idx >= static_cast<int>(controls.size()))
277 return;
278 int in_type;
279 tqsl_getLocationFieldInputType(loc, control_idx, &in_type);
280 switch (in_type) {
281 case TQSL_LOCATION_FIELD_DDLIST:
282 case TQSL_LOCATION_FIELD_LIST:
283 char gabbi_name[40];
284 tqsl_getLocationFieldDataGABBI(loc, control_idx, gabbi_name, sizeof gabbi_name);
285 tqsl_setLocationFieldIndex(loc, control_idx, event.GetInt());
286 if (strcmp(gabbi_name, "CALL") == 0) {
287 tqsl_getLocationFieldCharData(loc, control_idx, callsign, sizeof callsign);
288 }
289 UpdateFields(control_idx);
290 break;
291 }
292 }
293
294 void
OnCheckBoxEvent(wxCommandEvent & event)295 TQSLWizCertPage::OnCheckBoxEvent(wxCommandEvent& event) {
296 UpdateFields(-1);
297 }
298
TQSLWizCertPage(TQSLWizard * parent,tQSL_Location locp)299 TQSLWizCertPage::TQSLWizCertPage(TQSLWizard *parent, tQSL_Location locp)
300 : TQSLWizPage(parent, locp) {
301 tqslTrace("TQSLWizCertPage::TQSLWizCertPage", "parent=0x%lx, locp=0x%lx", reinterpret_cast<void *>(parent), reinterpret_cast<void *>(locp));
302 initialized = false;
303 errlbl = NULL;
304 wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
305 int control_width = getTextSize(this).GetWidth() * 40;
306
307 valMsg = wxT("");
308 invalidGrid = false;
309 allowBadGrid = false;
310 tqsl_getStationLocationCapturePage(loc, &loc_page);
311 wxScreenDC sdc;
312 int label_w = 0;
313 int numf;
314 tqsl_getNumLocationField(loc, &numf);
315 for (int i = 0; i < numf; i++) {
316 wxCoord w, h;
317 char label[256];
318 tqsl_getLocationFieldDataLabel(loc, i, label, sizeof label);
319 wxString lbl = wxGetTranslation(wxString::FromUTF8(label));
320 sdc.GetTextExtent(lbl, &w, &h);
321 if (w > label_w)
322 label_w = w;
323 }
324 wxCoord max_label_w, max_label_h;
325 // Measure width of longest expected label string
326 sdc.GetTextExtent(wxT("Longest label expected"), &max_label_w, &max_label_h);
327 bool addCheckbox = false;
328 wxString cbLabel;
329 for (int i = 0; i < numf; i++) {
330 char label[256];
331 int in_type, flags;
332 wxBoxSizer *hsizer;
333 tqsl_getLocationFieldDataLabel(loc, i, label, sizeof label);
334 wxString lbl = wxGetTranslation(wxString::FromUTF8(label));
335 tqsl_getLocationFieldInputType(loc, i, &in_type);
336 if (in_type != TQSL_LOCATION_FIELD_BADZONE) {
337 hsizer = new wxBoxSizer(wxHORIZONTAL);
338 hsizer->Add(new wxStaticText(this, -1, lbl, wxDefaultPosition,
339 wxSize(label_w, -1), wxALIGN_RIGHT/*|wxST_NO_AUTORESIZE*/), 0, wxTOP, 5);
340 }
341 wxWindow *control_p = 0;
342 char gabbi_name[256];
343 tqsl_getLocationFieldDataGABBI(loc, i, gabbi_name, sizeof gabbi_name);
344 tqsl_getLocationFieldFlags(loc, i, &flags);
345 switch(in_type) {
346 case TQSL_LOCATION_FIELD_DDLIST:
347 case TQSL_LOCATION_FIELD_LIST:
348 control_p = new wxComboBox(this, TQSL_ID_LOW+i, wxT(""), wxDefaultPosition, wxSize(control_width, -1),
349 0, 0, wxCB_DROPDOWN|wxCB_READONLY);
350 if (flags & TQSL_LOCATION_FIELD_SELNXT) {
351 addCheckbox = true;
352 cbLabel = lbl;
353 }
354 break;
355 case TQSL_LOCATION_FIELD_TEXT:
356 control_p = new wxTextCtrl(this, TQSL_ID_LOW+i, wxT(""), wxDefaultPosition, wxSize(control_width, -1));
357 break;
358 case TQSL_LOCATION_FIELD_BADZONE:
359 wxCoord w, h;
360 int tsize;
361 tqsl_getLocationFieldDataLength(loc, i, &tsize);
362 tsize /= 2;
363 sdc.GetTextExtent(wxString::FromUTF8("X"), &w, &h);
364 errlbl = new wxStaticText(this, -1, wxT(""), wxDefaultPosition,
365 wxSize(w*tsize, -1), wxALIGN_LEFT|wxST_NO_AUTORESIZE);
366 control_p = errlbl;
367 break;
368 }
369 controls.push_back(control_p);
370 if (in_type != TQSL_LOCATION_FIELD_BADZONE) {
371 hsizer->Add(control_p, 0, wxLEFT|wxTOP, 5);
372 sizer->Add(hsizer, 0, wxLEFT|wxRIGHT, 10);
373 } else {
374 sizer->Add(control_p, 0, wxEXPAND | wxLEFT| wxRIGHT, 10);
375 }
376 }
377
378 if (addCheckbox) {
379 wxBoxSizer *hsizer = new wxBoxSizer(wxHORIZONTAL);
380 okEmptyCB = new wxCheckBox(this, TQSL_ID_LOW+numf, _("Allow 'None' for ") + cbLabel, wxDefaultPosition, wxDefaultSize);
381
382 hsizer->Add(new wxStaticText(this, -1, wxT(""),
383 wxDefaultPosition, wxSize(label_w, -1), wxALIGN_RIGHT|wxST_NO_AUTORESIZE), 0, wxTOP, 5);
384 hsizer->Add(okEmptyCB, 0, wxLEFT|wxTOP, 5);
385 sizer->Add(hsizer, 0, wxLEFT|wxRight, 10);
386 } else {
387 okEmptyCB = 0;
388 }
389 initialized = true;
390 UpdateFields();
391 AdjustPage(sizer, wxT("stnloc1.htm"));
392 }
393
~TQSLWizCertPage()394 TQSLWizCertPage::~TQSLWizCertPage() {
395 }
396
397 const char *
validate()398 TQSLWizCertPage::validate() {
399 tqslTrace("TQSLWizCertPage::validate", NULL);
400
401 if (!initialized) return 0;
402 valMsg = wxT("");
403 tqsl_setStationLocationCapturePage(loc, loc_page);
404 for (int i = 0; i < static_cast<int>(controls.size()); i++) {
405 char gabbi_name[40];
406 int in_type;
407 int flags;
408 tqsl_getLocationFieldDataGABBI(loc, i, gabbi_name, sizeof gabbi_name);
409 tqsl_getLocationFieldInputType(loc, i, &in_type);
410 tqsl_getLocationFieldFlags(loc, i, &flags);
411 if (flags == TQSL_LOCATION_FIELD_SELNXT) {
412 int index;
413 tqsl_getLocationFieldIndex(loc, i, &index);
414 if (index <= 0 && (okEmptyCB && !okEmptyCB->IsChecked())) {
415 char label[256];
416 tqsl_getLocationFieldDataLabel(loc, i, label, sizeof label);
417 valMsg = wxString::Format(_("You must select a %hs"), label);
418 }
419 if (okEmptyCB) {
420 if (index <= 0)
421 okEmptyCB->Enable(true);
422 else
423 okEmptyCB->Enable(false);
424 }
425 } else if (strcmp(gabbi_name, "GRIDSQUARE") == 0) {
426 tqsl_getLocationFieldCharData(loc, 0, callsign, sizeof callsign);
427 wxString gridVal = (reinterpret_cast<wxTextCtrl *>(controls[i]))->GetValue();
428 if (gridVal.size() == 0) {
429 continue;
430 }
431 string gridlist;
432 get_address_field(callsign, "grids", gridlist);
433 wxString editedGrids = wxT("");
434 wxStringTokenizer grids(gridVal, wxT(",")); // Comma-separated list of squares
435 while (grids.HasMoreTokens()) {
436 wxString grid = grids.GetNextToken().Trim().Trim(false);
437 // Truncate to six character field
438 grid = grid.Left(6);
439 if (grid[0] <= 'z' && grid[0] >= 'a')
440 grid[0] = grid[0] - 'a' + 'A'; // Upper case first two
441 if (grid.size() > 1 && (grid[1] <= 'z' && grid[1] >= 'a'))
442 grid[1] = grid[1] - 'a' + 'A';
443 if (grid[0] < 'A' || grid[0] > 'R') {
444 if (valMsg.IsEmpty())
445 valMsg = wxString::Format(_("%s: Invalid Grid Square Field"), grid.c_str());
446 }
447 if (grid.size() > 1 && (grid[1] < 'A' || grid[1] > 'R')) {
448 if (valMsg.IsEmpty())
449 valMsg = wxString::Format(_("%s: Invalid Grid Square Field"), grid.c_str());
450 }
451 if (grid.size() > 2 && (grid[2] < '0' || grid[2] > '9')) {
452 if (valMsg.IsEmpty())
453 valMsg = wxString::Format(_("%s: Invalid Grid Square"), grid.c_str());
454 }
455 if (grid.size() < 4) {
456 if (valMsg.IsEmpty())
457 valMsg = wxString::Format(_("%s: Invalid Grid Square"), grid.c_str());
458 }
459 if (grid[3] < '0' || grid[3] > '9') {
460 if (valMsg.IsEmpty())
461 valMsg = wxString::Format(_("%s: Invalid Grid Square"), grid.c_str());
462 }
463
464 if (grid.size() > 4 && (grid[4] <= 'Z' && grid[4] >= 'A'))
465 grid[4] = grid[4] - 'A' + 'a'; // Lower case subsquare
466 if (grid.size() > 5 && (grid[5] <= 'Z' && grid[5] >= 'A'))
467 grid[5] = grid[5] - 'A' + 'a';
468
469 if (grid.size() > 4 && (grid[4] < 'a' || grid[4] > 'x')) {
470 if (valMsg.IsEmpty())
471 valMsg = wxString::Format(_("%s: Invalid Subsquare"), grid.c_str());
472 }
473 if (grid.size() > 5 && (grid[5] < 'a' || grid[5] > 'x')) {
474 if (valMsg.IsEmpty())
475 valMsg = wxString::Format(_("%s: Invalid Subsquare"), grid.c_str());
476 }
477 if (grid.size() != 6 && grid.size() != 4) {
478 // Not long enough yet or too long.
479 if (valMsg.IsEmpty())
480 valMsg = wxString::Format(_("%s: Invalid Grid Square"), grid.c_str());
481 }
482 if (valMsg.IsEmpty() && !gridlist.empty()) {
483 string probe = string(grid.Left(4).mb_str());
484 if (gridlist.find(probe) == string::npos) {
485 valMsg = wxString::Format(_("Grid %s is not correct for your QTH. Click 'Next' again to use it anyway."), grid.c_str());
486 invalidGrid = true;
487 } else {
488 invalidGrid = false;
489 }
490 }
491 if (!editedGrids.IsEmpty())
492 editedGrids += wxT(",");
493 editedGrids += grid;
494 (reinterpret_cast<wxTextCtrl *>(controls[i]))->SetValue(editedGrids);
495 tqsl_setLocationFieldCharData(loc, i, (reinterpret_cast<wxTextCtrl *>(controls[i]))->GetValue().ToUTF8());
496 }
497 } else if (in_type == TQSL_LOCATION_FIELD_BADZONE) {
498 // Possible errors, here for harvesting
499 #ifdef tqsltranslate
500 static const char* verrs[] = {
501 __("Invalid zone selections for state"),
502 __("Invalid zone selections for province"),
503 __("Invalid zone selections for oblast"),
504 __("Invalid zone selections for DXCC entity");
505 };
506 #endif
507 char buf[256];
508 tqsl_getLocationFieldCharData(loc, i, buf, sizeof buf);
509 if (strlen(buf) > 0)
510 valMsg = wxGetTranslation(wxString::FromUTF8(buf));
511 (reinterpret_cast<wxStaticText *>(controls[i]))->SetLabel(valMsg);
512 }
513 }
514 if (errlbl) errlbl->SetLabel(valMsg);
515 return 0;
516 }
517
518 bool
TransferDataFromWindow()519 TQSLWizCertPage::TransferDataFromWindow() {
520 tqslTrace("TQSLWizCertPage::TransferDataFromWindow", NULL);
521
522 tqsl_setStationLocationCapturePage(loc, loc_page);
523 for (int i = 0; i < static_cast<int>(controls.size()); i++) {
524 int in_type;
525 tqsl_getLocationFieldInputType(loc, i, &in_type);
526 switch(in_type) {
527 case TQSL_LOCATION_FIELD_DDLIST:
528 case TQSL_LOCATION_FIELD_LIST:
529 break;
530 case TQSL_LOCATION_FIELD_TEXT:
531 tqsl_setLocationFieldCharData(loc, i, (reinterpret_cast<wxTextCtrl *>(controls[i]))->GetValue().ToUTF8());
532 break;
533 }
534 }
535 if (errlbl) errlbl->SetLabel(valMsg);
536 return true;
537 }
538 void
OnPageChanging(wxWizardEvent & ev)539 TQSLWizCertPage::OnPageChanging(wxWizardEvent& ev) {
540 tqslTrace("TQSLWizCertPage::OnPageChanging", "Direction=", ev.GetDirection());
541
542 validate();
543 if (valMsg.Len() > 0 && ev.GetDirection()) {
544 if (!allowBadGrid) {
545 ev.Veto();
546 allowBadGrid = true; // Don't allow going forward once
547 } else {
548 allowBadGrid = false;
549 }
550 if (!invalidGrid) {
551 wxMessageBox(valMsg, _("Error"), wxOK | wxICON_ERROR, this);
552 }
553 }
554 }
555
BEGIN_EVENT_TABLE(TQSLWizFinalPage,TQSLWizPage)556 BEGIN_EVENT_TABLE(TQSLWizFinalPage, TQSLWizPage)
557 EVT_LISTBOX(TQSL_ID_LOW, TQSLWizFinalPage::OnListbox)
558 EVT_LISTBOX_DCLICK(TQSL_ID_LOW, TQSLWizFinalPage::OnListbox)
559 EVT_TEXT(TQSL_ID_LOW+1, TQSLWizFinalPage::check_valid)
560 EVT_WIZARD_PAGE_CHANGING(wxID_ANY, TQSLWizFinalPage::OnPageChanging)
561 END_EVENT_TABLE()
562
563 void
564 TQSLWizFinalPage::OnListbox(wxCommandEvent &) {
565 tqslTrace("TQSLWizFinalPage::OnListbox", NULL);
566 if (namelist->GetSelection() >= 0) {
567 const char *cp = (const char *)(namelist->GetClientData(namelist->GetSelection()));
568 if (cp)
569 newname->SetValue(wxString::FromUTF8(cp).Trim(true).Trim(false));
570 }
571 }
572
TQSLWizFinalPage(TQSLWizard * parent,tQSL_Location locp,TQSLWizPage * i_prev)573 TQSLWizFinalPage::TQSLWizFinalPage(TQSLWizard *parent, tQSL_Location locp, TQSLWizPage *i_prev)
574 : TQSLWizPage(parent, locp), prev(i_prev) {
575 tqslTrace("TQSLWizFinalPage::TQSLWizFinalPage", "parent=0x%lx, locp=0x%lx, i_prev=0x%lx", reinterpret_cast<void *>(parent), reinterpret_cast<void *>(locp), reinterpret_cast<void *>(i_prev));
576 initialized = false;
577 errlbl = NULL;
578 valMsg = wxT("");
579 wxSize text_size = getTextSize(this);
580 int control_width = text_size.GetWidth()*40;
581
582 int y = text_size.GetHeight();
583 sizer = new wxBoxSizer(wxVERTICAL);
584
585 wxStaticText *st = new wxStaticText(this, -1, _("Station Data input complete"));
586 sizer->Add(st, 0, wxALIGN_CENTER|wxTOP, 10);
587
588 // Title
589 st = new wxStaticText(this, -1, _("Select or enter name of this station location"));
590 sizer->Add(st, 0, wxALIGN_CENTER|wxBOTTOM, 10);
591
592 // List of existing location names
593 namelist = new wxListBox(this, TQSL_ID_LOW, wxDefaultPosition, wxSize(control_width, text_size.GetHeight()*10),
594 0, 0, wxLB_SINGLE|wxLB_HSCROLL|wxLB_NEEDED_SB);
595 sizer->Add(namelist, 0, wxEXPAND);
596 int n;
597 tqsl_getNumStationLocations(locp, &n);
598 for (int i = 0; i < n; i++) {
599 char buf[256];
600 tqsl_getStationLocationName(loc, i, buf, sizeof buf);
601 item_data.push_back(strdup(buf));
602 char cbuf[256];
603 tqsl_getStationLocationCallSign(loc, i, cbuf, sizeof cbuf);
604 wxString s = wxString::FromUTF8(buf);
605 s += (wxString(wxT(" (")) + wxString::FromUTF8(cbuf) + wxString(wxT(")")));
606 const void *v = item_data.back();
607 namelist->Append(s, const_cast<void *>(v));
608 }
609 if (namelist->GetCount() > 0)
610 namelist->SetSelection(0, FALSE);
611 // New name
612 st = new wxStaticText(this, -1, _("Station Location Name"));
613 sizer->Add(st, 0, wxALIGN_LEFT|wxTOP, 10);
614 newname = new wxTextCtrl(this, TQSL_ID_LOW+1, wxT(""), wxPoint(0, y), wxSize(control_width, -1));
615 sizer->Add(newname, 0, wxEXPAND);
616 newname->SetValue(parent->GetLocationName());
617 errlbl = new wxStaticText(this, -1, wxT(""), wxDefaultPosition, wxSize(control_width, -1),
618 wxALIGN_LEFT/*|wxST_NO_AUTORESIZE*/);
619 sizer->Add(errlbl, 0, wxTOP);
620 initialized = true;
621 AdjustPage(sizer, wxT("stnloc2.htm"));
622 }
623
624 bool
TransferDataFromWindow()625 TQSLWizFinalPage::TransferDataFromWindow() {
626 tqslTrace("TQSLWizFinalPage::TransferDataFromWindow", NULL);
627 validate();
628 if (valMsg.Len() > 0) // Must be a "back"
629 return true;
630 wxString s = newname->GetValue().Trim(true).Trim(false);
631 (reinterpret_cast<TQSLWizard *>(GetParent()))->SetLocationName(s);
632 return true;
633 }
634
635 void
OnPageChanging(wxWizardEvent & ev)636 TQSLWizFinalPage::OnPageChanging(wxWizardEvent& ev) {
637 tqslTrace("TQSLWizFinalPage::OnPageChanging", "Direction=", ev.GetDirection());
638
639 validate();
640 if (valMsg.Len() > 0 && ev.GetDirection()) {
641 ev.Veto();
642 wxMessageBox(valMsg, _("Error"), wxOK | wxICON_ERROR, this);
643 }
644 }
645
646 const char *
validate()647 TQSLWizFinalPage::validate() {
648 tqslTrace("TQSLWizFinalPage::validate", NULL);
649 if (!initialized) return 0;
650 wxString val = newname->GetValue().Trim(true).Trim(false);
651 valMsg = wxT("");
652
653 if (val == wxT("")) {
654 valMsg = wxGetTranslation(_("Station name must be provided"));
655 }
656 if (errlbl) errlbl->SetLabel(valMsg);
657 return 0;
658 }
659
~TQSLWizFinalPage()660 TQSLWizFinalPage::~TQSLWizFinalPage() {
661 for (int i = 0; i < static_cast<int>(item_data.size()); i++) {
662 free(item_data[i]);
663 }
664 }
665