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 string iaru_base_filename = "";
76 string iaru_def_filename = "";
77 string iaru_def_template_name = "";
78 
79 static string iaru_buffer;
80 
81 // iaru iaru_fields
82 
83 const char *iaru_s_prec[] = {"ROUTINE", "PRIORITY", "EMERGENCY"};
84 const char iaru_prec_items[] = "ROUTINE|PRIORITY|EMERGENCY";
85 
86 // new tag strings
87 
88 string iaru_nbr		= ":nbr:";		// 0
89 string iaru_prec	= ":prec:";		// 1
90 string iaru_station	= ":sta:";		// 2
91 string iaru_check	= ":ck:";		// 3
92 string iaru_orig	= ":org:";		// 4
93 
94 string iaru_d1		= ":d1:";		// 5
95 string iaru_t1		= ":t1:";		// 6
96 
97 string iaru_to		= ":to:";		// 7
98 string iaru_msg		= ":msg:";		// 8
99 string iaru_fm		= ":fm:";		// 9
100 
101 string iaru_rcv_fm	= ":rcv:";		// 10
102 string iaru_d2		= ":d2:";		// 11
103 string iaru_t2		= ":t2:";		// 12
104 
105 string iaru_sent_to	= ":sto:";		// 13
106 string iaru_d3		= ":d3:";		// 14
107 string iaru_t3		= ":t3:";		// 15
108 
109 FIELD iaru_fields[] = {
110 { iaru_nbr,		"", (void **)&iaru_txt_nbr,			't' },	// 0
111 { iaru_prec,	"0", (void **)&iaru_sel_prec,		's' },	// 1
112 { iaru_station,	"", (void **)&iaru_txt_station,		't' },	// 2
113 { iaru_check,	"", (void **)&iaru_txt_check,		't' },	// 3
114 { iaru_orig,	"", (void **)&iaru_txt_orig,		't' },	// 4
115 { iaru_d1,		"", (void **)&iaru_txt_d1,			't' },	// 5
116 { iaru_t1,		"", (void **)&iaru_txt_t1,			't' },	// 6
117 { iaru_to,		"", (void **)&iaru_txt_to,			't' },	// 7
118 { iaru_msg,		"", (void **)&iaru_txt_msg,			'e' },	// 8
119 { iaru_fm,		"", (void **)&iaru_txt_fm,			't' },	// 9
120 { iaru_rcv_fm,	"", (void **)&iaru_txt_rcv_fm,		't' },	// 10
121 { iaru_d2,		"", (void **)&iaru_txt_d2,			't' },	// 11
122 { iaru_t2,		"", (void **)&iaru_txt_t2,			't' },	// 12
123 { iaru_sent_to,	"", (void **)&iaru_txt_sent_to,		't' },	// 113
124 { iaru_d3,		"", (void **)&iaru_txt_d3,			't' },	// 14
125 { iaru_t3,		"", (void **)&iaru_txt_t3,			't' }	// 15
126 
127 };
128 
129 bool iaru_using_template = false;
130 
131 int iaru_num_fields = sizeof(iaru_fields) / sizeof(FIELD);
132 
133 //======================================================================
134 
iaru_cb_set_d1()135 void iaru_cb_set_d1()
136 {
137 	iaru_txt_d1->value(szAbbrevDate());
138 }
139 
iaru_cb_set_t1()140 void iaru_cb_set_t1()
141 {
142 	iaru_txt_t1->value(szTime(progStatus.UTC <= 1 ? 0 : 2));
143 }
144 
iaru_cb_set_d2()145 void iaru_cb_set_d2()
146 {
147 	iaru_txt_d2->value(szAbbrevDate());
148 }
149 
iaru_cb_set_t2()150 void iaru_cb_set_t2()
151 {
152 	iaru_txt_t2->value(szTime(progStatus.UTC <= 1 ? 0 : 2));
153 }
154 
iaru_cb_set_d3()155 void iaru_cb_set_d3()
156 {
157 	iaru_txt_d3->value(szAbbrevDate());
158 }
159 
iaru_cb_set_t3()160 void iaru_cb_set_t3()
161 {
162 	iaru_txt_t3->value(szTime(progStatus.UTC <= 1 ? 0 : 2));
163 }
164 
iaru_cb_nbr(Fl_Widget * wdg)165 void iaru_cb_nbr(Fl_Widget *wdg)
166 {
167 	Fl_Input2 *inp = (Fl_Input2 *)wdg;
168 	string s = inp->value();
169 	for (size_t n = 0; n < s.length(); n++)
170 		if (!isdigit(s[n])) s.erase(n,1);
171 	strip_leading_zeros(s);
172 	inp->value(s.c_str());
173 }
174 
175 static char valid_input[] = "0123456789/ ABCDEFGHIJKLMNOPQRSTUVWXYZ\n";
176 
iaru_cb_filter_input(Fl_Widget * wdg)177 void iaru_cb_filter_input(Fl_Widget *wdg)
178 {
179 	Fl_Input2 *inp = (Fl_Input2 *)wdg;
180 	string s = inp->value();
181 	ucase(s);
182 	for (size_t n = 0; n < s.length(); n++)
183 		if (strchr(valid_input, s[n]) == NULL)
184 			s.erase(n,1);
185 	inp->value(s.c_str());
186 }
187 
iaru_clear_fields()188 void iaru_clear_fields()
189 {
190 	for (int i = 0; i < iaru_num_fields; i++)
191 		iaru_fields[i].f_data.clear();
192 }
193 
numeric(int n)194 static string numeric(int n)
195 {
196 	static char snum[12];
197 	snprintf(snum, sizeof(snum), "%d", n);
198 	return snum;
199 }
200 
iaru_set_choices()201 void iaru_set_choices() {
202 	iaru_sel_prec->clear();
203 	iaru_sel_prec->add(iaru_prec_items);
204 	iaru_sel_prec->index(0);
205 }
206 
iaru_check_fields()207 bool iaru_check_fields()
208 {
209 	for (int i = 0; i < iaru_num_fields; i++) {
210 		if (iaru_fields[i].w_type == 'd') {
211 			if (iaru_fields[i].f_data != ((Fl_DateInput *)(*iaru_fields[i].w))->value())
212 				return true;
213 		} else if (iaru_fields[i].w_type == 't') {
214 			if (iaru_fields[i].f_data != ((Fl_Input2 *)(*iaru_fields[i].w))->value())
215 				return true;
216 		} else if (iaru_fields[i].w_type == 's') {
217 			int choice = ((Fl_ListBox *)(*iaru_fields[i].w))->index();
218 			if (choice >= 0) {
219 				if (iaru_fields[i].f_data != numeric(choice))
220 					return true;
221 			}
222 		} else if (iaru_fields[i].w_type == 'e') {
223 			if (iaru_fields[i].f_data != ((FTextEdit *)(*iaru_fields[i].w))->buffer()->text())
224 				return true;
225 		} else if (iaru_fields[i].w_type == 'b') {
226 			string val = ((Fl_Button *)(*iaru_fields[i].w))->value() ? "T" : "F";
227 			if (iaru_fields[i].f_data != val)
228 				return true;
229 		}
230 	}
231 	return false;
232 }
233 
iaru_update_fields()234 void iaru_update_fields()
235 {
236 	for (int i = 0; i < iaru_num_fields; i++) {
237 		if (iaru_fields[i].w_type == 'd') {
238 			iaru_fields[i].f_data = ((Fl_DateInput *)(*iaru_fields[i].w))->value();
239 		} else if (iaru_fields[i].w_type == 't') {
240 			iaru_fields[i].f_data = ((Fl_Input2 *)(*iaru_fields[i].w))->value();
241 		} else if (iaru_fields[i].w_type == 's') {
242 			int choice = ((Fl_ListBox *)(*iaru_fields[i].w))->index();
243 			if (choice >= 0) {
244 				iaru_fields[i].f_data = numeric(choice);
245 			}
246 		} else if (iaru_fields[i].w_type == 'e') {
247 			iaru_fields[i].f_data = ((FTextEdit *)(*iaru_fields[i].w))->buffer()->text();
248 		} else if (iaru_fields[i].w_type == 'b') {
249 			string val = ((Fl_Button *)(*iaru_fields[i].w))->value() ? "T" : "F";
250 			iaru_fields[i].f_data = val;
251 		}
252 	}
253 }
254 
iaru_clear_form()255 void iaru_clear_form()
256 {
257 	iaru_clear_fields();
258 
259 	if (progStatus.rgnbr_fname)
260 		iaru_txt_nbr->value(progStatus.rgnbr.c_str());
261 	else
262 		iaru_txt_nbr->value("");
263 
264 	for (int i = 1; i < iaru_num_fields; i++)
265 		if (iaru_fields[i].w_type == 'd')
266 			((Fl_DateInput *)(*iaru_fields[i].w))->value("");
267 		else if (iaru_fields[i].w_type == 't')
268 			((Fl_Input2 *)(*iaru_fields[i].w))->value("");
269 		else if (iaru_fields[i].w_type == 's')
270 			((Fl_ListBox *)(*iaru_fields[i].w))->index(0);
271 		else if (iaru_fields[i].w_type == 'e')
272 			((FTextEdit *)(*iaru_fields[i].w))->clear();
273 		else if (iaru_fields[i].w_type == 'b')
274 			((Fl_Button *)(*iaru_fields[i].w))->value(0);
275 	iaru_update_fields();
276 }
277 
iaru_update_form()278 void iaru_update_form()
279 {
280 	for (int i = 0; i < iaru_num_fields; i++) {
281 		if (iaru_fields[i].w_type == 'd')
282 			((Fl_DateInput *)(*iaru_fields[i].w))->value(iaru_fields[i].f_data.c_str());
283 		else if (iaru_fields[i].w_type == 't')
284 			((Fl_Input2 *)(*iaru_fields[i].w))->value(iaru_fields[i].f_data.c_str());
285 		else if (iaru_fields[i].w_type == 's')
286 			((Fl_ListBox *)(*iaru_fields[i].w))->index(atoi(iaru_fields[i].f_data.c_str()));
287 		else if (iaru_fields[i].w_type == 'e') {
288 			((FTextEdit *)(*iaru_fields[i].w))->clear();
289 			((FTextEdit *)(*iaru_fields[i].w))->add(iaru_fields[i].f_data.c_str());
290 		} else if (iaru_fields[i].w_type == 'b')
291 			((Fl_Button *)(*iaru_fields[i].w))->value(iaru_fields[i].f_data == "T" ? 1 : 0);
292 	}
293 }
294 
iaru_make_buffer(bool compress=false)295 void iaru_make_buffer(bool compress = false)
296 {
297 	string mbuff;
298 	mbuff.clear();
299 	for (int i = 0; i < iaru_num_fields; i++)
300 		mbuff.append( lineout( iaru_fields[i].f_type, iaru_fields[i].f_data ) );
301 	if (compress) compress_maybe(mbuff);
302 	iaru_buffer.append(mbuff);
303 }
304 
iaru_read_buffer(string data)305 void iaru_read_buffer(string data)
306 {
307 	clear_fields();
308 	read_header(data);
309 
310 	for (int i = 0; i < iaru_num_fields; i++)
311 		iaru_fields[i].f_data = findstr(data, iaru_fields[i].f_type);
312 
313 	iaru_update_form();
314 }
315 
iaru_cb_new()316 void iaru_cb_new()
317 {
318 	if (iaru_check_fields()) {
319 		if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 1) {
320 			update_header(CHANGED);
321 			iaru_cb_save();
322 		}
323 	}
324 	iaru_update_fields();
325 	iaru_clear_form();
326 	clear_header();
327 	iaru_def_filename = ICS_msg_dir;
328 	iaru_def_filename.append("new").append(IARU_FILE_EXT);
329 	iaru_using_template = false;
330 	show_filename(iaru_def_filename);
331 }
332 
iaru_cb_import()333 void iaru_cb_import()
334 {
335 	fl_alert2("Not implemented");
336 }
337 
iaru_cb_export()338 void iaru_cb_export()
339 {
340 	fl_alert2("Not implemented");
341 }
342 
iaru_cb_wrap_import(string wrapfilename,string inpbuffer)343 void iaru_cb_wrap_import(string wrapfilename, string inpbuffer)
344 {
345 	iaru_clear_form();
346 	iaru_read_buffer(inpbuffer);
347 	iaru_def_filename = ICS_msg_dir;
348 	iaru_def_filename.append(wrapfilename);
349 	show_filename(iaru_def_filename);
350 	iaru_using_template = false;
351 }
352 
eval_iaru_fsize()353 int eval_iaru_fsize()
354 {
355 	Ccrc16 chksum;
356 	evalstr.assign("[WRAP:beg][WRAP:lf][WRAP:fn ");
357 	evalstr.append(iaru_base_filename).append("]");
358 	iaru_update_fields();
359 	update_header(FROM);
360 	evalstr.append(header("<iaru>"));
361 	iaru_buffer.clear();
362 	iaru_make_buffer(true);
363 	if (iaru_buffer.empty()) return 0;
364 	evalstr.append( iaru_buffer );
365 	evalstr.append("[WRAP:chksum ").append(chksum.scrc16(evalstr)).append("][WRAP:end]");
366 	return evalstr.length();
367 }
368 
iaru_cb_wrap_export()369 void iaru_cb_wrap_export()
370 {
371 	if (iaru_check_fields()) {
372 		if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 0)
373 			return;
374 		update_header(CHANGED);
375 	}
376 	iaru_update_fields();
377 
378 	if (iaru_base_filename == string("new").append(IARU_FILE_EXT) ||
379 		iaru_base_filename == string("default").append(IARU_FILE_EXT) )
380 		if (!iaru_cb_save_as()) return;
381 
382 	string wrapfilename = WRAP_send_dir;
383 	wrapfilename.append(iaru_base_filename);
384 	wrapfilename.append(WRAP_EXT);
385 	const char *p = FSEL::saveas(
386 			"Save as wrapped iaru file",
387 			"Wrap file\t*.{wrap,WRAP}",
388 			wrapfilename.c_str());
389 	if (p) {
390 		string pext = fl_filename_ext(p);
391 		wrapfilename = p;
392 
393 		update_header(FROM);
394 		iaru_buffer.assign(header("<iaru>"));
395 		iaru_make_buffer(true);
396 		export_wrapfile(iaru_base_filename, wrapfilename, iaru_buffer, pext != WRAP_EXT);
397 
398 		iaru_buffer.assign(header("<iaru>"));
399 		iaru_make_buffer(false);
400 		iaru_write(iaru_def_filename);
401 	}
402 }
403 
iaru_cb_wrap_autosend()404 void iaru_cb_wrap_autosend()
405 {
406 	if (iaru_check_fields()) {
407 		if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 0)
408 			return;
409 		update_header(CHANGED);
410 	}
411 	iaru_update_fields();
412 
413 	if (iaru_base_filename == string("new").append(IARU_FILE_EXT) ||
414 		iaru_base_filename == string("default").append(IARU_FILE_EXT) )
415 		if (!iaru_cb_save_as()) return;
416 
417 	update_header(FROM);
418 	iaru_buffer.assign(header("<iaru>"));
419 	iaru_make_buffer(true);
420 	xfr_via_socket(iaru_base_filename, iaru_buffer);
421 
422 	iaru_buffer.assign(header("<iaru>"));
423 	iaru_make_buffer(false);
424 	iaru_write(iaru_def_filename);
425 }
426 
iaru_cb_load_template()427 void iaru_cb_load_template()
428 {
429 	string iaru_def_filename = iaru_def_template_name;
430 	const char *p = FSEL::select(
431 			"Open template file",
432 			string("Template file\t*").append(IARU_TEMP_EXT).c_str(),
433 			iaru_def_filename.c_str());
434 	if (p) {
435 		iaru_clear_form();
436 		read_data_file(p);
437 		iaru_def_template_name = p;
438 		show_filename(iaru_def_template_name);
439 		iaru_using_template = true;
440 	}
441 }
442 
iaru_cb_save_template()443 void iaru_cb_save_template()
444 {
445 	if (!iaru_using_template) {
446 		iaru_cb_save_as_template();
447 		return;
448 	}
449 	string iaru_def_filename = iaru_def_template_name;
450 	const char *p = FSEL::saveas(
451 			"Save template file",
452 			string("Template file\t*").append(IARU_TEMP_EXT).c_str(),
453 			iaru_def_filename.c_str());
454 	if (p) {
455 		update_header(CHANGED);
456 		iaru_update_fields();
457 		iaru_buffer.assign(header("<iaru>"));
458 		iaru_make_buffer();
459 		iaru_write(p);
460 	}
461 }
462 
iaru_cb_save_as_template()463 void iaru_cb_save_as_template()
464 {
465 	string iaru_def_filename = iaru_def_template_name;
466 	const char *p = FSEL::saveas(
467 			"Save as template file",
468 			string("Template file\t*").append(IARU_TEMP_EXT).c_str(),
469 			iaru_def_filename.c_str());
470 	if (p) {
471 		const char *pext = fl_filename_ext(p);
472 		iaru_def_template_name = p;
473 		if (strlen(pext) == 0) iaru_def_template_name.append(IARU_TEMP_EXT);
474 		remove_spaces_from_filename(iaru_def_template_name);
475 
476 		clear_header();
477 		update_header(CHANGED);
478 		iaru_update_fields();
479 		iaru_buffer.assign(header("<iaru>"));
480 		iaru_make_buffer();
481 		iaru_write(iaru_def_template_name);
482 
483 		show_filename(iaru_def_template_name);
484 		iaru_using_template = true;
485 	}
486 }
487 
iaru_cb_open()488 void iaru_cb_open()
489 {
490 	const char *p = FSEL::select(
491 			_("Open data file"),
492 			string("iaru\t*").append(IARU_FILE_EXT).c_str(),
493 			iaru_def_filename.c_str());
494 	if (!p) return;
495 	if (strlen(p) == 0) return;
496 	iaru_clear_form();
497 	read_data_file(p);
498 	iaru_using_template = false;
499 	iaru_def_filename = p;
500 	show_filename(iaru_def_filename);
501 }
502 
iaru_write(string s)503 void iaru_write(string s)
504 {
505 	FILE *iaru_file = fopen(s.c_str(), "w");
506 	if (!iaru_file) return;
507 
508 	fwrite(iaru_buffer.c_str(), iaru_buffer.length(), 1, iaru_file);
509 	fclose(iaru_file);
510 }
511 
iaru_cb_save_as()512 bool iaru_cb_save_as()
513 {
514 	const char *p;
515 	string newfilename;
516 
517 	string name = named_file();
518 	if (!name.empty()) {
519 		name.append(IARU_FILE_EXT);
520 		newfilename = ICS_msg_dir;
521 		newfilename.append(name);
522 	} else
523 		newfilename = iaru_def_filename;
524 
525 	p = FSEL::saveas(_("Save data file"), std::string("iaru\t*").append(IARU_FILE_EXT).c_str(),
526 						newfilename.c_str());
527 
528 	if (!p) return false;
529 	if (strlen(p) == 0) return false;
530 
531 	if (progStatus.rgnbr_fname) {
532 		int n = atoi(progStatus.rgnbr.c_str());
533 		n++;
534 		char szn[12];
535 		snprintf(szn, sizeof(szn), "%d", n);
536 		progStatus.rgnbr = szn;
537 		txt_rgnbr->value(szn);
538 		txt_rgnbr->redraw();
539 	} else if (progStatus.sernbr_fname)
540 		update_sernbr();
541 
542 	const char *pext = fl_filename_ext(p);
543 	iaru_def_filename = p;
544 	if (strlen(pext) == 0) iaru_def_filename.append(IARU_FILE_EXT);
545 
546 	remove_spaces_from_filename(iaru_def_filename);
547 
548 	update_header(NEW);
549 	iaru_update_fields();
550 	iaru_buffer.assign(header("<iaru>"));
551 	iaru_make_buffer();
552 	iaru_write(iaru_def_filename);
553 
554 	iaru_using_template = false;
555 	show_filename(iaru_def_filename);
556 	return true;
557 }
558 
iaru_cb_save()559 void iaru_cb_save()
560 {
561 	if (iaru_base_filename == std::string("new").append(IARU_FILE_EXT) ||
562 		iaru_base_filename == std::string("default").append(IARU_FILE_EXT) ||
563 		iaru_using_template == true) {
564 		iaru_cb_save_as();
565 		return;
566 	}
567 
568 	if (iaru_check_fields()) update_header(CHANGED);
569 	iaru_update_fields();
570 	iaru_buffer.assign(header("<iaru>"));
571 	iaru_make_buffer();
572 	iaru_write(iaru_def_filename);
573 
574 	iaru_using_template = false;
575 }
576 
577 const char *iaru_punctuation[] = {
578 ". ", " X ",
579 ",", " COMMA ",
580 "?", " QUERY ",
581 "\\", " BACKSLASH ",
582 "://", " COLON SLASH SLASH ",
583 "~", " TILDE ",
584 "_", " UNDERSCORE ",
585 "@", " AT ",
586 "#", " POUNDSIGN ",
587 "\"", " QUOTE ",
588 "\'", "",
589  0, 0 };
590 
iaru_cb_check()591 void iaru_cb_check()
592 {
593 	string temp = iaru_txt_msg->buffer()->text();
594 	if (temp.empty()) {
595 		iaru_txt_check->value("");
596 		iaru_btn_check->labelcolor(FL_BLACK);
597 		iaru_btn_check->redraw_label();
598 		return;
599 	}
600 
601 	// convert to uppercase
602 	for (size_t n = 0; n < temp.length(); n++)
603 		temp[n] = toupper(temp[n]);
604 
605 	size_t pos = string::npos;
606 
607 	strip_lfs(temp);
608 	// remove trailing period
609 	if (temp[temp.length()-1] == '.') temp.erase(temp.length()-1,1);
610 	// convert punctuation
611 	for (int n = 0; iaru_punctuation[n]; n += 2)
612 		while ((pos = temp.find(iaru_punctuation[n])) != string::npos)
613 			temp.replace(pos,1,iaru_punctuation[n+1]);
614 	//convert embedded periods
615 	while ((pos = temp.find(".")) != string::npos)
616 		if (isdigit(temp[pos-1]) || isdigit(temp[pos+1]))
617 			temp[pos] = 'R';
618 		else
619 			temp.replace(pos, 1, " DOT ");
620 
621 	// remove any user inserted end-of-lines
622 	while ((pos = temp.find('\n')) != string::npos) temp[pos] = ' ';
623 
624 	// only single spaces no trailing spaces, no leading spaces
625 	while ((pos = temp.find("  ")) != string::npos) temp.erase(pos,1);
626 	while (temp[temp.length() -1] == ' ') temp.erase(temp.length()-1, 1);
627 	if (temp[0] == ' ') temp.erase(0,1);
628 
629 	// count number of words in textiaru_def_filename
630 	int numwords = 1;
631 	if (temp.length()) {
632 		pos = 0;
633 		while ((pos = temp.find(" ", pos + 1)) != string::npos) numwords++;
634 	}
635 
636 	// no more than 5 words to a line
637 	if (numwords > progStatus.wpl) {
638 		int wc = numwords;
639 		size_t pos = 0;
640 		while (wc > progStatus.wpl) {
641 			for (int i = 0; i < progStatus.wpl; i++) pos = temp.find(' ', pos + 1);
642 			temp[pos] = '\n';
643 			wc -= progStatus.wpl;
644 		}
645 	}
646 	// insert trailing end-of-line
647 	temp += '\n';
648 
649 	// return converted text to editor
650 	iaru_txt_msg->clear();
651 	iaru_txt_msg->addstr(temp.c_str());
652 
653 	char snum[10];
654 	snprintf(snum, sizeof(snum), "%s%d",
655 		temp.find("ARL") != string::npos ? "ARL " : "",
656 		(numwords % 1000));
657 	iaru_txt_check->value(snum);
658 	iaru_update_fields();
659 	iaru_btn_check->labelcolor(FL_BLACK);
660 	iaru_btn_check->redraw_label();
661 }
662 
iaru_cb_html()663 void iaru_cb_html()
664 {
665 	string iaru_name;
666 	string html_text;
667 	unsigned int nbr;
668 	iaru_name = ICS_dir;
669 	iaru_name.append("iaru.html");
670 
671 	iaru_update_fields();
672 	iaru_cb_check();
673 	string form = iaru_html_template;
674 
675 	for (int i = 0; i < iaru_num_fields; i++) {
676 		if (iaru_fields[i].f_type == iaru_prec) {
677 			sscanf(iaru_fields[i].f_data.c_str(), "%u", &nbr);
678 			if (nbr >= 0 && nbr < (sizeof(iaru_s_prec) / sizeof(*iaru_s_prec)))
679 				html_text = iaru_s_prec[nbr];
680 			else
681 				html_text = "";
682 			replacestr( form, iaru_fields[i].f_type, html_text );
683 		} else if (iaru_fields[i].w_type == 'b') {
684 			replacestr( form, iaru_fields[i].f_type, iaru_fields[i].f_data == "T" ? yes : no);
685 		} else
686 			replacestr( form, iaru_fields[i].f_type, iaru_fields[i].f_data );
687 	}
688 
689 	string rxstr = "";
690 	rxstr.append(progStatus.my_call).append(" ").append(progStatus.my_tel);
691 	rxstr.append("<br>").append(progStatus.my_name);
692 	rxstr.append("<br>").append(progStatus.my_addr);
693 	rxstr.append("<br>").append(progStatus.my_city);
694 	html_text = ":rx:";
695 	replacestr( form, html_text, rxstr);
696 
697 	html_text = ":exp:";
698 	string arlmsgs = "";
699 	if (progStatus.arl_desc)
700 		arlmsgs = expand_arl(iaru_fields[10].f_data);
701 	replacestr( form, html_text, arlmsgs);
702 
703 	FILE *iaru_file = fopen(iaru_name.c_str(), "w");
704 	fprintf(iaru_file,"%s", form.c_str());
705 	fclose(iaru_file);
706 
707 	open_url(iaru_name.c_str());
708 }
709 
iaru_cb_textout()710 void iaru_cb_textout()
711 {
712 	string iaru_name;
713 	string lines;
714 	string str;
715 	int nbr = 0;//, fn;
716 	iaru_name = ICS_dir;
717 	iaru_name.append("iaru.txt");
718 
719 	iaru_update_fields();
720 	iaru_cb_check();
721 
722 	string form = iaru_txt_template;
723 
724 	for (int i = 0; i < iaru_num_fields; i++) {
725 		str.clear();
726 		if (iaru_fields[i].f_type == iaru_prec) {
727 			sscanf(iaru_fields[i].f_data.c_str(), "%d", &nbr);
728 			str = iaru_s_prec[nbr];
729 			if (str.find("EMERGENCY") == string::npos)
730 				str = str[0];
731 			replacestr( form, iaru_fields[i].f_type, str);
732 		} else {
733 			str = iaru_fields[i].f_data;
734 			strip_lfs(str);
735 			replacestr( form, iaru_fields[i].f_type, str);
736 		}
737 	}
738 
739 	FILE *iaru_file = fopen(iaru_name.c_str(), "w");
740 	fprintf(iaru_file,"%s", form.c_str());
741 	fclose(iaru_file);
742 	open_url(iaru_name.c_str());
743 }
744 
745