diff -Nru cutecom-0.22.0/Changelog cutecom-0.30.3/Changelog --- cutecom-0.22.0/Changelog 2009-06-27 12:23:48.000000000 +0000 +++ cutecom-0.30.3/Changelog 2016-02-15 17:13:18.000000000 +0000 @@ -1,3 +1,31 @@ +0.30.3, February 15th, 2016 +-now builds and runs using Qt5 versions less than 5.3 +-performance tuning by switching to QPlainTextEdit + +0.30.2, January 11th, 2016 +-opening a connnection with more than 200000 Baud not possible - FIX +-custom baud rate not restored - FIX +-extra long lines are wrapped - less disturbing + +0.31.1, December 21th, 2015 +-fixed a bug preventing to compile on gcc 5.2 + +0.30.0, December 18th, 2015 +-first public release of the reimplemented version + +0.25.0, November 30th, 2015 +-first preview of reimplemented version +-facelifted GUI +-full session support +-feature enhancements collected from various forks +-timestamp prefix +-display control characters +-requires Qt > 5.1 + +0.23.0, October 27th, 2015 +-ported partly to Qt5 +-made named sessions available via command line option (-s) + 0.22.0, June 27th, 2009 -CuteCom now also works on Mac OS X, patch by Oliver Klauke -support for more baudrates diff -Nru cutecom-0.22.0/CMakeLists.txt cutecom-0.30.3/CMakeLists.txt --- cutecom-0.22.0/CMakeLists.txt 2009-06-24 20:30:01.000000000 +0000 +++ cutecom-0.30.3/CMakeLists.txt 2016-02-15 17:13:18.000000000 +0000 @@ -1,34 +1,51 @@ -cmake_minimum_required(VERSION 2.4.3 FATAL_ERROR ) +cmake_minimum_required(VERSION 2.8.11 FATAL_ERROR ) project(CuteCom) -set(QT_MIN_VERSION 4.1.0) -find_package(Qt4 REQUIRED) - -include_directories(${QT_INCLUDES} ${CMAKE_BINARY_DIR}) -add_definitions(-DQT3_SUPPORT) -set(cutecomSrcs main.cpp qcppdialogimpl.cpp) - -qt4_wrap_cpp(cutecomSrcs qcppdialogimpl.h) - -qt4_wrap_ui(cutecomSrcs cutecommdlg.ui) +set (CuteCom_MAJOR_VERSION 0) +set (CuteCom_MINOR_VERSION 30) +set (CuteCom_PATCH_VERSION 3) +set (CuteCom_VERSION + ${CuteCom_MAJOR_VERSION}.${CuteCom_MINOR_VERSION}.${CuteCom_PATCH_VERSION}) + +configure_file ( + "${PROJECT_SOURCE_DIR}/version.h.in" + "${PROJECT_SOURCE_DIR}/version.h" +) + +# Find includes in corresponding build directories +set(CMAKE_INCLUDE_CURRENT_DIR ON) +# Instruct CMake to run moc automatically when needed. +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +# Find the Qt libraries +find_package(Qt5Widgets REQUIRED) +find_package(Qt5Core REQUIRED) +find_package(Qt5Gui REQUIRED) +#find_package(Serialport REQUIRED) + +qt5_wrap_ui(uiHeaders controlpanel.ui mainwindow.ui statusbar.ui sessionmanager.ui) +set(cutecomSrcs main.cpp mainwindow.cpp controlpanel.cpp devicecombo.cpp + serialdevicelistmodel.cpp settings.cpp statusbar.cpp sessionmanager.cpp + datadisplay.cpp) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +# C++14: set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y") +#add_definitions("-std=c++11") set(exeType) set(binInstallDir bin ) if(APPLE) - # with cmake < 2.6 install(TARGETS ... BUNDLE DESTINATION ... ) doesn't work: - cmake_minimum_required(VERSION 2.6 FATAL_ERROR ) set(exeType MACOSX_BUNDLE) set(binInstallDir /Applications ) - # hint to linker for indirect referenced libs inside qt3support - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -dylib_file QtSql.framework/Versions/4/QtSql:/Library/Frameworks/QtSql.framework/Versions/4/QtSql") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -dylib_file QtNetwork.framework/Versions/4/QtNetwork:/Library/Frameworks/QtNetwork.framework/Versions/4/QtNetwork") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -dylib_file QtXml.framework/Versions/4/QtXml:/Library/Frameworks/QtXml.framework/Versions/4/QtXml") endif(APPLE) -add_executable(cutecom ${exeType} ${cutecomSrcs} ${uiHeaders}) -target_link_libraries(cutecom ${QT_QT3SUPPORT_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY}) +add_executable(cutecom ${exeType} ${cutecomSrcs} ${uiHeaders} resources.qrc) + + +qt5_use_modules(cutecom Core Gui Widgets SerialPort) if (APPLE) set_target_properties(cutecom PROPERTIES OUTPUT_NAME CuteCom) @@ -36,12 +53,28 @@ install(TARGETS cutecom DESTINATION ${binInstallDir} ) -install(FILES cutecom.1 DESTINATION share/man/man1 ) +if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic") +endif() + +set (CPACK_PACKAGE_VERSION ${CuteCom_VERSION}) +set (CPACK_SOURCE_GENERATOR "TGZ") +set (CPACK_GENERATOR "RPM") +set (CPACK_PACKAGE_NAME "cutecom") +set (CPACK_PACKAGE_RELEASE 1) +set (CPACK_PACKAGE_VENDOR "cyc1insir") +set (CPACK_PACKAGE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) +set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_PACKAGE_RELEASE}.${CMAKE_SYSTEM_PROCESSOR}") +configure_file ( + "${CMAKE_CURRENT_SOURCE_DIR}/distribution/rpm-generic.spec.in" + "${CMAKE_CURRENT_BINARY_DIR}/cutecom.spec" + @ONLY IMMEDIATE ) +set (CPACK_RPM_USER_BINARY_SPECFILE "${CMAKE_CURRENT_BINARY_DIR}/cutecom.spec") +set (CPACK_SOURCE_PACKAGE_FILE_NAME + "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") +set (CPACK_SOURCE_IGNORE_FILES + "${CMAKE_CURRENT_BINARY_DIR};/.git/;~$;${CPACK_SOURCE_IGNORE_FILES}") +include (CPack) -find_program(KDECONFIG_EXECUTABLE NAMES kde-config ) +add_custom_target(dist COMMAND git archive --format tar --prefix=cutecom-${CuteCom_VERSION}/ HEAD | gzip > ${CMAKE_CURRENT_BINARY_DIR}/${CPACK_SOURCE_PACKAGE_FILE_NAME}.tgz WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) -if (KDECONFIG_EXECUTABLE) - # then ask kde-config for the kde data dirs - exec_program(${KDECONFIG_EXECUTABLE} ARGS --install apps --expandvars OUTPUT_VARIABLE _apps_DIR ) - install(FILES cutecom.desktop DESTINATION ${_apps_DIR}/Utilities) -endif (KDECONFIG_EXECUTABLE) diff -Nru cutecom-0.22.0/configure cutecom-0.30.3/configure --- cutecom-0.22.0/configure 2008-03-12 21:08:28.000000000 +0000 +++ cutecom-0.30.3/configure 2016-02-15 17:13:18.000000000 +0000 @@ -1,7 +1,7 @@ #!/bin/sh echo -echo "CuteCom uses the CMake build system, at least version 2.4.3 is required." +echo "CuteCom uses the CMake build system, at least version 2.8.11 is required." echo "If there is no package for your distribution, you can " echo "get it from http://www.cmake.org/HTML/Download.html" echo diff -Nru cutecom-0.22.0/controlpanel.cpp cutecom-0.30.3/controlpanel.cpp --- cutecom-0.22.0/controlpanel.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/controlpanel.cpp 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2015 Meinhard Ritscher + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "controlpanel.h" + +#include +#include +#include +#include +#include +#include + +#include "qdebug.h" +//#include + +ControlPanel::ControlPanel(QWidget *parent, Settings *settings) + : QFrame(parent) + , m_x(3) +{ + this->setupUi(this); + + m_baudValidator = new QIntValidator(0, 999000, this); + m_combo_Baud->setInsertPolicy(QComboBox::NoInsert); + const Settings::Session session = settings->getCurrentSession(); + + fillDeviceCombo(session.device); + fillBaudCombo(); + fillDataBitCombo(); + fillStopBitCombo(); + fillParityCombo(); + fillFlowCombo(); + fillOpenModeCombo(); + + connect(m_check_lineBreak, &QCheckBox::toggled, + [=](bool checked) { emit settingChanged(Settings::ShowCtrlCharacters, checked); }); + connect(m_check_timestamp, &QCheckBox::toggled, + [=](bool checked) { emit settingChanged(Settings::ShowTimestamp, checked); }); + connect(this, &ControlPanel::settingChanged, settings, &Settings::settingChanged); + + applySessionSettings(session); + + connect(m_bt_logfileDialog, &QToolButton::clicked, this, &ControlPanel::chooseLogFile); + + setAutoFillBackground(true); + // setWindowOpacity(0.1); + m_bt_open->setCheckable(true); + + // Connect button signal to slot + connect(m_bt_settings, &QPushButton::clicked, this, &ControlPanel::toggleMenu); + connect(m_bt_open, &QPushButton::clicked, this, &ControlPanel::toggleDevice); + connect(m_combo_Baud, static_cast(&QComboBox::activated), this, + &ControlPanel::customBaudRate); +} + +/** + * + * @brief ControlPanel::collapse + */ +void ControlPanel::collapse() +{ + QPoint btnPosition = m_bt_settings->mapToParent(m_bt_settings->rect().topLeft()); + + m_y = -(btnPosition.y() + 5); + // qDebug() << Q_FUNC_INFO << m_y << " : " << m_x; + move(m_x, m_y); + m_menuVisible = false; +} + +/** + * Makes the complete panel visible + * @brief ControlPanel::slideOut + */ +void ControlPanel::slideOut() +{ + if (!m_menuVisible) + toggleMenu(); +} + +ControlPanel::~ControlPanel() {} + +// for debugging +void ControlPanel::printPosition() +{ + qDebug() << "toParent pos" << m_bt_settings->mapToParent(m_bt_settings->pos()); + qDebug() << "toParten topRight" << m_bt_settings->mapToParent(m_bt_settings->rect().topLeft()); +} + +void ControlPanel::toggleMenu() +{ + // Create animation + QPropertyAnimation *animation = new QPropertyAnimation(this, "pos"); + // bool m_menuVisible = (y() < -3); + QPoint endPos = m_menuVisible ? QPoint(m_x, m_y) : QPoint(m_x, -3); + // qDebug() << m_menuVisible << endPos; + animation->setStartValue(pos()); + animation->setEndValue(endPos); + animation->start(); + if (m_menuVisible) { + m_bt_settings->setText("&Settings"); + m_menuVisible = false; + } else { + m_bt_settings->setText("^"); + m_bt_settings->setShortcut(Qt::KeyboardModifier::AltModifier + Qt::Key_S); + m_menuVisible = true; + m_combo_Baud->setFocus(); + } +} + +void ControlPanel::toggleDevice(bool open) +{ + if (open) { + if (m_menuVisible) + toggleMenu(); + m_bt_settings->setEnabled(false); + m_bt_open->setText(tr("Cl&ose")); + emit openDeviceClicked(); + } else { + m_bt_settings->setEnabled(true); + emit closeDeviceClicked(); + m_bt_open->setText(tr("&Open")); + } +} + +void ControlPanel::customBaudRate(int index) +{ + Q_UNUSED(index); + if (m_combo_Baud->currentData() == -1) { + m_combo_Baud->setEditable(true); + + m_baud_edit = m_combo_Baud->lineEdit(); + m_baud_edit->setValidator(m_baudValidator); + m_baud_edit->selectAll(); + connect(m_baud_edit, &QLineEdit::editingFinished, this, &ControlPanel::customBaudRateSet); + } +} + +void ControlPanel::customBaudRateSet() +{ + m_combo_Baud->setEditable(false); + m_combo_Baud->setItemText(m_combo_Baud->currentIndex(), m_baud_edit->text()); + settingChanged(Settings::BaudRate, m_baud_edit->text().toInt()); +} + +void ControlPanel::applySessionSettings(Settings::Session session) +{ + int index = m_combo_Baud->findText(QString::number(session.baudRate)); + int current_index = 0; + if (index != -1) { + m_combo_Baud->setCurrentIndex(index); + } else { + index = m_combo_Baud->findData(-1); + if (index != -1) { + m_combo_Baud->setItemText(index, QString::number(session.baudRate)); + m_combo_Baud->setCurrentIndex(index); + } + } + + index = m_combo_dataBits->findData(session.dataBits); + if (index != -1) { + m_combo_dataBits->setCurrentIndex(index); + } else { + current_index = m_combo_dataBits->currentIndex(); + index = m_combo_dataBits->findData(QSerialPort::Data8); + if (index != -1 && index != current_index) + m_combo_dataBits->setCurrentIndex(index); + else + emit settingChanged(Settings::DataBits, m_combo_dataBits->currentData()); + } + + index = m_combo_parity->findData(session.parity); + if (index != -1) { + m_combo_parity->setCurrentIndex(index); + } else { + current_index = m_combo_parity->currentIndex(); + index = m_combo_parity->findData(QSerialPort::NoParity); + if (index != -1 && index != current_index) + m_combo_parity->setCurrentIndex(index); + else + emit settingChanged(Settings::Parity, m_combo_parity->currentData()); + } + + index = m_combo_stopBits->findData(session.stopBits); + if (index != -1) { + m_combo_stopBits->setCurrentIndex(index); + } else { + current_index = m_combo_stopBits->currentIndex(); + int index = m_combo_stopBits->findData(QSerialPort::OneStop); + if (index != -1 && index != current_index) + m_combo_stopBits->setCurrentIndex(index); + else + emit settingChanged(Settings::StopBits, m_combo_stopBits->currentData()); + } + + index = m_combo_flowControl->findData(session.flowControl); + if (index != -1) { + m_combo_flowControl->setCurrentIndex(index); + } else { + current_index = m_combo_flowControl->currentIndex(); + index = m_combo_flowControl->findData(QSerialPort::NoFlowControl); + if (index != -1 && index != current_index) + m_combo_flowControl->setCurrentIndex(index); + else + emit settingChanged(Settings::FlowControl, m_combo_flowControl->currentData()); + } + + index = m_combo_Mode->findData(session.openMode); + if (index != -1) { + m_combo_Mode->setCurrentIndex(index); + } else { + current_index = m_combo_Mode->currentIndex(); + index = m_combo_Mode->findData(QIODevice::ReadWrite); + if (index != -1 && index != current_index) + m_combo_Mode->setCurrentIndex(index); + else + emit settingChanged(Settings::OpenMode, m_combo_Mode->currentData()); + } + + m_check_lineBreak->setChecked(session.showCtrlCharacters); + m_check_timestamp->setChecked(session.showTimestamp); +} + +void ControlPanel::fillDeviceCombo(const QString &deviceName) +{ + m_combo_device->clear(); + int numberDevices = 0; + for (auto info : QSerialPortInfo::availablePorts()) { + m_combo_device->addItem(info.systemLocation()); + if (info.isValid()) { + QString deviceInfo = QString("%1 %2\n%3:%4 " +#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) + ) +#else + "# %5") +#endif + .arg(info.manufacturer()) + .arg(info.description()) + .arg(info.vendorIdentifier()) + .arg(info.productIdentifier()) +#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) + ; +#else + .arg(info.serialNumber()); +#endif + m_combo_device->setItemData(numberDevices, deviceInfo, Qt::ToolTipRole); + QVariant temp = m_combo_device->itemData(numberDevices, Qt::ToolTipRole); + } else { + m_combo_device->setItemData(numberDevices, tr("Not a valid device"), Qt::ToolTipRole); + } + numberDevices++; + } + connect(m_combo_device, static_cast(&QComboBox::currentIndexChanged), [=](int index) { + emit settingChanged(Settings::Device, m_combo_device->currentText()); + // unfortunately, this is not working - itemDate returns an invalid QVariant + m_combo_device->setToolTip(m_combo_device->itemData(index, Qt::ToolTipRole).toString()); + }); + + if (!deviceName.isEmpty()) { + if (numberDevices) { + int index = m_combo_device->findText(deviceName); + if (index != -1) { + // found something - work done! + m_combo_device->setCurrentIndex(index); + return; + } + } + // maybe it's not connected at the moment + // let's add it anyway to the list of devices since the + // user might wan't to reconnect it + m_combo_device->addItem(deviceName); + m_combo_device->setCurrentIndex(numberDevices); + } else { + // use the first available port as default + m_combo_Baud->setCurrentIndex(0); + } +} + +void ControlPanel::fillBaudCombo() +{ + m_combo_Baud->addItem(QStringLiteral("1200"), QSerialPort::Baud1200); + m_combo_Baud->addItem(QStringLiteral("4800"), QSerialPort::Baud4800); + m_combo_Baud->addItem(QStringLiteral("9600"), QSerialPort::Baud9600); + m_combo_Baud->addItem(QStringLiteral("19200"), QSerialPort::Baud19200); + m_combo_Baud->addItem(QStringLiteral("38400"), QSerialPort::Baud38400); + m_combo_Baud->addItem(QStringLiteral("57600"), QSerialPort::Baud57600); + m_combo_Baud->addItem(QStringLiteral("115200"), QSerialPort::Baud115200); + m_combo_Baud->insertSeparator(90); // append this separator at the end + m_combo_Baud->addItem(QStringLiteral("Custom"), -1); + + connect(m_combo_Baud, static_cast(&QComboBox::currentIndexChanged), + [=]() { int custom = m_combo_Baud->currentData().toInt(); + emit settingChanged(Settings::BaudRate, + (custom == -1) ? m_combo_Baud->currentText() : m_combo_Baud->currentData()); + }); +} + +void ControlPanel::fillFlowCombo() +{ + m_combo_flowControl->addItem(QStringLiteral("None"), QSerialPort::NoFlowControl); + m_combo_flowControl->addItem(QStringLiteral("Hardware"), QSerialPort::HardwareControl); + m_combo_flowControl->addItem(QStringLiteral("Software"), QSerialPort::SoftwareControl); + + connect(m_combo_flowControl, static_cast(&QComboBox::currentIndexChanged), + [=]() { emit settingChanged(Settings::FlowControl, m_combo_flowControl->currentData()); }); +} + +void ControlPanel::fillParityCombo() +{ + m_combo_parity->addItem(QStringLiteral("None"), QSerialPort::NoParity); + m_combo_parity->addItem(QStringLiteral("Even"), QSerialPort::EvenParity); + m_combo_parity->addItem(QStringLiteral("Odd"), QSerialPort::OddParity); + m_combo_parity->addItem(QStringLiteral("Space"), QSerialPort::SpaceParity); + m_combo_parity->addItem(QStringLiteral("Mark"), QSerialPort::MarkParity); + + connect(m_combo_parity, static_cast(&QComboBox::currentIndexChanged), + [=]() { emit settingChanged(Settings::Parity, m_combo_parity->currentData()); }); +} + +void ControlPanel::fillDataBitCombo() +{ + m_combo_dataBits->addItem(QStringLiteral("5"), QSerialPort::Data5); + m_combo_dataBits->addItem(QStringLiteral("6"), QSerialPort::Data6); + m_combo_dataBits->addItem(QStringLiteral("7"), QSerialPort::Data7); + m_combo_dataBits->addItem(QStringLiteral("8"), QSerialPort::Data8); + + connect(m_combo_dataBits, static_cast(&QComboBox::currentIndexChanged), + [=]() { emit settingChanged(Settings::DataBits, m_combo_dataBits->currentData()); }); +} + +void ControlPanel::fillStopBitCombo() +{ + m_combo_stopBits->addItem(QStringLiteral("1"), QSerialPort::OneStop); +#ifdef Q_WS_WIN + m_combo_stopBits->addItem(QStringLiteral("1.5"), QSerialPort::OneAndHalfStop); +#endif + m_combo_stopBits->addItem(QStringLiteral("2"), QSerialPort::TwoStop); + + connect(m_combo_stopBits, static_cast(&QComboBox::currentIndexChanged), + [=]() { emit settingChanged(Settings::StopBits, m_combo_stopBits->currentData()); }); +} + +void ControlPanel::fillOpenModeCombo() +{ + m_combo_Mode->addItem(tr("Read Only"), QIODevice::ReadOnly); + m_combo_Mode->addItem(tr("Write Only"), QIODevice::WriteOnly); + m_combo_Mode->addItem(tr("Read/Write"), QIODevice::ReadWrite); + + connect(m_combo_Mode, static_cast(&QComboBox::currentIndexChanged), + [=]() { emit settingChanged(Settings::OpenMode, m_combo_Mode->currentData()); }); +} + +/** + * Display a file chooser dialog letting the user choose + * a file to log the output to + * @brief ControlPanel::chooseLogFile + */ +void ControlPanel::chooseLogFile() +{ + QString logFile = QFileDialog::getSaveFileName(this, tr("Save log file ..."), m_logfile_edit->text()); + if (!logFile.isEmpty()) { + m_logfile_edit->setText(logFile); + } +} diff -Nru cutecom-0.22.0/controlpanel.h cutecom-0.30.3/controlpanel.h --- cutecom-0.22.0/controlpanel.h 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/controlpanel.h 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015 Meinhard Ritscher + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef CONTROLPANEL_H +#define CONTROLPANEL_H + +#include "ui_controlpanel.h" +#include "settings.h" + +#include +#include + +class ControlPanel : public QFrame, public Ui::ControlPanel +{ + Q_OBJECT + +signals: + void openDeviceClicked(); + void closeDeviceClicked(); + void settingChanged(Settings::Options option, QVariant setting); + +public: + explicit ControlPanel(QWidget *parent = 0, Settings *settings = 0); + ~ControlPanel(); + /** + * Returns the space in the y-achsis needed + * when the panel is collapsed + * @brief hiddenHeight + * @return + */ + int hiddenHeight() { return height() + m_y; } + void printPosition(); + void collapse(); + void slideOut(); + /** + * @brief setLeftMargin + * @param x + */ + void setLeftMargin(int x) { m_x = x; } + + void fillDeviceCombo(const QString &deviceName); + void applySessionSettings(Settings::Session settings); + + void closeDevice() + { + toggleDevice(false); + m_bt_open->setChecked(false); + } + +private: + void fillBaudCombo(); + void fillFlowCombo(); + void fillParityCombo(); + void fillDataBitCombo(); + void fillStopBitCombo(); + void fillOpenModeCombo(); + + // slots + void toggleMenu(); + void toggleDevice(bool open); + void customBaudRate(int index); + void customBaudRateSet(); + void chooseLogFile(); + +private: + int m_x; + int m_y; + bool m_menuVisible; + QIntValidator *m_baudValidator; + QLineEdit *m_baud_edit; +}; + +#endif // CONTROLPANEL_H diff -Nru cutecom-0.22.0/controlpanel.ui cutecom-0.30.3/controlpanel.ui --- cutecom-0.22.0/controlpanel.ui 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/controlpanel.ui 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,306 @@ + + + ControlPanel + + + + 0 + 0 + 628 + 129 + + + + false + + + QFrame::StyledPanel + + + + 5 + + + 0 + + + 5 + + + 0 + + + 0 + + + + + 5 + + + 5 + + + + + &Parity + + + m_combo_parity + + + + + + + + + + + + + + + + Stop Bits + + + m_combo_stopBits + + + + + + + Display &Ctrl characters + + + + + + + Show &Timestamp + + + + + + + + + + + + + &Baudrate + + + m_combo_Baud + + + + + + + D&ata Bits + + + m_combo_dataBits + + + + + + + Open &Mode + + + m_combo_Mode + + + + + + + Flo&w Control + + + m_combo_flowControl + + + + + + + QFrame::NoFrame + + + QFrame::Plain + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Logfile: + + + + + + + + 80 + 0 + + + + + 400 + 16777215 + + + + + + + + Choose Logfile via file chooser. + + + ... + + + + + + + Appends to an existing logfile instead of truncating it. + + + Append + + + + + + + Qt::Horizontal + + + QSizePolicy::MinimumExpanding + + + + 2 + 20 + + + + + + + + + + + + + + + + 6 + + + + + &Open + + + + + + + &Device: + + + m_combo_device + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 35 + + + + &Settings + + + + + + + + + + DeviceCombo + QWidget +
devicecombo.h
+
+
+ + m_combo_Baud + m_combo_flowControl + m_combo_Mode + m_combo_dataBits + m_combo_parity + m_combo_stopBits + m_check_lineBreak + m_check_timestamp + m_logfile_edit + m_bt_logfileDialog + m_check_appendLog + m_combo_device + m_bt_open + m_bt_settings + + + +
diff -Nru cutecom-0.22.0/CREDITS cutecom-0.30.3/CREDITS --- cutecom-0.22.0/CREDITS 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/CREDITS 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,60 @@ +I'd like to thank all developers who made improvements to +CuteCom within the past years. I have tried to scan all +repos I could find for additions and improvements useful +for the reincarnation of this fine piece of software originally +created by Alexander Neundorf +I have not always copied the code directly but used the idea +behind. In case I might have used code originally written by +you but not mentioned you yet, please conctact me. I'll be more +than happy to add you to the list. + +First of all the source of the original CuteCom +from Alexander Neundorf which still +forms the base and large portions have been used for the +reimplemented CuteCom + +Antoine Calando +https://github.com/calandoa/cutecom +Mainly the option for displaying control characters +like \n \r and \t +but also the idea of switching in- and output upside down + +Damien R +https://github.com/damienrg/cutecom.git +Use QThread::msleep to delay characters + +Luca Ottaviano +https://github.com/asterix24/cutecom.git +Probably the original source of +Scroll view only if slider is at bottom. +Add support for pagUp and pagDown. +TnoDo check the other commits in more detail + +M1cha +https://github.com/M1cha/Cutecom.git +Could be the original source for +add support for tabs + +Preet Desai +https://github.com/preet/cutecom-qt5.git +Sending files with XYZModem proted to Qt5 + +Henrik Hautakoski +https://github.com/pnx/CuteCom.git +Option for prefixing each line with a timestamp + + +IDEAS - still a ToDo: +==================================== + +Toni Jovanoski +https://github.com/minimoog/qcom.git +Added completer for history commands. + +Ivan A-R +https://github.com/plumbum/Cutecom-my.git +Signals (DTR, RTS, etc) done. Break +including Hotkeys (disabled when +hardware handshake is used) +portable to QtSerialPort? + diff -Nru cutecom-0.22.0/cutecom.1 cutecom-0.30.3/cutecom.1 --- cutecom-0.22.0/cutecom.1 2006-11-25 18:48:48.000000000 +0000 +++ cutecom-0.30.3/cutecom.1 2016-02-15 17:13:18.000000000 +0000 @@ -30,12 +30,17 @@ (requires the lrzsz package) and hexadecimal input and output among other things. .SH OPTIONS -\fBCuteCom\fP doesn't really have any command-line options. +.IP -h +prints a short help message +.IP "-s " +opens a previously defined session. A new Session with default connection +parameters is created when a session with this name can not be found in +the config file .SH SEE ALSO .BR minicom (1), .BR sz (1). .SH AUTHOR -CuteCom was written by Alexander Neundorf . +CuteCom was originally written by Alexander Neundorf . .PP This manual page was written by Roman I Khimov , for the Debian project (but may be used by others). diff -Nru cutecom-0.22.0/cutecom.desktop cutecom-0.30.3/cutecom.desktop --- cutecom-0.22.0/cutecom.desktop 2004-07-09 20:13:46.000000000 +0000 +++ cutecom-0.30.3/cutecom.desktop 2016-02-15 17:13:18.000000000 +0000 @@ -1,12 +1,10 @@ [Desktop Entry] Encoding=UTF-8 -BinaryPattern= Name=CuteCom MimeType= GenericName=Serial Terminal Exec=cutecom Icon=openterm -TerminalOptions= Path= Type=Application Terminal=0 diff -Nru cutecom-0.22.0/cutecommdlg.ui cutecom-0.30.3/cutecommdlg.ui --- cutecom-0.22.0/cutecommdlg.ui 2009-06-23 20:30:04.000000000 +0000 +++ cutecom-0.30.3/cutecommdlg.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,615 +0,0 @@ - - CuteCommDlg - - - - 0 - 0 - 756 - 648 - - - - CuteCom - - - - - - - - Stop bits: - - - false - - - m_stopCb - - - - - - - &Quit - - - Alt+Q - - - - - - - Data bits: - - - false - - - m_dataBitsCb - - - - - - - &About - - - Alt+A - - - - - - - 3 - - - - 5 - - - - - 6 - - - - - 7 - - - - - 8 - - - - - - - - Device: - - - false - - - m_deviceCb - - - - - - - - - - &Open device - - - Alt+O - - - - - - - Cl&ose device - - - Alt+O - - - - - - - - 1 - - - - - 2 - - - - - - - - Baud rate: - - - false - - - m_baudCb - - - - - - - true - - - - - - - 7 - - - - - - - - - - - Parity: - - - false - - - m_parityCb - - - - - - - - None - - - - - Odd - - - - - Even - - - - - Mark - - - - - Space - - - - - - - - - - - - Enable Hardware Handshake - - - Hardware - - - - - - - Enable Software Handshake (XON/XOFF) - - - Software - - - - - - - Usually you want to use read and write - - - Writing - - - - - - - Usually you want to use read and write - - - Reading - - - - - - - Open for: - - - false - - - - - - - Handshake: - - - false - - - - - - - - - Apply settings when opening - - - - - - - - - - - Qt::Vertical - - - - - 0 - 2 - - - - QFrame::NoFrame - - - QFrame::Plain - - - - - - - Courier - - - - - - - - - - Clear the output window - - - &Clear - - - Alt+C - - - - - - - - 1 - 0 - - - - Show the output in hexadecimal format - - - &Hex output - - - Alt+H - - - - - - - Enable logging the data to a file. Chose "Append to" to append instead overwrite to an existing file. - - - - - - - - - - Enable logging the data to a file. Chose "Append to" to append instead overwrite to an existing file. - - - - Log to: - - - - - Append to: - - - - - - - - - 2 - 0 - - - - The logfile - - - - - - - Open file dialog - - - ... - - - - - - - - - - - 0 - 1 - - - - QFrame::NoFrame - - - QFrame::Plain - - - - - - - - - - - &Input: - - - false - - - m_cmdLe - - - - - - - Enter commands here, Ctrl+C, Ctrl+S, Ctrl+Q also work - - - - - - - - - - - Select a file to be sent using the specified protocol - - - Send file... - - - false - - - - - - - Select the transfer protocol - - - - Plain - - - - - XModem - - - - - ZModem - - - - - YModem - - - - - 1kXModem - - - - - Script - - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - Select the line end termination - - - - LF line end - - - - - CR line end - - - - - CR,LF line end - - - - - No line end - - - - - Hex input - - - - - - - - Char delay: - - - false - - - - - - - Delay between single characters - - - ms - - - 250 - - - 1 - - - - - - - - - - - - - qPixmapFromMimeSource - - m_connectPb - m_closePb - m_aboutPb - m_quitPb - m_deviceCb - m_baudCb - m_dataBitsCb - m_stopCb - m_parityCb - m_softwareCb - m_hardwareCb - m_readCb - m_writeCb - m_applyCb - m_outputView - m_clearOutputPb - m_hexOutputCb - m_enableLoggingCb - m_logAppendCb - m_logFileLe - m_logFileFileDialog - m_cmdLe - m_sendPb - m_protoPb - m_inputModeCb - m_charDelaySb - m_oldCmdsLb - - - - Binary files /tmp/tmpcePm31/p6GNbfuPwL/cutecom-0.22.0/cutecom.png and /tmp/tmpcePm31/OHesuVlVo7/cutecom-0.30.3/cutecom.png differ diff -Nru cutecom-0.22.0/CuteCom.pro cutecom-0.30.3/CuteCom.pro --- cutecom-0.22.0/CuteCom.pro 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/CuteCom.pro 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,54 @@ +#------------------------------------------------- +# +# This is the qmake build file mainly provided +# to ease development with Qt Creator. +# Since the version number is maintained within +# the CMakeLists.txt, cmake should have been +# called at least once. +# Otherwise the necessary version.h file will +# not have been generated. +# If for whatever reason cmake is not an option +# create the version.h from version.h.in manually +# +#------------------------------------------------- + +QT += core gui serialport + +greaterThan(QT_MAJOR_VERSION, 4){ + QT += widgets + CONFIG += c++11 +} + +TARGET = CuteCom +TEMPLATE = app + + +SOURCES += main.cpp\ + mainwindow.cpp \ + controlpanel.cpp \ + settings.cpp \ + devicecombo.cpp \ + serialdevicelistmodel.cpp \ + statusbar.cpp \ + sessionmanager.cpp \ + datadisplay.cpp + +HEADERS += mainwindow.h \ + controlpanel.h \ + settings.h \ + devicecombo.h \ + serialdevicelistmodel.h \ + statusbar.h \ + sessionmanager.h \ + datadisplay.h + +FORMS += mainwindow.ui \ + controlpanel.ui \ + statusbar.ui \ + sessionmanager.ui + +RESOURCES += \ + resources.qrc + +DISTFILES += \ + qt.astylerc diff -Nru cutecom-0.22.0/datadisplay.cpp cutecom-0.30.3/datadisplay.cpp --- cutecom-0.22.0/datadisplay.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/datadisplay.cpp 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,368 @@ +/* + * Copyright (C) 2004-2009 Alexander Neundorf (code used from original CuteCom) + * Copyright (c) 2015 Meinhard Ritscher + * Copyright (c) 2015 Antoine Calando (displaying Ctrl-characters and ascii for hex) + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "datadisplay.h" + +#include +#include +#include + +DataDisplay::DataDisplay(QWidget *parent) + : QPlainTextEdit(parent) + , m_hexBytes(0) + , m_displayHex(false) + , m_displayTime(false) + , m_displayCtrlCharacters(false) + , m_timestampFormat(QStringLiteral("HH:mm:ss:zzz")) + , m_previous_ended_with_nl(true) +{ + setupTextFormats(); +} + +void DataDisplay::clear() +{ + m_hexBytes = 0; + QPlainTextEdit::clear(); +} + +/** + * Prepare data and finally append it to the end of text edit's + * view port. + * @brief OutputTerminal::displayData + * @param data + */ +void DataDisplay::displayData(const QByteArray &data) +{ + if (m_displayTime) { + QTime timestamp = QTime::currentTime(); + m_timestamp = QStringLiteral("[") + timestamp.toString(m_timestampFormat) + QStringLiteral("] "); + } + + // stop auto scrolling if the user scrolled to + // to older data + QScrollBar *sb = verticalScrollBar(); + int save_scroll = sb->value(); + int save_max = (save_scroll == sb->maximum()); + + if (m_displayHex) { + if (formatHexData(data)) { + // the last line was incomplete + // we remove it from the display before redrawing it + // with the current data added + QTextCursor storeCursorPos = textCursor(); + moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); + moveCursor(QTextCursor::StartOfLine, QTextCursor::MoveAnchor); + moveCursor(QTextCursor::End, QTextCursor::KeepAnchor); + textCursor().removeSelectedText(); + // textCursor().deletePreviousChar(); + setTextCursor(storeCursorPos); + } + } else if (!data.contains('\n')) { + constructDisplayLine(data); + } else { + // display multiple lines + + // split line at '\n' but do not remove them + QList lines; + int start = 0; + int end; + while ((end = data.indexOf('\n', start)) != -1) { + end++; // include separator + lines.append(data.mid(start, end - start)); + start = end; + } + if (start < data.size()) { + lines.append(data.mid(start)); + // ends_with_lf = false; + } + + // if the last line of the previous junk of data + // was less than 16 bytes of data, it needs to + // be rewritten + // in this case, the last line was not removed + // test if last line of previous junk was complete + // append the first line of the current junk + // if (m_displayHex && m_data.size() > 0) { + // constructDisplayLine(lines.takeFirst(), true); + // } + + foreach (QByteArray line, lines) { + constructDisplayLine(line); + } + } + + // append the data to end of the parent's TextEdit + // each part of the line with it's set format + foreach (DisplayLine line, m_data) { + + if (m_displayHex) { + moveCursor(QTextCursor::End); + textCursor().insertText(line.prefix, *m_format_prefix); + + moveCursor(QTextCursor::End); + textCursor().insertText(line.data, *m_format_hex); + + moveCursor(QTextCursor::End); + textCursor().insertText(line.trailer, *m_format_ascii); + } else { + if (line.prefix.size() > 0) { + moveCursor(QTextCursor::End); + textCursor().insertText(line.prefix, *m_format_prefix); + } + moveCursor(QTextCursor::End); + textCursor().insertText(line.data, *m_format_data); + } + } + m_data.clear(); + + if (save_max) + sb->setValue(sb->maximum()); + else + sb->setValue(save_scroll); +} + +/*! + * Inserts a space between every byte + * abcdefg => a b c d e f g + * \brief OutputTerminal::insertSpaces + * \param data + * \param step + */ +void DataDisplay::insertSpaces(QString &data, unsigned int step) +{ + for (unsigned int i = data.size() - step; i > 0; i -= step) { + data.insert(i, ' '); + if (i == (8 * step)) { + data.insert(i, QStringLiteral(" ")); + } + } +} + +/*! + * \brief OutputTerminal::formatHexData + * \param inData + * \return should the last line be redisplayed + */ +bool DataDisplay::formatHexData(const QByteArray &inData) +{ + + QByteArray data; + bool redisplay = false; + + // 16 bytes will be displayed on each line + // if less have been displayed on the last round + // add to the last line and redisplay + int overflow = m_hexBytes % 16; + if (overflow) { + data = m_hexLeftOver.append(inData); + m_hexBytes -= overflow; + redisplay = true; + } else { + data = inData; + } + + QStringList junks; + int pos = 0; + QByteArray junk; + + unsigned int junkSize = 0; + while (pos < data.size()) { + junk = data.mid(pos, 16); + junkSize = junk.size(); + QString hexJunk = QString(junk.toHex()); + QString asciiText; + char *c = junk.data(); + while (*c) { + unsigned int b = *c; + if (b < 0x20) { + b += 0x2400; + } else if (0x7F <= b) { + b = '.'; + } + asciiText += QChar(b); + ++c; + } + if (junkSize == 16) + asciiText.append('\n'); + insertSpaces(hexJunk, 2); + if (asciiText.size() > 8) + asciiText.insert(8, QStringLiteral(" ")); + + DisplayLine line; + line.prefix = QString("%1 ").arg(m_hexBytes, 8, 10, QChar('0')); + line.data = QString("%1\t").arg(hexJunk, -50); + line.trailer = QString(asciiText); + m_data.append(line); + pos += 16; + m_hexBytes += junk.size(); + } + if (junkSize < 16) { + m_hexLeftOver = junk; + m_previous_ended_with_nl = false; + } else { + m_previous_ended_with_nl = true; + } + + return redisplay; +} + +/*! + * \brief OutputTerminal::constructDisplayLine + * \param inData + */ +void DataDisplay::constructDisplayLine(const QByteArray &inData) +{ + DisplayLine line; + + if (m_displayTime && m_previous_ended_with_nl) { + line.prefix = m_timestamp; + } + + for (int i = 0; i < inData.size(); i++) { + unsigned int b = inData.at(i); + // print one newline for \r\n only + if ((isprint(b)) || (b == '\n') || (b == '\r') || (b == '\t')) { + + if (b == '\r') { + if (m_displayCtrlCharacters) + line.data += QChar(0x240D); + } else if (b == '\n') { + if (m_displayCtrlCharacters) + line.data += QChar(0x240A); + line.data += '\n'; + Q_ASSERT(i != (inData.size())); + } else if (b == '\t') { + if (m_displayCtrlCharacters) + line.data += QChar(0x21E5); + line.data += '\t'; + } else { + line.data += b; + } + + } else { + if (b == '\0') { + line.data += "\n"; + m_previous_ended_with_nl = true; + m_data.append(line); + line = DisplayLine(); + line.prefix = m_timestamp; + continue; + } else { + line.data += QString("<0x%1>").arg(b & 0xff, 2, 16, QChar('0')); + } + } + } + if (!line.data.isEmpty()) { + m_data.append(line); + m_previous_ended_with_nl = line.data.endsWith('\n'); + } +} + +/*! + * \brief OutputTerminal::setDisplayTime + * \param displayTime + */ +void DataDisplay::setDisplayTime(bool displayTime) +{ + m_displayTime = displayTime; + if (!m_previous_ended_with_nl) { + displayData(QByteArray(1, '\n')); + } +} + +/*! + * \brief OutputTerminal::setDisplayHex + * \param displayHex + */ +void DataDisplay::setDisplayHex(bool displayHex) +{ + if (displayHex) { + setLineWrapMode(QPlainTextEdit::NoWrap); + if (!m_previous_ended_with_nl) { + displayData(QByteArray(1, '\n')); + } + m_hexBytes = 0; + m_displayHex = displayHex; + } else { + setLineWrapMode(QPlainTextEdit::WidgetWidth); + m_displayHex = displayHex; + if (!m_previous_ended_with_nl) { + displayData(QByteArray(1, '\n')); + } + } +} + +/*! + * \brief OutputTerminal::setDisplayCtrlCharacters + * \param displayCtrlCharacters + */ +void DataDisplay::setDisplayCtrlCharacters(bool displayCtrlCharacters) +{ + m_displayCtrlCharacters = displayCtrlCharacters; +} + +/*! + * \brief OutputTerminal::setTimestampFormat + * \param timestampFormat + */ +void DataDisplay::setTimestampFormat(const QString ×tampFormat) { m_timestampFormat = timestampFormat; } + +/*! + * Setting up different formats for displaying + * different sections of the data differently + * \brief OutputTerminal::setupTextFormats + */ +void DataDisplay::setupTextFormats() +{ + // ToDo make this changeable via settings + + QTextCursor cursor = textCursor(); + QTextCharFormat format = cursor.charFormat(); + QColor col = QColor(Qt::black); + format.setForeground(col); + QFont font; + font.setFamily(font.defaultFamily()); + font.setPointSize(10); + format.setFont(font); + m_format_data = new QTextCharFormat(format); + // qDebug() << m_format_data->foreground(); + + col = QColor(120, 180, 200); + format.setForeground(col); + m_format_prefix = new QTextCharFormat(format); + // qDebug() << m_format_prefix->foreground(); + + col = QColor(Qt::black); + format.setForeground(col); + font = QFont("Monospace"); + font.setStyleHint(QFont::Courier); + font.setPointSize(10); + // font.setFixedPitch(true); + // font.setKerning(false); + format.setFont(font); + m_format_hex = new QTextCharFormat(format); + + col = QColor(100, 100, 100); + format.setForeground(col); + m_format_ascii = new QTextCharFormat(format); +} diff -Nru cutecom-0.22.0/datadisplay.h cutecom-0.30.3/datadisplay.h --- cutecom-0.22.0/datadisplay.h 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/datadisplay.h 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2015 Meinhard Ritscher + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef DATADISPLAY_H +#define DATADISPLAY_H + +#include + +class DataDisplay : public QPlainTextEdit +{ + Q_OBJECT + + struct DisplayLine + { + QString prefix; + QString data; + QString trailer; + }; + +public: + explicit DataDisplay(QWidget *parent = 0); + + void clear(); + + void displayData(const QByteArray &data); + + void setDisplayTime(bool displayTime); + + void setDisplayHex(bool displayHex); + + void setDisplayCtrlCharacters(bool displayCtrlCharacters); + + void setTimestampFormat(const QString ×tampFormat); + +private: + void insertSpaces(QString &data, unsigned int step = 1); + bool formatHexData(const QByteArray &inData); + void constructDisplayLine(const QByteArray &inData); + void setupTextFormats(); + + /** + * @brief m_hexBytes + */ + quint64 m_hexBytes; + + /** + * Data is displayed as hexadecimal values. + * @brief m_displayTime + */ + bool m_displayHex; + /** + * Each line is prefixed with a timestamp. + * @brief m_displayHex + */ + bool m_displayTime; + + /** + * Ctrl characters like LF and Tabs are visualized + * with symbols + * @brief m_displayCtrlCharacters + */ + bool m_displayCtrlCharacters; + + /** + * @brief m_timestampFormat + */ + QString m_timestampFormat; + + /** + * @brief m_timestamp + */ + QString m_timestamp; + + /** + * The container to store multiple formated + * lines before beeing printed + * @brief m_data + */ + QList m_data; + + /** + * In case the last printed hex line + * contained less than 16 bytes, + * The line's raw content will be stored + * here so it can be reprinted in the next round + * @brief m_hexLeftOver + */ + QByteArray m_hexLeftOver; + + bool m_previous_ended_with_nl; + + QTextCharFormat *m_format_prefix; + QTextCharFormat *m_format_data; + QTextCharFormat *m_format_hex; + QTextCharFormat *m_format_ascii; +}; + +#endif // DATADISPLAY_H diff -Nru cutecom-0.22.0/debian/changelog cutecom-0.30.3/debian/changelog --- cutecom-0.22.0/debian/changelog 2016-10-04 08:09:25.000000000 +0000 +++ cutecom-0.30.3/debian/changelog 2016-10-03 20:04:20.000000000 +0000 @@ -1,3 +1,24 @@ +cutecom (0.30.3-1) unstable; urgency=low + + * New upstream release based on Qt5 (Closes: #788179, #696221) + * Update license to GPLv3+, upstream changed to that in 2015 + * Update homepage, source, copyright and watch information (upstream + development moved to github) + * Switch to dpkg-source 3.0 (quilt) format + * Upgrade package to standards 3.9.8 + * Upgrade to debhelper 10, set compat 10 + * Use standard dh rules to build the package + * Drop "cutecom-0.22.0-nolinebreak.diff", obsolete + * Drop "cutecom-remove-deprecated-desktop-entries.patch", obsolete + * Drop "fix_pathes_for_debian.patch", obsolete + * Remove obsolete menu support + * Use Cmake RelWithDebInfo build type to get '-O2 -g' flags + * Install desktop file (for 'System' category) system-wide (previously + it was installed into kde directory) (Closes: #614793) (LP: #1575347) + * Install an icon + + -- Roman I Khimov Mon, 03 Oct 2016 23:04:20 +0300 + cutecom (0.22.0-2) unstable; urgency=low * Add cutecom-0.22.0-nolinebreak.diff (closes: #591666) diff -Nru cutecom-0.22.0/debian/clean cutecom-0.30.3/debian/clean --- cutecom-0.22.0/debian/clean 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/debian/clean 2016-10-03 20:04:20.000000000 +0000 @@ -0,0 +1 @@ +version.h diff -Nru cutecom-0.22.0/debian/compat cutecom-0.30.3/debian/compat --- cutecom-0.22.0/debian/compat 2016-10-04 08:09:25.000000000 +0000 +++ cutecom-0.30.3/debian/compat 2016-10-03 20:04:20.000000000 +0000 @@ -1 +1 @@ -5 +10 diff -Nru cutecom-0.22.0/debian/control cutecom-0.30.3/debian/control --- cutecom-0.22.0/debian/control 2016-10-04 08:09:25.000000000 +0000 +++ cutecom-0.30.3/debian/control 2016-10-03 20:04:20.000000000 +0000 @@ -2,9 +2,9 @@ Section: comm Priority: optional Maintainer: Roman I Khimov -Build-Depends: debhelper (>= 7), cmake (>= 2.4.3), libqt4-dev, quilt (>= 0.40) -Standards-Version: 3.9.1 -Homepage: http://cutecom.sourceforge.net/ +Build-Depends: debhelper (>= 10), cmake (>= 2.8.11), qtbase5-dev (>= 5.1.0), qt5-qmake (>= 5.1.0), qtbase5-dev-tools (>= 5.1.0), libqt5serialport5-dev (>= 5.1.0) +Standards-Version: 3.9.8 +Homepage: http://github.com/neundorf/CuteCom Package: cutecom Architecture: any @@ -17,4 +17,4 @@ instead of character-oriented, xmodem, ymodem, zmodem support (requires the lrzsz package) and hexadecimal input and output among other things. - It is written using the Qt library by Trolltech (www.trolltech.com). + It is written using the Qt library originally by Trolltech (www.trolltech.com). diff -Nru cutecom-0.22.0/debian/copyright cutecom-0.30.3/debian/copyright --- cutecom-0.22.0/debian/copyright 2016-10-04 08:09:25.000000000 +0000 +++ cutecom-0.30.3/debian/copyright 2016-10-03 20:04:20.000000000 +0000 @@ -1,17 +1,244 @@ Format-Specification: http://wiki.debian.org/Proposals/CopyrightFormat?action=recall&rev=226 Upstream-Name: CuteCom -Upstream-Source: http://cutecom.sourceforge.net/ -Upstream-Maintainer: Alexander Neundorf +Upstream-Source: http://github.com/neundorf/CuteCom +Upstream-Maintainer: Meinhard Ritscher Files: * Copyright: Copyright 2004-2009, Alexander Neundorf -License: GPL-2+ +Copyright: Copyright 2015, Meinhard Ritscher +License: GPL-3+ On Debian systems the full text of the GNU General Public License can be found - in the `/usr/share/common-licenses/GPL-2' file. + in the `/usr/share/common-licenses/GPL-3' file. + +Files: datadisplay.cpp +Copyright: Copyright 2004-2009, Alexander Neundorf +Copyright: Copyright 2015, Meinhard Ritscher +Copyright: Copyright 2015, Antoine Calando +License: GPL-3+ + On Debian systems the full text of the GNU General Public License can be found + in the `/usr/share/common-licenses/GPL-3' file. + +Files: mainwindow.cpp +Copyright: Copyright 2004-2009, Alexander Neundorf +Copyright: Copyright 2013, Preet Desai +Copyright: Copyright 2015, Meinhard Ritscher +Copyright: Copyright 2015, Antoine Calando +License: GPL-3+ + On Debian systems the full text of the GNU General Public License can be found + in the `/usr/share/common-licenses/GPL-3' file. + +Files: sessionmanager.cpp +Copyright: Copyright 2015, Meinhard Ritscher +Copyright: Copyright 2015, The Qt Company Ltd. +License: GPL-3+ + On Debian systems the full text of the GNU General Public License can be found + in the `/usr/share/common-licenses/GPL-3' file. + +Files: images/cutecom.svg, images/terminal.svg +Copyright: Copyright 2005, Jakub Steiner +License: CC-BY-SA-2 + THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE + COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY + COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS + AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + + BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE + BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS + CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND + CONDITIONS. + + 1. Definitions + + "Collective Work" means a work, such as a periodical issue, anthology or + encyclopedia, in which the Work in its entirety in unmodified form, along with + a number of other contributions, constituting separate and independent works + in themselves, are assembled into a collective whole. A work that constitutes + a Collective Work will not be considered a Derivative Work (as defined below) + for the purposes of this License. + "Derivative Work" means a work based upon the Work or upon the Work and other + pre-existing works, such as a translation, musical arrangement, dramatization, + fictionalization, motion picture version, sound recording, art reproduction, + abridgment, condensation, or any other form in which the Work may be recast, + transformed, or adapted, except that a work that constitutes a Collective Work + will not be considered a Derivative Work for the purpose of this License. For + the avoidance of doubt, where the Work is a musical composition or sound + recording, the synchronization of the Work in timed-relation with a moving + image ("synching") will be considered a Derivative Work for the purpose of + this License. + "Licensor" means the individual or entity that offers the Work under the terms + of this License. + "Original Author" means the individual or entity who created the Work. + "Work" means the copyrightable work of authorship offered under the terms of + this License. + "You" means an individual or entity exercising rights under this License who + has not previously violated the terms of this License with respect to the + Work, or who has received express permission from the Licensor to exercise + rights under this License despite a previous violation. + "License Elements" means the following high-level license attributes as + selected by Licensor and indicated in the title of this License: Attribution, + ShareAlike. + 2. Fair Use Rights. Nothing in this license is intended to reduce, limit, or + restrict any rights arising from fair use, first sale or other limitations on + the exclusive rights of the copyright owner under copyright law or other + applicable laws. + + 3. License Grant. Subject to the terms and conditions of this License, + Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual + (for the duration of the applicable copyright) license to exercise the rights + in the Work as stated below: + + to reproduce the Work, to incorporate the Work into one or more Collective + Works, and to reproduce the Work as incorporated in the Collective Works; + to create and reproduce Derivative Works; + to distribute copies or phonorecords of, display publicly, perform publicly, + and perform publicly by means of a digital audio transmission the Work + including as incorporated in Collective Works; + to distribute copies or phonorecords of, display publicly, perform publicly, + and perform publicly by means of a digital audio transmission Derivative + Works. + For the avoidance of doubt, where the work is a musical composition: + + Performance Royalties Under Blanket Licenses. Licensor waives the exclusive + right to collect, whether individually or via a performance rights society + (e.g. ASCAP, BMI, SESAC), royalties for the public performance or public + digital performance (e.g. webcast) of the Work. + Mechanical Rights and Statutory Royalties. Licensor waives the exclusive right + to collect, whether individually or via a music rights society or designated + agent (e.g. Harry Fox Agency), royalties for any phonorecord You create from + the Work ("cover version") and distribute, subject to the compulsory license + created by 17 USC Section 115 of the US Copyright Act (or the equivalent in + other jurisdictions). + Webcasting Rights and Statutory Royalties. For the avoidance of doubt, where + the Work is a sound recording, Licensor waives the exclusive right to collect, + whether individually or via a performance-rights society (e.g. SoundExchange), + royalties for the public digital performance (e.g. webcast) of the Work, + subject to the compulsory license created by 17 USC Section 114 of the US + Copyright Act (or the equivalent in other jurisdictions). + The above rights may be exercised in all media and formats whether now known + or hereafter devised. The above rights include the right to make such + modifications as are technically necessary to exercise the rights in other + media and formats. All rights not expressly granted by Licensor are hereby + reserved. + + 4. Restrictions.The license granted in Section 3 above is expressly made + subject to and limited by the following restrictions: + + You may distribute, publicly display, publicly perform, or publicly digitally + perform the Work only under the terms of this License, and You must include a + copy of, or the Uniform Resource Identifier for, this License with every copy + or phonorecord of the Work You distribute, publicly display, publicly perform, + or publicly digitally perform. You may not offer or impose any terms on the + Work that alter or restrict the terms of this License or the recipients' + exercise of the rights granted hereunder. You may not sublicense the Work. You + must keep intact all notices that refer to this License and to the disclaimer + of warranties. You may not distribute, publicly display, publicly perform, or + publicly digitally perform the Work with any technological measures that + control access or use of the Work in a manner inconsistent with the terms of + this License Agreement. The above applies to the Work as incorporated in a + Collective Work, but this does not require the Collective Work apart from the + Work itself to be made subject to the terms of this License. If You create a + Collective Work, upon notice from any Licensor You must, to the extent + practicable, remove from the Collective Work any reference to such Licensor or + the Original Author, as requested. If You create a Derivative Work, upon + notice from any Licensor You must, to the extent practicable, remove from the + Derivative Work any reference to such Licensor or the Original Author, as + requested. + You may distribute, publicly display, publicly perform, or publicly digitally + perform a Derivative Work only under the terms of this License, a later + version of this License with the same License Elements as this License, or a + Creative Commons iCommons license that contains the same License Elements as + this License (e.g. Attribution-ShareAlike 2.0 Japan). You must include a copy + of, or the Uniform Resource Identifier for, this License or other license + specified in the previous sentence with every copy or phonorecord of each + Derivative Work You distribute, publicly display, publicly perform, or + publicly digitally perform. You may not offer or impose any terms on the + Derivative Works that alter or restrict the terms of this License or the + recipients' exercise of the rights granted hereunder, and You must keep intact + all notices that refer to this License and to the disclaimer of + warranties. You may not distribute, publicly display, publicly perform, or + publicly digitally perform the Derivative Work with any technological measures + that control access or use of the Work in a manner inconsistent with the terms + of this License Agreement. The above applies to the Derivative Work as + incorporated in a Collective Work, but this does not require the Collective + Work apart from the Derivative Work itself to be made subject to the terms of + this License. + If you distribute, publicly display, publicly perform, or publicly digitally + perform the Work or any Derivative Works or Collective Works, You must keep + intact all copyright notices for the Work and give the Original Author credit + reasonable to the medium or means You are utilizing by conveying the name (or + pseudonym if applicable) of the Original Author if supplied; the title of the + Work if supplied; to the extent reasonably practicable, the Uniform Resource + Identifier, if any, that Licensor specifies to be associated with the Work, + unless such URI does not refer to the copyright notice or licensing + information for the Work; and in the case of a Derivative Work, a credit + identifying the use of the Work in the Derivative Work (e.g., "French + translation of the Work by Original Author," or "Screenplay based on original + Work by Original Author"). Such credit may be implemented in any reasonable + manner; provided, however, that in the case of a Derivative Work or Collective + Work, at a minimum such credit will appear where any other comparable + authorship credit appears and in a manner at least as prominent as such other + comparable authorship credit. + 5. Representations, Warranties and Disclaimer + + UNLESS OTHERWISE AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK + AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE + MATERIALS, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT + LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR + PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, + OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME + JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH + EXCLUSION MAY NOT APPLY TO YOU. + + 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, + IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY + SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT + OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF + THE POSSIBILITY OF SUCH DAMAGES. + + 7. Termination + + This License and the rights granted hereunder will terminate automatically + upon any breach by You of the terms of this License. Individuals or entities + who have received Derivative Works or Collective Works from You under this + License, however, will not have their licenses terminated provided such + individuals or entities remain in full compliance with those + licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this + License. + Subject to the above terms and conditions, the license granted here is + perpetual (for the duration of the applicable copyright in the + Work). Notwithstanding the above, Licensor reserves the right to release the + Work under different license terms or to stop distributing the Work at any + time; provided, however that any such election will not serve to withdraw this + License (or any other license that has been, or is required to be, granted + under the terms of this License), and this License will continue in full force + and effect unless terminated as stated above. + 8. Miscellaneous + + Each time You distribute or publicly digitally perform the Work or a + Collective Work, the Licensor offers to the recipient a license to the Work on + the same terms and conditions as the license granted to You under this + License. + Each time You distribute or publicly digitally perform a Derivative Work, + Licensor offers to the recipient a license to the original Work on the same + terms and conditions as the license granted to You under this License. + If any provision of this License is invalid or unenforceable under applicable + law, it shall not affect the validity or enforceability of the remainder of + the terms of this License, and without further action by the parties to this + agreement, such provision shall be reformed to the minimum extent necessary to + make such provision valid and enforceable. + No term or provision of this License shall be deemed waived and no breach + consented to unless such waiver or consent shall be in writing and signed by + the party to be charged with such waiver or consent. + This License constitutes the entire agreement between the parties with respect + to the Work licensed here. There are no understandings, agreements or + representations with respect to the Work not specified here. Licensor shall + not be bound by any additional provisions that may appear in any communication + from You. This License may not be modified without the mutual written + agreement of the Licensor and You. Files: debian/* -Copyright: Copyright 2006-2009 Roman I Khimov -License: GPL-2+ +Copyright: Copyright 2006-2016 Roman I Khimov +License: GPL-3+ On Debian systems the full text of the GNU General Public License can be found - in the `/usr/share/common-licenses/GPL-2' file. + in the `/usr/share/common-licenses/GPL-3' file. diff -Nru cutecom-0.22.0/debian/cutecom.install cutecom-0.30.3/debian/cutecom.install --- cutecom-0.22.0/debian/cutecom.install 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/debian/cutecom.install 2016-10-03 20:04:20.000000000 +0000 @@ -0,0 +1,2 @@ +distribution/openSUSE/cutecom.desktop usr/share/applications +images/cutecom.svg usr/share/pixmaps diff -Nru cutecom-0.22.0/debian/cutecom.menu cutecom-0.30.3/debian/cutecom.menu --- cutecom-0.22.0/debian/cutecom.menu 2016-10-04 08:09:25.000000000 +0000 +++ cutecom-0.30.3/debian/cutecom.menu 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -?package(cutecom):needs="X11" section="Applications/System/Hardware"\ - title="Cutecom" command="/usr/bin/cutecom" diff -Nru cutecom-0.22.0/debian/docs cutecom-0.30.3/debian/docs --- cutecom-0.22.0/debian/docs 2016-10-04 08:09:25.000000000 +0000 +++ cutecom-0.30.3/debian/docs 2016-10-03 20:04:20.000000000 +0000 @@ -1 +1,3 @@ TODO +README.md +CREDITS diff -Nru cutecom-0.22.0/debian/manpages cutecom-0.30.3/debian/manpages --- cutecom-0.22.0/debian/manpages 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/debian/manpages 2016-10-03 20:04:20.000000000 +0000 @@ -0,0 +1 @@ +cutecom.1 diff -Nru cutecom-0.22.0/debian/patches/cutecom-0.22.0-nolinebreak.diff cutecom-0.30.3/debian/patches/cutecom-0.22.0-nolinebreak.diff --- cutecom-0.22.0/debian/patches/cutecom-0.22.0-nolinebreak.diff 2016-10-04 08:09:25.000000000 +0000 +++ cutecom-0.30.3/debian/patches/cutecom-0.22.0-nolinebreak.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -diff -ruN cutecom-0.22.0/qcppdialogimpl.cpp cutecom-0.22.0-nolinebreak/qcppdialogimpl.cpp ---- cutecom-0.22.0/qcppdialogimpl.cpp 2009-06-25 21:10:49.000000000 +0100 -+++ cutecom-0.22.0-nolinebreak/qcppdialogimpl.cpp 2010-08-04 15:57:15.951009886 +0100 -@@ -18,6 +18,7 @@ - - #include "qcppdialogimpl.h" - -+#include - #include - #include - #include -@@ -1362,13 +1363,23 @@ - - void QCPPDialogImpl::doOutput() - { -- if (m_outputBuffer.isEmpty()) -- { -- return; -- } -+ QScrollBar* vScrollBar; -+ bool scrollWithText; -+ -+ if (m_outputBuffer.isEmpty()) -+ return; -+ -+ vScrollBar = m_outputView->verticalScrollBar(); -+ scrollWithText = (vScrollBar->value() == vScrollBar->maximum()); -+ -+ QTextCursor cursor(m_outputView->document()); -+ cursor.movePosition(QTextCursor::End); -+ cursor.insertText(m_outputBuffer); -+ -+ if ((scrollWithText)) -+ vScrollBar->setValue(vScrollBar->maximum()); - -- m_outputView->append(m_outputBuffer); -- m_outputBuffer.clear(); -+ m_outputBuffer.clear(); - } - - void QCPPDialogImpl::hexOutputClicked(bool /* on */) diff -Nru cutecom-0.22.0/debian/patches/cutecom-remove-deprecated-desktop-entries.patch cutecom-0.30.3/debian/patches/cutecom-remove-deprecated-desktop-entries.patch --- cutecom-0.22.0/debian/patches/cutecom-remove-deprecated-desktop-entries.patch 2016-10-04 08:09:25.000000000 +0000 +++ cutecom-0.30.3/debian/patches/cutecom-remove-deprecated-desktop-entries.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -Index: cutecom-0.22.0/cutecom.desktop -=================================================================== ---- cutecom-0.22.0.orig/cutecom.desktop 2010-08-12 19:00:49.704956488 +0000 -+++ cutecom-0.22.0/cutecom.desktop 2010-08-12 19:01:30.321689994 +0000 -@@ -1,12 +1,10 @@ - [Desktop Entry] - Encoding=UTF-8 --BinaryPattern= - Name=CuteCom - MimeType= - GenericName=Serial Terminal - Exec=cutecom - Icon=openterm --TerminalOptions= - Path= - Type=Application - Terminal=0 diff -Nru cutecom-0.22.0/debian/patches/fix_pathes_for_debian.patch cutecom-0.30.3/debian/patches/fix_pathes_for_debian.patch --- cutecom-0.22.0/debian/patches/fix_pathes_for_debian.patch 2016-10-04 08:09:25.000000000 +0000 +++ cutecom-0.30.3/debian/patches/fix_pathes_for_debian.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -Index: cutecom-0.22.0/CMakeLists.txt -=================================================================== ---- cutecom-0.22.0.orig/CMakeLists.txt 2009-06-25 00:30:01.000000000 +0400 -+++ cutecom-0.22.0/CMakeLists.txt 2009-07-13 00:20:46.029992375 +0400 -@@ -40,8 +40,4 @@ - - find_program(KDECONFIG_EXECUTABLE NAMES kde-config ) - --if (KDECONFIG_EXECUTABLE) -- # then ask kde-config for the kde data dirs -- exec_program(${KDECONFIG_EXECUTABLE} ARGS --install apps --expandvars OUTPUT_VARIABLE _apps_DIR ) -- install(FILES cutecom.desktop DESTINATION ${_apps_DIR}/Utilities) --endif (KDECONFIG_EXECUTABLE) -+install(FILES cutecom.desktop DESTINATION share/applications/kde) diff -Nru cutecom-0.22.0/debian/patches/man-page-update.patch cutecom-0.30.3/debian/patches/man-page-update.patch --- cutecom-0.22.0/debian/patches/man-page-update.patch 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/debian/patches/man-page-update.patch 2016-10-03 20:04:20.000000000 +0000 @@ -0,0 +1,43 @@ +Description: Update man page (long-form options, author and FILES) +Forwarded: https://github.com/neundorf/CuteCom/pull/14 +Author: Roman Khimov +Last-Update: 2016-09-30 + +diff --git a/cutecom.1 b/cutecom.1 +index 5876c43..68f4e1c 100644 +--- a/cutecom.1 ++++ b/cutecom.1 +@@ -2,7 +2,7 @@ + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH CUTECOM 1 "November 24, 2006" ++.TH CUTECOM 1 "September 30, 2016" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -30,17 +30,21 @@ instead of character-oriented, xmodem, ymodem, zmodem support + (requires the lrzsz package) and hexadecimal input and output among + other things. + .SH OPTIONS +-.IP -h ++.IP "\fB-h\fP, \fB--help\fP" + prints a short help message +-.IP "-s " ++.IP "\fB-s\fP, \fB--session\fP " + opens a previously defined session. A new Session with default connection + parameters is created when a session with this name can not be found in + the config file ++.SH FILES ++.IP "~/.config/CuteCom/CuteCom5.conf" ++Personal CuteCom configuration file (with sessions stored there also). + .SH SEE ALSO + .BR minicom (1), + .BR sz (1). + .SH AUTHOR +-CuteCom was originally written by Alexander Neundorf . ++CuteCom was originally written by Alexander Neundorf ++and is now maintained by Meinhard Ritscher . + .PP + This manual page was written by Roman I Khimov , + for the Debian project (but may be used by others). diff -Nru cutecom-0.22.0/debian/patches/series cutecom-0.30.3/debian/patches/series --- cutecom-0.22.0/debian/patches/series 2016-10-04 08:09:25.000000000 +0000 +++ cutecom-0.30.3/debian/patches/series 2016-10-03 20:04:20.000000000 +0000 @@ -1,3 +1 @@ -fix_pathes_for_debian.patch -cutecom-0.22.0-nolinebreak.diff -cutecom-remove-deprecated-desktop-entries.patch +man-page-update.patch diff -Nru cutecom-0.22.0/debian/README.source cutecom-0.30.3/debian/README.source --- cutecom-0.22.0/debian/README.source 2016-10-04 08:09:25.000000000 +0000 +++ cutecom-0.30.3/debian/README.source 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -This package uses quilt to manage patches, please refer to /usr/share/doc/quilt/README.source diff -Nru cutecom-0.22.0/debian/rules cutecom-0.30.3/debian/rules --- cutecom-0.22.0/debian/rules 2016-10-04 08:09:25.000000000 +0000 +++ cutecom-0.30.3/debian/rules 2016-10-03 20:04:20.000000000 +0000 @@ -3,64 +3,5 @@ # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 -include /usr/share/quilt/quilt.make - -config: patch - dh_testdir - mkdir -p build - cd build && cmake -DCMAKE_INSTALL_PREFIX=$(CURDIR)/debian/cutecom/usr \ - -DCMAKE_CXX_FLAGS="$(CFLAGS)" -DCMAKE_C_FLAGS="$(CFLAGS)" \ - -DCMAKE_EXE_LINKER_FLAGS="-Wl,-z,defs" ../ - -build: build-stamp - -build-stamp: config - dh_testdir - - cd build && $(MAKE) - - touch $@ - -clean: clean-patched unpatch - -clean-patched: - dh_testdir - dh_testroot - rm -f build-stamp - - rm -fr build - - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - - cd build && $(MAKE) install - -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do here - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir - dh_testroot - dh_installchangelogs Changelog - dh_installdocs - dh_installexamples - dh_installmenu - dh_link - dh_strip - dh_compress - dh_fixperms - dh_installdeb - dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install +%: + dh $@ --buildsystem=cmake diff -Nru cutecom-0.22.0/debian/source/format cutecom-0.30.3/debian/source/format --- cutecom-0.22.0/debian/source/format 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/debian/source/format 2016-10-03 20:04:20.000000000 +0000 @@ -0,0 +1 @@ +3.0 (quilt) diff -Nru cutecom-0.22.0/debian/watch cutecom-0.30.3/debian/watch --- cutecom-0.22.0/debian/watch 2016-10-04 08:09:25.000000000 +0000 +++ cutecom-0.30.3/debian/watch 2016-10-03 20:04:20.000000000 +0000 @@ -1,4 +1,5 @@ # Compulsory line, this is a version 3 file version=3 -http://cutecom.sourceforge.net/cutecom-(.*)\.tar\.gz +opts=filenamemangle=s/.+\/v?(\d\S*)\.tgz/cutecom-$1\.tgz/ \ + https://github.com/neundorf/CuteCom/tags .*/v?(\d\S*)\.tgz diff -Nru cutecom-0.22.0/devicecombo.cpp cutecom-0.30.3/devicecombo.cpp --- cutecom-0.22.0/devicecombo.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/devicecombo.cpp 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2015 Meinhard Ritscher + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "devicecombo.h" + +#include +#include "qdebug.h" + +void DeviceCombo::showPopup() +{ + refill(); + QComboBox::showPopup(); +} + +void DeviceCombo::refill() +{ + QString selection = currentText(); + clear(); + int numberDevices = 0; + for (auto info : QSerialPortInfo::availablePorts()) { + addItem(info.systemLocation()); + if (info.isValid()) { + QString deviceInfo = QString("%1 %2\n%3:%4 " +#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) + ) +#else + "# %5") +#endif + .arg(info.manufacturer()) + .arg(info.description()) + .arg(info.vendorIdentifier()) + .arg(info.productIdentifier()) +#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) + ; +#else + .arg(info.serialNumber()); +#endif + setItemData(numberDevices, deviceInfo, Qt::ToolTipRole); + } else { + setItemData(numberDevices, tr("Not a valid device"), Qt::ToolTipRole); + } + numberDevices++; + } + + int index = findText(selection); + if (index != -1) { + // found something - work done! + setCurrentIndex(index); + } else { + // maybe it's no longer connected + // ToDo add this in a different colour + // via a own model to indicate the + // device's absence + // add this to the list and select this anyway as + // the user might want to reconnect the device + // after reconnection the device will be shown in the + // error/unconnected colour since we will get no notification + // about devices beeing removed or attached + // which is our problem in the first place + addItem(selection); + setCurrentIndex(numberDevices); + } +} diff -Nru cutecom-0.22.0/devicecombo.h cutecom-0.30.3/devicecombo.h --- cutecom-0.22.0/devicecombo.h 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/devicecombo.h 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015 Meinhard Ritscher + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef DEVICECOMBO_H +#define DEVICECOMBO_H + +#include + +class DeviceCombo : public QComboBox +{ + Q_OBJECT + +public: + DeviceCombo(QWidget *parent = 0) + : QComboBox(parent){}; + + virtual void showPopup() Q_DECL_OVERRIDE; + +private: + void refill(); +}; + +#endif // DEVICECOMBO_H diff -Nru cutecom-0.22.0/distribution/Arch/PKGBUILD cutecom-0.30.3/distribution/Arch/PKGBUILD --- cutecom-0.22.0/distribution/Arch/PKGBUILD 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/Arch/PKGBUILD 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,36 @@ +# Maintainer: danitool dgcbueu at gmail.com +# Contributor: Siôn Le Roux , Alessandro Biavati + +pkgname=cutecom-patched +pkgver=0.22.0 +pkgrel=1 +pkgdesc="Cutecom graphical serial terminal, with some improvements taken from patches not officially commited" +arch=('i686' 'x86_64') +url="http://cutecom.sourceforge.net" +license=('GPL2') +depends=('qt4' 'lrzsz') +makedepends=('cmake') +conflicts=('cutecom') +source=("${url}/cutecom-${pkgver}.tar.gz" + 'improvements.diff') + +md5sums=('dd85ceecf5a60b4d9e4b21a338920561' + 'd5707a9f872571d1d27f2bdffa8e8e20') + +prepare(){ + cd ${srcdir}/cutecom-${pkgver} + patch -p1 -i ../improvements.diff +} + +build() { + cd ${srcdir}/cutecom-${pkgver} + cmake -DQT_QMAKE_EXECUTABLE=qmake4 . + make || return 1 +} + +package() { + cd ${srcdir}/cutecom-${pkgver} + install -D -m 644 cutecom.desktop ${pkgdir}/usr/share/applications/cutecom.desktop + install -D -m 755 cutecom ${pkgdir}/usr/bin/cutecom + install -D -m 644 cutecom.1 ${pkgdir}/usr/share/man/man1/cutecom.1 +} diff -Nru cutecom-0.22.0/distribution/Arch/README cutecom-0.30.3/distribution/Arch/README --- cutecom-0.22.0/distribution/Arch/README 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/Arch/README 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,10 @@ +Package specification for Arch Linux (https://www.archlinux.org) + +found on + +https://github.com/aur-archive/cutecom-patched.git +by: AUR Archive Bot +see PKGBUILD for maintaine + +SATUS: ummaintained - original CuteCom + Binary files /tmp/tmpcePm31/p6GNbfuPwL/cutecom-0.22.0/distribution/cutecom.png and /tmp/tmpcePm31/OHesuVlVo7/cutecom-0.30.3/distribution/cutecom.png differ diff -Nru cutecom-0.22.0/distribution/Debian/changelog cutecom-0.30.3/distribution/Debian/changelog --- cutecom-0.22.0/distribution/Debian/changelog 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/Debian/changelog 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,59 @@ +cutecom (0.22.0-2) unstable; urgency=low + + * Add cutecom-0.22.0-nolinebreak.diff (closes: #591666) + * Install menu item for simple window managers (was always present in + debian dir, but not installed), change deprecated Apps/Tools section + to Applications/System/Hardware (nothing more appropriate IMO) + * Move .desktop file from /usr/share/applnk to more appropriate + /usr/share/applications/kde (should fix Ubuntu bug 379932) + * Add cutecom-remove-deprecated-desktop-entries.patch, fixes lintian + warnings + * Upgrade package to standards 3.9.1 + + -- Roman I Khimov Thu, 12 Aug 2010 22:47:38 +0400 + +cutecom (0.22.0-1) unstable; urgency=low + + * New upstream release + * Upgrade package to standards 3.8.2 + + -- Roman I Khimov Mon, 13 Jul 2009 00:16:00 +0400 + +cutecom (0.21.0-1) unstable; urgency=low + + * New upstream release + * Upgrade package to standards 3.8.1 + + -- Roman I Khimov Wed, 13 May 2009 23:09:09 +0400 + +cutecom (0.20.0-1) unstable; urgency=low + + * New upstream release + * Switch from qt3 to qt4 + * Upgrade package to standards 3.8.0 + * Upgrade package to debhelper 7 + * Rewrite copyright file in machine-interpretable format + * Add homepage field in control + * Switch from dpatch to quilt for patch management + * Remove 01-fix_iostream_include.dpatch and 02-fix_comparison_warning.dpatch + patches (moved upstream) + * Add fix_pathes_for_debian.patch, changes install path to conform Debian + standards + + -- Roman I Khimov Sun, 23 Aug 2008 14:31:40 +0400 + +cutecom (0.14.1-2) unstable; urgency=low + + * Resolve 'cutecom override disparity' found by Debian Installer, moving + package into 'comm' section + + -- Roman I Khimov Fri, 27 Nov 2006 09:27:09 +0300 + +cutecom (0.14.1-1) unstable; urgency=low + + * Initial release (Closes: #400388) + * Change CMakeLists.txt to install cutecom.desktop into fixed (proper for + Debian) location. + * Add patches to fix compile warnings + + -- Roman I Khimov Fri, 26 Nov 2006 19:15:49 +0300 diff -Nru cutecom-0.22.0/distribution/Debian/compat cutecom-0.30.3/distribution/Debian/compat --- cutecom-0.22.0/distribution/Debian/compat 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/Debian/compat 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1 @@ +5 diff -Nru cutecom-0.22.0/distribution/Debian/copyright cutecom-0.30.3/distribution/Debian/copyright --- cutecom-0.22.0/distribution/Debian/copyright 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/Debian/copyright 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,18 @@ +Format-Specification: + http://wiki.debian.org/Proposals/CopyrightFormat?action=recall&rev=226 +Upstream-Name: CuteCom +Upstream-Source: http://github.com/neundorf/CuteCom +Upstream-Maintainer: Meinhard Ritscher + +Files: * +Copyright: Copyright 2004-2009, Alexander Neundorf +Copyright: Copyright 2015-2015, Meinhard Ritscher +License: GPL-3+ + On Debian systems the full text of the GNU General Public License can be found + in the `/usr/share/common-licenses/GPL-3' file. + +Files: debian/* +Copyright: Copyright 2006-2009 Roman I Khimov +License: GPL-2+ + On Debian systems the full text of the GNU General Public License can be found + in the `/usr/share/common-licenses/GPL-2' file. diff -Nru cutecom-0.22.0/distribution/Debian/cutecom.dsc cutecom-0.30.3/distribution/Debian/cutecom.dsc --- cutecom-0.22.0/distribution/Debian/cutecom.dsc 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/Debian/cutecom.dsc 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,9 @@ +Format: 1.0 +Source: cutecom +Version: 0.30-3 +Binary: CuteCom +Maintainer: Meinhard Ritscher +Architecture: any +Build-Depends: debhelper (>= 4.1.16), cmake (>= 2.8.11), qt5-default, libqt5serialport5-dev ,cutecom +Files: + a123e277faa328ccef665145e1ea4ada 125197 cutecom-0.30.3.tgz diff -Nru cutecom-0.22.0/distribution/Debian/cutecom.menu cutecom-0.30.3/distribution/Debian/cutecom.menu --- cutecom-0.22.0/distribution/Debian/cutecom.menu 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/Debian/cutecom.menu 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,2 @@ +?package(cutecom):needs="X11" section="Applications/System/Hardware"\ + title="Cutecom" command="/usr/bin/cutecom" diff -Nru cutecom-0.22.0/distribution/Debian/debian.changelog cutecom-0.30.3/distribution/Debian/debian.changelog --- cutecom-0.22.0/distribution/Debian/debian.changelog 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/Debian/debian.changelog 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,86 @@ +cutecom (0.30.3-0) unstable; urgency=low + * now builds and runs with Qt5 versions less 5.3 + * performance tuning by switching to QPlainTextEdit + + -- Meinhard Ritscher Mon, 15 Feb 2016 18:10:00 +0100 + +cutecom (0.30.2-0) unstable; urgency=low + * opening a connnection with more than 200000 Baud not possible - FIX + * custom baud rate not restored - FIX + * extra long lines are wrapped - less disturbing + + -- Meinhard Ritscher Mon, 11 Jan 2016 17:10:00 +0100 + +cutecom (0.30.1-0) unstable; urgency=low + * fixed a bug preventing to compile on gcc 5.2 + + -- Meinhard Ritscher Mon, 21 Dec 2015 11:20:00 +0100 + +cutecom (0.30.0-0) unstable; urgency=low + + * Reimplementation using Qt5 + * Feature enhancements + * Facelift GUI + + -- Meinhard Ritscher Fri, 18 Dec 2015 11:20:00 +0100 + + +cutecom (0.22.0-2) unstable; urgency=low + + * Add cutecom-0.22.0-nolinebreak.diff (closes: #591666) + * Install menu item for simple window managers (was always present in + debian dir, but not installed), change deprecated Apps/Tools section + to Applications/System/Hardware (nothing more appropriate IMO) + * Move .desktop file from /usr/share/applnk to more appropriate + /usr/share/applications/kde (should fix Ubuntu bug 379932) + * Add cutecom-remove-deprecated-desktop-entries.patch, fixes lintian + warnings + * Upgrade package to standards 3.9.1 + + -- Roman I Khimov Thu, 12 Aug 2010 22:47:38 +0400 + +cutecom (0.22.0-1) unstable; urgency=low + + * New upstream release + * Upgrade package to standards 3.8.2 + + -- Roman I Khimov Mon, 13 Jul 2009 00:16:00 +0400 + +cutecom (0.21.0-1) unstable; urgency=low + + * New upstream release + * Upgrade package to standards 3.8.1 + + -- Roman I Khimov Wed, 13 May 2009 23:09:09 +0400 + +cutecom (0.20.0-1) unstable; urgency=low + + * New upstream release + * Switch from qt3 to qt4 + * Upgrade package to standards 3.8.0 + * Upgrade package to debhelper 7 + * Rewrite copyright file in machine-interpretable format + * Add homepage field in control + * Switch from dpatch to quilt for patch management + * Remove 01-fix_iostream_include.dpatch and 02-fix_comparison_warning.dpatch + patches (moved upstream) + * Add fix_pathes_for_debian.patch, changes install path to conform Debian + standards + + -- Roman I Khimov Sun, 23 Aug 2008 14:31:40 +0400 + +cutecom (0.14.1-2) unstable; urgency=low + + * Resolve 'cutecom override disparity' found by Debian Installer, moving + package into 'comm' section + + -- Roman I Khimov Fri, 27 Nov 2006 09:27:09 +0300 + +cutecom (0.14.1-1) unstable; urgency=low + + * Initial release (Closes: #400388) + * Change CMakeLists.txt to install cutecom.desktop into fixed (proper for + Debian) location. + * Add patches to fix compile warnings + + -- Roman I Khimov Fri, 26 Nov 2006 19:15:49 +0300 diff -Nru cutecom-0.22.0/distribution/Debian/debian.control cutecom-0.30.3/distribution/Debian/debian.control --- cutecom-0.22.0/distribution/Debian/debian.control 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/Debian/debian.control 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,20 @@ +Source: cutecom +Section: comm +Priority: optional +Maintainer: Roman I Khimov +Build-Depends: debhelper (>= 4), cmake (>= 2.8.11), qt5-default, libqt5serialport5-dev +Standards-Version: 3.9.1 +Homepage: http://github.com/neundorf/CuteCom + +Package: cutecom +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Suggests: lrzsz +Description: Graphical serial terminal, like minicom + Cutecom is a graphical serial terminal, like minicom. + It is aimed mainly at hardware developers or other people who need a + terminal to talk to their devices. It features lineoriented interface + instead of character-oriented, xmodem, ymodem, zmodem support + (requires the lrzsz package) and hexadecimal input and output among + other things. + It is written using the Qt library originally by Trolltech (www.trolltech.com). diff -Nru cutecom-0.22.0/distribution/Debian/debian.rules cutecom-0.30.3/distribution/Debian/debian.rules --- cutecom-0.22.0/distribution/Debian/debian.rules 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/Debian/debian.rules 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,85 @@ +#!/usr/bin/make -f +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# This is the debhelper compatibility version to use. +export DH_COMPAT=4 + +CFLAGS = -g +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) +CFLAGS += -O0 +else +CFLAGS += -O2 +endif + +config: + dh_testdir + mkdir -p build + cd build && cmake -DCMAKE_INSTALL_PREFIX=$(CURDIR)/debian/cutecom/usr \ + -DCMAKE_CXX_FLAGS="$(CFLAGS)" -DCMAKE_C_FLAGS="$(CFLAGS)" \ + -DCMAKE_EXE_LINKER_FLAGS="-Wl,-z,defs" ../ + +build: build-stamp + +build-stamp: config + dh_testdir + + cd build && $(MAKE) + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp + + rm -fr build + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + cd build && make install DESTDIR=/usr/src/packages/BUILD/debian/cutecom + +# Build architecture-independent files here. +binary-indep: build install + # We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot +# dh_installdebconf + dh_installdocs + dh_installexamples + dh_installmenu +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_installinit + dh_installcron + dh_installman + dh_installinfo +# dh_undocumented + dh_installchangelogs + dh_link + dh_strip + dh_compress + dh_fixperms +# dh_makeshlibs + dh_installdeb +# dh_perl + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install diff -Nru cutecom-0.22.0/distribution/Debian/docs cutecom-0.30.3/distribution/Debian/docs --- cutecom-0.22.0/distribution/Debian/docs 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/Debian/docs 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1 @@ +TODO diff -Nru cutecom-0.22.0/distribution/Debian/README cutecom-0.30.3/distribution/Debian/README --- cutecom-0.22.0/distribution/Debian/README 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/Debian/README 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,13 @@ +Package specification for Debian + +found on + +https://github.com/pnx/CuteCom.git +Jorge Salamero Sanz +Roman I Khimov + + +SATUS: updated to create packages on the open build service + +https://davesteele.github.io/development/2015/05/02/debian-watch-file-format-for-signed-github-source-tars/ + diff -Nru cutecom-0.22.0/distribution/Debian/README.source cutecom-0.30.3/distribution/Debian/README.source --- cutecom-0.22.0/distribution/Debian/README.source 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/Debian/README.source 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1 @@ +This package uses quilt to manage patches, please refer to /usr/share/doc/quilt/README.source diff -Nru cutecom-0.22.0/distribution/Debian/watch cutecom-0.30.3/distribution/Debian/watch --- cutecom-0.22.0/distribution/Debian/watch 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/Debian/watch 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,5 @@ +# Compulsory line, this is a version 3 file +version=3 + +opts=filenamemangle=s/.+\/v?(\d\S*)\.tgz/cutecom-$1\.tgz/ \ + https://github.com/neundorf/CuteCom/tags .*/v?(\d\S*)\.tgz diff -Nru cutecom-0.22.0/distribution/OpenMandriva/cutecom.spec cutecom-0.30.3/distribution/OpenMandriva/cutecom.spec --- cutecom-0.22.0/distribution/OpenMandriva/cutecom.spec 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/OpenMandriva/cutecom.spec 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,103 @@ +%define ver 0.20.0 +%define rel 1 + +Name: cutecom +Version: 0.22.0 +Release: %mkrel %rel +URL: http://cutecom.sourceforge.net/ +Summary: Graphical serial terminal program +License: GPL +Group: Communications +Source: http://cutecom.sourceforge.net/%{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-root +BuildRequires: qt4-devel desktop-file-utils cmake + +%description +CuteCom is a graphical serial terminal, like minicom. It is aimed mainly at +hardware developers or other people who need a terminal to talk to their +devices. + +%prep +%setup -q + +%build +%cmake +%make + +%install +rm -Rf %{buildroot} +%makeinstall_std -C build + +desktop-file-install --vendor="" \ + --remove-category="Application" \ + --add-category="System;Settings" \ + --dir $RPM_BUILD_ROOT%{_datadir}/applications cutecom.desktop + +%clean +rm -Rf %{buildroot} + +%if %mdkversion < 200900 +%post +%{update_menus} +%endif + +%if %mdkversion < 200900 +%postun +%{clean_menus} +%endif + +%files +%defattr(-,root,root) +%{_bindir}/cutecom +%{_datadir}/applications/cutecom.desktop +%{_mandir}/man1/cutecom.1* +%doc README Changelog + + +%changelog +* Sun Aug 22 2010 Funda Wang 0.22.0-1mdv2011.0 ++ Revision: 571881 +- use standard cmake macro + +* Tue Jul 14 2009 Frederik Himpe 0.22.0-1mdv2010.0 ++ Revision: 396004 +- update to new version 0.22.0 + +* Thu May 14 2009 Frederik Himpe 0.21.0-1mdv2010.0 ++ Revision: 375720 +- update to new version 0.21.0 + +* Sat Jun 21 2008 Buchan Milne 0.20.0-1mdv2009.0 ++ Revision: 227733 +- New version 0.20.0 (qt4) + + + Pixel + - rpm filetriggers deprecates update_menus/update_scrollkeeper/update_mime_database/update_icon_cache/update_desktop_database/post_install_gconf_schemas + + + Olivier Blin + - restore BuildRoot + + + Thierry Vignaud + - kill re-definition of %%buildroot on Pixel's request + +* Thu Sep 06 2007 Emmanuel Andry 0.14.1-2mdv2008.0 ++ Revision: 81134 +- xdg menu +- drop old menu + + +* Sun Jan 28 2007 Buchan Milne 0.14.1-1mdv2007.0 ++ Revision: 114553 +- New version 0.14.1 +- Import cutecom + +* Sun Aug 20 2006 Buchan Milne 0.14.0-1mdv2007.0 +- 0.14.0 + +* Tue Jan 31 2006 Buchan Milne 0.13.2-2mdk +- buildrequire mandriva-create-kde-mdk-menu for kdedesktop2mdkmenu.pl +- buildrequires kdelibs-common for kdeconfig (placement of .desktop file) + +* Mon Jan 30 2006 Buchan Milne 0.13.2-1mdk +- initial package + diff -Nru cutecom-0.22.0/distribution/OpenMandriva/README cutecom-0.30.3/distribution/OpenMandriva/README --- cutecom-0.22.0/distribution/OpenMandriva/README 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/OpenMandriva/README 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,9 @@ +Package specification for OpenMandriva (https://www.openmandriva.org/) + +found on +https://github.com/OpenMandrivaAssociation/cutecom.git +by: Alex Burmashev + et al + +SATUS: ummaintained - original CuteCom + diff -Nru cutecom-0.22.0/distribution/openSUSE/cutecom.changes cutecom-0.30.3/distribution/openSUSE/cutecom.changes --- cutecom-0.22.0/distribution/openSUSE/cutecom.changes 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/openSUSE/cutecom.changes 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,48 @@ +------------------------------------------------------------------- +Mon Feb 15 20:20:20 UTC 2016 - cyc1ingsir@gmail.com + +-update to release 0.30.3 + * make build and run using Qt5 versions less 5.3 + * performance tuning switching to QPlainTextEdit + +------------------------------------------------------------------- +Thu Jan 14 14:21:11 UTC 2016 - opensuse@dstoecker.de + +- update to release 0.30.2 + * custom baud rates restored properly on startup + * custom baud rates > 200000 now selectable + * prevent horizontal scroll bar showing up (feedback) + +------------------------------------------------------------------- +Fri Dec 18 20:20:20 UTC 2015 - cyc1ingsir@gmail.com + +- reimplementation based on Qt5 +- including various feature enhancements +- removed cutecom-0.22.0-license.diff - codebase changed +- removed cutecom-0.22.0-nolinebreak.diff - codebase changed + +------------------------------------------------------------------- +Tue Nov 17 10:35:42 UTC 2015 - opensuse@dstoecker.de + +- fix build for Leap 42.1 +- correct FSF address + +------------------------------------------------------------------- +Thu Feb 23 17:08:17 UTC 2012 - opensuse@dstoecker.de + +- display correct license in about dialog + +------------------------------------------------------------------- +Thu Jan 12 11:30:33 UTC 2012 - coolo@suse.com + +- change license to be in spdx.org format + +------------------------------------------------------------------- +Tue Apr 26 18:39:52 CEST 2011 - opensuse@dstoecker.de + +- fix line breaking issue (patch copied from Debian) + +------------------------------------------------------------------- +Tue Jan 27 12:00:00 CEST 2009 - opensuse@dstoecker.de + +- initial setup diff -Nru cutecom-0.22.0/distribution/openSUSE/cutecom.desktop cutecom-0.30.3/distribution/openSUSE/cutecom.desktop --- cutecom-0.22.0/distribution/openSUSE/cutecom.desktop 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/openSUSE/cutecom.desktop 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=CuteCom +GenericName=Serial Terminal +Exec=cutecom +Icon=cutecom +Type=Application +Terminal=0 +X-KDE-StartupNotify=false +X-SuSE-translate=false +Categories=System;TerminalEmulator; diff -Nru cutecom-0.22.0/distribution/openSUSE/cutecom.spec cutecom-0.30.3/distribution/openSUSE/cutecom.spec --- cutecom-0.22.0/distribution/openSUSE/cutecom.spec 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/openSUSE/cutecom.spec 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,67 @@ +# +# spec file for package cutecom +# +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# + + + +Name: cutecom +Version: 0.30.3 +Release: 0 +Url: http://github.com/neundorf/CuteCom +BuildRoot: %{_tmppath}/%{name}-%{version}-build +BuildRequires: cmake +BuildRequires: gcc-c++ +BuildRequires: libqt5-qtbase-devel libqt5-qtserialport-devel +Summary: Serial terminal +License: GPL-3.0+ +Group: Applications/Communications +Source: %{name}-%{version}.tgz + +%description +Qt5 based serial terminal + +%prep +%setup + +%build +cmake . +make + +%install +mkdir -p $RPM_BUILD_ROOT/%{_bindir} +mkdir -p $RPM_BUILD_ROOT/%{_mandir}/man1 +install -s -m 755 %{name} $RPM_BUILD_ROOT/%{_bindir}/ +gzip %{name}.1 +install -m 644 %{name}.1.gz $RPM_BUILD_ROOT/%{_mandir}/man1/ + +install -d 755 $RPM_BUILD_ROOT%{_datadir}/applications +install -m 644 distribution/openSUSE/cutecom.desktop $RPM_BUILD_ROOT%{_datadir}/applications/ +install -d 755 $RPM_BUILD_ROOT%{_datadir}/pixmaps +install -m 644 images/cutecom.svg $RPM_BUILD_ROOT%{_datadir}/pixmaps/ + +%clean +rm -rf "$RPM_BUILD_ROOT" + +%files +%defattr(-,root,root) +%{_bindir}/%{name} +%{_mandir}/man1/%{name}.1.gz +%{_datadir}/applications/%{name}.desktop +%{_datadir}/pixmaps/cutecom.svg +%doc Changelog TODO LICENSE CREDITS README.md + +%changelog + diff -Nru cutecom-0.22.0/distribution/PLD/cutecom.spec cutecom-0.30.3/distribution/PLD/cutecom.spec --- cutecom-0.22.0/distribution/PLD/cutecom.spec 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/PLD/cutecom.spec 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,57 @@ +Summary: A graphical serial terminal +Summary(pl.UTF-8): Graficzny terminal szeregowy +Name: cutecom +Version: 0.22.0 +Release: 1 +License: GPL v2 +Group: Applications/Communications +Source0: http://cutecom.sourceforge.net/%{name}-%{version}.tar.gz +# Source0-md5: dd85ceecf5a60b4d9e4b21a338920561 +URL: http://cutecom.sourceforge.net/ +BuildRequires: Qt3Support-devel +BuildRequires: QtCore-devel +BuildRequires: QtGui-devel +BuildRequires: cmake > 2.4.3 +BuildRequires: qt4-build +BuildRequires: qt4-qmake +BuildRequires: rpmbuild(macros) >= 1.167 +BuildRoot: %{tmpdir}/%{name}-%{version}-root-%(id -u -n) + +%description +Cutecom is a graphical serial terminal, like minicom. It is aimed +mainly at hardware developers or other people who need a terminal to +talk to their devices. + +%description -l pl.UTF-8 +Cutecom to graficzny terminal szeregowy podobny do minicoma. Jest +przeznaczony głównie dla twórców sprzÄ™tu i innych ludzi potrzebujÄ…cych +terminala do komunikacji ze swoimi urzÄ…dzeniami. + +%prep +%setup -q + +echo "Categories=Qt;TerminalEmulator;" >> ./cutecom.desktop + +%build +%cmake \ + -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + . + +%install +rm -rf $RPM_BUILD_ROOT +install -d $RPM_BUILD_ROOT%{_desktopdir} + +%{__make} install \ + DESTDIR=$RPM_BUILD_ROOT + +install cutecom.desktop $RPM_BUILD_ROOT%{_desktopdir} + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(644,root,root,755) +%doc Changelog README TODO +%attr(755,root,root) %{_bindir}/cutecom +%{_desktopdir}/*.desktop +%{_mandir}/man1/*.1* diff -Nru cutecom-0.22.0/distribution/PLD/README cutecom-0.30.3/distribution/PLD/README --- cutecom-0.22.0/distribution/PLD/README 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/PLD/README 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,9 @@ +Package specification for PLD-Linux (https://www.pld-linux.org/) + +found on + +https://github.com/pld-linux/cutecom.git +by: PaweÅ‚ GoÅ‚aszewski + +SATUS: ummaintained - original CuteCom + diff -Nru cutecom-0.22.0/distribution/rpm-generic.spec.in cutecom-0.30.3/distribution/rpm-generic.spec.in --- cutecom-0.22.0/distribution/rpm-generic.spec.in 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/distribution/rpm-generic.spec.in 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,59 @@ +# +# spec file for package cutecom +# + +Buildroot: @CMAKE_CURRENT_BINARY_DIR@/_CPack_Packages/Linux/RPM/@CPACK_PACKAGE_FILE_NAME@ +Name: @CPACK_PACKAGE_NAME@ +Version: @CPACK_PACKAGE_VERSION@ +Release: @CPACK_PACKAGE_RELEASE@ +Url: https://github.com/aneundorf/cutecom +BuildRequires: cmake +BuildRequires: gcc-c++ +BuildRequires: libqt5-qtbase-devel +Summary: Serial terminal +License: GPL-3.0+ +Group: Applications/Communications + +%define _rpmdir @CMAKE_CURRENT_BINARY_DIR@/_CPack_Packages/Linux/RPM +%define _rpmfilename @CPACK_PACKAGE_FILE_NAME@.rpm +%define _unpacked_files_terminate_build 0 +%define _topdir @CMAKE_CURRENT_BINARY_DIR@/_CPack_Packages/Linux/RPM + +%description +Qt5 based serial terminal + +%prep +mv $RPM_BUILD_ROOT @CMAKE_CURRENT_BINARY_DIR@/_CPack_Packages/Linux/RPM/tmpBBroot + + +%install +if [ -e $RPM_BUILD_ROOT ]; +then + rm -rf $RPM_BUILD_ROOT +fi +mv "@CMAKE_CURRENT_BINARY_DIR@/_CPack_Packages/Linux/RPM/tmpBBroot" $RPM_BUILD_ROOT + + +%clean +rm -rf "$RPM_BUILD_ROOT" + +%files +%defattr(-,root,root) +@CPACK_PACKAGING_INSTALL_PREFIX@/@LIB_INSTALL_DIR@/* +@CPACK_PACKAGING_INSTALL_PREFIX@/usr/bin/cutecom + +%changelog +* Fri Dec 18 2015 cyc1ingsir@gmail.com +- Version 0.30 release +* Mon Nov 30 2015 cyc1ingsir@gmail.com +- Version 0.25 reimplemented using Qt5 +* Tue Oct 27 2015 cyc1ingsir@gmail.com +- version 0.23 based on Qt5 and command line sessions +* Thu Feb 23 2012 opensuse@dstoecker.de +- display correct license in about dialog +* Thu Jan 12 2012 coolo@suse.com +- change license to be in spdx.org format +* Tue Apr 26 2011 opensuse@dstoecker.de +- fix line breaking issue (patch copied from Debian) +* Tue Jan 27 2009 opensuse@dstoecker.de +- initial setup diff -Nru cutecom-0.22.0/.gitignore cutecom-0.30.3/.gitignore --- cutecom-0.22.0/.gitignore 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/.gitignore 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,38 @@ +# C++ objects and libs + +*.slo +*.lo +*.o +*.a +*.la +*.lai +*.so +*.dll +*.dylib +version.h + +# Qt-es + +/.qmake.cache +/.qmake.stash +CMakeLists.txt.user +*.pro.user +*.pro.user.* +*.qbs.user +*.qbs.user.* +*.moc +moc_*.cpp +qrc_*.cpp +ui_*.h +Makefile* +*-build-* + +# QtCreator + +*.autosave + +#QtCtreator Qml +*.qmlproject.user +*.qmlproject.user.* + + diff -Nru cutecom-0.22.0/images/cutecom.svg cutecom-0.30.3/images/cutecom.svg --- cutecom-0.22.0/images/cutecom.svg 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/images/cutecom.svg 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,429 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Terminal + 2005-10-15 + + + Andreas Nilsson + + + + + terminal + emulator + term + command line + + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru cutecom-0.22.0/images/info.svg cutecom-0.30.3/images/info.svg --- cutecom-0.22.0/images/info.svg 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/images/info.svg 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru cutecom-0.22.0/images/terminal.svg cutecom-0.30.3/images/terminal.svg --- cutecom-0.22.0/images/terminal.svg 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/images/terminal.svg 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,429 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Terminal + 2005-10-15 + + + Andreas Nilsson + + + + + terminal + emulator + term + command line + + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru cutecom-0.22.0/LICENSE cutecom-0.30.3/LICENSE --- cutecom-0.22.0/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/LICENSE 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,675 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program 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. + + This program 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 this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + diff -Nru cutecom-0.22.0/main.cpp cutecom-0.30.3/main.cpp --- cutecom-0.22.0/main.cpp 2008-07-06 18:35:08.000000000 +0000 +++ cutecom-0.30.3/main.cpp 2016-02-15 17:13:18.000000000 +0000 @@ -1,32 +1,56 @@ -/* Copyright (C) 2004-2005 Alexander Neundorf - - This program 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 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - +/* + * Copyright (C) 2004-2009 Alexander Neundorf + * Copyright (c) 2015 Meinhard Ritscher + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "mainwindow.h" +// version.h is generated via cmake +// if you use qmake, please cp version.h.in to version.h +#include "version.h" #include +#include +#include -#include "qcppdialogimpl.h" - -//signal handlers should be installed... -int main( int argc, char ** argv ) +int main(int argc, char *argv[]) { - QApplication a( argc, argv ); - QCPPDialogImpl w(0); + QApplication a(argc, argv); + + QCommandLineParser parser; + parser.setApplicationDescription( + QCoreApplication::translate("main", "CuteCom - Serial Terminal %1").arg(CuteCom_VERSION)); + parser.addHelpOption(); + QCommandLineOption sessionOption(QStringList() << "s" + << "session", + QCoreApplication::translate("main", "Open a named "), + QCoreApplication::translate("main", "session")); + parser.addOption(sessionOption); + + // Process the actual command line arguments given by the user + parser.process(a); + QString session = parser.value(sessionOption); + + MainWindow w(0, session); + QIcon appIcon; + appIcon.addFile(QStringLiteral(":/images/terminal.svg")); + w.setWindowIcon(appIcon); w.show(); - a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) ); + return a.exec(); } - diff -Nru cutecom-0.22.0/mainwindow.cpp cutecom-0.30.3/mainwindow.cpp --- cutecom-0.22.0/mainwindow.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/mainwindow.cpp 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,895 @@ +/* + * Copyright (C) 2004-2009 Alexander Neundorf (code used from original CuteCom) + * Copyright (C) 2013 Preet Desai (code to send files ported to Qt5 for the original CuteCom + * from https://github.com/preet/cutecom-qt5) + * Copyright (c) 2015 Meinhard Ritscher + * Copyright (c) 2015 Antoine Calando (improvements added to original CuteCom) + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "mainwindow.h" +#include "datadisplay.h" +#include "version.h" +#include "settings.h" +#include "qdebug.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void millisleep(unsigned long ms) +{ + if (ms > 0) { + QThread::msleep(ms); + } +} + +MainWindow::MainWindow(QWidget *parent, const QString &session) + : QMainWindow(parent) + , m_device(new QSerialPort(this)) + , m_deviceState(DEVICE_CLOSED) + , m_progress(nullptr) + , m_sz(nullptr) + , m_previousChar('\0') + , m_command_history_model(nullptr) + , m_keyRepeatTimer(this) + , m_keyCode('\0') + , m_cmdBufIndex(0) +{ + QCoreApplication::setOrganizationName(QStringLiteral("CuteCom")); + // setting it to CuteCom5 will prevent the original CuteCom's settings file + // to be overwritten + QCoreApplication::setApplicationName(QStringLiteral("CuteCom5")); + QCoreApplication::setApplicationVersion(QStringLiteral("%1").arg(CuteCom_VERSION)); + // qRegisterMetaType(); + + setupUi(this); + + m_bt_sendfile->setEnabled(false); + m_command_history->setEnabled(false); + + m_lb_logfile->setStyleSheet(" QLabel:hover{color: blue;} "); + + connect(m_bt_clear, &QPushButton::clicked, [=]() { + if (m_device->isOpen()) + m_input_edit->setFocus(); + m_output_display->clear(); + }); + connect(m_check_hex_out, &QCheckBox::toggled, m_output_display, &DataDisplay::setDisplayHex); + + // initialize settings stored in the config file + m_settings = new Settings(this); + m_settings->readSettings(session); + this->setWindowTitle("CuteCom - " + m_settings->getCurrentSessionName()); + + // restore window size from the settings + QRect geometry = m_settings->getWindowGeometry(); + if (geometry.width() > 0) + setGeometry(geometry); + + QStringList history = m_settings->getCurrentSession().command_history; + if (!history.empty()) { + m_command_history->addItems(history); + m_command_history->setCurrentRow(m_command_history->count() - 1); + m_command_history->scrollToItem(m_command_history->currentItem()); + m_command_history->clearSelection(); + } + + m_commandCompleter = new QCompleter(m_input_edit); + m_commandCompleter->setCompletionMode(QCompleter::InlineCompletion); + m_input_edit->setCompleter(m_commandCompleter); + updateCommandHistory(); + + // adds a custom context menu with a single entry to clear the command history + m_command_history->setContextMenuPolicy(Qt::CustomContextMenu); + m_command_history_menu = new QMenu(this); + QAction *clearAction = new QAction(tr("Clear History"), m_command_history); + m_command_history_menu->addAction(clearAction); + connect(clearAction, &QAction::triggered, m_command_history, [=]() { + m_command_history->clear(); + saveCommandHistory(); + }); + connect(m_command_history, &QListWidget::customContextMenuRequested, + [=](const QPoint &pos) { m_command_history_menu->exec(mapToParent(pos)); }); + + fillLineTerminationChooser(m_settings->getLineTerminator()); + + fillProtocolChooser(m_settings->getProtocol()); + + m_spinner_chardelay->setValue(m_settings->getCharacterDelay()); + connect(m_spinner_chardelay, static_cast(&QSpinBox::valueChanged), + [=](int value) { m_settings->settingChanged(Settings::CharacterDelay, value); }); + + // add the settings slide out panel + controlPanel = new ControlPanel(this->centralWidget(), m_settings); + + QMargins mainMargins = m_verticalLayout->contentsMargins(); + controlPanel->setLeftMargin(mainMargins.left()); + + // show the controlPanel + controlPanel->show(); + // slide this panel to the top + controlPanel->collapse(); + + // make sure there is enough room for the controls + int minWidth = controlPanel->frameGeometry().width(); + if (minWidth > m_mainSplitter->minimumWidth()) + m_mainSplitter->setMinimumWidth(minWidth); + + // make sure there is enough space for the collapsed panel + // above all other widgets + int hHeight = controlPanel->hiddenHeight(); + qDebug() << Q_FUNC_INFO << "calculated height: " << hHeight; + mainMargins.setTop(hHeight); + m_verticalLayout->setContentsMargins(mainMargins); + m_mainSplitter->installEventFilter(this); + + // setup status bar with initial infromation + m_device_statusbar = new StatusBar(this); + m_device_statusbar->sessionChanged(m_settings->getCurrentSession()); + this->statusBar()->addWidget(m_device_statusbar); + connect(m_settings, &Settings::sessionChanged, m_device_statusbar, &StatusBar::sessionChanged); + + m_output_display->setDisplayCtrlCharacters(m_settings->getCurrentSession().showCtrlCharacters); + m_output_display->setDisplayTime(m_settings->getCurrentSession().showTimestamp); + connect(controlPanel->m_check_timestamp, &QCheckBox::toggled, m_output_display, &DataDisplay::setDisplayTime); + connect(controlPanel->m_check_lineBreak, &QCheckBox::toggled, m_output_display, &DataDisplay::setDisplayCtrlCharacters); + + connect(controlPanel, &ControlPanel::openDeviceClicked, this, &MainWindow::openDevice); + connect(controlPanel, &ControlPanel::closeDeviceClicked, this, &MainWindow::closeDevice); + connect(m_device, + static_cast(&QSerialPort::error), this, + &MainWindow::handleError); + connect(m_device, &QSerialPort::readyRead, this, &MainWindow::processData); + + m_input_edit->installEventFilter(this); + connect(&m_keyRepeatTimer, &QTimer::timeout, this, &MainWindow::sendKey); + connect(m_input_edit, &QLineEdit::returnPressed, this, &MainWindow::execCmd); + connect(m_command_history, &QListWidget::itemClicked, this, &MainWindow::commandFromHistoryClicked); + connect(m_command_history, &QListWidget::doubleClicked, this, &MainWindow::execCmd); + connect(m_bt_sendfile, &QPushButton::clicked, this, &MainWindow::sendFile); + + // tie the control panel's edit and this window's information label together + m_lb_logfile->setText(m_settings->getLogFileLocation()); + m_lb_logfile->installEventFilter(this); + controlPanel->m_logfile_edit->setText(m_settings->getLogFileLocation()); + connect(controlPanel->m_logfile_edit, &QLineEdit::editingFinished, [=]() { + const QString text = controlPanel->m_logfile_edit->text(); + m_lb_logfile->setText(text); + m_settings->settingChanged(Settings::LogFileLocation, text); + }); + connect(m_check_logging, &QCheckBox::toggled, this, &MainWindow::toggleLogging); + + connect(actionAbout_CuteCom, &QAction::triggered, this, &MainWindow::showAboutMsg); + connect(actionAbout_Qt, &QAction::triggered, &QApplication::aboutQt); + + m_sessionManager = new SessionManager(m_settings, this); + connect(m_sessionManager, &SessionManager::sessionSwitched, this, &MainWindow::switchSession); + connect(m_sessionManager, &SessionManager::sessionRemoved, m_settings, &Settings::removeSession); + connect(m_sessionManager, &SessionManager::sessionRenamed, m_settings, &Settings::renameSession); + connect(m_sessionManager, &SessionManager::sessionCloned, m_settings, &Settings::cloneSession); + connect(actionManager, &QAction::triggered, m_sessionManager, &QDialog::show); +} + +bool MainWindow::eventFilter(QObject *obj, QEvent *event) +{ + if (obj == m_mainSplitter) { + if (event->type() == QEvent::Resize) { + if (((QResizeEvent *)event)->oldSize().width() != m_mainSplitter->width()) { + // qDebug() << ((QResizeEvent*) event)->oldSize().width() << " : " << m_mainSplitter->width(); + controlPanel->resize(m_verticalLayout->contentsRect().width(), controlPanel->height()); + } + } + return false; + } else if (obj == m_input_edit && event->type() == QEvent::KeyPress) { + QKeyEvent *ke = (QKeyEvent *)event; + if (ke->modifiers() == Qt::NoModifier) { + switch (ke->key()) { + case Qt::Key_Up: + prevCmd(); + return true; + case Qt::Key_Down: + nextCmd(); + return true; + case Qt::Key_PageDown: // fall through + case Qt::Key_PageUp: + QApplication::sendEvent(m_output_display, event); + return true; + default: + break; + } + } else if (ke->modifiers() == Qt::ControlModifier) { + switch (ke->key()) { + case Qt::Key_C: + // std::cerr<<"c"; + m_keyCode = 3; + sendByte(m_keyCode, 0); + m_keyRepeatTimer.setSingleShot(false); + m_keyRepeatTimer.start(0); + return true; + case Qt::Key_Q: + // std::cerr<<"#"; + m_keyCode = 17; + sendByte(m_keyCode, 0); + return true; + case Qt::Key_S: + m_keyCode = 19; + sendByte(m_keyCode, 0); + return true; + case Qt::Key_Down: // fall through + case Qt::Key_Up: // fall through + case Qt::Key_PageUp: // fall through + case Qt::Key_PageDown: // fall through + case Qt::Key_Home: // fall through + case Qt::Key_End: { + QKeyEvent cpy(QEvent::KeyPress, ke->key(), Qt::NoModifier); + QApplication::sendEvent(m_output_display, &cpy); + } + return true; + default: + break; + } + } + } else if ((obj == m_input_edit) && (event->type() == QEvent::KeyRelease)) { + m_keyRepeatTimer.stop(); + return false; + } else if ((obj == m_lb_logfile) && (event->type() == QEvent::MouseButtonPress)) { + if (m_device->isOpen()) { + QMessageBox::warning(this, tr("Can't change logfile location"), + tr("Device needs to be closed to change the logfile")); + } else { + controlPanel->slideOut(); + controlPanel->m_logfile_edit->setFocus(); + } + + return false; + } else { + return QMainWindow::eventFilter(obj, event); + } + return false; +} + +void MainWindow::resizeEvent(QResizeEvent *event) +{ + QMainWindow::resizeEvent(event); + m_settings->settingChanged(Settings::WindowGeometry, this->frameGeometry()); +} + +void MainWindow::openDevice() +{ + const Settings::Session session = m_settings->getCurrentSession(); + + if (session.device.isEmpty()) { + + QMessageBox::warning(this, tr("Opening not possible."), tr("No device has been specified")); + + controlPanel->closeDevice(); + return; + } + + m_device->setPortName(session.device); + m_deviceState = DEVICE_OPENING; + if (m_device->open(session.openMode)) { + m_deviceState = DEVICE_OPEN; + // printDeviceInfo(); // debugging + + m_device->setBaudRate(session.baudRate); + m_device->setDataBits(session.dataBits); + m_device->setParity(session.parity); + m_device->setStopBits(session.stopBits); + m_device->setFlowControl(session.flowControl); + + m_device->flush(); + + controlPanel->m_combo_device->setEnabled(false); + m_previousChar = '\0'; + + // display connection parameter on status bar + m_device_statusbar->setDeviceInfo(m_device); + + // enable all inputs if writing to the device is enabled + if (session.openMode == QIODevice::WriteOnly || session.openMode == QIODevice::ReadWrite) { + + m_input_edit->setEnabled(true); + m_input_edit->setFocus(); + m_bt_sendfile->setEnabled(true); + m_command_history->setEnabled(true); + } + } +} + +/** + * This is connected to the control panels closing signal. + * and need not to be called directly + * @brief MainWindow::closeDevice + */ +void MainWindow::closeDevice() +{ + m_device->clearError(); + m_device->close(); + m_deviceState = DEVICE_CLOSED; + m_input_edit->setEnabled(false); + controlPanel->m_bt_open->setFocus(); + controlPanel->m_combo_device->setEnabled(true); + m_bt_sendfile->setEnabled(false); + m_command_history->setEnabled(false); + if (m_logFile.isOpen()) { + m_logFile.flush(); + } +} + +/** + * This is connected to the error signal of the serial port + * beeing used. + * @brief MainWindow::handleError + * @param error + */ +void MainWindow::handleError(QSerialPort::SerialPortError error) +{ + if (error == QSerialPort::NoError) { + return; + } else if (m_deviceState == DEVICE_OPEN || m_deviceState == DEVICE_OPENING) { + // on hot unplug of usb2serial adapters, multiple errors will be + // reported which is of no importance to the users. + // reporting it once should be enough + QString heading = (m_deviceState == DEVICE_OPENING)? tr("Error opening device") : tr("Device Error"); + m_deviceState = DEVICE_CLOSING; + QMessageBox::critical(this, heading, m_device->errorString()); + // this will finally close the device too; + controlPanel->closeDevice(); + } else if(m_deviceState != DEVICE_CLOSING && m_deviceState != DEVICE_CLOSED) { + qDebug() << "Error-#" << error << " " << m_device->errorString(); + } + m_device->clearError(); +} + +/** + * This displays information about the device on the console window. + * Useful mainly for debugging or for a CLI version of cutecom + * @brief MainWindow::printDeviceInfo + */ +void MainWindow::printDeviceInfo() +{ + QSerialPortInfo info = QSerialPortInfo(*m_device); + qDebug() << info.description() << info.manufacturer() << info.productIdentifier() +#if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) + << info.serialNumber() +#endif + << info.portName(); + qDebug() << m_device->baudRate() << " : " << m_device->dataBits() << "-" << m_device->parity() << "-" + << m_device->stopBits() << " # " << m_device->flowControl(); +} + +void MainWindow::toggleLogging(bool start) +{ + if (m_logFile.isOpen() == start) { + return; + } + + if (start) { + m_logFile.setFileName(m_lb_logfile->text()); + QIODevice::OpenMode mode = QIODevice::ReadWrite; + mode = (controlPanel->m_check_appendLog->isChecked()) ? mode | QIODevice::Append : mode | QIODevice::Truncate; + + if (!m_logFile.open(mode)) { + QMessageBox::information(this, tr("Opening file failed"), + tr("Could not open file %1 for writing").arg(m_lb_logfile->text())); + m_check_logging->setChecked(false); + } + } else { + m_logFile.close(); + } +} + +void MainWindow::fillLineTerminationChooser(const Settings::LineTerminator setting) +{ + m_combo_lineterm->addItem(QStringLiteral("LF"), QVariant::fromValue(Settings::LF)); + m_combo_lineterm->addItem(QStringLiteral("CR"), QVariant::fromValue(Settings::CR)); + m_combo_lineterm->addItem(QStringLiteral("CR/LF"), QVariant::fromValue(Settings::CRLF)); + m_combo_lineterm->addItem(tr("None"), QVariant::fromValue(Settings::NONE)); + m_combo_lineterm->addItem(QStringLiteral("Hex"), QVariant::fromValue(Settings::HEX)); + + int index = m_combo_lineterm->findData((setting > Settings::HEX) ? Settings::LF : setting); + if (index != -1) { + m_combo_lineterm->setCurrentIndex(index); + } + connect(m_combo_lineterm, static_cast(&QComboBox::currentIndexChanged), + [=]() { m_settings->settingChanged(Settings::LineTermination, m_combo_lineterm->currentData()); }); +} + +/** + * Fills the ComboBox from which the user can select the protocoll used + * for sending a file across the device + * @brief MainWindow::fillProtocolChooser + * @param setting + */ +void MainWindow::fillProtocolChooser(const Settings::Protocol setting) +{ + m_combo_protocol->addItem(tr("Plain"), QVariant::fromValue(Settings::PLAIN)); + m_combo_protocol->addItem(tr("Script"), QVariant::fromValue(Settings::SCRIPT)); +#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX) || defined(Q_OS_MAC) + m_combo_protocol->addItem(tr("XModem"), QVariant::fromValue(Settings::XMODEM)); + m_combo_protocol->addItem(tr("YModem"), QVariant::fromValue(Settings::YMODEM)); + m_combo_protocol->addItem(tr("ZModem"), QVariant::fromValue(Settings::ZMODEM)); + m_combo_protocol->addItem(tr("1KXModem"), QVariant::fromValue(Settings::ONEKXMODEM)); +#endif + int index = m_combo_protocol->findData((setting < Settings::PROTOCOL_MAX) ? setting : Settings::PLAIN); + if (index != -1) { + m_combo_protocol->setCurrentIndex(index); + } + connect(m_combo_protocol, static_cast(&QComboBox::currentIndexChanged), + [=]() { m_settings->settingChanged(Settings::ProtocolOption, m_combo_protocol->currentData()); }); +} + +void MainWindow::showAboutMsg() +{ + QMessageBox::about(this, tr("About CuteCom"), + tr("This is CuteCom %1
(c)2004-2009 Alexander Neundorf, <neundorf@kde.org>" + "
(c)2015 Meinhard Ritscher, <unreachable@gmx.net>
and contributors" + "
Licensed under the GNU GPL version 3 (or any later version).").arg(CuteCom_VERSION)); +} + +void MainWindow::prevCmd() +{ + if (m_command_history->count() <= m_cmdBufIndex) { + return; + } + + m_cmdBufIndex++; + QListWidgetItem *item = m_command_history->item(m_command_history->count() - m_cmdBufIndex); + if (item != 0) { + m_command_history->setCurrentItem(item); + m_input_edit->setText(item->text()); + } +} + +void MainWindow::nextCmd() +{ + if (m_cmdBufIndex == 0) { + return; + } + + m_cmdBufIndex--; + if (m_cmdBufIndex == 0) { + m_input_edit->clear(); + m_command_history->setCurrentItem(0); + } else { + QListWidgetItem *it = m_command_history->item(m_command_history->count() - m_cmdBufIndex); + m_command_history->setCurrentItem(it); + m_input_edit->setText(it->text()); + } +} + +void MainWindow::execCmd() +{ + m_cmdBufIndex = 0; + QString cmd = m_input_edit->text().trimmed(); + m_input_edit->clear(); + if (!cmd.isEmpty()) { + bool found = false; + QList list = m_command_history->findItems(cmd, 0); + for (QListWidgetItem *item : list) { + item = m_command_history->takeItem(m_command_history->row(item)); + delete item; + found = true; + } + + m_command_history->addItem(cmd); + m_command_history->setCurrentRow(m_command_history->count() - 1); + if (m_command_history->count() > 50) + m_command_history->removeItemWidget(m_command_history->item(0)); + + // Do not save settings if there is no new string + if (!found) { + saveCommandHistory(); + updateCommandHistory(); + } + // emit settingChanged .... // emit commandHistoryChanged and connect to settings slot above + } + m_command_history->clearSelection(); + if (!m_device->isOpen()) { + return; + } + + sendString(cmd); +} + +void MainWindow::commandFromHistoryClicked(QListWidgetItem *item) +{ + if (item == 0) + return; + m_input_edit->setText(item->text()); + m_input_edit->setFocus(); +} + +void MainWindow::saveCommandHistory() +{ + QStringList history; + for (int i = 0; i < m_command_history->count(); i++) { + history << m_command_history->item(i)->text(); + } + m_settings->settingChanged(Settings::CommandHistory, history); +} + +bool MainWindow::sendString(const QString &s) +{ + Settings::LineTerminator lineMode = m_combo_lineterm->currentData().value(); + // ToDo + unsigned int charDelay = m_spinner_chardelay->value(); + + if (lineMode == Settings::HEX) // hex + { + QString hex = s; + hex.remove(QRegExp("\\s")); + if ((hex.startsWith("0x")) || (hex.startsWith("0X"))) { + hex = hex.mid(2); + } + + if (hex.length() % 2 != 0) { + hex = "0" + hex; + } + + for (int i = 0; i < hex.length() / 2; i++) { + QString nextByte = hex.mid(i * 2, 2); + bool ok = true; + nextByte.toUInt(&ok, 16); + if (!ok) { + QMessageBox::information(this, tr("Invalid hex characters"), + tr("The input string contains invalid hex characters: 0x%1").arg(nextByte)); + return false; + } + } + + for (int i = 0; i < hex.length() / 2; i++) { + QString nextByte = hex.mid(i * 2, 2); + unsigned int byte = nextByte.toUInt(0, 16); + sendByte(byte & 0xff, charDelay); + // fprintf(stderr, " 0x%x d:%d ", byte & 0xff, charDelay); + } + return true; + } + + const QByteArray bytes = s.toLatin1(); + for (int i = 0; i < bytes.length(); i++) { + if (!sendByte(bytes[i], charDelay)) + return false; + } + + switch (lineMode) { + case Settings::LF: + if (!sendByte('\n', charDelay)) + return false; + break; + case Settings::CR: + if (!sendByte('\r', charDelay)) + return false; + break; + case Settings::CRLF: + if (!sendByte('\r', charDelay)) + return false; + if (!sendByte('\n', charDelay)) + return false; + break; + default: + break; + } + + return true; +} + +bool MainWindow::sendByte(const char c, unsigned long delay) +{ + if (!m_device->isOpen()) { + return false; + } + if ((m_device->write(&c, 1)) < 1) { + qDebug() << m_device->errorString(); + return false; + } + + if (delay) { + millisleep(delay); + m_device->flush(); + } + return true; +} + +void MainWindow::sendKey() { sendByte(m_keyCode, 0); } + +/** + * Presents a file chooser dialog with which the user may select one + * single file which will be sent across the previously opened serial port + * device using the protocol selected + * @brief MainWindow::sendFile + */ +void MainWindow::sendFile() +{ + QFileDialog fileDlg(this); + + fileDlg.setDirectory(m_settings->getSendStartDir()); + fileDlg.setFileMode(QFileDialog::ExistingFile); + + QString filename; + if (fileDlg.exec()) { + QStringList fn = fileDlg.selectedFiles(); + if (!fn.isEmpty()) + filename = fn[0]; + else + return; + m_settings->settingChanged(Settings::SendStartDir, fileDlg.directory().absolutePath()); + } else { + return; + } + + unsigned long charDelay = static_cast(m_spinner_chardelay->value()); + + Settings::Protocol protocol = m_combo_protocol->currentData().value(); + if (protocol == Settings::PLAIN) { + QFile fd(filename); + if (!fd.open(QIODevice::ReadOnly)) { + QMessageBox::warning(this, tr("Opening file failed"), tr("Could not open file %1").arg(filename)); + return; + } + QByteArray data = fd.readAll(); + delete m_progress; + m_progress = new QProgressDialog(tr("Sending file..."), tr("Cancel"), 0, 100, this); + m_progress->setMinimumDuration(100); + unsigned int step = data.size() / 100; + if (step < 1) { + step = 1; + } + for (int i = 0; i < data.size(); i++) { + if ((i % step) == 0) { + m_progress->setValue(i / step); + qApp->processEvents(); + } + sendByte(data.at(i), charDelay); + if ((data.at(i) == '\n') || (data.at(i) == '\r')) { + // waiting twice as long after bytes whigh might by line ends + //(this helps some uCs) + millisleep(charDelay); + } + if (0) { + QMessageBox::information(this, tr("Comm error"), tr("Sending failed (%1/%2").arg(i).arg(data.count())); + break; + } + if (m_progress->wasCanceled()) + break; + } + delete m_progress; + m_progress = nullptr; + + } else if (protocol == Settings::SCRIPT) { + QFile fd(filename); + if (!fd.open(QIODevice::ReadOnly)) { + QMessageBox::warning(this, tr("Opening file failed"), tr("Could not open file %1").arg(filename)); + return; + } + + QTextStream stream(&fd); + while (!stream.atEnd()) { + QString nextLine = stream.readLine(); + nextLine = nextLine.left((unsigned int)nextLine.indexOf("#")); + if (nextLine.isEmpty()) + continue; + + if (!sendString(nextLine)) { + QMessageBox::information(this, tr("Comm error"), tr("Sending failed")); + return; + } + millisleep(charDelay * 3); + } + + } else if (protocol == Settings::XMODEM || protocol == Settings::YMODEM || protocol == Settings::ZMODEM + || protocol == Settings::ONEKXMODEM) { + closeDevice(); + m_sz = new QProcess(this); + + QStringList listProcessArgs; + listProcessArgs.append("-c"); + + QString tmp = QString("sz "); + switch (protocol) { + case Settings::XMODEM: + tmp += "--xmodem"; + break; + case Settings::YMODEM: + tmp += "--ymodem"; + break; + case Settings::ZMODEM: + tmp += "--zmodem"; + break; + case Settings::ONEKXMODEM: + tmp += "--xmodem --1k"; + break; + default: + break; + } + QString device = controlPanel->m_combo_device->currentText(); + tmp = tmp + "-vv \"" + filename + "\" < " + device + " > " + device; + listProcessArgs.append(tmp); + + m_sz->setReadChannel(QProcess::StandardError); + + connect(m_sz, &QProcess::readyReadStandardError, this, &MainWindow::readFromStdErr); + connect(m_sz, static_cast(&QProcess::finished), this, + &MainWindow::sendDone); + + m_sz->start("sh", listProcessArgs); + if (!!m_sz->waitForStarted()) { + QMessageBox::information(this, tr("Comm error"), tr("Could not start sz")); + delete m_sz; + openDevice(); + return; + } + m_progress = new QProgressDialog(tr("Sending file via %1 ...").arg(protocol), tr("Cancel"), 0, 100, this); + connect(m_progress, &QProgressDialog::canceled, this, &MainWindow::killSz); + m_progress->setMinimumDuration(100); + QFileInfo fi(filename); + m_progressStepSize = fi.size() / 1024 / 100; + if (m_progressStepSize < 1) + m_progressStepSize = 1; + + m_progress->setValue(0); + while (m_sz->state() == QProcess::Running) { + qApp->processEvents(); + millisleep(10L); + } + + delete m_sz; + m_sz = nullptr; + delete m_progress; + m_progress = nullptr; + openDevice(); + } else { + QMessageBox::information(this, tr("Unsupported Protocol"), tr("The selected protocoll is not supported (yet)")); + } +} + +/** + * @brief MainWindow::killSz + */ +void MainWindow::killSz() +{ + if (m_sz == nullptr) + return; + m_sz->terminate(); +} + +void MainWindow::switchSession(const QString &session) +{ + if (m_device->isOpen()) + closeDevice(); + m_settings->settingChanged(Settings::CurrentSession, session); + controlPanel->applySessionSettings(m_settings->getCurrentSession()); + m_command_history->clear(); + QStringList history = m_settings->getCurrentSession().command_history; + if (!history.empty()) { + m_command_history->addItems(history); + m_command_history->setCurrentRow(m_command_history->count() - 1); + m_command_history->scrollToItem(m_command_history->currentItem()); + m_command_history->clearSelection(); + } + delete m_commandCompleter; + m_commandCompleter = new QCompleter(history, m_input_edit); + m_input_edit->setCompleter(m_commandCompleter); + this->setWindowTitle("CuteCom - " + session); +} + +void MainWindow::updateCommandHistory() +{ + if (m_command_history_model != nullptr) + m_command_history_model = dynamic_cast(m_commandCompleter->model()); + + if (m_command_history_model == nullptr) + m_command_history_model = new QStringListModel(); + + QStringList history = m_settings->getCurrentSession().command_history; + m_command_history_model->setStringList(history); + m_commandCompleter->setModel(m_command_history_model); +} + + +/** + * @brief MainWindow::readFromStdErr + */ +void MainWindow::readFromStdErr() +{ + QByteArray ba = m_sz->readAllStandardError(); + if (m_progress == nullptr) { + return; + } + QString s(ba); + QRegExp regex(".+\\d+/ *(\\d+)k.*"); + int pos = regex.indexIn(s); + if (pos > -1) { + QString captured = regex.cap(1); + // cerr<<"captured kb: -"<setValue(p); + } + } + } + // else + // cerr<<"--------"<readAll(); + // Debugging: + // QString temp = QString(QStringLiteral("abcd\ncd\tef\nuvwxyz12345\r\n67890123456\r\n-----\2---\0---\n")); + // QByteArray data = temp.toLatin1(); + // :Debugging + + if (m_logFile.isOpen()) { + m_logFile.write(data); + } + m_output_display->displayData(data); + +} + +MainWindow::~MainWindow() +{ + if (m_device->isOpen()){ + m_deviceState = DEVICE_CLOSING; + closeDevice(); + } + if (m_logFile.isOpen()) + m_logFile.close(); + delete m_settings; +} diff -Nru cutecom-0.22.0/mainwindow.h cutecom-0.30.3/mainwindow.h --- cutecom-0.22.0/mainwindow.h 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/mainwindow.h 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2015 Meinhard Ritscher + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include "ui_mainwindow.h" +#include "controlpanel.h" +#include "sessionmanager.h" +#include "statusbar.h" +#include "settings.h" + +#include +#include +#include +#include +#include + +class MainWindow : public QMainWindow, public Ui::MainWindow +{ + Q_OBJECT + + enum DeviceState { + DEVICE_CLOSED, + DEVICE_OPENING, + DEVICE_OPEN, + DEVICE_CLOSING + }; + +public: + explicit MainWindow(QWidget *parent = 0, const QString &session = ""); + ~MainWindow(); + +protected: + bool eventFilter(QObject *obj, QEvent *event); + +private: + void openDevice(); + void closeDevice(); + void processData(); + void handleError(QSerialPort::SerialPortError); + void printDeviceInfo(); + void showAboutMsg(); + void setHexOutputFormat(bool checked); + void saveCommandHistory(); + +protected: + void prevCmd(); + void nextCmd(); + void execCmd(); + void commandFromHistoryClicked(QListWidgetItem *item); + bool sendString(const QString &s); + bool sendByte(const char c, unsigned long delay); + void sendKey(); + void sendFile(); + void readFromStdErr(); + void sendDone(int exitCode, QProcess::ExitStatus exitStatus); + void resizeEvent(QResizeEvent *event); + +private: + void toggleLogging(bool start); + void fillLineTerminationChooser(const Settings::LineTerminator setting = Settings::LF); + void fillProtocolChooser(const Settings::Protocol setting = Settings::PLAIN); + void killSz(); + void switchSession(const QString &session); + void updateCommandHistory(); + + ControlPanel *controlPanel; + SessionManager *m_sessionManager; + QSerialPort *m_device; + DeviceState m_deviceState; + StatusBar *m_device_statusbar; + Settings *m_settings; + QProgressDialog *m_progress; + int m_progressStepSize; + QProcess *m_sz; + bool m_devices_needs_refresh; + char m_previousChar; + QTime m_timestamp; + QFile m_logFile; + + QCompleter *m_commandCompleter; + QStringListModel *m_command_history_model; + QMenu *m_command_history_menu; + + /** + * @brief m_keyRepeatTimer + */ + QTimer m_keyRepeatTimer; + char m_keyCode; + + /** + * @brief m_cmdBufIndex + */ + int m_cmdBufIndex; +}; + +#endif // MAINWINDOW_H diff -Nru cutecom-0.22.0/mainwindow.ui cutecom-0.30.3/mainwindow.ui --- cutecom-0.22.0/mainwindow.ui 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/mainwindow.ui 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,353 @@ + + + MainWindow + + + + 0 + 0 + 500 + 320 + + + + CuteCom + + + + + 0 + + + QLayout::SetDefaultConstraint + + + 9 + + + + + Qt::Vertical + + + + + 0 + 1 + + + + QFrame::NoFrame + + + QFrame::Plain + + + + 0 + + + 0 + + + 0 + + + 0 + + + 3 + + + + + true + + + + + + + 2 + + + 0 + + + + + &Input: + + + m_input_edit + + + + + + + false + + + + + + + Select the line end termination + + + + + + + Delay between single characters + + + Char delay: + + + false + + + + + + + Qt::ClickFocus + + + Delay between single characters + + + ms + + + 250 + + + 0 + + + + + + + ArrowCursor + + + Select a file to be sent using the specified protocol + + + S&end file... + + + false + + + + + + + Qt::NoFocus + + + Select the transfer protocol + + + + + + + + + + + 0 + 2 + + + + QFrame::NoFrame + + + QFrame::Plain + + + + 0 + + + 0 + + + 3 + + + 0 + + + 0 + + + + + false + + + true + + + + + + + 2 + + + + + Clear the output window + + + C&lear + + + Alt+L + + + + + + + + 1 + 0 + + + + Show the output in hexadecimal format + + + He&x output + + + Alt+X + + + + + + + Enable logging the data to a file. + + + Logging to: + + + + + + + + 100 + 0 + + + + PointingHandCursor + + + + + + + + + + Qt::Horizontal + + + + 140 + 20 + + + + + + + + + + + + + + + + 0 + 0 + 500 + 19 + + + + + S&essions + + + + + + + &Help + + + + + + + + + + + false + + + Open + + + + + Save + + + + + Session &Manager ... + + + Open Session Manager + + + + + + :/images/info.svg:/images/info.svg + + + About CuteCom + + + + + About Qt + + + + + + + + + diff -Nru cutecom-0.22.0/qcppdialogimpl.cpp cutecom-0.30.3/qcppdialogimpl.cpp --- cutecom-0.22.0/qcppdialogimpl.cpp 2009-06-25 20:10:49.000000000 +0000 +++ cutecom-0.30.3/qcppdialogimpl.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1440 +0,0 @@ -/* Copyright (C) 2004-2009 Alexander Neundorf - - This program 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 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "qcppdialogimpl.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//Added by qt3to4: -#include -#include -#include -#include - -#include -#include - - -#include -using namespace std; - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void millisleep(int ms) -{ - if (ms>0) - { - struct timeval tv; - tv.tv_sec=0; - tv.tv_usec=ms*1000; - select(0, 0, 0, 0, &tv); - } -} - -QCPPDialogImpl::QCPPDialogImpl(QWidget* parent) -:QWidget(parent) -,m_isConnected(false) -,m_fd(-1) -,m_cmdBufIndex(0) -,m_notifier(0) -,m_sz(0) -,m_progress(0) -,m_progressStepSize(1000) -,m_fileDlg(0) -,m_outputTimer(this) -,m_keyRepeatTimer(this) -,m_keyCode(0) -,m_hexBytes(0) -,m_previousChar('\0') -{ - QCoreApplication::setOrganizationName("CuteCom"); -// QCoreApplication::setOrganizationDomain("mysoft.com"); - QCoreApplication::setApplicationName("CuteCom"); - - this->setupUi(this); - fillBaudCb(); - - connect(m_connectPb, SIGNAL(clicked()), this, SLOT(connectTTY())); - connect(m_closePb, SIGNAL(clicked()), this, SLOT(disconnectTTY())); - connect(m_clearOutputPb, SIGNAL(clicked()), this, SLOT(clearOutput())); -// connect(m_clearInputPb, SIGNAL(clicked()), m_oldCmdsLb, SLOT(clear())); - - connect(m_cmdLe, SIGNAL(returnPressed()), this, SLOT(execCmd())); - - connect(m_sendPb, SIGNAL(clicked()), this, SLOT(sendFile())); - connect(m_aboutPb, SIGNAL(clicked()), this, SLOT(showAboutMsg())); - connect(m_quitPb, SIGNAL(clicked()), this, SLOT(close())); - - connect(m_oldCmdsLb, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(oldCmdClicked(QListWidgetItem*))); - connect(m_oldCmdsLb, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(execCmd())); - - connect(m_hexOutputCb, SIGNAL(toggled(bool)), this, SLOT(hexOutputClicked(bool))); - - connect(m_connectPb, SIGNAL(clicked()), this, SLOT(saveSettings())); - connect(m_deviceCb, SIGNAL(activated(int)), this, SLOT(saveSettings())); - connect(m_baudCb, SIGNAL(activated(int)), this, SLOT(saveSettings())); - connect(m_dataBitsCb, SIGNAL(activated(int)), this, SLOT(saveSettings())); - connect(m_parityCb, SIGNAL(activated(int)), this, SLOT(saveSettings())); - connect(m_stopCb, SIGNAL(activated(int)), this, SLOT(saveSettings())); - connect(m_protoPb, SIGNAL(activated(int)), this, SLOT(saveSettings())); - connect(m_softwareCb, SIGNAL(clicked()), this, SLOT(saveSettings())); - connect(m_hardwareCb, SIGNAL(clicked()), this, SLOT(saveSettings())); - connect(m_readCb, SIGNAL(clicked()), this, SLOT(saveSettings())); - connect(m_writeCb, SIGNAL(clicked()), this, SLOT(saveSettings())); - connect(m_applyCb, SIGNAL(clicked()), this, SLOT(saveSettings())); - connect(m_hexOutputCb, SIGNAL(clicked()), this, SLOT(saveSettings())); - connect(m_inputModeCb, SIGNAL(activated(int)), this, SLOT(saveSettings())); - connect(m_charDelaySb, SIGNAL(valueChanged(int)), this, SLOT(saveSettings())); - connect(m_logAppendCb, SIGNAL(activated(int)), this, SLOT(saveSettings())); - - connect(m_applyCb, SIGNAL(toggled(bool)), this, SLOT(enableSettingWidgets(bool))); - connect(m_logFileFileDialog, SIGNAL(clicked()), this, SLOT(chooseLogFile())); - - connect(&m_outputTimer, SIGNAL(timeout()), this, SLOT(doOutput())); - connect(&m_keyRepeatTimer, SIGNAL(timeout()), this, SLOT(sendKey())); - - connect(m_enableLoggingCb, SIGNAL(toggled(bool)), this, SLOT(enableLogging(bool))); -// connect(m_enableLoggingCb, SIGNAL(toggled(bool)), this, SLOT(enableLogging(bool))); - - m_outputView->setWordWrapMode(QTextOption::WrapAnywhere); - m_outputView->document()->setMaximumBlockCount(500); -// TODO ? m_outputView->setWordWrap(Q3TextEdit::WidgetWidth); - -/* QAccel* accel=new QAccel(this); - accel->insertItem(CTRL+Key_C, 3); - accel->insertItem(CTRL+Key_Q, 17); - accel->insertItem(CTRL+Key_S, 19); - connect(accel, SIGNAL(activated(int)), this, SLOT(sendByte(int)));*/ - - m_outputTimerStart.start(); - - readSettings(); - - disconnectTTY(); - - m_cmdLe->installEventFilter(this); -} - -void QCPPDialogImpl::fillBaudCb() -{ -#ifdef B0 - m_baudCb->addItem("0"); -#endif - -#ifdef B50 - m_baudCb->addItem("50"); -#endif -#ifdef B75 - m_baudCb->addItem("75"); -#endif -#ifdef B110 - m_baudCb->addItem("110"); -#endif -#ifdef B134 - m_baudCb->addItem("134"); -#endif -#ifdef B150 - m_baudCb->addItem("150"); -#endif -#ifdef B200 - m_baudCb->addItem("200"); -#endif -#ifdef B300 - m_baudCb->addItem("300"); -#endif -#ifdef B600 - m_baudCb->addItem("600"); -#endif -#ifdef B1200 - m_baudCb->addItem("1200"); -#endif -#ifdef B1800 - m_baudCb->addItem("1800"); -#endif -#ifdef B2400 - m_baudCb->addItem("2400"); -#endif -#ifdef B4800 - m_baudCb->addItem("4800"); -#endif -#ifdef B7200 - m_baudCb->addItem("7200"); -#endif -#ifdef B9600 - m_baudCb->addItem("9600"); -#endif -#ifdef B14400 - m_baudCb->addItem("14400"); -#endif -#ifdef B19200 - m_baudCb->addItem("19200"); -#endif -#ifdef B28800 - m_baudCb->addItem("28800"); -#endif -#ifdef B38400 - m_baudCb->addItem("38400"); -#endif -#ifdef B57600 - m_baudCb->addItem("57600"); -#endif -#ifdef B76800 - m_baudCb->addItem("76800"); -#endif - - // this one is the default (without special reason) - m_baudCb->addItem("115200"); - m_baudCb->setCurrentIndex(m_baudCb->count()-1); - -#ifdef B128000 - m_baudCb->addItem("128000"); -#endif -#ifdef B230400 - m_baudCb->addItem("230400"); -#endif -#ifdef B460800 - m_baudCb->addItem("460800"); -#endif -#ifdef B576000 - m_baudCb->addItem("576000"); -#endif -#ifdef B921600 - m_baudCb->addItem("921600"); -#endif -} - -void QCPPDialogImpl::resizeEvent(QResizeEvent *e) -{ - QWidget::resizeEvent(e); - saveSettings(); -} - -void QCPPDialogImpl::saveSettings() -{ - QSettings settings; - settings.setValue("/cutecom/HardwareHandshake", m_hardwareCb->isChecked()); - settings.setValue("/cutecom/SoftwareHandshake", m_softwareCb->isChecked()); - - settings.setValue("/cutecom/OpenForReading", m_readCb->isChecked()); - settings.setValue("/cutecom/OpenForWriting", m_writeCb->isChecked()); - settings.setValue("/cutecom/DontApplySettings", !m_applyCb->isChecked()); - - settings.setValue("/cutecom/Device", m_deviceCb->currentText()); - settings.setValue("/cutecom/Baud", m_baudCb->currentItem()); - settings.setValue("/cutecom/Databits", m_dataBitsCb->currentItem()); - settings.setValue("/cutecom/Parity", m_parityCb->currentItem()); - settings.setValue("/cutecom/Stopbits", m_stopCb->currentItem()); - settings.setValue("/cutecom/Protocol", m_protoPb->currentItem()); - settings.setValue("/cutecom/width", width()); - settings.setValue("/cutecom/height", height()); - - settings.setValue("/cutecom/LineMode", m_inputModeCb->currentItem()); - settings.setValue("/cutecom/HexOutput", m_hexOutputCb->isChecked()); - settings.setValue("/cutecom/CharDelay", m_charDelaySb->value()); - - settings.setValue("/cutecom/SendFileDialogStartDir", m_sendFileDialogStartDir); - settings.setValue("/cutecom/LogFileName", m_logFileLe->text()); - - settings.setValue("/cutecom/AppendToLogFile", m_logAppendCb->currentItem()); - - - QString currentDevice=m_deviceCb->currentText(); - settings.setValue("/cutecom/CurrentDevice", currentDevice); - bool currentDeviceIsInList=false; - QStringList devices; - for (int i=0; icount(); i++) - { - QString s=m_deviceCb->itemText(i); - devices<count(); - if (historyCount>50) - { - historyCount=50; - } - - QStringList saveHist; - for (unsigned int i=m_oldCmdsLb->count()-historyCount; icount(); i++) - { - saveHist << m_oldCmdsLb->item(i)->text(); - } - settings.setValue("/cutecom/History", saveHist); -} - -void QCPPDialogImpl::readSettings() -{ - QSettings settings; - m_hardwareCb->setChecked(settings.value("/cutecom/HardwareHandshake", false).toBool()); - m_softwareCb->setChecked(settings.value("/cutecom/SoftwareHandshake", false).toBool()); - m_readCb->setChecked(settings.value("/cutecom/OpenForReading", true).toBool()); - m_writeCb->setChecked(settings.value("/cutecom/OpenForWriting", true).toBool()); - - m_applyCb->setChecked(!settings.value("/cutecom/DontApplySettings", false).toBool()); - enableSettingWidgets(m_applyCb->isChecked()); - - int defaultBaud = settings.value("/cutecom/Baud", -1).toInt(); - if (defaultBaud != -1) - { - m_baudCb->setCurrentIndex(defaultBaud); - } - m_dataBitsCb->setCurrentIndex(settings.value("/cutecom/Databits", 3).toInt()); - m_parityCb->setCurrentIndex(settings.value("/cutecom/Parity", 0).toInt()); - m_stopCb->setCurrentIndex(settings.value("/cutecom/Stopbits", 0).toInt()); - m_protoPb->setCurrentIndex(settings.value("/cutecom/Protocol", 0).toInt()); - - m_inputModeCb->setCurrentIndex(settings.value("/cutecom/LineMode", 0).toInt()); - m_hexOutputCb->setChecked(settings.value("/cutecom/HexOutput", false).toBool()); - m_charDelaySb->setValue(settings.value("/cutecom/CharDelay", 1).toInt()); - - m_sendFileDialogStartDir=settings.value("/cutecom/SendFileDialogStartDir", QDir::homePath()).toString(); - m_logFileLe->setText(settings.value("/cutecom/LogFileName", QDir::homePath()+"/cutecom.log").toString()); - - m_logAppendCb->setCurrentIndex(settings.value("/cutecom/AppendToLogFile", 0).toInt()); - - int x=settings.value("/cutecom/width", -1).toInt(); - int y=settings.value("/cutecom/height", -1).toInt(); - if ((x>100) && (y>100)) - { - resize(x,y); - } - - bool entryFound = settings.contains("/cutecom/AllDevices"); - QStringList devices=settings.value("/cutecom/AllDevices").toStringList(); - if (!entryFound) - { - devices<<"/dev/ttyS0"<<"/dev/ttyS1"<<"/dev/ttyS2"<<"/dev/ttyS3"; - } - - m_deviceCb->insertItems(0, devices); - - int indexOfCurrentDevice = devices.indexOf(settings.value("/cutecom/CurrentDevice", "/dev/ttyS0").toString()); - // fprintf(stderr, "currentDEev: -%s - index: %d\n", settings.value("/cutecom/CurrentDevice", "/dev/ttyS0").toString().toLatin1().constData(), indexOfCurrentDevice); - if (indexOfCurrentDevice!=-1) - { - m_deviceCb->setCurrentIndex(indexOfCurrentDevice); - } - - QStringList history=settings.value("/cutecom/History").toStringList(); - - if (!history.empty()) - { - m_oldCmdsLb->addItems(history); - m_oldCmdsLb->setCurrentRow(m_oldCmdsLb->count()-1); - m_oldCmdsLb->scrollToItem(m_oldCmdsLb->currentItem()); - m_oldCmdsLb->clearSelection(); - } -} - -void QCPPDialogImpl::showAboutMsg() -{ - QMessageBox::about(this, tr("About CuteCom"), tr("This is CuteCom 0.22.0
(c)2004-2009 Alexander Neundorf, <neundorf@kde.org>
Licensed under the GNU GPL v2")); -} - -void QCPPDialogImpl::sendFile() -{ - if (m_fileDlg==0) - { - m_fileDlg=new QFileDialog(); - m_fileDlg->setDirectory(m_sendFileDialogStartDir); - m_fileDlg->setFileMode(QFileDialog::ExistingFile); - } - - QString filename; - if ( m_fileDlg->exec() == QDialog::Accepted ) - { - QStringList fn = m_fileDlg->selectedFiles(); - if(!fn.isEmpty()) - { - filename = fn[0]; - } - m_sendFileDialogStartDir=m_fileDlg->directory().absolutePath(); - saveSettings(); - } - else - { - return; - } - - unsigned int charDelay=m_charDelaySb->value(); - if (m_protoPb->currentText()=="Script") - { - QFile file(filename); - if (!file.open(QIODevice::ReadOnly)) - { - QMessageBox::information(this, tr("Opening file failed"), tr("Could not open file %1").arg(filename)); - return; - } - - QTextStream stream(&file); - while (!stream.atEnd()) - { - QString nextLine=stream.readLine(); - nextLine=nextLine.left((unsigned int)nextLine.indexOf('#')); - if (nextLine.isEmpty()) - { - continue; - } - - if (!sendString(nextLine)) - { - QMessageBox::information(this, tr("Comm error"), tr("Sending failed")); - return; - } - millisleep(charDelay*3); - } - } - else if (m_protoPb->currentText()=="Plain") - { - QFile file(filename); - if (!file.open(QIODevice::ReadOnly)) - { - QMessageBox::information(this, tr("Opening file failed"), tr("Could not open file %1").arg(filename)); - return; - } - QByteArray data=file.readAll(); - delete m_progress; - m_progress=new QProgressDialog(tr("Sending file..."), tr("Cancel"), 0, 100, this); - m_progress->setMinimumDuration(100); - unsigned int step=data.size()/100; - if (step<1) - { - step=1; - } - for (int i=0; isetValue(i/step); - qApp->processEvents(); - } - sendByte(data.data()[i], charDelay); - if ((data.data()[i]=='\n') || (data.data()[i]=='\r')) //wait twice as long after bytes which might be line ends (helps some uCs) - { - millisleep(charDelay); - } -// if (!sendByte(data.data()[i])) - if (0) - { - QMessageBox::information(this, tr("Comm error"), tr("Sending failed (%1/%2").arg(i).arg(data.count())); - break; - } - if ( m_progress->wasCanceled() ) - { - break; - } - } - delete m_progress; - m_progress=0; - } - else if ((m_protoPb->currentText()=="XModem") - || (m_protoPb->currentText()=="YModem") - || (m_protoPb->currentText()=="ZModem") - || (m_protoPb->currentText()=="1kXModem")) - { -// QProcess sx(this); - disconnectTTYRestore(false); - m_sz=new Q3Process(this); - m_sz->addArgument("sh"); - m_sz->addArgument("-c"); -// QString tmp=QString("sx -vv \"")+filename+"\" < "+m_deviceCb->currentText()+" > "+m_deviceCb->currentText(); - QString tmp=QString("sz "); - if (m_protoPb->currentText()=="XModem") - { - tmp+="--xmodem "; - } - else if (m_protoPb->currentText()=="YModem") - { - tmp+="--ymodem "; - } - else if (m_protoPb->currentText()=="ZModem") - { - tmp+="--zmodem "; - } - else if (m_protoPb->currentText()=="1kXModem") - { - tmp+="--xmodem --1k "; - } - - tmp=tmp+"-vv \""+filename+"\" < "+m_deviceCb->currentText()+" > "+m_deviceCb->currentText(); - m_sz->addArgument(tmp); - m_sz->setCommunication(Q3Process::Stderr); - - connect(m_sz, SIGNAL(readyReadStderr()), this, SLOT(readFromStderr())); -/* m_sz->addArgument("sx"); - m_sz->addArgument("-vv"); - m_sz->addArgument(filename); - m_sz->setCommunication(QProcess::Stdin|QProcess::Stdout|QProcess::Stderr); - - connect(m_sz, SIGNAL(readyReadStdout()), this, SLOT(readFromStdout())); - connect(m_sz, SIGNAL(readyReadStderr()), this, SLOT(readFromStderr()));*/ - connect(m_sz, SIGNAL(processExited()), this, SLOT(sendDone())); - if (!m_sz->start()) - { - QMessageBox::information(this, tr("Comm error"), tr("Could not start sx")); - delete m_sz; - m_sz=0; - connectTTY(); - return; - } - m_progress=new QProgressDialog(tr("Sending file via xmodem..."), tr("Cancel"), 0, 100, this); - connect(m_progress, SIGNAL(cancelled()), this, SLOT(killSz())); - m_progress->setMinimumDuration(100); - QFileInfo fi(filename); - m_progressStepSize=fi.size()/1024/100; - if (m_progressStepSize<1) - { - m_progressStepSize=1; - } -// cerr<<"while(isRunning)"<setValue(0); - while (m_sz->isRunning()) - { - qApp->processEvents(); - millisleep(10); - } -// cerr<<"----------------- sx done"<currentText())); - } -} - -void QCPPDialogImpl::killSz() -{ - if (m_sz==0) - { - return; - } - m_sz->tryTerminate(); -} - -void QCPPDialogImpl::readFromStdout() -{ - QByteArray ba=m_sz->readStdout(); -// cerr<<"readFromStdout() "<0) - { - int bytesWritten=::write(m_fd, src, (bytesToWrite>CUTECOMM_BUFSIZE?CUTECOMM_BUFSIZE:bytesToWrite)); - if (bytesWritten<0) - { -// cerr<<"readFromStdout() error "<readStderr(); -// cerr<<"readFromStderr() "<-1) - { - QString captured=regex.cap(1); -// cerr<<"captured kb: -"<setValue(p); - } - } - } -// else -// cerr<<"--------"<type()==QEvent::KeyPress)) - { - if (ke->state()==Qt::NoModifier) - { - if (ke->key()==Qt::Key_Up) - { - prevCmd(); - return true; - } - else if (ke->key()==Qt::Key_Down) - { - nextCmd(); - return true; - } - } - else if (ke->modifiers()==Qt::ControlModifier) - { - if (ke->key()==Qt::Key_C) - { -// std::cerr<<"c"; - m_keyCode=3; - sendByte(m_keyCode, 0); - m_keyRepeatTimer.setSingleShot(false); - m_keyRepeatTimer.start(0); - return true; - } - else if (ke->key()==Qt::Key_Q) - { -// std::cerr<<"#"; - m_keyCode=17; - sendByte(m_keyCode, 0); - return true; - } - else if (ke->key()==Qt::Key_S) - { - m_keyCode=19; - sendByte(m_keyCode, 0); - return true; - } - } - } - else if ((watched==m_cmdLe) && (e->type()==QEvent::KeyRelease)) - { - m_keyRepeatTimer.stop(); - } - - return false; -} - -void QCPPDialogImpl::sendKey() -{ -// std::cerr<<"-"; - sendByte(m_keyCode, 0); -} - -void QCPPDialogImpl::oldCmdClicked(QListWidgetItem* item) -{ - if (item==0) - { - return; - } - int index=m_oldCmdsLb->row(item); - m_cmdLe->setText(item->text()); - m_cmdBufIndex=m_oldCmdsLb->count()-index; - m_cmdLe->setFocus(); -} - -void QCPPDialogImpl::prevCmd() -{ - if (m_oldCmdsLb->count()<=m_cmdBufIndex) - { - return; - } - -// std::cerr<<"prevCmd() count: "<count()<<" bufIndex: "<< - m_cmdBufIndex++; - QListWidgetItem* item=m_oldCmdsLb->item(m_oldCmdsLb->count()-m_cmdBufIndex); - if (item!=0) - { - m_oldCmdsLb->setCurrentItem(item); - m_cmdLe->setText(item->text()); - } -// std::cerr<<"prev() count: "<count()<<" bufIndex: "<clear(); - m_oldCmdsLb->setCurrentItem(0); -// TODO ? m_oldCmdsLb->setCurrentIndex(0); - } - else - { - QListWidgetItem* it=m_oldCmdsLb->item(m_oldCmdsLb->count()-m_cmdBufIndex); - m_oldCmdsLb->setCurrentItem(it); - m_cmdLe->setText(it->text()); - } -// std::cerr<<"next() count: "<count()<<" bufIndex: "<text().trimmed(); - m_cmdLe->clear(); - if (!cmd.isEmpty()) - { - if ((m_oldCmdsLb->count()<1) || (m_oldCmdsLb->item(m_oldCmdsLb->count()-1)->text()!=cmd)) - { - m_oldCmdsLb->addItem(cmd); - m_oldCmdsLb->setCurrentRow(m_oldCmdsLb->count()-1); - if (m_oldCmdsLb->count()>50) - { -#if QT_VERSION >= 0x040300 - m_oldCmdsLb->removeItemWidget(m_oldCmdsLb->item(0)); -#else /* QT_VERSION >= 0x030000 */ - m_oldCmdsLb->setItemWidget(m_oldCmdsLb->item(0), 0); -#endif /* QT_VERSION >= 0x030000 */ - } - saveSettings(); - } - } - m_oldCmdsLb->clearSelection(); - if (m_fd==-1) - { - return; - } - - sendString(cmd); - -/* std::cerr<<"paras: "<paragraphs()<paragraphs()>1100) - { - m_outputView->setUpdatesEnabled(false); - m_outputView->setSelection(0, 0, 100, 0); - m_outputView->removeSelectedText(); - m_outputView->scrollToBottom(); - m_outputView->append("abc\n"); - m_outputView->setUpdatesEnabled(true); - } - else*/ -/* m_outputView->setCursorPosition(m_outputView->paragraphs()-1, 0); - static int i=0; - i++; - QString s=QString::number(i); - s=" -"+s+"-\n "; - m_outputView->insert(s);*/ -/* m_outputView->insert("abc"); - m_outputView->insert("def"); - m_outputView->insert("ghi\n"); - m_outputView->update();*/ -} - -bool QCPPDialogImpl::sendString(const QString& s) -{ - unsigned int lineMode=m_inputModeCb->currentIndex(); - unsigned int charDelay=m_charDelaySb->value(); - - if (lineMode==4) // hex - { - QString hex=s; - hex.remove(QRegExp("\\s")); - if ((hex.startsWith("0x")) || (hex.startsWith("0X"))) - { - hex=hex.mid(2); - } - - if (hex.length()%2 != 0) - { - hex="0"+hex; - } - - for (int i=0; icurrentText(); - int baudrate=m_baudCb->currentText().toInt(); - int dataBits=m_dataBitsCb->currentText().toInt(); - QString parity=m_parityCb->currentText(); - QString stop=m_stopCb->currentText(); - bool softwareHandshake=m_softwareCb->isChecked(); - bool hardwareHandshake=m_hardwareCb->isChecked(); - - int flags=0; - if (m_readCb->isChecked() && m_writeCb->isChecked()) - { - flags=O_RDWR; - } - else if (!m_readCb->isChecked() && m_writeCb->isChecked()) - { - flags=O_WRONLY; - } - else if (m_readCb->isChecked() && !m_writeCb->isChecked()) - { - flags=O_RDONLY; - } - else - { - QMessageBox::information(this, tr("Error"), tr("Opening the device neither for reading nor writing doesn't seem to make much sense ;-)")); - return; - } - - m_fd=open(dev.toLatin1(), flags | O_NDELAY); - if (m_fd<0) - { - std::cerr<<"opening failed"<isChecked()) - { - int n = fcntl(m_fd, F_GETFL, 0); - fcntl(m_fd, F_SETFL, n & ~O_NDELAY); - - if (tcgetattr(m_fd, &m_oldtio)!=0) - { - std::cerr<<"tcgetattr() 2 failed"<setEnabled(false); - m_deviceCb->setEnabled(false); - - enableSettingWidgets(false); - m_applyCb->setEnabled(false); - - m_readCb->setEnabled(false); - m_writeCb->setEnabled(false); - m_isConnected=true; - - - if (m_readCb->isChecked()) - { - m_notifier=new QSocketNotifier(m_fd, QSocketNotifier::Read, this); - connect(m_notifier, SIGNAL(activated(int)), this, SLOT(readData(int))); - } - m_oldCmdsLb->setEnabled(true); - m_cmdLe->setEnabled(true); - m_sendPb->setEnabled(true); - m_protoPb->setEnabled(true); - m_closePb->setEnabled(true); - - m_cmdLe->setFocus(); - - m_previousChar = '\0'; - m_hexBytes=0; -} - -void QCPPDialogImpl::enableSettingWidgets(bool enable) -{ - m_baudCb->setEnabled(enable); - m_dataBitsCb->setEnabled(enable); - m_parityCb->setEnabled(enable); - m_stopCb->setEnabled(enable); - m_softwareCb->setEnabled(enable); - m_hardwareCb->setEnabled(enable); -} - -void QCPPDialogImpl::disconnectTTY() -{ - disconnectTTYRestore(m_applyCb->isChecked()); -} - -void QCPPDialogImpl::disconnectTTYRestore(bool restoreSettings) -{ - m_outputTimer.stop(); - m_outputBuffer=""; - -// std::cerr<<"closing "<setEnabled(true); - m_deviceCb->setEnabled(true); - - if (m_applyCb->isChecked()) - { - enableSettingWidgets(true); - } - - m_applyCb->setEnabled(true); - m_readCb->setEnabled(true); - m_writeCb->setEnabled(true); - - m_oldCmdsLb->setEnabled(false); - m_cmdLe->setEnabled(false); - m_sendPb->setEnabled(false); - m_protoPb->setEnabled(false); - m_closePb->setEnabled(false); - - m_connectPb->setFocus(); - - m_isConnected=false; - delete m_notifier; - m_notifier=0; -} - - - -/** This function features some code from minicom 2.0.0, src/sysdep1.c */ -void QCPPDialogImpl::setNewOptions(int baudrate, int databits, const QString& parity, const QString& stop, bool softwareHandshake, bool hardwareHandshake) -{ - struct termios newtio; -// memset(&newtio, 0, sizeof(newtio)); - if (tcgetattr(m_fd, &newtio)!=0) - { - std::cerr<<"tcgetattr() 3 failed"<writeToStdin(ba); - return; - } - - if (m_logFile.isOpen()) - { - m_logFile.write(m_buf, bytesRead); - } - - QString text; - char buf[16]; - for (int i=0; iisChecked()) - { - if ((m_hexBytes % 16) == 0) - { - snprintf(buf, 16, "%08x: ", m_hexBytes); - text+=buf; - } - unsigned int b=*c; - snprintf(buf, 16, "%02x ", b & 0xff); - text+=buf; - - m_hexBytes++; - if ((m_hexBytes % 16)==0) - { - text+="\n"; - } - else if ((m_hexBytes % 8)==0) - { - text+=" "; - } - } - else - { - // also print a newline for \r, and print only one newline for \r\n - if ((isprint(*c)) || (*c=='\n') || (*c=='\r')) - { - if (*c=='\r') - { - text+='\n'; - } - else if (*c=='\n') - { - if (m_previousChar != '\r') - { - text+='\n'; - } - } - else - { - text+=(*c); - } - - m_previousChar = *c; - } - else - { - unsigned int b=*c; - snprintf(buf, 16, "\\0x%02x", b & 0xff); - text+=buf; - } - } - c++; - } - - addOutput(text); -} - -void QCPPDialogImpl::addOutput(const QString& text) -{ - m_outputBuffer+=text; - - if (!m_outputTimer.isActive()) - { - doOutput(); - m_outputTimerStart.restart(); - m_outputTimer.setSingleShot(true); - m_outputTimer.start(50); - } - else - { - if ((m_outputTimerStart.elapsed()>400) - || ((m_outputTimerStart.elapsed()>200) && (m_outputBuffer.length()<100))) - { - doOutput(); - m_outputTimerStart.restart(); - } - m_outputTimer.setSingleShot(true); - m_outputTimer.start(50); - } -} - -void QCPPDialogImpl::doOutput() -{ - if (m_outputBuffer.isEmpty()) - { - return; - } - - m_outputView->append(m_outputBuffer); - m_outputBuffer.clear(); -} - -void QCPPDialogImpl::hexOutputClicked(bool /* on */) -{ - addOutput("\n"); - m_hexBytes=0; -} - -void QCPPDialogImpl::clearOutput() -{ - m_outputView->clear(); - m_hexBytes=0; -} - -void QCPPDialogImpl::enableLogging(bool on) -{ - if (m_logFile.isOpen()==on) - { - return; - } - - if (on) - { - m_logFile.setFileName(m_logFileLe->text()); - QIODevice::OpenMode mode=QIODevice::ReadWrite; - if (m_logAppendCb->currentIndex()==0) - { - mode=mode | QIODevice::Truncate; - } - else - { - mode=mode | QIODevice::Append; - } - - if (!m_logFile.open(mode)) - { - QMessageBox::information(this, tr("Opening file failed"), tr("Could not open file %1 for writing").arg(m_logFileLe->text())); - m_enableLoggingCb->setChecked(false); - } - else - { - m_logAppendCb->setEnabled(false); - m_logFileLe->setEnabled(false); - m_logFileFileDialog->setEnabled(false); - saveSettings(); - } - } - else - { - m_logFile.close(); - - m_logAppendCb->setEnabled(true); - m_logFileLe->setEnabled(true); - m_logFileFileDialog->setEnabled(true); - - } - -} - - -void QCPPDialogImpl::chooseLogFile() -{ - QString logFile=QFileDialog::getSaveFileName(this, tr("Save log file ..."), m_logFileLe->text()); - if (!logFile.isEmpty()) - { - m_logFileLe->setText(logFile); - } -} - diff -Nru cutecom-0.22.0/qcppdialogimpl.h cutecom-0.30.3/qcppdialogimpl.h --- cutecom-0.22.0/qcppdialogimpl.h 2009-06-23 20:35:06.000000000 +0000 +++ cutecom-0.30.3/qcppdialogimpl.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ -/* Copyright (C) 2004-2005 Alexander Neundorf - - This program 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 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifndef QCPPIALOGIMPL_H -#define QCPPIALOGIMPL_H - -#include "ui_cutecommdlg.h" - -#include - -#include -#include -#include -#include -//Added by qt3to4: -#include -#include -#include - -#define CUTECOMM_BUFSIZE (4096) - -class QListWidgetItem; -class QResizeEvent; -class Q3Process; -class QProgressDialog; -class QFileDialog; - -class QCPPDialogImpl:public QWidget, public Ui::CuteCommDlg -{ - Q_OBJECT - public: - QCPPDialogImpl(QWidget* parent); - virtual bool eventFilter(QObject* watched, QEvent *e); - protected slots: - void execCmd(); - void readData(int fd); - void sendFile(); - void showAboutMsg(); - - void oldCmdClicked(QListWidgetItem* item); - void saveSettings(); - void readFromStdout(); - void readFromStderr(); - void sendDone(); - void connectTTY(); - void disconnectTTY(); - void killSz(); - void enableSettingWidgets(bool enable); - void doOutput(); - void sendKey(); - void hexOutputClicked(bool on); - void enableLogging(bool on); - void chooseLogFile(); - void clearOutput(); - protected: - void fillBaudCb(); - void addOutput(const QString& text); - bool sendByte(char c, unsigned int delay); - void disconnectTTYRestore(bool restore); - void readSettings(); - void prevCmd(); - void nextCmd(); - bool sendString(const QString& s); - void setNewOptions(int baudrate, int databits, const QString& parity, const QString& stop, bool softwareHandshake, bool hardwareHandshake); - virtual void resizeEvent(QResizeEvent *e); - - bool m_isConnected; - int m_fd; - struct termios m_oldtio; - unsigned int m_cmdBufIndex; - QSocketNotifier *m_notifier; - char m_buf[CUTECOMM_BUFSIZE]; - Q3Process *m_sz; - QProgressDialog *m_progress; - int m_progressStepSize; - - QFileDialog *m_fileDlg; - QString m_sendFileDialogStartDir; - - QTimer m_outputTimer; - QTime m_outputTimerStart; - QString m_outputBuffer; - - QTimer m_keyRepeatTimer; - char m_keyCode; - unsigned int m_hexBytes; - char m_previousChar; - - QFile m_logFile; - -}; - -#endif diff -Nru cutecom-0.22.0/README cutecom-0.30.3/README --- cutecom-0.22.0/README 2009-06-25 20:10:38.000000000 +0000 +++ cutecom-0.30.3/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -CuteCom 0.22.0, June 27th, 2009 - -CuteCom is a graphical serial terminal, similar to minicom. -It is aimed mainly at hardware developers or other people -who need a terminal to talk to their devices. -It is free software and distributed under the GNU General -Public License Version 2, which can find in the file COPYING. - -It is written using the Qt library by Trolltech (www.trolltech.com), -at least version 4.1.0 is required. - -CuteCom doesn't use the autotools (autoconf, automake, libtool, etc.) -but CMake (http://www.cmake.org), you need at least version 2.4.3. -Enter the source directory and run "cmake ." followed by make and make -install and you're done. To make sure it can find Qt4, set the PATH so that -qmake from Qt4 is in the PATH (and comes before qmake from Qt3 in the PATH), -e.g.: export PATH=/opt/qt4/bin:$PATH; cmake . - -If you are using CMake >= 2.6.0, adjust the CMAKE_PREFIX_PATH environment variable -instead of PATH to help CMake finding Qt4, e.g.: export CMAKE_PREFIX_PATH=/opt/qt4; cmake . - -To uninstall cutecom simply delete the file "cutecom" and the file -"cutecom.desktop" amd your done. The config file is ~/.config/CuteCom/CuteCom.conf. - -Currently it is known to run on Linux, FreeBSD and Mac OS X, and porting to other systems -should be easy. -Everything platformspecific should be in QCPPDialogImpl::setNewOptions(). -Distributions welcome :-) -Now that it uses Qt4 it should also be portable to Windows. - -CuteCom is heavily inspired by Bray++ for Windows (http://bray.velenje.cx/avr/terminal/) - -Homepage: http://cutecom.sourceforge.net - -Alexander Neundorf - diff -Nru cutecom-0.22.0/README.md cutecom-0.30.3/README.md --- cutecom-0.22.0/README.md 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/README.md 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,97 @@ +[![Build status](https://api.travis-ci.org/cyc1ingsir/cutecom.svg?branch=master)](https://travis-ci.org/cyc1ingsir/cutecom) + +## Welcome to _CuteCom_ + +CuteCom is a graphical serial terminal, like minicom. +Currently it runs on Linux (tested) and should run on FreeBSD, Mac OS X and maybe other systems as well (untested). +It is aimed mainly at hardware developers or other people who need a terminal to talk to their devices. +It is free software and distributed under the GNU General Public License Version 3. +It is written using the [Qt library](http://www.qt.io/) originally created by Trolltech. + +### History + +The current CuteCom-version has being reimplemented using Qt 5 switching to the now available QSerialport. +The GUI was facelifted and amongst other features a session support was added. +Session support comes in handy if you have two or more devices connected, each of it talking +in different baudrates or other connection parameters. The command history is stored for each individual session since +different devices may provide a different set of commands. +Features enhancements of various forks have been included see [**_CREDITS_**](CREDITS) for a complete list. +Version 0.30.0 is the first public release after the reimplementation. + +### Features: + +* easy to use GUI +* no cryptic keyboard shortcuts +* lineoriented interface instead of character-oriented +* Ctrl+C, Ctrl+Q and Ctrl+S control sequences work +* input history +* a cute GUI ;-) +* session support via -s specified at the command line +* switching sessions via a session manager +* control panel hides when not used +* xmodem, ymodem, zmodem support (requires the sz tools) +* easy to differentiate between typed text and echoed text +* select between read/write, read-only and write-only open mode +* hexadecimal input and output +* configurable line end characters (LF, CR, LFCR) +* configurable delay between characters +* optionally show control characters like line feed or tabs in output +* optionally prefix each line in output with a timestamp +* open the device without changing its settings (was not ported but could be added if demand arrises ) + + +### Build instructions + +On Linux you will hopefully find ready made packages using the package manager of your distribution. +To build your own copy, you need to run `cmake .` followd by make. +You'll then find a cutecom binary in the same folder. +`make package` should provide you with a generic RPM package (which lacks the documentation and the like). +`make dist` creates a tar ball (so does `make package_source`) + +#### Requirements for Building: + +* CuteCom 0.30.0 +: Qt >= 5.1, CMake >= 2.8.11 +* on linux look for the qt5 development packages including QSerialport +* Since C++C11 features are used a gcc supporting these is needed too + +## Changelog + +Here is the complete [**_Changelog_**](Changelog). + +**_Current state:_** stable + +**_TODO_ **: + +* searching in the output view via context menu and Ctrl+F shortcut +* translations +* show control characters in a different colour +* selectable style for the output view like green on black including +* font selection for the output view + + +As always: +**Pull requests are welcome ! :-)** + +### Screenshot + +Ok, here comes the inevitable screenshot: + +![](cutecom.png) + +The control panel for adjusting the device settings slides out when pressing the Settings button. +At the upper half, commands issued are accumulated. +Commands may be selected from the history using up and down arrow keys.' +Right below command line situated right in the middle, the output view can be found. +It will autoscroll to the end of the date sent from the connected device. +Autoscolling will stop, once a certain section of the data is scrolled to. +PageUp and PageDown are working for moving through the output view. + +## Previous versions: + +**_Previous version (uses Qt4):_** [cutecom-0.22.0.tar.gz,](http://cutecom.sourceforge.net/cutecom-0.22.0.tar.gz) , June 27th, 2009 +(yes, it's really only 22kb). Now also works on Mac OSX and supports more baud rates. + +For older versions have a look at the SourceForge project page. + +CuteCom was heavily inspired by [Bray++ Terminal for Windows](https://sites.google.com/site/terminalbpp/). + diff -Nru cutecom-0.22.0/resources.qrc cutecom-0.30.3/resources.qrc --- cutecom-0.22.0/resources.qrc 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/resources.qrc 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,6 @@ + + + images/info.svg + images/terminal.svg + + diff -Nru cutecom-0.22.0/serialdevicelistmodel.cpp cutecom-0.30.3/serialdevicelistmodel.cpp --- cutecom-0.22.0/serialdevicelistmodel.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/serialdevicelistmodel.cpp 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2015 Meinhard Ritscher + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "serialdevicelistmodel.h" + +#include +#include "qdebug.h" + +SerialDeviceListModel::SerialDeviceListModel(QObject *parent) + : QAbstractListModel(parent) +{ +} + +int SerialDeviceListModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + qDebug() << Q_FUNC_INFO; + return m_device_count; +} + +QVariant SerialDeviceListModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (index.row() >= m_devices.size() || index.row() < 0) + return QVariant(); + + qDebug() << Q_FUNC_INFO; + if (role == Qt::ToolTipRole) { + return QStringLiteral("SerialDevice ..."); + } else if (role == Qt::DisplayRole) { + return m_devices.at(index.row()); + } else { + return QVariant(); + } +} + +bool SerialDeviceListModel::canFetchMore(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + qDebug() << Q_FUNC_INFO; + return true; +} + +void SerialDeviceListModel::fetchMore(const QModelIndex &parent) +{ + Q_UNUSED(parent) + m_devices.clear(); + for (auto info : QSerialPortInfo::availablePorts()) { + m_devices.append(info.systemLocation()); + } + m_device_count = m_devices.size(); +} diff -Nru cutecom-0.22.0/serialdevicelistmodel.h cutecom-0.30.3/serialdevicelistmodel.h --- cutecom-0.22.0/serialdevicelistmodel.h 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/serialdevicelistmodel.h 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015 Meinhard Ritscher + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef SERIALDEVICELISTMODEL_H +#define SERIALDEVICELISTMODEL_H + +#include + +class SerialDeviceListModel : public QAbstractListModel +{ + Q_OBJECT +public: + explicit SerialDeviceListModel(QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; + +protected: + bool canFetchMore(const QModelIndex &parent) const Q_DECL_OVERRIDE; + void fetchMore(const QModelIndex &parent) Q_DECL_OVERRIDE; + +private: + QStringList m_devices; + int m_device_count; +}; + +#endif // SERIALDEVICELISTMODEL_H diff -Nru cutecom-0.22.0/sessionmanager.cpp cutecom-0.30.3/sessionmanager.cpp --- cutecom-0.22.0/sessionmanager.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/sessionmanager.cpp 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2015 Meinhard Ritscher + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "sessionmanager.h" + +#include +#include +#include +#include + +/** + * This Validator prevents session names to contain some + * characters not very sensible to use within session names. + * It prevents duplicate session names as well. + * It's based on the one included in the QtCreator's sessiondialog. + * Copyright (C) 2015 The Qt Company Ltd. + * @brief The SessionNameValidator class + */ +class SessionNameValidator : public QValidator +{ +public: + SessionNameValidator(QListWidget *list); + void fixup(QString &input) const; + QValidator::State validate(QString &input, int &pos) const; + +private: + QListWidget *m_list; + QString m_original_name; +}; + +SessionNameValidator::SessionNameValidator(QListWidget *list) + : QValidator(list) + , m_list(list) +{ + m_original_name = list->currentItem()->text(); +} + +QValidator::State SessionNameValidator::validate(QString &input, int &pos) const +{ + Q_UNUSED(pos) + + if (input.contains(QLatin1Char('/')) || input.contains(QLatin1Char(':')) || input.contains(QLatin1Char('\\')) + || input.contains(QLatin1Char('?')) || input.contains(QLatin1Char('*')) || input.contains(QLatin1Char(' '))) + return QValidator::Invalid; + + QList items = m_list->findItems(input, Qt::MatchExactly); + + // qDebug() << Q_FUNC_INFO << input << "found " + // << items.size() << " x" + // << "origin: " << m_original_name; + + if (items.size() > 0 && input != m_original_name) { + return QValidator::Intermediate; + } else + return QValidator::Acceptable; +} + +void SessionNameValidator::fixup(QString &input) const +{ + int orderNum = -1; + QString copy; + do { + int index = input.lastIndexOf("-"); + if (index > -1) { + bool ok; + if (orderNum < 0) + orderNum = input.right(input.length() - 1 - index).toInt(&ok); + if (ok) { + orderNum++; + copy = input.left(index + 1) + QString::number(orderNum); + continue; + } + } + if (orderNum < 0) + orderNum = 0; + copy = input + QStringLiteral("-%1").arg(++orderNum); + // qDebug() << "fixup : " << "copy: " << copy << " : " << m_list->findItems(copy, + // Qt::MatchExactly).size(); + } while ((m_list->findItems(copy, Qt::MatchExactly)).size() > 0); + + input = copy; +} + +QWidget *SessionItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QWidget *editor = QItemDelegate::createEditor(parent, option, index); + QLineEdit *lineEdit = dynamic_cast(editor); + if (lineEdit) { + lineEdit->setValidator(new SessionNameValidator(m_list)); + connect(lineEdit, &QLineEdit::editingFinished, this, [=]() { emit editingFinished(lineEdit->text()); }); + } + return editor; +} + +SessionManager::SessionManager(Settings *settings, QWidget *parent) + : QDialog(parent) + , m_settings(settings) + , m_current_item(0) + , m_current_session(0) + , m_isCloning(false) + , m_isRenaming(false) +{ + setupUi(this); + + m_session_list->setEditTriggers(QAbstractItemView::NoEditTriggers); + + connect(m_session_list, &QListWidget::currentItemChanged, this, &SessionManager::currentItemChanged); + + // special session "Default" is always on top of the list + m_session_list->addItem(QStringLiteral("Default")); + + QStringList sessions = m_settings->getSessionNames(); + if (sessions.size() > 0) { + if (sessions.contains(QStringLiteral("Default"))) { + sessions.removeOne(QStringLiteral("Default")); + } + sessions.sort(); + m_session_list->addItems(sessions); + } + QList items = m_session_list->findItems(m_settings->getCurrentSessionName(), Qt::MatchExactly); + if (items.size() > 0) { + m_session_list->setCurrentItem(items.at(0)); + QFont font = m_current_item->font(); + font.setBold(true); + m_current_item->setFont(font); + } + + m_current_session = m_current_item; + m_bt_switch->setEnabled(false); + connect(m_bt_switch, &QPushButton::clicked, this, &SessionManager::switchSession); + connect(m_bt_delete, &QPushButton::clicked, this, &SessionManager::removeSession); + connect(m_bt_rename, &QPushButton::clicked, this, &SessionManager::renameSession); + connect(m_bt_clone, &QPushButton::clicked, this, &SessionManager::cloneSession); + + m_session_list->setItemDelegate(new SessionItemDelegate(m_session_list)); + connect(static_cast(m_session_list->itemDelegate()), &SessionItemDelegate::editingFinished, + this, &SessionManager::editingFinished); +} + +void SessionManager::currentItemChanged(QListWidgetItem *current, QListWidgetItem * /*previous*/) +{ + + if (current != m_current_session) + m_bt_switch->setEnabled(true); + + m_current_item = current; + if (current->text() == QStringLiteral("Default")) { + m_bt_delete->setEnabled(false); + m_bt_rename->setEnabled(false); + } else { + m_bt_delete->setEnabled(true); + m_bt_rename->setEnabled(true); + } +} + +void SessionManager::editingFinished(const QString &newSessionName) +{ + // qDebug() << Q_FUNC_INFO << "New session name: " << newSessionName; + if (m_isRenaming) { + if (newSessionName != m_previous_sessionName) + emit sessionRenamed(m_previous_sessionName, newSessionName); + if (m_previous_sessionName == m_current_session->text()) + emit sessionSwitched(newSessionName); + m_isRenaming = false; + } else if (m_isCloning) { + emit sessionCloned(m_previous_sessionName, newSessionName); + m_isCloning = false; + } else { + qDebug() << "This slot is called multiple times after editing finished - Why?"; + } + m_bt_rename->setEnabled(true); + m_bt_clone->setEnabled(true); +} + +void SessionManager::switchSession() +{ + m_bt_switch->setEnabled(false); + emit sessionSwitched(m_current_item->text()); + QFont font = m_current_item->font(); + if (m_current_session) + m_current_session->setFont(font); + font.setBold(true); + m_current_item->setFont(font); + + m_current_session = m_current_item; + this->close(); +} + +/** + * @brief SessionManager::removeSession + */ +void SessionManager::removeSession() +{ + emit sessionRemoved(m_current_item->text()); + QListWidgetItem *remove_item = m_current_item; + + if (m_current_session == remove_item) { + // the currently used session was removed + // we would be better off, switching to a different one + // the default session is save to switch too + m_session_list->setCurrentRow(0); + switchSession(); + } else { + // otherwise we select the current session + m_session_list->setCurrentRow(m_session_list->row(m_current_session)); + m_bt_switch->setEnabled(false); + } + m_session_list->takeItem(m_session_list->row(remove_item)); +} + +/** + * @brief SessionManager::cloneSession + */ +void SessionManager::cloneSession() +{ + QString newName = m_current_item->text(); + SessionNameValidator *validator = new SessionNameValidator(m_session_list); + validator->fixup(newName); + QListWidgetItem *new_item = new QListWidgetItem(newName, m_session_list); + new_item->setFlags(new_item->flags() | Qt::ItemIsEditable); + + m_session_list->setCurrentItem(new_item); + m_isCloning = true; + m_bt_clone->setEnabled(false); + m_session_list->editItem(m_current_item); +} +/** + * @brief SessionManager::renameSession + */ +void SessionManager::renameSession() +{ + m_previous_sessionName = m_current_item->text(); + m_current_item->setFlags(m_current_item->flags() | Qt::ItemIsEditable); + + m_isRenaming = true; + m_bt_rename->setEnabled(false); + m_session_list->editItem(m_current_item); +} diff -Nru cutecom-0.22.0/sessionmanager.h cutecom-0.30.3/sessionmanager.h --- cutecom-0.22.0/sessionmanager.h 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/sessionmanager.h 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2015 Meinhard Ritscher + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef SESSIONMANAGER_H +#define SESSIONMANAGER_H + +#include "ui_sessionmanager.h" +#include "settings.h" + +#include + +class SessionManager : public QDialog, private Ui::SessionManager +{ + Q_OBJECT + +signals: + void sessionSwitched(const QString &name); + void sessionRemoved(const QString &name); + void sessionRenamed(const QString &source, const QString &destination); + void sessionCloned(const QString &source, const QString &destination); + +public: + explicit SessionManager(Settings *settings, QWidget *parent = 0); + void editingFinished(const QString &newSessionName); + +private: + void currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous); + void switchSession(); + void removeSession(); + void cloneSession(); + void renameSession(); + + /** + * stores the reference of the application wide settings instance + * @brief m_settings + */ + Settings *m_settings; + /** + * The currently selected session + * @brief m_current_item + */ + QListWidgetItem *m_current_item; + /** + * The currently used session + * @brief m_current_item + */ + QListWidgetItem *m_current_session; + + bool m_isCloning; + bool m_isRenaming; + QString m_previous_sessionName; +}; + +class SessionItemDelegate : public QItemDelegate +{ + Q_OBJECT +public: + SessionItemDelegate(QListWidget *list) + : QItemDelegate(list) + , m_list(list) + { + } + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; + +signals: + void editingFinished(QString newSessionName) const; + +private: + QListWidget *m_list; +}; + +#endif // SESSIONMANAGER_H diff -Nru cutecom-0.22.0/sessionmanager.ui cutecom-0.30.3/sessionmanager.ui --- cutecom-0.22.0/sessionmanager.ui 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/sessionmanager.ui 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,120 @@ + + + SessionManager + + + + 0 + 0 + 240 + 200 + + + + Session Manager + + + + :/images/terminal.svg:/images/terminal.svg + + + + + + + 1 + 1 + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + &Switch to + + + + + + + C&lone + + + + + + + &Rename + + + + + + + Delete + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Close + + + + + + + + + + + + + + m_bt_close + clicked() + SessionManager + close() + + + 308 + 200 + + + 180 + 113 + + + + + diff -Nru cutecom-0.22.0/settings.cpp cutecom-0.30.3/settings.cpp --- cutecom-0.22.0/settings.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/settings.cpp 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2015 Meinhard Ritscher + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ +#include "settings.h" + +#include +#include +#include +#include + +#include + +const QString Settings::DEFAULT_SESSION_NAME = QStringLiteral("Default"); + +Settings::Settings(QObject *parent) + : QObject(parent) +{ +} + +void Settings::settingChanged(Settings::Options option, QVariant setting) +{ + bool sessionSettings = true; + Session session; + if (m_sessions.contains(m_current_session)) + session = m_sessions.value(m_current_session); + + switch (option) { + case BaudRate: + session.baudRate = setting.toInt(); + break; + case StopBits: + session.stopBits = static_cast(setting.toInt()); + break; + case DataBits: + session.dataBits = static_cast(setting.toInt()); + break; + case Parity: + session.parity = static_cast(setting.toInt()); + break; + case FlowControl: + session.flowControl = static_cast(setting.toInt()); + break; + case OpenMode: + session.openMode = static_cast(setting.toInt()); + break; + case Device: + session.device = setting.toString(); + break; + case ShowCtrlCharacters: + session.showCtrlCharacters = setting.toBool(); + break; + case ShowTimestamp: + session.showTimestamp = setting.toBool(); + break; + case CommandHistory: + session.command_history = setting.toStringList(); + break; + case WindowGeometry: + m_windowGeometry = setting.toRect(); + sessionSettings = false; + break; + case LogFileLocation: + m_logFileLocation = setting.toString(); + sessionSettings = false; + break; + case LineTermination: + m_lineterm = setting.value(); + sessionSettings = false; + break; + case CharacterDelay: + m_character_delay = setting.toUInt(); + sessionSettings = false; + break; + case ProtocolOption: + m_protocol = setting.value(); + sessionSettings = false; + break; + case SendStartDir: + m_sendingStartDir = setting.toString(); + sessionSettings = false; + break; + case CurrentSession: + m_current_session = setting.toString(); + emit sessionChanged(getCurrentSession()); + sessionSettings = false; + default: + break; + } + m_sessions.insert(m_current_session, session); + if (sessionSettings) { + saveSessionSettings(); + emit sessionChanged(getCurrentSession()); + } else { + saveGenericSettings(); + } +} + +/** + * @brief Settings::readSessionSettings + * Reads the settings of all stored sessions. + * These settings contain settings relevant to connect to a specific device + * especially the baud rate but also the command history which may be device + * specific as well. + * If the value for a setting can't be successfully been read, a default value + * will be used. + * If that value isn't beeing changed by the user, the setting will not be + * rewritten to the config file. But this doesn't effect the user since the + * default values for this setting seem to be suit him/her. + * + * @param settings a reference to the QSetting instance of this process + */ +void Settings::readSessionSettings(QSettings &settings) +{ + int size = settings.beginReadArray("sessions"); + + if (size < 1) { + qDebug() << "no session information found in conf file"; + return; + } + m_sessions.clear(); + quint32 value; + + for (int i = 0; i < size; i++) { + settings.setArrayIndex(i); + Session session; + QString name = settings.value("name").toString(); + if (name.isEmpty()) + continue; + + /* + * the static casts are prone to errors since a valid int in the config + * file might not be able to be mapped to a QSerialPort enum + * e.g. flowControl=35600 has no equivalent + * the static cast can't throw an error but this error will be + * handled the time this value is appied to the combo boxes within + * the control panel. It's a workaround though. + */ + session.baudRate = settings.value("BaudRate", 115200).toInt(); + session.dataBits = (readUIntSetting(settings, QStringLiteral("DataBits"), &value)) + ? static_cast(value) + : QSerialPort::Data8; + session.parity = (readUIntSetting(settings, QStringLiteral("Parity"), &value)) + ? static_cast(value) + : QSerialPort::NoParity; + session.stopBits = (readUIntSetting(settings, QStringLiteral("StopBits"), &value)) + ? static_cast(value) + : QSerialPort::OneStop; + session.flowControl = (readUIntSetting(settings, QStringLiteral("FlowControl"), &value)) + ? static_cast(value) + : QSerialPort::NoFlowControl; + session.openMode = (readUIntSetting(settings, QStringLiteral("OpenMode"), &value)) + ? static_cast(value) + : QIODevice::ReadWrite; + // the recovering default for the device its Linux specific but I can live with that + session.device = settings.value("Device", QStringLiteral("/dev/ttyUSB0")).toString(); + session.showCtrlCharacters = settings.value("showCtrlCharacters", false).toBool(); + session.showTimestamp = settings.value("showTimestamp", false).toBool(); + session.command_history = settings.value("History").toStringList(); + + m_sessions.insert(name, session); + } + settings.endArray(); +} + +bool Settings::readUIntSetting(QSettings &settings, QString const &name, quint32 *i) +{ + bool ok = false; + int r = settings.value(name, -1).toInt(&ok); + if (r < 0 || !ok) { + *i = 0; + return false; + } else { + *i = r; + } + return true; +} + +/** + * @brief Settings::readSettings + * @param session A specific session to be used as the current session. + */ +void Settings::readSettings(const QString &session) +{ + QSettings settings(this->parent()); + settings.beginGroup("CuteCom"); + QString stored_session = settings.value("session", DEFAULT_SESSION_NAME).toString(); + if (session.isEmpty()) { + m_current_session = stored_session; + } else { + m_current_session = session; + if (session != stored_session) + settings.setValue("session", session); + } + qDebug() << "setting current session to: " << m_current_session; + + m_windowGeometry = settings.value("WindowGeometry", QRect(0, 0, 0, 0)).toRect(); + m_logFileLocation = settings.value("LogFileLocation").toString(); + if (m_logFileLocation.isEmpty()) { + m_logFileLocation = QDir::homePath() + QDir::separator() + QStringLiteral("cutecom.log"); + } + + m_lineterm = static_cast( + settings.value("LineTerminator", QVariant::fromValue(Settings::LF)).toUInt()); + + m_protocol + = static_cast(settings.value("Protocol", QVariant::fromValue(Settings::PLAIN)).toUInt()); + + m_sendingStartDir = settings.value("SendingStartDir", QDir::homePath()).toString(); + + m_character_delay = settings.value("CharacterDelay", 0).toUInt(); + + settings.endGroup(); + readSessionSettings(settings); +} + +const Settings::Session Settings::getCurrentSession() +{ + if (!m_sessions.contains(m_current_session)) { + // Since this is probably the first time CuteCom is + // started (with this session specified as parameter) + // we set sensible default values for at least + // the connection parameter + + Settings::Session session; + session.baudRate = 115200; + session.dataBits = QSerialPort::Data8; + session.parity = QSerialPort::NoParity; + session.stopBits = QSerialPort::OneStop; + session.openMode = QIODevice::ReadWrite; + session.flowControl = QSerialPort::NoFlowControl; + m_sessions.insert(m_current_session, session); + } + + return m_sessions.value(m_current_session); +} + +void Settings::saveGenericSettings() +{ + QSettings settings(this->parent()); + settings.beginGroup("CuteCom"); + // store generic fluff + settings.setValue("WindowGeometry", m_windowGeometry); + settings.setValue("LogFileLocation", m_logFileLocation); + + // save session releated settings + if (!m_current_session.isEmpty()) + settings.setValue("session", m_current_session); + else + settings.setValue("session", DEFAULT_SESSION_NAME); + + settings.setValue("LineTerminator", m_lineterm); + + settings.setValue("CharacterDelay", m_character_delay); + + settings.setValue("Protocol", m_protocol); + + settings.setValue("SendingStartDir", m_sendingStartDir); + + settings.endGroup(); +} + +void Settings::saveSessionSettings() +{ + QSettings settings(this->parent()); + + if (m_sessions.size() > 0) { + settings.beginWriteArray("sessions"); + int index = 0; + QHashIterator iter(m_sessions); + while (iter.hasNext()) { + iter.next(); + settings.setArrayIndex(index++); + settings.setValue("name", iter.key()); + Session session = iter.value(); + settings.setValue("BaudRate", session.baudRate); + settings.setValue("DataBits", session.dataBits); + settings.setValue("Parity", session.parity); + settings.setValue("StopBits", session.stopBits); + settings.setValue("FlowControl", session.flowControl); + settings.setValue("OpenMode", session.openMode); + settings.setValue("Device", session.device); + settings.setValue("showCtrlCharacters", session.showCtrlCharacters); + settings.setValue("showTimestamp", session.showTimestamp); + settings.setValue("History", session.command_history); + } + settings.endArray(); + } +} + +void Settings::removeSession(const QString &session) +{ + m_sessions.remove(session); + QSettings settings; + settings.beginGroup("sessions"); + settings.remove(""); + settings.endGroup(); + saveSessionSettings(); + m_current_session = QStringLiteral("Default"); + saveGenericSettings(); + emit this->sessionChanged(getCurrentSession()); +} + +void Settings::cloneSession(const QString &source, const QString &destination) +{ + Session session = m_sessions.value(source); + m_sessions.insert(destination, session); + saveSessionSettings(); +} + +void Settings::renameSession(const QString &source, const QString &destination) +{ + Session session = m_sessions.value(source); + m_sessions.remove(source); + QSettings settings; + settings.beginGroup("sessions"); + settings.remove(""); + settings.endGroup(); + m_sessions.insert(destination, session); + saveSessionSettings(); +} + +QString Settings::getLogFileLocation() const { return m_logFileLocation; } + +Settings::LineTerminator Settings::getLineTerminator() const { return m_lineterm; } + +QList Settings::getSessionNames() const +{ + QList sessions = m_sessions.keys(); + if (sessions.isEmpty()) + sessions.append(QStringLiteral("Default")); + return sessions; +} + +QRect Settings::getWindowGeometry() const { return m_windowGeometry; } diff -Nru cutecom-0.22.0/settings.h cutecom-0.30.3/settings.h --- cutecom-0.22.0/settings.h 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/settings.h 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2015 Meinhard Ritscher + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef SETTINGS_H +#define SETTINGS_H + +#include +#include + +class Settings : public QObject +{ + Q_OBJECT + +public: + enum Options { + Device, + BaudRate, + DataBits, + StopBits, + Parity, + FlowControl, + OpenMode, + ShowCtrlCharacters, + ShowTimestamp, + CommandHistory, + WindowGeometry, + LogFileLocation, + LineTermination, + CharacterDelay, + SendStartDir, + ProtocolOption, + CurrentSession + }; + + struct Session + { + QString device; + quint32 baudRate; + QSerialPort::DataBits dataBits; + QSerialPort::Parity parity; + QSerialPort::StopBits stopBits; + QSerialPort::FlowControl flowControl; + QIODevice::OpenModeFlag openMode; + bool showCtrlCharacters; + bool showTimestamp; + QStringList command_history; + }; + + enum LineTerminator { LF = 0, CR, CRLF, NONE, HEX }; + Q_ENUMS(LineTerminator) + + enum Protocol { PLAIN, SCRIPT, XMODEM, YMODEM, ZMODEM, ONEKXMODEM, PROTOCOL_MAX }; + Q_ENUMS(Protocol) + + explicit Settings(QObject *parent = 0); + void readSettings(const QString &session); + + const Settings::Session getCurrentSession(); + QString getCurrentSessionName() const { return m_current_session; } + void settingChanged(Settings::Options option, QVariant setting); + + QRect getWindowGeometry() const; + + QString getLogFileLocation() const; + + Settings::LineTerminator getLineTerminator() const; + + quint8 getCharacterDelay() const { return m_character_delay; } + + Settings::Protocol getProtocol() const { return m_protocol; } + + QString getSendStartDir() const { return m_sendingStartDir; } + + QList getSessionNames() const; + + void removeSession(const QString &session); + + void cloneSession(const QString &source, const QString &destination); + + void renameSession(const QString &source, const QString &destination); + +signals: + void sessionChanged(const Settings::Session &); + +private: + void readSessionSettings(QSettings &settings); + void saveGenericSettings(); + void saveSessionSettings(); + bool readUIntSetting(QSettings &settings, QString const &name, quint32 *i); + + QRect m_windowGeometry; + QString m_logFileLocation; + /** + * The location QFileDialog displayed for choosing a file + * to send starts off + * @brief m_sendingStartDir + */ + QString m_sendingStartDir; + Settings::LineTerminator m_lineterm; + + /** + * This holds the last protocol selected for + * sending a file across the device + * @brief m_protocol + */ + Settings::Protocol m_protocol; + + /** + * Delay between each character sent + * @brief m_character_delay; + */ + quint8 m_character_delay; + + QHash m_sessions; + QString m_current_session; + static const QString DEFAULT_SESSION_NAME; +}; + +Q_DECLARE_METATYPE(Settings::Session) +Q_DECLARE_METATYPE(Settings::LineTerminator) +Q_DECLARE_METATYPE(Settings::Protocol) + +#endif // SETTINGS_H diff -Nru cutecom-0.22.0/statusbar.cpp cutecom-0.30.3/statusbar.cpp --- cutecom-0.22.0/statusbar.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/statusbar.cpp 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2015 Meinhard Ritscher + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "statusbar.h" +#include +#include +#include + +StatusBar::StatusBar(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); +} + +void StatusBar::sessionChanged(const Settings::Session &session) +{ + QString parity; + switch (session.parity) { + case QSerialPort::NoParity: + parity = QStringLiteral("N"); + break; + case QSerialPort::MarkParity: + parity = QStringLiteral("Mark"); + break; + case QSerialPort::SpaceParity: + parity = QStringLiteral("Space"); + break; + case QSerialPort::EvenParity: + parity = QStringLiteral("Even"); + break; + case QSerialPort::OddParity: + parity = QStringLiteral("Odd"); + break; + default: + parity = QStringLiteral("?"); + break; + } + QString stopBits; + switch (session.stopBits) { + case QSerialPort::OneStop: + stopBits = QString::number(1); + break; + case QSerialPort::OneAndHalfStop: + stopBits = QString::number(1.5); + break; + case QSerialPort::TwoStop: + stopBits = QString::number(2); + break; + default: + break; + } + + QString connectionParameter + = QString("%1 @ %2-%3-%4").arg(session.baudRate).arg(session.dataBits).arg(parity).arg(stopBits); + m_lb_portparams->setText(connectionParameter); + + if (!session.device.isEmpty()) + m_lb_deviceName->setText(session.device); + QWidget::setToolTip(QStringLiteral("")); +} + +void StatusBar::setDeviceInfo(const QSerialPort *port) +{ + QSerialPortInfo info = QSerialPortInfo(*port); + if (info.isValid()) { + QString deviceInfo = QString("%1 %2 @%3").arg(info.manufacturer()).arg(info.description()).arg(info.portName()); + m_lb_deviceName->setText(deviceInfo); + } +} + +void StatusBar::setToolTip(const QSerialPort *port) +{ + + QSerialPortInfo info = QSerialPortInfo(*port); + if (info.isValid()) { + QString deviceInfo = QString("%1 %2\n%3:%4 " +#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) + ) +#else + "# %5") +#endif + .arg(info.manufacturer()) + .arg(info.description()) + .arg(info.vendorIdentifier()) + .arg(info.productIdentifier()) +#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) + ; +#else + .arg(info.serialNumber()); +#endif + QWidget::setToolTip(deviceInfo); + } else { + QWidget::setToolTip(tr("Not a valid device")); + } +} diff -Nru cutecom-0.22.0/statusbar.h cutecom-0.30.3/statusbar.h --- cutecom-0.22.0/statusbar.h 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/statusbar.h 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015 Meinhard Ritscher + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef STATUSBAR_H +#define STATUSBAR_H + +#include "ui_statusbar.h" +#include "settings.h" + +class StatusBar : public QWidget, private Ui::StatusBar +{ + Q_OBJECT + +public: + explicit StatusBar(QWidget *parent = 0); + void sessionChanged(const Settings::Session &session); + void setDeviceInfo(const QSerialPort *port); + void setToolTip(const QSerialPort *port); +}; + +#endif // STATUSBAR_H diff -Nru cutecom-0.22.0/statusbar.ui cutecom-0.30.3/statusbar.ui --- cutecom-0.22.0/statusbar.ui 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/statusbar.ui 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,73 @@ + + + StatusBar + + + + 0 + 0 + 654 + 16 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Device: + + + + + + + + 100 + 0 + + + + + + + + + + + Connection: + + + + + + + + 100 + 0 + + + + + + + + + + + + diff -Nru cutecom-0.22.0/.travis.yml cutecom-0.30.3/.travis.yml --- cutecom-0.22.0/.travis.yml 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/.travis.yml 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,30 @@ + +language: cpp + +env: + - CONFIG=Release + + +install: + - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then + wget --no-check-certificate http://www.cmake.org/files/v3.3/cmake-3.3.2-Linux-i386.tar.gz + && tar -xzf cmake-3.3.2-Linux-i386.tar.gz + && sudo cp -fR cmake-3.3.2-Linux-i386/* /usr + && sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test + && sudo apt-add-repository -y ppa:beineri/opt-qt542 + && sudo apt-get -qq update + && sudo apt-get -qq install g++-4.8 libc6-i386 qt54svg qt54tools qt54serialport + && export CXX="g++-4.8" + && export CC="gcc-4.8" + ; + fi + +script: + - mkdir build + && cd build + && if [ "${TRAVIS_OS_NAME}" = "linux" ]; then + cmake -DCMAKE_BUILD_TYPE=$CONFIG -DENABLE_TRAVIS_CI=ON -DCMAKE_PREFIX_PATH=/opt/qt54/lib/cmake .. + ; + fi + && make -j 3 + && cd .. diff -Nru cutecom-0.22.0/version.h.in cutecom-0.30.3/version.h.in --- cutecom-0.22.0/version.h.in 1970-01-01 00:00:00.000000000 +0000 +++ cutecom-0.30.3/version.h.in 2016-02-15 17:13:18.000000000 +0000 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2015 Meinhard Ritscher + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * For more information on the GPL, please go to: + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef VERSION_H +#define VERSION_H + +#define CuteCom_VERSION "@CuteCom_VERSION@" + +#endif // VERSION_H