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 "date.h"
53 #include "calendar.h"
54 #include "icons.h"
55 #include "fileselect.h"
56 #include "wrap.h"
57 #include "status.h"
58 #include "parse_xml.h"
59
60 #ifdef WIN32
61 # include "flmsgrc.h"
62 # include "compat.h"
63 # define dirent fl_dirent_no_thanks
64 #endif
65
66 #include <FL/filename.H>
67 #include "dirent-check.h"
68
69 #include <FL/x.H>
70 #include <FL/Fl_Pixmap.H>
71 #include <FL/Fl_Image.H>
72
73 using namespace std;
74
75 // ---------------------------------------------------------------------
76 // ics 205a field variables and template variables
77 // ---------------------------------------------------------------------
78
79 string ics205a_incident = ":inc:";
80 string ics205a_date_fm = ":dfm:";
81 string ics205a_time_fm = ":tfm:";
82 string ics205a_date_to = ":dto:";
83 string ics205a_time_to = ":tto:";
84 string ics205a_prepared_by = ":pre:";
85 string ics205a_preparer_position = ":pos:";
86 string ics205a_preparer_date_time = ":dtm:";
87
88 string ics205a_comm_position = ":asg[n]:"; // 32
89 string ics205a_comm_name = ":nam[n]:"; // 32
90 string ics205a_comm_info = ":inf[n]:"; // 32
91
92 string s205a_incident;
93 string s205a_date_fm;
94 string s205a_time_fm;
95 string s205a_date_to;
96 string s205a_time_to;
97 string s205a_prepared_by;
98 string s205a_preparer_position;
99 string s205a_preparer_date_time;
100
101 string s205a_comm_position[32];
102 string s205a_comm_name[32];
103 string s205a_comm_info[32];
104
105 // =====================================================================
106
107 string buff205a;
108 string def_205a_filename = "";
109 string base_205a_filename = "";
110 string def_205a_TemplateName = "";
111 bool using_ics205a_template = false;
112
cb_205a_set_date_fm()113 void cb_205a_set_date_fm()
114 {
115 txt_205a_date_fm->value(szDate(progStatus.dtformat));
116 }
117
cb_205a_set_time_fm()118 void cb_205a_set_time_fm()
119 {
120 txt_205a_time_fm->value(szTime(progStatus.UTC));
121 }
122
cb_205a_set_date_to()123 void cb_205a_set_date_to()
124 {
125 txt_205a_date_to->value(szDate(progStatus.dtformat));
126 }
127
cb_205a_set_time_to()128 void cb_205a_set_time_to()
129 {
130 txt_205a_time_to->value(szTime(progStatus.UTC));
131 }
132
clear_205afields()133 void clear_205afields()
134 {
135 s205a_incident.clear();
136 s205a_date_fm.clear();
137 s205a_time_fm.clear();
138 s205a_date_to.clear();
139 s205a_time_to.clear();
140 s205a_prepared_by.clear();
141 s205a_preparer_position.clear();
142 s205a_preparer_date_time.clear();
143
144 for (int i = 0; i < 32; i++) {
145 s205a_comm_position[i].clear();
146 s205a_comm_name[i].clear();
147 s205a_comm_info[i].clear();
148 }
149 }
150
check_205afields()151 bool check_205afields()
152 {
153 if (s205a_incident != txt_205a_incident->value())
154 return true;
155 if (s205a_date_fm != txt_205a_date_fm->value())
156 return true;
157 if (s205a_time_fm != txt_205a_time_fm->value())
158 return true;
159 if (s205a_date_to != txt_205a_date_to->value())
160 return true;
161 if (s205a_time_to != txt_205a_time_to->value())
162 return true;
163 if (s205a_prepared_by != txt_205a_prepared_by->value())
164 return true;
165 if (s205a_preparer_position != txt_205a_preparer_position->value())
166 return true;
167 if (s205a_preparer_date_time != txt_205a_preparer_date_time->value())
168 return true;
169 for (int i = 0; i < 32; i++) {
170 if (s205a_comm_position[i] != txt_205a_comm_position[i]->value())
171 return true;
172 if (s205a_comm_name[i] != txt_205a_comm_name[i]->value())
173 return true;
174 if (s205a_comm_info[i] != txt_205a_comm_info[i]->value())
175 return true;
176 }
177 return false;
178 }
179
update_205afields()180 void update_205afields()
181 {
182 s205a_incident = txt_205a_incident->value();
183 s205a_date_fm = txt_205a_date_fm->value();
184 s205a_time_fm = txt_205a_time_fm->value();
185 s205a_date_to = txt_205a_date_to->value();
186 s205a_time_to = txt_205a_time_to->value();
187 s205a_prepared_by = txt_205a_prepared_by->value();
188 s205a_preparer_position = txt_205a_preparer_position->value();
189 s205a_preparer_date_time = txt_205a_preparer_date_time->value();
190 for (int i = 0; i < 32; i++) {
191 s205a_comm_position[i] = txt_205a_comm_position[i]->value();
192 s205a_comm_name[i] = txt_205a_comm_name[i]->value();
193 s205a_comm_info[i] = txt_205a_comm_info[i]->value();
194 }
195 }
196
update_205aform()197 void update_205aform()
198 {
199 txt_205a_incident->value(s205a_incident.c_str());
200 txt_205a_date_fm->value(s205a_date_fm.c_str());
201 txt_205a_time_fm->value(s205a_time_fm.c_str());
202 txt_205a_date_to->value(s205a_date_to.c_str());
203 txt_205a_time_to->value(s205a_time_to.c_str());
204 txt_205a_prepared_by->value(s205a_prepared_by.c_str());
205 txt_205a_preparer_position->value(s205a_preparer_position.c_str());
206 txt_205a_preparer_date_time->value(s205a_preparer_date_time.c_str());
207
208 for (int i = 0; i < 32; i++) {
209 txt_205a_comm_position[i]->value(s205a_comm_position[i].c_str());
210 txt_205a_comm_name[i]->value(s205a_comm_name[i].c_str());
211 txt_205a_comm_info[i]->value(s205a_comm_info[i].c_str());
212 }
213 }
214
clear_205a_form()215 void clear_205a_form()
216 {
217 clear_205afields();
218 update_205aform();
219 }
220
ics205a_nn(string & subst,int n)221 string &ics205a_nn(string & subst, int n)
222 {
223 static string garbage = "#$^*!";
224 static string ics;
225 ics.clear();
226 ics = subst;
227 size_t pos = ics.find("[");
228 if (pos == string::npos) return garbage;
229 pos++;
230 if (n < 10)
231 ics[pos] = '0' + n;
232 else {
233 ics[pos] = n > 29 ? '3' : n > 19 ? '2' : '1';
234 ics[pos+1] = '0' + n % 10;
235 ics[pos+2] = ']';
236 ics += ':';
237 }
238 return ics;
239 }
240
make_buff205a(bool compress=false)241 void make_buff205a(bool compress = false)
242 {
243 string mbuff;
244 mbuff.clear();
245 mbuff.append( lineout( ics205a_incident, s205a_incident ) );
246 mbuff.append( lineout( ics205a_date_fm, s205a_date_fm ) );
247 mbuff.append( lineout( ics205a_time_fm, s205a_time_fm ) );
248 mbuff.append( lineout( ics205a_date_to, s205a_date_to ) );
249 mbuff.append( lineout( ics205a_time_to, s205a_time_to ) );
250 mbuff.append( lineout( ics205a_prepared_by, s205a_prepared_by ) );
251 mbuff.append( lineout( ics205a_preparer_position, s205a_preparer_position ) );
252 mbuff.append( lineout( ics205a_preparer_date_time, s205a_preparer_date_time ) );
253
254 for (int i = 0; i < 32; i++) {
255 mbuff.append( lineout( ics205a_nn( ics205a_comm_position, i ), s205a_comm_position[i] ) );
256 mbuff.append( lineout( ics205a_nn( ics205a_comm_name, i ), s205a_comm_name[i] ) );
257 mbuff.append( lineout( ics205a_nn( ics205a_comm_info, i ), s205a_comm_info[i] ) );
258 }
259 if (compress) compress_maybe(mbuff);
260 buff205a.append(mbuff);
261 }
262
read_205a_buffer(string data)263 void read_205a_buffer(string data)
264 {
265 clear_205afields();
266 read_header(data);
267
268 s205a_incident = findstr( data, ics205a_incident );
269 s205a_date_fm = findstr( data, ics205a_date_fm );
270 s205a_time_fm = findstr( data, ics205a_time_fm );
271 s205a_date_to = findstr( data, ics205a_date_to );
272 s205a_time_to = findstr( data, ics205a_time_to );
273 s205a_prepared_by = findstr( data, ics205a_prepared_by );
274 s205a_preparer_position = findstr( data, ics205a_preparer_position );
275 s205a_preparer_date_time = findstr( data, ics205a_preparer_date_time );
276
277 for (int i = 0; i < 32; i++) {
278 s205a_comm_position[i] = findstr( data, ics205a_nn( ics205a_comm_position, i ) );
279 s205a_comm_name[i] = findstr( data, ics205a_nn( ics205a_comm_name, i ) );
280 s205a_comm_info[i] = findstr( data, ics205a_nn( ics205a_comm_info, i ) );
281 }
282
283 update_205aform();
284 }
285
cb_205a_new()286 void cb_205a_new()
287 {
288 if (check_205afields()) {
289 if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 1) {
290 update_header(CHANGED);
291 cb_205a_save();
292 }
293 }
294 clear_205a_form();
295 clear_header();
296 def_205a_filename = ICS_msg_dir;
297 def_205a_filename.append("new").append(F205A_EXT);
298 show_filename(def_205a_filename);
299 using_ics205a_template = false;
300 }
301
cb_205a_import()302 void cb_205a_import()
303 {
304 fl_alert2("Not implemented");
305 }
306
cb_205a_export()307 void cb_205a_export()
308 {
309 fl_alert2("Not implemented");
310 }
311
cb_205a_wrap_import(string wrapfilename,string inpbuffer)312 void cb_205a_wrap_import(string wrapfilename, string inpbuffer)
313 {
314 clear_205a_form();
315 read_205a_buffer(inpbuffer);
316 def_205a_filename = ICS_msg_dir;
317 def_205a_filename.append(wrapfilename);
318 show_filename(def_205a_filename);
319 using_ics205a_template = false;
320 }
321
eval_205a_fsize()322 int eval_205a_fsize()
323 {
324 Ccrc16 chksum;
325 evalstr.assign("[WRAP:beg][WRAP:lf][WRAP:fn ");
326 evalstr.append(base_205a_filename).append("]");
327 update_205afields();
328 update_header(FROM);
329 evalstr.append(header("<ics205a>"));
330 buff205a.clear();
331 make_buff205a(true);
332 if (buff205a.empty()) return 0;
333 compress_maybe( buff205a );
334 evalstr.append( buff205a );
335 evalstr.append("[WRAP:chksum ").append(chksum.scrc16(evalstr)).append("][WRAP:end]");
336 return evalstr.length();
337 }
338
cb_205a_wrap_export()339 void cb_205a_wrap_export()
340 {
341 if (check_205afields()) {
342 if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 0)
343 return;
344 update_header(CHANGED);
345 }
346 update_205afields();
347
348 if (base_205a_filename == string("new").append(F205A_EXT) ||
349 base_205a_filename == string("default").append(F205A_EXT) )
350 if (!cb_205a_save_as()) return;
351
352 string wrapfilename = WRAP_send_dir;
353 wrapfilename.append(base_205a_filename);
354 wrapfilename.append(".wrap");
355 const char *p = FSEL::saveas(
356 "Save as wrap file",
357 "Wrap file\t*.{wrap,WRAP}",
358 wrapfilename.c_str());
359 if (p) {
360 string pext = fl_filename_ext(p);
361 wrapfilename = p;
362 update_header(FROM);
363 buff205a.assign(header("<ics205a>"));
364 make_buff205a(true);
365 export_wrapfile(base_205a_filename, wrapfilename, buff205a, pext != ".wrap");
366 write_205a(def_205a_filename);
367 }
368 }
369
cb_205a_wrap_autosend()370 void cb_205a_wrap_autosend()
371 {
372 if (check_205afields()) {
373 if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 0)
374 return;
375 update_header(CHANGED);
376 }
377 update_205afields();
378
379 if (base_205a_filename == string("new").append(F205A_EXT) ||
380 base_205a_filename == string("default").append(F205A_EXT) )
381 cb_205a_save_as();
382
383 update_header(FROM);
384 buff205a.assign(header("<ics205a>"));
385 make_buff205a(true);
386
387 xfr_via_socket(base_205a_filename, buff205a);
388 write_205a(def_205a_filename);
389 }
390
cb_205a_load_template()391 void cb_205a_load_template()
392 {
393 string def_205a_filename = def_205a_TemplateName;
394 const char *p = FSEL::select(
395 "Open template file",
396 string("Template file\t*").append(F205A_EXT).c_str(),
397 def_205a_filename.c_str());
398 if (p) {
399 clear_205a_form();
400 read_data_file(p);
401 def_205a_TemplateName = p;
402 show_filename(def_205a_TemplateName);
403 using_ics205a_template = true;
404 }
405 }
406
cb_205a_save_template()407 void cb_205a_save_template()
408 {
409 if (!using_ics205a_template) {
410 cb_205a_save_as_template();
411 return;
412 }
413 string def_205a_filename = def_205a_TemplateName;
414 const char *p = FSEL::saveas(
415 "Save template file",
416 string("Template file\t*").append(T205A_EXT).c_str(),
417 def_205a_filename.c_str());
418 if (p) {
419 clear_header();
420 make_buff205a();
421 write_205a(p);
422 }
423 }
424
cb_205a_save_as_template()425 void cb_205a_save_as_template()
426 {
427 string def_205a_filename = def_205a_TemplateName;
428 const char *p = FSEL::saveas(
429 "Save as template file",
430 string("Template file\t*").append(T205A_EXT).c_str(),
431 def_205a_filename.c_str());
432 if (p) {
433 const char *pext = fl_filename_ext(p);
434 def_205a_TemplateName = p;
435 if (strlen(pext) == 0) def_205a_TemplateName.append(T205A_EXT);
436 remove_spaces_from_filename(def_205a_TemplateName);
437 clear_header();
438 make_buff205a();
439 write_205a(def_205a_TemplateName);
440 show_filename(def_205a_TemplateName);
441 using_ics205a_template = true;
442 }
443 }
444
cb_205a_open()445 void cb_205a_open()
446 {
447 const char *p = FSEL::select(
448 _("Open data file"),
449 string("ICS-205a\t*").append(F205A_EXT).c_str(),
450 def_205a_filename.c_str());
451 if (!p) return;
452 if (strlen(p) == 0) return;
453 clear_205a_form();
454 read_data_file(p);
455 using_ics205a_template = false;
456 def_205a_filename = p;
457 show_filename(def_205a_filename);
458 }
459
write_205a(string s)460 void write_205a(string s)
461 {
462 FILE *file205a = fopen(s.c_str(), "w");
463 if (!file205a) return;
464
465 fwrite(buff205a.c_str(), buff205a.length(), 1, file205a);
466 fclose(file205a);
467 }
468
cb_205a_save_as()469 bool cb_205a_save_as()
470 {
471 const char *p;
472 string newfilename;
473
474 string name = named_file();
475 if (!name.empty()) {
476 name.append(F205A_EXT);
477 newfilename = ICS_msg_dir;
478 newfilename.append(name);
479 } else
480 newfilename = def_205a_filename;
481
482 p = FSEL::saveas(
483 _("Save data file"),
484 string("ICS-205a\t*").append(F205A_EXT).c_str(),
485 newfilename.c_str());
486
487 if (!p) return false;
488 if (strlen(p) == 0) return false;
489
490 if (progStatus.sernbr_fname) update_sernbr();
491
492 const char *pext = fl_filename_ext(p);
493 def_205a_filename = p;
494 if (strlen(pext) == 0) def_205a_filename.append(F205A_EXT);
495
496 remove_spaces_from_filename(def_205a_filename);
497 update_205afields();
498 update_header(NEW);
499 buff205a.assign(header("<ics205a>"));
500 make_buff205a();
501 write_205a(def_205a_filename);
502
503 using_ics205a_template = false;
504 show_filename(def_205a_filename);
505 return true;
506 }
507
cb_205a_save()508 void cb_205a_save()
509 {
510 if (base_205a_filename == string("new").append(F205A_EXT) ||
511 base_205a_filename == string("default").append(F205A_EXT) ||
512 using_ics205a_template == true) {
513 cb_205a_save_as();
514 return;
515 }
516 if (check_205afields()) update_header(CHANGED);
517 update_205afields();
518 buff205a.assign(header("<ics205a>"));
519 make_buff205a();
520 write_205a(def_205a_filename);
521 using_ics205a_template = false;
522 }
523
cb_205a_html()524 void cb_205a_html()
525 {
526 string fname_name = fl_filename_name(def_205a_filename.c_str());
527 size_t p = fname_name.rfind('.');
528 if (p != string::npos) fname_name.erase(p);
529
530 string ics205a_fname = ICS_dir;
531 ics205a_fname.append(fname_name);
532 ics205a_fname.append(".html");
533
534 string html_text = "";
535 string empty = "<br>";
536
537 update_205afields();
538 string form205a = ics205a_html_template;
539
540 replacestr(form205a, TITLE, fname_name);
541 replacestr(form205a, ics205a_incident, s205a_incident );
542 replacestr(form205a, ics205a_date_fm, s205a_date_fm );
543 replacestr(form205a, ics205a_time_fm, s205a_time_fm );
544 replacestr(form205a, ics205a_date_to, s205a_date_to );
545 replacestr(form205a, ics205a_time_to, s205a_time_to );
546 replacestr(form205a, ics205a_prepared_by, s205a_prepared_by );
547 replacestr(form205a, ics205a_preparer_position, s205a_preparer_position );
548 replacestr(form205a, ics205a_preparer_date_time, s205a_preparer_date_time );
549
550 for (int i = 0; i < 32; i++) {
551 replacestr(form205a, ics205a_nn( ics205a_comm_position, i ),
552 s205a_comm_position[i].empty() ? empty : s205a_comm_position[i] );
553 replacestr(form205a, ics205a_nn( ics205a_comm_name, i ),
554 s205a_comm_name[i].empty() ? empty : s205a_comm_name[i] );
555 replacestr(form205a, ics205a_nn( ics205a_comm_info, i ),
556 s205a_comm_info[i].empty() ? empty : s205a_comm_info[i] );
557 }
558
559 FILE *file205a = fopen(ics205a_fname.c_str(), "w");
560 fprintf(file205a,"%s", form205a.c_str());
561 fclose(file205a);
562
563 open_url(ics205a_fname.c_str());
564 }
565
cb_205a_msg_type()566 void cb_205a_msg_type()
567 {
568 if (tabs_msg_type->value() == tab_ics205a ) {
569 tab_ics205a_type->value(tab_205a_1);
570 show_filename(def_205a_filename);
571 }
572 }
573
cb_205a_textout()574 void cb_205a_textout()
575 {
576 string ics205a_fname = ICS_dir;
577 ics205a_fname.append("ics205a.txt");
578
579 update_205afields();
580 string form205a = ics205a_text_template;
581
582 replacestr(form205a, ics205a_incident, s205a_incident );
583 replacestr(form205a, ics205a_date_fm, s205a_date_fm );
584 replacestr(form205a, ics205a_time_fm, s205a_time_fm );
585 replacestr(form205a, ics205a_date_to, s205a_date_to );
586 replacestr(form205a, ics205a_time_to, s205a_time_to );
587 replacestr(form205a, ics205a_prepared_by, s205a_prepared_by );
588 replacestr(form205a, ics205a_preparer_position, s205a_preparer_position );
589 replacestr(form205a, ics205a_preparer_date_time, s205a_preparer_date_time );
590
591 for (int i = 0; i < 32; i++) {
592 replacestr(form205a, ics205a_nn( ics205a_comm_position, i ), s205a_comm_position[i] );
593 replacestr(form205a, ics205a_nn( ics205a_comm_name, i ), s205a_comm_name[i] );
594 replacestr(form205a, ics205a_nn( ics205a_comm_info, i ), s205a_comm_info[i] );
595 }
596
597 FILE *file205a = fopen(ics205a_fname.c_str(), "w");
598 fprintf(file205a,"%s", form205a.c_str());
599 fclose(file205a);
600
601 open_url(ics205a_fname.c_str());
602 }
603