summaryrefslogtreecommitdiffstats
path: root/clients/tde/src/part/commanalyzer
diff options
context:
space:
mode:
Diffstat (limited to 'clients/tde/src/part/commanalyzer')
-rw-r--r--clients/tde/src/part/commanalyzer/Makefile.am9
-rw-r--r--clients/tde/src/part/commanalyzer/debug.h36
-rw-r--r--clients/tde/src/part/commanalyzer/layout.ui159
-rwxr-xr-xclients/tde/src/part/commanalyzer/layout_test.ui68
-rw-r--r--clients/tde/src/part/commanalyzer/part.cpp396
-rw-r--r--clients/tde/src/part/commanalyzer/part.h73
6 files changed, 741 insertions, 0 deletions
diff --git a/clients/tde/src/part/commanalyzer/Makefile.am b/clients/tde/src/part/commanalyzer/Makefile.am
new file mode 100644
index 0000000..db98e9e
--- /dev/null
+++ b/clients/tde/src/part/commanalyzer/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = $(all_includes) -I$(top_srcdir)/src -I$(top_srcdir)/src/widgets
+METASOURCES = AUTO
+
+#Part
+kde_module_LTLIBRARIES = libremotelab_commanalyzer.la
+libremotelab_commanalyzer_la_LIBADD = ../../widgets/libtracewidget.la ../../widgets/libfloatspinbox.la $(LIB_KFILE) $(LIB_KPARTS) $(LIB_TDEUI) $(LIB_QT)
+libremotelab_commanalyzer_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -ltdecore -ltdeui -lkio -ltdefx
+libremotelab_commanalyzer_la_SOURCES = \
+ part.cpp layout.ui
diff --git a/clients/tde/src/part/commanalyzer/debug.h b/clients/tde/src/part/commanalyzer/debug.h
new file mode 100644
index 0000000..e5e680b
--- /dev/null
+++ b/clients/tde/src/part/commanalyzer/debug.h
@@ -0,0 +1,36 @@
+//Author: Max Howell <max.howell@methylblue.com>, (C) 2003-4
+//Copyright: See COPYING file that comes with this distribution
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+/** Fancy debug header
+ * @author Max Howell
+ *
+ * Define DEBUG_PREFIX as a string before you include this to insert a fancy debug prefix
+ * Debug::debug(), can be used as debug() and is just kdDebug()
+ * use Debug::indent() and Debug::unindent()
+ */
+
+#include <kdebug.h>
+
+#ifdef NDEBUG
+static inline kndbgstream debug() { return kndbgstream(); }
+#else
+static inline kdbgstream debug()
+{
+ return kdbgstream(
+ #ifdef DEBUG_PREFIX
+ "[" DEBUG_PREFIX "] ",
+ #endif
+ 0, 0 );
+}
+#endif
+
+#define error kdError
+#define fatal kdFatal
+#define warning kdWarning
+
+#define DEBUG_ANNOUNCE debug() << ">> " << __PRETTY_FUNCTION__ << endl;
+
+#endif
diff --git a/clients/tde/src/part/commanalyzer/layout.ui b/clients/tde/src/part/commanalyzer/layout.ui
new file mode 100644
index 0000000..29d9392
--- /dev/null
+++ b/clients/tde/src/part/commanalyzer/layout.ui
@@ -0,0 +1,159 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+ <class>CommAnalyzerBase</class>
+ <widget class="TQWidget">
+ <property name="name">
+ <cstring>CommAnalyzerBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>519</width>
+ <height>356</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQTabWidget" row="0" column="0">
+ <property name="name">
+ <cstring>TabWidget2</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <widget class="TQWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Spectrum Analyzer</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupSpectrumAnalyzer</cstring>
+ </property>
+ <property name="title">
+ <string>Spectrum Analyzer</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupSpectrumAnalyzerView</cstring>
+ </property>
+ <property name="title">
+ <string>Trace Viewer</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TraceWidget" row="0" column="0" colspan="1">
+ <property name="name">
+ <cstring>traceWidget</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>1</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="TQGroupBox" row="0" column="1">
+ <property name="name">
+ <cstring>groupSpectrumAnalyzerRecControls</cstring>
+ </property>
+ <property name="title">
+ <string>Receiver Controls</string>
+ </property>
+ <grid>
+ <widget class="TQLabel" row="0" column="0" colspan="1">
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="text">
+ <string>Reference Power Level:</string>
+ </property>
+ <property name="textFormat">
+ <enum>PlainText</enum>
+ </property>
+ </widget>
+ <widget class="FloatSpinBox" row="0" column="1" colspan="1">
+ <property name="name">
+ <cstring>saRefLevel</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maxValue">
+ <number>128</number>
+ </property>
+ <property name="minValue">
+ <number>-128</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="TQLabel" row="0" column="3" colspan="1">
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="text">
+ <string>dBm</string>
+ </property>
+ <property name="textFormat">
+ <enum>PlainText</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ </widget>
+ </grid>
+ </widget>
+ <includes>
+ <include location="local" impldecl="in implementation">CommAnalyzerBase.ui.h</include>
+ </includes>
+ <includes>
+ <include location="local" impldecl="in implementation">tracewidget.h</include>
+ <include location="local" impldecl="in implementation">floatspinbox.h</include>
+ </includes>
+ <layoutdefaults spacing="3" margin="6"/>
+ <layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/>
+</UI>
diff --git a/clients/tde/src/part/commanalyzer/layout_test.ui b/clients/tde/src/part/commanalyzer/layout_test.ui
new file mode 100755
index 0000000..243649d
--- /dev/null
+++ b/clients/tde/src/part/commanalyzer/layout_test.ui
@@ -0,0 +1,68 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>CommAnalyzerBase</class>
+<widget class="TQWidget">
+ <property name="name">
+ <cstring>CommAnalyzerBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>519</width>
+ <height>356</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>CommAnalyzerBase</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQTabWidget" row="0" column="0">
+ <property name="name">
+ <cstring>TabWidget2</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <widget class="TQWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Spectrum Analyzer</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupSpectrumAnalyzer</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Spectrum Analyzer</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="3" margin="6"/>
+<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/>
+</UI>
diff --git a/clients/tde/src/part/commanalyzer/part.cpp b/clients/tde/src/part/commanalyzer/part.cpp
new file mode 100644
index 0000000..3fd89eb
--- /dev/null
+++ b/clients/tde/src/part/commanalyzer/part.cpp
@@ -0,0 +1,396 @@
+//Author: Timothy Pearson <kb9vqf@pearsoncomputing.net>, (C) 2012
+//Copyright: See COPYING file that comes with this distribution
+
+#include "debug.h"
+#include "define.h"
+#include "part.h"
+
+#include <kaboutdata.h> //::createAboutData()
+#include <kaction.h>
+#include <klocale.h>
+#include <kmessagebox.h> //::start()
+#include <kparts/genericfactory.h>
+#include <kstatusbar.h>
+#include <kstdaction.h>
+#include <tqfile.h> //encodeName()
+#include <tqtimer.h> //postInit() hack
+#include <tqvbox.h>
+#include <tqsocket.h>
+#include <tqmutex.h>
+#include <tqeventloop.h>
+#include <tqapplication.h>
+#include <unistd.h> //access()
+#include <stdint.h>
+
+#include "tracewidget.h"
+#include "floatspinbox.h"
+#include "layout.h"
+
+namespace RemoteLab {
+
+typedef KParts::GenericFactory<RemoteLab::CommAnalyzerPart> Factory;
+K_EXPORT_COMPONENT_FACTORY( libremotelab_commanalyzer, RemoteLab::Factory )
+
+
+CommAnalyzerPart::CommAnalyzerPart( TQWidget *parentWidget, const char *widgetName, TQObject *parent, const char *name, const TQStringList& )
+ : ReadOnlyPart( parent, name ), m_traceWidget(0), m_socket(0), m_base(0), stopTraceUpdate(false)
+{
+ // Initialize mutex
+ m_instrumentMutex = new TQMutex(false);
+
+ // Initialize kpart
+ setInstance(Factory::instance());
+ setWidget(new TQVBox(parentWidget, widgetName));
+
+ // Create widgets
+ m_base = new CommAnalyzerBase(widget());
+ m_traceWidget = m_base->traceWidget;
+ m_base->saRefLevel->setFloatMin(-128);
+ m_base->saRefLevel->setFloatMax(128);
+ m_base->saRefLevel->setLineStep(1);
+
+ connect(m_base->saRefLevel, SIGNAL(floatValueChanged(double)), this, SLOT(saRefLevelChanged(double)));
+
+ TQTimer::singleShot(0, this, TQT_SLOT(postInit()));
+}
+
+CommAnalyzerPart::~CommAnalyzerPart() {
+ if (m_traceWidget) {
+ delete m_traceWidget;
+ }
+ if (m_socket) {
+ m_socket->close();
+ while (m_socket->state() == TQSocket::Closing) {
+ tqApp->processEvents();
+ }
+ delete m_socket;
+ }
+
+ delete m_instrumentMutex;
+}
+
+void CommAnalyzerPart::postInit() {
+ m_updateTimer = new TQTimer(this);
+ connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(updateTrace()));
+}
+
+bool CommAnalyzerPart::openURL(const KURL &url) {
+ connectToServer(url.url());
+}
+
+bool CommAnalyzerPart::closeURL() {
+ m_socket->close();
+
+ while (m_socket->state() != TQSocket::Idle) {
+ tqApp->processEvents();
+ }
+
+ m_url = KURL();
+
+ return true;
+}
+
+TQString CommAnalyzerPart::callServerMethod(int command) {
+ if (m_instrumentMutex->locked() == true) {
+ printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout);
+ return TQString::null;
+ }
+ m_instrumentMutex->lock();
+ if (m_socket->state() == TQSocket::Connected) {
+ TQString cmd = TQChar(command);
+ cmd.append('\r');
+ m_socket->writeBlock(cmd.latin1(), cmd.length());
+ // Read from the server
+ TQString serverRet;
+ while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
+ char data[1];
+ if( m_socket->readBlock(data, 1) > 0) {
+ serverRet.append(data[0]);
+ }
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ m_instrumentMutex->unlock();
+ return serverRet;
+ }
+ else {
+ m_instrumentMutex->unlock();
+ return TQString::null;
+ }
+}
+
+int16_t CommAnalyzerPart::callServerMethodInt16(int command) {
+ if (m_instrumentMutex->locked() == true) {
+ printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout);
+ return 0;
+ }
+ m_instrumentMutex->lock();
+ if (m_socket->state() == TQSocket::Connected) {
+ TQString cmd = TQChar(command);
+ cmd.append('\r');
+ m_socket->writeBlock(cmd.latin1(), cmd.length());
+ // Read from the server
+ int bytesread = 0;
+ int16_t data[1];
+ while ((bytesread < 2) && (m_socket->state() == TQSocket::Connected)) {
+ int ret = m_socket->readBlock(((char*)data)+bytesread, 1);
+ if (ret > 0) {
+ bytesread += ret;
+ }
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ TQString serverRet;
+ while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
+ char data[1];
+ if( m_socket->readBlock(data, 1) > 0) {
+ serverRet.append(data[0]);
+ }
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ m_instrumentMutex->unlock();
+ return data[0];
+ }
+ else {
+ m_instrumentMutex->unlock();
+ return 0;
+ }
+}
+
+double CommAnalyzerPart::callServerMethodDouble(int command) {
+ if (m_instrumentMutex->locked() == true) {
+ printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout);
+ return 0;
+ }
+ m_instrumentMutex->lock();
+ if (m_socket->state() == TQSocket::Connected) {
+ TQString cmd = TQChar(command);
+ cmd.append('\r');
+ m_socket->writeBlock(cmd.latin1(), cmd.length());
+ // Read from the server
+ unsigned int bytesread = 0;
+ double data[1];
+ while ((bytesread < sizeof(double)) && (m_socket->state() == TQSocket::Connected)) {
+ int ret = m_socket->readBlock(((char*)data)+bytesread, 1);
+ if (ret > 0) {
+ bytesread += ret;
+ }
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ TQString serverRet;
+ while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
+ char data[1];
+ if( m_socket->readBlock(data, 1) > 0) {
+ serverRet.append(data[0]);
+ }
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ m_instrumentMutex->unlock();
+ return data[0];
+ }
+ else {
+ m_instrumentMutex->unlock();
+ return 0;
+ }
+}
+
+void CommAnalyzerPart::sendServerCommandWithParameter(int command, TQString param) {
+ if (m_instrumentMutex->locked() == true) {
+ printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout);
+ return;
+ }
+ m_instrumentMutex->lock();
+ if (m_socket->state() == TQSocket::Connected) {
+ TQString cmd = TQChar(command);
+ param = TQString("%1%2%3").arg(param).arg(TQChar('°')).arg(TQChar('\r'));
+ cmd += param;
+ m_socket->writeBlock(cmd.ascii(), cmd.length());
+ // Read from the server
+ TQString serverRet;
+ while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
+ char data[1];
+ if( m_socket->readBlock(data, 1) > 0) {
+ serverRet.append(data[0]);
+ }
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ }
+ m_instrumentMutex->unlock();
+}
+
+void CommAnalyzerPart::sendServerCommand(int command) {
+ if (m_instrumentMutex->locked() == true) {
+ printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout);
+ return;
+ }
+ m_instrumentMutex->lock();
+ if (m_socket->state() == TQSocket::Connected) {
+ TQString cmd = TQChar(command);
+ cmd.append('\r');
+ m_socket->writeBlock(cmd.latin1(), cmd.length());
+ // Read from the server
+ TQString serverRet;
+ while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
+ char data[1];
+ if( m_socket->readBlock(data, 1) > 0) {
+ serverRet.append(data[0]);
+ }
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ }
+ m_instrumentMutex->unlock();
+}
+
+void CommAnalyzerPart::callServerMethodDoubleArray(int command, double * array, int arrayLen) {
+ if (m_instrumentMutex->locked() == true) {
+ printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout);
+ return;
+ }
+ m_instrumentMutex->lock();
+ if (m_socket->state() == TQSocket::Connected) {
+ TQString cmd = TQChar(command);
+ cmd.append('\r');
+ m_socket->writeBlock(cmd.latin1(), cmd.length());
+ // Read from the server
+ TQString serverRet;
+ while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
+ char data[1];
+ if( m_socket->readBlock(data, 1) > 0) {
+ serverRet.append(data[0]);
+ }
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ unsigned int bytesread = 0;
+ int16_t data[1];
+ while ((bytesread < 2) && (m_socket->state() == TQSocket::Connected)) {
+ int ret = m_socket->readBlock(((char*)data)+bytesread, 1);
+ if (ret > 0) {
+ bytesread += ret;
+ }
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ serverRet = "";
+ while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
+ char data[1];
+ if( m_socket->readBlock(data, 1) > 0) {
+ serverRet.append(data[0]);
+ }
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ bytesread = 0;
+ int elementsread = 0;
+ for (elementsread=0;elementsread<arrayLen;elementsread++) {
+ bytesread = 0;
+ while ((bytesread < sizeof(double)) && (m_socket->state() == TQSocket::Connected)) {
+ if (m_socket->size() < 1) {
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ int ret = m_socket->readBlock(((char*)array)+bytesread+(elementsread*sizeof(double)), 1);
+ if (ret > 0) {
+ bytesread += ret;
+ }
+ }
+ }
+ }
+ m_instrumentMutex->unlock();
+}
+
+int CommAnalyzerPart::connectToServer(TQString server) {
+ if (!m_socket) {
+ m_socket = new TQSocket(this);
+// connect(m_socket, SIGNAL(connected()), SLOT(socketConnected()));
+// connect(m_socket, SIGNAL(connectionClosed()), SLOT(socketConnectionClosed()));
+// connect(m_socket, SIGNAL(readyRead()), SLOT(socketReadyRead()));
+// connect(m_socket, SIGNAL(error(int)), SLOT(socketError(int)));
+ }
+ m_socket->connectToHost(server, 4002);
+ while ((m_socket->state() != TQSocket::Connected) && (m_socket->state() != TQSocket::Idle)) {
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ if (m_socket->state() != TQSocket::Connected) {
+ return -1;
+ }
+
+ // Gather information from the server
+ if (callServerMethod(41) == "NCK") {
+ // FIXME
+ // Display message and exit
+ return -1;
+ }
+ sendServerCommand(40); // Set spectrum analyzer mode
+ m_samplesInTrace = callServerMethodInt16(63); // Get number of samples in trace
+ m_traceWidget->setNumberOfSamples(m_samplesInTrace);
+ m_hdivs = callServerMethodInt16(62); // Get number of horizontal divisions
+ m_traceWidget->setNumberOfHorizontalDivisions(m_hdivs);
+ m_vdivs = callServerMethodInt16(64); // Get number of vertical divisions
+ m_traceWidget->setNumberOfVerticalDivisions(m_vdivs);
+
+ m_rpower = callServerMethodDouble(65); // Get reference power level
+ m_vscale = callServerMethodDouble(66); // Get vertical division scale
+
+ m_centerfreq = callServerMethodDouble(67); // Get center frequency
+ m_spanfreq = callServerMethodDouble(68); // Get frequency span
+
+ updateGraticule();
+
+ // Start trace update timer
+ m_updateTimer->start(10, FALSE);
+}
+
+void CommAnalyzerPart::postProcessTrace() {
+ return;
+}
+
+void CommAnalyzerPart::updateTrace() {
+ m_updateTimer->stop();
+ callServerMethodDoubleArray(42, m_traceWidget->samples(), m_samplesInTrace);
+ postProcessTrace();
+ m_traceWidget->repaint();
+ if (m_socket->state() == TQSocket::Connected) {
+ if (stopTraceUpdate == true) {
+ stopTraceUpdate = false;
+ }
+ else {
+ m_updateTimer->start(10, FALSE);
+ }
+ }
+}
+
+void CommAnalyzerPart::updateGraticule() {
+ m_leftFrequency = m_centerfreq - (m_spanfreq/2.0);
+ m_rightFrequency = m_centerfreq + (m_spanfreq/2.0);
+ m_traceWidget->setDisplayLimits(m_leftFrequency, m_rpower, m_rightFrequency, m_rpower-(m_vscale*m_hdivs));
+
+ // Also update controls
+ m_base->saRefLevel->blockSignals(true);
+ m_base->saRefLevel->setFloatValue(m_rpower);
+ m_base->saRefLevel->blockSignals(false);
+}
+
+void CommAnalyzerPart::saRefLevelChanged(double newval) {
+ // We cannot directly send data to the remote instrument because the GUI event may have ocurred during a remote instrument transaction
+ // This "flaw" is a direct result of maximizing performance by processing GUI events during network transfers, as well as the fact that this client is a multithreaded application
+ m_rpower = newval;
+ stopTraceUpdate = true;
+ TQTimer::singleShot(0, this, SLOT(changeSaRefLevel()));
+}
+
+void CommAnalyzerPart::changeSaRefLevel() {
+ // Keep trying to set the new power level
+ if (m_instrumentMutex->locked() == false) {
+ sendServerCommandWithParameter(61, TQString("%1").arg(m_rpower, 0, 'E')); // Set reference power level
+ m_rpower = callServerMethodDouble(65); // Get reference power level
+ updateGraticule(); // Update the display grid
+ m_updateTimer->start(10, FALSE); // Restart trace update timer
+ }
+ else {
+ tqApp->eventLoop()->processEvents(TQEventLoop::ExcludeUserInput);
+ TQTimer::singleShot(0, this, SLOT(changeSaRefLevel()));
+ }
+}
+
+KAboutData* CommAnalyzerPart::createAboutData() {
+ return new KAboutData( APP_NAME, I18N_NOOP( APP_PRETTYNAME ), APP_VERSION );
+}
+
+} //namespace RemoteLab
+
+#include "part.moc"
diff --git a/clients/tde/src/part/commanalyzer/part.h b/clients/tde/src/part/commanalyzer/part.h
new file mode 100644
index 0000000..196706b
--- /dev/null
+++ b/clients/tde/src/part/commanalyzer/part.h
@@ -0,0 +1,73 @@
+//Author: Timothy Pearson <kb9vqf@pearsoncomputing.net>, (C) 2012
+//Copyright: See COPYING file that comes with this distribution
+
+#ifndef REMOTELAB_COMMANALYZERPART_H
+#define REMOTELAB_COMMANALYZERPART_H
+
+#include <kparts/browserextension.h>
+#include <kparts/statusbarextension.h>
+#include <kparts/part.h>
+#include <kurl.h>
+
+class KAboutData;
+using KParts::StatusBarExtension;
+class TraceWidget;
+class TQSocket;
+class TQTimer;
+class TQMutex;
+class CommAnalyzerBase;
+
+namespace RemoteLab
+{
+ class CommAnalyzerPart : public KParts::ReadOnlyPart
+ {
+ Q_OBJECT
+
+ public:
+ CommAnalyzerPart( QWidget *, const char *, TQObject *, const char *, const TQStringList&);
+ ~CommAnalyzerPart();
+
+ virtual bool openFile() { return false; } // pure virtual in the base class
+ virtual bool closeURL();
+ static KAboutData *createAboutData();
+ int connectToServer(TQString server);
+
+ public slots:
+ virtual bool openURL(const KURL &url);
+
+ private slots:
+ void postInit();
+ void updateTrace();
+ void updateGraticule();
+ virtual void postProcessTrace();
+ void saRefLevelChanged(double);
+ void changeSaRefLevel();
+
+ private:
+ TQString callServerMethod(int command);
+ void sendServerCommand(int command);
+ int16_t callServerMethodInt16(int command);
+ double callServerMethodDouble(int command);
+ void callServerMethodDoubleArray(int command, double * array, int arrayLen);
+ void sendServerCommandWithParameter(int command, TQString param);
+
+ private:
+ TraceWidget* m_traceWidget;
+ TQSocket* m_socket;
+ int16_t m_samplesInTrace;
+ double m_leftFrequency;
+ double m_rightFrequency;
+ int16_t m_hdivs;
+ int16_t m_vdivs;
+ double m_centerfreq;
+ double m_spanfreq;
+ double m_rpower;
+ double m_vscale;
+ TQTimer* m_updateTimer;
+ CommAnalyzerBase* m_base;
+ TQMutex* m_instrumentMutex;
+ bool stopTraceUpdate;
+ };
+}
+
+#endif