Changeset - 58fcfc14522e
[Not reviewed]
settings
0 6 0
Hasan Yavuz ÖZDERYA - 9 years ago 2016-09-07 18:00:24
hy@ozderya.net
save/load commands
6 files changed with 140 insertions and 18 deletions:
0 comments (0 inline, 0 general)
src/commandpanel.cpp
Show inline comments
 
/*
 
  Copyright © 2015 Hasan Yavuz Özderya
 
  Copyright © 2016 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 <http://www.gnu.org/licenses/>.
 
*/
 

	
 
#include <QByteArray>
 
#include <QtDebug>
 

	
 
#include "commandpanel.h"
 
#include "ui_commandpanel.h"
 

	
 
#include <QByteArray>
 
#include <QtDebug>
 
#include "setting_defines.h"
 

	
 
CommandPanel::CommandPanel(QSerialPort* port, QWidget *parent) :
 
    QWidget(parent),
 
    ui(new Ui::CommandPanel),
 
    _menu(trUtf8("Commands")), _newCommandAction(trUtf8("New Command"), this)
 
{
 
    serialPort = port;
 

	
 
    ui->setupUi(this);
 
    auto layout = new QVBoxLayout();
 
    layout->setSpacing(0);
 
    ui->scrollAreaWidgetContents->setLayout(layout);
 

	
 
#ifdef Q_OS_WIN
 
    ui->pbNew->setIcon(QIcon(":/icons/list-add"));
 
#endif // Q_OS_WIN
 

	
 
    connect(ui->pbNew, &QPushButton::clicked, this, &CommandPanel::newCommand);
 
    connect(&_newCommandAction, &QAction::triggered, this, &CommandPanel::newCommand);
 

	
 
    _menu.addAction(&_newCommandAction);
 
    _menu.addSeparator();
 

	
 
    command_name_counter = 0;
 
    newCommand(); // add an empty slot by default
 
}
 

	
 
CommandPanel::~CommandPanel()
 
{
 
    commands.clear(); // UI will 'delete' actual objects
 
    delete ui;
 
}
 

	
 
void CommandPanel::newCommand()
 
CommandWidget* CommandPanel::newCommand()
 
{
 
    auto command = new CommandWidget();
 
    command_name_counter++;
 
    command->setName(trUtf8("Command ") + QString::number(command_name_counter));
 
    ui->scrollAreaWidgetContents->layout()->addWidget(command);
 
    command->setFocusToEdit();
 
    connect(command, &CommandWidget::sendCommand, this, &CommandPanel::sendCommand);
 
    connect(command, &CommandWidget::focusRequested, this, &CommandPanel::focusRequested);
 
    _menu.addAction(command->sendAction());
 

	
 
    // add to command list and remove on destroy
 
    commands << command;
 
    connect(command, &QObject::destroyed, [this](QObject* obj)
 
            {
 
                commands.removeOne(static_cast<CommandWidget*>(obj));
 
            });
 
    return command;
 
}
 

	
 
void CommandPanel::sendCommand(QByteArray command)
 
{
 
    if (!serialPort->isOpen())
 
    {
 
        qCritical() << "Port is not open!";
 
        return;
 
    }
 

	
 
    if (serialPort->write(command) < 0)
 
    {
 
@@ -80,12 +89,75 @@ void CommandPanel::sendCommand(QByteArra
 
    }
 
}
 

	
 
QMenu* CommandPanel::menu()
 
{
 
    return &_menu;
 
}
 

	
 
QAction* CommandPanel::newCommandAction()
 
{
 
    return &_newCommandAction;
 
}
 

	
 
unsigned CommandPanel::numOfCommands()
 
{
 
    return commands.size();
 
}
 

	
 
void CommandPanel::saveSettings(QSettings* settings)
 
{
 
    settings->beginGroup(SettingGroup_Commands);
 
    settings->beginWriteArray(SG_Commands_Command);
 
    for (int i = 0; i < commands.size(); i ++)
 
    {
 
        settings->setArrayIndex(i);
 
        auto command = commands[i];
 
        settings->setValue(SG_Commands_Name, command->name());
 
        settings->setValue(SG_Commands_Type, command->isASCIIMode() ? "ascii" : "hex");
 
        settings->setValue(SG_Commands_Data, command->commandText());
 
    }
 
    settings->endArray();
 
    settings->endGroup();
 
}
 

	
 
void CommandPanel::loadSettings(QSettings* settings)
 
{
 
    // clear all commands
 
    while (commands.size())
 
    {
 
        auto command = commands.takeLast();
 
        command->disconnect();
 
        delete command;
 
    }
 

	
 
    // load commands
 
    settings->beginGroup(SettingGroup_Commands);
 
    unsigned size = settings->beginReadArray(SG_Commands_Command);
 

	
 
    for (unsigned i = 0; i < size; i ++)
 
    {
 
        settings->setArrayIndex(i);
 
        auto command = newCommand();
 

	
 
        // load command name
 
        QString name = settings->value(SG_Commands_Name, "").toString();
 
        if (!name.isEmpty()) command->setName(name);
 

	
 
        // Important: type should be set before command data for correct validation
 
        QString type = settings->value(SG_Commands_Type, "").toString();
 
        if (type == "ascii")
 
        {
 
            command->setASCIIMode(true);
 
        }
 
        else if (type == "hex")
 
        {
 
            command->setASCIIMode(false);
 
        } // else unchanged
 

	
 
        // load command data
 
        command->setCommandText(settings->value(SG_Commands_Data, "").toString());
 
    }
 

	
 
    settings->endArray();
 
    settings->endGroup();
 
}
src/commandpanel.h
Show inline comments
 
/*
 
  Copyright © 2015 Hasan Yavuz Özderya
 
  Copyright © 2016 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 <http://www.gnu.org/licenses/>.
 
*/
 

	
 
#ifndef COMMANDPANEL_H
 
#define COMMANDPANEL_H
 

	
 
#include <QWidget>
 
#include <QSerialPort>
 
#include <QByteArray>
 
#include <QList>
 
#include <QMenu>
 
#include <QAction>
 
#include <QSettings>
 

	
 
#include "commandwidget.h"
 

	
 
namespace Ui {
 
class CommandPanel;
 
}
 

	
 
class CommandPanel : public QWidget
 
{
 
    Q_OBJECT
 

	
 
public:
 
    explicit CommandPanel(QSerialPort* port, QWidget *parent = 0);
 
    ~CommandPanel();
 

	
 
    QMenu* menu();
 
    /// Action for creating a new command.
 
    QAction* newCommandAction();
 
    /// Stores commands into a `QSettings`
 
    void saveSettings(QSettings* settings);
 
    /// Loads commands from a `QSettings`.
 
    void loadSettings(QSettings* settings);
 
    /// Number of commands
 
    unsigned numOfCommands();
 

	
 
signals:
 
    // emitted when user tries to send an empty command
 
    void focusRequested();
 

	
 
private:
 
    Ui::CommandPanel *ui;
 
    QSerialPort* serialPort;
 
    QMenu _menu;
 
    QAction _newCommandAction;
 
    QList<CommandWidget*> commands;
 

	
 
    unsigned command_name_counter;
 

	
 
private slots:
 
    void newCommand();
 
    CommandWidget* newCommand();
 
    void sendCommand(QByteArray command);
 
};
 

	
 
#endif // COMMANDPANEL_H
src/commandwidget.cpp
Show inline comments
 
/*
 
  Copyright © 2015 Hasan Yavuz Özderya
 
  Copyright © 2016 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.
 
@@ -92,31 +92,47 @@ void CommandWidget::onSendClicked()
 
}
 

	
 
void CommandWidget::onASCIIToggled(bool checked)
 
{
 
    ui->leCommand->setMode(checked);
 
}
 

	
 
bool CommandWidget::isASCIIMode()
 
{
 
    return ui->pbASCII->isChecked();
 
}
 

	
 
void CommandWidget::setASCIIMode(bool enabled)
 
{
 
    ui->pbASCII->setChecked(enabled);
 
}
 

	
 
void CommandWidget::setName(QString name)
 
{
 
    ui->leName->setText(name);
 
}
 

	
 
QString CommandWidget::name()
 
{
 
    return ui->leName->text();
 
}
 

	
 
void CommandWidget::setFocusToEdit()
 
{
 
    ui->leCommand->setFocus(Qt::OtherFocusReason);
 
}
 

	
 
QAction* CommandWidget::sendAction()
 
{
 
    return &_sendAction;
 
}
 

	
 
QString CommandWidget::commandText()
 
{
 
    return ui->leCommand->text();
 
}
 

	
 
void CommandWidget::setCommandText(QString str)
 
{
 
    ui->leCommand->selectAll();
 
    ui->leCommand->insert(str);
 
}
src/commandwidget.h
Show inline comments
 
/*
 
  Copyright © 2015 Hasan Yavuz Özderya
 
  Copyright © 2016 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.
 
@@ -30,39 +30,49 @@ class CommandWidget;
 

	
 
class CommandWidget : public QWidget
 
{
 
    Q_OBJECT
 

	
 
public:
 
    explicit CommandWidget(QWidget *parent = 0);
 
    ~CommandWidget();
 

	
 
    void setName(QString name);
 
    QString name();
 
    void setFocusToEdit();
 
    /// An action that triggers sending of command.
 
    QAction* sendAction();
 
    /// true: ascii mode, false hex mode
 
    bool isASCIIMode();
 
    /// true: ascii mode, false hex mode
 
    void setASCIIMode(bool ascii);
 
        /// Returns the command data as text
 
    QString commandText();
 
    /// Set command data as text. Text is validated according to current mode.
 
    void setCommandText(QString str);
 

	
 
signals:
 
    void deleteRequested(CommandWidget* thisWidget); // emitted when delete button is clicked
 
    /// emitted when delete button is clicked
 
    void deleteRequested(CommandWidget* thisWidget);
 

	
 
    // emitted when send button is clicked
 
    //
 
    // in case of hex mode, command text should be a hexadecimal
 
    // string containing hexadecimal characters only (not even spaces)
 
    /**
 
     * Emitted when send button is clicked.
 
     *
 
     * In case of hex mode, command text should be a hexadecimal
 
     * string containing hexadecimal characters only (not even spaces)
 
     */
 
    void sendCommand(QByteArray command);
 

	
 
    // emitted when user tries to send an empty command
 
    /// emitted when user tries to send an empty command
 
    void focusRequested();
 

	
 
private:
 
    Ui::CommandWidget *ui;
 
    QAction _sendAction;
 

	
 
    bool isASCIIMode(); // true: ascii mode, false hex mode
 

	
 
private slots:
 
    void onDeleteClicked();
 
    void onSendClicked();
 
    void onASCIIToggled(bool checked);
 
};
 

	
 
#endif // COMMANDWIDGET_H
src/mainwindow.cpp
Show inline comments
 
@@ -192,24 +192,30 @@ MainWindow::MainWindow(QWidget *parent) 
 
                     this, &MainWindow::onSpsChanged);
 

	
 
    // init demo
 
    QObject::connect(ui->actionDemoMode, &QAction::toggled,
 
                     this, &MainWindow::enableDemo);
 

	
 
    QObject::connect(ui->actionDemoMode, &QAction::toggled,
 
                     plotMan, &PlotManager::showDemoIndicator);
 

	
 
    // load default settings
 
    QSettings settings("serialplot", "serialplot");
 
    loadAllSettings(&settings);
 

	
 
    // ensure command panel has 1 command if none loaded
 
    if (!commandPanel.numOfCommands())
 
    {
 
        commandPanel.newCommandAction()->trigger();
 
    }
 
}
 

	
 
MainWindow::~MainWindow()
 
{
 
    // save settings
 
    QSettings settings("serialplot", "serialplot");
 
    saveAllSettings(&settings);
 

	
 
    if (serialPort.isOpen())
 
    {
 
        serialPort.close();
 
    }
 
@@ -425,33 +431,35 @@ void MainWindow::messageHandler(QtMsgTyp
 
    {
 
        ui->statusBar->showMessage(msg, 5000);
 
    }
 
}
 

	
 
void MainWindow::saveAllSettings(QSettings* settings)
 
{
 
    saveMWSettings(settings);
 
    portControl.saveSettings(settings);
 
    dataFormatPanel.saveSettings(settings);
 
    channelMan.saveSettings(settings);
 
    plotControlPanel.saveSettings(settings);
 
    commandPanel.saveSettings(settings);
 
}
 

	
 
void MainWindow::loadAllSettings(QSettings* settings)
 
{
 
    loadMWSettings(settings);
 
    portControl.loadSettings(settings);
 
    dataFormatPanel.loadSettings(settings);
 
    channelMan.loadSettings(settings);
 
    plotControlPanel.loadSettings(settings);
 
    commandPanel.loadSettings(settings);
 
}
 

	
 
void MainWindow::saveMWSettings(QSettings* settings)
 
{
 
    // save window geometry
 
    settings->beginGroup(SettingGroup_MainWindow);
 
    settings->setValue(SG_MainWindow_Size, size());
 
    settings->setValue(SG_MainWindow_Pos, pos());
 
    // save active panel
 
    settings->setValue(SG_MainWindow_ActivePanel,
 
                       panelSettingMap.value(ui->tabWidget->currentIndex()));
 
    // save panel minimization
src/setting_defines.h
Show inline comments
 
@@ -67,13 +67,19 @@ const char SG_CustomFrame_Checksum[] = "
 
const char SG_CustomFrame_DebugMode[] = "debugMode";
 

	
 
// channel manager keys
 
const char SG_Channels_Channel[] = "channel";
 
const char SG_Channels_Name[] = "name";
 

	
 
// plot settings keys
 
const char SG_Plot_NumOfSamples[] = "numOfSamples";
 
const char SG_Plot_AutoScale[] = "autoScale";
 
const char SG_Plot_YMax[] = "yMax";
 
const char SG_Plot_YMin[] = "yMin";
 

	
 
// command setting keys
 
const char SG_Commands_Command[] = "command";
 
const char SG_Commands_Name[] = "name";
 
const char SG_Commands_Type[] = "type";
 
const char SG_Commands_Data[] = "data";
 

	
 
#endif // SETTING_DEFINES_H
0 comments (0 inline, 0 general)