Skip to content

Commit

Permalink
feat: Service list can be exported to CSV (Issue #192), number of ser…
Browse files Browse the repository at this point in the history
…vices is printed to log after loading the service list
  • Loading branch information
KejPi committed Feb 16, 2025
1 parent 0310206 commit 4b82aa4
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 3 deletions.
26 changes: 23 additions & 3 deletions gui/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,9 @@ MainWindow::MainWindow(const QString &iniFilename, const QString &iniSlFilename,
m_clearServiceListAction = new QAction(tr("Clear service list"), this);
connect(m_clearServiceListAction, &QAction::triggered, this, &MainWindow::clearServiceList);

m_exportServiceListAction = new QAction(tr("Export service list..."), this);
connect(m_exportServiceListAction, &QAction::triggered, this, &MainWindow::exportServiceList);

m_bandScanAction = new QAction(tr("Band scan..."), this);
connect(m_bandScanAction, &QAction::triggered, this, &MainWindow::bandScan);

Expand Down Expand Up @@ -459,6 +462,7 @@ MainWindow::MainWindow(const QString &iniFilename, const QString &iniSlFilename,
m_menu->addSeparator();
m_menu->addAction(m_setupAction);
m_menu->addAction(m_bandScanAction);
m_menu->addAction(m_exportServiceListAction);
m_menu->addAction(m_clearServiceListAction);
m_menu->addSeparator();
m_menu->addAction(m_epgAction);
Expand Down Expand Up @@ -3003,13 +3007,14 @@ void MainWindow::loadSettings()
m_audioRecScheduleModel->save(m_audioRecScheduleFilename);
}
else
{ // new settings with dedicated JSON for service lis and audio recording schedule
{ // new settings with dedicated JSON for service list and audio recording schedule
// it will be loaded when device is initialized (this reduces duplication of service list information in log)

// load servicelist
m_serviceList->load(m_serviceListFilename);
// m_serviceList->load(m_serviceListFilename);

// load recording schedule
m_audioRecScheduleModel->load(m_audioRecScheduleFilename);
// m_audioRecScheduleModel->load(m_audioRecScheduleFilename);
}

m_audioVolume = settings->value("volume", 100).toInt();
Expand Down Expand Up @@ -3043,6 +3048,7 @@ void MainWindow::loadSettings()
m_settings->updateCheckEna = settings->value("updateCheckEna", true).toBool();
m_settings->updateCheckTime = settings->value("updateCheckTime", QDateTime::currentDateTime().addDays(-1)).value<QDateTime>();
m_settings->uploadEnsembleInfo = settings->value("uploadEnsembleInfoEna", true).toBool();
m_settings->serviceListExportPath = settings->value("serviceListExportPath", QDir::homePath()).toString();
#if (HAVE_PORTAUDIO)
if (nullptr != dynamic_cast<AudioOutputPa *>(m_audioOutput))
{
Expand Down Expand Up @@ -3326,6 +3332,7 @@ void MainWindow::saveSettings()
settings->setValue("updateCheckTime", m_settings->updateCheckTime);
settings->setValue("uploadEnsembleInfoEna", m_settings->uploadEnsembleInfo);
settings->setValue("showTrayIcon", m_settings->trayIconEna);
settings->setValue("serviceListExportPath", m_settings->serviceListExportPath);

settings->setValue("AudioRecording/folder", m_settings->audioRec.folder);
settings->setValue("AudioRecording/captureOutput", m_settings->audioRec.captureOutput);
Expand Down Expand Up @@ -3896,6 +3903,7 @@ void MainWindow::setExpertMode(bool ena)
m_tiiAction->setVisible(ena);
m_scanningToolAction->setVisible(ena);
m_signalDialogAction->setVisible(ena);
m_exportServiceListAction->setVisible(ena);

// set tab order
if (ena)
Expand Down Expand Up @@ -3974,6 +3982,18 @@ void MainWindow::stop()
}
}

void MainWindow::exportServiceList()
{
QString f =
QString("%1/%2.csv").arg(m_settings->serviceListExportPath, "servicelist_" + QDateTime::currentDateTime().toString("yyyy-MM-dd_hhmmss"));
QString fileName = QFileDialog::getSaveFileName(this, tr("Export CSV file"), QDir::toNativeSeparators(f), tr("CSV Files") + " (*.csv)");
if (!fileName.isEmpty())
{
m_settings->serviceListExportPath = QFileInfo(fileName).path(); // store path for next time
m_serviceList->exportCSV(fileName);
}
}

void MainWindow::clearServiceList()
{
stop();
Expand Down
2 changes: 2 additions & 0 deletions gui/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ class MainWindow : public QMainWindow
QMenu *m_audioOutputMenu;

QAction *m_setupAction;
QAction *m_exportServiceListAction;
QAction *m_clearServiceListAction;
QAction *m_bandScanAction;
QAction *m_ensembleInfoAction;
Expand Down Expand Up @@ -268,6 +269,7 @@ class MainWindow : public QMainWindow
void bandScan();
void audioRecordingToggle();
void setAudioRecordingUI();
void exportServiceList();
void clearServiceList();
void clearEnsembleInformationLabels();
void clearServiceInformationLabels();
Expand Down
39 changes: 39 additions & 0 deletions gui/servicelist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,9 @@ void ServiceList::load(const QString &filename)
RadioControlServiceComponent item;
RadioControlEnsemble ens;

int numUniqueServices = 0;
int numServices = 0;

// doc is not null and is array
QVariantList list = doc.toVariant().toList();
for (auto it = list.cbegin(); it != list.cend(); ++it)
Expand Down Expand Up @@ -359,8 +362,11 @@ void ServiceList::load(const QString &filename)
ens.labelShort = ensMap.value("ShortLabel").toString();
// float snr = settings.value("SNR").toFloat();
addService(ens, item, fav, currentEns);
numServices += 1;
}
numUniqueServices += 1;
}
qCInfo(serviceList, "Service list loaded: number of services in all ensembles %d, unique services %d", numServices, numUniqueServices);
}

void ServiceList::loadFromSettings(QSettings *settings)
Expand Down Expand Up @@ -418,6 +424,39 @@ void ServiceList::loadFromSettings(QSettings *settings)
settings->endArray();
}

void ServiceList::exportCSV(const QString &filename)
{
QFile file(filename);
if (!file.open(QIODevice::WriteOnly))
{
qCWarning(serviceList) << "Failed to export CSV file.";
return;
}

QTextStream out(&file);
// header
out << tr("Service name;Short label;SID;SCIdS;Number of ensembles") << Qt::endl;
// export in alphabetical order
QStringList labelList;
for (auto &s : m_serviceList)
{
labelList.append(s->label());
}
labelList.sort();

for (const auto &label : labelList)
{
auto it =
std::find_if(m_serviceList.cbegin(), m_serviceList.cend(), [&label](const ServiceListItem *item) { return item->label() == label; });
if (it != m_serviceList.cend())
{
out << it.value()->label() << ";" << it.value()->shortLabel() << ";" << QString::number(it.value()->SId().value(), 16).toUpper() << ";"
<< it.value()->SCIdS() << ";" << it.value()->numEnsembles() << Qt::endl;
}
}
file.close();
}

// this marks all services as obsolete
void ServiceList::beginEnsembleUpdate(const RadioControlEnsemble &e)
{
Expand Down
1 change: 1 addition & 0 deletions gui/servicelist.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class ServiceList : public QObject
void save(const QString &filename);
void load(const QString &filename);
void loadFromSettings(QSettings *settings);
void exportCSV(const QString &filename);

void beginEnsembleUpdate(const RadioControlEnsemble &e);
void endEnsembleUpdate(const RadioControlEnsemble &e);
Expand Down
1 change: 1 addition & 0 deletions gui/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ class Settings
bool updateCheckEna;
QDateTime updateCheckTime;
bool uploadEnsembleInfo;
QString serviceListExportPath;

// audio recording settings
struct AudioRec
Expand Down

0 comments on commit 4b82aa4

Please sign in to comment.