summaryrefslogtreecommitdiffstats
path: root/clients/tde/src/part
diff options
context:
space:
mode:
Diffstat (limited to 'clients/tde/src/part')
-rw-r--r--clients/tde/src/part/scope/layout.ui56
-rw-r--r--clients/tde/src/part/scope/part.cpp505
-rw-r--r--clients/tde/src/part/scope/part.h45
3 files changed, 492 insertions, 114 deletions
diff --git a/clients/tde/src/part/scope/layout.ui b/clients/tde/src/part/scope/layout.ui
index 9390e82..ee3bb81 100644
--- a/clients/tde/src/part/scope/layout.ui
+++ b/clients/tde/src/part/scope/layout.ui
@@ -98,63 +98,15 @@
</widget>
<widget class="TQGroupBox" row="0" column="1">
<property name="name">
- <cstring>groupOscilloscopeTraceControls</cstring>
+ <cstring>groupOscilloscopeCaptureControls</cstring>
</property>
<property name="title">
- <string>Receiver Controls</string>
+ <string>Capture Controls</string>
</property>
<grid>
- <widget class="TQLabel" row="0" column="0" colspan="1">
+ <widget class="TQWidget" row="0" column="0" colspan="4">
<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>
+ <cstring>traceControlLayoutWidget</cstring>
</property>
</widget>
</grid>
diff --git a/clients/tde/src/part/scope/part.cpp b/clients/tde/src/part/scope/part.cpp
index 9909e65..17c137d 100644
--- a/clients/tde/src/part/scope/part.cpp
+++ b/clients/tde/src/part/scope/part.cpp
@@ -18,6 +18,9 @@
#include <tqsocket.h>
#include <tqmutex.h>
#include <tqgroupbox.h>
+#include <tqlayout.h>
+#include <tqcombobox.h>
+#include <tqcheckbox.h>
#include <tqpushbutton.h>
#include <tqeventloop.h>
#include <tqapplication.h>
@@ -38,19 +41,23 @@ struct exit_exception {
};
enum connectionStates {
- ScopeState_InitialRequest = 0,
- ScopeState_ResetRequest = 2,
- ScopeState_HorizontalDivCountRequest = 4,
- ScopeState_VerticalDivCountRequest = 6,
- ScopeState_ChannelCountRequest = 8,
- ScopeState_ChannelActiveStateRequest = 10,
- ScopeState_TraceSampleCountRequest = 12,
- ScopeState_TraceVoltsDivRequest = 14,
- ScopeState_TraceSecondsDivRequest = 16,
- ScopeState_TriggerChannelRequest = 18,
- ScopeState_TriggerLevelRequest = 20,
- ScopeState_TraceRequest = 50,
- ScopeState_ExternalCommandRequest = 255
+ ScopeState_InitialRequest = 0,
+ ScopeState_ResetRequest = 2,
+ ScopeState_HorizontalDivCountRequest = 4,
+ ScopeState_VerticalDivCountRequest = 6,
+ ScopeState_ChannelCountRequest = 8,
+ ScopeState_ChannelActiveStateRequest = 10,
+ ScopeState_TraceSampleCountRequest = 12,
+ ScopeState_TracePermittedVoltsDivRequest = 14,
+ ScopeState_TraceVoltsDivRequest = 16,
+ ScopeState_TraceSecondsDivRequest = 18,
+ ScopeState_TriggerChannelRequest = 20,
+ ScopeState_TriggerLevelRequest = 22,
+ ScopeState_TraceRequest = 50,
+ ScopeState_ChannelActiveStateUpdate = 100,
+ ScopeState_TraceVoltsDivUpdate = 102,
+ ScopeState_TriggerLevelUpdate = 104,
+ ScopeState_ExternalCommandRequest = 255
};
namespace RemoteLab {
@@ -59,6 +66,80 @@ typedef KParts::GenericFactory<RemoteLab::ScopePart> Factory;
#define CLIENT_LIBRARY "libremotelab_scope"
K_EXPORT_COMPONENT_FACTORY( libremotelab_scope, RemoteLab::Factory )
+TraceControlWidget::TraceControlWidget(TQWidget *parent, const char *name)
+ : TQWidget(parent, name)
+{
+ TQGridLayout *topGrid = new TQGridLayout(this);
+ m_groupBox = new TQGroupBox(this);
+ m_groupBox->setColumnLayout(0, TQt::Vertical);
+ topGrid->addMultiCellWidget(m_groupBox, 0, 0, 0, 0);
+ m_groupBox->setTitle(i18n("Unknown Channel"));
+ m_primaryLayout = new TQGridLayout(m_groupBox->layout(), KDialog::marginHint(), KDialog::spacingHint());
+
+ m_channelEnabledCheckBox = new TQCheckBox(m_groupBox);
+ connect(m_channelEnabledCheckBox, SIGNAL(clicked()), this, SLOT(enableClicked()));
+ m_channelEnabledCheckBox->setText(i18n("Enable"));
+ m_primaryLayout->addMultiCellWidget(m_channelEnabledCheckBox, 0, 0, 0, 0);
+
+ m_voltsDivComboBox = new TQComboBox(m_groupBox);
+ connect(m_voltsDivComboBox, SIGNAL(activated(int)), this, SLOT(vdivChanged(int)));
+ m_primaryLayout->addMultiCellWidget(m_voltsDivComboBox, 0, 0, 1, 1);
+
+ TQLabel* label = new TQLabel(m_groupBox);
+ label->setText(i18n("V/div"));
+ m_primaryLayout->addMultiCellWidget(label, 0, 0, 2, 2);
+}
+
+TraceControlWidget::~TraceControlWidget() {
+ //
+}
+
+void TraceControlWidget::setVoltsPerDivList(TQDoubleList list) {
+ m_voltsDivList = list;
+
+ // Update drop down list
+ double prevValue = m_voltsDivComboBox->currentText().toDouble();
+ m_voltsDivComboBox->clear();
+ TQDoubleList::iterator it;
+ int i = 0;
+ for (it = m_voltsDivList.begin(); it != m_voltsDivList.end(); ++it) {
+ m_voltsDivComboBox->insertItem(TQString("%1").arg(*it), i);
+ if (prevValue == (*it)) {
+ m_voltsDivComboBox->setCurrentItem(i);
+ }
+ i++;
+ }
+}
+
+void TraceControlWidget::setSelectedVoltsPerDiv(double vdiv) {
+ int i = 0;
+ for (i=0;i<m_voltsDivComboBox->count();i++) {
+ if (m_voltsDivComboBox->text(i).toDouble() == vdiv) {
+ m_voltsDivComboBox->setCurrentItem(i);
+ }
+ }
+}
+
+void TraceControlWidget::setTraceEnabled(bool enabled) {
+ m_channelEnabledCheckBox->setChecked(enabled);
+ m_voltsDivComboBox->setEnabled(enabled);
+}
+
+void TraceControlWidget::setTraceName(TQString name) {
+ m_groupBox->setTitle(name);
+}
+
+void TraceControlWidget::enableClicked() {
+ bool enabled = m_channelEnabledCheckBox->isOn();
+ m_voltsDivComboBox->setEnabled(enabled);
+ emit(enableChanged(enabled));
+}
+
+void TraceControlWidget::vdivChanged(int index) {
+ Q_UNUSED(index)
+ double value = m_voltsDivComboBox->currentText().toDouble();
+ emit(voltsPerDivChanged(value));
+}
ScopePart::ScopePart( TQWidget *parentWidget, const char *widgetName, TQObject *parent, const char *name, const TQStringList& )
: RemoteInstrumentPart( parent, name ), m_traceWidget(0), m_commHandlerState(-1), m_commHandlerMode(0), m_commHandlerCommandState(0), m_connectionActiveAndValid(false),
@@ -88,11 +169,18 @@ ScopePart::ScopePart( TQWidget *parentWidget, const char *widgetName, TQObject *
m_channelActive[traceno] = false;
m_voltsDiv[traceno] = 0;
m_secsDiv[traceno] = 0;
+ m_traceControlWidgetList[traceno] = NULL;
+
+ m_voltsDivSet[traceno] = false;
+ m_channelActiveSet[traceno] = false;
}
+ m_triggerLevelSet = false;
// Create widgets
m_base = new ScopeBase(widget());
+ m_traceControlWidgetGrid = new TQGridLayout(m_base->traceControlLayoutWidget);
m_traceWidget = m_base->traceWidget;
+ connect(m_traceWidget, SIGNAL(cursorDragged(uint, double)), this, SLOT(cursorLevelChanged(uint, double)));
m_traceWidget->setSizePolicy(TQSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding));
m_traceWidget->setNumberOfCursors(5);
m_traceWidget->setZoomCursorStartIndex(1);
@@ -132,19 +220,12 @@ ScopePart::ScopePart( TQWidget *parentWidget, const char *widgetName, TQObject *
connect(m_traceWidget, SIGNAL(zoomBoxChanged(const TQRectF&)), this, SLOT(updateZoomWidgetLimits(const TQRectF&)));
connect(m_traceWidget, SIGNAL(offsetChanged(uint, double)), m_base->traceZoomWidget, SLOT(setTraceOffset(uint, double)));
- m_base->saRefLevel->setSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed));
- m_base->saRefLevel->setFloatMin(-128);
- m_base->saRefLevel->setFloatMax(128);
- m_base->saRefLevel->setLineStep(1);
-
connect(m_base->acqStart, SIGNAL(clicked()), this, SLOT(startDAQ()));
connect(m_base->acqStop, SIGNAL(clicked()), this, SLOT(stopDAQ()));
connect(m_base->waveformSave, SIGNAL(clicked()), this, SLOT(saveWaveforms()));
connect(m_base->waveformRecall, SIGNAL(clicked()), this, SLOT(recallWaveforms()));
- connect(m_base->saRefLevel, SIGNAL(floatValueChanged(double)), this, SLOT(saRefLevelChanged(double)));
-
TQTimer::singleShot(0, this, TQT_SLOT(postInit()));
}
@@ -190,11 +271,11 @@ void ScopePart::processLockouts() {
}
// Middle area
- if ((m_commHandlerMode < 2) && (m_commHandlerState < 50)) {
- m_base->groupOscilloscopeTraceControls->setEnabled(false);
+ if (((m_commHandlerMode < 2) && (m_commHandlerState < 50)) || (stopTraceUpdate)) {
+ m_base->groupOscilloscopeCaptureControls->setEnabled(false);
}
else {
- m_base->groupOscilloscopeTraceControls->setEnabled(true);
+ m_base->groupOscilloscopeCaptureControls->setEnabled(true);
}
// Least area
@@ -237,6 +318,14 @@ void ScopePart::connectionStatusChangedCallback() {
}
void ScopePart::setTickerMessage(TQString message) {
+ int i;
+ bool updatesPending = false;
+ for (i=0; i<=MAXTRACES;i++) {
+ if (m_channelActiveSet[i]) updatesPending = true;
+ if (m_voltsDivSet[i]) updatesPending = true;
+ if (m_triggerLevelSet) updatesPending = true;
+ }
+
m_connectionActiveAndValid = true;
TQString tickerChar;
switch (m_tickerState) {
@@ -253,7 +342,12 @@ void ScopePart::setTickerMessage(TQString message) {
tickerChar = "/";
break;
}
- setStatusMessage(message + TQString("... %1").arg(tickerChar));
+ if (updatesPending) {
+ setStatusMessage(i18n("Updates pending") + ", " + message + TQString("... %1").arg(tickerChar));
+ }
+ else {
+ setStatusMessage(message + TQString("... %1").arg(tickerChar));
+ }
m_tickerState++;
if (m_tickerState > 3) {
m_tickerState = 0;
@@ -474,6 +568,7 @@ void ScopePart::mainEventLoop() {
if (m_maxNumberOfTraces > MAXTRACES) {
m_maxNumberOfTraces = MAXTRACES;
}
+ updateTraceControlWidgets();
}
m_socket->clearFrameTail();
@@ -574,6 +669,54 @@ void ScopePart::mainEventLoop() {
}
else {
m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces);
+ SET_NEXT_STATE(ScopeState_TracePermittedVoltsDivRequest)
+ }
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else {
+ COMMUNICATIONS_FAILED
+ }
+ }
+ else {
+ if (!m_updateTimeoutTimer->isActive()) {
+ UPDATEDISPLAY_TIMEOUT
+ }
+ }
+ }
+ else if (m_commHandlerState == ScopeState_TracePermittedVoltsDivRequest) {
+ // Get permitted volts/div settings, step 1
+ ds << TQString("GETPERMITTEDVDIVS");
+ ds << m_currentOpChannel;
+ m_socket->writeEndOfFrame();
+
+ SET_NEXT_STATE(ScopeState_TracePermittedVoltsDivRequest+1)
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else if (m_commHandlerState == ScopeState_TracePermittedVoltsDivRequest+1) {
+ // Get response data
+ if (m_socket->canReadFrame()) {
+ PAT_WATCHDOG_TIMER
+ setTickerMessage(i18n("Loading [Received allowed V/div list for channel %1]").arg(m_currentOpChannel));
+
+ // Get permitted volts/div settings, step 2
+ TQString result;
+ ds >> result;
+ if (result == "ACK") {
+ TQDoubleList list;
+ ds >> list;
+ if (m_traceControlWidgetList[m_currentOpChannel-1]) {
+ m_traceControlWidgetList[m_currentOpChannel-1]->setVoltsPerDivList(list);
+ }
+ }
+ m_socket->clearFrameTail();
+
+ if (result == "ACK") {
+ if (m_currentOpChannel < m_maxNumberOfTraces) {
+ m_currentOpChannel++;
+ SET_NEXT_STATE(ScopeState_TracePermittedVoltsDivRequest)
+ }
+ else {
+ m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces);
SET_NEXT_STATE(ScopeState_TraceVoltsDivRequest)
}
EXEC_NEXT_STATE_IMMEDIATELY
@@ -645,7 +788,7 @@ void ScopePart::mainEventLoop() {
// Get response data
if (m_socket->canReadFrame()) {
PAT_WATCHDOG_TIMER
- setTickerMessage(i18n("Loading [Received seconds/div]"));
+ setTickerMessage(i18n("Loading [Received seconds/div for channel %1]").arg(m_currentOpChannel));
// Get seconds per division, step 2
TQString result;
@@ -738,9 +881,6 @@ void ScopePart::mainEventLoop() {
if (result == "ACK") {
// Update display widget(s)
updateGraticule();
- // HACK
- // Force resize of parent frame
- emit(resizeToHintRequested());
}
if (result == "ACK") {
@@ -764,6 +904,7 @@ void ScopePart::mainEventLoop() {
ds << m_currentOpChannel;
m_socket->writeEndOfFrame();
+ m_lastChangesRequireFullUpdate = false;
SET_NEXT_STATE(ScopeState_TraceRequest+1)
EXEC_NEXT_STATE_IMMEDIATELY
}
@@ -797,12 +938,16 @@ void ScopePart::mainEventLoop() {
if (result == "ACK") {
m_currentOpChannel = getNextActiveChannel(m_currentOpChannel, m_channelActive, m_maxNumberOfTraces);
- if (m_currentOpChannel > 0) {
+ if ((m_currentOpChannel > 0)
+ && (m_channelActiveSet[m_currentOpChannel] == false)
+ && (m_voltsDivSet[m_currentOpChannel] == false)
+ && (m_triggerLevelSet == false)
+ ) {
SET_NEXT_STATE(ScopeState_TraceRequest)
}
else {
m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces);
- SET_NEXT_STATE(ScopeState_TraceRequest)
+ SET_NEXT_STATE(ScopeState_ChannelActiveStateUpdate)
}
EXEC_NEXT_STATE_IMMEDIATELY
}
@@ -816,6 +961,168 @@ void ScopePart::mainEventLoop() {
}
}
}
+ else if (m_commHandlerState == ScopeState_ChannelActiveStateUpdate) {
+ if (m_channelActiveSet[m_currentOpChannel]) {
+ // Set channel active, step 1
+ ds << TQString("SETCHANNELACTIVE");
+ ds << m_currentOpChannel;
+ TQ_INT16 active = (m_channelActive[m_currentOpChannel])?1:0;
+ ds << active;
+ m_socket->writeEndOfFrame();
+
+ m_lastChangesRequireFullUpdate = true;
+ m_channelActiveSet[m_currentOpChannel] = false;
+ SET_NEXT_STATE(ScopeState_ChannelActiveStateUpdate+1)
+ }
+ else {
+ if (m_currentOpChannel < m_maxNumberOfTraces) {
+ m_currentOpChannel++;
+ SET_NEXT_STATE(ScopeState_ChannelActiveStateUpdate)
+ }
+ else {
+ m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces);
+ if (m_lastChangesRequireFullUpdate) {
+ SET_NEXT_STATE(ScopeState_TraceVoltsDivRequest)
+ }
+ else {
+ SET_NEXT_STATE(ScopeState_TraceVoltsDivUpdate)
+ }
+ }
+ }
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else if (m_commHandlerState == ScopeState_ChannelActiveStateUpdate+1) {
+ // Get response data
+ if (m_socket->canReadFrame()) {
+ PAT_WATCHDOG_TIMER
+ setTickerMessage(i18n("Updating [Set channel %1 activity status]").arg(m_currentOpChannel));
+
+ // Set channel active, step 2
+ TQString result;
+ ds >> result;
+ m_socket->clearFrameTail();
+
+ if (result == "ACK") {
+ m_currentOpChannel = getNextActiveChannel(m_currentOpChannel, m_channelActive, m_maxNumberOfTraces);
+ if (m_currentOpChannel > 0) {
+ SET_NEXT_STATE(ScopeState_ChannelActiveStateUpdate)
+ }
+ else {
+ m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces);
+ if (m_lastChangesRequireFullUpdate) {
+ SET_NEXT_STATE(ScopeState_TraceVoltsDivRequest)
+ }
+ else {
+ SET_NEXT_STATE(ScopeState_TraceVoltsDivUpdate)
+ }
+ }
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else {
+ COMMUNICATIONS_FAILED
+ }
+ }
+ else {
+ if (!m_updateTimeoutTimer->isActive()) {
+ UPDATEDISPLAY_TIMEOUT
+ }
+ }
+ }
+ else if (m_commHandlerState == ScopeState_TraceVoltsDivUpdate) {
+ if (m_voltsDivSet[m_currentOpChannel]) {
+ // Set volts per division, step 1
+ ds << TQString("SETVOLTSDIV");
+ ds << m_currentOpChannel;
+ ds << m_voltsDiv[m_currentOpChannel];
+ m_socket->writeEndOfFrame();
+
+ m_voltsDivSet[m_currentOpChannel] = false;
+ SET_NEXT_STATE(ScopeState_TraceVoltsDivUpdate+1)
+ }
+ else {
+ m_currentOpChannel = getNextActiveChannel(m_currentOpChannel, m_channelActive, m_maxNumberOfTraces);
+ if (m_currentOpChannel > 0) {
+ SET_NEXT_STATE(ScopeState_TraceVoltsDivUpdate)
+ }
+ else {
+ SET_NEXT_STATE(ScopeState_TriggerLevelUpdate)
+ }
+ }
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else if (m_commHandlerState == ScopeState_TraceVoltsDivUpdate+1) {
+ // Get response data
+ if (m_socket->canReadFrame()) {
+ PAT_WATCHDOG_TIMER
+ setTickerMessage(i18n("Updating [Set volts/div for channel %1]").arg(m_currentOpChannel));
+
+ // Set volts per division, step 2
+ TQString result;
+ ds >> result;
+ m_socket->clearFrameTail();
+
+ if (result == "ACK") {
+ m_currentOpChannel = getNextActiveChannel(m_currentOpChannel, m_channelActive, m_maxNumberOfTraces);
+ if (m_currentOpChannel > 0) {
+ SET_NEXT_STATE(ScopeState_TraceVoltsDivUpdate)
+ }
+ else {
+ SET_NEXT_STATE(ScopeState_TriggerLevelUpdate)
+ }
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else {
+ COMMUNICATIONS_FAILED
+ }
+ }
+ else {
+ if (!m_updateTimeoutTimer->isActive()) {
+ UPDATEDISPLAY_TIMEOUT
+ }
+ }
+ }
+ else if (m_commHandlerState == ScopeState_TriggerLevelUpdate) {
+ if (m_voltsDivSet[m_currentOpChannel]) {
+ // Set trigger level, step 1
+ ds << TQString("SETTRIGGERLEVEL");
+ ds << m_triggerLevel;
+ m_socket->writeEndOfFrame();
+
+ m_triggerLevelSet = false;
+ SET_NEXT_STATE(ScopeState_TriggerLevelUpdate+1)
+ }
+ else {
+ m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces);
+ SET_NEXT_STATE(ScopeState_TraceRequest)
+ }
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else if (m_commHandlerState == ScopeState_TriggerLevelUpdate+1) {
+ // Get response data
+ if (m_socket->canReadFrame()) {
+ PAT_WATCHDOG_TIMER
+ setTickerMessage(i18n("Updating [Set trigger level]"));
+
+ // Set trigger level, step 2
+ TQString result;
+ ds >> result;
+ m_socket->clearFrameTail();
+
+ if (result == "ACK") {
+ m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces);
+ SET_NEXT_STATE(ScopeState_TraceRequest)
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else {
+ COMMUNICATIONS_FAILED
+ }
+ }
+ else {
+ if (!m_updateTimeoutTimer->isActive()) {
+ UPDATEDISPLAY_TIMEOUT
+ }
+ }
+ }
else if (m_commHandlerState == ScopeState_ExternalCommandRequest) {
// Execute pending command
m_commHandlerMode = 2;
@@ -892,12 +1199,18 @@ void ScopePart::postProcessTrace() {
void ScopePart::startDAQ() {
stopTraceUpdate = false;
+ if (m_socket) m_socket->clearIncomingData();
EXEC_NEXT_STATE_IMMEDIATELY
}
void ScopePart::stopDAQ() {
if (m_commHandlerMode < 2) {
stopTraceUpdate = true;
+ for (int i=0; i<=MAXTRACES;i++) {
+ m_channelActiveSet[i] = false;
+ m_voltsDivSet[i] = false;
+ }
+ m_triggerLevelSet = false;
m_commHandlerMode = 1;
m_commHandlerCommandState = 3;
mainEventLoop();
@@ -976,11 +1289,9 @@ void ScopePart::recallWaveforms() {
m_triggerLevel = 0;
updateGraticule();
postProcessTrace();
- // HACK
- // Force resize of parent frame
- emit(resizeToHintRequested());
m_traceWidget->repaint(false);
m_base->traceZoomWidget->repaint(false);
+ updateTraceControlWidgets();
}
else {
KMessageBox::error(0, i18n("<qt>The selected waveform file version does not match this client</qt>"), i18n("Invalid File"));
@@ -1010,26 +1321,28 @@ void ScopePart::updateGraticule() {
m_base->traceZoomWidget->setNumberOfHorizontalDivisions(m_hdivs);
m_base->traceZoomWidget->setNumberOfVerticalDivisions(m_vdivs);
- if ((m_triggerChannel > 0) && (m_triggerChannel <= m_maxNumberOfTraces)) {
- TraceNumberList activeTraces;
- activeTraces.append(m_triggerChannel-1);
- m_traceWidget->setCursorActiveTraceList(0, activeTraces);
- m_traceWidget->setCursorPosition(0, (50.0-((m_triggerLevel*100.0)/(m_voltsDiv[m_triggerChannel]*m_vdivs))));
- m_traceWidget->setCursorEnabled(0, true);
- }
- else {
- m_traceWidget->setCursorEnabled(0, false);
+ if (!m_triggerLevelSet) {
+ if ((m_triggerChannel > 0) && (m_triggerChannel <= m_maxNumberOfTraces)) {
+ TraceNumberList activeTraces;
+ activeTraces.append(m_triggerChannel-1);
+ m_traceWidget->setCursorActiveTraceList(0, activeTraces);
+ m_traceWidget->setCursorPosition(0, (50.0-((m_triggerLevel*100.0)/(m_voltsDiv[m_triggerChannel]*m_vdivs))));
+ m_traceWidget->setCursorEnabled(0, true);
+ }
+ else {
+ m_traceWidget->setCursorEnabled(0, false);
+ }
}
- m_traceWidget->setTraceColor(0, TQColor(255, 255, 255));
- m_traceWidget->setTraceColor(1, TQColor(128, 255, 128));
- m_traceWidget->setTraceColor(2, TQColor(255, 255, 128));
- m_traceWidget->setTraceColor(3, TQColor(128, 128, 255));
+ if (m_maxNumberOfTraces > 0) m_traceWidget->setTraceColor(0, TQColor(255, 255, 255));
+ if (m_maxNumberOfTraces > 1) m_traceWidget->setTraceColor(1, TQColor(128, 255, 128));
+ if (m_maxNumberOfTraces > 2) m_traceWidget->setTraceColor(2, TQColor(255, 255, 128));
+ if (m_maxNumberOfTraces > 3) m_traceWidget->setTraceColor(3, TQColor(128, 128, 255));
- m_base->traceZoomWidget->setTraceColor(0, TQColor(255, 255, 255));
- m_base->traceZoomWidget->setTraceColor(1, TQColor(128, 255, 128));
- m_base->traceZoomWidget->setTraceColor(2, TQColor(255, 255, 128));
- m_base->traceZoomWidget->setTraceColor(3, TQColor(128, 128, 255));
+ if (m_maxNumberOfTraces > 0) m_base->traceZoomWidget->setTraceColor(0, TQColor(255, 255, 255));
+ if (m_maxNumberOfTraces > 1) m_base->traceZoomWidget->setTraceColor(1, TQColor(128, 255, 128));
+ if (m_maxNumberOfTraces > 2) m_base->traceZoomWidget->setTraceColor(2, TQColor(255, 255, 128));
+ if (m_maxNumberOfTraces > 3) m_base->traceZoomWidget->setTraceColor(3, TQColor(128, 128, 255));
for (int traceno=1; traceno<=m_maxNumberOfTraces; traceno++) {
m_traceWidget->setTraceEnabled(traceno-1, m_channelActive[traceno]);
@@ -1046,22 +1359,92 @@ void ScopePart::updateGraticule() {
m_base->traceZoomWidget->setNumberOfSamples(traceno-1, m_samplesInTrace[traceno]);
m_traceWidget->setDisplayLimits(traceno-1, TQRectF(0.0, (m_voltsDiv[traceno]*m_vdivs)/2.0, (m_secsDiv[traceno]*m_hdivs), (m_voltsDiv[traceno]*m_vdivs)/-2.0));
+ if (m_traceControlWidgetList[traceno-1]) {
+ m_traceControlWidgetList[traceno-1]->setSelectedVoltsPerDiv(m_voltsDiv[traceno]);
+ m_traceControlWidgetList[traceno-1]->setTraceEnabled(m_channelActive[traceno]);
+ }
}
updateZoomWidgetLimits(m_traceWidget->zoomBox());
+}
+
+void ScopePart::updateTraceControlWidgets() {
+ // Add or remove trace control widgets as needed...
+ int i;
+ for (i=0; i<m_maxNumberOfTraces;i++) {
+ if (!m_traceControlWidgetList[i]) {
+ m_traceControlWidgetList[i] = new TraceControlWidget(m_base->traceControlLayoutWidget);
+ connect(m_traceControlWidgetList[i], SIGNAL(enableChanged(bool)), this, SLOT(traceControlEnableChanged(bool)));
+ connect(m_traceControlWidgetList[i], SIGNAL(voltsPerDivChanged(double)), this, SLOT(traceControlVDivChanged(double)));
+ m_traceControlWidgetGrid->addMultiCellWidget(m_traceControlWidgetList[i], i, i, 0, 0);
+ m_traceControlWidgetList[i]->setTraceName(i18n("Channel %1").arg(i+1));
+ m_traceControlWidgetList[i]->show();
+ }
+ }
+ for (i=m_maxNumberOfTraces; i<MAXTRACES;i++) {
+ if (m_traceControlWidgetList[i]) {
+ m_traceControlWidgetGrid->remove(m_traceControlWidgetList[i]);
+ delete m_traceControlWidgetList[i];
+ }
+ }
+}
+
+void ScopePart::traceControlEnableChanged(bool enabled) {
+ int i;
+ int channel = -1;
+ const TraceControlWidget* widget = dynamic_cast<const TraceControlWidget*>(sender());
+ if (widget) {
+ for (i=0; i<MAXTRACES;i++) {
+ if (m_traceControlWidgetList[i] == widget) {
+ channel = i;
+ break;
+ }
+ }
+ if ((channel >= 0) && (channel <=MAXTRACES)) {
+ m_channelActive[channel+1] = enabled;
+ m_channelActiveSet[channel+1] = true;
+ }
+ }
+
+ updateGraticule();
+ m_traceWidget->repaint(false);
+ m_base->traceZoomWidget->repaint(false);
+ updateTraceControlWidgets();
+}
+
+void ScopePart::traceControlVDivChanged(double vdiv) {
+ int i;
+ int channel = -1;
+ const TraceControlWidget* widget = dynamic_cast<const TraceControlWidget*>(sender());
+ if (widget) {
+ for (i=0; i<MAXTRACES;i++) {
+ if (m_traceControlWidgetList[i] == widget) {
+ channel = i;
+ break;
+ }
+ }
+ if ((channel >= 0) && (channel <=MAXTRACES)) {
+ m_voltsDiv[channel+1] = vdiv;
+ m_voltsDivSet[channel+1] = true;
+ }
+ }
-// // Also update controls
-// m_base->saRefLevel->blockSignals(true);
-// m_base->saRefLevel->setFloatValue(m_voltsDiv);
-// m_base->saRefLevel->blockSignals(false);
+ updateGraticule();
+ m_traceWidget->repaint(false);
+ m_base->traceZoomWidget->repaint(false);
+ updateTraceControlWidgets();
}
-void ScopePart::saRefLevelChanged(double newval) {
-// if (m_commHandlerMode < 2) {
-// m_voltsDiv = newval;
-// m_commHandlerMode = 1;
-// m_commHandlerCommandState = 1;
-// mainEventLoop();
-// }
+void ScopePart::cursorLevelChanged(uint cursor, double level) {
+ if (cursor == 0) {
+ // Trigger level changed
+ m_triggerLevel = (((50.0-level)*(m_voltsDiv[m_triggerChannel]*m_vdivs))/100.0);
+ m_triggerLevelSet = true;
+
+ updateGraticule();
+ m_traceWidget->repaint(false);
+ m_base->traceZoomWidget->repaint(false);
+ updateTraceControlWidgets();
+ }
}
KAboutData* ScopePart::createAboutData() {
diff --git a/clients/tde/src/part/scope/part.h b/clients/tde/src/part/scope/part.h
index 1e342da..24e2c84 100644
--- a/clients/tde/src/part/scope/part.h
+++ b/clients/tde/src/part/scope/part.h
@@ -20,10 +20,44 @@ class TQSocket;
class TQTimer;
class TQMutex;
class TQRectF;
+class TQGridLayout;
+class TQCheckBox;
+class TQGroupBox;
class ScopeBase;
namespace RemoteLab
{
+ class TraceControlWidget : public TQWidget
+ {
+ Q_OBJECT
+
+ public:
+ TraceControlWidget(TQWidget *parent=0, const char *name=0);
+ ~TraceControlWidget();
+
+ public:
+ void setVoltsPerDivList(TQDoubleList list);
+ void setSelectedVoltsPerDiv(double vdiv);
+ void setTraceEnabled(bool enabled);
+ void setTraceName(TQString name);
+
+ signals:
+ void enableChanged(bool enabled);
+ void voltsPerDivChanged(double vdiv);
+
+ private slots:
+ void enableClicked();
+ void vdivChanged(int index);
+
+ private:
+ TQGroupBox* m_groupBox;
+ TQGridLayout* m_primaryLayout;
+ TQComboBox* m_voltsDivComboBox;
+ TQCheckBox* m_channelEnabledCheckBox;
+
+ TQDoubleList m_voltsDivList;
+ };
+
class ScopePart : public KParts::RemoteInstrumentPart
{
Q_OBJECT
@@ -51,13 +85,17 @@ namespace RemoteLab
void mainEventLoop();
void startDAQ();
void stopDAQ();
+ void updateTraceControlWidgets();
+ void traceControlEnableChanged(bool enabled);
+ void traceControlVDivChanged(double vdiv);
+ void cursorLevelChanged(uint cursor, double level);
void saveWaveforms();
void recallWaveforms();
virtual void postProcessTrace();
- void saRefLevelChanged(double);
private:
TraceWidget* m_traceWidget;
+ TQGridLayout* m_traceControlWidgetGrid;
int m_commHandlerState;
int m_commHandlerMode;
int m_commHandlerCommandState;
@@ -77,6 +115,11 @@ namespace RemoteLab
bool m_channelActive[MAXTRACES+1];
double m_voltsDiv[MAXTRACES+1];
double m_secsDiv[MAXTRACES+1];
+ TraceControlWidget* m_traceControlWidgetList[MAXTRACES];
+ bool m_triggerLevelSet;
+ bool m_voltsDivSet[MAXTRACES+1];
+ bool m_channelActiveSet[MAXTRACES+1];
+ bool m_lastChangesRequireFullUpdate;
ScopeBase* m_base;
TQMutex* m_instrumentMutex;
bool stopTraceUpdate;