Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ngscopeclient/scopehal-apps
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2cc76ddb35d1
Choose a base ref
...
head repository: ngscopeclient/scopehal-apps
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4f931accd4f2
Choose a head ref
  • 1 commit
  • 6 files changed
  • 1 contributor

Commits on Apr 25, 2021

  1. Copy the full SHA
    4f931ac View commit details
Showing with 137 additions and 55 deletions.
  1. +1 −1 lib
  2. +79 −34 src/glscopeclient/OscilloscopeWindow.cpp
  3. +2 −1 src/glscopeclient/OscilloscopeWindow.h
  4. +39 −10 src/glscopeclient/ScopeApp.cpp
  5. +7 −2 src/glscopeclient/ScopeApp.h
  6. +9 −7 src/glscopeclient/main.cpp
2 changes: 1 addition & 1 deletion lib
113 changes: 79 additions & 34 deletions src/glscopeclient/OscilloscopeWindow.cpp
Original file line number Diff line number Diff line change
@@ -672,7 +672,7 @@ void OscilloscopeWindow::OnFileImport()
auto filterName = dlg.get_filter()->get_name();
if(filterName == "Comma Separated Value (*.csv)")
{
DoImportCSV(dlg.get_filename());
ImportCSVToNewSession(dlg.get_filename());
}
else if(filterName == "Agilent/Keysight/Rigol Binary Capture (*.bin)")
{
@@ -681,46 +681,43 @@ void OscilloscopeWindow::OnFileImport()
}

/**
@brief Import a CSV file
@brief Import a CSV file and create a new session around it
*/
void OscilloscopeWindow::DoImportCSV(const string& filename)
void OscilloscopeWindow::ImportCSVToNewSession(const string& filename)
{
LogDebug("Importing CSV file \"%s\"\n", filename.c_str());
{
LogIndenter li;
LogDebug("Importing CSV file \"%s\" to new session\n", filename.c_str());

//Setup
CloseSession();
m_currentFileName = filename;
m_loadInProgress = true;
//Setup
CloseSession();
m_currentFileName = filename;
m_loadInProgress = true;

//Clear performance counters
m_totalWaveforms = 0;
m_lastWaveformTimes.clear();
//Clear performance counters
m_totalWaveforms = 0;
m_lastWaveformTimes.clear();

//Create the mock scope
auto scope = new MockOscilloscope("CSV Import", "Generic", "12345");
scope->m_nickname = "import";
g_app->m_scopes.push_back(scope);
m_scopes.push_back(scope);
//Create the mock scope
auto scope = new MockOscilloscope("CSV Import", "Generic", "12345");
scope->m_nickname = "import";
g_app->m_scopes.push_back(scope);
m_scopes.push_back(scope);

//Set up history for it
auto hist = new HistoryWindow(this, scope);
hist->hide();
m_historyWindows[scope] = hist;
//Set up history for it
auto hist = new HistoryWindow(this, scope);
hist->hide();
m_historyWindows[scope] = hist;

//Load the waveform
if(!scope->LoadCSV(filename))
{
Gtk::MessageDialog dlg(
*this,
"CSV import failed",
false,
Gtk::MESSAGE_ERROR,
Gtk::BUTTONS_OK,
true);
dlg.run();
}
//Load the waveform
if(!scope->LoadCSV(filename))
{
Gtk::MessageDialog dlg(
*this,
"CSV import failed",
false,
Gtk::MESSAGE_ERROR,
Gtk::BUTTONS_OK,
true);
dlg.run();
}

//Add the top level splitter right before the status bar
@@ -742,6 +739,54 @@ void OscilloscopeWindow::DoImportCSV(const string& filename)
OnAllWaveformsUpdated();
}

/**
@brief Import a CSV file into the existing session
The CSV must have the same configuration (number of channels, etc) as the originally loaded one.
TODO: support adding a CSV to an existing session by creating a new mock scope if we don't have one?
*/
void OscilloscopeWindow::ImportCSVToExistingSession(const string& filename)
{
LogDebug("Importing CSV file \"%s\" to current session\n", filename.c_str());

auto scope = dynamic_cast<MockOscilloscope*>(m_scopes[0]);
if(scope == NULL)
{
LogError("not a mock scope, can't import a CSV into it\n");
return;
}

m_lastWaveformTimes.push_back(GetTime());
while(m_lastWaveformTimes.size() > 10)
m_lastWaveformTimes.erase(m_lastWaveformTimes.begin());

//Detach the old waveform data so we don't destroy it
for(size_t i=0; i<scope->GetChannelCount(); i++)
{
auto chan = scope->GetChannel(i);
for(size_t j=0; j<chan->GetStreamCount(); j++)
chan->Detach(j);
}

if(!scope->LoadCSV(filename))
{
Gtk::MessageDialog dlg(
*this,
"CSV import failed",
false,
Gtk::MESSAGE_ERROR,
Gtk::BUTTONS_OK,
true);
dlg.run();
return;
}

//Process the new data
m_historyWindows[scope]->OnWaveformDataReady();
OnAllWaveformsUpdated();
}

/**
@brief Import a Agilent/Keysight BIN file
*/
3 changes: 2 additions & 1 deletion src/glscopeclient/OscilloscopeWindow.h
Original file line number Diff line number Diff line change
@@ -239,7 +239,8 @@ class OscilloscopeWindow : public Gtk::Window
void OnFileOpen();
void DoFileOpen(const std::string& filename, bool loadLayout = true, bool loadWaveform = true, bool reconnect = true);
void OnFileImport();
void DoImportCSV(const std::string& filename);
void ImportCSVToNewSession(const std::string& filename);
void ImportCSVToExistingSession(const std::string& filename);
void DoImportBIN(const std::string& filename);
void LoadInstruments(const YAML::Node& node, bool reconnect, IDTable& table);
void LoadDecodes(const YAML::Node& node, IDTable& table);
49 changes: 39 additions & 10 deletions src/glscopeclient/ScopeApp.cpp
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
* *
* glscopeclient *
* *
* Copyright (c) 2012-2020 Andrew D. Zonenberg *
* Copyright (c) 2012-2021 Andrew D. Zonenberg *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
@@ -43,26 +43,55 @@ ScopeApp::~ScopeApp()
ShutDownSession();
}

void ScopeApp::run(string fileToLoad, bool reconnect, bool nodata, bool retrigger, bool nodigital, bool nospectrum)
void ScopeApp::run(
vector<string> filesToLoad,
bool reconnect,
bool nodata,
bool retrigger,
bool nodigital,
bool nospectrum)
{
register_application();

m_window = new OscilloscopeWindow(m_scopes, nodigital, nospectrum);
add_window(*m_window);

//Handle file loads specified on the command line
if(!fileToLoad.empty())
bool first = true;
for(auto f : filesToLoad)
{
//Guess files by extension
if(fileToLoad.find(".csv") != string::npos)
m_window->DoImportCSV(fileToLoad);
//Ignore blank files (should never happen)
if(f.empty())
continue;

//Can load multiple CSVs
if(f.find(".csv") != string::npos)
{
if(first)
{
m_window->ImportCSVToNewSession(f);
first = false;
}
else
m_window->ImportCSVToExistingSession(f);
}

//Can only load one bin for now
else if (f.find(".bin") != string::npos)
{
m_window->DoImportBIN(f);
break;
}

else if (fileToLoad.find(".bin") != string::npos)
m_window->DoImportBIN(fileToLoad);
//Can only load one scopesession
else if (f.find(".scopesession") != string::npos)
{
m_window->DoFileOpen(f, true, !nodata, reconnect);
break;
}

//Assume anything else is a scopesession
else
m_window->DoFileOpen(fileToLoad, true, !nodata, reconnect);
LogError("Unrecognized file extension, ignoring %s\n", f.c_str());
}

m_window->present();
9 changes: 7 additions & 2 deletions src/glscopeclient/ScopeApp.h
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
* *
* glscopeclient *
* *
* Copyright (c) 2012-2020 Andrew D. Zonenberg *
* Copyright (c) 2012-2021 Andrew D. Zonenberg *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
@@ -52,7 +52,12 @@ class ScopeApp : public Gtk::Application
std::vector<Oscilloscope*> m_scopes;

virtual void run(
std::string fileToLoad, bool reconnect, bool nodata, bool retrigger, bool nodigital, bool nospectrum);
std::vector<std::string> filesToLoad,
bool reconnect,
bool nodata,
bool retrigger,
bool nodigital,
bool nospectrum);

void DispatchPendingEvents();

16 changes: 9 additions & 7 deletions src/glscopeclient/main.cpp
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
* *
* glscopeclient *
* *
* Copyright (c) 2012-2020 Andrew D. Zonenberg *
* Copyright (c) 2012-2021 Andrew D. Zonenberg *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
@@ -95,6 +95,8 @@ void help()
"\n"
" [filename|scope]:\n"
" filename : path to a .scopesession to load on startup\n"
" May also be a CSV or other supported file to be imported.\n"
" Some file formats (like CSV) allow multiple files to be specified, separated by spaces\n"
" scope : <scope name>:<scope driver>:<transport protocol>[:<transport arguments]\n"
"\n"
" Examples:\n"
@@ -112,7 +114,7 @@ int main(int argc, char* argv[])

//Parse command-line arguments
vector<string> scopes;
string fileToLoad;
vector<string> filesToLoad;
bool reconnect = false;
bool nodata = false;
bool retrigger = false;
@@ -157,7 +159,7 @@ int main(int argc, char* argv[])
return 1;
}

//Not a flag. Either a connection string or a save file name.
//Not a flag. Either a connection string or a file name.
else
{
//If there's a colon after the first few characters, it's a connection string
@@ -166,9 +168,9 @@ int main(int argc, char* argv[])
if( (colon != string::npos) && (colon > 1) )
scopes.push_back(s);

//Otherwise assume it's a save file
//Otherwise assume it's a file
else
fileToLoad = s;
filesToLoad.push_back(s);
}
}

@@ -252,7 +254,7 @@ int main(int argc, char* argv[])

//If there are no scopes and we're not loading a file, show the dialog to connect.
//TODO: support multi-scope connection
if(scopes.empty() && fileToLoad.empty())
if(scopes.empty() && filesToLoad.empty())
{
InstrumentConnectionDialog dlg;

@@ -328,7 +330,7 @@ int main(int argc, char* argv[])
g_app->m_scopes.push_back(scope);
}

g_app->run(fileToLoad, reconnect, nodata, retrigger, nodigital, nospectrum);
g_app->run(filesToLoad, reconnect, nodata, retrigger, nodigital, nospectrum);

//Global cleanup
ScopehalStaticCleanup();