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 <sys/types.h>
22 #include <dirent.h>
23 #include <iostream>
24 #include <fstream>
25 #include <vector>
26 
27 #include <FL/Fl_Native_File_Chooser.H>
28 
29 #include "gettext.h"
30 #include "flmsg_arq.h"
31 #include "flmsg_dialog.h"
32 #include "drop_button.h"
33 
34 #include "status.h"
35 #include "flmsg.h"
36 #include "fileselect.h"
37 #include "debug.h"
38 #include "util.h"
39 
40 #include "transfer.h"
41 #include "time_table.h"
42 #include "xml_io.h"
43 #include "combo.h"
44 #include "wrap.h"
45 #include "icons.h"
46 
47 //======================================================================
48 
49 Fl_Menu_Bar *ve_menubar = (Fl_Menu_Bar *)0;
50 Fl_ComboBox *temp_combo = (Fl_ComboBox *)0;
51 Fl_Button   *ve_create  = (Fl_Button *)0;
52 Fl_Drop_Button   *ve_editor  = (Fl_Drop_Button *)0;
53 Fl_Drop_Button   *ve_viewer  = (Fl_Drop_Button *)0;
54 
55 //======================================================================
56 
57 Fl_Menu_Bar *mb = (Fl_Menu_Bar *)0;
58 
59 Fl_Browser			*brwsOptions = (Fl_Browser *)0;
60 Fl_Return_Button	*btnCloseOptions = (Fl_Return_Button *)0;
61 
62 Fl_Output			*txt_formname = (Fl_Output *)0;
63 
64 Fl_Output			*txt_filename = (Fl_Output *)0;
65 Fl_Input			*drop_file = (Fl_Input *)0;
66 
67 Fl_Group			*all_tabs = (Fl_Group *)0;
68 Fl_Group			*controls = (Fl_Group *)0;
69 
70 int					tab_top;
71 
72 Fl_Browser			*select_arl = (Fl_Browser *)0;
73 Fl_Input2			*txt_arl_fill1 = (Fl_Input2 *)0;
74 Fl_Input2			*txt_arl_fill2 = (Fl_Input2 *)0;
75 Fl_Input2			*txt_arl_fill3 = (Fl_Input2 *)0;
76 Fl_Input2			*txt_arl_fill4 = (Fl_Input2 *)0;
77 Fl_Button			*btn_arl_cancel = (Fl_Button *)0;
78 Fl_Button			*btn_arl_add = (Fl_Button *)0;
79 FTextEdit			*arl_text = (FTextEdit *)0;
80 Fl_Check_Button		*btnInsertX = (Fl_Check_Button *)0;
81 
82 Fl_Check_Button		*btn_force_compression = (Fl_Check_Button *)0;
83 
84 Fl_Input2			*txt_mars_roster_file = (Fl_Input2 *)0;
85 
86 Fl_Input2*			txt_hdr_from = (Fl_Input2 *)0;
87 Fl_Input2*			txt_hdr_edit = (Fl_Input2 *)0;
88 
89 Fl_Check_Button *btnAutoWordWrap = (Fl_Check_Button *)0;
90 Fl_Check_Button *btn_use_compression = (Fl_Check_Button *)0;
91 Fl_Button *btn_estimate = (Fl_Button *)0;
92 
93 Fl_Check_Button *btnSendOriginalFile = (Fl_Check_Button *)0;
94 
95 Fl_ListBox *encoders = (Fl_ListBox *)0;
96 
97 Fl_Counter *cntCharCount = (Fl_Counter *)0;
98 
99 Fl_ListBox	*cbo_modes = (Fl_ListBox *)0;
100 Fl_Output *txt_xfr_size_time = (Fl_Output *)0;
101 
102 //----------------------------------------------------------------------
103 // arq transfer controls group
104 //----------------------------------------------------------------------
105 Fl_Group			*arq_group = (Fl_Group *)0;
106 Fl_Progress			*prgSTATE = (Fl_Progress *)0;
107 Fl_Input2			*txtSTATE = (Fl_Input2 *)0;
108 Fl_Input2			*txtSENDTO = (Fl_Input2 *)0;
109 Fl_Button			*btnSEND = (Fl_Button *)0;
110 
111 int transfer_size;
112 
113 void cb_btn_transfer_size(Fl_Button *, void*);
114 
115 //----------------------------------------------------------------------
116 #define NO_OF_MODEMS 200
117 char *s_modes[NO_OF_MODEMS];
118 
119 string valid_modes;
120 
update_cbo_modes(string & fldigi_modes)121 void update_cbo_modes(string &fldigi_modes)
122 {
123 	memset(s_modes, 0, sizeof(s_modes));
124 
125 	valid_modes.clear();
126 	cbo_modes->clear();
127 
128 	int j = 0;
129 	int num_modes = mode_table_count();
130 	char *m = (char *)0;
131 
132 	if(num_modes >= NO_OF_MODEMS)
133 		num_modes = NO_OF_MODEMS - 1;
134 
135 	for (int i = 0; i < num_modes; i++) {
136 		m = modem_at_index(i);
137 		if (fldigi_modes.find(m) != string::npos) {
138 			s_modes[j] = (char *) m;
139 			cbo_modes->add(s_modes[j]);
140 			valid_modes.append(s_modes[j]).append("|");
141 			j++;
142 		}
143 	}
144 
145 	cbo_modes->index(progStatus.selected_mode);
146 }
147 
init_cbo_modes()148 void init_cbo_modes()
149 {
150 	string min_modes = "";
151 	min_modes.append("8PSK125|8PSK250|8PSK500|8PSK1000|8PSK1333");
152 	min_modes.append("|8PSK125F|8PSK125FL|8PSK250F|8PSK500F|8PSK1000F|8PSK1200F|8PSK1333F");
153 	min_modes.append("|BPSK31|BPSK63|BPSK63F|BPSK125|BPSK250|BPSK500|BPSK1000");
154 	min_modes.append("|DOMX22|DOMX44|DOMX88");
155 	min_modes.append("|MFSK16|MFSK22|MFSK31|MFSK32|MFSK64|MFSK64L|MFSK128|MFSK128L");
156 	min_modes.append("|MT63-500L|MT63-500S|MT63-1KL|MT63-1KS|MT63-2KL|MT63-2KS");
157 	min_modes.append("|Olivia-4-250|Olivia-4-500|Olivia-8-250|Olivia-8-500|Olivia-8-1K");
158 	min_modes.append("|Olivia-16-500|Olivia-16-1K|Olivia-32-1K|Olivia-64-2K");
159 	min_modes.append("|PSK63RC4|PSK63RC5|PSK63RC10|PSK63RC20|PSK63RC32");
160 	min_modes.append("|PSK125R|PSK125RC4|PSK125RC5|PSK125C12|PSK125RC10");
161 	min_modes.append("|PSK125RC12|PSK125RC16");
162 	min_modes.append("|PSK250R|PSK250C6|PSK250RC2|PSK250RC3|PSK250RC5|PSK250RC6|PSK250RC7");
163 	min_modes.append("|PSK500R|PSK500C2|PSK500C4|PSK500RC2|PSK500RC3|PSK500RC4");
164 	min_modes.append("|PSK800C2|PSK800RC2");
165 	min_modes.append("|PSK1000C2|PSK1000R|PSK1000RC2");
166 	min_modes.append("|QPSK31|QPSK63|QPSK125|QPSK250|QPSK500");
167 	min_modes.append("|THOR16|THOR22|THOR25x4|THOR50x1|THOR50x2|THOR100");
168 	update_cbo_modes(min_modes);
169 }
170 
valid_mode_check(string & md)171 bool valid_mode_check(string &md)
172 {
173 	return (valid_modes.find(md) != string::npos);
174 }
175 
clear_estimate()176 void clear_estimate() {
177 	transfer_size = 0;
178 	txt_xfr_size_time->value("");
179 }
180 
estimate()181 void estimate() {
182 	static char sz_xfr_size[30];
183 	float xfr_time = 0, overhead;
184 
185 	transfer_size = eval_transfer_size();
186 	if (transfer_size == 0) {
187 		txt_xfr_size_time->value("");
188 		return;
189 	}
190 
191 	xfr_time = seconds_from_c_string(cbo_modes->value(), evalstr.c_str(), transfer_size, &overhead);
192 	xfr_time += overhead;
193 
194 	if (xfr_time < 60)
195 		snprintf(sz_xfr_size, sizeof(sz_xfr_size), "%d bytes / %d secs",
196 			transfer_size, (int)(xfr_time + 0.5));
197 	else
198 		snprintf(sz_xfr_size, sizeof(sz_xfr_size), "%d bytes / %d m %d s",
199 			transfer_size,
200 			(int)(xfr_time / 60), ((int)xfr_time) % 60);
201 	txt_xfr_size_time->value(sz_xfr_size);
202 
203 }
204 
205 //======================================================================
206 
cb_mnu_folders(Fl_Menu_ *,void *)207 static void cb_mnu_folders(Fl_Menu_*, void*) {
208 	cb_folders();
209 }
210 
cb_mnuNew(Fl_Menu_ *,void *)211 static void cb_mnuNew(Fl_Menu_*, void*) {
212 	update_custom = false;
213 	cb_new();
214 }
215 
cb_mnuOpen(Fl_Menu_ *,void *)216 static void cb_mnuOpen(Fl_Menu_*, void*) {
217 	update_custom = false;
218 	cb_open();
219 }
220 
cb_mnuSave(Fl_Menu_ *,void *)221 static void cb_mnuSave(Fl_Menu_*, void*) {
222 	cb_save();
223 }
224 
cb_mnuSaveAs(Fl_Menu_ *,void *)225 static void cb_mnuSaveAs(Fl_Menu_*, void*) {
226 	cb_save_as();
227 }
228 
cb_mnu_html(Fl_Menu_ *,void *)229 static void cb_mnu_html(Fl_Menu_*, void*) {
230 	cb_html();
231 }
232 
cb_mnu_html_fcopy(Fl_Menu_ *,void *)233 static void cb_mnu_html_fcopy(Fl_Menu_*, void*) {
234 	cb_html_fcopy();
235 }
236 
cb_mnu_text(Fl_Menu_ *,void *)237 static void cb_mnu_text(Fl_Menu_*, void*) {
238 	cb_text();
239 }
240 
cb_mnu_qimport(Fl_Menu_ *,void *)241 static void cb_mnu_qimport(Fl_Menu_*, void*) {
242 	update_custom = false;
243 	cb_import();
244 }
245 
cb_mnu_qexport(Fl_Menu_ *,void *)246 static void cb_mnu_qexport(Fl_Menu_*, void*) {
247 	cb_export();
248 }
249 
cb_mnuWrapImport(Fl_Menu_ *,void *)250 static void cb_mnuWrapImport(Fl_Menu_*, void*) {
251 	update_custom = false;
252 	cb_wrap_import();
253 }
254 
cb_mnuWrapExport(Fl_Menu_ *,void *)255 static void cb_mnuWrapExport(Fl_Menu_*, void*) {
256 	cb_wrap_export();
257 }
258 
259 static int dbl_click_timeout = 2000;
260 static int dbl_click_time = 0;
261 
dbl_click_timer(void *)262 void dbl_click_timer(void *)
263 {
264 	dbl_click_time -= 50;
265 	if (dbl_click_time != 0)
266 		Fl::repeat_timeout(0.05, dbl_click_timer);
267 	return;
268 }
269 
cb_mnuAutoSend(Fl_Menu_ *,void *)270 static void cb_mnuAutoSend(Fl_Menu_*, void*) {
271 	if (dbl_click_time) return;
272 	dbl_click_time = dbl_click_timeout;
273 	Fl::add_timeout(0.05, dbl_click_timer);
274 	b_autosend = true;
275 	cb_wrap_autosend();
276 }
277 
cb_mnuExit(Fl_Menu_ *,void *)278 static void cb_mnuExit(Fl_Menu_*, void*) {
279 	cb_exit();
280 }
281 
cb_mnu_load_template(Fl_Menu_ *,void *)282 static void cb_mnu_load_template(Fl_Menu_*, void*) {
283 	cb_load_template();
284 }
285 
cb_mnu_save_template(Fl_Menu_ *,void *)286 static void cb_mnu_save_template(Fl_Menu_*, void*) {
287 	cb_save_template();
288 }
289 
cb_mnu_save_as_template(Fl_Menu_ *,void *)290 static void cb_mnu_save_as_template(Fl_Menu_*, void*) {
291 	cb_save_as_template();
292 }
293 
cb_mnuPersonalConfig(Fl_Menu_ *,void *)294 static void cb_mnuPersonalConfig(Fl_Menu_ *, void*) {
295 	cb_config_personal();
296 }
297 
cb_mnuDateTimeConfig(Fl_Menu_ *,void *)298 static void cb_mnuDateTimeConfig(Fl_Menu_ *, void*) {
299 	cb_config_date_time();
300 }
301 
cb_mnuConfigRadiogram(Fl_Menu_ *,void *)302 static void cb_mnuConfigRadiogram(Fl_Menu_ *, void*) {
303 	cb_config_radiogram();
304 }
305 
cb_mnuConfigFiles(Fl_Menu_ *,void *)306 static void cb_mnuConfigFiles(Fl_Menu_*, void*) {
307 	cb_config_files();
308 }
309 
cb_mnuConfigARQ(Fl_Menu_ *,void *)310 static void cb_mnuConfigARQ(Fl_Menu_ *, void*) {
311 	cb_config_arq();
312 }
313 
cb_mnuConfigUI(Fl_Menu_ *,void *)314 static void cb_mnuConfigUI(Fl_Menu_ *, void*) {
315 	cb_config_UI();
316 }
317 
cb_mnuOptions(Fl_Menu_ *,void *)318 static void cb_mnuOptions(Fl_Menu_*, void*) {
319 	showoptions();
320 }
321 
cb_mnuHeaders(Fl_Menu_ *,void *)322 static void cb_mnuHeaders(Fl_Menu_*, void*) {
323 	string tmp = hdr_from;
324 	while (tmp.length() && tmp[0] == '\n') tmp.erase(0,1);
325 	txt_hdr_from->value(tmp.c_str());
326 
327 	tmp = hdr_edit;
328 	while (tmp.length() && tmp[0] == '\n') tmp.erase(0,1);
329 	txt_hdr_edit->value(tmp.c_str());
330 	header_window->show();
331 }
332 
cb_btnSEND(Fl_Button *,void *)333 static void cb_btnSEND(Fl_Button*, void*) {
334 	arqSEND();
335 }
336 
cb_mnuEvents(Fl_Menu_ *,void *)337 static void cb_mnuEvents(Fl_Menu_*, void*) {
338 	debug::show();
339 }
340 
cb_mnuOnLineHelp(Fl_Menu_ *,void *)341 static void cb_mnuOnLineHelp(Fl_Menu_*, void*) {
342 	show_help();
343 }
344 
cb_mnuCustomDownload(Fl_Menu_ *,void *)345 static void cb_mnuCustomDownload(Fl_Menu_*, void*) {
346 	custom_download();
347 }
348 
cb_mnuAbout(Fl_Menu_ *,void *)349 static void cb_mnuAbout(Fl_Menu_*, void*) {
350 	cb_About();
351 }
352 
cb_ARC_SF_download(Fl_Menu_ *,void *)353 static void cb_ARC_SF_download(Fl_Menu_*, void *) {
354 	open_url("https://sourceforge.net/projects/fldigi/files/flmsg/templates/");
355 }
356 
cb_ARC_HKJ_download(Fl_Menu_ *,void *)357 static void cb_ARC_HKJ_download(Fl_Menu_*, void*) {
358 	open_url("http://www.w1hkj.com/files/flmsg/templates/");
359 }
360 
361 int mICS203 = ICS203;
362 int mICS205 = ICS205;
363 int mICS205A = ICS205A;
364 int mICS206 = ICS206;
365 int mICS213 = ICS213;
366 int mICS214 = ICS214;
367 int mICS216 = ICS216;
368 int mICS309 = ICS309;
369 int mNETLOG = NETLOG;
370 int mHICS203 = HICS203;
371 int mHICS206 = HICS206;
372 int mHICS213 = HICS213;
373 int mHICS214 = HICS214;
374 int mIARU = IARU;
375 int mRADIOGRAM = RADIOGRAM;
376 int mPLAINTEXT = PLAINTEXT;
377 int mBLANK = BLANK;
378 int mCSV = CSV;
379 int mCUSTOM = CUSTOM;
380 int mMARSDAILY = MARSDAILY;
381 int mMARSINEEI = MARSINEEI;
382 int mMARSNET = MARSNET;
383 int mMARSARMY = MARSARMY;
384 int mWXHC = WXHC;
385 int mSEVEREWX = SEVEREWX;
386 int mSTORMREP = STORMREP;
387 int mCAP105 = CAP105;
388 int mCAP110 = CAP110;
389 int mTRANSFER = TRANSFER;
390 
391 Fl_Group *oldtab = (Fl_Group *)0;
392 
select_plaintext()393 static void select_plaintext()
394 {
395 	oldtab = tab_plaintext;
396 	tab_plaintext->show();
397 	txt_formname->value(_("Plaintext message"));
398 	show_filename(def_pt_filename);
399 }
400 
select_ics203()401 static void select_ics203()
402 {
403 	oldtab = tab_ics203;
404 	tab_ics203->show();
405 	txt_formname->value(_("ICS-203 report"));
406 	show_filename(def_203_filename);
407 }
408 
select_ics205()409 static void select_ics205()
410 {
411 	oldtab = tab_ics205;
412 	tab_ics205->show();
413 	txt_formname->value(_("ICS-205 report"));
414 	show_filename(def_205_filename);
415 }
416 
select_ics205A()417 static void select_ics205A()
418 {
419 	oldtab = tab_ics205a;
420 	tab_ics205a->show();
421 	txt_formname->value(_("ICS-205A report"));
422 	show_filename(def_205a_filename);
423 }
424 
select_ics206()425 static void select_ics206()
426 {
427 	oldtab = tab_ics206;
428 	tab_ics206->show();
429 	tab_ics206_type->value(tab_206_med_plan);
430 	txt_formname->value(_("ICS-206 report"));
431 	show_filename(def_206_filename);
432 }
433 
select_ics213()434 static void select_ics213()
435 {
436 	oldtab = tab_ics213;
437 	txt_213_d1->local_datetime(progStatus.UTC < 2);
438 	txt_213_d2->local_datetime(progStatus.UTC < 2);
439 	tab_ics213->show();
440 	tab_ics213_type->value(tab_213_originator);
441 	txt_formname->value(_("ICS-213 report"));
442 	show_filename(def_213_filename);
443 }
444 
select_ics214()445 static void select_ics214()
446 {
447 	oldtab = tab_ics214;
448 	tab_ics214->show();
449 	tab_ics214_type->value(tab_214_1);
450 	txt_formname->value(_("ICS-214 report"));
451 	show_filename(def_214_filename);
452 }
453 
select_ics216()454 static void select_ics216()
455 {
456 	oldtab = tab_ics216;
457 	tab_ics216->show();
458 	tab_ics216_type->value(tab_216_1);
459 	txt_formname->value(_("ICS-216 report"));
460 	show_filename(def_216_filename);
461 }
462 
select_ics309()463 static void select_ics309()
464 {
465 	oldtab = tab_ics309;
466 	tab_ics309->show();
467 	tab_ics309_type->value(tab_309_1);
468 	txt_formname->value(_("ICS-309 report"));
469 	show_filename(def_309_filename);
470 }
471 
select_netlog()472 static void select_netlog()
473 {
474 	oldtab = tab_netlog;
475 	tab_netlog->show();
476 	tab_netlog_type->value(tab_netlog_1);
477 	txt_formname->value(_("Net Log report"));
478 	show_filename(def_netlog_filename);
479 }
480 
select_marsdaily()481 static void select_marsdaily()
482 {
483 	oldtab = tab_mars_daily;
484 	tab_mars_daily->show();
485 	txt_formname->value(_("MARS daily report"));
486 	show_filename(def_mars_daily_filename);
487 }
488 
select_marsineei()489 static void select_marsineei()
490 {
491 	oldtab = tab_mars_ineei;
492 	tab_mars_ineei->show();
493 	txt_formname->value(_("MARS IN/EEI report"));
494 	show_filename(def_mars_ineei_filename);
495 }
496 
select_marsnet()497 static void select_marsnet()
498 {
499 	oldtab = tab_mars_net;
500 	tab_mars_net->show();
501 	txt_formname->value(_("MARS Net report"));
502 	show_filename(def_mars_net_filename);
503 }
504 
select_marsarmy()505 static void select_marsarmy()
506 {
507 	oldtab = tab_mars_army;
508 	tab_mars_army->show();
509 	txt_formname->value(_("MARS Army message"));
510 	show_filename(def_mars_army_filename);
511 }
512 
select_wxhc()513 static void select_wxhc()
514 {
515 	oldtab = tab_wxhc;
516 	tab_wxhc->show();
517 	txt_formname->value(_("Hurricane Report"));
518 	show_filename(def_wxhc_filename);
519 }
520 
select_severewx()521 static void select_severewx()
522 {
523 	oldtab = tab_severe_wx;
524 	tab_severe_wx->show();
525 	txt_formname->value(_("Severe Wx Report"));
526 	show_filename(def_severe_wx_filename);
527 }
528 
select_stormrep()529 static void select_stormrep()
530 {
531 	oldtab = tab_storm;
532 	tab_storm->show();
533 	txt_formname->value(_("Storm Report"));
534 	show_filename(def_storm_filename);
535 }
536 
select_hics203()537 static void select_hics203()
538 {
539 	oldtab = tab_hics203;
540 	tab_hics203->show();
541 	txt_formname->value(_("HICS-203 report"));
542 	show_filename(def_hics203_filename);
543 }
544 
select_hics206()545 static void select_hics206()
546 {
547 	oldtab = h206_tab;
548 	h206_txt_date_prepared->local_datetime(progStatus.UTC < 2);
549 	h206_tab->show();
550 	txt_formname->value(_("HICS-206 report"));
551 	show_filename(h206_def_filename);
552 }
553 
select_hics213()554 static void select_hics213()
555 {
556 	oldtab = h213_tab;
557 	h213_txt_date->local_datetime(progStatus.UTC < 2);
558 	h213_tab->show();
559 	txt_formname->value(_("HICS-213 report"));
560 	show_filename(h213_def_filename);
561 }
562 
select_hics214()563 static void select_hics214()
564 {
565 	oldtab = hics214_tab;
566 	hics214_tab->show();
567 	txt_formname->value(_("HICS-214 report"));
568 	show_filename(hics214_def_filename);
569 }
570 
select_iaru()571 static void select_iaru()
572 {
573 	oldtab = tab_iaru;
574 	tab_iaru->show();
575 	txt_formname->value(_("IARU radiogram"));
576 	show_filename(iaru_def_filename);
577 }
578 
select_radiogram()579 static void select_radiogram()
580 {
581 	oldtab = tab_radiogram;
582 	tab_radiogram->show();
583 	txt_formname->value(_("ARRL radiogram"));
584 	show_filename(def_rg_filename);
585 }
586 
select_cap105()587 static void select_cap105()
588 {
589 	oldtab = tab_cap105;
590 	tab_cap105->show();
591 	txt_formname->value(_("CAP 105"));
592 	show_filename(cap105_def_filename);
593 }
594 
select_cap110()595 static void select_cap110()
596 {
597 	oldtab = tab_cap110;
598 	tab_cap110->show();
599 	txt_formname->value(_("CAP 110"));
600 	show_filename(cap110_def_filename);
601 }
602 
select_csv()603 static void select_csv()
604 {
605 	oldtab = tab_csv;
606 	tab_csv->show();
607 	txt_formname->value(_("CSV spreadsheet"));
608 	show_filename(def_csv_filename);
609 }
610 
select_custom()611 static void select_custom()
612 {
613 	oldtab = tab_custom;
614 	tab_custom->show();
615 	txt_formname->value(_("Custom Editable Html"));
616 	show_filename(def_custom_filename);
617 }
618 
select_transfer()619 static void select_transfer()
620 {
621 	oldtab = tab_transfer;
622 	tab_transfer->show();
623 	txt_formname->value(_("File transfer"));
624 	show_filename(def_transfer_filename);
625 }
626 
select_custom_transfer()627 static void select_custom_transfer()
628 {
629 	oldtab = tab_custom_transfer;
630 	tab_custom_transfer->show();
631 	txt_formname->value(_("FORM transfer"));
632 	show_filename(def_custom_transfer_filename);
633 	if (!def_custom_transfer_filename.empty())
634 		load_custom_html_file();
635 }
636 
select_form(int form)637 void select_form(int form)
638 {
639 	if (oldtab) oldtab->hide();
640 	if (tab_dnd->visible()) tab_dnd->hide();
641 	switch (form) {
642 		case PLAINTEXT:
643 			select_plaintext();
644 			break;
645 		case ICS203:
646 			select_ics203();
647 			break;
648 		case ICS205:
649 			select_ics205();
650 			break;
651 		case ICS205A:
652 			select_ics205A();
653 			break;
654 		case ICS206:
655 			select_ics206();
656 			break;
657 		case ICS213:
658 			select_ics213();
659 			break;
660 		case ICS214:
661 			select_ics214();
662 			break;
663 		case ICS216:
664 			select_ics216();
665 			break;
666 		case ICS309:
667 			select_ics309();
668 			break;
669 		case NETLOG:
670 			select_netlog();
671 			break;
672 		case MARSDAILY:
673 			select_marsdaily();
674 			break;
675 		case MARSINEEI:
676 			select_marsineei();
677 			break;
678 		case MARSNET:
679 			select_marsnet();
680 			break;
681 		case MARSARMY:
682 			select_marsarmy();
683 			break;
684 		case WXHC:
685 			select_wxhc();
686 			break;
687 		case SEVEREWX:
688 			select_severewx();
689 			break;
690 		case STORMREP:
691 			select_stormrep();
692 			break;
693 		case HICS203:
694 			select_hics203();
695 			break;
696 		case HICS206:
697 			select_hics206();
698 			break;
699 		case HICS213:
700 			select_hics213();
701 			break;
702 		case HICS214:
703 			select_hics214();
704 			break;
705 		case IARU:
706 			select_iaru();
707 			break;
708 		case RADIOGRAM:
709 			select_radiogram();
710 			break;
711 		case CAP105:
712 			select_cap105();
713 			break;
714 		case CAP110:
715 			select_cap110();
716 			break;
717 		case CSV:
718 			select_csv();
719 			break;
720 		case CUSTOM:
721 			select_custom();
722 			break;
723 		case TRANSFER:
724 			select_transfer();
725 			break;
726 		case CUSTOM_TRANSFER:
727 			select_custom_transfer();
728 			break;
729 		case BLANK:
730 		case NONE:
731 		default:
732 			oldtab = tab_blank;
733 			tab_blank->show();
734 			txt_formname->value(_("Blank form"));
735 			show_filename(def_blank_filename);
736 			break;
737 	}
738 	estimate();
739 }
740 
cb_mnuFormSelect(Fl_Menu_ *,void * d)741 static void cb_mnuFormSelect(Fl_Menu_*, void *d)
742 {
743 	int *pint = (int *)d;
744 	selected_form = *pint;
745 	select_form(selected_form);
746 }
747 
cb_mnuDragAndDrop(Fl_Menu_ *,void * d)748 static void cb_mnuDragAndDrop(Fl_Menu_*, void *d)
749 {
750 	if (!oldtab) return;
751 	if (tab_dnd->visible()) {
752 		tab_dnd->hide();
753 		oldtab->show();
754 	} else {
755 		oldtab->hide();
756 		tab_dnd->show();
757 	}
758 }
759 
cb_mnuARQrcvdmsgs(Fl_Menu_ *,void * d)760 static void cb_mnuARQrcvdmsgs(Fl_Menu_*, void *d)
761 {
762 	if (!rcvd_msgs_dialog) rcvd_msgs_dialog = create_rcvd_msgs_dialog();
763 	if (!rcvd_msgs_dialog->visible()) rcvd_msgs_dialog->show();
764 }
765 
766 Fl_Double_Window *event_dialog = (Fl_Double_Window *)0;
767 
768 extern void print_status(void *);
769 
cb_events(Fl_Menu_ *,void * d)770 static void cb_events(Fl_Menu_ *, void *d)
771 {
772 	if (event_dialog == 0) event_dialog = create_ARQ_event_dialog();
773 	print_status(0);
774 	event_dialog->show();
775 }
776 
777 #define NBR_CUSTOM_MENUS 200
778 Fl_Menu_Item custom_menu[NBR_CUSTOM_MENUS];
779 void load_custom_menu();
780 
781 Fl_Menu_Item menu_[] = {
782  {_("&File"), 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
783  {_("&Folders"), 0, (Fl_Callback*)cb_mnu_folders, 0, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
784  {_("&New"), 0x4006e,  (Fl_Callback*)cb_mnuNew, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
785  {_("&Open"), 0x4006f,  (Fl_Callback*)cb_mnuOpen, 0, 128, FL_NORMAL_LABEL, 0, 14, 0},
786  {_("&Save"), 0x40073,  (Fl_Callback*)cb_mnuSave, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
787  {_("Save &As"), 0x40061,  (Fl_Callback*)cb_mnuSaveAs, 0, 128, FL_NORMAL_LABEL, 0, 14, 0},
788  {_("View"), 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
789  {_("Html delivery"), 0,  (Fl_Callback*)cb_mnu_html, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
790  {_("Html file copy"), 0,  (Fl_Callback*)cb_mnu_html_fcopy, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
791  {_("Plain Text"), 0,  (Fl_Callback*)cb_mnu_text, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
792  {0,0,0,0,0,0,0,0,0},
793  {_("Q-forms"), 0,  0, 0, 192, FL_NORMAL_LABEL, 0, 14, 0},
794  {_("Import"), 0,  (Fl_Callback*)cb_mnu_qimport, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
795  {_("Export"), 0,  (Fl_Callback*)cb_mnu_qexport, 0, 128, FL_NORMAL_LABEL, 0, 14, 0},
796  {0,0,0,0,0,0,0,0,0},
797  {_("Wrap"), 0,  0, 0, 192, FL_NORMAL_LABEL, 0, 14, 0},
798  {_("Import"), 0,  (Fl_Callback*)cb_mnuWrapImport, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
799  {_("Export"), 0,  (Fl_Callback*)cb_mnuWrapExport, 0, 128, FL_NORMAL_LABEL, 0, 14, 0},
800  {0,0,0,0,0,0,0,0,0},
801  {_("E&xit"), 0x40078,  (Fl_Callback*)cb_mnuExit, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
802  {0,0,0,0,0,0,0,0,0},
803 
804  {_("F&orm"), 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
805 
806  {_("Drag-n-Drop"),  0,  (Fl_Callback*)cb_mnuDragAndDrop, 0, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
807  {_("Blank"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mBLANK, 0, FL_NORMAL_LABEL, 0, 14, 0},
808 
809  {_("CAP"), 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
810  {_("Form 105"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mCAP105, 0, FL_NORMAL_LABEL, 0, 14, 0},
811  {_("Form 110"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mCAP110, 0, FL_NORMAL_LABEL, 0, 14, 0},
812  {0,0,0,0,0,0,0,0,0},
813 
814  {_("CSV"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mCSV, 0, FL_NORMAL_LABEL, 0, 14, 0},
815 
816  {_("Custom"), 0, 0, (void*)custom_menu, FL_SUBMENU_POINTER},//, 0, FL_NORMAL_LABEL, 0, 14, 0},
817 
818  {_("Ham Forms"), 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
819  {_("NETLOG"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mNETLOG, 0, FL_NORMAL_LABEL, 0, 14, 0},
820  {0,0,0,0,0,0,0,0,0},
821 
822  {_("HICS"), 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
823  {_("HICS203"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mHICS203, 0, FL_NORMAL_LABEL, 0, 14, 0},
824  {_("HICS206"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mHICS206, 0, FL_NORMAL_LABEL, 0, 14, 0},
825  {_("HICS213"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mHICS213, 0, FL_NORMAL_LABEL, 0, 14, 0},
826  {_("HICS214"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mHICS214, 0, FL_NORMAL_LABEL, 0, 14, 0},
827  {0,0,0,0,0,0,0,0,0},
828 
829  {_("IARU"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mIARU, 0, FL_NORMAL_LABEL, 0, 14, 0},
830 
831  {_("ICS"), 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
832  {_("ICS203"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mICS203, 0, FL_NORMAL_LABEL, 0, 14, 0},
833  {_("ICS205"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mICS205, 0, FL_NORMAL_LABEL, 0, 14, 0},
834  {_("ICS205A"), 0, (Fl_Callback*)cb_mnuFormSelect, &mICS205A, 0, FL_NORMAL_LABEL, 0, 14, 0},
835  {_("ICS206"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mICS206, 0, FL_NORMAL_LABEL, 0, 14, 0},
836  {_("ICS213"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mICS213, 0, FL_NORMAL_LABEL, 0, 14, 0},
837  {_("ICS214"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mICS214, 0, FL_NORMAL_LABEL, 0, 14, 0},
838  {_("ICS216"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mICS216, 0, FL_NORMAL_LABEL, 0, 14, 0},
839  {_("ICS309"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mICS309, 0, FL_NORMAL_LABEL, 0, 14, 0},
840  {0,0,0,0,0,0,0,0,0},
841 
842  {_("MARS"), 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
843  {_("Daily"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mMARSDAILY, 0, FL_NORMAL_LABEL, 0, 14, 0},
844  {_("IN/EEI"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mMARSINEEI, 0, FL_NORMAL_LABEL, 0, 14, 0},
845  {_("Net"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mMARSNET, 0, FL_NORMAL_LABEL, 0, 14, 0},
846  {_("Army"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mMARSARMY, 0, FL_NORMAL_LABEL, 0, 14, 0},
847  {0,0,0,0,0,0,0,0,0},
848 
849  {_("Plaintext"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mPLAINTEXT, 0, FL_NORMAL_LABEL, 0, 14, 0},
850 
851  {_("Radiogram"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mRADIOGRAM, 0, FL_NORMAL_LABEL, 0, 14, 0},
852 
853  {_("Red Cross"), 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
854  {_("Download from Source Forge"), 0, (Fl_Callback*)cb_ARC_SF_download, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
855  {_("Download from W1HKJ web site"), 0, (Fl_Callback*)cb_ARC_HKJ_download, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
856  {0,0,0,0,0,0,0,0,0},
857 
858  {_("Transfer"), 0,  (Fl_Callback*)cb_mnuFormSelect, &mTRANSFER, 0, FL_NORMAL_LABEL, 0, 14, 0},
859 
860  {_("Weather"), 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
861  {_("Hurricane"), 0, (Fl_Callback*)cb_mnuFormSelect, &mWXHC, 0, FL_NORMAL_LABEL, 0, 14, 0},
862  {_("Severe WX"), 0, (Fl_Callback*)cb_mnuFormSelect, &mSEVEREWX, 0, FL_NORMAL_LABEL, 0, 14, 0},
863  {_("Storm Report"), 0, (Fl_Callback*)cb_mnuFormSelect, &mSTORMREP, 0, FL_NORMAL_LABEL, 0, 14, 0},
864  {0,0,0,0,0,0,0,0,0},
865  {0,0,0,0,0,0,0,0,0},
866 
867  {_("&Template"), 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
868  {_("Load"), 0,  (Fl_Callback*)cb_mnu_load_template, 0, 128, FL_NORMAL_LABEL, 0, 14, 0},
869  {_("Save"), 0,  (Fl_Callback*)cb_mnu_save_template, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
870  {_("Save As"), 0,  (Fl_Callback*)cb_mnu_save_as_template, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
871  {0,0,0,0,0,0,0,0,0},
872 
873  {_("&Config"), 0,  0, 0, 64 | FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
874  {_("Personal data"), 0,  (Fl_Callback*)cb_mnuPersonalConfig, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
875  {_("Date/Time"), 0,  (Fl_Callback*)cb_mnuDateTimeConfig, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
876  {_("Files/Formatting"), 0,  (Fl_Callback*)cb_mnuConfigFiles, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
877  {_("Radiogram"), 0,  (Fl_Callback*)cb_mnuConfigRadiogram, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
878  {_("ARQ interface"), 0,   (Fl_Callback*)cb_mnuConfigARQ, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
879  {_("User interface"), 0,   (Fl_Callback*)cb_mnuConfigUI, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
880  {0,0,0,0,0,0,0,0,0},
881 
882  {_("AutoSend"), 0,  (Fl_Callback*)cb_mnuAutoSend, 0, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
883 
884  {_("Utilities"), 0,  0, 0, 64 | FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
885  {_("Received Msgs"), 0, (Fl_Callback*)cb_mnuARQrcvdmsgs, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
886  {_("Events"), 0, (Fl_Callback*)cb_events, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
887  {0,0,0,0,0,0,0,0,0},
888 
889  {0,0,0,0,0,0,0,0,0}
890 };
891 
892 Fl_Menu_Item help_menu_[] = {
893  {_("&Help"), 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
894 #ifdef DEBUG
895  {_("Event log"), 0,  (Fl_Callback*)cb_mnuEvents, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
896 #endif
897  {_("Header trace"), 0,  (Fl_Callback*)cb_mnuHeaders, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
898  {_("Command line options"), 0,  (Fl_Callback*)cb_mnuOptions, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
899  {_("On Line help"), 0,  (Fl_Callback*)cb_mnuOnLineHelp, 0, 128, FL_NORMAL_LABEL, 0, 14, 0},
900  {_("Download custom forms"), 0, (Fl_Callback*)cb_mnuCustomDownload, 0, 128, FL_NORMAL_LABEL, 0, 14, 0},
901  {_("About"), 0,  (Fl_Callback*)cb_mnuAbout, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
902  {0,0,0,0,0,0,0,0,0},
903  {0,0,0,0,0,0,0,0,0}
904 };
905 
906 int num_custom_entries = 0;
907 int custom_select = -1;
908 
909 CUSTOM_PAIRS custom_pairs[NBR_CUSTOM_MENUS];
910 
911 extern void extract_fields();
912 
cb_mnuCustomFormSelect(Fl_Menu_ *,void * d)913 static void cb_mnuCustomFormSelect(Fl_Menu_ *, void *d) {
914 extern string edit_txt;
915 	size_t n = (size_t)(d);
916 	custom_select = n;
917 	selected_form = CUSTOM;
918 	select_form(selected_form);
919 	extract_fields();
920 	txt_custom_msg->clear();
921 	txt_custom_msg->add(edit_txt.c_str());
922 }
923 
cb_open_custom_transfer_tab(Fl_Menu_ *,void * d)924 static void cb_open_custom_transfer_tab(Fl_Menu_ *, void *d) {
925 	selected_form = CUSTOM_TRANSFER;
926 	select_form(selected_form);
927 }
928 
init_custom_menu()929 void init_custom_menu()
930 {
931 	for (int i = 0; i < NBR_CUSTOM_MENUS; i++) {
932 		custom_menu[i].text = 0;
933 		custom_menu[i].shortcut_ = 0;
934 		custom_menu[i].callback_ = (Fl_Callback*)cb_mnuFormSelect;
935 		custom_menu[i].user_data_ = (void *)&mCUSTOM,
936 		custom_menu[i].flags = 0;
937 		custom_menu[i].labeltype_ = FL_NORMAL_LABEL;
938 		custom_menu[i].labelfont_ = 0;
939 		custom_menu[i].labelsize_ = 14;
940 		custom_menu[i].labelcolor_ = 0;
941 		custom_pairs[i].mnu_name = 0;
942 		custom_pairs[i].file_name = 0;
943 	}
944 	num_custom_entries = 0;
945 }
946 
load_custom_menu()947 void load_custom_menu()
948 {
949 static const string key1 = "<META NAME=\"EDITABLE\" CONTENT=\"true\">";
950 static const string key2 = "<META NAME=\"MENU_ITEM\" CONTENT=";
951 	guard_lock web_lock(&mutex_web_server);
952 	for (int i = 0; i < NBR_CUSTOM_MENUS; i++) {
953 		custom_menu[i].text = 0;
954 		custom_menu[i].shortcut_ = 0;
955 		if (i)
956 			custom_menu[i].callback_ = (Fl_Callback*)cb_mnuCustomFormSelect;
957 		else
958 			custom_menu[i].callback_ = (Fl_Callback*)cb_open_custom_transfer_tab;
959 		custom_menu[i].user_data_ = 0;
960 		if (i)
961 			custom_menu[i].flags = 0;
962 		else
963 			custom_menu[i].flags = FL_MENU_DIVIDER;
964 		custom_menu[i].labeltype_ = FL_NORMAL_LABEL;
965 		custom_menu[i].labelfont_ = 0;
966 		custom_menu[i].labelsize_ = 14;
967 		custom_menu[i].labelcolor_ = 0;
968 		if (custom_pairs[i].mnu_name) delete [] custom_pairs[i].mnu_name;
969 		custom_pairs[i].mnu_name = 0;
970 		if (custom_pairs[i].file_name) delete [] custom_pairs[i].file_name;
971 		custom_pairs[i].file_name = 0;
972 	}
973 
974 	num_custom_entries = 0;
975 
976 	DIR *cdir = opendir(CUSTOM_dir.c_str());
977 	if (!cdir) return;
978 	dirent *dentry = 0;
979 	string contents;
980 	string fname;
981 	string menu_name;
982 	ifstream in;
983 	char cin;
984 	dentry = readdir(cdir);
985 	while (dentry) {
986 		fname = CUSTOM_dir;
987 		fname.append(dentry->d_name);
988 		if (fname.find(".htm") != string::npos) {
989 			contents.clear();
990 			in.open(fname.c_str(), ios::in);
991 			if (in) {
992 				while (in.get(cin))
993 					contents += cin;
994 				in.close();
995 				size_t p = string::npos;
996 				const char *ptr = strcasestr(contents.c_str(), key1.c_str());
997 				if (ptr) p = ptr - contents.c_str();
998 				if ( p != string::npos) {
999 					p = string::npos;
1000 					ptr = strcasestr(contents.c_str(), key2.c_str());
1001 					if (ptr) p = ptr - contents.c_str();
1002 					if (p != string::npos) {
1003 						p += key2.length() + 1;
1004 						contents.erase(0, p);
1005 						p = contents.find("\"");
1006 						menu_name = contents.substr(0, p);
1007 // custom pair item
1008 						custom_pairs[num_custom_entries].mnu_name =
1009 							new char[menu_name.length() + 1];
1010 						strcpy(
1011 							custom_pairs[num_custom_entries].mnu_name,
1012 							menu_name.c_str());
1013 
1014 						custom_pairs[num_custom_entries].file_name =
1015 							new char[strlen(dentry->d_name) + 1];
1016 						strcpy(
1017 							custom_pairs[num_custom_entries].file_name,
1018 							dentry->d_name);
1019 						num_custom_entries++;
1020 					}
1021 				}
1022 			}
1023 		}
1024 		dentry = readdir(cdir);
1025 	}
1026 	closedir(cdir);
1027 
1028 	for (int i = 0; i < num_custom_entries - 1; i++)
1029 		for (int j = i+1; j < num_custom_entries; j++)
1030 			if (strcmp(custom_pairs[j].mnu_name, custom_pairs[i].mnu_name) < 0) {
1031 				CUSTOM_PAIRS temp = custom_pairs[j];
1032 				custom_pairs[j] = custom_pairs[i];
1033 				custom_pairs[i] = temp;
1034 			}
1035 
1036 	custom_menu[0].text = "Transfer FORM";
1037 	custom_menu[0].user_data_ = 0;
1038 	for (int i = 0; i < num_custom_entries; i++) {
1039 // custom menu item
1040 		custom_menu[i+1].text       = custom_pairs[i].mnu_name;
1041 		custom_menu[i+1].user_data_ = reinterpret_cast<void *>(i);
1042 	}
1043 	update_custom_transfer();
1044 
1045 	if (temp_combo) {
1046 		temp_combo->clear();
1047 		temp_combo->add(_("Template not selected"));
1048 		for (int i = 0; i < num_custom_entries; i++)
1049 			temp_combo->add(custom_pairs[i].mnu_name);
1050 		temp_combo->index(0);
1051 	}
1052 
1053 }
1054 
1055 vector<string> custom_files;
1056 
update_custom_transfer()1057 void update_custom_transfer()
1058 {
1059 	string current_selection = custom_selector->value();
1060 	custom_files.clear();
1061 	custom_selector->clear();
1062 
1063 	if (num_custom_entries == 0) return;
1064 
1065 	for (int i = 0; i < num_custom_entries; i++) {
1066 		custom_selector->add(custom_pairs[i].mnu_name);
1067 		custom_files.push_back(custom_pairs[i].file_name);
1068 	}
1069 	if (current_selection.empty())
1070 		custom_selector->index(0);
1071 	else
1072 		custom_selector->value(current_selection.c_str());
1073 	def_custom_transfer_filename = custom_files[custom_selector->index()];
1074 }
1075 
load_custom_transfer()1076 void load_custom_transfer()
1077 {
1078 	if (tab_custom_transfer->visible()) return;
1079 	update_custom_transfer();
1080 }
1081 
1082 //------------------------------------------------------------------------------
1083 
1084 extern void drop_file_changed();
cb_drop_file(Fl_Input *,void *)1085 static void cb_drop_file(Fl_Input*, void*) {
1086 	drop_file_changed();
1087 }
1088 
cb_btn_estimate()1089 void cb_btn_estimate()
1090 {
1091 	estimate();
1092 }
1093 
cb_use_compression()1094 void cb_use_compression()
1095 {
1096 	progStatus.use_compression = btn_use_compression->value();
1097 	estimate();
1098 }
1099 
cb_cbo_modes()1100 void cb_cbo_modes()
1101 {
1102 	estimate();
1103 	if (!progStatus.change_modem_with_autosend)
1104 		send_new_modem();
1105 }
1106 
1107 
flmsg_dialog()1108 Fl_Double_Window* flmsg_dialog() {
1109 	int W = 570, H = 492;
1110 	Fl_Double_Window* win = new Fl_Double_Window(W, H, "");
1111 	win->begin();
1112 	win->align(FL_ALIGN_INSIDE);
1113 
1114 	mb = new Fl_Menu_Bar(0, 0, W - 60, 22);
1115 
1116 	mb->menu(menu_);
1117 	init_custom_menu();
1118 
1119 	Fl_Menu_Bar *hm = new Fl_Menu_Bar(W-60, 0, 60, 22);
1120 	hm->menu(help_menu_);
1121 
1122 	txt_formname = new Fl_Output(4, 26, 220, 20);
1123 	txt_formname->box(FL_FLAT_BOX);
1124 	txt_formname->color(fl_rgb_color(245, 245, 245)); // white smoke
1125 
1126 	txt_filename = new Fl_Output(260, 26, 270, 20, _("file:"));
1127 	txt_filename->box(FL_FLAT_BOX);
1128 	txt_filename->align(FL_ALIGN_LEFT);
1129 	txt_filename->color(fl_rgb_color(245, 245, 245));
1130 
1131 	drop_file = new Fl_Input2(
1132 		txt_filename->x() + txt_filename->w() + 2, 23,
1133 		W - txt_filename->x() - txt_filename->w() - 2, 25);
1134 	drop_file->box(FL_THIN_DOWN_BOX);
1135 	drop_file->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE);
1136 	drop_file->value("");
1137 	drop_file->color(fl_rgb_color(108, 166, 205));
1138 	drop_file->cursor_color(fl_rgb_color(108, 166, 205));
1139 	drop_file->labelcolor( fl_rgb_color( 205, 55, 0) );
1140 	drop_file->label("DnD");
1141 	drop_file->tooltip(_("drag and drop files here ..."));
1142 	drop_file->callback((Fl_Callback*)cb_drop_file);
1143 	drop_file->when(FL_WHEN_CHANGED);
1144 
1145 	tab_top = 46;
1146 
1147 	all_tabs = new Fl_Group(0, tab_top, 570, 390);
1148 		create_ics_tab();
1149 		create_hics_tab();
1150 		create_netlog_tab();
1151 		create_mars_tab();
1152 		create_cap105_tab();
1153 		create_cap110_tab();
1154 		create_iaru_tab();
1155 		create_radiogram_tab();
1156 		create_plaintext_tab();
1157 		create_blank_tab();
1158 		create_csv_tab();
1159 		create_custom_tab();
1160 		create_dnd_tab();
1161 		create_wxhc_tab();
1162 		create_severe_wx_tab();
1163 		create_storm_tab();
1164 		create_transfer_tab();
1165 		create_custom_transfer_tab();
1166 	all_tabs->end();
1167 
1168 	controls = new Fl_Group(0, 465 - 30, W, 28, "controls");
1169 	controls->begin();
1170 	controls->box(FL_ENGRAVED_BOX);
1171 	controls->align(FL_ALIGN_INSIDE);
1172 	controls->copy_label("");
1173 
1174 	btn_use_compression = new Fl_Check_Button(
1175 		10, controls->y() + 5,
1176 		60, 18, _("Comp"));
1177 	btn_use_compression->tooltip(_("Data will be sent compressed\nif file size is reduced"));
1178 	btn_use_compression->down_box(FL_DOWN_BOX);
1179 	btn_use_compression->callback((Fl_Callback*)cb_use_compression);
1180 	btn_use_compression->value(progStatus.use_compression);
1181 
1182 	cbo_modes = new Fl_ListBox(
1183 		btn_use_compression->x() + btn_use_compression->w() + 2,
1184 		controls->y() + 3, 120, 22, "cbo_modes");
1185 	cbo_modes->begin();
1186 	cbo_modes->copy_label("");
1187 	cbo_modes->align(FL_ALIGN_INSIDE);
1188 	cbo_modes->when(FL_WHEN_RELEASE);
1189 	cbo_modes->tooltip(_("fldigi modem type"));
1190 	cbo_modes->box(FL_DOWN_BOX);
1191 	cbo_modes->color(FL_BACKGROUND2_COLOR);
1192 	cbo_modes->selection_color(FL_BACKGROUND_COLOR);
1193 	cbo_modes->labeltype(FL_NORMAL_LABEL);
1194 	cbo_modes->labelfont(0);
1195 	cbo_modes->labelsize(14);
1196 	cbo_modes->labelcolor(FL_FOREGROUND_COLOR);
1197 	cbo_modes->callback((Fl_Callback*)cb_cbo_modes);
1198 	cbo_modes->end();
1199 
1200 	btn_estimate = new Fl_Button(
1201 		cbo_modes->x() + cbo_modes->w() + 2,
1202 		cbo_modes->y() + 2, 18, 18, "*");
1203 	btn_estimate->tooltip(_("Press to update size/time"));
1204 	btn_estimate->callback((Fl_Callback*)cb_btn_estimate);
1205 
1206 	txt_xfr_size_time = new Fl_Output(
1207 		btn_estimate->x() + btn_estimate->w() + 2,
1208 		cbo_modes->y(),
1209 		controls->w() - btn_estimate->x() - btn_estimate->w() - 4, 22, "");
1210 	txt_xfr_size_time->tooltip(_("Transfer size / time"));
1211 
1212 	controls->end();
1213 
1214 	arq_group = new Fl_Group(0, H - 28, W, 26);
1215 		arq_group->box(FL_ENGRAVED_FRAME);
1216 
1217 		Fl_Group  *arq_title = new Fl_Group(2, arq_group->y()+2, 40, 22, "ARQ");
1218 		arq_title->box(FL_FLAT_BOX);
1219 		arq_title->labeltype(FL_NORMAL_LABEL);
1220 		arq_title->labelfont(0);
1221 		arq_title->labelsize(14);
1222 		arq_title->labelcolor(FL_FOREGROUND_COLOR);
1223 		arq_title->align(Fl_Align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE));
1224 		arq_title->end();
1225 
1226 		btnSEND = new Fl_Button(42, arq_group->y()+2, 60, 22, _("Send"));
1227 		btnSEND->tooltip(_("Send data file to this station"));
1228 		btnSEND->callback((Fl_Callback*)cb_btnSEND);
1229 
1230 		txtSENDTO = new Fl_Input2(108, arq_group->y()+2, 100, 22);
1231 		txtSENDTO->tooltip(_("Send to this station"));
1232 		txtSENDTO->box(FL_DOWN_BOX);
1233 		txtSENDTO->color(FL_BACKGROUND2_COLOR);
1234 		txtSENDTO->selection_color(FL_SELECTION_COLOR);
1235 		txtSENDTO->labeltype(FL_NORMAL_LABEL);
1236 		txtSENDTO->labelfont(0);
1237 		txtSENDTO->labelsize(14);
1238 		txtSENDTO->labelcolor(FL_FOREGROUND_COLOR);
1239 		txtSENDTO->align(Fl_Align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE));
1240 		txtSENDTO->when(FL_WHEN_RELEASE);
1241 
1242 		txtSTATE = new Fl_Input2(210, arq_group->y()+2, 200, 22, "");
1243 		txtSTATE->box(FL_FLAT_BOX);
1244 		txtSTATE->color(FL_BACKGROUND_COLOR);
1245 		txtSTATE->selection_color(FL_SELECTION_COLOR);
1246 		txtSTATE->labeltype(FL_NORMAL_LABEL);
1247 		txtSTATE->labelfont(0);
1248 		txtSTATE->labelsize(14);
1249 		txtSTATE->labelcolor(FL_BLACK);
1250 		txtSTATE->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE));
1251 		txtSTATE->when(FL_WHEN_RELEASE);
1252 		txtSTATE->type(FL_NORMAL_OUTPUT);
1253 
1254 		prgSTATE = new Fl_Progress(W - 74, arq_group->y()+3, 70, 20);
1255 		prgSTATE->tooltip(_("ARQ transfer progress"));
1256 		prgSTATE->selection_color((Fl_Color)70);
1257 		prgSTATE->labelfont(1);
1258 		prgSTATE->minimum(0.0);
1259 		prgSTATE->maximum(1.0);
1260 
1261 	arq_group->end();
1262 
1263 	win->end();
1264 
1265 	win->resizable(all_tabs);
1266 
1267 	init_cbo_modes();
1268 
1269 	return win;
1270 }
1271 
cb_btnCloseOptions(Fl_Return_Button *,void *)1272 static void cb_btnCloseOptions(Fl_Return_Button*, void*) {
1273 	closeoptions();
1274 }
1275 
1276 static int opt_col_sizes[] = {200, 0};
1277 
optionsdialog()1278 Fl_Double_Window* optionsdialog() {
1279 	int H = 300, W = 560;
1280 	Fl_Double_Window* w = new Fl_Double_Window(W, H, _("Command Line Options"));
1281 
1282 	brwsOptions = new Fl_Browser(2, 2, W - 4, H - 4 - 5 - 20);
1283 	brwsOptions->column_widths(opt_col_sizes);
1284 
1285 	btnCloseOptions = new Fl_Return_Button(W - 4 - 72, H - 5 - 20, 72, 20, _("OK"));
1286 	btnCloseOptions->callback((Fl_Callback*)cb_btnCloseOptions);
1287 
1288 	w->end();
1289 
1290 	return w;
1291 }
1292 
cb_select_arl(Fl_Browser * o,void *)1293 static void cb_select_arl(Fl_Browser* o, void*) {
1294 	arl_nbr = o->value()- 1;
1295 arl_text->clear();
1296 arl_text->addstr(arl_list[arl_nbr].text);
1297 txt_arl_fill1->value("");
1298 txt_arl_fill1->deactivate();
1299 txt_arl_fill2->value("");
1300 txt_arl_fill2->deactivate();
1301 txt_arl_fill3->value("");
1302 txt_arl_fill3->deactivate();
1303 txt_arl_fill4->value("");
1304 txt_arl_fill4->deactivate();
1305 if (arl_list[arl_nbr].nfills > 0) txt_arl_fill1->activate();
1306 if (arl_list[arl_nbr].nfills > 1) txt_arl_fill2->activate();
1307 if (arl_list[arl_nbr].nfills > 2) txt_arl_fill3->activate();
1308 if (arl_list[arl_nbr].nfills > 3) txt_arl_fill4->activate();
1309 }
1310 
cb_btn_arl_cancel(Fl_Button *,void *)1311 static void cb_btn_arl_cancel(Fl_Button*, void*) {
1312 	cb_arl_cancel();
1313 }
1314 
cb_btn_arl_add(Fl_Button *,void *)1315 static void cb_btn_arl_add(Fl_Button*, void*) {
1316 	cb_arl_add();
1317 }
1318 
cb_btnInsertX(Fl_Check_Button * o,void *)1319 static void cb_btnInsertX(Fl_Check_Button* o, void*) {
1320 	progStatus.insert_x = o->value();
1321 }
1322 
arl_dialog()1323 Fl_Double_Window* arl_dialog() {
1324 	Fl_Double_Window* w = new Fl_Double_Window(521, 261, _("ARL Message Selector"));
1325 		w->begin();
1326 		select_arl = new Fl_Browser(6, 21, 161, 107, _("ARL #"));
1327 		select_arl->type(2);
1328 		select_arl->callback((Fl_Callback*)cb_select_arl);
1329 		select_arl->align(FL_ALIGN_TOP);
1330 
1331 		txt_arl_fill1 = new Fl_Input2(48, 131, 465, 22, _("fill 1:"));
1332 
1333 		txt_arl_fill2 = new Fl_Input2(48, 155, 465, 22, _("fill 2:"));
1334 
1335 		txt_arl_fill3 = new Fl_Input2(48, 179, 465, 22, _("fill 3:"));
1336 
1337 		txt_arl_fill4 = new Fl_Input2(48, 204, 465, 22, _("fill 4:"));
1338 
1339 		btn_arl_cancel = new Fl_Button(362, 232, 70, 20, _("Cancel"));
1340 		btn_arl_cancel->callback((Fl_Callback*)cb_btn_arl_cancel);
1341 
1342 		btn_arl_add = new Fl_Button(440, 232, 70, 20, _("Add"));
1343 		btn_arl_add->callback((Fl_Callback*)cb_btn_arl_add);
1344 
1345 		arl_text = new FTextEdit(169, 21, 345, 107, _("Message:"));
1346 		arl_text->tooltip(_("Message contents - recommend limit to 25 words or less"));
1347 		arl_text->box(FL_DOWN_BOX);
1348 		arl_text->color((Fl_Color)FL_LIGHT3);
1349 		arl_text->selection_color((Fl_Color)FL_SELECTION_COLOR);
1350 		arl_text->labeltype(FL_NORMAL_LABEL);
1351 		arl_text->labelfont(0);
1352 		arl_text->labelsize(14);
1353 		arl_text->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
1354 		arl_text->align(FL_ALIGN_TOP_LEFT);
1355 		arl_text->when(FL_WHEN_RELEASE);
1356 		Fl_Group::current()->resizable(arl_text);
1357 
1358 		btnInsertX = new Fl_Check_Button(18, 234, 201, 15, _("Insert \"X\" between fields"));
1359 		btnInsertX->down_box(FL_DOWN_BOX);
1360 		btnInsertX->callback((Fl_Callback*)cb_btnInsertX);
1361 		btnInsertX->value(progStatus.insert_x);
1362 		w->end();
1363 	return w;
1364 }
1365 
1366 Fl_ListBox	*sel_hx_select = (Fl_ListBox *)0;
1367 
cb_sel_hx_select(Fl_ListBox *,void *)1368 static void cb_sel_hx_select(Fl_ListBox*, void*) {
1369 	cb_hx_select();
1370 }
1371 
1372 Fl_Button	*btn_hx_select_add = (Fl_Button *)0;
1373 
cb_btn_hx_select_add(Fl_Button *,void *)1374 static void cb_btn_hx_select_add(Fl_Button*, void*) {
1375 	cb_hx_select_add();
1376 }
1377 
1378 Fl_Input2	*txt_hx_select_text = (Fl_Input2 *)0;
1379 
1380 Fl_Button	*btn_hx_select_cancel = (Fl_Button *)0;
1381 
cb_btn_hx_select_cancel(Fl_Button *,void *)1382 static void cb_btn_hx_select_cancel(Fl_Button*, void*) {
1383 	cb_hx_select_cancel();
1384 }
1385 
1386 Fl_Return_Button	*btn_hx_select_ok = (Fl_Return_Button *)0;
1387 
cb_btn_hx_select_ok(Fl_Return_Button *,void *)1388 static void cb_btn_hx_select_ok(Fl_Return_Button*, void*) {
1389 	cb_hx_select_ok();
1390 }
1391 
1392 Fl_Output	*txt_hx_instructions = (Fl_Output *)0;
1393 
hx_dialog()1394 Fl_Double_Window* hx_dialog() {
1395 	Fl_Double_Window* w = new Fl_Double_Window(359, 121, _("Optional Handling"));
1396 
1397 	w->begin();
1398 
1399 		sel_hx_select = new Fl_ListBox(3, 20, 68, 24, _("HX__:"));
1400 		sel_hx_select->callback((Fl_Callback*)cb_sel_hx_select);
1401 		sel_hx_select->align(FL_ALIGN_TOP_LEFT);
1402 
1403 		btn_hx_select_add = new Fl_Button(73, 20, 30, 24, _("=>"));
1404 		btn_hx_select_add->callback((Fl_Callback*)cb_btn_hx_select_add);
1405 
1406 		txt_hx_select_text = new Fl_Input2(105, 20, 121, 24, _("HX text"));
1407 		txt_hx_select_text->box(FL_DOWN_BOX);
1408 		txt_hx_select_text->color((Fl_Color)FL_BACKGROUND2_COLOR);
1409 		txt_hx_select_text->selection_color((Fl_Color)FL_SELECTION_COLOR);
1410 		txt_hx_select_text->labeltype(FL_NORMAL_LABEL);
1411 		txt_hx_select_text->labelfont(0);
1412 		txt_hx_select_text->labelsize(14);
1413 		txt_hx_select_text->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
1414 		txt_hx_select_text->align(FL_ALIGN_TOP_LEFT);
1415 		txt_hx_select_text->when(FL_WHEN_RELEASE);
1416 
1417 		btn_hx_select_cancel = new Fl_Button(229, 20, 60, 24, _("Cancel"));
1418 		btn_hx_select_cancel->callback((Fl_Callback*)cb_btn_hx_select_cancel);
1419 
1420 		btn_hx_select_ok = new Fl_Return_Button(293, 20, 60, 24, _("OK"));
1421 		btn_hx_select_ok->callback((Fl_Callback*)cb_btn_hx_select_ok);
1422 
1423 		txt_hx_instructions = new Fl_Output(5, 47, 348, 70);
1424 		txt_hx_instructions->type(12);
1425 		txt_hx_instructions->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
1426 
1427 	w->end();
1428 	return w;
1429 }
1430 
headers_dialog()1431 Fl_Double_Window* headers_dialog() {
1432 	Fl_Double_Window* w = new Fl_Double_Window(500, 200, _("Transfer/Edit trail"));
1433 
1434 	w->begin();
1435 
1436 	txt_hdr_from = new Fl_Input2(50, 30, 440, 80, _("From:"));
1437 	txt_hdr_from->type(4);
1438 
1439 	txt_hdr_edit = new Fl_Input2(50, 115, 440, 80, _("Edit:"));
1440 	txt_hdr_edit->type(4);
1441 
1442 	w->end();
1443 
1444 	return w;
1445 }
1446 
1447 //==============================================================================
1448 // configuration dialog
1449 //==============================================================================
1450 Fl_Round_Button		*btn_dtformat0 = (Fl_Round_Button *)0;
1451 Fl_Round_Button		*btn_dtformat1 = (Fl_Round_Button *)0;
1452 Fl_Round_Button		*btn_dtformat2 = (Fl_Round_Button *)0;
1453 Fl_Round_Button		*btn_dtformat3 = (Fl_Round_Button *)0;
1454 Fl_Round_Button		*btn_dtformat4 = (Fl_Round_Button *)0;
1455 Fl_Round_Button		*btn_utc_format0 = (Fl_Round_Button *)0;
1456 Fl_Round_Button		*btn_utc_format1 = (Fl_Round_Button *)0;
1457 Fl_Round_Button		*btn_utc_format2 = (Fl_Round_Button *)0;
1458 Fl_Round_Button		*btn_utc_format3 = (Fl_Round_Button *)0;
1459 Fl_Round_Button		*btn_utc_format4 = (Fl_Round_Button *)0;
1460 Fl_Round_Button		*btn_utc_format5 = (Fl_Round_Button *)0;
1461 Fl_Check_Button		*btn_caplocal = (Fl_Check_Button *)0;
1462 
1463 Fl_Input2			*txt_my_call = (Fl_Input2 *)0;
1464 Fl_Input2			*txt_my_tel = (Fl_Input2 *)0;
1465 Fl_Input2			*txt_my_name = (Fl_Input2 *)0;
1466 Fl_Input2			*txt_my_addr = (Fl_Input2 *)0;
1467 Fl_Input2			*txt_my_city = (Fl_Input2 *)0;
1468 Fl_Input2			*txt_my_email = (Fl_Input2 *)0;
1469 
1470 Fl_Check_Button		*btn_open_on_export = (Fl_Check_Button *)0;
1471 Fl_Check_Button		*btn_call_fname = (Fl_Check_Button *)0;
1472 Fl_ListBox			*cbo_dt_fname = (Fl_ListBox *)0;
1473 Fl_Check_Button		*btn_sernbr_fname = (Fl_Check_Button *)0;
1474 Fl_Input2			*txt_sernbr = (Fl_Input2 *)0;
1475 
1476 Fl_Spinner			*cnt_wpl = (Fl_Spinner *)0;
1477 Fl_Check_Button		*btn_rgnbr_fname = (Fl_Check_Button *)0;
1478 Fl_Check_Button		*btn_arl_desc = (Fl_Check_Button *)0;
1479 Fl_Check_Button		*btn_rri = (Fl_Check_Button *)0;
1480 Fl_Input2			*txt_rgnbr = (Fl_Input2 *)0;
1481 
1482 Fl_Input2 * txt_socket_addr = (Fl_Input2 *)0;
1483 Fl_Input2 * txt_socket_port = (Fl_Input2 *)0;
1484 
set_datetime_widgets()1485 void set_datetime_widgets()
1486 {
1487 	txt_213_d1->format(progStatus.dtformat);
1488 	txt_213_d2->format(progStatus.dtformat);
1489 	h206_txt_date_prepared->format(progStatus.dtformat);
1490 	h213_txt_date->format(progStatus.dtformat);
1491 	txt_pt_date->format(progStatus.dtformat);
1492 	w_storm_date->format(progStatus.dtformat);
1493 	w_severe_wx_date->format(progStatus.dtformat);
1494 }
1495 
cb_btn_dtformat0(Fl_Round_Button * o,void *)1496 static void cb_btn_dtformat0(Fl_Round_Button* o, void*)
1497 {
1498 	btn_dtformat3->value(0);
1499 	btn_dtformat1->value(0);
1500 	btn_dtformat2->value(0);
1501 	btn_dtformat4->value(0);
1502 	if (o->value()) {
1503 		progStatus.dtformat = 0;
1504 	} else {
1505 		btn_dtformat4->value(1);
1506 		progStatus.dtformat = 4;
1507 	}
1508 	set_datetime_widgets();
1509 }
1510 
cb_btn_dtformat1(Fl_Round_Button * o,void *)1511 static void cb_btn_dtformat1(Fl_Round_Button* o, void*)
1512 {
1513 	btn_dtformat0->value(0);
1514 	btn_dtformat3->value(0);
1515 	btn_dtformat2->value(0);
1516 	btn_dtformat4->value(0);
1517 	if (o->value()) {
1518 		progStatus.dtformat = 1;
1519 	} else {
1520 		btn_dtformat4->value(1);
1521 		progStatus.dtformat = 4;
1522 	}
1523 	set_datetime_widgets();
1524 }
1525 
cb_btn_dtformat2(Fl_Round_Button * o,void *)1526 static void cb_btn_dtformat2(Fl_Round_Button* o, void*)
1527 {
1528 	btn_dtformat0->value(0);
1529 	btn_dtformat1->value(0);
1530 	btn_dtformat3->value(0);
1531 	btn_dtformat4->value(0);
1532 	if (o->value()) {
1533 		progStatus.dtformat = 2;
1534 	} else {
1535 		btn_dtformat4->value(1);
1536 		progStatus.dtformat = 4;
1537 	}
1538 	set_datetime_widgets();
1539 }
1540 
cb_btn_dtformat3(Fl_Round_Button * o,void *)1541 static void cb_btn_dtformat3(Fl_Round_Button* o, void*)
1542 {
1543 	btn_dtformat0->value(0);
1544 	btn_dtformat1->value(0);
1545 	btn_dtformat2->value(0);
1546 	btn_dtformat4->value(0);
1547 	if (o->value()) {
1548 		progStatus.dtformat = 3;
1549 	} else {
1550 		btn_dtformat4->value(1);
1551 		progStatus.dtformat = 4;
1552 	}
1553 	set_datetime_widgets();
1554 }
1555 
cb_btn_dtformat4(Fl_Round_Button * o,void *)1556 static void cb_btn_dtformat4(Fl_Round_Button* o, void*)
1557 {
1558 	btn_dtformat0->value(0);
1559 	btn_dtformat1->value(0);
1560 	btn_dtformat2->value(0);
1561 	btn_dtformat3->value(0);
1562 	btn_dtformat4->value(1);
1563 
1564 	progStatus.dtformat = 4;
1565 
1566 	set_datetime_widgets();
1567 }
1568 
cb_btn_utc_format0(Fl_Round_Button * o,void *)1569 static void cb_btn_utc_format0(Fl_Round_Button* o, void*)
1570 {
1571 	if (o->value()) {
1572 		progStatus.UTC = 0;
1573 		btn_utc_format1->value(0);
1574 		btn_utc_format2->value(0);
1575 		btn_utc_format3->value(0);
1576 		btn_utc_format4->value(0);
1577 		btn_utc_format5->value(0);
1578 	}
1579 }
1580 
cb_btn_utc_format1(Fl_Round_Button * o,void *)1581 static void cb_btn_utc_format1(Fl_Round_Button* o, void*)
1582 {
1583 	if (o->value()) {
1584 		progStatus.UTC = 1;
1585 		btn_utc_format0->value(0);
1586 		btn_utc_format2->value(0);
1587 		btn_utc_format3->value(0);
1588 		btn_utc_format4->value(0);
1589 		btn_utc_format5->value(0);
1590 	}
1591 }
1592 
cb_btn_utc_format2(Fl_Round_Button * o,void *)1593 static void cb_btn_utc_format2(Fl_Round_Button* o, void*)
1594 {
1595 	if (o->value()) {
1596 		progStatus.UTC = 2;
1597 		btn_utc_format1->value(0);
1598 		btn_utc_format0->value(0);
1599 		btn_utc_format3->value(0);
1600 		btn_utc_format4->value(0);
1601 		btn_utc_format5->value(0);
1602 	}
1603 }
1604 
cb_btn_utc_format3(Fl_Round_Button * o,void *)1605 static void cb_btn_utc_format3(Fl_Round_Button* o, void*)
1606 {
1607 	if (o->value()) {
1608 		progStatus.UTC = 3;
1609 		btn_utc_format1->value(0);
1610 		btn_utc_format2->value(0);
1611 		btn_utc_format0->value(0);
1612 		btn_utc_format4->value(0);
1613 		btn_utc_format5->value(0);
1614 	}
1615 }
1616 
cb_btn_utc_format4(Fl_Round_Button * o,void *)1617 static void cb_btn_utc_format4(Fl_Round_Button* o, void*)
1618 {
1619 	if (o->value()) {
1620 		progStatus.UTC = 4;
1621 		btn_utc_format1->value(0);
1622 		btn_utc_format2->value(0);
1623 		btn_utc_format3->value(0);
1624 		btn_utc_format0->value(0);
1625 		btn_utc_format5->value(0);
1626 	}
1627 }
1628 
cb_btn_utc_format5(Fl_Round_Button * o,void *)1629 static void cb_btn_utc_format5(Fl_Round_Button* o, void*)
1630 {
1631 	if (o->value()) {
1632 		progStatus.UTC = 5;
1633 		btn_utc_format1->value(0);
1634 		btn_utc_format2->value(0);
1635 		btn_utc_format3->value(0);
1636 		btn_utc_format4->value(0);
1637 		btn_utc_format0->value(0);
1638 	}
1639 }
1640 
cb_caplocal(Fl_Check_Button * o,void *)1641 static void cb_caplocal(Fl_Check_Button *o, void*)
1642 {
1643 	if (o->value())
1644 		progStatus.caplocal = true;
1645 	else
1646 		progStatus.caplocal = false;
1647 }
1648 
cb_txt_my_call(Fl_Input * o,void *)1649 static void cb_txt_my_call(Fl_Input* o, void*)
1650 {
1651 	progStatus.my_call = o->value();
1652 }
1653 
cb_txt_my_tel(Fl_Input * o,void *)1654 static void cb_txt_my_tel(Fl_Input* o, void*)
1655 {
1656 	progStatus.my_tel = o->value();
1657 }
1658 
cb_txt_my_name(Fl_Input * o,void *)1659 static void cb_txt_my_name(Fl_Input* o, void*)
1660 {
1661 	progStatus.my_name = o->value();
1662 }
1663 
cb_txt_my_addr(Fl_Input * o,void *)1664 static void cb_txt_my_addr(Fl_Input* o, void*)
1665 {
1666 	progStatus.my_addr = o->value();
1667 }
1668 
cb_txt_my_email(Fl_Input * o,void *)1669 static void cb_txt_my_email(Fl_Input* o, void*)
1670 {
1671 	progStatus.my_email = o->value();
1672 }
1673 
cb_txt_my_city(Fl_Input * o,void *)1674 static void cb_txt_my_city(Fl_Input* o, void*)
1675 {
1676 	progStatus.my_city = o->value();
1677 }
1678 
cb_cnt_wpl(Fl_Spinner * o,void *)1679 static void cb_cnt_wpl(Fl_Spinner* o, void*)
1680 {
1681 	progStatus.wpl = (int)o->value();
1682 }
1683 
cb_btn_open_on_export(Fl_Check_Button * o,void *)1684 static void cb_btn_open_on_export(Fl_Check_Button* o, void*)
1685 {
1686 	progStatus.open_on_export = o->value();
1687 }
1688 
cb_btn_call_fname(Fl_Check_Button * o,void *)1689 static void cb_btn_call_fname(Fl_Check_Button* o, void*)
1690 {
1691 	progStatus.call_fname = o->value();
1692 }
1693 
cb_cbo_dt_fname(Fl_ListBox * o,void *)1694 static void cb_cbo_dt_fname(Fl_ListBox * o, void *)
1695 {
1696 	progStatus.dt_fname = o->index();
1697 }
1698 
cb_btn_sernbr_fname(Fl_Check_Button * o,void *)1699 static void cb_btn_sernbr_fname(Fl_Check_Button* o, void*)
1700 {
1701 	progStatus.sernbr_fname = o->value();
1702 }
1703 
cb_txt_sernbr(Fl_Input * o,void *)1704 static void cb_txt_sernbr(Fl_Input* o, void*)
1705 {
1706 	progStatus.sernbr = o->value();
1707 }
1708 
cb_btn_rgnbr_fname(Fl_Check_Button * o,void *)1709 static void cb_btn_rgnbr_fname(Fl_Check_Button* o, void*)
1710 {
1711 	progStatus.rgnbr_fname = o->value();
1712 }
1713 
cb_txt_rgnbr(Fl_Input * o,void *)1714 static void cb_txt_rgnbr(Fl_Input* o, void*)
1715 {
1716 	progStatus.rgnbr = o->value();
1717 }
1718 
cb_btn_arl_desc(Fl_Check_Button * o,void *)1719 static void cb_btn_arl_desc(Fl_Check_Button* o, void*)
1720 {
1721 	progStatus.arl_desc = o->value();
1722 }
1723 
cb_btn_rri(Fl_Check_Button * o,void *)1724 static void cb_btn_rri(Fl_Check_Button* o, void*)
1725 {
1726 	progStatus.rri = o->value();
1727 }
1728 
create_tab_date_time(int X,int Y,int W,int H,const char * title)1729 Fl_Group *create_tab_date_time(int X, int Y, int W, int H, const char *title)
1730 {
1731 	Fl_Group *grp = new Fl_Group(X, Y, W, H, title);
1732 
1733 	Y += 40;
1734 	X += 40;
1735 
1736 	btn_dtformat0 = new Fl_Round_Button(X, Y+8, 70, 20, _("YYYY-MM-DD"));
1737 	btn_dtformat0->down_box(FL_ROUND_DOWN_BOX);
1738 	btn_dtformat0->callback((Fl_Callback*)cb_btn_dtformat0);
1739 	if (progStatus.dtformat == 0) btn_dtformat0->value(1); else btn_dtformat0->value(0);
1740 
1741 	btn_dtformat3 = new Fl_Round_Button(X, Y+30, 70, 20, _("YYYY-DD-MM"));
1742 	btn_dtformat3->down_box(FL_ROUND_DOWN_BOX);
1743 	btn_dtformat3->callback((Fl_Callback*)cb_btn_dtformat3);
1744 	if (progStatus.dtformat == 3) btn_dtformat3->value(1); else btn_dtformat3->value(0);
1745 
1746 	btn_dtformat1 = new Fl_Round_Button(X, Y+52, 70, 20, _("MM/DD/YY"));
1747 	btn_dtformat1->down_box(FL_ROUND_DOWN_BOX);
1748 	btn_dtformat1->callback((Fl_Callback*)cb_btn_dtformat1);
1749 	if (progStatus.dtformat == 1) btn_dtformat1->value(1); else btn_dtformat1->value(0);
1750 
1751 	btn_dtformat2 = new Fl_Round_Button(X, Y+74, 70, 20, _("DD/MM/YY"));
1752 	btn_dtformat2->down_box(FL_ROUND_DOWN_BOX);
1753 	btn_dtformat2->callback((Fl_Callback*)cb_btn_dtformat2);
1754 	if (progStatus.dtformat == 2) btn_dtformat2->value(1); else btn_dtformat2->value(0);
1755 
1756 	btn_dtformat4 = new Fl_Round_Button(X, Y+96, 70, 20, _("YYYYMMDD"));
1757 	btn_dtformat4->down_box(FL_ROUND_DOWN_BOX);
1758 	btn_dtformat4->callback((Fl_Callback*)cb_btn_dtformat4);
1759 	if (progStatus.dtformat == 4) btn_dtformat4->value(1); else btn_dtformat4->value(0);
1760 
1761 	btn_caplocal = new Fl_Check_Button(X, Y+140, 70, 20, _("CAP Local date/time"));
1762 	btn_caplocal->tooltip(_("Check to use local date/time\ndefault Zulu"));
1763 	btn_caplocal->callback((Fl_Callback*)cb_caplocal);
1764 
1765 	X += 200;
1766 	btn_utc_format0 = new Fl_Round_Button(X, Y+8, 70, 20, _("hhmmL"));
1767 	btn_utc_format0->down_box(FL_ROUND_DOWN_BOX);
1768 	btn_utc_format0->callback((Fl_Callback*)cb_btn_utc_format0);
1769 	if (progStatus.UTC == 0) btn_utc_format0->value(1); else btn_utc_format0->value(0);
1770 
1771 	btn_utc_format1 = new Fl_Round_Button(X, Y+30, 70, 20, _("hh:mmL"));
1772 	btn_utc_format1->down_box(FL_ROUND_DOWN_BOX);
1773 	btn_utc_format1->callback((Fl_Callback*)cb_btn_utc_format1);
1774 	if (progStatus.UTC == 1) btn_utc_format1->value(1); else btn_utc_format1->value(0);
1775 
1776 	btn_utc_format2 = new Fl_Round_Button(X, Y+52, 70, 20, _("hhmmZ"));
1777 	btn_utc_format2->down_box(FL_ROUND_DOWN_BOX);
1778 	btn_utc_format2->callback((Fl_Callback*)cb_btn_utc_format2);
1779 	if (progStatus.UTC == 2) btn_utc_format2->value(1); else btn_utc_format2->value(0);
1780 
1781 	btn_utc_format3 = new Fl_Round_Button(X, Y+74, 70, 20, _("hh:mmZ"));
1782 	btn_utc_format3->down_box(FL_ROUND_DOWN_BOX);
1783 	btn_utc_format3->callback((Fl_Callback*)cb_btn_utc_format3);
1784 	if (progStatus.UTC == 3) btn_utc_format3->value(1); else btn_utc_format3->value(0);
1785 
1786 	btn_utc_format4 = new Fl_Round_Button(X, Y+96, 70, 20, _("hhmm UTC"));
1787 	btn_utc_format4->down_box(FL_ROUND_DOWN_BOX);
1788 	btn_utc_format4->callback((Fl_Callback*)cb_btn_utc_format4);
1789 	if (progStatus.UTC == 4) btn_utc_format4->value(1); else btn_utc_format4->value(0);
1790 
1791 	btn_utc_format5 = new Fl_Round_Button(X, Y+118, 70, 20, _("hh:mm UTC"));
1792 	btn_utc_format5->down_box(FL_ROUND_DOWN_BOX);
1793 	btn_utc_format5->callback((Fl_Callback*)cb_btn_utc_format5);
1794 	if (progStatus.UTC == 5) btn_utc_format5->value(1); else btn_utc_format5->value(0);
1795 
1796 	grp->end();
1797 	return grp;
1798 }
1799 
create_tab_personal(int X,int Y,int W,int H,const char * title)1800 Fl_Group *create_tab_personal(int X, int Y, int W, int H, const char *title)
1801 {
1802 	Fl_Group *grp = new Fl_Group(X, Y, W, H, title);
1803 
1804 	Y += 10;
1805 
1806 	txt_my_call = new Fl_Input2(X+90, Y+6, W - 94, 24, _("Call:"));
1807 	txt_my_call->callback((Fl_Callback*)cb_txt_my_call);
1808 	txt_my_call->value(progStatus.my_call.c_str());
1809 
1810 	txt_my_tel = new Fl_Input2(X+90, Y+32, W - 94, 24, _("Tel:"));
1811 	txt_my_tel->callback((Fl_Callback*)cb_txt_my_tel);
1812 	txt_my_tel->value(progStatus.my_tel.c_str());
1813 
1814 	txt_my_name = new Fl_Input2(X+90, Y+58, W - 94, 24, _("Name:"));
1815 	txt_my_name->callback((Fl_Callback*)cb_txt_my_name);
1816 	txt_my_name->value(progStatus.my_name.c_str());
1817 
1818 	txt_my_addr = new Fl_Input2(X+90, Y+84, W - 94, 24, _("Addr:"));
1819 	txt_my_addr->callback((Fl_Callback*)cb_txt_my_addr);
1820 	txt_my_addr->value(progStatus.my_addr.c_str());
1821 
1822 	txt_my_city = new Fl_Input2(X+90, Y+110, W - 94, 24, _("City/St/Zip:"));
1823 	txt_my_city->callback((Fl_Callback*)cb_txt_my_city);
1824 	txt_my_city->value(progStatus.my_city.c_str());
1825 
1826 	txt_my_email = new Fl_Input2(X+90, Y+136, W - 94, 24, _("Email addr:"));
1827 	txt_my_email->callback((Fl_Callback*)cb_txt_my_email);
1828 	txt_my_email->value(progStatus.my_email.c_str());
1829 
1830 	grp->end();
1831 	return grp;
1832 }
1833 
create_tab_radiogram(int X,int Y,int W,int H,const char * title)1834 Fl_Group *create_tab_radiogram(int X, int Y, int W, int H, const char *title)
1835 {
1836 	Fl_Group *grp = new Fl_Group(X, Y, W, H, title);
1837 
1838 	Y += 30;
1839 
1840 	cnt_wpl = new Fl_Spinner(60, Y, 40, 24, _("message words/line"));
1841 	cnt_wpl->tooltip(_("Radiogram message contents auto format"));
1842 	cnt_wpl->minimum(4);
1843 	cnt_wpl->maximum(10);
1844 	cnt_wpl->value(5);
1845 	cnt_wpl->callback((Fl_Callback*)cb_cnt_wpl);
1846 	cnt_wpl->align(FL_ALIGN_RIGHT);
1847 	cnt_wpl->value(progStatus.wpl);
1848 
1849 	Y += 30;
1850 	btn_rgnbr_fname = new Fl_Check_Button(60, Y, 70, 24, _("Auto incr\'"));
1851 	btn_rgnbr_fname->tooltip(_("enable auto increment of message number"));
1852 	btn_rgnbr_fname->down_box(FL_DOWN_BOX);
1853 	btn_rgnbr_fname->callback((Fl_Callback*)cb_btn_rgnbr_fname);
1854 	btn_rgnbr_fname->value(progStatus.rgnbr_fname);
1855 
1856 	Y += 30;
1857 	txt_rgnbr = new Fl_Input2(60, Y, 66, 24, _("Next #"));
1858 	txt_rgnbr->tooltip(_("next number in auto-increment sequence"));
1859 	txt_rgnbr->type(2);
1860 	txt_rgnbr->callback((Fl_Callback*)cb_txt_rgnbr);
1861 	txt_rgnbr->align(FL_ALIGN_RIGHT);
1862 	txt_rgnbr->value(progStatus.rgnbr.c_str());
1863 
1864 	Y += 30;
1865 	btn_arl_desc = new Fl_Check_Button(60, Y, 70, 24, _("Show ARL desc\'"));
1866 	btn_arl_desc->tooltip(_("Add keyed text descriptions for ARL ## messages"));
1867 	btn_arl_desc->down_box(FL_DOWN_BOX);
1868 	btn_arl_desc->callback((Fl_Callback*)cb_btn_arl_desc);
1869 	btn_arl_desc->value(progStatus.arl_desc);
1870 
1871 	Y += 30;
1872 	btn_rri = new Fl_Check_Button(60, Y, 70, 24, _("Radio Relay International"));
1873 	btn_rri->tooltip(_("Use RRI radiogram templates"));
1874 	btn_rri->down_box(FL_DOWN_BOX);
1875 	btn_rri->callback((Fl_Callback*)cb_btn_rri);
1876 	btn_rri->value(progStatus.rri);
1877 
1878 	grp->end();
1879 	return grp;
1880 }
1881 
cb_find_roster()1882 void cb_find_roster()
1883 {
1884 	string filename = ICS_dir;
1885 	filename.append("MARS_ROSTER.csv");
1886 
1887 	Fl_Native_File_Chooser native;
1888 
1889 	native.filter("csv file\t*.{csv,CSV}");
1890 	native.title(_("Select MARS roster file"));
1891 	native.preset_file(filename.c_str());
1892 	native.type(Fl_Native_File_Chooser::BROWSE_FILE);
1893 	native.options(Fl_Native_File_Chooser::PREVIEW);
1894 	native.directory(ICS_dir.c_str());
1895 
1896 	switch ( native.show() ) {
1897 		case -1: // ERROR
1898 			LOG_ERROR("ERROR: %s\n", native.errmsg()); // Error fall through
1899 		case  1: // CANCEL
1900 			break;
1901 		default:
1902 			progStatus.mars_roster_file = native.filename();
1903 			txt_mars_roster_file->value(progStatus.mars_roster_file.c_str());
1904 			break;
1905 	}
1906 
1907 }
1908 
cb_autowordwrap()1909 void cb_autowordwrap()
1910 {
1911 	progStatus.autowordwrap = btnAutoWordWrap->value();
1912 }
1913 
cb_send_original()1914 void cb_send_original()
1915 {
1916 	progStatus.send_original = btnSendOriginalFile->value();
1917 }
1918 
cb_charcount()1919 void cb_charcount()
1920 {
1921 	progStatus.charcount = cntCharCount->value();
1922 }
1923 
create_tab_files(int X,int Y,int W,int H,const char * title)1924 Fl_Group *create_tab_files(int X, int Y, int W, int H, const char *title)
1925 {
1926 	Fl_Group *grp = new Fl_Group(X, Y, W, H, title);
1927 
1928 	Y += 10;
1929 
1930 	Fl_Group* group1 = new Fl_Group(X + 2, Y, W-4, 50, _("Wrap"));
1931 	group1->box(FL_ENGRAVED_FRAME);
1932 	group1->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
1933 		btn_open_on_export = new Fl_Check_Button(X+10, Y + 24, 18, 18, _("Open folder when exporting"));
1934 		btn_open_on_export->tooltip(_(""));
1935 		btn_open_on_export->down_box(FL_DOWN_BOX);
1936 		btn_open_on_export->callback((Fl_Callback*)cb_btn_open_on_export);
1937 		btn_open_on_export->value(progStatus.open_on_export);
1938 	group1->end();
1939 
1940 	Fl_Group* group2 = new Fl_Group(X + 2, Y + 52, W-4, 70, _("Naming Files"));
1941 	group2->box(FL_ENGRAVED_FRAME);
1942 	group2->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
1943 		btn_call_fname = new Fl_Check_Button(X+10, Y+74, 18, 18, _("Callsign"));
1944 		btn_call_fname->down_box(FL_DOWN_BOX);
1945 		btn_call_fname->callback((Fl_Callback*)cb_btn_call_fname);
1946 		btn_call_fname->value(progStatus.call_fname);
1947 		btn_call_fname->tooltip(_("Add CALL to date-time"));
1948 
1949 		cbo_dt_fname = new Fl_ListBox(X+120, Y + 73, 200, 20, _("Date-time"));
1950 		cbo_dt_fname->callback((Fl_Callback*)cb_cbo_dt_fname);
1951 		cbo_dt_fname->add("not used");
1952 		cbo_dt_fname->add("Local time,  L");
1953 		cbo_dt_fname->add("Local time, TZ name");
1954 		cbo_dt_fname->add("Local time, TZ offset");
1955 		cbo_dt_fname->add("UTC time,    Z");
1956 		cbo_dt_fname->index(progStatus.dt_fname);
1957 
1958 		btn_sernbr_fname = new Fl_Check_Button(X+10, Y + 95, 18, 18, _("Serial #"));
1959 		btn_sernbr_fname->down_box(FL_DOWN_BOX);
1960 		btn_sernbr_fname->callback((Fl_Callback*)cb_btn_sernbr_fname);
1961 		btn_sernbr_fname->value(progStatus.sernbr_fname);
1962 		btn_sernbr_fname->tooltip(_("Add incremental serial number to filename"));
1963 
1964 		txt_sernbr = new Fl_Input2(X +100, Y+96, 66, 20, _("Next #"));
1965 		txt_sernbr->type(2);
1966 		txt_sernbr->callback((Fl_Callback*)cb_txt_sernbr);
1967 		txt_sernbr->align(FL_ALIGN_RIGHT);
1968 		txt_sernbr->value(progStatus.sernbr.c_str());
1969 	group2->end();
1970 
1971 	Fl_Group* group3 = new Fl_Group(X + 2, Y + 124, W-4, 46, "");
1972 	group3->box(FL_ENGRAVED_FRAME);
1973 		txt_mars_roster_file = new Fl_Input2(X+10, Y + 144, 360, 22, _("MARS roster file"));
1974 		txt_mars_roster_file->align(FL_ALIGN_TOP_LEFT);
1975 
1976 		Fl_Button *btn_find_roster = new Fl_Button(X+372, Y + 144, 68, 22, _("Find"));
1977 		btn_find_roster->callback((Fl_Callback*)cb_find_roster);
1978 
1979 	group3->end();
1980 
1981 	Fl_Group* group4 = new Fl_Group(X+2, Y + 172, W-4, 46, "Html message text");
1982 	group4->box(FL_ENGRAVED_FRAME);
1983 	group4->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
1984 		btnAutoWordWrap = new Fl_Check_Button(X+10, Y+194, 18, 18, _("Word wrap at "));
1985 		btnAutoWordWrap->down_box(FL_DOWN_BOX);
1986 		btnAutoWordWrap->value(progStatus.autowordwrap);
1987 		btnAutoWordWrap->callback((Fl_Callback*)cb_autowordwrap);
1988 
1989 		cntCharCount = new Fl_Counter(X+135, Y+193, 60, 20, _("characters"));
1990 		cntCharCount->align(FL_ALIGN_RIGHT);
1991 		cntCharCount->value(progStatus.charcount);
1992 		cntCharCount->type(FL_SIMPLE_COUNTER);
1993 		cntCharCount->step(1);
1994 		cntCharCount->callback((Fl_Callback*)cb_charcount);
1995 	group4->end();
1996 
1997 	Fl_Group* group5 = new Fl_Group(X+2, Y + 220, W-4, 42, _("File transfers"));
1998 	group5->box(FL_ENGRAVED_FRAME);
1999 	group5->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
2000 		btnSendOriginalFile = new Fl_Check_Button(X+10, Y+240, 18, 18, _("Do not compress file"));
2001 		btnSendOriginalFile->down_box(FL_DOWN_BOX);
2002 		btnSendOriginalFile->value(progStatus.send_original);
2003 		btnSendOriginalFile->callback((Fl_Callback*)cb_send_original);
2004 	group5->end();
2005 
2006 	grp->end();
2007 	return grp;
2008 }
2009 
2010 //----------------------------------------------------------------------
2011 // ARQ config tab
2012 //----------------------------------------------------------------------
2013 
cb_txt_socket_addr(Fl_Input * o,void *)2014 static void cb_txt_socket_addr(Fl_Input* o, void*) {
2015 	progStatus.xmlrpc_addr = o->value();
2016 }
2017 
cb_txt_socket_port(Fl_Input * o,void *)2018 static void cb_txt_socket_port(Fl_Input* o, void*) {
2019 	progStatus.xmlrpc_port = o->value();
2020 }
2021 
cb_socket_default(Fl_Input * o,void *)2022 static void cb_socket_default(Fl_Input* o, void*) {
2023 	progStatus.xmlrpc_addr = "127.0.0.1";
2024 	progStatus.xmlrpc_port = "7362";
2025 	txt_socket_addr->value(progStatus.xmlrpc_addr.c_str());
2026 	txt_socket_port->value(progStatus.xmlrpc_port.c_str());
2027 }
2028 
cb_change_modem_with_autosend(Fl_Check_Button * o,void *)2029 static void cb_change_modem_with_autosend(Fl_Check_Button *o, void *) {
2030 	progStatus.change_modem_with_autosend = o->value();
2031 }
2032 
cb_sync_modem_to_fldigi(Fl_Check_Button * o,void *)2033 static void cb_sync_modem_to_fldigi(Fl_Check_Button *o, void *) {
2034 	progStatus.sync_modem_to_fldigi = o->value();
2035 }
2036 
2037 Fl_Button *btn_socket_default = (Fl_Button *)0;
2038 Fl_Check_Button *btn_change_modem_with_autosend = (Fl_Check_Button *)0;
2039 Fl_Check_Button *btn_sync_modem_to_fldigi = (Fl_Check_Button *)0;
2040 
2041 Fl_Spinner2 *spnRetries      = (Fl_Spinner2 *)0;
2042 Fl_Spinner2 *spnWaitTime     = (Fl_Spinner2 *)0;
2043 Fl_Counter *cntrTimeout      = (Fl_Counter2 *)0;
2044 Fl_Check_Button *btn_notify_receipt = (Fl_Check_Button *)0;
2045 Fl_ComboBox *choiceBlockSize = (Fl_ComboBox *)0;
2046 Fl_Check_Button *btnAutoOpen = (Fl_Check_Button *)0;
2047 Fl_Check_Button *btnIDon   = (Fl_Check_Button *)0;
2048 Fl_Check_Button *btnIDoff  = (Fl_Check_Button *)0;
2049 
cb_cntrTimeout(Fl_Counter2 * o,void *)2050 static void cb_cntrTimeout(Fl_Counter2* o, void*) {
2051 	progStatus.arq_notify_timeout = (int)o->value();
2052 }
2053 
cb_notify_receipt(Fl_Check_Button * o,void *)2054 static void cb_notify_receipt(Fl_Check_Button *o, void *) {
2055 	progStatus.notify_receipt = (int)o->value();
2056 }
2057 
cb_spnRetries(Fl_Spinner2 * o,void *)2058 static void cb_spnRetries(Fl_Spinner2* o, void*) {
2059 	progStatus.retries = (int)o->value();
2060 	flmsg_arq.setRetries(progStatus.retries);
2061 }
2062 
cb_auto_open(Fl_Check_Button * o,void *)2063 static void cb_auto_open(Fl_Check_Button* o, void*) {
2064 	progStatus.auto_open_url = o->value();
2065 }
2066 
cb_choiceBlockSize(Fl_ComboBox * o,void *)2067 static void cb_choiceBlockSize(Fl_ComboBox* o, void*) {
2068 	progStatus.exponent = (int)o->index() + 4;
2069 	flmsg_arq.setExponent(progStatus.exponent);
2070 }
2071 
cb_ID_on(Fl_Check_Button * o,void *)2072 static void cb_ID_on(Fl_Check_Button* o, void*) {
2073 	progStatus.ID_on = o->value();
2074 }
2075 
cb_ID_off(Fl_Check_Button * o,void *)2076 static void cb_ID_off(Fl_Check_Button* o, void*) {
2077 	progStatus.ID_off = o->value();
2078 }
2079 
cb_ID_restore(Fl_Check_Button * o,void *)2080 static void cb_ID_restore(Fl_Check_Button* o, void*) {
2081 	progStatus.ID_restore = o->value();
2082 }
2083 
create_tab_arq(int X,int Y,int W,int H,const char * title)2084 Fl_Group *create_tab_arq(int X, int Y, int W, int H, const char *title)
2085 {
2086 	Fl_Group *grp = new Fl_Group(X, Y, W, H, title);
2087 
2088 	Y += 10;
2089 	X += 80;
2090 
2091 	txt_socket_addr = new Fl_Input2(X+100, Y, 130, 22, _("Fldigi xmlrpc Addr: "));
2092 	txt_socket_addr->tooltip(_("default = 127.0.0.1"));
2093 	txt_socket_addr->callback((Fl_Callback*)cb_txt_socket_addr);
2094 	txt_socket_addr->value(progStatus.xmlrpc_addr.c_str());
2095 
2096 	Y += 25;
2097 	txt_socket_port = new Fl_Input2(X+100, Y, 130, 22, _("Fldigi xmlrpc Port: "));
2098 	txt_socket_port->tooltip(_("default = 7362"));
2099 	txt_socket_port->callback((Fl_Callback*)cb_txt_socket_port);
2100 	txt_socket_port->value(progStatus.xmlrpc_port.c_str());
2101 
2102 	Y += 25;
2103 	X -= 60;
2104 	spnRetries = new Fl_Spinner2(X, Y, 50, 24, _("Retries"));
2105 	spnRetries->tooltip(_("# retries before connection declared down"));
2106 	spnRetries->box(FL_NO_BOX);
2107 	spnRetries->color(FL_BACKGROUND2_COLOR);
2108 	spnRetries->selection_color(FL_BACKGROUND_COLOR);
2109 	spnRetries->labeltype(FL_NORMAL_LABEL);
2110 	spnRetries->labelfont(0);
2111 	spnRetries->labelsize(14);
2112 	spnRetries->labelcolor(FL_FOREGROUND_COLOR);
2113 	spnRetries->callback((Fl_Callback*)cb_spnRetries);
2114 	spnRetries->align(Fl_Align(FL_ALIGN_RIGHT));
2115 	spnRetries->when(FL_WHEN_RELEASE);
2116 	spnRetries->minimum(2);
2117 	spnRetries->maximum(20);
2118 	spnRetries->step(1);
2119 	spnRetries->value(progStatus.retries);
2120 
2121 	choiceBlockSize = new Fl_ComboBox(X+200, Y, 100, 24, _("Block Size"));
2122 	choiceBlockSize->box(FL_DOWN_BOX);
2123 	choiceBlockSize->color(FL_BACKGROUND2_COLOR);
2124 	choiceBlockSize->selection_color(FL_BACKGROUND_COLOR);
2125 	choiceBlockSize->labeltype(FL_NORMAL_LABEL);
2126 	choiceBlockSize->labelfont(0);
2127 	choiceBlockSize->labelsize(14);
2128 	choiceBlockSize->labelcolor(FL_FOREGROUND_COLOR);
2129 	choiceBlockSize->callback((Fl_Callback*)cb_choiceBlockSize);
2130 	choiceBlockSize->align(Fl_Align(FL_ALIGN_RIGHT));
2131 	choiceBlockSize->when(FL_WHEN_RELEASE);
2132 	choiceBlockSize->add("16");
2133 	choiceBlockSize->add("32");
2134 	choiceBlockSize->add("64");
2135 	choiceBlockSize->add("128");
2136 	choiceBlockSize->add("256");
2137 	choiceBlockSize->add("512");
2138 	choiceBlockSize->add("1024");
2139 	choiceBlockSize->index(progStatus.exponent - 4);
2140 	choiceBlockSize->end();
2141 
2142 	Y += 28;
2143 	cntrTimeout = new Fl_Counter2(X, Y, 120, 24, _("Notifier timeout"));
2144 	cntrTimeout->tooltip(_("Keep notifier dialog open for ## secs\nZero = no timeout"));
2145 	cntrTimeout->labeltype(FL_NORMAL_LABEL);
2146 	cntrTimeout->labelfont(0);
2147 	cntrTimeout->labelsize(14);
2148 	cntrTimeout->callback((Fl_Callback*)cb_cntrTimeout);
2149 	cntrTimeout->align(Fl_Align(FL_ALIGN_RIGHT));
2150 	cntrTimeout->when(FL_WHEN_RELEASE);
2151 	cntrTimeout->minimum(0);
2152 	cntrTimeout->maximum(600);
2153 	cntrTimeout->step(1);
2154 	cntrTimeout->lstep(10);
2155 	cntrTimeout->value(progStatus.arq_notify_timeout);
2156 
2157 	btn_notify_receipt = new Fl_Check_Button(X + 250, Y, 22, 22, _("Notify Receipt"));
2158 	btn_notify_receipt->tooltip(_("Enable to display receipt notification dialog"));
2159 	btn_notify_receipt->value(progStatus.notify_receipt);
2160 	btn_notify_receipt->callback((Fl_Callback*)cb_notify_receipt);
2161 
2162 	Y += 24;
2163 	X += 60;
2164 	btnIDon = new Fl_Check_Button(X, Y, 22, 22, _("Enable ID/RxID"));
2165 	btnIDon->tooltip(_("Enable ID during ARQ session"));
2166 	btnIDon->value(progStatus.ID_on);
2167 	btnIDon->callback((Fl_Callback*)cb_ID_on);
2168 
2169 	Y += 24;
2170 	btnIDoff = new Fl_Check_Button(X, Y, 22, 22, _("Disable ID/RxID after connect"));
2171 	btnIDoff->tooltip(_("Disable ID after connect is established"));
2172 	btnIDoff->value(progStatus.ID_off);
2173 	btnIDoff->callback((Fl_Callback*)cb_ID_off);
2174 
2175 	Y += 24;
2176 	btnIDoff = new Fl_Check_Button(X, Y, 22, 22, _("Restore ID/RxID"));
2177 	btnIDoff->tooltip(_("Restore ID/RsID after ARQ session"));
2178 	btnIDoff->value(progStatus.ID_restore);
2179 	btnIDoff->callback((Fl_Callback*)cb_ID_restore);
2180 
2181 	Y += 24;
2182 	btnAutoOpen = new Fl_Check_Button(X, Y, 22, 22, _("Open Browser"));
2183 	btnAutoOpen->tooltip(_("Open msg in browser on successful receipt"));
2184 	btnAutoOpen->value(progStatus.auto_open_url);
2185 	btnAutoOpen->callback((Fl_Callback*)cb_auto_open);
2186 
2187 	Y += 24;
2188 	btn_sync_modem_to_fldigi = new Fl_Check_Button(X, Y, 24, 22, _("Sync modem to fldigi"));
2189 	btn_sync_modem_to_fldigi->tooltip(_("flmsg will follow modem change in fldigi"));
2190 	btn_sync_modem_to_fldigi->value(progStatus.sync_modem_to_fldigi);
2191 	btn_sync_modem_to_fldigi->callback((Fl_Callback*)cb_sync_modem_to_fldigi);
2192 
2193 	Y += 24;
2194 	btn_change_modem_with_autosend = new Fl_Check_Button(X, Y, 24, 22, _("Change modem with autosend"));
2195 	btn_change_modem_with_autosend->tooltip(_("flmsg sends new modem to fldigi after \"autosend\""));
2196 	btn_change_modem_with_autosend->value(progStatus.change_modem_with_autosend);
2197 	btn_change_modem_with_autosend->callback((Fl_Callback*)cb_change_modem_with_autosend);
2198 
2199 	Y -= 2;
2200 	X = W - 80 - 10;
2201 	Fl_Button *btn_socket_default = new Fl_Button(X, Y, 80, 24, _("Defaults"));
2202 	btn_socket_default->tooltip("Reset all ARQ values to default");
2203 	btn_socket_default->callback((Fl_Callback*)cb_socket_default);
2204 	grp->end();
2205 	return grp;
2206 }
2207 
2208 Fl_Check_Button *btn_UI = (Fl_Check_Button *)0;
2209 
cb_UI_set(void *)2210 void cb_UI_set(void *)
2211 {
2212 	progStatus.UI_expert = btn_UI->value();
2213 }
2214 
create_tab_UI(int X,int Y,int W,int H,const char * title)2215 Fl_Group *create_tab_UI(int X, int Y, int W, int H, const char *title)
2216 {
2217 	Fl_Group *grp = new Fl_Group(X, Y, W, H, title);
2218 
2219 		Y += 20;
2220 		X += 90;
2221 		btn_UI = new Fl_Check_Button(X, Y, 22, 22, _("User Interface = expert"));
2222 		btn_UI->tooltip(_("\
2223 Startup User Interface:\n\
2224 Checked   - Expert Interface\n\
2225 Unchecked - Service Agency (simple)\n\
2226 "));
2227 		btn_UI->value(progStatus.UI_expert);
2228 		btn_UI->callback((Fl_Callback*)cb_UI_set);
2229 
2230 	grp->end();
2231 	return grp;
2232 }
2233 //----------------------------------------------------------------------
2234 
2235 Fl_Tabs		*tabs_config			= (Fl_Tabs *)0;
2236 Fl_Group	*tab_date_time			= (Fl_Group *)0;
2237 Fl_Group	*tab_personal			= (Fl_Group *)0;
2238 Fl_Group	*tab_config_radiogram	= (Fl_Group *)0;
2239 Fl_Group	*tab_files				= (Fl_Group *)0;
2240 Fl_Group	*tab_headers			= (Fl_Group *)0;
2241 Fl_Group	*tab_arq				= (Fl_Group *)0;
2242 Fl_Group	*tab_UI					= (Fl_Group *)0;
2243 
create_config_dialog()2244 Fl_Double_Window* create_config_dialog() {
2245 	int W = 450, H = 300, X = 0, Y = 0;
2246 	Fl_Double_Window* w = new Fl_Double_Window(W, H, _("flmsg config"));
2247 	w->begin();
2248 		tabs_config = new Fl_Tabs(X, Y, W, H);
2249 		tabs_config->selection_color((Fl_Color)246);
2250 			Y += 25;
2251 			H -= 25;
2252 			tab_personal  = create_tab_personal(X, Y, W, H, _("Personal"));
2253 			tab_date_time = create_tab_date_time(X, Y, W, H, _("Date/Time"));
2254 			tab_files     = create_tab_files(X, Y, W, H, _("Files"));
2255 			tab_config_radiogram = create_tab_radiogram(X, Y, W, H, _("Radiogram"));
2256 			tab_arq       = create_tab_arq(X, Y, W, H, _("ARQ"));
2257 			tab_UI        = create_tab_UI(X, Y, W, H, _("UI"));
2258 		tabs_config->end();
2259 	w->end();
2260 	return w;
2261 }
2262 
2263 //----------------------------------------------------------------------
2264 // ARQ events dialog
2265 //----------------------------------------------------------------------
2266 
2267 Fl_Browser *btext = (Fl_Browser *)0;
2268 
clear_cb(Fl_Widget * w,void *)2269 static void clear_cb(Fl_Widget* w, void*)
2270 {
2271 	btext->clear();
2272 }
2273 
add_event(string s)2274 void add_event(string s)
2275 {
2276 	if (!btext) return;
2277 	btext->add(s.c_str());
2278 	btext->bottomline(btext->size());
2279 	btext->redraw();
2280 }
2281 
create_ARQ_event_dialog()2282 Fl_Double_Window* create_ARQ_event_dialog()
2283 {
2284 	int W = 570, H = 300;
2285 	Fl_Double_Window* w = new Fl_Double_Window(W, H, _("flmsg ARQ events"));
2286 	w->begin();
2287 		Fl_Button* clearbtn = new Fl_Button(w->w() - 64, 2, 60, 22, _("Clear"));
2288 		clearbtn->callback(clear_cb);
2289 		btext = new Fl_Browser(2,  clearbtn->h() + 4, w->w() - 4, w->h() - clearbtn->h() - 6, 0);
2290 		btext->textfont(FL_HELVETICA);
2291 		btext->textsize(14);
2292 		w->resizable(btext);
2293 	w->end();
2294 	return w;
2295 }
2296 
2297 //----------------------------------------------------------------------
2298 // received msgs dialog
2299 //----------------------------------------------------------------------
2300 Fl_Double_Window *rcvd_msgs_dialog = (Fl_Double_Window *)0;
2301 Fl_Hold_Browser  *bmsgs = (Fl_Hold_Browser *)0;
2302 Fl_Button        *btnShow = (Fl_Button *)0;
2303 Fl_Button        *btnClearSelected = (Fl_Button *)0;
2304 Fl_Button        *btnClearAll = (Fl_Button *)0;
2305 
add_rcvd_msg(string s)2306 void add_rcvd_msg(string s)
2307 {
2308 	if (!rcvd_msgs_dialog) rcvd_msgs_dialog = create_rcvd_msgs_dialog();
2309 	bmsgs->add(s.c_str());
2310 	bmsgs->bottomline(bmsgs->size());
2311 	bmsgs->redraw();
2312 	if (!rcvd_msgs_dialog->visible()) rcvd_msgs_dialog->show();
2313 }
2314 
cb_view_msg(Fl_Button * w,void * d)2315 void cb_view_msg(Fl_Button *w, void *d)
2316 {
2317 	if (bmsgs->value() == 0) return;
2318 	string pathname = ICS_msg_dir;
2319 	pathname.append(bmsgs->text(bmsgs->value()));
2320 
2321 	read_data_file(pathname);
2322 	show_filename(pathname);
2323 
2324 	if(progStatus.auto_open_url)
2325 		cb_html();
2326 }
2327 
cb_clear_selected(Fl_Button * w,void * d)2328 void cb_clear_selected(Fl_Button *w, void *d)
2329 {
2330 	if (bmsgs->value())
2331 		bmsgs->remove(bmsgs->value());
2332 }
2333 
cb_clear_all(Fl_Button * w,void * d)2334 void cb_clear_all(Fl_Button *w, void *d)
2335 {
2336 	bmsgs->clear();
2337 }
2338 
create_rcvd_msgs_dialog()2339 Fl_Double_Window* create_rcvd_msgs_dialog()
2340 {
2341 	int W = 260, H = 300;
2342 	Fl_Double_Window* w = new Fl_Double_Window( W, H, _("Rcvd Msgs") );
2343 	w->begin();
2344 		bmsgs = new Fl_Hold_Browser(2, 2, w->w() - 4, w->h() - 30, 0);
2345 		bmsgs->textfont(FL_HELVETICA);
2346 		bmsgs->textsize(14);
2347 
2348 		btnClearSelected = new Fl_Button( 2, w->h() - 26, 80, 24, _("Clear Sel'") );
2349 		btnClearSelected->tooltip(_("Clear selected file from list"));
2350 		btnClearSelected->callback((Fl_Callback*)cb_clear_selected);
2351 
2352 		btnClearAll = new Fl_Button( 86, w->h() - 26, 80, 24, _("Clear All") );
2353 		btnClearAll->tooltip(_("Clear all files from list"));
2354 		btnClearAll->callback((Fl_Callback*)cb_clear_all);
2355 
2356 		btnShow = new Fl_Button( w->w() - 62, w->h() - 26, 60, 24, _("View") );
2357 		btnShow->tooltip(_("View selected file"));
2358 		btnShow->callback((Fl_Callback*)cb_view_msg);
2359 
2360 		w->resizable(bmsgs);
2361 	w->end();
2362 	return w;
2363 }
2364 
2365 //----------------------------------------------------------------------
2366 // pick custom message dialog
2367 //----------------------------------------------------------------------
2368 Fl_Double_Window *custom_msg_dialog = (Fl_Double_Window *)0;
2369 Fl_Hold_Browser  *bcustom = (Fl_Hold_Browser *)0;
2370 Fl_Button        *btnCustomCancel = (Fl_Button *)0;
2371 Fl_Button		 *btnCustomSelect = (Fl_Button *)0;
2372 
cb_custom_cancel(Fl_Button * w,void * d)2373 void cb_custom_cancel(Fl_Button *w, void *d)
2374 {
2375 	custom_msg_dialog->hide();
2376 }
2377 
cb_custom_select(Fl_Button * w,void * d)2378 void cb_custom_select(Fl_Button *w, void *d)
2379 {
2380 	custom_select = bcustom->value() - 1;
2381 	if (custom_select < 0) {
2382 		custom_msg_dialog->hide();
2383 		return;
2384 	}
2385 
2386 	select_form(selected_form = CUSTOM);
2387 	cb_custom_new();
2388 	update_custom = true;
2389 
2390 	custom_msg_dialog->hide();
2391 
2392 	handle_type = HANDLE_EDIT;
2393 	string url = "http://127.0.0.1:";
2394 	url.append(sz_srvr_portnbr);
2395 	open_url(url.c_str());
2396 }
2397 
create_custom_msgs_dialog()2398 Fl_Double_Window* create_custom_msgs_dialog()
2399 {
2400 	int W = 260, H = 300;
2401 	Fl_Double_Window* w = new Fl_Double_Window( W, H, _("Custom Templates") );
2402 	w->begin();
2403 		bcustom = new Fl_Hold_Browser(2, 2, w->w() - 4, w->h() - 30, 0);
2404 		bcustom->textfont(FL_HELVETICA);
2405 		bcustom->textsize(14);
2406 
2407 		btnCustomCancel = new Fl_Button( 5, w->h() - 26, 80, 24, _("Cancel") );
2408 		btnCustomCancel->tooltip(_("Cancel message creation"));
2409 		btnCustomCancel->callback((Fl_Callback*)cb_custom_cancel);
2410 
2411 		btnCustomSelect = new Fl_Button( w->w() - 85, w->h() - 26, 80, 24, _("Select") );
2412 		btnCustomSelect->tooltip(_("Open selected template"));
2413 		btnCustomSelect->callback((Fl_Callback*)cb_custom_select);
2414 
2415 		w->resizable(bmsgs);
2416 	w->end();
2417 	return w;
2418 }
2419 
2420 //----------------------------------------------------------------------
2421 
2422 extern void extract_fields();
2423 extern void exit_main(void *);
2424 extern string cmd_fname;
2425 
cb_ve_combo(Fl_Widget *,void * d)2426 void cb_ve_combo(Fl_Widget *, void *d)
2427 {
2428 	custom_select = temp_combo->index() - 1;
2429 	if (custom_select < 0) return;
2430 	select_form(selected_form = CUSTOM);
2431 	cb_custom_new();
2432 	update_custom = true;
2433 }
2434 
cb_ve_create(void *)2435 void cb_ve_create(void *)
2436 {
2437 	if (!custom_msg_dialog) custom_msg_dialog = create_custom_msgs_dialog();
2438 
2439 	bcustom->clear();
2440 
2441 	load_custom_menu();
2442 
2443 	for (int i = 0; i < num_custom_entries; i++)
2444 		bcustom->add(custom_pairs[i].mnu_name);
2445 
2446 	custom_msg_dialog->resize(
2447 		tyro_dialog->x() + 10 + tyro_dialog->w(),
2448 		tyro_dialog->y(),
2449 		custom_msg_dialog->w(), custom_msg_dialog->h());
2450 
2451 	custom_msg_dialog->show();
2452 }
2453 
2454 #include <FL/names.h>
2455 
cb_ve_viewer(void *)2456 void cb_ve_viewer(void *)
2457 {
2458 	int event = Fl::event();
2459 	if (event == FL_PASTE) {
2460 		cmd_fname = Fl::event_text();
2461 		size_t n;
2462 		if ((n = cmd_fname.find("file:///")) != string::npos)
2463 			cmd_fname.erase(0, n + 7);
2464 		if ((cmd_fname.find(":\\")) != string::npos || (cmd_fname.find("/") == 0)) {
2465 			while ((n = cmd_fname.find('\n')) != string::npos)
2466 				cmd_fname.erase(n, 1);
2467 			while ((n = cmd_fname.find('\r')) != string::npos)
2468 				cmd_fname.erase(n, 1);
2469 			print_and_exit();
2470 		} else
2471 			cmd_fname.clear();
2472 		return;
2473 	}
2474 
2475 	string viewer_filename = ICS_msg_dir;
2476 
2477 	Fl_Native_File_Chooser native;
2478 
2479 	native.filter("All msgs\t*\n");
2480 	native.title(_("Open data file"));
2481 	native.preset_file(viewer_filename.c_str());
2482 	native.type(Fl_Native_File_Chooser::BROWSE_FILE);
2483 	native.options(Fl_Native_File_Chooser::PREVIEW);
2484 	native.directory(ICS_msg_dir.c_str());
2485 
2486 	switch ( native.show() ) {
2487 		case -1: // ERROR
2488 			LOG_ERROR("ERROR: %s\n", native.errmsg()); // Error fall through
2489 		case  1: // CANCEL
2490 			break;
2491 		default:
2492 			cmd_fname = viewer_filename = native.filename();
2493 			print_and_exit();
2494 			break;
2495 	}
2496 }
2497 
cb_ve_editor(void *)2498 void cb_ve_editor(void *)
2499 {
2500 	int event = Fl::event();
2501 	if (event == FL_PASTE) {
2502 		def_custom_filename = Fl::event_text();
2503 
2504 		size_t n;
2505 		if ((n = def_custom_filename.find("file:///")) != string::npos)
2506 			def_custom_filename.erase(0, n + 7);
2507 		if ((def_custom_filename.find(":\\")) != string::npos || (def_custom_filename.find("/") == 0)) {
2508 			while ((n = def_custom_filename.find('\n')) != string::npos)
2509 				def_custom_filename.erase(n, 1);
2510 			while ((n = def_custom_filename.find('\r')) != string::npos)
2511 				def_custom_filename.erase(n, 1);
2512 			if (def_custom_filename.find("k2s") == std::string::npos) {
2513 				fl_alert2("Use expert dialog to edit built-in forms!");
2514 				return;
2515 			}
2516 			clear_custom_form();
2517 			read_data_file(def_custom_filename.c_str());
2518 			using_custom_template = false;
2519 			update_custom = true;
2520 			handle_type = HANDLE_EDIT;
2521 			string url = "http://127.0.0.1:";
2522 			url.append(sz_srvr_portnbr);
2523 			open_url(url.c_str());
2524 		} else
2525 			def_custom_filename.clear();
2526 		return;
2527 	}
2528 
2529 	select_form(selected_form = CUSTOM);
2530 
2531 	Fl_Native_File_Chooser native;
2532 
2533 	native.filter("Custon msgs\t*.k2s\n");
2534 	native.title(_("Open data file"));
2535 	native.preset_file(def_custom_filename.c_str());
2536 	native.type(Fl_Native_File_Chooser::BROWSE_FILE);
2537 	native.options(Fl_Native_File_Chooser::PREVIEW);
2538 	native.directory(ICS_msg_dir.c_str());
2539 
2540 	switch ( native.show() ) {
2541 		case -1: // ERROR
2542 			LOG_ERROR("ERROR: %s\n", native.errmsg()); // Error fall through
2543 		case  1: // CANCEL
2544 			break;
2545 		default:
2546 			def_custom_filename =  native.filename();
2547 			if (def_custom_filename.find(".k2s") == std::string::npos) {
2548 				fl_alert2("Not a custom form\nUse Main Dialog for other forms");
2549 				return;
2550 			}
2551 			clear_custom_form();
2552 			read_data_file(def_custom_filename.c_str());
2553 			using_custom_template = false;
2554 			update_custom = true;
2555 			handle_type = HANDLE_EDIT;
2556 			string url = "http://127.0.0.1:";
2557 			url.append(sz_srvr_portnbr);
2558 			open_url(url.c_str());
2559 			break;
2560 	}
2561 }
2562 
cb_ve_Exit(Fl_Widget *,void * d)2563 void cb_ve_Exit(Fl_Widget *, void *d)
2564 {
2565 	cb_exit();
2566 }
2567 
cb_ve_templates(Fl_Widget *,void * d)2568 void cb_ve_templates(Fl_Widget *, void *d)
2569 {
2570 	string dir = CUSTOM_dir;
2571 	open_url(dir.c_str(), 1);
2572 }
2573 
cb_ve_messages(Fl_Widget *,void * d)2574 void cb_ve_messages(Fl_Widget *, void *d)
2575 {
2576 	string dir = ICS_msg_dir;
2577 	open_url(dir.c_str(), 1);
2578 }
2579 
cb_close_main_dialog(Fl_Widget *,void *)2580 void cb_close_main_dialog(Fl_Widget *, void *)
2581 {
2582 	expert_dialog->hide();
2583 }
2584 
cb_show_main_dialog(Fl_Widget *,void * d)2585 void cb_show_main_dialog(Fl_Widget *, void *d)
2586 {
2587 	const char *szClose = _("Close dialog");
2588 	expert_dialog->resize(
2589 		tyro_dialog->x() + 10 + tyro_dialog->w(),
2590 		tyro_dialog->y(),
2591 		expert_dialog->w(), expert_dialog->h());
2592 	menu_[19].shortcut_ = 0;
2593 	menu_[19].text = szClose;
2594 	menu_[19].callback_ = (Fl_Callback *)cb_close_main_dialog;
2595 	expert_dialog->show();
2596 }
2597 
cb_mnu_load_custom(void *)2598 void cb_mnu_load_custom(void *)
2599 {
2600 	load_custom_menu();
2601 }
2602 
2603 /*
2604 struct Fl_Menu_Item {
2605 	const char*		text; // label()
2606 	ulong			shortcut_;
2607 	Fl_Callback*	callback_;
2608 	void*			user_data_;
2609 	int				flags;
2610 	uchar			labeltype_;
2611 	uchar			labelfont_;
2612 	uchar			labelsize_;
2613 	uchar			labelcolor_;
2614 };
2615 
2616 enum { // values for flags, OR'd
2617 FL_MENU_INACTIVE 	= 1, // Deactivate menu item (gray out)
2618 FL_MENU_TOGGLE 		= 2, // Item is a checkbox toggle (shows checkbox for on/off state)
2619 FL_MENU_VALUE 		= 4, // The on/off state for checkbox/radio buttons (if set, state is 'on')
2620 FL_MENU_RADIO 		= 8, // Item is a radio button (one checkbox of many can be on)
2621 FL_MENU_INVISIBLE 	= 0x10, // Item will not show up (shortcut will work)
2622 FL_SUBMENU_POINTER 	= 0x20, // Indicates user_data() is a pointer to another menu array
2623 FL_SUBMENU 			= 0x40, // This item is a submenu to other items
2624 FL_MENU_DIVIDER 	= 0x80, // Creates divider line below this item. Also ends a group of radio buttons.
2625 FL_MENU_HORIZONTAL 	= 0x100 // ??? -- reserved
2626 };
2627 */
2628 
2629 Fl_Menu_Item ve_menu_[] = {
2630  {_("&File"), 0, 0, 0, FL_SUBMENU},
2631 	{_("&Template Folder"), 0, (Fl_Callback*)cb_ve_templates},
2632 	{_("&Messages Folder"), 0, (Fl_Callback*)cb_ve_messages, 0, FL_MENU_DIVIDER},
2633 	{_("E&xit"), 0x40078,  (Fl_Callback*)cb_ve_Exit},
2634 	{0},
2635  {_("&Tools"), 0, 0, 0, FL_SUBMENU},
2636 	{_("Update templates"), 0, (Fl_Callback*)cb_mnu_load_custom},
2637 	{_("Expert Dialog"), 0, (Fl_Callback*)cb_show_main_dialog},
2638 	{0},
2639  {0},
2640  {0}
2641 };
2642 
edit_view_dialog()2643 Fl_Double_Window* edit_view_dialog()
2644 {
2645 	int W = 300, H = 130;
2646 	Fl_Double_Window *w = new Fl_Double_Window( W, H, _("Flmsg - Simple UI") );
2647 	w->begin();
2648 		ve_menubar = new Fl_Menu_Bar(0, 0, W, 24);
2649 
2650 		ve_menubar->menu(ve_menu_);
2651 
2652 		ve_create = new Fl_Button(75, 35, 150, 25, _("New Message") );
2653 		ve_create->callback((Fl_Callback*)cb_ve_create);
2654 		ve_create->tooltip(_("Create a new message"));
2655 
2656 		ve_editor = new Fl_Drop_Button(75, 65, 150, 25, _("Edit Message") );
2657 		ve_editor->callback((Fl_Callback*)cb_ve_editor);
2658 		ve_editor->tooltip(_("Edit existing message"));
2659 
2660 		ve_viewer = new Fl_Drop_Button(75, 95, 150, 25, _("View Message") );
2661 		ve_viewer->callback((Fl_Callback*)cb_ve_viewer);
2662 		ve_viewer->tooltip(_("View existing message"));
2663 
2664 	w->end();
2665 	return w;
2666 }
2667