/*
Copyright © 2018 Hasan Yavuz Özderya
This file is part of serialplot.
serialplot is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
serialplot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with serialplot. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include "recordpanel.h"
#include "ui_recordpanel.h"
#include "setting_defines.h"
RecordPanel::RecordPanel(Stream* stream, QWidget *parent) :
QWidget(parent),
ui(new Ui::RecordPanel),
recordToolBar(tr("Record Toolbar")),
recordAction(QIcon::fromTheme("media-record"), tr("Record"), this),
recorder(this)
{
overwriteSelected = false;
_stream = stream;
ui->setupUi(this);
recordToolBar.setObjectName("tbRecord");
recordAction.setCheckable(true);
recordToolBar.addAction(&recordAction);
ui->pbRecord->setDefaultAction(&recordAction);
connect(ui->pbBrowse, &QPushButton::clicked,
this, &RecordPanel::selectFile);
connect(&recordAction, &QAction::triggered,
this, &RecordPanel::onRecord);
connect(ui->cbRecordPaused, SIGNAL(toggled(bool)),
this, SIGNAL(recordPausedChanged(bool)));
connect(ui->cbDisableBuffering, &QCheckBox::toggled,
[this](bool enabled)
{
recorder.disableBuffering = enabled;
});
connect(ui->cbWindowsLE, &QCheckBox::toggled,
[this](bool enabled)
{
recorder.windowsLE = enabled;
});
connect(&recordAction, &QAction::toggled, ui->cbWindowsLE, &QWidget::setDisabled);
connect(&recordAction, &QAction::toggled, ui->cbTimestamp, &QWidget::setDisabled);
connect(&recordAction, &QAction::toggled, ui->leSeparator, &QWidget::setDisabled);
connect(&recordAction, &QAction::toggled, ui->pbBrowse, &QWidget::setDisabled);
}
RecordPanel::~RecordPanel()
{
delete ui;
}
QToolBar* RecordPanel::toolbar()
{
return &recordToolBar;
}
bool RecordPanel::recordPaused()
{
return ui->cbRecordPaused->isChecked();
}
bool RecordPanel::selectFile()
{
QString fileName = QFileDialog::getSaveFileName(
parentWidget(), tr("Select recording file"));
if (fileName.isEmpty())
{
return false;
}
else
{
selectedFile = fileName;
ui->lbFileName->setText(selectedFile);
overwriteSelected = QFile::exists(fileName);
return true;
}
}
void RecordPanel::onRecord(bool start)
{
if (!start)
{
stopRecording();
return;
}
bool canceled = false;
if (ui->leSeparator->text().isEmpty())
{
QMessageBox::critical(this, "Error",
"Column separator cannot be empty! Please select a separator.");
ui->leSeparator->setFocus(Qt::OtherFocusReason);
canceled = true;
}
// check file name
if (!canceled && selectedFile.isEmpty() && !selectFile())
{
canceled = true;
}
if (!canceled && !overwriteSelected && QFile::exists(selectedFile))
{
if (ui->cbAutoIncrement->isChecked())
{
// TODO: should we increment even if user selected to replace?
canceled = !incrementFileName();
}
else
{
canceled = !confirmOverwrite(selectedFile);
}
}
if (canceled)
{
recordAction.setChecked(false);
}
else
{
overwriteSelected = false;
startRecording();
}
}
bool RecordPanel::incrementFileName(void)
{
QFileInfo fileInfo(selectedFile);
QString base = fileInfo.completeBaseName();
QRegularExpression regex("(.*?)(\\d+)(?!.*\\d)(.*)");
auto match = regex.match(base);
if (match.hasMatch())
{
bool ok;
int fileNum = match.captured(2).toInt(&ok);
base = match.captured(1) + QString::number(fileNum + 1) + match.captured(3);
}
else
{
base += "_1";
}
QString suffix = fileInfo.suffix();;
if (!suffix.isEmpty())
{
suffix = "." + suffix;
}
QString autoFileName = fileInfo.path() + "/" + base + suffix;
// check if auto generated file name exists, ask user another name
if (QFile::exists(autoFileName))
{
if (!confirmOverwrite(autoFileName))
{
return false;
}
}
else
{
selectedFile = autoFileName;
}
ui->lbFileName->setText(selectedFile);
return true;
}
bool RecordPanel::confirmOverwrite(QString fileName)
{
// prepare message box
QMessageBox mb(parentWidget());
mb.setWindowTitle(tr("File Already Exists"));
mb.setIcon(QMessageBox::Warning);
mb.setText(tr("File (%1) already exists. How to continue?").arg(fileName));
auto bCancel = mb.addButton(QMessageBox::Cancel);
auto bOverwrite = mb.addButton(tr("Overwrite"), QMessageBox::DestructiveRole);
mb.addButton(tr("Select Another File"), QMessageBox::YesRole);
mb.setEscapeButton(bCancel);
// show message box
mb.exec();
if (mb.clickedButton() == bCancel)
{
return false;
}
else if (mb.clickedButton() == bOverwrite)
{
selectedFile = fileName;
return true;
}
else // select button
{
return selectFile();
}
}
void RecordPanel::startRecording(void)
{
QStringList channelNames;
if (ui->cbHeader->isChecked())
{
channelNames = _stream->infoModel()->channelNames();
}
if (recorder.startRecording(selectedFile, getSeparator(),
channelNames, ui->cbTimestamp->isChecked()))
{
_stream->connectFollower(&recorder);
}
}
void RecordPanel::stopRecording(void)
{
recorder.stopRecording();
_stream->disconnectFollower(&recorder);
}
void RecordPanel::onPortClose()
{
if (recordAction.isChecked() && ui->cbStopOnClose->isChecked())
{
stopRecording();
recordAction.setChecked(false);
}
}
QString RecordPanel::getSeparator() const
{
QString sep = ui->leSeparator->text();
sep.replace("\\t", "\t");
return sep;
}
void RecordPanel::saveSettings(QSettings* settings)
{
settings->beginGroup(SettingGroup_Record);
settings->setValue(SG_Record_AutoIncrement, ui->cbAutoIncrement->isChecked());
settings->setValue(SG_Record_RecordPaused, ui->cbRecordPaused->isChecked());
settings->setValue(SG_Record_StopOnClose, ui->cbStopOnClose->isChecked());
settings->setValue(SG_Record_Header, ui->cbHeader->isChecked());
settings->setValue(SG_Record_DisableBuffering, ui->cbDisableBuffering->isChecked());
settings->setValue(SG_Record_Timestamp, ui->cbTimestamp->isChecked());
settings->setValue(SG_Record_Separator, ui->leSeparator->text());
settings->endGroup();
}
void RecordPanel::loadSettings(QSettings* settings)
{
settings->beginGroup(SettingGroup_Record);
ui->cbAutoIncrement->setChecked(
settings->value(SG_Record_AutoIncrement, ui->cbAutoIncrement->isChecked()).toBool());
ui->cbRecordPaused->setChecked(
settings->value(SG_Record_RecordPaused, ui->cbRecordPaused->isChecked()).toBool());
ui->cbStopOnClose->setChecked(
settings->value(SG_Record_StopOnClose, ui->cbStopOnClose->isChecked()).toBool());
ui->cbHeader->setChecked(
settings->value(SG_Record_Header, ui->cbHeader->isChecked()).toBool());
ui->cbDisableBuffering->setChecked(
settings->value(SG_Record_DisableBuffering, ui->cbDisableBuffering->isChecked()).toBool());
ui->cbTimestamp->setChecked(
settings->value(SG_Record_Timestamp, ui->cbTimestamp->isChecked()).toBool());
ui->leSeparator->setText(settings->value(SG_Record_Separator, ui->leSeparator->text()).toString());
settings->endGroup();
}