1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2014
3 // David Freese, W1HKJ
4 //
5 // This file is part of flmsg
6 //
7 // flrig is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // flrig is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 // ----------------------------------------------------------------------------
20
21 #include <stdlib.h>
22 #include <iostream>
23 #include <fstream>
24 #include <cstring>
25 #include <ctime>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <stdio.h>
29 #include <errno.h>
30
31 #include <FL/Fl.H>
32 #include <FL/Enumerations.H>
33 #include <FL/Fl_Window.H>
34 #include <FL/Fl_Button.H>
35 #include <FL/Fl_Group.H>
36 #include <FL/Fl_Sys_Menu_Bar.H>
37 #include <FL/x.H>
38 #include <FL/Fl_Help_Dialog.H>
39 #include <FL/Fl_Menu_Item.H>
40 #include <FL/Fl_File_Icon.H>
41
42 #include "config.h"
43 #include "flmsg_config.h"
44
45 #include "flmsg.h"
46 #include "templates.h"
47 #include "debug.h"
48 #include "util.h"
49 #include "gettext.h"
50 #include "flmsg_dialog.h"
51 #include "flinput2.h"
52 #include "date.h"
53 #include "calendar.h"
54 #include "icons.h"
55 #include "fileselect.h"
56 #include "wrap.h"
57 #include "status.h"
58 #include "parse_xml.h"
59
60 #ifdef WIN32
61 # include "flmsgrc.h"
62 # include "compat.h"
63 # define dirent fl_dirent_no_thanks
64 #endif
65
66 #include <FL/filename.H>
67 #include "dirent-check.h"
68
69 #include <FL/x.H>
70 #include <FL/Fl_Pixmap.H>
71 #include <FL/Fl_Image.H>
72
73 using namespace std;
74
75 const char army_precedent[] = "RPOZM";
76
77 string mars_army_de = ":de:";
78 string mars_army_nbr = ":nbr:";
79
80 string mars_army_prec = ":pre:";
81 string mars_army_dtg = ":dtg:";
82 string mars_army_fm = ":fm:";
83 string mars_army_to = ":to:";
84 string mars_army_info = ":info:";
85 string mars_army_subj = ":subj:";
86 string mars_army_text = ":text:";
87
88 string s_mars_army_de;
89 string s_mars_army_nbr;
90 string s_mars_army_prec = "R";
91 string s_mars_army_dtg;
92 string s_mars_army_fm;
93 string s_mars_army_to;
94 string s_mars_army_subj;
95 string s_mars_army_info;
96 string s_mars_army_text;
97
98 string buffmars_army;
99 string def_mars_army_filename = "";
100 string base_mars_army_filename = "";
101 string def_mars_army_TemplateName = "";
102
103 bool using_mars_army_template = false;
104
clear_mars_armyfields()105 void clear_mars_armyfields()
106 {
107 s_mars_army_prec = "R";
108 s_mars_army_dtg.clear();
109 s_mars_army_fm.clear();
110 s_mars_army_de.clear();
111 s_mars_army_nbr.clear();
112 s_mars_army_to.clear();
113 s_mars_army_subj.clear();
114 s_mars_army_info.clear();
115 s_mars_army_text.clear();
116 }
117
check_mars_armyfields()118 bool check_mars_armyfields()
119 {
120 string temp;
121 temp = army_precedent[sel_mars_army_prec->index()];
122 if (s_mars_army_prec != temp) return true;
123 if (s_mars_army_dtg != txt_mars_army_dtg->value()) return true;
124 if (s_mars_army_fm != txt_mars_army_fm->value()) return true;
125 if (s_mars_army_de != txt_mars_army_de->value()) return true;
126 if (s_mars_army_nbr != txt_mars_army_nbr->value()) return true;
127 if (s_mars_army_to != txt_mars_army_to->buffer()->text()) return true;
128 if (s_mars_army_info != txt_mars_army_info->buffer()->text()) return true;
129 if (s_mars_army_subj != txt_mars_army_subj->value()) return true;
130 if (s_mars_army_text != txt_mars_army_text->buffer()->text()) return true;
131 return false;
132 }
133
update_mars_armyfields()134 void update_mars_armyfields()
135 {
136 s_mars_army_prec.clear();
137 s_mars_army_prec = army_precedent[sel_mars_army_prec->index()];
138 s_mars_army_dtg = txt_mars_army_dtg->value();
139 s_mars_army_fm = txt_mars_army_fm->value();
140 s_mars_army_de = txt_mars_army_de->value();
141 s_mars_army_nbr = txt_mars_army_nbr->value();
142 s_mars_army_to = txt_mars_army_to->buffer()->text();
143 s_mars_army_info = txt_mars_army_info->buffer()->text();
144 s_mars_army_subj = txt_mars_army_subj->value();
145 s_mars_army_text = txt_mars_army_text->buffer()->text();
146 striplf (s_mars_army_dtg);
147 striplf (s_mars_army_de);
148 striplf (s_mars_army_fm);
149 striplf (s_mars_army_nbr);
150 striplf (s_mars_army_to);
151 striplf (s_mars_army_info);
152 striplf (s_mars_army_subj);
153 striplf (s_mars_army_text);
154 }
155
update_mars_armyform()156 void update_mars_armyform()
157 {
158 size_t n = strchr(army_precedent, s_mars_army_prec[0]) - army_precedent;
159 if (n < 0) n = 0;
160 if (n > 4) n = 4;
161 sel_mars_army_prec->index(n);
162
163 txt_mars_army_dtg->value(s_mars_army_dtg.c_str());
164 txt_mars_army_fm->value(s_mars_army_fm.c_str());
165 txt_mars_army_de->value(s_mars_army_de.c_str());
166 txt_mars_army_nbr->value(s_mars_army_nbr.c_str());
167 txt_mars_army_to->add(s_mars_army_to.c_str());
168 txt_mars_army_info->add(s_mars_army_info.c_str());
169 txt_mars_army_subj->value(s_mars_army_subj.c_str());
170 txt_mars_army_text->add(s_mars_army_text.c_str());
171
172 }
173
clear_mars_army_form()174 void clear_mars_army_form()
175 {
176 clear_mars_armyfields();
177 sel_mars_army_prec->index(0);
178 txt_mars_army_dtg->value("");
179 txt_mars_army_fm->value("");
180 txt_mars_army_de->value("");
181 txt_mars_army_nbr->value("");
182
183 txt_mars_army_to->clear();
184 txt_mars_army_info->clear();
185 txt_mars_army_subj->value("");
186 txt_mars_army_text->clear();
187 }
188
make_buffmars_army(bool compress=false)189 void make_buffmars_army(bool compress = false)
190 {
191 string mbuff;
192 mbuff.clear();
193 mbuff.append( lineout( mars_army_prec, s_mars_army_prec ) );
194 mbuff.append( lineout( mars_army_dtg, s_mars_army_dtg ) );
195 mbuff.append( lineout( mars_army_fm, s_mars_army_fm ) );
196 mbuff.append( lineout( mars_army_de, s_mars_army_de ) );
197 mbuff.append( lineout( mars_army_nbr, s_mars_army_nbr ) );
198 mbuff.append( lineout( mars_army_to, s_mars_army_to ) );
199 mbuff.append( lineout( mars_army_info, s_mars_army_info ) );
200 mbuff.append( lineout( mars_army_subj, s_mars_army_subj ) );
201 mbuff.append( lineout( mars_army_text, s_mars_army_text ) );
202 if (compress) compress_maybe(mbuff);
203 buffmars_army.append(mbuff);
204 }
205
read_mars_army_buffer(string data)206 void read_mars_army_buffer(string data)
207 {
208 clear_mars_armyfields();
209 // search the file buffer for each of the mars_army fields
210 s_mars_army_prec = findstr( data, mars_army_prec );
211 s_mars_army_dtg = findstr( data, mars_army_dtg );
212 s_mars_army_fm = findstr( data, mars_army_fm );
213 s_mars_army_de = findstr( data, mars_army_de );
214 s_mars_army_nbr = findstr( data, mars_army_nbr );
215 s_mars_army_to = findstr( data, mars_army_to );
216 s_mars_army_info = findstr( data, mars_army_info );
217 s_mars_army_subj = findstr( data, mars_army_subj );
218 s_mars_army_text = findstr( data, mars_army_text );
219
220 update_mars_armyform();
221 }
222
cb_mars_army_new()223 void cb_mars_army_new()
224 {
225 if (check_mars_armyfields()) {
226 if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 1) {
227 update_header(CHANGED);
228 cb_mars_army_save();
229 }
230 }
231 clear_mars_army_form();
232 def_mars_army_filename = ICS_msg_dir;
233 def_mars_army_filename.append("new").append(FMARSARMY_EXT);
234 show_filename(def_mars_army_filename);
235 using_mars_army_template = false;
236 }
237
cb_mars_army_import()238 void cb_mars_army_import()
239 {
240 fl_alert2("Not implemented");
241 }
242
cb_mars_army_export()243 void cb_mars_army_export()
244 {
245 fl_alert2("Not implemented");
246 }
247
cb_mars_army_wrap_import(string wrapfilename,string inpbuffer)248 void cb_mars_army_wrap_import(string wrapfilename, string inpbuffer)
249 {
250 clear_mars_army_form();
251 read_mars_army_buffer(inpbuffer);
252 def_mars_army_filename = ICS_msg_dir;
253 def_mars_army_filename.append(wrapfilename);
254 show_filename(def_mars_army_filename);
255 using_mars_army_template = false;
256 }
257
eval_mars_army_fsize()258 int eval_mars_army_fsize()
259 {
260 Ccrc16 chksum;
261 evalstr.assign("[WRAP:beg][WRAP:lf][WRAP:fn ");
262 evalstr.append(base_mars_army_filename).append("]");
263 update_mars_armyfields();
264 update_header(FROM);
265 evalstr.append(header("<mars_army>"));
266 buffmars_army.clear();
267 make_buffmars_army(true);
268 if (buffmars_army.empty()) return 0;
269 compress_maybe( buffmars_army );
270 evalstr.append( buffmars_army );
271 evalstr.append("[WRAP:chksum ").append(chksum.scrc16(evalstr)).append("][WRAP:end]");
272 return evalstr.length();
273 }
274
cb_mars_army_wrap_export()275 void cb_mars_army_wrap_export()
276 {
277 if (check_mars_armyfields()) {
278 if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 0)
279 return;
280 update_header(CHANGED);
281 }
282 update_mars_armyfields();
283
284 if (base_mars_army_filename == string("new").append(FMARSARMY_EXT) ||
285 base_mars_army_filename == string("default").append(FMARSARMY_EXT) )
286 if (!cb_mars_army_save_as()) return;
287
288 string wrapfilename = WRAP_send_dir;
289 wrapfilename.append(base_mars_army_filename);
290 wrapfilename.append(".wrap");
291 const char *p = FSEL::saveas(
292 "Save as wrap file",
293 "Wrap file\t*.{wrap,WRAP}",
294 wrapfilename.c_str());
295 if (p) {
296 string pext = fl_filename_ext(p);
297 wrapfilename = p;
298
299 update_header(FROM);
300 buffmars_army.assign(header("<mars_army>"));
301 make_buffmars_army(true);
302 export_wrapfile(base_mars_army_filename, wrapfilename, buffmars_army, pext != ".wrap");
303
304 buffmars_army.assign(header("<mars_army>"));
305 make_buffmars_army(false);
306 write_mars_army(def_mars_army_filename);
307 }
308 }
309
cb_mars_army_wrap_autosend()310 void cb_mars_army_wrap_autosend()
311 {
312 if (check_mars_armyfields()) {
313 if (fl_choice2("Form modified, save?", "No", "Yes", NULL) == 0)
314 return;
315 update_header(CHANGED);
316 }
317 update_mars_armyfields();
318
319 if (base_mars_army_filename == string("new").append(FMARSARMY_EXT) ||
320 base_mars_army_filename == string("default").append(FMARSARMY_EXT) )
321 if (!cb_mars_army_save_as()) return;
322
323 update_header(FROM);
324 buffmars_army.assign(header("<mars_army>"));
325 make_buffmars_army(true);
326 xfr_via_socket(base_mars_army_filename, buffmars_army);
327
328 buffmars_army.assign(header("<mars_army>"));
329 make_buffmars_army(false);
330 write_mars_army(def_mars_army_filename);
331 }
332
cb_mars_army_load_template()333 void cb_mars_army_load_template()
334 {
335 string def_mars_army_filename = def_mars_army_TemplateName;
336 const char *p = FSEL::select(
337 "Open template file",
338 string("Template file\t*").append(TMARSARMY_EXT).c_str(),
339 def_mars_army_filename.c_str());
340 if (p) {
341 clear_mars_army_form();
342 read_data_file(p);
343 def_mars_army_TemplateName = p;
344 show_filename(def_mars_army_TemplateName);
345 using_mars_army_template = true;
346 }
347 }
348
cb_mars_army_save_template()349 void cb_mars_army_save_template()
350 {
351 if (!using_mars_army_template) {
352 cb_mars_army_save_as_template();
353 return;
354 }
355 string def_mars_army_filename = def_mars_army_TemplateName;
356 const char *p = FSEL::saveas(
357 "Save template file",
358 string("Template file\t*").append(TMARSARMY_EXT).c_str(),
359 def_mars_army_filename.c_str());
360 if (p)
361 write_mars_army(p);
362 if (p) {
363 update_header(CHANGED);
364 update_mars_armyfields();
365 buffmars_army.assign(header("<mars_army>"));
366 make_buffmars_army();
367 write_mars_army(p);
368 }
369 }
370
cb_mars_army_save_as_template()371 void cb_mars_army_save_as_template()
372 {
373 string def_mars_army_filename = def_mars_army_TemplateName;
374 const char *p = FSEL::saveas(
375 "Save as template file",
376 string("Template file\t*").append(TMARSARMY_EXT).c_str(),
377 def_mars_army_filename.c_str());
378 if (p) {
379 const char *pext = fl_filename_ext(p);
380 def_mars_army_TemplateName = p;
381 if (strlen(pext) == 0) def_mars_army_TemplateName.append(TMARSARMY_EXT);
382 remove_spaces_from_filename(def_mars_army_TemplateName);
383
384 clear_header();
385 update_header(CHANGED);
386 update_mars_armyfields();
387 buffmars_army.assign(header("<mars_army>"));
388 make_buffmars_army();
389 write_mars_army(def_mars_army_TemplateName);
390
391 show_filename(def_mars_army_TemplateName);
392 using_mars_army_template = true;
393 }
394 }
395
cb_mars_army_open()396 void cb_mars_army_open()
397 {
398 const char *p = FSEL::select(
399 _("Open data file"),
400 string("ICS-mars_army\t*").append(FMARSARMY_EXT).c_str(),
401 def_mars_army_filename.c_str());
402 if (!p) return;
403 if (strlen(p) == 0) return;
404 clear_mars_army_form();
405 read_data_file(p);
406 using_mars_army_template = false;
407 def_mars_army_filename = p;
408 show_filename(def_mars_army_filename);
409 }
410
write_mars_army(string s)411 void write_mars_army(string s)
412 {
413 FILE *filemars_army = fopen(s.c_str(), "w");
414 if (!filemars_army) return;
415 make_buffmars_army();
416 fwrite(buffmars_army.c_str(), buffmars_army.length(), 1, filemars_army);
417 fclose(filemars_army);
418 }
419
cb_mars_army_save_as()420 bool cb_mars_army_save_as()
421 {
422 const char *p;
423 string newfilename;
424
425 string name = named_file();
426 if (!name.empty()) {
427 name.append(FMARSARMY_EXT);
428 newfilename = ICS_msg_dir;
429 newfilename.append(name);
430 } else
431 newfilename = def_mars_army_filename;
432
433 p = FSEL::saveas(
434 _("Save data file"),
435 string("ICS-mars_army\t*").append(FMARSARMY_EXT).c_str(),
436 newfilename.c_str());
437
438 if (!p) return false;
439 if (strlen(p) == 0) return false;
440
441 if (progStatus.sernbr_fname) update_sernbr();
442
443 const char *pext = fl_filename_ext(p);
444 def_mars_army_filename = p;
445 if (strlen(pext) == 0) def_mars_army_filename.append(FMARSARMY_EXT);
446
447 remove_spaces_from_filename(def_mars_army_filename);
448
449 update_header(NEW);
450 update_mars_armyfields();
451 buffmars_army.assign(header("<mars_army>"));
452 make_buffmars_army();
453 write_mars_army(def_mars_army_filename);
454
455 using_mars_army_template = false;
456 show_filename(def_mars_army_filename);
457 return true;
458 }
459
cb_mars_army_save()460 void cb_mars_army_save()
461 {
462 if (base_mars_army_filename == string("new").append(FMARSARMY_EXT) ||
463 base_mars_army_filename == string("default").append(FMARSARMY_EXT) ||
464 using_mars_army_template == true) {
465 cb_mars_army_save_as();
466 return;
467 }
468
469 if (check_mars_armyfields()) update_header(CHANGED);
470 update_mars_armyfields();
471 buffmars_army.assign(header("<mars_army>"));
472 make_buffmars_army();
473 write_mars_army(def_mars_army_filename);
474
475 using_mars_army_template = false;
476 }
477
cb_mars_army_html()478 void cb_mars_army_html()
479 {
480 string fname_name = fl_filename_name(def_mars_army_filename.c_str());
481 size_t p = fname_name.rfind('.');
482 if (p != string::npos) fname_name.erase(p);
483
484 string mars_army_fname = ICS_dir;
485 mars_army_fname.append(fname_name);
486 mars_army_fname.append(".html");
487
488 update_mars_armyfields();
489 string formmars_army = mars_army_html_template;
490
491 replacestr(formmars_army, TITLE, fname_name);
492
493 replacestr(formmars_army, mars_army_prec, s_mars_army_prec );
494 replacestr(formmars_army, mars_army_dtg, s_mars_army_dtg );
495 replacestr(formmars_army, mars_army_fm, s_mars_army_fm );
496 replacestr(formmars_army, mars_army_de, s_mars_army_de );
497 replacestr(formmars_army, mars_army_nbr, s_mars_army_nbr );
498 replacestr(formmars_army, mars_army_to, s_mars_army_to );
499
500 if (s_mars_army_info.empty()) {
501 size_t p = formmars_army.find("INFO");
502 size_t p2 = formmars_army.find('\n', p);
503 formmars_army.erase(p, p2 - p + 1);
504 } else
505 replacestr(formmars_army, mars_army_info, s_mars_army_info );
506
507 string text = "";
508 string temp = "";
509 if (!s_mars_army_subj.empty()) {
510 temp = "SUBJ: "; temp.append(s_mars_army_subj);
511 temp = maxchars(temp, 69, 6);
512 text = temp;
513 text += '\n';
514 }
515 temp = maxchars(s_mars_army_text, 69);
516 text.append(temp);
517
518 replacestr(formmars_army, mars_army_text, text );
519
520 FILE *filemars_army = fopen(mars_army_fname.c_str(), "w");
521 fprintf(filemars_army,"%s", formmars_army.c_str());
522 fclose(filemars_army);
523
524 open_url(mars_army_fname.c_str());
525 }
526
cb_mars_army_msg_type()527 void cb_mars_army_msg_type()
528 {
529 if (tabs_msg_type->value() == tab_mars_army ) {
530 show_filename(def_mars_army_filename);
531 } else {
532 show_filename(def_rg_filename);
533 }
534 }
535
cb_mars_army_textout()536 void cb_mars_army_textout()
537 {
538 string mars_army_fname = ICS_dir;
539 mars_army_fname.append("mars_army.txt");
540
541 update_mars_armyfields();
542 string formmars_army = mars_army_text_template;
543
544 replacestr(formmars_army, mars_army_prec, s_mars_army_prec );
545 replacestr(formmars_army, mars_army_dtg, s_mars_army_dtg );
546 replacestr(formmars_army, mars_army_fm, s_mars_army_fm );
547 replacestr(formmars_army, mars_army_de, s_mars_army_de );
548 replacestr(formmars_army, mars_army_nbr, s_mars_army_nbr );
549 replacestr(formmars_army, mars_army_to, s_mars_army_to );
550
551 if (s_mars_army_info.empty()) {
552 size_t p = formmars_army.find("INFO");
553 size_t p2 = formmars_army.find('\n', p);
554 formmars_army.erase(p, p2 - p + 1);
555 } else
556 replacestr(formmars_army, mars_army_info, s_mars_army_info );
557
558 string text = "";
559 string temp = "";
560 if (!s_mars_army_subj.empty()) {
561 temp = "SUBJ: "; temp.append(s_mars_army_subj);
562 temp = maxchars(temp, 69, 6);
563 text = temp;
564 text += '\n';
565 }
566 temp = maxchars(s_mars_army_text, 69);
567 text.append(temp);
568
569 replacestr(formmars_army, mars_army_text, text );
570
571 FILE *filemars_army = fopen(mars_army_fname.c_str(), "w");
572 fprintf(filemars_army,"%s", formmars_army.c_str());
573 fclose(filemars_army);
574
575 open_url(mars_army_fname.c_str());
576 }
577
578