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 309 field variables and template variables
77 // ---------------------------------------------------------------------
78
79 string ics309_incident = ":inc:";
80 string ics309_date_fm = ":dfm:";
81 string ics309_time_fm = ":tfm:";
82 string ics309_date_to = ":dto:";
83 string ics309_time_to = ":tto:";
84 string ics309_prepared_by = ":pre:";
85 string ics309_preparer_date_time = ":dtm:";
86 string ics309_radio_net = ":net:";
87 string ics309_radio_operator = ":opr:";
88
89 string ics309_comm_msg = ":msg[n]:"; // 34
90 string ics309_comm_to = ":to[n]:"; // 34
91 string ics309_comm_from = ":fm[n]:"; // 34
92 string ics309_comm_time = ":tm[n]:"; // 34
93
94 string s309_incident;
95 string s309_date_fm;
96 string s309_time_fm;
97 string s309_date_to;
98 string s309_time_to;
99 string s309_prepared_by;
100 string s309_preparer_date_time;
101 string s309_radio_net;
102 string s309_radio_operator;
103
104 string s309_comm_time[34];
105 string s309_comm_from[34];
106 string s309_comm_msg[34];
107 string s309_comm_to[34];
108
109 // =====================================================================
110
111 string buff309;
112 string def_309_filename = "";
113 string base_309_filename = "";
114 string def_309_TemplateName = "";
115 bool using_ics309_template = false;
116
cb_309_set_date_fm()117 void cb_309_set_date_fm()
118 {
119 txt_309_date_fm->value(szDate(progStatus.dtformat));
120 }
121
cb_309_set_time_fm()122 void cb_309_set_time_fm()
123 {
124 txt_309_time_fm->value(szTime(progStatus.UTC));
125 }
126
cb_309_set_date_to()127 void cb_309_set_date_to()
128 {
129 txt_309_date_to->value(szDate(progStatus.dtformat));
130 }
131
cb_309_set_time_to()132 void cb_309_set_time_to()
133 {
134 txt_309_time_to->value(szTime(progStatus.UTC));
135 }
136
cb_309_set_date_time()137 void cb_309_set_date_time()
138 {
139 string dt = szDate(progStatus.dtformat);
140 dt.append(", ").append(szTime(progStatus.UTC));
141 txt_309_preparer_date_time->value(dt.c_str());
142 }
143
clear_309fields()144 void clear_309fields()
145 {
146 s309_incident.clear();
147 s309_date_fm.clear();
148 s309_time_fm.clear();
149 s309_date_to.clear();
150 s309_time_to.clear();
151 s309_prepared_by.clear();
152 s309_preparer_date_time.clear();
153 s309_radio_net.clear();
154 s309_radio_operator.clear();
155
156 for (int i = 0; i < 34; i++) {
157 s309_comm_msg[i].clear();
158 s309_comm_to[i].clear();
159 s309_comm_from[i].clear();
160 }
161 }
162
check_309fields()163 bool check_309fields()
164 {
165 if (s309_incident != txt_309_incident->value())
166 return true;
167 if (s309_date_fm != txt_309_date_fm->value())
168 return true;
169 if (s309_time_fm != txt_309_time_fm->value())
170 return true;
171 if (s309_date_to != txt_309_date_to->value())
172 return true;
173 if (s309_time_to != txt_309_time_to->value())
174 return true;
175 if (s309_prepared_by != txt_309_prepared_by->value())
176 return true;
177 if (s309_radio_net != txt_309_radio_net->value())
178 return true;
179 if (s309_radio_operator != txt_309_radio_operator->value())
180 return true;
181 if (s309_preparer_date_time != txt_309_preparer_date_time->value())
182 return true;
183 for (int i = 0; i < 34; i++) {
184 if (s309_comm_time[i] != txt_309_comm_time[i]->value())
185 return true;
186 if (s309_comm_msg[i] != txt_309_comm_msg[i]->value())
187 return true;
188 if (s309_comm_to[i] != txt_309_comm_to[i]->value())
189 return true;
190 if (s309_comm_from[i] != txt_309_comm_from[i]->value())
191 return true;
192 }
193 return false;
194 }
195
update_309fields()196 void update_309fields()
197 {
198 s309_incident = txt_309_incident->value();
199 s309_date_fm = txt_309_date_fm->value();
200 s309_time_fm = txt_309_time_fm->value();
201 s309_date_to = txt_309_date_to->value();
202 s309_time_to = txt_309_time_to->value();
203 s309_prepared_by = txt_309_prepared_by->value();
204 s309_radio_net = txt_309_radio_net->value();
205 s309_radio_operator = txt_309_radio_operator->value();
206 s309_preparer_date_time = txt_309_preparer_date_time->value();
207 for (int i = 0; i < 34; i++) {
208 s309_comm_time[i] = txt_309_comm_time[i]->value();
209 s309_comm_from[i] = txt_309_comm_from[i]->value();
210 s309_comm_to[i] = txt_309_comm_to[i]->value();
211 s309_comm_msg[i] = txt_309_comm_msg[i]->value();
212 }
213 }
214
update_309form()215 void update_309form()
216 {
217 txt_309_incident->value(s309_incident.c_str());
218 txt_309_date_fm->value(s309_date_fm.c_str());
219 txt_309_time_fm->value(s309_time_fm.c_str());
220 txt_309_date_to->value(s309_date_to.c_str());
221 txt_309_time_to->value(s309_time_to.c_str());
222 txt_309_prepared_by->value(s309_prepared_by.c_str());
223 txt_309_radio_net->value(s309_radio_net.c_str());
224 txt_309_radio_operator->value(s309_radio_operator.c_str());
225 txt_309_preparer_date_time->value(s309_preparer_date_time.c_str());
226
227 for (int i = 0; i < 34; i++) {
228 txt_309_comm_time[i]->value(s309_comm_time[i].c_str());
229 txt_309_comm_to[i]->value(s309_comm_to[i].c_str());
230 txt_309_comm_from[i]->value(s309_comm_from[i].c_str());
231 txt_309_comm_msg[i]->value(s309_comm_msg[i].c_str());
232 }
233 }
234
clear_309_form()235 void clear_309_form()
236 {
237 clear_309fields();
238 update_309form();
239 }
240
ics309_nn(string & subst,int n)241 string &ics309_nn(string & subst, int n)
242 {
243 static string garbage = "#$^*!";
244 static string ics;
245 ics.clear();
246 ics = subst;
247 size_t pos = ics.find("[");
248 if (pos == string::npos) return garbage;
249 pos++;
250 if (n < 10)
251 ics[pos] = '0' + n;
252 else {
253 ics[pos] = n > 29 ? '3' : n > 19 ? '2' : '1';
254 ics[pos+1] = '0' + n % 10;
255 ics[pos+2] = ']';
256 ics += ':';
257 }
258 return ics;
259 }
260
make_buff309(bool compress=false)261 void make_buff309(bool compress = false)
262 {
263 string mbuff;
264 mbuff.clear();
265 mbuff.append( lineout( ics309_incident, s309_incident ) );
266 mbuff.append( lineout( ics309_date_fm, s309_date_fm ) );
267 mbuff.append( lineout( ics309_time_fm, s309_time_fm ) );
268 mbuff.append( lineout( ics309_date_to, s309_date_to ) );
269 mbuff.append( lineout( ics309_time_to, s309_time_to ) );
270 mbuff.append( lineout( ics309_prepared_by, s309_prepared_by ) );
271 mbuff.append( lineout( ics309_preparer_date_time, s309_preparer_date_time ) );
272 mbuff.append( lineout( ics309_radio_net, s309_radio_net ) );
273 mbuff.append( lineout( ics309_radio_operator, s309_radio_operator ) );
274
275 for (int i = 0; i < 34; i++) {
276 mbuff.append( lineout( ics309_nn( ics309_comm_time, i ), s309_comm_time[i] ) );
277 mbuff.append( lineout( ics309_nn( ics309_comm_to, i ), s309_comm_to[i] ) );
278 mbuff.append( lineout( ics309_nn( ics309_comm_from, i ), s309_comm_from[i] ) );
279 mbuff.append( lineout( ics309_nn( ics309_comm_msg, i ), s309_comm_msg[i] ) );
280 }
281 if (compress) compress_maybe(mbuff);
282 buff309.append(mbuff);
283 }
284
read_309_buffer(string data)285 void read_309_buffer(string data)
286 {
287 clear_309fields();
288 read_header(data);
289
290 s309_incident = findstr( data, ics309_incident );
291 s309_date_fm = findstr( data, ics309_date_fm );
292 s309_time_fm = findstr( data, ics309_time_fm );
293 s309_date_to = findstr( data, ics309_date_to );
294 s309_time_to = findstr( data, ics309_time_to );
295 s309_prepared_by = findstr( data, ics309_prepared_by );
296 s309_preparer_date_time = findstr( data, ics309_preparer_date_time );
297 s309_radio_net = findstr( data, ics309_radio_net );
298 s309_radio_operator = findstr( data, ics309_radio_operator );
299
300 for (int i = 0; i < 34; i++) {
301 s309_comm_time[i] = findstr( data, ics309_nn( ics309_comm_time, i ) );
302 s309_comm_to[i] = findstr( data, ics309_nn( ics309_comm_to, i ) );
303 s309_comm_from[i] = findstr( data, ics309_nn( ics309_comm_from, i ) );
304 s309_comm_msg[i] = findstr( data, ics309_nn( ics309_comm_msg, i ) );
305 }
306
307 update_309form();
308 }
309
cb_309_new()310 void cb_309_new()
311 {
312 if (check_309fields()) {
313 if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 1) {
314 update_header(CHANGED);
315 cb_309_save();
316 }
317 }
318 clear_309_form();
319 clear_header();
320 def_309_filename = ICS_msg_dir;
321 def_309_filename.append("new").append(F309_EXT);
322 show_filename(def_309_filename);
323 using_ics309_template = false;
324 }
325
cb_309_import()326 void cb_309_import()
327 {
328 fl_alert2("Not implemented");
329 }
330
cb_309_export()331 void cb_309_export()
332 {
333 fl_alert2("Not implemented");
334 }
335
cb_309_wrap_import(string wrapfilename,string inpbuffer)336 void cb_309_wrap_import(string wrapfilename, string inpbuffer)
337 {
338 clear_309_form();
339 read_309_buffer(inpbuffer);
340 def_309_filename = ICS_msg_dir;
341 def_309_filename.append(wrapfilename);
342 show_filename(def_309_filename);
343 using_ics309_template = false;
344 }
345
eval_309_fsize()346 int eval_309_fsize()
347 {
348 Ccrc16 chksum;
349 evalstr.assign("[WRAP:beg][WRAP:lf][WRAP:fn ");
350 evalstr.append(base_309_filename).append("]");
351 update_309fields();
352 update_header(FROM);
353 evalstr.append(header("<ics309>"));
354 buff309.clear();
355 make_buff309(true);
356 if (buff309.empty()) return 0;
357 compress_maybe( buff309 );
358 evalstr.append( buff309 );
359 evalstr.append("[WRAP:chksum ").append(chksum.scrc16(evalstr)).append("][WRAP:end]");
360 return evalstr.length();
361 }
362
cb_309_wrap_export()363 void cb_309_wrap_export()
364 {
365 if (check_309fields()) {
366 if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 0)
367 return;
368 update_header(CHANGED);
369 }
370 update_309fields();
371
372 if (base_309_filename == string("new").append(F309_EXT) ||
373 base_309_filename == string("default").append(F309_EXT) )
374 if (!cb_309_save_as()) return;
375
376 string wrapfilename = WRAP_send_dir;
377 wrapfilename.append(base_309_filename);
378 wrapfilename.append(".wrap");
379 const char *p = FSEL::saveas(
380 "Save as wrap file",
381 "Wrap file\t*.{wrap,WRAP}",
382 wrapfilename.c_str());
383 if (p) {
384 string pext = fl_filename_ext(p);
385 wrapfilename = p;
386 update_header(FROM);
387 buff309.assign(header("<ics309>"));
388 make_buff309(true);
389 export_wrapfile(base_309_filename, wrapfilename, buff309, pext != ".wrap");
390 write_309(def_309_filename);
391 }
392 }
393
cb_309_wrap_autosend()394 void cb_309_wrap_autosend()
395 {
396 if (check_309fields()) {
397 if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 0)
398 return;
399 update_header(CHANGED);
400 }
401 update_309fields();
402
403 if (base_309_filename == string("new").append(F309_EXT) ||
404 base_309_filename == string("default").append(F309_EXT) )
405 cb_309_save_as();
406
407 update_header(FROM);
408 buff309.assign(header("<ics309>"));
409 make_buff309(true);
410
411 xfr_via_socket(base_309_filename, buff309);
412 write_309(def_309_filename);
413 }
414
cb_309_load_template()415 void cb_309_load_template()
416 {
417 string def_309_filename = def_309_TemplateName;
418 const char *p = FSEL::select(
419 "Open template file",
420 string("Template file\t*").append(T309_EXT).c_str(),
421 def_309_filename.c_str());
422 if (p) {
423 clear_309_form();
424 read_data_file(p);
425 def_309_TemplateName = p;
426 show_filename(def_309_TemplateName);
427 using_ics309_template = true;
428 }
429 }
430
cb_309_save_template()431 void cb_309_save_template()
432 {
433 if (!using_ics309_template) {
434 cb_309_save_as_template();
435 return;
436 }
437 string def_309_filename = def_309_TemplateName;
438 const char *p = FSEL::saveas(
439 "Save template file",
440 string("Template file\t*").append(T309_EXT).c_str(),
441 def_309_filename.c_str());
442 if (p) {
443 update_header(CHANGED);
444 buff309.assign(header("<ics309>"));
445 make_buff309();
446 write_309(p);
447 }
448 }
449
cb_309_save_as_template()450 void cb_309_save_as_template()
451 {
452 string def_309_filename = def_309_TemplateName;
453 const char *p = FSEL::saveas(
454 "Save as template file",
455 string("Template file\t*").append(T309_EXT).c_str(),
456 def_309_filename.c_str());
457 if (p) {
458 const char *pext = fl_filename_ext(p);
459 def_309_TemplateName = p;
460 if (strlen(pext) == 0) def_309_TemplateName.append(T309_EXT);
461 remove_spaces_from_filename(def_309_TemplateName);
462 clear_header();
463 update_header(CHANGED);
464 buff309.assign(header("<ics309>"));
465 make_buff309();
466 write_309(def_309_TemplateName);
467 show_filename(def_309_TemplateName);
468 using_ics309_template = true;
469 }
470 }
471
cb_309_open()472 void cb_309_open()
473 {
474 const char *p = FSEL::select(
475 _("Open data file"),
476 string("ICS-309\t*").append(F309_EXT).c_str(),
477 def_309_filename.c_str());
478 if (!p) return;
479 if (strlen(p) == 0) return;
480 clear_309_form();
481 read_data_file(p);
482 using_ics309_template = false;
483 def_309_filename = p;
484 show_filename(def_309_filename);
485 }
486
write_309(string s)487 void write_309(string s)
488 {
489 FILE *file309 = fopen(s.c_str(), "w");
490 if (!file309) return;
491
492 fwrite(buff309.c_str(), buff309.length(), 1, file309);
493 fclose(file309);
494 }
495
cb_309_save_as()496 bool cb_309_save_as()
497 {
498 const char *p;
499 string newfilename;
500
501 string name = named_file();
502 if (!name.empty()) {
503 name.append(F309_EXT);
504 newfilename = ICS_msg_dir;
505 newfilename.append(name);
506 } else
507 newfilename = def_309_filename;
508
509 p = FSEL::saveas(
510 _("Save data file"),
511 string("ICS-309\t*").append(F309_EXT).c_str(),
512 newfilename.c_str());
513
514 if (!p) return false;
515 if (strlen(p) == 0) return false;
516
517 if (progStatus.sernbr_fname) update_sernbr();
518
519 const char *pext = fl_filename_ext(p);
520 def_309_filename = p;
521 if (strlen(pext) == 0) def_309_filename.append(F309_EXT);
522
523 remove_spaces_from_filename(def_309_filename);
524 update_309fields();
525 update_header(NEW);
526 buff309.assign(header("<ics309>"));
527 make_buff309();
528 write_309(def_309_filename);
529
530 using_ics309_template = false;
531 show_filename(def_309_filename);
532 return true;
533 }
534
cb_309_save()535 void cb_309_save()
536 {
537 if (base_309_filename == string("new").append(F309_EXT) ||
538 base_309_filename == string("default").append(F309_EXT) ||
539 using_ics309_template == true) {
540 cb_309_save_as();
541 return;
542 }
543 if (check_309fields()) update_header(CHANGED);
544 update_309fields();
545 buff309.assign(header("<ics309>"));
546 make_buff309();
547 write_309(def_309_filename);
548 using_ics309_template = false;
549 }
550
cb_309_html()551 void cb_309_html()
552 {
553 string fname_name = fl_filename_name(def_309_filename.c_str());
554 size_t p = fname_name.rfind('.');
555 if (p != string::npos) fname_name.erase(p);
556
557 string ics309_fname = ICS_dir;
558 ics309_fname.append(fname_name);
559 ics309_fname.append(".html");
560
561 string html_text = "";
562 string empty = "<br>";
563
564 update_309fields();
565 string form309 = ics309_html_template;
566
567 replacestr(form309, TITLE, fname_name);
568 replacestr(form309, ics309_incident, s309_incident );
569 replacestr(form309, ics309_date_fm, s309_date_fm );
570 replacestr(form309, ics309_time_fm, s309_time_fm );
571 replacestr(form309, ics309_date_to, s309_date_to );
572 replacestr(form309, ics309_time_to, s309_time_to );
573 replacestr(form309, ics309_prepared_by, s309_prepared_by );
574 replacestr(form309, ics309_preparer_date_time, s309_preparer_date_time );
575 replacestr(form309, ics309_radio_net, s309_radio_net );
576 replacestr(form309, ics309_radio_operator, s309_radio_operator );
577
578 for (int i = 0; i < 34; i++) {
579 replacestr(form309, ics309_nn( ics309_comm_time, i ),
580 s309_comm_time[i].empty() ? empty : s309_comm_time[i] );
581 replacestr(form309, ics309_nn( ics309_comm_to, i ),
582 s309_comm_to[i].empty() ? empty : s309_comm_to[i] );
583 replacestr(form309, ics309_nn( ics309_comm_from, i ),
584 s309_comm_from[i].empty() ? empty : s309_comm_from[i] );
585 replacestr(form309, ics309_nn( ics309_comm_msg, i ),
586 s309_comm_msg[i].empty() ? empty : s309_comm_msg[i] );
587 }
588
589 FILE *file309 = fopen(ics309_fname.c_str(), "w");
590 fprintf(file309,"%s", form309.c_str());
591 fclose(file309);
592
593 open_url(ics309_fname.c_str());
594 }
595
cb_309_msg_type()596 void cb_309_msg_type()
597 {
598 if (tabs_msg_type->value() == tab_ics309 ) {
599 tab_ics309_type->value(tab_309_1);
600 show_filename(def_309_filename);
601 }
602 }
603
cb_309_textout()604 void cb_309_textout()
605 {
606 string ics309_fname = ICS_dir;
607 ics309_fname.append("ics309.txt");
608
609 update_309fields();
610 string form309 = ics309_text_template;
611
612 replacestr(form309, ics309_incident, s309_incident );
613 replacestr(form309, ics309_date_fm, s309_date_fm );
614 replacestr(form309, ics309_time_fm, s309_time_fm );
615 replacestr(form309, ics309_date_to, s309_date_to );
616 replacestr(form309, ics309_time_to, s309_time_to );
617 replacestr(form309, ics309_prepared_by, s309_prepared_by );
618 replacestr(form309, ics309_preparer_date_time, s309_preparer_date_time );
619 replacestr(form309, ics309_radio_net, s309_radio_net );
620 replacestr(form309, ics309_radio_operator, s309_radio_operator );
621
622 for (int i = 0; i < 34; i++) {
623 replacestr(form309, ics309_nn( ics309_comm_time, i ), s309_comm_time[i] );
624 replacestr(form309, ics309_nn( ics309_comm_msg, i ), s309_comm_msg[i] );
625 replacestr(form309, ics309_nn( ics309_comm_to, i ), s309_comm_to[i] );
626 replacestr(form309, ics309_nn( ics309_comm_from, i ), s309_comm_from[i] );
627 }
628
629 FILE *file309 = fopen(ics309_fname.c_str(), "w");
630 fprintf(file309,"%s", form309.c_str());
631 fclose(file309);
632
633 open_url(ics309_fname.c_str());
634 }
635
ics309_csv(Fl_Widget * w,void * d)636 void ics309_csv(Fl_Widget *w, void *d)
637 {
638 string csv_fname = ICS_dir;
639 csv_fname.append("ics309.csv");
640
641 const char *p;
642
643 p = FSEL::saveas(_("Save csv file"), "ICS-309\t*.csv",
644 csv_fname.c_str());
645
646 if (!p) return;
647 if (strlen(p) == 0) return;
648
649 csv_fname = p;
650
651 update_309fields();
652
653 string cvs_text;
654 cvs_text.assign("Incident,Start_Date,Start_Time,End_Date,End_Time,Preparer,Prepared_Date,Radio_Net,Radio_operator\n");
655 cvs_text.append("\"").append(s309_incident).append("\",");
656 cvs_text.append("\"").append(s309_date_fm).append("\",");
657 cvs_text.append("\"").append(s309_time_fm).append("\",");
658 cvs_text.append("\"").append(s309_date_to).append("\",");
659 cvs_text.append("\"").append(s309_time_to).append("\",");
660 cvs_text.append("\"").append(s309_prepared_by).append("\",");
661 cvs_text.append("\"").append(s309_preparer_date_time).append("\",");
662 cvs_text.append("\"").append(s309_radio_net).append("\",");
663 cvs_text.append("\"").append(s309_radio_operator).append("\"\n");
664 cvs_text.append("\n");
665 cvs_text.append("COMM_TIME,COMM_TO,COMM_FM,COMM_MSG\n");
666
667 for (int i = 0; i < 34; i++) {
668 cvs_text.append("\"").append(s309_comm_time[i]).append("\",");
669 cvs_text.append("\"").append(s309_comm_to[i]).append("\",");
670 cvs_text.append("\"").append(s309_comm_from[i]).append("\",");
671 cvs_text.append("\"").append(s309_comm_msg[i]).append("\"\n");
672 }
673
674 FILE *csv_file = fopen(csv_fname.c_str(), "w");
675 if (!csv_file) return;
676 fprintf(csv_file,"%s", cvs_text.c_str());
677 fclose(csv_file);
678 }
679