1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2014
3 // David Freese, W1HKJ
4 //
5 // This file is part of flmsg
6 //
7 // flrig is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // flrig is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 // ----------------------------------------------------------------------------
20
21 #include <stdlib.h>
22 #include <iostream>
23 #include <fstream>
24 #include <cstring>
25 #include <ctime>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <stdio.h>
29 #include <errno.h>
30
31 #include <FL/Fl.H>
32 #include <FL/Enumerations.H>
33 #include <FL/Fl_Window.H>
34 #include <FL/Fl_Button.H>
35 #include <FL/Fl_Group.H>
36 #include <FL/Fl_Sys_Menu_Bar.H>
37 #include <FL/x.H>
38 #include <FL/Fl_Help_Dialog.H>
39 #include <FL/Fl_Menu_Item.H>
40 #include <FL/Fl_File_Icon.H>
41
42 #include "config.h"
43 #include "flmsg_config.h"
44
45 #include "flmsg.h"
46 #include "templates.h"
47 #include "debug.h"
48 #include "util.h"
49 #include "gettext.h"
50 #include "flmsg_dialog.h"
51 #include "flinput2.h"
52 #include "combo.h"
53 #include "date.h"
54 #include "calendar.h"
55 #include "icons.h"
56 #include "fileselect.h"
57 #include "wrap.h"
58 #include "status.h"
59 #include "parse_xml.h"
60
61 #ifdef WIN32
62 # include "flmsgrc.h"
63 # include "compat.h"
64 # define dirent fl_dirent_no_thanks
65 #endif
66
67 #include <FL/filename.H>
68 #include "dirent-check.h"
69
70 #include <FL/x.H>
71 #include <FL/Fl_Pixmap.H>
72 #include <FL/Fl_Image.H>
73
74 using namespace std;
75
76 string wxhc_rptsta;
77 string wxhc_email;
78 string wxhc_phone;
79 string wxhc_addr;
80 string wxhc_city;
81 string wxhc_state;
82 string wxhc_country;
83 string wxhc_lat;
84 string wxhc_long;
85 string wxhc_date;
86 string wxhc_time;
87
88 bool wxhc_meas;
89 bool wxhc_est;
90 string wxhc_wind_speed;
91 string wxhc_wind_speed_units;
92 string wxhc_wind_gusts;
93 string wxhc_wind_gusts_units;
94 string wxhc_wind_dir;
95 string wxhc_wind_degrees;
96 string wxhc_baro_press;
97 string wxhc_baro_units;
98
99 string wxhc_comments;
100
101 const char *s_wsu_units[] = { "MPH", "KNOTS", "KPH", NULL };
102 const char *s_wdu_units[] = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", NULL };
103 const char *s_baro_units[] = { "Inches", "Millibars", NULL };
104
105 // could not use real names ... WIN32 barfs
106 enum NHC_QTYPE { B, S, M, T, I, F, C, O, E };
107 // bool, string, multi-line string, text, int, float, character, cOmbo, empty
108
109 struct NHC_QUAD {
110 NHC_QTYPE qtype; // type of field
111 string html_fld;
112 void *ptr;
113 Fl_Widget *widget; };
114
115 NHC_QUAD wxhc_QUAD[] = {
116 { S, ":rptsta:", &wxhc_rptsta, w_wxhc_rptsta }, // 0
117 { S, ":email:", &wxhc_email, w_wxhc_email }, // 1
118 { S, ":phone:", &wxhc_phone, w_wxhc_phone }, // 2
119 { S, ":addr:", &wxhc_addr, w_wxhc_addr }, // 3
120 { S, ":city:", &wxhc_city, w_wxhc_city }, // 4
121 { S, ":state:", &wxhc_state, w_wxhc_state }, // 5
122 { S, ":country:", &wxhc_country, w_wxhc_country }, // 6
123 { S, ":lat:", &wxhc_lat, w_wxhc_lat }, // 7
124 { S, ":long:", &wxhc_long, w_wxhc_long }, // 8
125 { S, ":date:", &wxhc_date, w_wxhc_date }, // 9
126 { S, ":time:", &wxhc_time, w_wxhc_time }, // 10
127
128 { B, ":meas:", &wxhc_meas, w_wxhc_meas }, // 11
129 { B, ":est:", &wxhc_est, w_wxhc_est }, // 12
130 { S, ":wspd:", &wxhc_wind_speed, w_wxhc_wind_speed }, // 13
131 { O, ":wsunits:", &wxhc_wind_speed_units, w_wxhc_wind_speed_units}, // 14
132 { S, ":wgst:", &wxhc_wind_gusts, w_wxhc_wind_gusts }, // 15
133 { O, ":wgunits:", &wxhc_wind_gusts_units, w_wxhc_wind_gusts_units }, // 16
134 { O, ":wdir:", &wxhc_wind_dir, w_wxhc_wind_dir }, // 17
135 { S, ":wdeg:", &wxhc_wind_degrees, w_wxhc_wind_degrees }, // 18
136 { S, ":baro:", &wxhc_baro_press, w_wxhc_baro_press }, // 19
137 { O, ":bunits:", &wxhc_baro_units, w_wxhc_baro_units }, // 20
138
139 { T, ":cmmts:", &wxhc_comments, w_wxhc_comments }, // 21
140
141 { E, "", NULL, NULL }
142 };
143
144 string buffwxhc;
145 string def_wxhc_filename = "";
146 string base_wxhc_filename = "";
147 string def_wxhc_TemplateName = "";
148
149 bool using_wxhc_template = false;
150 static bool fields_initialized = false;
151
152 // required to initialize the control pointers in the QUAD array
153
init_widgets()154 static void init_widgets()
155 {
156 wxhc_QUAD[0].widget = w_wxhc_rptsta;
157 wxhc_QUAD[1].widget = w_wxhc_email;
158 wxhc_QUAD[2].widget = w_wxhc_phone;
159 wxhc_QUAD[3].widget = w_wxhc_addr;
160 wxhc_QUAD[4].widget = w_wxhc_city;
161 wxhc_QUAD[5].widget = w_wxhc_state;
162 wxhc_QUAD[6].widget = w_wxhc_country;
163 wxhc_QUAD[7].widget = w_wxhc_lat;
164 wxhc_QUAD[8].widget = w_wxhc_long;
165 wxhc_QUAD[9].widget = w_wxhc_date;
166 wxhc_QUAD[10].widget = w_wxhc_time;
167 wxhc_QUAD[11].widget = w_wxhc_meas;
168 wxhc_QUAD[12].widget = w_wxhc_est;
169 wxhc_QUAD[13].widget = w_wxhc_wind_speed;
170 wxhc_QUAD[14].widget = w_wxhc_wind_speed_units;
171 wxhc_QUAD[15].widget = w_wxhc_wind_gusts;
172 wxhc_QUAD[16].widget = w_wxhc_wind_gusts_units;
173 wxhc_QUAD[17].widget = w_wxhc_wind_dir;
174 wxhc_QUAD[18].widget = w_wxhc_wind_degrees;
175 wxhc_QUAD[19].widget = w_wxhc_baro_press;
176 wxhc_QUAD[20].widget = w_wxhc_baro_units;
177 wxhc_QUAD[21].widget = w_wxhc_comments;
178
179 fields_initialized = true;
180 }
181
182 //enum NHC_QTYPE { B, S, T, I, F, C, E };
183 // bool, string, text, int, float, character, empty
184
clearQUAD(NHC_QUAD * p)185 static void clearQUAD(NHC_QUAD *p)
186 {
187 NHC_QTYPE qt = E;
188 while ((qt = p->qtype) != E) {
189 switch (qt) {
190 case B : (*(bool *)(p->ptr)) = false; break;
191 case S :
192 case M : ((string *)(p->ptr))->clear(); break;
193 case T : ((string *)(p->ptr))->clear(); break;
194 case C : (*(char *)(p->ptr)) = ' '; break;
195 case I : (*(int *)(p->ptr)) = 0; break;
196 case F : (*(float *)(p->ptr)) = 0.0; break;
197 case O : break;
198 case E : return;
199 }
200 p++;
201 }
202 wxhc_est = true;
203 wxhc_wind_speed_units = s_wsu_units[0];
204 wxhc_wind_gusts_units = s_wsu_units[0];
205 wxhc_wind_dir = s_wdu_units[0];
206 wxhc_baro_units = s_baro_units[0];
207 }
208
clear_wxhcfields()209 void clear_wxhcfields()
210 {
211 if (!fields_initialized) init_widgets();
212 clearQUAD(wxhc_QUAD);
213 }
214
checkQUAD(NHC_QUAD * p)215 static bool checkQUAD(NHC_QUAD *p)
216 {
217 int i = 0;
218 float f = 0;
219 char c = ' ';
220 NHC_QTYPE qt = E;
221 while ((qt = p->qtype) != E) {
222 if (p->widget == NULL) return false;
223 switch (qt) {
224 case B:
225 if (*((bool *)(p->ptr)) != ((Fl_Check_Button *)p->widget)->value())
226 return true;
227 break;
228 case S:
229 case M:
230 if (*((string *)(p->ptr)) != ((Fl_Input2 *)p->widget)->value())
231 return true;
232 break;
233 case T:
234 if (*((string *)(p->ptr)) != ((FTextEdit *)p->widget)->buffer()->text())
235 return true;
236 break;
237 case C:
238 c = ' ';
239 if (((Fl_Input2 *)p->widget)->value()[0])
240 c = ((Fl_Input2 *)p->widget)->value()[0];
241 if (*((char *)(p->ptr)) != c)
242 return true;
243 break;
244 case I:
245 i = 0;
246 if (((Fl_Input2 *)p->widget)->value()[0])
247 sscanf( ((Fl_Input2 *)p->widget)->value(), "%d", &i);
248 if (*((int *)(p->ptr)) != i)
249 return true;
250 break;
251 case F:
252 f = 0;
253 if (((Fl_Input2 *)p->widget)->value()[0])
254 sscanf( ((Fl_Input2 *)p->widget)->value(), "%f", &f);
255 if (*((float *)(p->ptr)) != f)
256 return true;
257 break;
258 case O:
259 if (*((string *)(p->ptr)) != ((Fl_ListBox *)p->widget)->value())
260 return true;
261 break;
262 case E:
263 default: return false;
264 }
265 p++;
266 }
267 return false;
268 }
269
check_wxhcfields()270 bool check_wxhcfields()
271 {
272 return checkQUAD(wxhc_QUAD);
273 }
274
updateQUAD(NHC_QUAD * p)275 static void updateQUAD(NHC_QUAD *p)
276 {
277 int i = 0;
278 float f = 0;
279 char c = ' ';
280 NHC_QTYPE qt = E;
281 while ((qt = p->qtype) != E) {
282 switch (qt) {
283 case B:
284 *((bool *)(p->ptr)) = ((Fl_Check_Button *)p->widget)->value();
285 break;
286 case S:
287 case M:
288 *((string *)(p->ptr)) = ((Fl_Input2 *)p->widget)->value();
289 break;
290 case O:
291 *((string *)(p->ptr)) = ((Fl_ListBox *)p->widget)->value();
292 break;
293 case T:
294 *((string *)(p->ptr)) = ((FTextEdit *)p->widget)->buffer()->text();
295 break;
296 case C:
297 c = ' ';
298 if (((Fl_Input2 *)p->widget)->value()[0])
299 c = ((Fl_Input2 *)p->widget)->value()[0];
300 *((char *)(p->ptr)) = c;
301 break;
302 case I:
303 i = 0;
304 if (((Fl_Input2 *)p->widget)->value()[0])
305 sscanf( ((Fl_Input2 *)p->widget)->value(), "%d", &i);
306 *((int *)(p->ptr)) = i;
307 break;
308 case F:
309 f = 0;
310 if (((Fl_Input2 *)p->widget)->value()[0])
311 sscanf( ((Fl_Input2 *)p->widget)->value(), "%f", &f);
312 *((float *)(p->ptr)) = f;
313 break;
314 case E:
315 default: return;
316 }
317 p++;
318 }
319 }
320
update_wxhcfields()321 void update_wxhcfields()
322 {
323 if (!fields_initialized) init_widgets();
324 updateQUAD(wxhc_QUAD);
325 }
326
set_nhc_wx_combos()327 void set_nhc_wx_combos() {
328 const char **s = s_wsu_units;
329 int i = 0;
330 w_wxhc_wind_speed_units->clear();
331 while (s[i]) { w_wxhc_wind_speed_units->add(s[i]);
332 i++;}
333
334 s = s_wsu_units;
335 i = 0;
336 w_wxhc_wind_gusts_units->clear();
337 while (s[i]) { w_wxhc_wind_gusts_units->add(s[i]); i++; }
338
339 s = s_wdu_units;
340 i = 0;
341 w_wxhc_wind_dir->clear();
342 while (s[i]) { w_wxhc_wind_dir->add(s[i]); i++; }
343
344 s = s_baro_units;
345 i = 0;
346 w_wxhc_baro_units->clear();
347 while (s[i]) { w_wxhc_baro_units->add(s[i]); i++; }
348
349 }
350
updateFORM(NHC_QUAD * p)351 static void updateFORM(NHC_QUAD *p)
352 {
353 char val[20];
354 NHC_QTYPE qt = E;
355 while ((qt = p->qtype) != E) {
356 switch (qt) {
357 case B:
358 ((Fl_Check_Button *)p->widget)->value(*((bool *)(p->ptr)));
359 break;
360 case S:
361 case M:
362 ((Fl_Input2 *)p->widget)->value(((string *)(p->ptr))->c_str());
363 break;
364 case O:
365 ((Fl_ListBox *)p->widget)->put_value(((string *)(p->ptr))->c_str());
366 break;
367 case T:
368 ((FTextEdit *)p->widget)->clear();
369 ((FTextEdit *)p->widget)->add(((string *)(p->ptr))->c_str());
370 break;
371 case C:
372 val[0] = *((char *)(p->ptr));
373 val[1] = 0;
374 ((Fl_Input2 *)p->widget)->value(val);
375 break;
376 case I:
377 if (*((int *)(p->ptr)) == 0)
378 ((Fl_Input2 *)p->widget)->value("");
379 else {
380 snprintf(val, sizeof(val), "%d", *((int *)(p->ptr)));
381 ((Fl_Input2 *)p->widget)->value(val);
382 }
383 break;
384 case F:
385 snprintf(val, sizeof(val), "%f", *((float *)(p->ptr)));
386 ((Fl_Input2 *)p->widget)->value(val);
387 break;
388 case E:
389 default: return;
390 }
391 p++;
392 }
393 }
394
update_wxhcform()395 void update_wxhcform()
396 {
397 if (!fields_initialized) init_widgets();
398 updateFORM(wxhc_QUAD);
399 }
400
clear_wxhc_form()401 void clear_wxhc_form()
402 {
403 clear_wxhcfields();
404 update_wxhcform();
405 }
406
407 static string mbuff;
408
make_buffQUAD(NHC_QUAD * p)409 static void make_buffQUAD(NHC_QUAD *p)
410 {
411 string one = "1"; string zero = "0";
412 string sval = " ";
413 char szval[20];
414 NHC_QTYPE qt = E;
415 while ((qt = p->qtype) != E) {
416 switch (qt) {
417 case B:
418 if (*((bool *)(p->ptr)) == true)
419 mbuff.append( lineout( p->html_fld, *((bool *)(p->ptr)) ? one : zero));
420 break;
421 case O:
422 case S:
423 case M:
424 if (((string *)(p->ptr))->length())
425 mbuff.append( lineout( p->html_fld, *((string *)(p->ptr))));
426 break;
427 case T:
428 mbuff.append( lineout( p->html_fld, *((string *)(p->ptr))));
429 break;
430 case C:
431 if ((*(char *)(p->ptr)) != 0 && *((char *)(p->ptr)) != ' ') {
432 sval = " ";
433 sval[0] = *((char *)(p->ptr));
434 mbuff.append( lineout( p->html_fld, sval));
435 }
436 break;
437 case I:
438 if (*((int*)(p->ptr)) > 0) {
439 snprintf(szval, sizeof(szval), "%d", *((int *)(p->ptr)) );
440 sval = szval;
441 mbuff.append( lineout( p->html_fld, sval) );
442 }
443 break;
444 case F:
445 if (*((float *)(p->ptr)) > 0) {
446 snprintf(szval, sizeof(szval), "%f", *((float *)(p->ptr)));
447 sval = szval;
448 mbuff.append( lineout( p->html_fld, sval) );
449 }
450 break;
451 case E:
452 default: return;
453 }
454 p++;
455 }
456 }
457
make_buffwxhc(bool compress=false)458 void make_buffwxhc(bool compress = false)
459 {
460 mbuff.clear();
461 make_buffQUAD(wxhc_QUAD);
462 if (compress) compress_maybe(mbuff);
463 buffwxhc.append(mbuff);
464 }
465
readQUAD(string data,NHC_QUAD * p)466 static void readQUAD(string data, NHC_QUAD *p)
467 {
468 int i = 0;
469 float f;
470 NHC_QTYPE qt = p->qtype;
471 while (qt != E) {
472 switch (qt) {
473 case B:
474 *((bool *)(p->ptr)) = (findstr( data, p->html_fld ) == "1");
475 break;
476 case O:
477 case S:
478 case M:
479 *((string *)(p->ptr)) = findstr( data, p->html_fld );
480 break;
481 case T:
482 *((string *)(p->ptr)) = findstr( data, p->html_fld );
483 break;
484 case C:
485 *((char *)(p->ptr)) = findstr( data, p->html_fld )[0];
486 break;
487 case I:
488 i = 0;
489 sscanf( findstr( data, p->html_fld ).c_str(), "%d", &i);
490 *((int *)(p->ptr)) = i;
491 break;
492 case F:
493 f = 0;
494 sscanf( findstr( data, p->html_fld ).c_str(), "%f", &f);
495 *((float *)(p->ptr)) = f;
496 break;
497 case E:
498 default: return;
499 }
500 p++;
501 qt = p->qtype;
502 }
503 }
504
read_wxhc_buffer(string data)505 void read_wxhc_buffer(string data)
506 {
507 clear_wxhcfields();
508 read_header(data);
509
510 readQUAD (data, wxhc_QUAD);
511 update_wxhcform();
512 }
513
cb_wxhc_new()514 void cb_wxhc_new()
515 {
516 if (check_wxhcfields()) {
517 if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 1) {
518 update_header(CHANGED);
519 cb_wxhc_save();
520 }
521 }
522 clear_wxhc_form();
523 clear_header();
524 def_wxhc_filename = ICS_msg_dir;
525 def_wxhc_filename.append("new").append(FWXHC_EXT);
526 show_filename(def_wxhc_filename);
527 using_wxhc_template = false;
528 }
529
cb_wxhc_import()530 void cb_wxhc_import()
531 {
532 fl_alert2("Not implemented");
533 }
534
cb_wxhc_export()535 void cb_wxhc_export()
536 {
537 fl_alert2("Not implemented");
538 }
539
cb_wxhc_wrap_import(string wrapfilename,string inpbuffer)540 void cb_wxhc_wrap_import(string wrapfilename, string inpbuffer)
541 {
542 clear_wxhc_form();
543 read_wxhc_buffer(inpbuffer);
544 def_wxhc_filename = ICS_msg_dir;
545 def_wxhc_filename.append(wrapfilename);
546 show_filename(def_wxhc_filename);
547 using_wxhc_template = false;
548 }
549
eval_wxhc_fsize()550 int eval_wxhc_fsize()
551 {
552 Ccrc16 chksum;
553 evalstr.assign("[WRAP:beg][WRAP:lf][WRAP:fn ");
554 evalstr.append(base_wxhc_filename).append("]");
555 update_wxhcfields();
556 update_header(FROM);
557 evalstr.append(header("<nhc_wx>"));
558 buffwxhc.clear();
559 make_buffwxhc(true);
560 if (buffwxhc.empty()) return 0;
561 compress_maybe( buffwxhc );
562 evalstr.append( buffwxhc );
563 evalstr.append("[WRAP:chksum ").append(chksum.scrc16(evalstr)).append("][WRAP:end]");
564 return evalstr.length();
565 }
566
cb_wxhc_wrap_export()567 void cb_wxhc_wrap_export()
568 {
569 if (check_wxhcfields()) {
570 if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 0)
571 return;
572 update_header(CHANGED);
573 }
574 update_wxhcfields();
575
576 if (base_wxhc_filename == string("new").append(FWXHC_EXT) ||
577 base_wxhc_filename == string("default").append(FWXHC_EXT) )
578 if (!cb_wxhc_save_as()) return;
579
580 string wrapfilename = WRAP_send_dir;
581 wrapfilename.append(base_wxhc_filename);
582 wrapfilename.append(".wrap");
583 const char *p = FSEL::saveas(
584 "Save as wrap file",
585 "Wrap file\t*.{wrap,WRAP}",
586 wrapfilename.c_str());
587 if (p) {
588 string pext = fl_filename_ext(p);
589 wrapfilename = p;
590
591 update_header(FROM);
592 buffwxhc.assign(header("<nhc_wx>"));
593 make_buffwxhc(true);
594 export_wrapfile(base_wxhc_filename, wrapfilename, buffwxhc, pext != ".wrap");
595
596 buffwxhc.assign(header("<nhc_wx>"));
597 make_buffwxhc(false);
598 write_wxhc(def_wxhc_filename);
599 }
600 }
601
cb_wxhc_wrap_autosend()602 void cb_wxhc_wrap_autosend()
603 {
604 if (check_wxhcfields()) {
605 if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 0)
606 return;
607 update_header(CHANGED);
608 }
609 update_wxhcfields();
610
611 if (base_wxhc_filename == string("new").append(FWXHC_EXT) ||
612 base_wxhc_filename == string("default").append(FWXHC_EXT) )
613 if (!cb_wxhc_save_as()) return;
614
615 update_header(FROM);
616 buffwxhc.assign(header("<nhc_wx>"));
617 make_buffwxhc(true);
618 xfr_via_socket(base_wxhc_filename, buffwxhc);
619
620 buffwxhc.assign(header("<nhc_wx>"));
621 make_buffwxhc(false);
622 write_wxhc(def_wxhc_filename);
623 }
624
cb_wxhc_load_template()625 void cb_wxhc_load_template()
626 {
627 string def_wxhc_filename = def_wxhc_TemplateName;
628 const char *p = FSEL::select(
629 "Open template file",
630 string("Template file\t*").append(TWXHC_EXT).c_str(),
631 def_wxhc_filename.c_str());
632 if (p) {
633 clear_wxhc_form();
634 read_data_file(p);
635 def_wxhc_TemplateName = p;
636 show_filename(def_wxhc_TemplateName);
637 using_wxhc_template = true;
638 }
639 }
640
cb_wxhc_save_template()641 void cb_wxhc_save_template()
642 {
643 if (!using_wxhc_template) {
644 cb_wxhc_save_as_template();
645 return;
646 }
647 string def_wxhc_filename = def_wxhc_TemplateName;
648 const char *p = FSEL::saveas(
649 "Save template file",
650 string("Template file\t*").append(TWXHC_EXT).c_str(),
651 def_wxhc_filename.c_str());
652 if (p) {
653 update_header(CHANGED);
654 update_wxhcfields();
655 buffwxhc.assign(header("<nhc_wx>"));
656 make_buffwxhc();
657 write_wxhc(p);
658 }
659 }
660
cb_wxhc_save_as_template()661 void cb_wxhc_save_as_template()
662 {
663 string def_wxhc_filename = def_wxhc_TemplateName;
664 const char *p = FSEL::saveas(
665 "Save as template file",
666 string("Template file\t*").append(TWXHC_EXT).c_str(),
667 def_wxhc_filename.c_str());
668 if (p) {
669 const char *pext = fl_filename_ext(p);
670 def_wxhc_TemplateName = p;
671 if (strlen(pext) == 0) def_wxhc_TemplateName.append(TWXHC_EXT);
672 remove_spaces_from_filename(def_wxhc_TemplateName);
673
674 clear_header();
675 update_header(CHANGED);
676 update_wxhcfields();
677 buffwxhc.assign(header("<nhc_wx>"));
678 make_buffwxhc();
679 write_wxhc(def_wxhc_TemplateName);
680
681 show_filename(def_wxhc_TemplateName);
682 using_wxhc_template = true;
683 }
684 }
685
cb_wxhc_open()686 void cb_wxhc_open()
687 {
688 const char *p = FSEL::select(
689 _("Open data file"),
690 string("ICS-wxhc\t*").append(FWXHC_EXT).c_str(),
691 def_wxhc_filename.c_str());
692 if (!p) return;
693 if (strlen(p) == 0) return;
694 clear_wxhc_form();
695 read_data_file(p);
696 using_wxhc_template = false;
697 def_wxhc_filename = p;
698 show_filename(def_wxhc_filename);
699 }
700
write_wxhc(string s)701 void write_wxhc(string s)
702 {
703 FILE *filewxhc = fopen(s.c_str(), "w");
704 if (!filewxhc) return;
705
706 fwrite(buffwxhc.c_str(), buffwxhc.length(), 1, filewxhc);
707 fclose(filewxhc);
708 }
709
710
cb_wxhc_save_as()711 bool cb_wxhc_save_as()
712 {
713 const char *p;
714 string newfilename;
715
716 string name = named_file();
717 if (!name.empty()) {
718 name.append(FWXHC_EXT);
719 newfilename = ICS_msg_dir;
720 newfilename.append(name);
721 } else
722 newfilename = def_wxhc_filename;
723
724 p = FSEL::saveas(
725 _("Save data file"),
726 string("ICS-wxhc\t*").append(FWXHC_EXT).c_str(),
727 newfilename.c_str());
728
729 if (!p) return false;
730 if (strlen(p) == 0) return false;
731
732 if (progStatus.sernbr_fname) update_sernbr();
733
734 const char *pext = fl_filename_ext(p);
735 def_wxhc_filename = p;
736 if (strlen(pext) == 0) def_wxhc_filename.append(FWXHC_EXT);
737
738 remove_spaces_from_filename(def_wxhc_filename);
739
740 update_header(NEW);
741 update_wxhcfields();
742 buffwxhc.assign(header("<nhc_wx>"));
743 make_buffwxhc();
744 write_wxhc(def_wxhc_filename);
745
746 using_wxhc_template = false;
747 show_filename(def_wxhc_filename);
748 return true;
749 }
750
cb_wxhc_save()751 void cb_wxhc_save()
752 {
753 if (base_wxhc_filename == string("new").append(FWXHC_EXT) ||
754 base_wxhc_filename == string("default").append(FWXHC_EXT) ||
755 using_wxhc_template == true) {
756 cb_wxhc_save_as();
757 return;
758 }
759
760 if (check_wxhcfields()) update_header(CHANGED);
761 update_wxhcfields();
762 buffwxhc.assign(header("<nhc_wx>"));
763 make_buffwxhc();
764 write_wxhc(def_wxhc_filename);
765
766 using_wxhc_template = false;
767 }
768
quad_to_html(string & target,NHC_QUAD * p)769 static void quad_to_html( string &target, NHC_QUAD *p)
770 {
771 string X = "X"; string SP = " ";
772 string sval = " ";
773 char szval[20];
774 while (p->qtype != E) {
775 if (p->qtype == B)
776 replacestr(target, p->html_fld, *((bool *)(p->ptr)) ? X : SP);
777 else if (p->qtype == S || p->qtype == O)
778 replacestr(target, p->html_fld, *((string *)(p->ptr)));
779 else if (p->qtype == M) {
780 sval = *((string *)(p->ptr));
781 size_t np = string::npos;
782 while ( (np = sval.find("\n")) != string::npos)
783 sval.replace(np, 1, "<br>");
784 replacestr(target, p->html_fld, sval);
785 } else if (p->qtype == T)
786 replacestr(target, p->html_fld, *((string *)(p->ptr)));
787 else if (p->qtype == C) {
788 sval = " ";
789 sval[0] = *((char *)(p->ptr));
790 replacestr(target, p->html_fld, sval);
791 }
792 else if (p->qtype == I) {
793 if (*((int *)(p->ptr)) > 0) {
794 snprintf(szval, sizeof(szval), "%d", *((int *)(p->ptr)) );
795 sval = szval;
796 } else sval.clear();
797 replacestr(target, p->html_fld, sval);
798 }
799 else if (p->qtype == F) {
800 if (*((float *)(p->ptr)) != 0) {
801 snprintf(szval, sizeof(szval), "%f", *((float *)(p->ptr)));
802 sval = szval;
803 } else sval.clear();
804 replacestr(target, p->html_fld, sval);
805 }
806 p++;
807 }
808 }
809
cb_wxhc_html()810 void cb_wxhc_html()
811 {
812 string name_name = fl_filename_name(def_wxhc_filename.c_str());
813 size_t p = name_name.rfind('.');
814 if (p != string::npos) name_name.erase(p);
815
816 string wxhc_rptsta = ICS_dir;
817 wxhc_rptsta.append(name_name);
818 wxhc_rptsta.append(".html");
819
820 update_wxhcfields();
821 string formwxhc = wxhc_html_template;
822
823 replacestr(formwxhc, TITLE, name_name);
824
825 quad_to_html (formwxhc, wxhc_QUAD);
826
827 FILE *filewxhc = fopen(wxhc_rptsta.c_str(), "w");
828 fprintf(filewxhc,"%s", formwxhc.c_str());
829 fclose(filewxhc);
830
831 open_url(wxhc_rptsta.c_str());
832 }
833
quad_to_text(string & target,NHC_QUAD * p)834 static void quad_to_text( string &target, NHC_QUAD *p)
835 {
836 string X = "X"; string SP = " ";
837 string sval = " ";
838 string del = "DELETE";
839 char szval[20];
840 while (p->qtype != E) {
841 if (p->qtype == B) {
842 bool b = *((bool *)(p->ptr));
843 if (b) replacestr(target, p->html_fld, X);
844 else replacestr(target, p->html_fld, SP);
845 } else if (p->qtype == S || p->qtype == M || p->qtype == O) {
846 if (((string *)(p->ptr))->length())
847 replacestr(target, p->html_fld, *((string *)(p->ptr)));
848 else replacestr(target, p->html_fld, del);
849 } else if (p->qtype == T) {
850 if (((string *)(p->ptr))->length())
851 replacestr(target, p->html_fld, *((string *)(p->ptr)));
852 else replacestr(target, p->html_fld, del);
853 } else if (p->qtype == C) {
854 sval = " ";
855 sval[0] = *((char *)(p->ptr));
856 if (sval[0] != 0 && sval[0] != ' ')
857 replacestr(target, p->html_fld, sval);
858 else replacestr(target, p->html_fld, del);
859 }
860 else if (p->qtype == I) {
861 if (*((int *)(p->ptr)) > 0) {
862 snprintf(szval, sizeof(szval), "%d", *((int *)(p->ptr)) );
863 sval = szval;
864 replacestr(target, p->html_fld, sval);
865 } else replacestr(target, p->html_fld, del);
866 }
867 else if (p->qtype == F) {
868 if (*((float *)(p->ptr)) != 0) {
869 snprintf(szval, sizeof(szval), "%f", *((float *)(p->ptr)));
870 sval = szval;
871 replacestr(target, p->html_fld, sval);
872 } else replacestr(target, p->html_fld, del);
873 }
874 p++;
875 }
876 }
877
strip_text(string & target)878 static void strip_text( string &target )
879 {
880 size_t p = 0, p1, p2;
881 while ((p = target.find ("DELETE"), p) != string::npos) {
882 p1 = target.rfind ("\n", p);
883 p2 = target.find ("\n", p);
884 if (p1 != string::npos && p2 != string::npos)
885 target.erase( p1, p2 - p1 );
886 p++;
887 }
888 }
889
cb_wxhc_textout()890 void cb_wxhc_textout()
891 {
892 string wxhc_rptsta = ICS_dir;
893 wxhc_rptsta.append("wxhc.txt");
894
895 update_wxhcfields();
896 string formwxhc = wxhc_text_template;
897
898 quad_to_text (formwxhc, wxhc_QUAD);
899
900 strip_text (formwxhc);
901
902 FILE *filewxhc = fopen(wxhc_rptsta.c_str(), "w");
903 fprintf(filewxhc,"%s", formwxhc.c_str());
904 fclose(filewxhc);
905
906 open_url(wxhc_rptsta.c_str());
907 }
908
909