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