1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Denis Shienkov <denis.shienkov@gmail.com>
4 ** Copyright (C) 2012 Laszlo Papp <lpapp@kde.org>
5 ** Contact: http://www.qt-project.org/legal
6 **
7 ** This file is part of the QtSerialPort module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and Digia.  For licensing terms and
15 ** conditions see http://qt.digia.com/licensing.  For further information
16 ** use the contact form at http://qt.digia.com/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 2.1 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL included in the
22 ** packaging of this file.  Please review the following information to
23 ** ensure the GNU Lesser General Public License version 2.1 requirements
24 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** In addition, as a special exception, Digia gives you certain additional
27 ** rights.  These rights are described in the Digia Qt LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 **
39 ** $QT_END_LICENSE$
40 **
41 ****************************************************************************/
42 
43 #include "consolewindow.h"
44 #include "ui_consolewindow.h"
45 #include "console.h"
46 #include "consolesettings.h"
47 
48 #include <QFile>
49 #include <QMessageBox>
50 #include <QSettings>
51 #include <QtSerialPort/QSerialPort>
52 
ConsoleWindow(QWidget * parent)53 ConsoleWindow::ConsoleWindow(QWidget *parent) :
54     QMainWindow(parent),
55     ui(new Ui::ConsoleWindow)
56 {
57     QFile styleSheet(":/resources/styles/programwindow.qss");
58 
59     this->setObjectName("consoleWindow");
60     if (!styleSheet.open(QIODevice::ReadOnly)) {
61         qWarning("Unable to open :/resources/styles/programwindow.qss");
62     } else {
63         QString ss = styleSheet.readAll();
64 #ifdef Q_OS_MAC
65                 int paneLoc = 4;
66                 int tabBarLoc = 0;
67 #else
68                 int paneLoc = -1;
69                 int tabBarLoc = 5;
70 #endif
71                 ss = ss.arg(paneLoc).arg(tabBarLoc);
72         this->setStyleSheet(ss);
73     }
74 
75     ui->setupUi(this);
76     console = new Console;
77     console->setEnabled(false);
78     setCentralWidget(console);
79     serial = new QSerialPort(this);
80     settings = new ConsoleSettings;
81 
82     QSettings settings;
83     if (!settings.value("consolewindow/state").isNull()) {
84         restoreState(settings.value("consolewindow/state").toByteArray());
85     }
86     if (!settings.value("consolewindow/geometry").isNull()) {
87         restoreGeometry(settings.value("consolewindow/geometry").toByteArray());
88     }
89 
90     ui->actionConnect->setEnabled(true);
91     ui->actionDisconnect->setEnabled(false);
92     ui->actionQuit->setEnabled(true);
93     ui->actionConfigure->setEnabled(true);
94 
95     initActionsConnections();
96 
97     connect(serial, SIGNAL(error(QSerialPort::SerialPortError)), this,
98             SLOT(handleError(QSerialPort::SerialPortError)));
99 
100     connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
101     connect(console, SIGNAL(getData(QByteArray)), this, SLOT(writeData(QByteArray)));
102 }
103 
~ConsoleWindow()104 ConsoleWindow::~ConsoleWindow()
105 {
106     delete settings;
107     delete ui;
108 }
109 
closeEvent(QCloseEvent * event)110 void ConsoleWindow::closeEvent(QCloseEvent *event)
111  {
112      closeSerialPort();
113      QSettings settings;
114      settings.setValue("consolewindow/geometry", saveGeometry());
115      settings.setValue("consolewindow/tate", saveState());
116      QMainWindow::closeEvent(event);
117  }
118 
openSerialPort(const QString portName)119 void ConsoleWindow::openSerialPort(const QString portName)
120 {
121     if (portName.isEmpty()) return;
122 
123     settings->selectPortName(portName);
124     if (serial->isOpen()) {
125         if (serial->portName().compare(portName) != 0) {
126             closeSerialPort();
127             openSerialPort();
128         }
129     } else {
130         openSerialPort();
131     }
132 }
133 
openSerialPort()134 void ConsoleWindow::openSerialPort()
135 {
136     ConsoleSettings::Settings p = settings->settings();
137     serial->setPortName(p.name);
138     if (serial->open(QIODevice::ReadWrite)) {
139         serial->setBaudRate(p.baudRate);
140         serial->setDataBits(p.dataBits);
141         serial->setParity(p.parity);
142         serial->setStopBits(p.stopBits);
143         serial->setFlowControl(p.flowControl);
144         console->setEnabled(true);
145         console->setLocalEchoEnabled(p.localEchoEnabled);
146         ui->actionConnect->setEnabled(false);
147         ui->actionDisconnect->setEnabled(true);
148         ui->actionConfigure->setEnabled(false);
149         ui->statusBar->showMessage(tr("Connected to %1 : %2, %3, %4, %5, %6")
150                                    .arg(p.name).arg(p.stringBaudRate).arg(p.stringDataBits)
151                                    .arg(p.stringParity).arg(p.stringStopBits).arg(p.stringFlowControl));
152     } else {
153         QMessageBox::critical(this, tr("Error"), serial->errorString());
154 
155         ui->statusBar->showMessage(tr("Serial port open error"));
156     }
157 }
158 
closeSerialPort(const QString portName)159 void ConsoleWindow::closeSerialPort(const QString portName)
160 {
161     if (portName.isEmpty()) return;
162     if (portName.compare(serial->portName()) == 0) {
163         closeSerialPort();
164     }
165 }
166 
closeSerialPort()167 void ConsoleWindow::closeSerialPort()
168 {
169     if (serial->isOpen()) {
170         serial->close();
171         console->setEnabled(false);
172         ui->actionConnect->setEnabled(true);
173         ui->actionDisconnect->setEnabled(false);
174         ui->actionConfigure->setEnabled(true);
175         ui->statusBar->showMessage(tr("Disconnected"));
176     }
177 }
178 
about()179 void ConsoleWindow::about()
180 {
181     QMessageBox::about(this, tr("About Serial Monitor"),
182                        tr("This terminal displays the serial communication on the "
183                           "selected port, usually between your computer and the "
184                           "connected microcontroller."));
185 }
186 
writeData(const QByteArray & data)187 void ConsoleWindow::writeData(const QByteArray &data)
188 {
189     serial->write(data);
190 }
191 
readData()192 void ConsoleWindow::readData()
193 {
194     QByteArray data = serial->readAll();
195     console->putData(data);
196 }
197 
handleError(QSerialPort::SerialPortError error)198 void ConsoleWindow::handleError(QSerialPort::SerialPortError error)
199 {
200     if (error == QSerialPort::ResourceError) {
201         QMessageBox::critical(this, tr("Critical Error"), serial->errorString());
202         closeSerialPort();
203     }
204 }
205 
initActionsConnections()206 void ConsoleWindow::initActionsConnections()
207 {
208     connect(ui->actionConnect, SIGNAL(triggered()), this, SLOT(openSerialPort()));
209     connect(ui->actionDisconnect, SIGNAL(triggered()), this, SLOT(closeSerialPort()));
210     connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(close()));
211     connect(ui->actionConfigure, SIGNAL(triggered()), settings, SLOT(show()));
212     connect(ui->actionClear, SIGNAL(triggered()), console, SLOT(clear()));
213     connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(about()));
214     connect(ui->actionAboutQt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
215 }
216