-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathQtTermTCP.cpp
More file actions
8189 lines (6171 loc) · 198 KB
/
Copy pathQtTermTCP.cpp
File metadata and controls
8189 lines (6171 loc) · 198 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Qt Version of BPQTermTCP
// Application icon design by Red PE1RRR
#define VersionString "0.0.0.81"
// .12 Save font weight
// .13 Display incomplete lines (ie without CR)
// .14 Add YAPP and Listen Mode
// .15 Reuse windows in Listen Mode
// .17 MDI Version 7/1/20
// .18 Fix input window losing focus when data arrivn other window
// .19 Fix Scrollback
// .20 WinXP compatibility changes
// .21 Save Window Positions
// .22 Open a window on first start
// .23 Add Tabbed display option
// .24 Fix crash when setting Monitor flags in Tabbed mode
// .25 Add AGW mode
// .26 Add sending CTRL/C CTRL/D and CTRL/Z)
// .27 Limit size of windows to 10000 lines
// Fix YAPP in Tabbed Mode
// .28 Add AGW Beacon
// .29 Fix allocating Listem sessions to tabs connected using AGW
// .30 Fix allocationd AGW Monitor Sessions
// .31 Fix output being written to the wrong place when window is scrolled back
// .32 Fix connect with digis
// .33 Add StripLF option
// .34 Improvements for Andriod
// Option to change Menu Fonts
// Fix receiving part lines when scrolled back
// .35 Fix PE if not in Tabbed Mode
// .36 Improved dialogs mainly for Android
// Try to make sure sessions are closed before exiting
// .37 Replace VT with LF (for pasting from BPQ32 Terminal Window)
// Dont show AGW status line if AGW interface is disabled
// Don't show Window Menu in Single Mode
// .38 Protect against connect to normal Telnet Port.
// Send CTEXT and Beep for inward AGW Connects
// Make sending Idle and Connect beeps configurable
// Change displayed Monitor flags when active window changed.
// Fix duplicate text on long lines
// .39 Add option to Convert non-utf8 charaters
// .40 Prevent crash if AGW monitor Window closed
// .41 Allow AGW Config and Connect dialogs to be resized with scrollbars
// Fix disabling connect flag on current session when AGW connects
// .42 Fix some bugs in AGW session handling
// .43 Include Ross KD5LPB's fixes for MAC
// .44 Ctrl/[ sends ESC (0x1b)
// .45 Add VARA support Nov 2021
// .46 Fix dialog size on VARA setup
// .47 Move VARA Status indicator.
// Add FLRIG PTT for VARA
// .48 Check that YAPP Receive Directory has been set
// Save separate configs for VARA, VARAFM and VARASAT
// .49 Add BBS Monitor Dec 2021
// .50 Make Serial port support optional for Android Version
// .51 Add KISS TNC Support May 2022
// .52 Save partially typed lines on cursor up May 2022
// .53 Add UI Mode for KISS Sessions May 2022
// Fix saving KISS Paclen (b)
// Fix Keepalive (c)
// .54 Add option to change screen colours June 2022
// .55 Build without optimisation
// .56 Add Teletext mode Nov 2022
// .57 Fix KISS mode incoming call handling
// .58 Add method to toggle Normal/Teletext Mode
// Fix KISS multiple session protection
// .59 Add Teletext double height mode
// .60 Add option to name sessions Jan 2023
// .61 Add VARA Init Script Feb 2023
// .62 Fix running AGW in single session mode Feb 2023
// .63 Fix handling split monitor frame (no fe in buffer) Apr 2023
// .64 Add Clear Screen command to context menu Apr 2023
// .65 Fixes for 63 port version of BPQ May 2023
// .66 Colour Tab of incoming calls June 2023
// .67 Add config Yapp RX Size dialog July 2023
// Fix 63 port montoring
// .68 Sept 2023
// Remember last used host on restart
// Add AutoConnect in Tabbed Mode
// Fix auto copy when QtTerm not active window
// .69 October 2023
// Options related to sound alerts moved to a separte menu in Setup
// Allow use of WAV files instead of Beep sound for sound alerts
// Enable an alarm to be sounded when one of a list of words or phrases is received.
// .70 October 2023
// Include some .wav files in resources
// Add Test button to Alert setup dialog
// .71 October 2023
// Add option to use local time
// Fixes for Mac OS
// .72 November 2023
// Don't display "Enable Monitor" on startup
// .73 November 2023
// Raise RTS on KISS serial port
// .74 April 2024
// Support BPQKISS TNCs with CHECKSUM and/or ACKMODE enabled
// .75 May 2024
// Flush Monitor log file every minute
// .76 August 2024
// Fix using digs in KISS UI mode.
// Add option to send TXDELAY to KISS TNC
// .77
// Support multichannel KISS TNCs (Beta 1)
// Fix using AGW listen in single terminal mode
// .78
// Fix restoring monitor flags when connecting to current host
// .79
// Add KISS MHEARD Window (Feb 2025)
// .80
// Allow sending BEL (Ctrl/G)
// Map Chat colour black to Other Text colour (for when using black background)
// .81
// Allow configuring resptime in KISS interface (Feb 26)
#define _CRT_SECURE_NO_WARNINGS
#define UNUSED(x) (void)(x)
#define USESERIAL
#include "QtTermTCP.h"
#include "TabDialog.h"
#include <time.h>
#include <QVBoxLayout>
#include <QListWidgetItem>
#include <QToolButton>
#include <QInputMethod>
#include "QTreeWidget"
#include <QToolBar>
#include <QLabel>
#include <QAction>
#include <QtWidgets>
#include <QColor>
#include <QClipboard>
#ifdef USESERIAL
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#endif
#ifndef WIN32
#define strtok_s strtok_r
#endif
#include <fcntl.h>
#include <errno.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include "ax25.h"
#define UNREFERENCED_PARAMETER(P) (P)
void DecodeTeleText(Ui_ListenSession * Sess, char * text);
char Host[MAXHOSTS + 1][100] = { "" };
int Port[MAXHOSTS + 1] = { 0 };
char UserName[MAXHOSTS + 1][80] = { "" };
char Password[MAXHOSTS + 1][80] = { "" };
char MonParams[MAXHOSTS + 1][80] = { "" };
char SessName[MAXHOSTS + 1][80] = { "" };
int ListenPort = 8015;
// Session Type Equates
#define Term 1
#define Mon 2
#define Listen 4
// Presentation - Single Window, MDI or Tabbed
int TermMode = 0;
#define Single 0
#define MDI 1
#define Tabbed 2
int singlemodeFormat = Mon + Term;
char monStyleSheet[128] = "background-color: rgb(0,255,255)";
char termStyleSheet[128] = "background-color: rgb(255,0,255);";
char inputStyleSheet[128] = "color: rgb(255, 0, 0); background-color: rgb(255,255,0);";
QColor monBackground = qRgb(0, 255, 255);
QColor monRxText = qRgb(0, 0, 255);
QColor monTxText = qRgb(255, 0, 0);
QColor monOtherText = qRgb(0, 0, 0);
QColor termBackground = qRgb(255, 0, 255);
QColor outputText = qRgb(0, 0, 0);
QColor EchoText = qRgb(0, 0, 255);
QColor WarningText = qRgb(255, 0, 0);
QColor inputBackground = qRgb(255, 255, 0);
QColor inputText = qRgb(0, 0, 255);
QColor newTabText = qRgb(255, 0, 0); // Red
QColor oldTabText = qRgb(0, 0, 0); // Black
// There is something odd about this. It doesn't match BPQTERMTCP though it looks the same
// Chat uses these (+ 10)
//{ 0, 4, 9, 11, 13, 16, 17, 42, 45, 50, 61, 64, 66, 72, 81, 84, 85, 86, 87, 89 };
// As we have a white background we need dark colours
// 0 is black. 23 is normal output (blue) 81 is red (used by AGW Mon)
// for monitor in colour, host sends 17 for RX Text, 81 for TX Text but code converts to monRx/TxText qrgb values
QRgb Colours[256] = { 0,
qRgb(0,0,0), qRgb(0,0,128), qRgb(0,0,192), qRgb(0,0,255), // 1 - 4
qRgb(0,64,0), qRgb(0,64,128), qRgb(0,64,192), qRgb(0,64,255), // 5 - 8
qRgb(0,128,0), qRgb(0,128,128), qRgb(0,128,192), qRgb(0,128,255), // 9 - 12
qRgb(0,192,0), qRgb(0,192,128), qRgb(0,192,192), qRgb(0,192,255), // 13 - 16
qRgb(0,255,0), qRgb(0,255,128), qRgb(0,255,192), qRgb(0,255,255), // 17 - 20
qRgb(64,0,0), qRgb(64,0,128), qRgb(64,0,192), qRgb(0,0,255), // 21
qRgb(64,64,0), qRgb(64,64,128), qRgb(64,64,192), qRgb(64,64,255),
qRgb(64,128,0), qRgb(64,128,128), qRgb(64,128,192), qRgb(64,128,255),
qRgb(64,192,0), qRgb(64,192,128), qRgb(64,192,192), qRgb(64,192,255),
qRgb(64,255,0), qRgb(64,255,128), qRgb(64,255,192), qRgb(64,255,255),
qRgb(128,0,0), qRgb(128,0,128), qRgb(128,0,192), qRgb(128,0,255), // 41
qRgb(128,64,0), qRgb(128,64,128), qRgb(128,64,192), qRgb(128,64,255),
qRgb(128,128,0), qRgb(128,128,128), qRgb(128,128,192), qRgb(128,128,255),
qRgb(128,192,0), qRgb(128,192,128), qRgb(128,192,192), qRgb(128,192,255),
qRgb(128,255,0), qRgb(128,255,128), qRgb(128,255,192), qRgb(128,255,255),
qRgb(192,0,0), qRgb(192,0,128), qRgb(192,0,192), qRgb(192,0,255), // 61 - 80
qRgb(192,64,0), qRgb(192,64,128), qRgb(192,64,192), qRgb(192,64,255),
qRgb(192,128,0), qRgb(192,128,128), qRgb(192,128,192), qRgb(192,128,255),
qRgb(192,192,0), qRgb(192,192,128), qRgb(192,192,192), qRgb(192,192,255),
qRgb(192,255,0), qRgb(192,255,128), qRgb(192,255,192), qRgb(192,255,255),
qRgb(255,0,0), qRgb(255,0,128), qRgb(255,0,192), qRgb(255,0,255), // 81 - 100
qRgb(255,64,0), qRgb(255,64,128), qRgb(255,64,192), qRgb(255,64,255),
qRgb(255,128,0), qRgb(255,128,128), qRgb(255,128,192), qRgb(255,128,255),
qRgb(255,192,0), qRgb(255,192,128), qRgb(255,192,192), qRgb(255,192,255),
qRgb(255,255,0), qRgb(255,255,128), qRgb(255,255,192), qRgb(255,255,255)
};
int SavedHost = 0; // from config
char * sessionList = NULL; // Saved sessions
extern int ChatMode;
extern int Bells;
extern int StripLF;
extern int convUTF8;
extern time_t LastWrite;
extern int AlertInterval;
extern int AlertBeep;
extern int AlertFreq;
extern int AlertDuration;
extern int ConnectBeep;
bool useBeep; // use wav files if not set
extern int UseKeywords;
extern QString KeyWordsFile;
QString ConnectWAV("");
QString AlertWAV("");
QString BellWAV("");
QString IntervalWAV("");
extern int MaxRXSize;
extern int AutoTeletext;
// AGW Host Interface stuff
int AGWEnable = 0;
int AGWMonEnable = 0;
int AGWLocalTime = 0;
int AGWMonNodes = 0;
char AGWTermCall[12] = "";
char AGWBeaconDest[12] = "";
char AGWBeaconPath[80] = "";
int AGWBeaconInterval = 0;
char AGWBeaconPorts[80];
char AGWBeaconMsg[260] = "";
char AGWHost[128] = "127.0.0.1";
int AGWPortNum = 8000;
int AGWPaclen = 80;
extern char * AGWPortList;
extern myTcpSocket * AGWSock;
typedef struct AGWUser_t
{
QTcpSocket *socket;
unsigned char data_in[8192];
int data_in_len;
unsigned char AGW_frame_buf[512];
int Monitor;
int Monitor_raw;
Ui_ListenSession * MonSess; // Window for Monitor info
} AGWUser;
extern AGWUser *AGWUsers; // List of currently connected clients
void Send_AGW_m_Frame(QTcpSocket* socket);
QStringList AGWToCalls;
// KISS Interface
int KISSEnable = 0;
extern "C" int KISSMonEnable;
extern "C" int KISSLocalTime;
extern "C" int KISSMonNodes;
extern "C" int KISSListen;
extern "C" int KISSChecksum;
extern "C" int KISSAckMode;
extern "C" int KISSMH;
extern "C" short txtail[5];
extern "C" short txdelay[5];
extern "C" int sendTXDelay[4];
char SerialPort[80] = "";
char KISSHost[128] = "127.0.0.1";
int KISSPortNum = 1000;
int KISSBAUD = 19200;
char KISSMYCALL[32];
char KISSVia[128]; // Digi String
extern "C" UCHAR axMYCALL[7]; // Mycall in ax.25
int KISSMode = 0; // Connected (0) or UI (1)
myTcpSocket * KISSSock;
extern "C" void * KISSSockCopy[4];
int KISSConnected = 0;
int KISSConnecting = 0;
Ui_ListenSession * KISSMonSess = nullptr;
QSerialPort * m_serial = nullptr;
// VARA Interface
int VARAEnable = 0;
char VARAHost[128] = "127.0.0.1";
char VARAHostHF[128] = "127.0.0.1";
char VARAHostFM[128] = "127.0.0.1";
char VARAHostSAT[128] = "127.0.0.1";
int VARAPortNum = 8000;
int VARAPortHF = 8000;
int VARAPortFM = 8000;
int VARAPortSAT = 8000;
char VARATermCall[12] = "";
char VARAPath[256] = "";
char VARAInit[256] = "";
char VARAPathHF[256] = "";
char VARAPathFM[256] = "";
char VARAPathSAT[256] = "";
int VARA500 = 0;
int VARA2300 = 1;
int VARA2750 = 0;
int VARAHF = 1;
int VARAFM = 0;
int VARASAT = 0;
myTcpSocket * VARASock;
myTcpSocket * VARADataSock;
int VARAConnected = 0;
int VARAConnecting = 0;
extern char YAPPPath[256];
void menuChecked(QAction * Act);
// PTT Stuff
#define PTTRTS 1
#define PTTDTR 2
#define PTTCAT 4
#define PTTCM108 8
#define PTTHAMLIB 16
#define PTTFLRIG 32
#ifdef USESERIAL
QSerialPort * hPTTDevice = 0;
#else
#endif
char PTTPort[80] = ""; // Port for Hardware PTT - may be same as control port.
int PTTBAUD = 19200;
int PTTMode = PTTRTS; // PTT Control Flags.
char PTTOnString[128] = "";
char PTTOffString[128] = "";
int CATHex = 1;
unsigned char PTTOnCmd[64];
int PTTOnCmdLen = 0;
unsigned char PTTOffCmd[64];
int PTTOffCmdLen = 0;
int pttGPIOPin = 17; // Default
int pttGPIOPinR = 17;
bool pttGPIOInvert = false;
bool useGPIO = false;
bool gotGPIO = false;
int HamLibPort = 4532;
char HamLibHost[32] = "192.168.1.14";
int FLRigPort = 12345;
char FLRigHost[32] = "127.0.0.1";
char CM108Addr[80] = "";
int VID = 0;
int PID = 0;
// CM108 Code
char * CM108Device = NULL;
QProcess *process = NULL;
void GetSettings();
// These widgets defined here as they are accessed from outside the framework
QLabel * Status1;
QLabel * Status2;
QLabel * Status3;
QLabel * Status4;
QAction *actHost[19];
QAction *actSetup[16];
QAction * TabSingle = NULL;
QAction * TabBoth = NULL;
QAction * TabMon = NULL;
QMenu *monitorMenu;
QMenu * YAPPMenu;
QMenu *connectMenu;
QMenu *disconnectMenu;
QAction *EnableMonitor;
QAction *EnableMonLog;
QAction *MonLocalTime;
QAction *MonTX;
QAction *MonSup;
QAction *MonNodes;
QAction *MonUI;
QAction *MonColour;
QAction *MonPort[65];
QAction *actChatMode;
QAction *actAutoTeletext;
QAction *actBells;
QAction *actStripLF;
QAction *actIntervalBeep;
QAction *actConnectBeep;
QAction *actAuto;
QAction *actnoConv;
QAction *actCP1251;
QAction *actCP1252;
QAction *actCP437;
QAction *actFonts;
QAction *actmenuFont;
QAction *actColours;
QAction *actmyFonts;
QAction *YAPPSend;
QAction *YAPPSetRX;
QAction *YAPPSetSize;
QAction *singleAct;
QAction *singleAct2;
QAction *MDIAct;
QAction *tabbedAct;
QAction *discAction;
QFont * menufont;
QMenu *windowMenu;
QMenu *setupMenu;
QAction *ListenAction;
QTabWidget *tabWidget;
QMdiArea *mdiArea;
QWidget * mythis;
QStatusBar * myStatusBar;
QTcpServer * _server;
QMenuBar *mymenuBar;
QToolBar *toolBar;
QToolButton * but1;
QToolButton * but2;
QToolButton * but3;
QToolButton * but4;
QToolButton * but5;
QList<Ui_ListenSession *> _sessions;
// Session Type Equates
#define Term 1
#define Mon 2
#define Listen 4
int TabType[10] = { Term, Term + Mon, Term, Term, Term, Term, Mon, Mon, Mon };
int AutoConnect[10] = {0, 0 ,0, 0, 0, 0, 0, 0, 0, 0};
int currentHost[10] = {0, 0 ,0, 0, 0, 0, 0, 0, 0, 0};
int listenPort = 8015;
extern "C" int listenEnable;
char listenCText[4096] = "";
int ConfigHost = 0;
int Split = 50; // Mon/Term size split
int termX;
bool Cascading = false; // Set to stop size being saved when cascading
QMdiSubWindow * ActiveSubWindow = NULL;
Ui_ListenSession * ActiveSession = NULL;
Ui_ListenSession * newWindow(QObject * parent, int Type, const char * Label = nullptr);
void Send_AGW_C_Frame(Ui_ListenSession * Sess, int Port, char * CallFrom, char * CallTo, char * Data, int DataLen);
void AGW_AX25_data_in(void * AX25Sess, unsigned char * data, int Len);
void AGWMonWindowClosing(Ui_ListenSession *Sess);
void AGWWindowClosing(Ui_ListenSession *Sess);
extern "C" void KISSDataReceived(void * socket, unsigned char * data, int length);
void closeSerialPort();
int newMHWindow(int Type, const char * Label);
extern void initUTF8();
int checkUTF8(unsigned char * Msg, int Len, unsigned char * out);
QDialog * deviceUI;
#include <QStandardPaths>
#include <sys/stat.h>
#include <sys/types.h>
void EncodeSettingsLine(int n, char * String)
{
sprintf(String, "%s|%d|%s|%s|%s|%s", Host[n], Port[n], UserName[n], Password[n], MonParams[n], SessName[n]);
return;
}
// This is used for placing discAction in the preference menu
#ifdef __APPLE__
bool is_mac = true;
#else
bool is_mac = false;
#endif
QString GetConfPath()
{
std::string conf_path = "QtTermTCP.ini"; // Default conf file stored alongside application.
#ifdef __APPLE__
// Get configuration path for MacOS.
// This will usually be placed in /Users/USER/Library/Application Support/QtTermTCP
std::string directory = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).at(0).toStdString();
conf_path = directory + "/QtTermTCP.ini";
mkdir(directory.c_str(), 0775);
#endif
return QString::fromUtf8(conf_path.c_str());
}
void DecodeSettingsLine(int n, char * String)
{
char * Param = strdup(String);
char * Rest;
char * Save = Param; // for Free
Rest = strlop(Param, '|');
if (Rest == NULL)
return;
strcpy(Host[n], Param);
Param = Rest;
Rest = strlop(Param, '|');
Port[n] = atoi(Param);
Param = Rest;
Rest = strlop(Param, '|');
strcpy(UserName[n], Param);
Param = Rest;
Rest = strlop(Param, '|');
strcpy(Password[n], Param);
Param = Rest;
Rest = strlop(Param, '|');
strcpy(MonParams[n], Param);
if (Rest)
strcpy(SessName[n], Rest);
free(Save);
return;
}
//#ifdef ANDROID
//#define inputheight 60
//#else
#define inputheight 25
//#endif
extern "C" void SendtoAX25(void * conn, unsigned char * Msg, int Len);
void DoTermResize(Ui_ListenSession * Sess)
{
QRect r = Sess->rect();
int H, Mid, monHeight, termHeight, Width, Border = 3;
Width = r.width();
H = r.height();
if (TermMode == Tabbed)
{
// H -= 20;
Width -= 7;
}
else if (TermMode == Single)
{
Width -= 7;
// H += 20;
}
if (Sess->SessionType == Listen || Sess->SessionType == Term)
{
// Term and Input
// Calc Positions of window
termHeight = H - (inputheight + 3 * Border);
Sess->termWindow->setGeometry(QRect(Border, Border, Width, termHeight));
if (Sess->TTActive)
{
Sess->TTLabel->setGeometry(QRect(Border, Border, 600, 475));
// Sess->termWindow->setVisible(false);
Sess->TTLabel->setVisible(true);
}
else
{
// Sess->termWindow->setVisible(true);
Sess->TTLabel->setVisible(false);
}
Sess->inputWindow->setGeometry(QRect(Border, H - (inputheight + Border), Width, inputheight));
}
else if (Sess->SessionType == (Term | Mon))
{
// All 3
// Calc Positions of window
Mid = (H * Split) / 100;
monHeight = Mid - Border;
termX = Mid;
termHeight = H - Mid - (inputheight + 3 * Border);
Sess->monWindow->setGeometry(QRect(Border, Border, Width, monHeight));
Sess->termWindow->setGeometry(QRect(Border, Mid + Border, Width, termHeight));
if (Sess->TTActive)
{
Sess->TTLabel->setGeometry(QRect(3, Mid + Border, 600, 475));
// Sess->termWindow->setVisible(false);
Sess->TTLabel->setVisible(true);
}
else
{
// Sess->termWindow->setVisible(true);
Sess->TTLabel->setVisible(false);
}
Sess->inputWindow->setGeometry(QRect(Border, H - (inputheight + Border), Width, inputheight));
}
else
{
// Should just be Mon only
Sess->monWindow->setGeometry(QRect(Border, Border, Width, H - 2 * Border));
}
}
extern "C" Ui_ListenSession * MHWindow;
bool QtTermTCP::eventFilter(QObject* obj, QEvent *event)
{
// See if from a Listening Session
Ui_ListenSession * Sess;
if (obj == MHWindow)
{
if (event->type() == QEvent::Resize)
{
QRect r = MHWindow->rect();
int H, Width, Border = 3;
Width = r.width() - 6;
H = r.height() - 6;
MHWindow->monWindow->setGeometry(QRect(Border, Border, Width, H));
return true;
}
if (event->type() == QEvent::Close)
{
QSettings mysettings(GetConfPath(), QSettings::IniFormat);
mysettings.setValue("MHgeometry", MHWindow->saveGeometry());
SaveSettings();
MHWindow = 0;
}
}
for (int i = 0; i < _sessions.size(); ++i)
{
Sess = _sessions.at(i);
// Sess = _sessions.at(i); for (Ui_ListenSession * Sess : _sessions)
// {
if (Sess == NULL)
continue;
if (Sess == obj)
{
if (event->type() == QEvent::Close)
{
// Window closing
// This only closed mon sessinos
if (Sess->AGWMonSession)
// AGWMonWindowClosing(Sess);
AGWWindowClosing(Sess);
if (Sess->AGWSession)
AGWWindowClosing(Sess);
if (Sess->clientSocket)
{
int loops = 100;
Sess->clientSocket->disconnectFromHost();
while (Sess->clientSocket && loops-- && Sess->clientSocket->state() != QAbstractSocket::UnconnectedState)
QThread::msleep(10);
}
_sessions.removeOne(Sess);
return QMainWindow::eventFilter(obj, event);
}
if (event->type() == QEvent::Resize)
{
DoTermResize(Sess);
}
}
if (Sess->inputWindow == obj)
{
if (event->type() == QEvent::KeyPress)
{
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
int key = keyEvent->key();
Qt::KeyboardModifiers modifier = keyEvent->modifiers();
if (modifier == Qt::ControlModifier)
{
char Msg[] = "\0\r";
if (key == Qt::Key_BracketLeft)
Msg[0] = 0x1b;
if (key == Qt::Key_Z)
Msg[0] = 0x1a;
else if (key == Qt::Key_C)
Msg[0] = 3;
else if (key == Qt::Key_D)
Msg[0] = 4;
else if (key == Qt::Key_G)
{
// Append BELL char to input line
QByteArray stringData = Sess->inputWindow->text().toUtf8();
stringData.append(7);
Sess->inputWindow->setText(stringData);
}
if (Msg[0])
{
if (Sess->KISSSession)
{
// Send to ax.25 code
SendtoAX25(Sess->KISSSession, (unsigned char *)Msg, (int)strlen(Msg));
}
else if (Sess->AGWSession)
{
// Terminal is in AGWPE mode - send as AGW frame
AGW_AX25_data_in(Sess->AGWSession, (unsigned char *)Msg, (int)strlen(Msg));
}
else if (Sess->clientSocket && Sess->clientSocket->state() == QAbstractSocket::ConnectedState)
{
Sess->clientSocket->write(Msg);
}
return true;
}
}
if (key == Qt::Key_Up)
{
// Scroll up
if (Sess->KbdStack[Sess->StackIndex] == NULL)
return true;
// If anything typed, stack part command
QByteArray stringData = Sess->inputWindow->text().toUtf8();
if (stringData.length() && Sess->StackIndex == 0)
{
if (Sess->KbdStack[49])
free(Sess->KbdStack[49]);
for (int i = 48; i >= 0; i--)
{
Sess->KbdStack[i + 1] = Sess->KbdStack[i];
}
Sess->KbdStack[0] = qstrdup(stringData.data());
Sess->StackIndex++;
}
Sess->inputWindow->setText(Sess->KbdStack[Sess->StackIndex]);
Sess->inputWindow->cursorForward(strlen(Sess->KbdStack[Sess->StackIndex]));
Sess->StackIndex++;
if (Sess->StackIndex == 50)
Sess->StackIndex = 49;
return true;
}
else if (key == Qt::Key_Down)
{
// Scroll down
if (Sess->StackIndex == 0)
{
Sess->inputWindow->setText("");
return true;
}
Sess->StackIndex--;
if (Sess->StackIndex && Sess->KbdStack[Sess->StackIndex - 1])
{
Sess->inputWindow->setText(Sess->KbdStack[Sess->StackIndex - 1]);
Sess->inputWindow->cursorForward(strlen(Sess->KbdStack[Sess->StackIndex - 1]));
}
else
Sess->inputWindow->setText("");
return true;
}
else if (key == Qt::Key_Return || key == Qt::Key_Enter)
{
LreturnPressed(Sess);
return true;
}
return false;
}
if (event->type() == QEvent::MouseButtonPress)
{
QMouseEvent *k = static_cast<QMouseEvent *> (event);
// Paste on Right Click
if (k->button() == Qt::RightButton)
{
// Get clipboard data and process a line at a time
QClipboard *clipboard = QGuiApplication::clipboard();
QString Text = clipboard->text();
QByteArray ba = Text.toLocal8Bit();
Sess->inputWindow->paste();
return true;
}
return QMainWindow::eventFilter(obj, event);
}
}
}
return QMainWindow::eventFilter(obj, event);
}
QAction * setupMenuLine(QMenu * Menu, char * Label, QObject * parent, int State)
{
QAction * Act = new QAction(Label, parent);
if (Menu)
Menu->addAction(Act);
Act->setCheckable(true);
if (State)
Act->setChecked(true);
parent->connect(Act, SIGNAL(triggered()), parent, SLOT(menuChecked()));
Act->setFont(*menufont);
return Act;
}
// This now creates all window types - Term, Mon, Combined, Listen
int xCount = 0;
int sessNo = 0;
Ui_ListenSession * newWindow(QObject * parent, int Type, const char * Label)
{
Ui_ListenSession * Sess = new(Ui_ListenSession);
// Need to explicity initialise on Qt4
Sess->termWindow = NULL;
Sess->monWindow = NULL;
Sess->inputWindow = NULL;