From 2e2f717d19dfb3cd00c2181a97524a5a1476103f Mon Sep 17 00:00:00 2001
From: John Wiseman <john.wiseman@cantab.net>
Date: Wed, 27 Sep 2023 09:27:12 +0100
Subject: [PATCH] 0.0.0.68

---
 Config.cpp                |  14 +-
 ModemDialog.ui            |  52 ++++--
 QtSoundModem.cpp          | 342 ++++++++++++++++++++++++++++----------
 QtSoundModem.h            |  11 +-
 QtSoundModem.ui           |  60 +++++--
 QtSoundModem.vcxproj.user |   8 +-
 SMMain.c                  |  11 +-
 UZ7HOStuff.h              |  11 +-
 Waveout.c                 |   6 +-
 debug/QtSoundModem.ini    |  10 +-
 devicesDialog.ui          |   3 +
 il2p.c                    |   4 +-
 release/moc_predefs.h     |  11 --
 sm_main.c                 |   2 +-
 tcpCode.h                 |   2 +
 15 files changed, 404 insertions(+), 143 deletions(-)
 delete mode 100644 release/moc_predefs.h

diff --git a/Config.cpp b/Config.cpp
index bb5ebd8..ad03176 100644
--- a/Config.cpp
+++ b/Config.cpp
@@ -52,12 +52,15 @@ extern "C" char CWIDMark[32];
 extern int CWIDInterval;
 extern int CWIDLeft;
 extern int CWIDRight;
-extern int CWIDType;	
+extern int CWIDType;
+extern bool afterTraffic;
 
 extern "C" int RSID_SABM[4];
 extern "C" int RSID_UI[4];
 extern "C" int RSID_SetModem[4];
 
+extern QFont Font;
+
 
 QSettings* settings = new QSettings("QtSoundModem.ini", QSettings::IniFormat);
 
@@ -236,7 +239,7 @@ void getSettings()
 	CWIDLeft = settings->value("Modem/CWIDLeft", 0).toInt();
 	CWIDRight = settings->value("Modem/CWIDRight", 0).toInt();
 	CWIDType = settings->value("Modem/CWIDType", 1).toInt();			// on/off
-
+	afterTraffic = settings->value("Modem/afterTraffic", false).toBool();
 
 	getAX25Params(0);
 	getAX25Params(1);
@@ -353,6 +356,10 @@ void saveSettings()
 {
 	QSettings * settings = new QSettings("QtSoundModem.ini", QSettings::IniFormat);
 
+	settings->setValue("FontFamily", Font.family());
+	settings->setValue("PointSize", Font.pointSize());
+	settings->setValue("Weight", Font.weight());
+
 	settings->setValue("PSKWindow", constellationDialog->geometry());
 	settings->setValue("Init/SoundMode", SoundMode);
 	settings->setValue("Init/UDPClientPort", UDPClientPort);
@@ -453,7 +460,8 @@ void saveSettings()
 	settings->setValue("Modem/CWIDInterval", CWIDInterval);
 	settings->setValue("Modem/CWIDLeft", CWIDLeft);
 	settings->setValue("Modem/CWIDRight", CWIDRight);
-	settings->setValue("Modem/CWIDType", CWIDType);			
+	settings->setValue("Modem/CWIDType", CWIDType);
+	settings->setValue("Modem/afterTraffic", afterTraffic);
 
 	saveAX25Params(0);
 	saveAX25Params(1);
diff --git a/ModemDialog.ui b/ModemDialog.ui
index fa91460..e8f7903 100644
--- a/ModemDialog.ui
+++ b/ModemDialog.ui
@@ -3055,7 +3055,7 @@
   <widget class="QLabel" name="label_7">
    <property name="geometry">
     <rect>
-     <x>44</x>
+     <x>12</x>
      <y>516</y>
      <width>71</width>
      <height>20</height>
@@ -3068,9 +3068,9 @@
   <widget class="QLineEdit" name="CWIDCall">
    <property name="geometry">
     <rect>
-     <x>114</x>
+     <x>78</x>
      <y>516</y>
-     <width>51</width>
+     <width>71</width>
      <height>20</height>
     </rect>
    </property>
@@ -3081,12 +3081,15 @@
   <widget class="QRadioButton" name="CWIDType">
    <property name="geometry">
     <rect>
-     <x>410</x>
+     <x>340</x>
      <y>516</y>
      <width>61</width>
      <height>20</height>
     </rect>
    </property>
+   <property name="layoutDirection">
+    <enum>Qt::RightToLeft</enum>
+   </property>
    <property name="text">
     <string>FSK</string>
    </property>
@@ -3094,12 +3097,20 @@
   <widget class="QRadioButton" name="radioButton_2">
    <property name="geometry">
     <rect>
-     <x>460</x>
+     <x>396</x>
      <y>516</y>
      <width>101</width>
      <height>20</height>
     </rect>
    </property>
+   <property name="font">
+    <font>
+     <family>MS Shell Dlg 2</family>
+    </font>
+   </property>
+   <property name="layoutDirection">
+    <enum>Qt::RightToLeft</enum>
+   </property>
    <property name="text">
     <string>Tone On/Off</string>
    </property>
@@ -3107,7 +3118,7 @@
   <widget class="QLabel" name="label_66">
    <property name="geometry">
     <rect>
-     <x>190</x>
+     <x>158</x>
      <y>516</y>
      <width>61</width>
      <height>20</height>
@@ -3120,7 +3131,7 @@
   <widget class="QLineEdit" name="CWIDInterval">
    <property name="geometry">
     <rect>
-     <x>240</x>
+     <x>208</x>
      <y>516</y>
      <width>31</width>
      <height>20</height>
@@ -3130,7 +3141,7 @@
   <widget class="QLabel" name="label_91">
    <property name="geometry">
     <rect>
-     <x>294</x>
+     <x>248</x>
      <y>516</y>
      <width>61</width>
      <height>20</height>
@@ -3143,9 +3154,9 @@
   <widget class="QLineEdit" name="CWIDMark">
    <property name="geometry">
     <rect>
-     <x>348</x>
+     <x>318</x>
      <y>516</y>
-     <width>41</width>
+     <width>31</width>
      <height>20</height>
     </rect>
    </property>
@@ -3156,6 +3167,27 @@
     <string/>
    </property>
   </widget>
+  <widget class="QCheckBox" name="afterTraffic">
+   <property name="geometry">
+    <rect>
+     <x>500</x>
+     <y>516</y>
+     <width>91</width>
+     <height>20</height>
+    </rect>
+   </property>
+   <property name="font">
+    <font>
+     <family>MS Shell Dlg 2</family>
+    </font>
+   </property>
+   <property name="layoutDirection">
+    <enum>Qt::RightToLeft</enum>
+   </property>
+   <property name="text">
+    <string>After Traffic</string>
+   </property>
+  </widget>
  </widget>
  <resources/>
  <connections/>
diff --git a/QtSoundModem.cpp b/QtSoundModem.cpp
index fdf137f..cadb3fb 100644
--- a/QtSoundModem.cpp
+++ b/QtSoundModem.cpp
@@ -46,7 +46,7 @@ along with QtSoundModem.  If not, see http://www.gnu.org/licenses
 #include <qevent.h>
 #include <QStandardItemModel>
 #include <QScrollBar>
-
+#include <QFontDialog>
 #include "UZ7HOStuff.h"
 
 
@@ -61,11 +61,13 @@ QImage *RXLevel;
 
 QLabel *WaterfallCopy[2];
 QLabel *HeaderCopy[2];
+QLabel * RXLevelCopy;
 
 QTextEdit * monWindowCopy;
 
 extern workerThread *t;
 extern QtSoundModem * w;
+extern QCoreApplication * a;
 
 QList<QSerialPortInfo> Ports = QSerialPortInfo::availablePorts();
 
@@ -148,6 +150,8 @@ int CWIDInterval = 0;
 int CWIDLeft = 0;
 int CWIDRight = 0;
 int CWIDType = 1;			// on/off
+bool afterTraffic = 0;
+bool cwidtimerisActive = false;
 
 int WaterfallMin = 00;
 int WaterfallMax = 6000;
@@ -205,6 +209,8 @@ extern "C" int TXPort;
 extern char UDPHost[64];
 
 QTimer *cwidtimer;
+QWidget * mythis;
+
 
 QSystemTrayIcon * trayIcon = nullptr;
 
@@ -379,22 +385,22 @@ void QtSoundModem::resizeEvent(QResizeEvent* event)
 
 	if (UsingBothChannels)
 	{
-		ui.HeaderA->setGeometry(QRect(0, A, W, 35));
-		ui.WaterfallA->setGeometry(QRect(0, A + 35, W, 80));
-		ui.HeaderB->setGeometry(QRect(0, B, W, 35));
-		ui.WaterfallB->setGeometry(QRect(0, B + 35, W, 80));
+		ui.HeaderA->setGeometry(QRect(0, A, W, 38));
+		ui.WaterfallA->setGeometry(QRect(0, A + 38, W, 80));
+		ui.HeaderB->setGeometry(QRect(0, B, W, 38));
+		ui.WaterfallB->setGeometry(QRect(0, B + 38, W, 80));
 	}
 	else
 	{
 		if (soundChannel[0] == RIGHT)
 		{
-			ui.HeaderB->setGeometry(QRect(0, A, W, 35));
-			ui.WaterfallB->setGeometry(QRect(0, A + 35, W, 80));
+			ui.HeaderB->setGeometry(QRect(0, A, W, 38));
+			ui.WaterfallB->setGeometry(QRect(0, A + 38, W, 80));
 		}
 		else
 		{
-			ui.HeaderA->setGeometry(QRect(0, A, W, 35));
-			ui.WaterfallA->setGeometry(QRect(0, A + 35, W, 80));
+			ui.HeaderA->setGeometry(QRect(0, A, W, 38));
+			ui.WaterfallA->setGeometry(QRect(0, A + 38, W, 80));
 		}
 	}
 }
@@ -456,7 +462,6 @@ void QtSoundModem::initWaterfall(int chan, int state)
 		}
 		Waterfall[chan] = new QImage(1024, 80, QImage::Format_RGB32);
 		Waterfall[chan]->fill(black);
-
 	}
 	else
 	{
@@ -480,6 +485,8 @@ QLabel * QualLabel[4];
 QLabel *RXOffsetLabel;
 QSlider *RXOffset;
 
+QFont Font;
+
 extern "C" void CheckPSKWindows()
 {
 	NeedPSKRefresh = 1;
@@ -515,10 +522,26 @@ void DoPSKWindows()
 
 QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent)
 {
+	QString family;
+	int csize;
+	QFont::Weight weight;
+
 	ui.setupUi(this);
- 
+
+	mythis = this;
+
 	QSettings mysettings("QtSoundModem.ini", QSettings::IniFormat);
 
+	family = mysettings.value("FontFamily", "Courier New").toString();
+	csize = mysettings.value("PointSize", 0).toInt();
+	weight = (QFont::Weight)mysettings.value("Weight", 50).toInt();
+
+	Font = QFont(family);
+	Font.setPointSize(csize);
+	Font.setWeight(weight);
+
+	QApplication::setFont(Font);
+
 	constellationDialog = new QDialog(nullptr, Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
 	constellationDialog->resize(488, 140);
 	constellationDialog->setGeometry(PSKRect);
@@ -625,6 +648,12 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent)
 
 	connect(actModems, SIGNAL(triggered()), this, SLOT(clickedSlot()));
 
+	actFont = new QAction("Setup Font", this);
+	actFont->setObjectName("actFont");
+	setupMenu->addAction(actFont);
+
+	connect(actFont, SIGNAL(triggered()), this, SLOT(clickedSlot()));
+
 	actMintoTray = setupMenu->addAction("Minimize to Tray", this, SLOT(MinimizetoTray()));
 	actMintoTray->setCheckable(1);
 	actMintoTray->setChecked(MintoTray);
@@ -643,11 +672,13 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent)
 	actAbout = ui.menuBar->addAction("&About");
 	connect(actAbout, SIGNAL(triggered()), this, SLOT(doAbout()));
 
-	//	Constellation = new QImage(91, 91, QImage::Format_RGB32);
-
-	Header[0] = new QImage(1024, 35, QImage::Format_RGB32);
-	Header[1] = new QImage(1024, 35, QImage::Format_RGB32);
+	Header[0] = new QImage(1024, 38, QImage::Format_RGB32);
+	Header[1] = new QImage(1024, 38, QImage::Format_RGB32);
 	RXLevel = new QImage(150, 10, QImage::Format_RGB32);
+	RXLevel->fill(white);
+	ui.RXLevel->setPixmap(QPixmap::fromImage(*RXLevel));
+	RXLevelCopy = ui.RXLevel;
+
 
 	DCDLabel[0] = new QLabel(this);
 	DCDLabel[0]->setObjectName(QString::fromUtf8("DCDLedA"));
@@ -725,9 +756,6 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent)
 	wf_Scale(0);
 	wf_Scale(1);
 
-	//	RefreshLevel(0);
-	//	RXLevel->setPixmap(QPixmap::fromImage(*RXLevel));
-
 	connect(ui.modeA, SIGNAL(currentIndexChanged(int)), this, SLOT(clickedSlotI(int)));
 	connect(ui.modeB, SIGNAL(currentIndexChanged(int)), this, SLOT(clickedSlotI(int)));
 	connect(ui.modeC, SIGNAL(currentIndexChanged(int)), this, SLOT(clickedSlotI(int)));
@@ -769,10 +797,11 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent)
 	connect(ui.DCDSlider, SIGNAL(sliderMoved(int)), this, SLOT(clickedSlotI(int)));
 	connect(ui.RXOffset, SIGNAL(valueChanged(int)), this, SLOT(clickedSlotI(int)));
 
-
 	QObject::connect(t, SIGNAL(sendtoTrace(char *, int)), this, SLOT(sendtoTrace(char *, int)), Qt::QueuedConnection);
 	QObject::connect(t, SIGNAL(updateDCD(int, int)), this, SLOT(doupdateDCD(int, int)), Qt::QueuedConnection);
 
+	QObject::connect(t, SIGNAL(startCWIDTimer()), this, SLOT(startCWIDTimerSlot()), Qt::QueuedConnection);
+
 	connect(ui.RXOffsetA, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
 	connect(ui.RXOffsetB, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
 	connect(ui.RXOffsetC, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
@@ -786,11 +815,11 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent)
 	connect(wftimer, SIGNAL(timeout()), this, SLOT(doRestartWF()));
 	wftimer->start(1000 * 300);
 
-	
 	cwidtimer = new QTimer(this);
 	connect(cwidtimer, SIGNAL(timeout()), this, SLOT(CWIDTimer()));
 
-	if (CWIDInterval)
+
+	if (CWIDInterval && afterTraffic == false)
 		cwidtimer->start(CWIDInterval * 60000);
 
 	if (RSID_SetModem[0])
@@ -798,7 +827,15 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent)
 		RSID_WF = 1;
 		RSIDinitfft();
 	}
-	il2p_init(1);
+//	il2p_init(1);
+
+	QTimer::singleShot(200, this, &QtSoundModem::updateFont);
+
+}
+
+void QtSoundModem::updateFont()
+{
+	QApplication::setFont(Font);
 }
 
 void QtSoundModem::MinimizetoTray()
@@ -821,8 +858,23 @@ void QtSoundModem::TrayActivated(QSystemTrayIcon::ActivationReason reason)
 
 extern "C" void sendCWID(char * strID, BOOL blnPlay, int Chan);
 
+extern "C" void checkforCWID()
+{
+	emit(t->startCWIDTimer());
+};
+
+extern "C" void QtSoundModem::startCWIDTimerSlot()
+{
+	if (CWIDInterval && afterTraffic == 1 && cwidtimerisActive == false)
+	{
+		cwidtimerisActive = true;
+		QTimer::singleShot(CWIDInterval * 60000, this, &QtSoundModem::CWIDTimer);
+	}
+}
+
 void QtSoundModem::CWIDTimer()
 {
+	cwidtimerisActive = false;
 	sendCWID(CWIDCall, CWIDType, 0);
 	calib_mode[0] = 4;
 }
@@ -1061,7 +1113,6 @@ void QtSoundModem::clickedSlotI(int i)
 		return;
 	}
 
-
 	QMessageBox msgBox;
 	msgBox.setWindowTitle("MessageBox Title");
 	msgBox.setText("You Clicked " + ((QPushButton*)sender())->objectName());
@@ -1221,6 +1272,27 @@ void QtSoundModem::clickedSlot()
 		return;
 	}
 
+	if (strcmp(Name, "actFont") == 0)
+	{
+		bool ok;
+		Font = QFontDialog::getFont(&ok, QFont(Font, this));
+		if (ok)
+		{
+			// the user clicked OK and font is set to the font the user selected
+			QApplication::setFont(Font);
+			saveSettings();
+		}
+		else
+		{
+			// the user canceled the dialog; font is set to the initial
+			// value, in this case Helvetica [Cronyx], 10
+
+			QApplication::setFont(Font);
+
+		}
+		return;
+	}
+
 	QMessageBox msgBox;
 	msgBox.setWindowTitle("MessageBox Title");
 	msgBox.setText("You Clicked " + ((QPushButton*)sender())->objectName());
@@ -1417,6 +1489,8 @@ void QtSoundModem::doModems()
 	else
 		Dlg->CWIDType->setChecked(1);
 
+	Dlg->afterTraffic->setChecked(afterTraffic);
+
 	Dlg->RSIDSABM_A->setChecked(RSID_SABM[0]);
 	Dlg->RSIDSABM_B->setChecked(RSID_SABM[1]);
 	Dlg->RSIDSABM_C->setChecked(RSID_SABM[2]);
@@ -1635,7 +1709,9 @@ void QtSoundModem::modemSave()
 	CWIDInterval = Dlg->CWIDInterval->text().toInt();
 	CWIDType = Dlg->radioButton_2->isChecked();
 
-	if (CWIDInterval)
+	afterTraffic = Dlg->afterTraffic->isChecked();
+
+	if (CWIDInterval && afterTraffic == false)
 		cwidtimer->start(CWIDInterval * 60000);
 	else
 		cwidtimer->stop();
@@ -1677,6 +1753,19 @@ void QtSoundModem::modemSave()
 		get_exclude_list(MyDigiCall[i], &list_digi_callsigns[i]);
 	}
 
+/*
+	Q = Dlg->LPFWidthA->text();
+	lpf[0] = Q.toInt();
+
+	Q = Dlg->LPFWidthB->text();
+	lpf[1] = Q.toInt();
+
+	Q = Dlg->LPFWidthC->text();
+	lpf[2] = Q.toInt();
+
+	Q = Dlg->LPFWidthD->text();
+	lpf[3] = Q.toInt();
+*/
 }
 
 void QtSoundModem::modemreject()
@@ -2030,7 +2119,19 @@ void QtSoundModem::doDevices()
 		Dev->PTTPort->addItem(info);
 	}
 
-	Dev->PTTPort->setCurrentIndex(Dev->PTTPort->findText(PTTPort, Qt::MatchFixedString));
+	// If we are using a user specifed device add it
+
+	i = Dev->PTTPort->findText(PTTPort, Qt::MatchFixedString);
+
+	if (i == -1)
+	{
+		// Add our device to list
+
+		Dev->PTTPort->insertItem(0, PTTPort);
+		i = Dev->PTTPort->findText(PTTPort, Qt::MatchContains);
+	}
+
+	Dev->PTTPort->setCurrentIndex(i);
 
 	PTTPortChanged(0);				// Force reevaluation
 
@@ -2163,7 +2264,13 @@ void QtSoundModem::deviceaccept()
 	AGWPort = Q.toInt();
 
 	Q = Dev->PTTPort->currentText();
-	strcpy(PTTPort, Q.toString().toUtf8());
+	
+	char temp[256];
+
+	strcpy(temp, Q.toString().toUtf8());
+
+	if (strlen(temp))
+		strcpy(PTTPort, temp);
 
 	DualPTT = Dev->DualPTT->isChecked();
 	TX_rotate = Dev->txRotation->isChecked();
@@ -2312,6 +2419,20 @@ void QtSoundModem::doRestartWF()
 		initWaterfall(1, 0);
 		initWaterfall(1, 1);
 	}
+
+	delete(RXLevel);
+	delete(ui.RXLevel);
+	ui.RXLevel = new QLabel(ui.centralWidget);
+	RXLevelCopy = ui.RXLevel;
+	ui.RXLevel->setGeometry(QRect(780, 17, 150, 12));
+//	ui.RXLevel->setFrameShape(QFrame::Box);
+//	ui.RXLevel->setFrameShadow(QFrame::Sunken);
+
+	RXLevel = new QImage(150, 10, QImage::Format_RGB32);
+	RXLevel->fill(cyan);
+//	ui.RXLevel->setPixmap(QPixmap::fromImage(*RXLevel));
+
+	ui.RXLevel->setVisible(1);
 }
 
 
@@ -2399,6 +2520,34 @@ void QtSoundModem::RefreshSpectrum(unsigned char * Data)
 
 }
 
+void RefreshLevel(unsigned int Level)
+{
+	// Redraw the RX Level Bar Graph
+
+	unsigned int  x, y;
+
+	for (x = 0; x < 150; x++)
+	{
+		for (y = 0; y < 10; y++)
+		{
+			if (x < Level)
+			{
+				if (Level < 50)
+					RXLevel->setPixel(x, y, yellow);
+				else if (Level > 135)
+					RXLevel->setPixel(x, y, red);
+				else
+					RXLevel->setPixel(x, y, green);
+			}
+			else
+				RXLevel->setPixel(x, y, white);
+		}
+	}
+	RXLevelCopy->setPixmap(QPixmap::fromImage(*RXLevel));
+}
+
+extern "C" unsigned char CurrentLevel;
+
 void QtSoundModem::RefreshWaterfall(int snd_ch, unsigned char * Data)
 {
 	int j;
@@ -2584,7 +2733,7 @@ void do_pointer(int waterfall)
 	// We drew markers every 100 Hz or 100 / binsize pixels
 
 	float PixelsPerHz = 1.0 / BinSize;
-	k = 28;
+	k = 26;
 
 	// draw all enabled ports on the ports on this soundcard
 
@@ -2632,6 +2781,8 @@ void do_pointer(int waterfall)
 			qPainter.drawLine(pos3, k - 3, pos3, k + 3);
 			qPainter.drawLine(pos3 - 2, k - 3, pos3 + 2, k - 3);
 		}
+
+		k += 3;
 	}
 	HeaderCopy[waterfall]->setPixmap(QPixmap::fromImage(*bm));
 }
@@ -2696,6 +2847,10 @@ extern "C" void SMUpdateBusyDetector(int LR, float * Real, float *Imag);
 void doWaterfallThread(void * param)
 {
 	int snd_ch = (int)(size_t)param;
+	int WaterfallNumber = snd_ch;
+
+	if (snd_ch == 1 && UsingLeft == 0)	// Only using right
+		snd_ch = 0;						// Samples are in first buffer
 
 	QImage * bm = Waterfall[snd_ch];
 	
@@ -2713,6 +2868,7 @@ void doWaterfallThread(void * param)
 	if (Configuring)
 		return;
 
+
 	hFFTSize = FFTSize / 2;
 
 
@@ -2794,56 +2950,67 @@ void doWaterfallThread(void * param)
 
 	SMUpdateBusyDetector(snd_ch, RealOut, ImagOut);
 
+	RefreshLevel(CurrentLevel);	// Signal Level
+
 	if (bm == 0)
 		return;
 
-	p = Line;
-	lineLen = bm->bytesPerLine();
-
-	if (raduga == DISP_MONO)
+	try
 	{
-		for (i = Start; i < End; i++)
+
+		p = Line;
+		lineLen = bm->bytesPerLine();
+
+		if (raduga == DISP_MONO)
 		{
-			n = fft_disp[snd_ch][i];
-			*(p++) = n;					// all colours the same
-			*(p++) = n;
-			*(p++) = n;
-			p++;
+			for (i = Start; i < End; i++)
+			{
+				n = fft_disp[snd_ch][i];
+				*(p++) = n;					// all colours the same
+				*(p++) = n;
+				*(p++) = n;
+				p++;
+			}
 		}
-	}
-	else
-	{
-		for (i = Start; i < End; i++)
+		else
 		{
-			n = fft_disp[snd_ch][i];
-			memcpy(p, &RGBWF[n], 4);
-			p += 4;
+			for (i = Start; i < End; i++)
+			{
+				n = fft_disp[snd_ch][i];
+				memcpy(p, &RGBWF[n], 4);
+				p += 4;
+			}
 		}
+
+		// Scroll
+
+		int TopLine = NextWaterfallLine[snd_ch];
+
+		// Write line to cyclic buffer then draw starting with the line just written
+
+		memcpy(&WaterfallLines[snd_ch][NextWaterfallLine[snd_ch]++][0], Line, 4096);
+		if (NextWaterfallLine[snd_ch] > 79)
+			NextWaterfallLine[snd_ch] = 0;
+
+		for (int j = 79; j > 0; j--)
+		{
+			p = bm->scanLine(j);
+			memcpy(p, &WaterfallLines[snd_ch][TopLine][0], lineLen);
+			TopLine++;
+			if (TopLine > 79)
+				TopLine = 0;
+		}
+
+		WaterfallCopy[WaterfallNumber]->setPixmap(QPixmap::fromImage(*bm));
+		//	WaterfallCopy[snd_ch - 1]->setPixmap(*pm);
+			//	WaterfallCopy[1]->setPixmap(QPixmap::fromImage(*bm));
 	}
-
-	// Scroll
-
-	int TopLine = NextWaterfallLine[snd_ch];
-
-	// Write line to cyclic buffer then draw starting with the line just written
-
-	memcpy(&WaterfallLines[snd_ch][NextWaterfallLine[snd_ch]++][0], Line, 4096);
-	if (NextWaterfallLine[snd_ch] > 79)
-		NextWaterfallLine[snd_ch] = 0;
-
-	for (int j = 79; j > 0; j--)
+	catch (const std::exception& e) // caught by reference to base
 	{
-		p = bm->scanLine(j);
-		memcpy(p, &WaterfallLines[snd_ch][TopLine][0], lineLen);
-		TopLine++;
-		if (TopLine > 79)
-			TopLine = 0;
+		qDebug() << " a standard exception was caught, with message '"
+			<< e.what() << "'\n";
 	}
 
-	WaterfallCopy[snd_ch]->setPixmap(QPixmap::fromImage(*bm));
-	//	WaterfallCopy[snd_ch - 1]->setPixmap(*pm);
-		//	WaterfallCopy[1]->setPixmap(QPixmap::fromImage(*bm));
-
 }
 
 
@@ -3078,17 +3245,19 @@ extern "C" int SMUpdatePhaseConstellation(int chan, float * Phases, float * Mags
 	int yCenter = (ConstellationHeight - 2) / 2;
 	int xCenter = (ConstellationWidth - 2) / 2;
 
-	Constellation[chan]->fill(black);
-
-	for (i = 0; i < 120; i++)
-	{
-		Constellation[chan]->setPixel(xCenter, i, cyan);
-		Constellation[chan]->setPixel(i, xCenter, cyan);
-	}
-
 	if (Count == 0)
 		return 0;
 
+	if (nonGUIMode == 0)
+	{
+		Constellation[chan]->fill(black);
+
+		for (i = 0; i < 120; i++)
+		{
+			Constellation[chan]->setPixel(xCenter, i, cyan);
+			Constellation[chan]->setPixel(i, xCenter, cyan);
+		}
+	}
 	dbPhaseStep = 2 * M_PI / intPSKPhase;
 
 	for (i = 1; i < Count; i++)  // Don't plot the first phase (reference)
@@ -3099,7 +3268,7 @@ extern "C" int SMUpdatePhaseConstellation(int chan, float * Phases, float * Mags
 
 	dblAvgRad = dblAvgRad / Count; // the average radius
 
-	for (i = 0; i < Count; i++) 
+	for (i = 0; i < Count; i++)
 	{
 		dblRad = PLOTRADIUS * Mags[i] / MagMax; //  scale the radius dblRad based on intMag
 		intP = round((Phases[i]) / dbPhaseStep);
@@ -3109,23 +3278,28 @@ extern "C" int SMUpdatePhaseConstellation(int chan, float * Phases, float * Mags
 		dblPhaseError = fabsf(Phases[i] - intP * dbPhaseStep); // always positive and < .5 *  dblPhaseStep
 		dblPhaseErrorSum += dblPhaseError;
 
-		intX = xCenter + dblRad * cosf(dblPlotRotation + Phases[i]);
-		intY = yCenter + dblRad * sinf(dblPlotRotation + Phases[i]);
+		if (nonGUIMode == 0)
+		{
+			intX = xCenter + dblRad * cosf(dblPlotRotation + Phases[i]);
+			intY = yCenter + dblRad * sinf(dblPlotRotation + Phases[i]);
 
-		if (intX > 0 && intY > 0)
-			if (intX != xCenter && intY != yCenter)
-				Constellation[chan]->setPixel(intX, intY, yellow);
+			if (intX > 0 && intY > 0)
+				if (intX != xCenter && intY != yCenter)
+					Constellation[chan]->setPixel(intX, intY, yellow);
+		}
 	}
 
 	dblAvgRad = dblAvgRad / Count; // the average radius
 
 	intQuality = MAX(0, ((100 - 200 * (dblPhaseErrorSum / (Count)) / dbPhaseStep))); // ignore radius error for (PSK) but include for QAM
 
-	char QualText[64];
-	sprintf(QualText, "Chan %c Qual = %d", chan + 'A', intQuality);
-	QualLabel[chan]->setText(QualText);
-	constellationLabel[chan]->setPixmap(QPixmap::fromImage(*Constellation[chan]));
-//	constellationDialog[chan]->setWindowTitle(QualText);
+	if (nonGUIMode == 0)
+	{
+		char QualText[64];
+		sprintf(QualText, "Chan %c Qual = %d", chan + 'A', intQuality);
+		QualLabel[chan]->setText(QualText);
+		constellationLabel[chan]->setPixmap(QPixmap::fromImage(*Constellation[chan]));
+	}
 	return intQuality;
 }
 
diff --git a/QtSoundModem.h b/QtSoundModem.h
index 869ae25..fc21d79 100644
--- a/QtSoundModem.h
+++ b/QtSoundModem.h
@@ -31,13 +31,17 @@ public:
 	void RefreshWaterfall(int snd_ch, unsigned char * Data);
 	void initWaterfall(int chan, int state);
 	void show_grid();
+	void checkforCWID();
+
+public slots:
 
 private slots:
 
+	void CWIDTimer();
 	void doDevices();
+	void updateFont();
 	void MinimizetoTray();
 	void TrayActivated(QSystemTrayIcon::ActivationReason reason);
-	void CWIDTimer();
 	void MyTimerSlot();
 	void returnPressed();
 	void clickedSlotI(int i);
@@ -58,6 +62,7 @@ private slots:
 	void doRSIDD();
 	void handleButton(int Port, int Act);
 	void doCalibrate();
+	void RefreshSpectrum(unsigned char * Data);
 	void doAbout();
 	void doRestartWF();
 	void doupdateDCD(int, int);
@@ -69,6 +74,7 @@ private slots:
 	void menuChecked();
 	void onTEselectionChanged();
 	void clickedSlot();
+	void startCWIDTimerSlot();
 
 protected:
 	 
@@ -85,6 +91,7 @@ private:
 
 	QAction *actDevices;
 	QAction *actModems;
+	QAction *actFont;
 	QAction *actMintoTray;
 	QAction *actCalib;
 	QAction *actAbout;
@@ -92,8 +99,8 @@ private:
 	QAction *actWaterfall1;
 	QAction *actWaterfall2;
 
+signals:
 
-	void RefreshSpectrum(unsigned char * Data);
 };
 
 class myResize : public QObject
diff --git a/QtSoundModem.ui b/QtSoundModem.ui
index ef72635..e264b7d 100644
--- a/QtSoundModem.ui
+++ b/QtSoundModem.ui
@@ -215,26 +215,13 @@
      <number>10</number>
     </property>
    </widget>
-   <widget class="QCheckBox" name="holdPointers">
-    <property name="geometry">
-     <rect>
-      <x>782</x>
-      <y>6</y>
-      <width>93</width>
-      <height>22</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Hold Pointers</string>
-    </property>
-   </widget>
    <widget class="QLabel" name="HeaderA">
     <property name="geometry">
      <rect>
       <x>25</x>
       <y>460</y>
       <width>1076</width>
-      <height>30</height>
+      <height>38</height>
      </rect>
     </property>
     <property name="minimumSize">
@@ -270,7 +257,7 @@
       <x>10</x>
       <y>560</y>
       <width>1076</width>
-      <height>30</height>
+      <height>38</height>
      </rect>
     </property>
     <property name="minimumSize">
@@ -496,6 +483,49 @@
      <set>Qt::AlignCenter</set>
     </property>
    </widget>
+   <widget class="QLabel" name="RXLevel">
+    <property name="geometry">
+     <rect>
+      <x>780</x>
+      <y>17</y>
+      <width>150</width>
+      <height>12</height>
+     </rect>
+    </property>
+    <property name="frameShape">
+     <enum>QFrame::Box</enum>
+    </property>
+    <property name="frameShadow">
+     <enum>QFrame::Sunken</enum>
+    </property>
+    <property name="text">
+     <string/>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_7">
+    <property name="geometry">
+     <rect>
+      <x>780</x>
+      <y>0</y>
+      <width>91</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="font">
+     <font>
+      <pointsize>8</pointsize>
+     </font>
+    </property>
+    <property name="text">
+     <string>Rcv Level:</string>
+    </property>
+    <property name="textFormat">
+     <enum>Qt::PlainText</enum>
+    </property>
+    <property name="wordWrap">
+     <bool>true</bool>
+    </property>
+   </widget>
   </widget>
   <widget class="QMenuBar" name="menuBar">
    <property name="geometry">
diff --git a/QtSoundModem.vcxproj.user b/QtSoundModem.vcxproj.user
index b2b9590..65f157d 100644
--- a/QtSoundModem.vcxproj.user
+++ b/QtSoundModem.vcxproj.user
@@ -20,15 +20,15 @@
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
   </PropertyGroup>
   <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <QtLastBackgroundBuild>2023-08-31T18:31:29.1703485Z</QtLastBackgroundBuild>
+    <QtLastBackgroundBuild>2023-09-26T11:58:59.9128543Z</QtLastBackgroundBuild>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="QtSettings">
-    <QtLastBackgroundBuild>2023-08-31T18:31:29.3763536Z</QtLastBackgroundBuild>
+    <QtLastBackgroundBuild>2023-09-26T11:59:00.0378577Z</QtLastBackgroundBuild>
   </PropertyGroup>
   <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <QtLastBackgroundBuild>2023-08-31T18:31:30.2753833Z</QtLastBackgroundBuild>
+    <QtLastBackgroundBuild>2023-09-26T11:59:00.1388610Z</QtLastBackgroundBuild>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="QtSettings">
-    <QtLastBackgroundBuild>2023-08-31T18:31:32.1264353Z</QtLastBackgroundBuild>
+    <QtLastBackgroundBuild>2023-09-26T11:59:00.2228656Z</QtLastBackgroundBuild>
   </PropertyGroup>
 </Project>
\ No newline at end of file
diff --git a/SMMain.c b/SMMain.c
index 3c87359..141947b 100644
--- a/SMMain.c
+++ b/SMMain.c
@@ -54,6 +54,7 @@ unsigned short * SendtoCard(unsigned short * buf, int n);
 short * SoundInit();
 void DoTX(int Chan);
 void UDPPollReceivedSamples();
+extern void checkforCWID();
 
 
 extern int SampleNo;
@@ -139,6 +140,8 @@ void soundMain()
 	init_raduga();			// Set up waterfall colour table
 
 	initfft();
+	il2p_init(1);
+
 
 	if (nonGUIMode)
 	{
@@ -563,7 +566,7 @@ int Freq_Change(int Chan, int Freq)
 	tx_freq[Chan] = Freq;
 
 	pnt_change[Chan] = TRUE;
-	wf_pointer(soundChannel[Chan]);
+	wf_pointer(Chan);
 
 	return Freq;
 }
@@ -805,6 +808,8 @@ void DoTX(int Chan)
 
 	// Start a new send. modulator should handle TXD etc
 
+	checkforCWID();		// See if need to start CWID timer in afteractivity mode
+
 	Debugprintf("TX Start");
 	SampleNo = 0;
 
@@ -1131,7 +1136,9 @@ void OpenPTTPort()
 
 void ClosePTTPort()
 {
-	CloseCOMPort(hPTTDevice);
+	if (hPTTDevice)
+		CloseCOMPort(hPTTDevice);
+	
 	hPTTDevice = 0;
 }
 void CM108_set_ptt(int PTTState)
diff --git a/UZ7HOStuff.h b/UZ7HOStuff.h
index 586edce..f62c123 100644
--- a/UZ7HOStuff.h
+++ b/UZ7HOStuff.h
@@ -4,8 +4,8 @@
 //	 My port of UZ7HO's Soundmodem
 //
 
-#define VersionString "0.0.0.67-2"
-#define VersionBytes {0, 0, 0, 67}
+#define VersionString "0.0.0.68"
+#define VersionBytes {0, 0, 0, 68}
 
 // Added FX25. 4x100 FEC and V27 not Working and disabled
 
@@ -159,6 +159,13 @@
 // .68 Monitor XID and TEST
 //	   Flag active interface in title bar
 //	   Improve header validation in il2p
+//	   Add CWID only after traffic option
+//	   Add font selection
+//	   Separate modem bandwidth indicators
+//	   Fix problems with il2p and PSK modes in nogui mode
+//	   Add signal level bar to GUI
+//	   Fix Waterfall display when using right channel only
+//	   Allow PTT device to be added 
 
 
 
diff --git a/Waveout.c b/Waveout.c
index 77c8b10..0b37658 100644
--- a/Waveout.c
+++ b/Waveout.c
@@ -511,7 +511,7 @@ for (i = 0; i < 100; i++)
 
 static int min = 0, max = 0, lastlevelGUI = 0, lastlevelreport = 0;
 
-static UCHAR CurrentLevel = 0;		// Peak from current samples
+UCHAR CurrentLevel = 0;		// Peak from current samples
 
 void PollReceivedSamples()
 {
@@ -988,9 +988,7 @@ void StdinPollReceivedSamples()
 
 	if ((Now - lastlevelGUI) > 2000)	// 2 Secs
 	{
-		//			if (WaterfallActive == 0 && SpectrumActive == 0)				// Don't need to send as included in Waterfall Line
-		//				SendtoGUI('L', &CurrentLevel, 1);	// Signal Level
-
+//		RefreshLevel(CurrentLevel);	// Signal Level
 		lastlevelGUI = Now;
 
 		if ((Now - lastlevelreport) > 10000)	// 10 Secs
diff --git a/debug/QtSoundModem.ini b/debug/QtSoundModem.ini
index 9747798..0aefa4a 100644
--- a/debug/QtSoundModem.ini
+++ b/debug/QtSoundModem.ini
@@ -1,7 +1,10 @@
 [General]
-geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\a\0\0\0\0\0\0\x3\xca\0\0\x2\xf0\0\0\0\b\0\0\0\x1f\0\0\x3\xc9\0\0\x2\xef\0\0\0\0\0\0\0\0\x5\0\0\0\0\b\0\0\0\x1f\0\0\x3\xc9\0\0\x2\xef)
-windowState=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\0\0\0\x3\xc2\0\0\x2\xbc\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\0)
+geometry="@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0z\0\0\0\t\0\0\x4=\0\0\x2\xf9\0\0\0{\0\0\0(\0\0\x4<\0\0\x2\xf8\0\0\0\0\0\0\0\0\x5\0\0\0\0{\0\0\0(\0\0\x4<\0\0\x2\xf8)"
+windowState=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\0\0\0\x3\xc2\0\0\x2\xb9\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\0)
 PSKWindow=@Rect(46 499 366 140)
+FontFamily=Courier New
+PointSize=12
+Weight=50
 
 [AX25_A]
 Retries=15
@@ -56,7 +59,7 @@ HamLibPort=4532
 HamLibHost=127.0.0.1
 MinimizetoTray=1
 multiCore=1
-Wisdom=(fftw-3.3.5 fftwf_wisdom #x08ac4c16 #x457005cc #xea102cf7 #xd7ff9038\n  (fftwf_dft_vrank_geq1_register 0 #x10048 #x10048 #x0 #x2fce15e1 #x178d4f4d #x1e956a41 #xf3fd6b80)\n  (fftwf_dft_buffered_register 0 #x11048 #x11048 #x0 #x4f8e87b4 #xec4f2fa0 #x79fe76a1 #xa16e32a5)\n  (fftwf_codelet_t1fv_6_sse2 0 #x10048 #x10048 #x0 #xd9db29d8 #x3302fcf3 #x19ce6e5d #x869fc341)\n  (fftwf_codelet_t1fv_12_sse2 0 #x10048 #x10048 #x0 #x0b0d3933 #x08267d12 #x45613873 #xde496efe)\n  (fftwf_codelet_n2fv_12_sse2 0 #x10048 #x10048 #x0 #xb0767e46 #x8d41dd22 #x439264a0 #x18435a99)\n  (fftwf_dft_bluestein_register 0 #x11048 #x11048 #x0 #x5e17c068 #x1682c5d6 #x89dd79be #x9b951c0f)\n  (fftwf_codelet_t1fuv_8_sse2 0 #x11048 #x11048 #x0 #x34057a74 #x664db78f #xa9524ebc #x606afd88)\n  (fftwf_dft_r2hc_register 0 #x11048 #x11048 #x0 #x576d5db6 #xa6a15f8a #x875d87d5 #x7561a866)\n  (fftwf_dft_vrank_geq1_register 0 #x11048 #x11048 #x0 #x1e354940 #xac45f390 #x8260fb76 #x1a44862e)\n  (fftwf_rdft_rank0_register 0 #x11048 #x11048 #x0 #xff75c762 #x3a0ee093 #x5b78d592 #x6b6be60e)\n  (fftwf_dft_nop_register 0 #x11048 #x11048 #x0 #x4a593e24 #xb5f06ddf #xf11fe7f2 #xc010b545)\n)\n
+Wisdom=(fftw-3.3.5 fftwf_wisdom #x9e7d4dee #xdb14fed1 #x34bf76a4 #xeb6e8fdf\n  (fftwf_codelet_n2fv_12_avx 0 #x10048 #x10048 #x0 #xb0767e46 #x8d41dd22 #x439264a0 #x18435a99)\n  (fftwf_rdft_rank0_register 0 #x11048 #x11048 #x0 #xff75c762 #x3a0ee093 #x5b78d592 #x6b6be60e)\n  (fftwf_codelet_t2fv_2_avx 0 #x11048 #x11048 #x0 #x34057a74 #x664db78f #xa9524ebc #x606afd88)\n  (fftwf_dft_nop_register 0 #x11048 #x11048 #x0 #x4a593e24 #xb5f06ddf #xf11fe7f2 #xc010b545)\n  (fftwf_dft_bluestein_register 0 #x11048 #x11048 #x0 #x5e17c068 #x1682c5d6 #x89dd79be #x9b951c0f)\n  (fftwf_dft_vrank_geq1_register 0 #x10048 #x10048 #x0 #x2fce15e1 #x178d4f4d #x1e956a41 #xf3fd6b80)\n  (fftwf_codelet_t1fuv_4_sse2 0 #x11048 #x11048 #x0 #x2fb84bc5 #x2792028e #x8ec66ed5 #x47b5f7dc)\n  (fftwf_dft_buffered_register 0 #x11048 #x11048 #x0 #x4f8e87b4 #xec4f2fa0 #x79fe76a1 #xa16e32a5)\n  (fftwf_dft_vrank_geq1_register 0 #x11048 #x11048 #x0 #x8a9c355b #xb6dbadad #xbac1daac #xa866ceb3)\n  (fftwf_dft_r2hc_register 0 #x11048 #x11048 #x0 #x576d5db6 #xa6a15f8a #x875d87d5 #x7561a866)\n  (fftwf_codelet_t1fv_6_avx 0 #x10048 #x10048 #x0 #xd9db29d8 #x3302fcf3 #x19ce6e5d #x869fc341)\n  (fftwf_dft_vrank_geq1_register 0 #x11048 #x11048 #x0 #xf7abab03 #x5f0e79b1 #x1b8367ad #xe5028f2c)\n  (fftwf_codelet_t1fv_12_avx 0 #x10048 #x10048 #x0 #x0b0d3933 #x08267d12 #x45613873 #xde496efe)\n)\n
 WaterfallMin=0
 WaterfallMax=3300
 
@@ -131,6 +134,7 @@ RXFreq2=1700
 RXFreq3=500
 RXFreq4=1700
 CWIDMark=
+afterTraffic=false
 
 [AGWHost]
 Server=1
diff --git a/devicesDialog.ui b/devicesDialog.ui
index 0f46639..bf2bd9b 100644
--- a/devicesDialog.ui
+++ b/devicesDialog.ui
@@ -748,6 +748,9 @@
         <height>22</height>
        </rect>
       </property>
+      <property name="editable">
+       <bool>true</bool>
+      </property>
      </widget>
      <widget class="QLabel" name="label_5">
       <property name="geometry">
diff --git a/il2p.c b/il2p.c
index 6b3ae52..e51264c 100644
--- a/il2p.c
+++ b/il2p.c
@@ -4001,8 +4001,8 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit)
 					if (len > 340)
 					{
 						Debugprintf("Packet too big for QtSM");
-		//				F->state = IL2P_SEARCHING;
-		//				return;
+						F->state = IL2P_SEARCHING;
+						return;
 					}
 					if (F->eplen >= 1) {		// Need to gather payload.
 						F->pc = 0;
diff --git a/release/moc_predefs.h b/release/moc_predefs.h
deleted file mode 100644
index 4c9c0c7..0000000
--- a/release/moc_predefs.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#define _MSC_EXTENSIONS 
-#define _INTEGRAL_MAX_BITS 64
-#define _MSC_VER 1916
-#define _MSC_FULL_VER 191627043
-#define _MSC_BUILD 0
-#define _WIN32 
-#define _M_IX86 600
-#define _M_IX86_FP 2
-#define _CPPRTTI 
-#define _MT 
-#define _DLL 
diff --git a/sm_main.c b/sm_main.c
index a75ea5f..57bf549 100644
--- a/sm_main.c
+++ b/sm_main.c
@@ -728,7 +728,7 @@ void init_speed(int snd_ch)
 	  form1.show_freq_a;
 	  form1.show_freq_b;
 	  */
-	wf_pointer(soundChannel[snd_ch]);
+	wf_pointer(snd_ch);
 
 	CheckPSKWindows();
 }
diff --git a/tcpCode.h b/tcpCode.h
index 8d15a05..9255a49 100644
--- a/tcpCode.h
+++ b/tcpCode.h
@@ -64,6 +64,8 @@ signals:
 	void sendtoTrace(char *, int);
 	void sendtoKISS(void *, unsigned char *, int);
 	void openSockets();
+	void startCWIDTimer();
+
 
 private:
 	void run();