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 #include "wx_strings.h"
75
76 string buffstorm;
77 string def_storm_filename = "";
78 string base_storm_filename = "";
79 string def_storm_TemplateName = "";
80
81 string storm_date;
82 string storm_time;
83 string storm_zone;
84 string storm_state;
85 string storm_county;
86 string storm_location;
87 bool storm_tornado;
88 string storm_tornado_cat;
89 bool storm_hail;
90 string storm_hail_size;
91 bool storm_wind;
92 string storm_wind_cat;
93 bool storm_flood;
94 string storm_flood_cat;
95 bool storm_damage;
96 string storm_damage_cat;
97 bool storm_snow;
98 string storm_snow_tot;
99 string storm_snow_dur;
100 bool storm_f_rain;
101 string storm_f_rain_tot;
102 string storm_f_rain_dur;
103 bool storm_h_rain;
104 string storm_h_rain_tot;
105 string storm_h_rain_dur;
106 string storm_o_name;
107 string storm_o_email;
108 string storm_o_tele;
109 string storm_o_profile;
110 string storm_details;
111
112 // could not use real names ... WIN32 barfs
113 enum STORM_QTYPE { B, D, S, M, T, I, F, C, O, E };
114 // bool, string, multi-line string, text, int, float, character, cOmbo, empty
115
116 struct STORM_QUAD {
117 STORM_QTYPE qtype; // type of field
118 string html_fld;
119 void *ptr;
120 Fl_Widget *widget; };
121
122 STORM_QUAD sQ[] = {
123 { D, ":date:", &storm_date, w_storm_date },
124 { S, ":time:", &storm_time, w_storm_time },
125 { O, ":zone:", &storm_zone, w_storm_zone },
126 { O, ":state:", &storm_state, w_storm_state },
127 { O, ":county:", &storm_county, w_storm_county },
128 { S, ":location:", &storm_location, w_storm_location },
129 { B, ":tornado:", &storm_tornado, w_storm_tornado },
130 { O, ":tornado_cat:", &storm_tornado_cat, w_storm_tornado_cat },
131 { B, ":hail:", &storm_hail, w_storm_hail },
132 { O, ":hail_size:", &storm_hail_size, w_storm_hail_size },
133 { B, ":high_wind:", &storm_wind, w_storm_wind },
134 { O, ":speed:", &storm_wind_cat, w_storm_wind_cat },
135 { B, ":flood:", &storm_flood, w_storm_flood },
136 { O, ":flood_cat:", &storm_flood_cat, w_storm_flood_cat },
137 { B, ":damage:", &storm_damage, w_storm_damage },
138 { O, ":damage_cat:", &storm_damage_cat, w_storm_damage_cat },
139 { B, ":snow:", &storm_snow, w_storm_snow },
140 { O, ":snow_tot:", &storm_snow_tot, w_storm_snow_tot },
141 { O, ":snow_dur:", &storm_snow_dur, w_storm_snow_dur },
142 { B, ":f_rain:", &storm_f_rain, w_storm_f_rain },
143 { O, ":f_rain_tot:", &storm_f_rain_tot, w_storm_f_rain_tot },
144 { O, ":f_rain_dur:", &storm_f_rain_dur, w_storm_f_rain_dur },
145 { B, ":h_rain:", &storm_h_rain, w_storm_h_rain },
146 { O, ":h_rain_tot:", &storm_h_rain_tot, w_storm_h_rain_tot },
147 { O, ":h_rain_dur:", &storm_h_rain_dur, w_storm_h_rain_dur },
148 { S, ":o_name:", &storm_o_name, w_storm_o_name },
149 { S, ":o_email:", &storm_o_email, w_storm_o_email },
150 { S, ":o_tele:", &storm_o_tele, w_storm_o_tele },
151 { O, ":o_profile:", &storm_o_profile, w_storm_o_profile },
152 { T, ":details:", &storm_details, w_storm_details }
153 };
154
155 int num_quads = (int)(sizeof(sQ) / sizeof(STORM_QUAD));
156
157 bool using_storm_template = false;
158
159 //------------------------------------------------------------------------------
160 // required to initialize the control pointers in the QUAD array
161 //------------------------------------------------------------------------------
162 static bool fields_initialized = false;
163
init_widget(string s,Fl_Widget * w)164 static void init_widget(string s, Fl_Widget * w)
165 {
166 for (int i = 0; i < num_quads; i++) {
167 if (sQ[i].html_fld == s) {
168 sQ[i].widget = w;
169 break;
170 }
171 }
172 }
173
init_widgets()174 static void init_widgets()
175 {
176 init_widget(":date:", (Fl_Widget *)w_storm_date);
177 init_widget(":time:", (Fl_Widget *)w_storm_time);
178 init_widget(":zone:", (Fl_Widget *)w_storm_zone);
179 init_widget(":state:", (Fl_Widget *)w_storm_state);
180 init_widget(":county:", (Fl_Widget *)w_storm_county);
181 init_widget(":location:", (Fl_Widget *)w_storm_location);
182 init_widget(":flood:", (Fl_Widget *)w_storm_flood);
183 init_widget(":flood_cat:", (Fl_Widget *)w_storm_flood_cat);
184 init_widget(":hail:", (Fl_Widget *)w_storm_hail);
185 init_widget(":hail_size:", (Fl_Widget *)w_storm_hail_size);
186 init_widget(":high_wind:", (Fl_Widget *)w_storm_wind);
187 init_widget(":speed:", (Fl_Widget *)w_storm_wind_cat);
188 init_widget(":tornado:", (Fl_Widget *)w_storm_tornado);
189 init_widget(":tornado_cat:", (Fl_Widget *)w_storm_tornado_cat);
190 init_widget(":damage:", (Fl_Widget *)w_storm_damage);
191 init_widget(":damage_cat:", (Fl_Widget *)w_storm_damage_cat);
192 init_widget(":snow:", (Fl_Widget *)w_storm_snow);
193 init_widget(":snow_tot:", (Fl_Widget *)w_storm_snow_tot);
194 init_widget(":snow_dur:", (Fl_Widget *)w_storm_snow_dur);
195 init_widget(":f_rain:", (Fl_Widget *)w_storm_f_rain);
196 init_widget(":f_rain_tot:", (Fl_Widget *)w_storm_f_rain_tot);
197 init_widget(":f_rain_dur:", (Fl_Widget *)w_storm_f_rain_dur);
198 init_widget(":h_rain:", (Fl_Widget *)w_storm_h_rain);
199 init_widget(":h_rain_tot:", (Fl_Widget *)w_storm_h_rain_tot);
200 init_widget(":h_rain_dur:", (Fl_Widget *)w_storm_h_rain_dur);
201 init_widget(":o_name:", (Fl_Widget *)w_storm_o_name);
202 init_widget(":o_email:", (Fl_Widget *)w_storm_o_email);
203 init_widget(":o_tele:", (Fl_Widget *)w_storm_o_tele);
204 init_widget(":o_profile:", (Fl_Widget *)w_storm_o_profile);
205 init_widget(":details:", (Fl_Widget *)w_storm_details);
206
207 fields_initialized = true;
208 }
209 //------------------------------------------------------------------------------
210
211 // bool, string, multi-line string, text, int, float, character, cOmbo, empty
212 //enum STORM_QTYPE { B, D, S, M, T, I, F, C, O, E };
213
clearQUAD()214 static void clearQUAD()
215 {
216 for (int i = 0; i < num_quads; i++) {
217 switch (sQ[i].qtype) {
218 case B : (*(bool *)(sQ[i].ptr)) = false; break;
219 case S :
220 case D :
221 case M : ((string *)(sQ[i].ptr))->clear(); break;
222 case T : ((string *)(sQ[i].ptr))->clear(); break;
223 case C : (*(char *)(sQ[i].ptr)) = ' '; break;
224 case I : (*(int *)(sQ[i].ptr)) = 0; break;
225 case F : (*(float *)(sQ[i].ptr)) = 0.0; break;
226 case O : ((string *)(sQ[i].ptr))->clear(); break;
227 case E : return;
228 }
229 }
230 }
231
clear_stormfields()232 void clear_stormfields()
233 {
234 if (!fields_initialized) init_widgets();
235 clearQUAD();
236 }
237
checkQUAD()238 static bool checkQUAD()
239 {
240 float f = 0;
241 char c = ' ';
242 for (int i = 0; i < num_quads; i++) {
243 switch (sQ[i].qtype) {
244 case B:
245 if (*((bool *)(sQ[i].ptr)) != ((Fl_Check_Button *)sQ[i].widget)->value()){
246 return true;
247 }
248 break;
249 case S:
250 case M:
251 if (*((string *)(sQ[i].ptr)) != ((Fl_Input2 *)sQ[i].widget)->value()){
252 return true;
253 }
254 break;
255 case D:
256 if (*((string *)(sQ[i].ptr)) != ((Fl_DateInput *)sQ[i].widget)->value()){
257 return true;
258 }
259 break;
260 case T:
261 if (*((string *)(sQ[i].ptr)) != ((FTextEdit *)sQ[i].widget)->buffer()->text()){
262 return true;
263 }
264 break;
265 case C:
266 c = ' ';
267 if (((Fl_Input2 *)sQ[i].widget)->value()[0])
268 c = ((Fl_Input2 *)sQ[i].widget)->value()[0];
269 if (*((char *)(sQ[i].ptr)) != c){
270 return true;
271 }
272 break;
273 case I:
274 i = 0;
275 if (((Fl_Input2 *)sQ[i].widget)->value()[0])
276 sscanf( ((Fl_Input2 *)sQ[i].widget)->value(), "%d", &i);
277 if (*((int *)(sQ[i].ptr)) != i){
278 return true;
279 }
280 break;
281 case F:
282 f = 0;
283 if (((Fl_Input2 *)sQ[i].widget)->value()[0])
284 sscanf( ((Fl_Input2 *)sQ[i].widget)->value(), "%f", &f);
285 if (*((float *)(sQ[i].ptr)) != f) {
286 return true;
287 }
288 break;
289 case O:
290 if (((Fl_ListBox *)sQ[i].widget)->index() == 0) break;
291 if (*((string *)(sQ[i].ptr)) != ((Fl_ListBox *)sQ[i].widget)->value()) {
292 return true;
293 }
294 break;
295 case E:
296 default: return false;
297 }
298 }
299 return false;
300 }
301
check_stormfields()302 bool check_stormfields()
303 {
304 return checkQUAD();
305 }
306
updateQUAD()307 static void updateQUAD()
308 {
309 float f = 0;
310 char c = ' ';
311 for (int i = 0; i < num_quads; i++) {
312 switch (sQ[i].qtype) {
313 case B:
314 *((bool *)(sQ[i].ptr)) = ((Fl_Check_Button *)sQ[i].widget)->value();
315 break;
316 case S:
317 case M:
318 *((string *)(sQ[i].ptr)) = ((Fl_Input2 *)sQ[i].widget)->value();
319 break;
320 case D:
321 *((string *)(sQ[i].ptr)) = ((Fl_DateInput *)sQ[i].widget)->value();
322 break;
323 case O:
324 { string s = ((Fl_ListBox *)sQ[i].widget)->value();
325 if (s.find("--") == 0)
326 ((string *)(sQ[i].ptr))->clear();
327 else
328 *((string *)(sQ[i].ptr)) = ((Fl_ListBox *)sQ[i].widget)->value();
329 }
330 break;
331 case T:
332 *((string *)(sQ[i].ptr)) = ((FTextEdit *)sQ[i].widget)->buffer()->text();
333 break;
334 case C:
335 c = ' ';
336 if (((Fl_Input2 *)sQ[i].widget)->value()[0])
337 c = ((Fl_Input2 *)sQ[i].widget)->value()[0];
338 *((char *)(sQ[i].ptr)) = c;
339 break;
340 case I:
341 i = 0;
342 if (((Fl_Input2 *)sQ[i].widget)->value()[0])
343 sscanf( ((Fl_Input2 *)sQ[i].widget)->value(), "%d", &i);
344 *((int *)(sQ[i].ptr)) = i;
345 break;
346 case F:
347 f = 0;
348 if (((Fl_Input2 *)sQ[i].widget)->value()[0])
349 sscanf( ((Fl_Input2 *)sQ[i].widget)->value(), "%f", &f);
350 *((float *)(sQ[i].ptr)) = f;
351 break;
352 case E:
353 default: return;
354 }
355 }
356 }
357
update_stormfields()358 void update_stormfields()
359 {
360 if (!fields_initialized) init_widgets();
361 updateQUAD();
362 }
363
activate_listbox()364 static void activate_listbox()
365 {
366 if (w_storm_flood->value())
367 w_storm_flood_cat->activate();
368 else
369 w_storm_flood_cat->deactivate();
370 if (w_storm_hail->value())
371 w_storm_hail_size->activate();
372 else
373 w_storm_hail_size->deactivate();
374 if (w_storm_wind->value())
375 w_storm_wind_cat->activate();
376 else
377 w_storm_wind_cat->deactivate();
378 if (w_storm_tornado->value())
379 w_storm_tornado_cat->activate();
380 else
381 w_storm_tornado_cat->deactivate();
382 if (w_storm_damage->value())
383 w_storm_damage_cat->activate();
384 else
385 w_storm_damage_cat->deactivate();
386 if (w_storm_snow->value()) {
387 w_storm_snow_tot->activate();
388 w_storm_snow_dur->activate();
389 } else {
390 w_storm_snow_tot->deactivate();
391 w_storm_snow_dur->deactivate();
392 }
393 if (w_storm_f_rain->value()) {
394 w_storm_f_rain_tot->activate();
395 w_storm_f_rain_dur->activate();
396 } else {
397 w_storm_f_rain_tot->deactivate();
398 w_storm_f_rain_dur->deactivate();
399 }
400 if (w_storm_h_rain->value()) {
401 w_storm_h_rain_tot->activate();
402 w_storm_h_rain_dur->activate();
403 } else {
404 w_storm_h_rain_tot->deactivate();
405 w_storm_h_rain_dur->deactivate();
406 }
407 }
408
updateFORM()409 static void updateFORM()
410 {
411 char val[20];
412 for (int i = 0; i < num_quads; i++ ) {
413 switch (sQ[i].qtype) {
414 case B:
415 ((Fl_Check_Button *)sQ[i].widget)->value(*((bool *)(sQ[i].ptr)));
416 break;
417 case S:
418 case M:
419 ((Fl_Input2 *)sQ[i].widget)->value(((string *)(sQ[i].ptr))->c_str());
420 break;
421 case D:
422 ((Fl_DateInput *)sQ[i].widget)->value(((string *)(sQ[i].ptr))->c_str());
423 break;
424 case O:
425 if (((string *)(sQ[i].ptr))->empty())
426 ((Fl_ListBox *)sQ[i].widget)->index(0);
427 else
428 ((Fl_ListBox *)sQ[i].widget)->put_value(((string *)(sQ[i].ptr))->c_str());
429 break;
430 case T:
431 ((FTextEdit *)sQ[i].widget)->clear();
432 ((FTextEdit *)sQ[i].widget)->add(((string *)(sQ[i].ptr))->c_str());
433 break;
434 case C:
435 val[0] = *((char *)(sQ[i].ptr));
436 val[1] = 0;
437 ((Fl_Input2 *)sQ[i].widget)->value(val);
438 break;
439 case I:
440 if (*((int *)(sQ[i].ptr)) == 0)
441 ((Fl_Input2 *)sQ[i].widget)->value("");
442 else {
443 snprintf(val, sizeof(val), "%d", *((int *)(sQ[i].ptr)));
444 ((Fl_Input2 *)sQ[i].widget)->value(val);
445 }
446 break;
447 case F:
448 snprintf(val, sizeof(val), "%f", *((float *)(sQ[i].ptr)));
449 ((Fl_Input2 *)sQ[i].widget)->value(val);
450 break;
451 case E:
452 default: return;
453 }
454 }
455 }
456
update_stormform()457 void update_stormform()
458 {
459 if (!fields_initialized) init_widgets();
460 updateFORM();
461 activate_listbox();
462 }
463
clear_storm_form()464 void clear_storm_form()
465 {
466 clear_stormfields();
467 update_stormform();
468 w_storm_state->index(0);
469 set_storm_counties(0);
470 w_storm_o_profile->index(0);
471 w_storm_location->index(0);
472 w_storm_zone->index(0);
473 }
474
475 static string mbuff;
476
make_buffQUAD()477 static void make_buffQUAD()
478 {
479 string one = "1"; string zero = "0";
480 string sval = " ";
481 char szval[20];
482 for (int i = 0; i < num_quads; i++) {
483 switch (sQ[i].qtype) {
484 case B:
485 if (*((bool *)(sQ[i].ptr)) == true)
486 mbuff.append( lineout( sQ[i].html_fld, *((bool *)(sQ[i].ptr)) ? one : zero));
487 break;
488 case O: case S: case D: case M:
489 if (((string *)(sQ[i].ptr))->length())
490 mbuff.append( lineout( sQ[i].html_fld, *((string *)(sQ[i].ptr))));
491 break;
492 case T:
493 mbuff.append( lineout( sQ[i].html_fld, *((string *)(sQ[i].ptr))));
494 break;
495 case C:
496 if ((*(char *)(sQ[i].ptr)) != 0 && *((char *)(sQ[i].ptr)) != ' ') {
497 sval = " ";
498 sval[0] = *((char *)(sQ[i].ptr));
499 mbuff.append( lineout( sQ[i].html_fld, sval));
500 }
501 break;
502 case I:
503 if (*((int*)(sQ[i].ptr)) > 0) {
504 snprintf(szval, sizeof(szval), "%d", *((int *)(sQ[i].ptr)) );
505 sval = szval;
506 mbuff.append( lineout( sQ[i].html_fld, sval) );
507 }
508 break;
509 case F:
510 if (*((float *)(sQ[i].ptr)) > 0) {
511 snprintf(szval, sizeof(szval), "%f", *((float *)(sQ[i].ptr)));
512 sval = szval;
513 mbuff.append( lineout( sQ[i].html_fld, sval) );
514 }
515 break;
516 case E:
517 default: return;
518 }
519 }
520 }
521
make_buff_storm(bool compress=false)522 void make_buff_storm(bool compress = false)
523 {
524 mbuff.clear();
525 make_buffQUAD();
526 if (compress) compress_maybe(mbuff);
527 buffstorm.append(mbuff);
528 }
529
readQUAD(string data)530 static void readQUAD(string data)
531 {
532 float f;
533 for (int i = 0; i < num_quads; i++) {
534 switch (sQ[i].qtype) {
535 case B:
536 *((bool *)(sQ[i].ptr)) = (findstr( data, sQ[i].html_fld ) == "1");
537 break;
538 case D: case O: case S: case M:
539 *((string *)(sQ[i].ptr)) = findstr( data, sQ[i].html_fld );
540 break;
541 case T:
542 *((string *)(sQ[i].ptr)) = findstr( data, sQ[i].html_fld );
543 break;
544 case C:
545 *((char *)(sQ[i].ptr)) = findstr( data, sQ[i].html_fld )[0];
546 break;
547 case I:
548 i = 0;
549 sscanf( findstr( data, sQ[i].html_fld ).c_str(), "%d", &i);
550 *((int *)(sQ[i].ptr)) = i;
551 break;
552 case F:
553 f = 0;
554 sscanf( findstr( data, sQ[i].html_fld ).c_str(), "%f", &f);
555 *((float *)(sQ[i].ptr)) = f;
556 break;
557 case E:
558 default: return;
559 }
560 }
561 }
562
read_storm_buffer(string data)563 void read_storm_buffer(string data)
564 {
565 clear_stormfields();
566 read_header(data);
567
568 readQUAD (data);
569 update_stormform();
570 int idx = w_storm_state->index();
571 set_storm_counties(idx);
572 w_storm_county->value( ((string *)(sQ[4].ptr))->c_str() );
573 }
574
cb_storm_new()575 void cb_storm_new()
576 {
577 if (check_stormfields()) {
578 if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 1) {
579 update_header(CHANGED);
580 cb_storm_save();
581 }
582 }
583 clear_storm_form();
584 clear_header();
585 def_storm_filename = ICS_msg_dir;
586 def_storm_filename.append("new").append(FSTRM_EXT);
587 show_filename(def_storm_filename);
588 using_storm_template = false;
589 }
590
cb_storm_import()591 void cb_storm_import()
592 {
593 fl_alert2("Not implemented");
594 }
595
cb_storm_export()596 void cb_storm_export()
597 {
598 fl_alert2("Not implemented");
599 }
600
cb_storm_wrap_import(string wrapfilename,string inpbuffer)601 void cb_storm_wrap_import(string wrapfilename, string inpbuffer)
602 {
603 clear_storm_form();
604 read_storm_buffer(inpbuffer);
605 def_storm_filename = ICS_msg_dir;
606 def_storm_filename.append(wrapfilename);
607 show_filename(def_storm_filename);
608 using_storm_template = false;
609 }
610
eval_storm_fsize()611 int eval_storm_fsize()
612 {
613 Ccrc16 chksum;
614 evalstr.assign("[WRAP:beg][WRAP:lf][WRAP:fn ");
615 evalstr.append(base_storm_filename).append("]");
616 update_stormfields();
617 update_header(FROM);
618 evalstr.append(header("<storm_wx>"));
619 buffstorm.clear();
620 make_buff_storm(true);
621 if (buffstorm.empty()) return 0;
622 compress_maybe( buffstorm );
623 evalstr.append( buffstorm );
624 evalstr.append("[WRAP:chksum ").append(chksum.scrc16(evalstr)).append("][WRAP:end]");
625 return evalstr.length();
626 }
627
cb_storm_wrap_export()628 void cb_storm_wrap_export()
629 {
630 if (check_stormfields()) {
631 if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 0)
632 return;
633 update_header(CHANGED);
634 }
635 update_stormfields();
636
637 if (base_storm_filename == string("new").append(FSTRM_EXT) ||
638 base_storm_filename == string("default").append(FSTRM_EXT) )
639 if (!cb_storm_save_as()) return;
640
641 string wrapfilename = WRAP_send_dir;
642 wrapfilename.append(base_storm_filename);
643 wrapfilename.append(".wrap");
644 const char *p = FSEL::saveas(
645 "Save as wrap file",
646 "Wrap file\t*.{wrap,WRAP}",
647 wrapfilename.c_str());
648 if (p) {
649 string pext = fl_filename_ext(p);
650 wrapfilename = p;
651
652 update_header(FROM);
653 buffstorm.assign(header("<storm_wx>"));
654 make_buff_storm(true);
655 export_wrapfile(base_storm_filename, wrapfilename, buffstorm, pext != ".wrap");
656
657 buffstorm.assign(header("<storm_wx>"));
658 make_buff_storm(false);
659 write_storm(def_storm_filename);
660 }
661 }
662
cb_storm_wrap_autosend()663 void cb_storm_wrap_autosend()
664 {
665 if (check_stormfields()) {
666 if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 0)
667 return;
668 update_header(CHANGED);
669 }
670 update_stormfields();
671
672 if (base_storm_filename == string("new").append(FSTRM_EXT) ||
673 base_storm_filename == string("default").append(FSTRM_EXT) )
674 if (!cb_storm_save_as()) return;
675
676 update_header(FROM);
677 buffstorm.assign(header("<storm_wx>"));
678 make_buff_storm(true);
679 xfr_via_socket(base_storm_filename, buffstorm);
680
681 buffstorm.assign(header("<storm_wx>"));
682 make_buff_storm(false);
683 write_storm(def_storm_filename);
684 }
685
cb_storm_load_template()686 void cb_storm_load_template()
687 {
688 string def_storm_filename = def_storm_TemplateName;
689 const char *p = FSEL::select(
690 "Open template file",
691 string("Template file\t*").append(TSTRM_EXT).c_str(),
692 def_storm_filename.c_str());
693 if (p) {
694 clear_storm_form();
695 read_data_file(p);
696 def_storm_TemplateName = p;
697 show_filename(def_storm_TemplateName);
698 using_storm_template = true;
699 }
700 }
701
cb_storm_save_template()702 void cb_storm_save_template()
703 {
704 if (!using_storm_template) {
705 cb_storm_save_as_template();
706 return;
707 }
708 string def_storm_filename = def_storm_TemplateName;
709 const char *p = FSEL::saveas(
710 "Save template file",
711 string("Template file\t*").append(TSTRM_EXT).c_str(),
712 def_storm_filename.c_str());
713 if (p) {
714 update_header(CHANGED);
715 update_stormfields();
716 buffstorm.assign(header("<storm_wx>"));
717 make_buff_storm();
718 write_storm(p);
719 }
720 }
721
cb_storm_save_as_template()722 void cb_storm_save_as_template()
723 {
724 string def_storm_filename = def_storm_TemplateName;
725 const char *p = FSEL::saveas(
726 "Save as template file",
727 string("Template file\t*").append(TSTRM_EXT).c_str(),
728 def_storm_filename.c_str());
729 if (p) {
730 const char *pext = fl_filename_ext(p);
731 def_storm_TemplateName = p;
732 if (strlen(pext) == 0) def_storm_TemplateName.append(TSTRM_EXT);
733 remove_spaces_from_filename(def_storm_TemplateName);
734
735 clear_header();
736 update_header(CHANGED);
737 update_stormfields();
738 buffstorm.assign(header("<storm_wx>"));
739 make_buff_storm();
740 write_storm(def_storm_TemplateName);
741
742 show_filename(def_storm_TemplateName);
743 using_storm_template = true;
744 }
745 }
746
cb_storm_open()747 void cb_storm_open()
748 {
749 const char *p = FSEL::select(
750 _("Open data file"),
751 string("ICS-storm\t*").append(FSTRM_EXT).c_str(),
752 def_storm_filename.c_str());
753 if (!p) return;
754 if (strlen(p) == 0) return;
755 clear_storm_form();
756 read_data_file(p);
757 using_storm_template = false;
758 def_storm_filename = p;
759 show_filename(def_storm_filename);
760 }
761
write_storm(string s)762 void write_storm(string s)
763 {
764 FILE *filestorm = fopen(s.c_str(), "w");
765 if (!filestorm) return;
766
767 fwrite(buffstorm.c_str(), buffstorm.length(), 1, filestorm);
768 fclose(filestorm);
769 }
770
771
cb_storm_save_as()772 bool cb_storm_save_as()
773 {
774 const char *p;
775 string newfilename;
776
777 string name = named_file();
778 if (!name.empty()) {
779 name.append(FSTRM_EXT);
780 newfilename = ICS_msg_dir;
781 newfilename.append(name);
782 } else
783 newfilename = def_storm_filename;
784
785 p = FSEL::saveas(
786 _("Save data file"),
787 string("ICS-storm\t*").append(FSTRM_EXT).c_str(),
788 newfilename.c_str());
789
790 if (!p) return false;
791 if (strlen(p) == 0) return false;
792
793 if (progStatus.sernbr_fname) update_sernbr();
794
795 const char *pext = fl_filename_ext(p);
796 def_storm_filename = p;
797 if (strlen(pext) == 0) def_storm_filename.append(FSTRM_EXT);
798
799 remove_spaces_from_filename(def_storm_filename);
800
801 update_header(NEW);
802 update_stormfields();
803 buffstorm.assign(header("<storm_wx>"));
804 make_buff_storm();
805 write_storm(def_storm_filename);
806
807 using_storm_template = false;
808 show_filename(def_storm_filename);
809 return true;
810 }
811
cb_storm_save()812 void cb_storm_save()
813 {
814 if (base_storm_filename == string("new").append(FSTRM_EXT) ||
815 base_storm_filename == string("default").append(FSTRM_EXT) ||
816 using_storm_template == true) {
817 cb_storm_save_as();
818 return;
819 }
820
821 if (check_stormfields()) update_header(CHANGED);
822 update_stormfields();
823 buffstorm.assign(header("<storm_wx>"));
824 make_buff_storm();
825 write_storm(def_storm_filename);
826
827 using_storm_template = false;
828 }
829
830 static string X = "x"; string SP = "_";
831 static string sval = " ";
832 static string del = "";
833
quad_to_html(string & target)834 static void quad_to_html(string &target)
835 {
836 char szval[20];
837 for (int i = 0; i < num_quads; i++) {
838 if (sQ[i].qtype == B)
839 replacestr(target, sQ[i].html_fld, *((bool *)(sQ[i].ptr)) ? X : SP);
840 else if (sQ[i].qtype == O ) {
841 string s = *((string *)(sQ[i].ptr));
842 if (sQ[i].html_fld == ":state:") {
843 if (s.length() > 1) s.erase(2);
844 replacestr(target, sQ[i].html_fld, s);
845 } else if (sQ[i].html_fld == ":zone") {
846 size_t cp = s.find(',');
847 s.erase(cp);
848 replacestr(target, sQ[i].html_fld, s);
849 } else if (s.find("--") == 0) {
850 replacestr(target, sQ[i].html_fld, del);
851 } else {
852 if (s.length())
853 replacestr(target, sQ[i].html_fld, s);
854 else replacestr(target, sQ[i].html_fld, del);
855 }
856 } else if (sQ[i].qtype == S || sQ[i].qtype == M || sQ[i].qtype == D) {
857 if (((string *)(sQ[i].ptr))->length())
858 replacestr(target, sQ[i].html_fld, *((string *)(sQ[i].ptr)));
859 else replacestr(target, sQ[i].html_fld, del);
860 } else if (sQ[i].qtype == M) {
861 sval = *((string *)(sQ[i].ptr));
862 size_t np = string::npos;
863 while ( (np = sval.find("\n")) != string::npos)
864 sval.replace(np, 1, "<br>");
865 replacestr(target, sQ[i].html_fld, sval);
866 } else if (sQ[i].qtype == T)
867 replacestr(target, sQ[i].html_fld, *((string *)(sQ[i].ptr)));
868 else if (sQ[i].qtype == C) {
869 sval = " ";
870 sval[0] = *((char *)(sQ[i].ptr));
871 replacestr(target, sQ[i].html_fld, sval);
872 }
873 else if (sQ[i].qtype == I) {
874 if (*((int *)(sQ[i].ptr)) > 0) {
875 snprintf(szval, sizeof(szval), "%d", *((int *)(sQ[i].ptr)) );
876 sval = szval;
877 } else sval.clear();
878 replacestr(target, sQ[i].html_fld, sval);
879 }
880 else if (sQ[i].qtype == F) {
881 if (*((float *)(sQ[i].ptr)) != 0) {
882 snprintf(szval, sizeof(szval), "%f", *((float *)(sQ[i].ptr)));
883 sval = szval;
884 } else sval.clear();
885 replacestr(target, sQ[i].html_fld, sval);
886 }
887 }
888 }
889
cb_storm_html()890 void cb_storm_html()
891 {
892 string name_name = fl_filename_name(def_storm_filename.c_str());
893 size_t p = name_name.rfind('.');
894 if (p != string::npos) name_name.erase(p);
895
896 string storm_rptsta = ICS_dir;
897 storm_rptsta.append(name_name);
898 storm_rptsta.append(".html");
899
900 update_stormfields();
901 string formstorm = storm_html_template;
902
903 replacestr(formstorm, TITLE, name_name);
904
905 quad_to_html (formstorm);
906
907 FILE *filestorm = fopen(storm_rptsta.c_str(), "w");
908 fprintf(filestorm,"%s", formstorm.c_str());
909 fclose(filestorm);
910
911 open_url(storm_rptsta.c_str());
912 }
913
quad_to_text(string & target)914 static void quad_to_text( string &target)
915 {
916 char szval[20];
917 for (int i = 0; i < num_quads; i++) {
918 if (sQ[i].qtype == B)
919 replacestr(target, sQ[i].html_fld, *((bool *)(sQ[i].ptr)) ? X : del);
920 else if (sQ[i].qtype == O ) {
921 string s = *((string *)(sQ[i].ptr));
922 if (sQ[i].html_fld == ":state:") {
923 if (s.length() > 1) s.erase(2);
924 replacestr(target, sQ[i].html_fld, s);
925 } else if (sQ[i].html_fld == ":zone") {
926 size_t cp = s.find(',');
927 s.erase(cp);
928 replacestr(target, sQ[i].html_fld, s);
929 } else if (s.find("--") == 0) {
930 replacestr(target, sQ[i].html_fld, del);
931 } else {
932 if (s.length())
933 replacestr(target, sQ[i].html_fld, s);
934 else replacestr(target, sQ[i].html_fld, del);
935 }
936 } else if (sQ[i].qtype == S || sQ[i].qtype == M || sQ[i].qtype == D) {
937 if (((string *)(sQ[i].ptr))->length())
938 replacestr(target, sQ[i].html_fld, *((string *)(sQ[i].ptr)));
939 else replacestr(target, sQ[i].html_fld, del);
940 } else if (sQ[i].qtype == T) {
941 if (((string *)(sQ[i].ptr))->length())
942 replacestr(target, sQ[i].html_fld, *((string *)(sQ[i].ptr)));
943 else replacestr(target, sQ[i].html_fld, del);
944 } else if (sQ[i].qtype == C) {
945 sval = " ";
946 sval[0] = *((char *)(sQ[i].ptr));
947 if (sval[0] != 0 && sval[0] != ' ')
948 replacestr(target, sQ[i].html_fld, sval);
949 else replacestr(target, sQ[i].html_fld, del);
950 }
951 else if (sQ[i].qtype == I) {
952 if (*((int *)(sQ[i].ptr)) > 0) {
953 snprintf(szval, sizeof(szval), "%d", *((int *)(sQ[i].ptr)) );
954 sval = szval;
955 replacestr(target, sQ[i].html_fld, sval);
956 } else replacestr(target, sQ[i].html_fld, del);
957 }
958 else if (sQ[i].qtype == F) {
959 if (*((float *)(sQ[i].ptr)) != 0) {
960 snprintf(szval, sizeof(szval), "%f", *((float *)(sQ[i].ptr)));
961 sval = szval;
962 replacestr(target, sQ[i].html_fld, sval);
963 } else replacestr(target, sQ[i].html_fld, del);
964 }
965 }
966 }
967
cb_storm_textout()968 void cb_storm_textout()
969 {
970 string storm_rptsta = ICS_dir;
971 storm_rptsta.append("storm.txt");
972
973 update_stormfields();
974 string formstorm = storm_text_template;
975
976 quad_to_text (formstorm);
977
978 FILE *filestorm = fopen(storm_rptsta.c_str(), "w");
979 fprintf(filestorm,"%s", formstorm.c_str());
980 fclose(filestorm);
981
982 open_url(storm_rptsta.c_str());
983 }
984
985