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 #include "flmsg_strings.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 using namespace std;
75 
76 string cap105_base_filename = "";
77 string cap105_def_filename = "";
78 string cap105_def_template_name = "";
79 
80 static string cap105_buffer;
81 
82 // cap105 cap105_fields
83 
84 const char *cap105_s_prec[] = {"ROUTINE","PRIORITY","IMMEDIATE","FLASH"};
85 const char cap105_prec_items[] = "ROUTINE|PRIORITY|IMMEDIATE|FLASH";
86 
87 string cap105_nbr      = ":msg nbr:";
88 string cap105_prec     = ":prec:";
89 string cap105_dtm      = ":dtm:";
90 string cap105_from     = ":from:";
91 string cap105_to       = ":to:";
92 string cap105_info     = ":info:";
93 string cap105_subj     = ":subj:";
94 string cap105_grpcnt   = ":grpcnt:";
95 string cap105_msg      = ":msgtxt:";
96 string cap105_rcvd_fm  = ":rcvd_fm:";
97 string cap105_sent_to  = ":sent_to:";
98 string cap105_rcvd_dtm = ":rcvd_dtm:";
99 string cap105_sent_dtm = ":sent_dtm:";
100 string cap105_rcvop    = ":rcvop:";
101 string cap105_sendop   = ":sendop:";
102 
103 //struct FIELD { string f_type; string f_data; void **w; char w_type; };
104 FIELD cap105_fields[] = {
105 { cap105_nbr,		"", (void **)&cap105_txt_nbr,		't' },	// 0
106 { cap105_prec,		"", (void **)&cap105_sel_prec,		's' },	// 1
107 { cap105_dtm,		"", (void **)&cap105_txt_dtm,		't' },	// 2
108 { cap105_from,		"", (void **)&cap105_txt_from,		't' },	// 3
109 { cap105_to,		"", (void **)&cap105_txt_to,		't' },	// 4
110 { cap105_info,		"", (void **)&cap105_txt_info,		't' },	// 5
111 { cap105_subj,		"", (void **)&cap105_txt_subj,		't' },	// 6
112 { cap105_grpcnt,	"", (void **)&cap105_txt_grpcnt,	't' },	// 7
113 { cap105_msg,		"", (void **)&cap105_txt_msg,		'e' },	// 8
114 { cap105_rcvd_fm,	"", (void **)&cap105_txt_rcvd_fm,	't' },	// 9
115 { cap105_sent_to,	"", (void **)&cap105_txt_sent_to,	't' },	// 10
116 { cap105_rcvd_dtm,	"", (void **)&cap105_txt_rcvd_dtm,	't' },	// 11
117 { cap105_sent_dtm,	"", (void **)&cap105_txt_sent_dtm,	't' },	// 12
118 { cap105_rcvop,		"", (void **)&cap105_txt_rcvop,		't' },	// 13
119 { cap105_sendop,	"", (void **)&cap105_txt_sendop,	't' },	// 14
120 };
121 
122 bool cap105_using_template = false;
123 
124 int cap105_num_fields = sizeof(cap105_fields) / sizeof(FIELD);
125 
126 //======================================================================
127 
cap105_cb_set_dtm()128 void cap105_cb_set_dtm()
129 {
130 	cap105_txt_dtm->value(szCAPDateTime());
131 }
132 
cap105_cb_set_rcvd_dtm()133 void cap105_cb_set_rcvd_dtm()
134 {
135 	cap105_txt_rcvd_dtm->value(szCAPDateTime());
136 }
137 
cap105_cb_set_sent_dtm()138 void cap105_cb_set_sent_dtm()
139 {
140 	cap105_txt_sent_dtm->value(szCAPDateTime());
141 }
142 
cap105_cb_nbr(Fl_Widget * wdg)143 void cap105_cb_nbr(Fl_Widget *wdg)
144 {
145 	Fl_Input2 *inp = (Fl_Input2 *)wdg;
146 	string s = inp->value();
147 	for (size_t n = 0; n < s.length(); n++)
148 		if (!isdigit(s[n])) s.erase(n,1);
149 	strip_leading_zeros(s);
150 	inp->value(s.c_str());
151 }
152 
153 static char valid_input[] = "0123456789/,; ABCDEFGHIJKLMNOPQRSTUVWXYZ\n";
154 
cap105_cb_filter_input(Fl_Widget * wdg)155 void cap105_cb_filter_input(Fl_Widget *wdg)
156 {
157 	Fl_Input2 *inp = (Fl_Input2 *)wdg;
158 	string s = inp->value();
159 	ucase(s);
160 	for (size_t n = 0; n < s.length(); n++)
161 		if (strchr(valid_input, s[n]) == NULL)
162 			s.erase(n,1);
163 	inp->value(s.c_str());
164 }
165 
cap105_clear_fields()166 void cap105_clear_fields()
167 {
168 	for (int i = 0; i < cap105_num_fields; i++)
169 		cap105_fields[i].f_data.clear();
170 }
171 
numeric(int n)172 static string numeric(int n)
173 {
174 	static char snum[12];
175 	snprintf(snum, sizeof(snum), "%d", n);
176 	return snum;
177 }
178 
cap105_set_choices()179 void cap105_set_choices() {
180 	cap105_sel_prec->clear();
181 	cap105_sel_prec->add(cap105_prec_items);
182 	cap105_sel_prec->index(0);
183 }
184 
cap105_check_fields()185 bool cap105_check_fields()
186 {
187 	for (int i = 0; i < cap105_num_fields; i++) {
188 		if (cap105_fields[i].w_type == 'd') {
189 			if (cap105_fields[i].f_data != ((Fl_DateInput *)(*cap105_fields[i].w))->value())
190 				return true;
191 		} else if (cap105_fields[i].w_type == 't') {
192 			if (cap105_fields[i].f_data != ((Fl_Input2 *)(*cap105_fields[i].w))->value())
193 				return true;
194 		} else if (cap105_fields[i].w_type == 's') {
195 			int choice = ((Fl_ListBox *)(*cap105_fields[i].w))->index();
196 			if (choice >= 0) {
197 				if (cap105_fields[i].f_data != numeric(choice))
198 					return true;
199 			}
200 		} else if (cap105_fields[i].w_type == 'e') {
201 			if (cap105_fields[i].f_data != ((FTextEdit *)(*cap105_fields[i].w))->buffer()->text())
202 				return true;
203 		} else if (cap105_fields[i].w_type == 'b') {
204 			string val = ((Fl_Button *)(*cap105_fields[i].w))->value() ? "T" : "F";
205 			if (cap105_fields[i].f_data != val)
206 				return true;
207 		}
208 	}
209 	return false;
210 }
211 
cap105_update_fields()212 void cap105_update_fields()
213 {
214 	for (int i = 0; i < cap105_num_fields; i++) {
215 		if (cap105_fields[i].w_type == 'd') {
216 			cap105_fields[i].f_data = ((Fl_DateInput *)(*cap105_fields[i].w))->value();
217 		} else if (cap105_fields[i].w_type == 't') {
218 			cap105_fields[i].f_data = ((Fl_Input2 *)(*cap105_fields[i].w))->value();
219 		} else if (cap105_fields[i].w_type == 's') {
220 			int choice = ((Fl_ListBox *)(*cap105_fields[i].w))->index();
221 			if (choice >= 0) {
222 				cap105_fields[i].f_data = numeric(choice);
223 			}
224 		} else if (cap105_fields[i].w_type == 'e') {
225 			cap105_fields[i].f_data = ((FTextEdit *)(*cap105_fields[i].w))->buffer()->text();
226 		} else if (cap105_fields[i].w_type == 'b') {
227 			string val = ((Fl_Button *)(*cap105_fields[i].w))->value() ? "T" : "F";
228 			cap105_fields[i].f_data = val;
229 		}
230 	}
231 }
232 
cap105_clear_form()233 void cap105_clear_form()
234 {
235 	cap105_clear_fields();
236 
237 	if (progStatus.rgnbr_fname)
238 		cap105_txt_nbr->value(progStatus.rgnbr.c_str());
239 	else
240 		cap105_txt_nbr->value("");
241 
242 	for (int i = 1; i < cap105_num_fields; i++)
243 		if (cap105_fields[i].w_type == 'd')
244 			((Fl_DateInput *)(*cap105_fields[i].w))->value("");
245 		else if (cap105_fields[i].w_type == 't')
246 			((Fl_Input2 *)(*cap105_fields[i].w))->value("");
247 		else if (cap105_fields[i].w_type == 's')
248 			((Fl_ListBox *)(*cap105_fields[i].w))->index(0);
249 		else if (cap105_fields[i].w_type == 'e')
250 			((FTextEdit *)(*cap105_fields[i].w))->clear();
251 		else if (cap105_fields[i].w_type == 'b')
252 			((Fl_Button *)(*cap105_fields[i].w))->value(0);
253 	cap105_update_fields();
254 }
255 
cap105_update_form()256 void cap105_update_form()
257 {
258 	for (int i = 0; i < cap105_num_fields; i++) {
259 		if (cap105_fields[i].w_type == 'd')
260 			((Fl_DateInput *)(*cap105_fields[i].w))->value(cap105_fields[i].f_data.c_str());
261 		else if (cap105_fields[i].w_type == 't')
262 			((Fl_Input2 *)(*cap105_fields[i].w))->value(cap105_fields[i].f_data.c_str());
263 		else if (cap105_fields[i].w_type == 's')
264 			((Fl_ListBox *)(*cap105_fields[i].w))->index(atoi(cap105_fields[i].f_data.c_str()));
265 		else if (cap105_fields[i].w_type == 'e') {
266 			((FTextEdit *)(*cap105_fields[i].w))->clear();
267 			((FTextEdit *)(*cap105_fields[i].w))->add(cap105_fields[i].f_data.c_str());
268 		} else if (cap105_fields[i].w_type == 'b')
269 			((Fl_Button *)(*cap105_fields[i].w))->value(cap105_fields[i].f_data == "T" ? 1 : 0);
270 	}
271 }
272 
cap105_make_buffer(bool compress)273 void cap105_make_buffer(bool compress)
274 {
275 	string mbuff;
276 	mbuff.clear();
277 	for (int i = 0; i < cap105_num_fields; i++)
278 		mbuff.append( lineout( cap105_fields[i].f_type, cap105_fields[i].f_data ) );
279 	if (compress) compress_maybe(mbuff);
280 	cap105_buffer.append(mbuff);
281 }
282 
cap105_read_buffer(string data)283 void cap105_read_buffer(string data)
284 {
285 	clear_fields();
286 	read_header(data);
287 
288 	for (int i = 0; i < cap105_num_fields; i++)
289 		cap105_fields[i].f_data = findstr(data, cap105_fields[i].f_type);
290 
291 	cap105_update_form();
292 }
293 
cap105_cb_new()294 void cap105_cb_new()
295 {
296 	if (cap105_check_fields()) {
297 		if (fl_choice2(xMODIFIED, xNO, xYES, NULL) == 1) {
298 			update_header(CHANGED);
299 			cap105_cb_save();
300 		}
301 	}
302 	cap105_update_fields();
303 	cap105_clear_form();
304 	clear_header();
305 	cap105_def_filename = ICS_msg_dir;
306 	cap105_def_filename.append(xNEW).append(CAP105_FILE_EXT);
307 	cap105_using_template = false;
308 	show_filename(cap105_def_filename);
309 }
310 
cap105_cb_import()311 void cap105_cb_import()
312 {
313 	fl_alert2(xNOTIMPLEMENTED);
314 }
315 
cap105_cb_export()316 void cap105_cb_export()
317 {
318 	fl_alert2(xNOTIMPLEMENTED);
319 }
320 
cap105_cb_wrap_import(string wrapfilename,string inpbuffer)321 void cap105_cb_wrap_import(string wrapfilename, string inpbuffer)
322 {
323 	cap105_clear_form();
324 	cap105_read_buffer(inpbuffer);
325 	cap105_def_filename = ICS_msg_dir;
326 	cap105_def_filename.append(wrapfilename);
327 	show_filename(cap105_def_filename);
328 	cap105_using_template = false;
329 }
330 
eval_cap105_fsize()331 int eval_cap105_fsize()
332 {
333 	Ccrc16 chksum;
334 	evalstr.assign("[WRAP:beg][WRAP:lf][WRAP:fn ");
335 	evalstr.append(cap105_base_filename).append("]");
336 	cap105_update_fields();
337 	update_header(FROM);
338 	evalstr.append(header("<cap105>"));
339 	cap105_buffer.clear();
340 	cap105_make_buffer(true);
341 	if (cap105_buffer.empty()) return 0;
342 	evalstr.append( cap105_buffer );
343 	evalstr.append("[WRAP:chksum ").append(chksum.scrc16(evalstr)).append("][WRAP:end]");
344 	return evalstr.length();
345 }
346 
cap105_cb_wrap_export()347 void cap105_cb_wrap_export()
348 {
349 	if (cap105_check_fields()) {
350 		if (fl_choice2(xMODIFIED, xNO, xYES, NULL) == 0)
351 			return;
352 		update_header(CHANGED);
353 	}
354 	cap105_update_fields();
355 
356 	if (cap105_base_filename == string(xNEW).append(CAP105_FILE_EXT) ||
357 		cap105_base_filename == string(xDEFAULT).append(CAP105_FILE_EXT) )
358 		if (!cap105_cb_save_as()) return;
359 
360 	string wrapfilename = WRAP_send_dir;
361 	wrapfilename.append(cap105_base_filename);
362 	wrapfilename.append(WRAP_EXT);
363 	const char *p = FSEL::saveas(
364 			xSAVEASWRAP,
365 			xWRAPFILE,
366 			wrapfilename.c_str());
367 	if (p) {
368 		string pext = fl_filename_ext(p);
369 		wrapfilename = p;
370 
371 		update_header(FROM);
372 		cap105_buffer.assign(header("<cap105>"));
373 		cap105_make_buffer(true);
374 		export_wrapfile(cap105_base_filename, wrapfilename, cap105_buffer, pext != WRAP_EXT);
375 
376 		cap105_buffer.assign(header("<cap105>"));
377 		cap105_make_buffer(false);
378 		cap105_write(cap105_def_filename);
379 	}
380 }
381 
cap105_cb_wrap_autosend()382 void cap105_cb_wrap_autosend()
383 {
384 	if (cap105_check_fields()) {
385 		if (fl_choice2(xMODIFIED, xNO, xYES, NULL) == 0)
386 			return;
387 		update_header(CHANGED);
388 	}
389 	cap105_update_fields();
390 
391 	if (cap105_base_filename == string(xNEW).append(CAP105_FILE_EXT) ||
392 		cap105_base_filename == string(xDEFAULT).append(CAP105_FILE_EXT) )
393 		if (!cap105_cb_save_as()) return;
394 
395 	update_header(FROM);
396 	cap105_buffer.assign(header("<cap105>"));
397 	cap105_make_buffer(true);
398 	xfr_via_socket(cap105_base_filename, cap105_buffer);
399 
400 	cap105_buffer.assign(header("<cap105>"));
401 	cap105_make_buffer(false);
402 	cap105_write(cap105_def_filename);
403 }
404 
cap105_cb_load_template()405 void cap105_cb_load_template()
406 {
407 	string cap105_def_filename = cap105_def_template_name;
408 	const char *p = FSEL::select(
409 			xOPENTEMPLATE,
410 			string(xTEMPLATEFILE).append(CAP105_TEMP_EXT).c_str(),
411 			cap105_def_filename.c_str());
412 	if (p) {
413 		cap105_clear_form();
414 		read_data_file(p);
415 		cap105_def_template_name = p;
416 		show_filename(cap105_def_template_name);
417 		cap105_using_template = true;
418 	}
419 }
420 
cap105_cb_save_template()421 void cap105_cb_save_template()
422 {
423 	if (!cap105_using_template) {
424 		cap105_cb_save_as_template();
425 		return;
426 	}
427 	string cap105_def_filename = cap105_def_template_name;
428 	const char *p = FSEL::saveas(
429 			xSAVEASTEMPLATE,
430 			string(xTEMPLATEFILE).append(CAP105_TEMP_EXT).c_str(),
431 			cap105_def_filename.c_str());
432 	if (p) {
433 		update_header(CHANGED);
434 		cap105_update_fields();
435 		cap105_buffer.assign(header("<cap105>"));
436 		cap105_make_buffer();
437 		cap105_write(p);
438 	}
439 }
440 
cap105_cb_save_as_template()441 void cap105_cb_save_as_template()
442 {
443 	string cap105_def_filename = cap105_def_template_name;
444 	const char *p = FSEL::saveas(
445 			xSAVEASTEMPLATE,
446 			string(xTEMPLATEFILE).append(CAP105_TEMP_EXT).c_str(),
447 			cap105_def_filename.c_str());
448 	if (p) {
449 		const char *pext = fl_filename_ext(p);
450 		cap105_def_template_name = p;
451 		if (strlen(pext) == 0) cap105_def_template_name.append(CAP105_TEMP_EXT);
452 		remove_spaces_from_filename(cap105_def_template_name);
453 
454 		clear_header();
455 		update_header(CHANGED);
456 		cap105_update_fields();
457 		cap105_buffer.assign(header("<cap105>"));
458 		cap105_make_buffer();
459 		cap105_write(cap105_def_template_name);
460 
461 		show_filename(cap105_def_template_name);
462 		cap105_using_template = true;
463 	}
464 }
465 
cap105_cb_open()466 void cap105_cb_open()
467 {
468 	const char *p = FSEL::select(
469 			_(xOPENDATAFILE),
470 			string("cap105\t*").append(CAP105_FILE_EXT).c_str(),
471 			cap105_def_filename.c_str());
472 	if (!p) return;
473 	if (strlen(p) == 0) return;
474 	cap105_clear_form();
475 	read_data_file(p);
476 	cap105_using_template = false;
477 	cap105_def_filename = p;
478 	show_filename(cap105_def_filename);
479 }
480 
cap105_write(string s)481 void cap105_write(string s)
482 {
483 	FILE *cap105_file = fopen(s.c_str(), "w");
484 	if (!cap105_file) return;
485 
486 	fwrite(cap105_buffer.c_str(), cap105_buffer.length(), 1, cap105_file);
487 	fclose(cap105_file);
488 }
489 
cap105_cb_save_as()490 bool cap105_cb_save_as()
491 {
492 	const char *p;
493 	string newfilename;
494 
495 	string name = named_file();
496 	if (!name.empty()) {
497 		name.append(CAP105_FILE_EXT);
498 		newfilename = ICS_msg_dir;
499 		newfilename.append(name);
500 	} else
501 		newfilename = cap105_def_filename;
502 
503 	p = FSEL::saveas(_(xSAVEDATAFILE),
504 				string("cap105\t*").append(CAP105_FILE_EXT).c_str(),
505 				newfilename.c_str());
506 
507 	if (!p) return false;
508 	if (strlen(p) == 0) return false;
509 
510 	if (progStatus.rgnbr_fname) {
511 		int n = atoi(progStatus.rgnbr.c_str());
512 		n++;
513 		char szn[12];
514 		snprintf(szn, sizeof(szn), "%d", n);
515 		progStatus.rgnbr = szn;
516 		txt_rgnbr->value(szn);
517 		txt_rgnbr->redraw();
518 	} else if (progStatus.sernbr_fname)
519 		update_sernbr();
520 
521 	const char *pext = fl_filename_ext(p);
522 	cap105_def_filename = p;
523 	if (strlen(pext) == 0) cap105_def_filename.append(CAP105_FILE_EXT);
524 
525 	remove_spaces_from_filename(cap105_def_filename);
526 
527 	update_header(NEW);
528 	cap105_update_fields();
529 	cap105_buffer.assign(header("<cap105>"));
530 	cap105_make_buffer();
531 	cap105_write(cap105_def_filename);
532 
533 	cap105_using_template = false;
534 	show_filename(cap105_def_filename);
535 	return true;
536 }
537 
cap105_cb_save()538 void cap105_cb_save()
539 {
540 	if (cap105_base_filename == string(xNEW).append(CAP105_FILE_EXT) ||
541 		cap105_base_filename == string(xDEFAULT).append(CAP105_FILE_EXT) ||
542 		cap105_using_template == true) {
543 		cap105_cb_save_as();
544 		return;
545 	}
546 
547 	if (cap105_check_fields()) update_header(CHANGED);
548 	cap105_update_fields();
549 	cap105_buffer.assign(header("<cap105>"));
550 	cap105_make_buffer();
551 	cap105_write(cap105_def_filename);
552 
553 	cap105_using_template = false;
554 }
555 
556 /*
557 const char *cap105_punctuation[] = {
558 ". ", " X ",
559 ",", " COMMA ",
560 "?", " QUERY ",
561 "\\", " BACKSLASH ",
562 "://", " COLON SLASH SLASH ",
563 "~", " TILDE ",
564 "_", " UNDERSCORE ",
565 "@", " AT ",
566 "#", " POUNDSIGN ",
567 "\"", " QUOTE ",
568 "\'", "",
569  0, 0 };
570 */
571 
cap105_cb_check()572 void cap105_cb_check()
573 {
574 	string temp = cap105_txt_msg->buffer()->text();
575 	if (temp.empty()) {
576 		cap105_txt_grpcnt->value("");
577 		cap105_btn_check->labelcolor(FL_BLACK);
578 		cap105_btn_check->redraw_label();
579 		return;
580 	}
581 
582 	// convert to uppercase
583 	for (size_t n = 0; n < temp.length(); n++)
584 		temp[n] = toupper(temp[n]);
585 	// convert tabs to 5 spaces
586 	size_t pos = string::npos;
587 	while ((pos = temp.find("\t")) != string::npos)
588 		temp.replace(pos, 1, "     ");
589 	// return converted text to editor
590 	cap105_txt_msg->clear();
591 	cap105_txt_msg->addstr(temp.c_str());
592 
593 // compute word count
594 // remove any user inserted end-of-lines
595 	while ((pos = temp.find('\n')) != string::npos) temp[pos] = ' ';
596 // only single spaces no trailing spaces, no leading spaces
597 	while ((pos = temp.find("  ")) != string::npos) temp.erase(pos,1);
598 	while (temp[temp.length() -1] == ' ') temp.erase(temp.length()-1, 1);
599 	if (temp[0] == ' ') temp.erase(0,1);
600 // count number of words in textcap105_def_filename
601 	int numwords = 0;
602 	if (temp.length()) {
603 		pos = 0;
604 		numwords = 1;
605 		while ((pos = temp.find(" ", pos + 1)) != string::npos) numwords++;
606 	}
607 
608 /*
609 	// no more than 5 words to a line
610 	if (numwords > progStatus.wpl) {
611 		int wc = numwords;
612 		size_t pos = 0;
613 		while (wc > progStatus.wpl) {
614 			for (int i = 0; i < progStatus.wpl; i++) pos = temp.find(' ', pos + 1);
615 			temp[pos] = '\n';
616 			wc -= progStatus.wpl;
617 		}
618 	}
619 */
620 
621 	char snum[15];
622 	snprintf(snum, sizeof(snum), "%d", numwords);
623 	cap105_grpcnt = snum;
624 	cap105_txt_grpcnt->value(snum);
625 	cap105_update_fields();
626 	cap105_btn_check->labelcolor(FL_BLACK);
627 	cap105_btn_check->redraw_label();
628 }
629 
cap105_cb_html()630 void cap105_cb_html()
631 {
632 	string cap105_name;
633 	string html_text;
634 	unsigned int nbr;
635 	cap105_name = ICS_dir;
636 	cap105_name.append("cap105.html");
637 
638 	cap105_update_fields();
639 	cap105_cb_check();
640 	string form = cap105_html_template;
641 
642 string pg = ":pg:";
643 string pgnr = ":npgs:";
644 string pgone = "1";
645 	replacestr( form, pg, pgone);
646 	replacestr( form, pgnr, pgone);
647 	for (int i = 0; i < cap105_num_fields; i++) {
648 		if (cap105_fields[i].f_type == cap105_prec) {
649 			sscanf(cap105_fields[i].f_data.c_str(), "%u", &nbr);
650 			if (nbr >= 0 && nbr < (sizeof(cap105_s_prec) / sizeof(*cap105_s_prec)))
651 				html_text = cap105_s_prec[nbr];
652 			else
653 				html_text = "";
654 			replacestr( form, cap105_fields[i].f_type, html_text );
655 		} else if (cap105_fields[i].w_type == 'b') {
656 			replacestr( form, cap105_fields[i].f_type, cap105_fields[i].f_data == "T" ? yes : no);
657 		} else if (cap105_fields[i].w_type == 'e') {
658 			string temp = cap105_fields[i].f_data;
659 			size_t p = 0;
660 			while ( (p = temp.find("\n")) != string::npos)
661 				temp.replace(p, 1, "<br>");
662 			replacestr( form, cap105_fields[i].f_type, temp);
663 		} else
664 			replacestr( form, cap105_fields[i].f_type, cap105_fields[i].f_data );
665 	}
666 
667 	string rxstr = "";
668 	rxstr.append(progStatus.my_call).append(" ").append(progStatus.my_tel);
669 	rxstr.append("<br>").append(progStatus.my_name);
670 	rxstr.append("<br>").append(progStatus.my_addr);
671 	rxstr.append("<br>").append(progStatus.my_city);
672 	html_text = ":rx:";
673 	replacestr( form, html_text, rxstr);
674 
675 	html_text = ":exp:";
676 	string arlmsgs = "";
677 	if (progStatus.arl_desc)
678 		arlmsgs = expand_arl(cap105_fields[10].f_data);
679 	replacestr( form, html_text, arlmsgs);
680 
681 	FILE *cap105_file = fopen(cap105_name.c_str(), "w");
682 	fprintf(cap105_file,"%s", form.c_str());
683 	fclose(cap105_file);
684 
685 	open_url(cap105_name.c_str());
686 }
687 
cap105_cb_textout()688 void cap105_cb_textout()
689 {
690 	string cap105_name;
691 	string lines;
692 	string str;
693 	int nbr = 0;//, fn;
694 	cap105_name = ICS_dir;
695 	cap105_name.append("cap105.txt");
696 
697 	cap105_update_fields();
698 	cap105_cb_check();
699 
700 	string form = cap105_txt_template;
701 
702 	for (int i = 0; i < cap105_num_fields; i++) {
703 		str.clear();
704 		if (cap105_fields[i].f_type == cap105_prec) {
705 			sscanf(cap105_fields[i].f_data.c_str(), "%d", &nbr);
706 			str = cap105_s_prec[nbr];
707 			if (str.find("EMERGENCY") == string::npos)
708 				str = str[0];
709 			replacestr( form, cap105_fields[i].f_type, str);
710 		} else {
711 			str = cap105_fields[i].f_data;
712 //			strip_lfs(str);
713 			replacestr( form, cap105_fields[i].f_type, str);
714 		}
715 	}
716 
717 	FILE *cap105_file = fopen(cap105_name.c_str(), "w");
718 	fprintf(cap105_file,"%s", form.c_str());
719 	fclose(cap105_file);
720 	open_url(cap105_name.c_str());
721 }
722 
723