First implementation

This commit is contained in:
Yury Shuvakin
2024-07-03 19:11:29 +09:00
parent 25a3a8ac11
commit d708fc3499
153 changed files with 17687 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
/*
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
This file is part of cangaroo.
cangaroo 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.
cangaroo 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 cangaroo. If not, see <http://www.gnu.org/licenses/>.
*/
#include "SelectCanInterfacesDialog.h"
#include "ui_SelectCanInterfacesDialog.h"
#include <core/Backend.h>
SelectCanInterfacesDialog::SelectCanInterfacesDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::SelectCanInterfacesDialog)
{
ui->setupUi(this);
ui->treeWidget->setHeaderLabels(QStringList() << "Device" << "Driver" << "Description");
}
SelectCanInterfacesDialog::~SelectCanInterfacesDialog()
{
delete ui;
}
bool SelectCanInterfacesDialog::selectInterfaces(Backend &backend, CanInterfaceIdList &selectedInterfaces, const CanInterfaceIdList &excludeInterfaces)
{
ui->treeWidget->clear();
CanInterfaceIdList allInterfaces;
foreach (CanInterfaceId intf, backend.getInterfaceList()) {
if (!excludeInterfaces.contains(intf)) {
allInterfaces.append(intf);
}
}
foreach (CanInterfaceId intf, allInterfaces) {
QTreeWidgetItem *treeItem = new QTreeWidgetItem(ui->treeWidget);
treeItem->setText(0, backend.getInterfaceName(intf));
treeItem->setText(1, backend.getDriverName(intf));
treeItem->setText(2, "");
}
if (exec()==QDialog::Accepted) {
selectedInterfaces.clear();
foreach (QModelIndex idx, ui->treeWidget->selectionModel()->selectedRows()) {
if (idx.isValid()) {
selectedInterfaces.append(allInterfaces[idx.row()]);
}
}
return true;
} else {
return false;
}
}

View File

@@ -0,0 +1,47 @@
/*
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
This file is part of cangaroo.
cangaroo 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.
cangaroo 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 cangaroo. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QDialog>
#include <QList>
#include <driver/CanDriver.h>
#include <driver/CanInterface.h>
class Backend;
namespace Ui {
class SelectCanInterfacesDialog;
}
class SelectCanInterfacesDialog : public QDialog
{
Q_OBJECT
public:
explicit SelectCanInterfacesDialog(QWidget *parent = 0);
~SelectCanInterfacesDialog();
bool selectInterfaces(Backend &backend, CanInterfaceIdList &selectedInterfaces, const CanInterfaceIdList &excludeInterfaces);
private:
Ui::SelectCanInterfacesDialog *ui;
};

View File

@@ -0,0 +1,154 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SelectCanInterfacesDialog</class>
<widget class="QDialog" name="SelectCanInterfacesDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>570</width>
<height>438</height>
</rect>
</property>
<property name="windowTitle">
<string>Select CAN Interface(s)</string>
</property>
<property name="windowIcon">
<iconset resource="../../cangaroo.qrc">
<normaloff>:/assets/cangaroo.png</normaloff>:/assets/cangaroo.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTreeWidget" name="treeWidget">
<property name="indentation">
<number>0</number>
</property>
<property name="columnCount">
<number>3</number>
</property>
<attribute name="headerDefaultSectionSize">
<number>100</number>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">2</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">3</string>
</property>
</column>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>&amp;Create Interface...</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../cangaroo.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SelectCanInterfacesDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SelectCanInterfacesDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,340 @@
/*
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
This file is part of cangaroo.
cangaroo 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.
cangaroo 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 cangaroo. If not, see <http://www.gnu.org/licenses/>.
*/
#include "SetupDialog.h"
#include "ui_SetupDialog.h"
#include <QItemSelectionModel>
#include <QMenu>
#include <QFileDialog>
#include <QTreeWidget>
#include <core/Backend.h>
#include <core/MeasurementSetup.h>
#include <driver/CanInterface.h>
#include <driver/CanDriver.h>
#include "SetupDialogTreeModel.h"
#include "SetupDialogTreeItem.h"
#include "SelectCanInterfacesDialog.h"
SetupDialog::SetupDialog(Backend &backend, QWidget *parent) :
QDialog(parent),
ui(new Ui::SetupDialog),
_backend(&backend),
_currentNetwork(0)
{
ui->setupUi(this);
QIcon icon(":/assets/cangaroo.png");
setWindowIcon(icon);
_actionAddInterface = new QAction("Add...", this);
_actionDeleteInterface = new QAction("Delete", this);
_actionAddCanDb = new QAction("Add...", this);
_actionDeleteCanDb = new QAction("Delete", this);
_actionReloadCanDbs = new QAction("Reload", this);
model = new SetupDialogTreeModel(_backend, this);
ui->treeView->setModel(model);
ui->interfacesTreeView->setModel(model);
ui->candbsTreeView->setModel(model);
for (int i=0; i<model->columnCount(); i++) {
ui->treeView->setColumnHidden(i, true);
ui->interfacesTreeView->setColumnHidden(i, true);
ui->candbsTreeView->setColumnHidden(i, true);
}
ui->treeView->setColumnHidden(SetupDialogTreeModel::column_device, false);
ui->interfacesTreeView->setColumnHidden(SetupDialogTreeModel::column_device, false);
ui->interfacesTreeView->setColumnHidden(SetupDialogTreeModel::column_driver, false);
ui->interfacesTreeView->setColumnHidden(SetupDialogTreeModel::column_bitrate, false);
ui->candbsTreeView->setColumnHidden(SetupDialogTreeModel::column_filename, false);
ui->candbsTreeView->setColumnHidden(SetupDialogTreeModel::column_path, false);
connect(ui->treeView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(treeViewContextMenu(QPoint)));
connect(ui->edNetworkName, SIGNAL(textChanged(QString)), this, SLOT(edNetworkNameChanged()));
connect(ui->treeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(treeViewSelectionChanged(QItemSelection,QItemSelection)));
connect(ui->candbsTreeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(updateButtons()));
connect(ui->interfacesTreeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(updateButtons()));
connect(ui->btReloadDatabases, SIGNAL (released()), this, SLOT(executeReloadCanDbs()));
connect(ui->btRefreshNetworks, SIGNAL(released()), this, SLOT(on_btRefreshNetwork_clicked()));
connect(_actionAddCanDb, SIGNAL(triggered()), this, SLOT(executeAddCanDb()));
connect(_actionDeleteCanDb, SIGNAL(triggered()), this, SLOT(executeDeleteCanDb()));
connect(_actionAddInterface, SIGNAL(triggered()), this, SLOT(executeAddInterface()));
connect(_actionDeleteInterface, SIGNAL(triggered()), this, SLOT(executeDeleteInterface()));
emit backend.onSetupDialogCreated(*this);
}
SetupDialog::~SetupDialog()
{
delete ui;
delete model;
}
void SetupDialog::addPage(QWidget *widget)
{
ui->stackedWidget->addWidget(widget);
}
void SetupDialog::displayPage(QWidget *widget)
{
ui->stackedWidget->setCurrentWidget(widget);
}
bool SetupDialog::showSetupDialog(MeasurementSetup &setup)
{
model->load(setup);
ui->treeView->expandAll();
QModelIndex first = model->index(0, 0, QModelIndex());
ui->treeView->setCurrentIndex(first);
updateButtons();
return exec()==QDialog::Accepted;
}
void SetupDialog::treeViewSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{
(void) selected;
(void) deselected;
_currentNetwork = 0;
if (selected.isEmpty()) {
ui->stackedWidget->setCurrentWidget(ui->emptyPage);
updateButtons();
return;
}
QModelIndex idx = selected.first().topLeft();
SetupDialogTreeItem *item = static_cast<SetupDialogTreeItem *>(idx.internalPointer());
_currentNetwork = item->network;
if (item->network) {
ui->edNetworkName->setText(item->network->name());
}
if (item) {
switch (item->getType()) {
case SetupDialogTreeItem::type_network:
ui->stackedWidget->setCurrentWidget(ui->networkPage);
break;
case SetupDialogTreeItem::type_interface_root:
ui->stackedWidget->setCurrentWidget(ui->interfacesPage);
ui->interfacesTreeView->setRootIndex(getSelectedIndex());
break;
case SetupDialogTreeItem::type_interface:
emit onShowInterfacePage(*this, item->intf);
break;
case SetupDialogTreeItem::type_candb_root:
ui->stackedWidget->setCurrentWidget(ui->candbsPage);
ui->candbsTreeView->setRootIndex(getSelectedIndex());
break;
default:
ui->stackedWidget->setCurrentWidget(ui->emptyPage);
break;
}
}
updateButtons();
}
QModelIndex SetupDialog::getSelectedIndex()
{
QModelIndexList list = ui->treeView->selectionModel()->selectedRows();
if (list.isEmpty()) {
return QModelIndex();
} else {
return list.first();
}
}
SetupDialogTreeItem *SetupDialog::getSelectedItem()
{
const QModelIndex index = getSelectedIndex();
SetupDialogTreeItem *item = static_cast<SetupDialogTreeItem *>(index.internalPointer());
return item;
}
void SetupDialog::treeViewContextMenu(const QPoint &pos)
{
(void) pos;
QMenu contextMenu;
SetupDialogTreeItem *item = getSelectedItem();
if (item) {
switch (item->getType()) {
case SetupDialogTreeItem::type_interface_root:
contextMenu.addAction(_actionAddInterface);
break;
case SetupDialogTreeItem::type_interface:
contextMenu.addAction(_actionDeleteInterface);
break;
case SetupDialogTreeItem::type_candb_root:
contextMenu.addAction(_actionAddCanDb);
break;
case SetupDialogTreeItem::type_candb:
contextMenu.addAction(_actionDeleteCanDb);
contextMenu.addAction(_actionReloadCanDbs);
break;
default:
break;
}
}
QPoint globalPos = ui->treeView->mapToGlobal(pos);
contextMenu.exec(globalPos);
}
void SetupDialog::edNetworkNameChanged()
{
if (_currentNetwork) {
_currentNetwork->setName(ui->edNetworkName->text());
model->dataChanged(getSelectedIndex(), getSelectedIndex());
}
}
void SetupDialog::addInterface(const QModelIndex &parent)
{
SelectCanInterfacesDialog dlg(0);
CanInterfaceIdList list;
if (dlg.selectInterfaces(*_backend, list, _currentNetwork->getReferencedCanInterfaces())) {
foreach (CanInterfaceId intf, list) {
model->addInterface(parent, intf);
}
}
}
void SetupDialog::executeAddInterface()
{
addInterface(ui->treeView->selectionModel()->currentIndex());
}
void SetupDialog::on_btAddInterface_clicked()
{
addInterface(ui->treeView->selectionModel()->currentIndex());
}
void SetupDialog::executeDeleteInterface()
{
model->deleteInterface(ui->treeView->selectionModel()->currentIndex());
}
void SetupDialog::on_btRemoveInterface_clicked()
{
model->deleteInterface(ui->interfacesTreeView->selectionModel()->currentIndex());
}
void SetupDialog::addCanDb(const QModelIndex &parent)
{
QString filename = QFileDialog::getOpenFileName(this, "Load CAN Database", "", "Vector DBC Files (*.dbc)");
if (!filename.isNull()) {
pCanDb candb = _backend->loadDbc(filename);
model->addCanDb(parent, candb);
}
}
void SetupDialog::reloadCanDbs(const QModelIndex &parent)
{
SetupDialogTreeItem *parentItem = static_cast<SetupDialogTreeItem*>(parent.internalPointer());
parentItem->network->reloadCanDbs(_backend);
}
void SetupDialog::executeAddCanDb()
{
addCanDb(ui->treeView->selectionModel()->currentIndex());
}
void SetupDialog::executeReloadCanDbs()
{
reloadCanDbs(ui->treeView->selectionModel()->currentIndex());
}
void SetupDialog::on_btAddDatabase_clicked()
{
addCanDb(ui->treeView->selectionModel()->currentIndex());
}
void SetupDialog::executeDeleteCanDb()
{
model->deleteCanDb(getSelectedIndex());
}
void SetupDialog::on_btRemoveDatabase_clicked()
{
model->deleteCanDb(ui->candbsTreeView->selectionModel()->currentIndex());
}
void SetupDialog::updateButtons()
{
ui->btRemoveDatabase->setEnabled(ui->candbsTreeView->selectionModel()->hasSelection());
// ui->btReloadDatabases->setEnabled(ui->candbsTreeView->children.count() > 0);
ui->btRemoveInterface->setEnabled(ui->interfacesTreeView->selectionModel()->hasSelection());
SetupDialogTreeItem *item = getSelectedItem();
ui->btRemoveNetwork->setEnabled(ui->treeView->selectionModel()->hasSelection() && item && (item->getType()==SetupDialogTreeItem::type_network));
}
void SetupDialog::on_btAddNetwork_clicked()
{
QModelIndex idx = model->indexOfItem(model->addNetwork());
ui->treeView->expand(idx);
ui->treeView->selectionModel()->select(idx, QItemSelectionModel::ClearAndSelect);
}
void SetupDialog::on_btRemoveNetwork_clicked()
{
model->deleteNetwork(getSelectedIndex());
}
void SetupDialog::on_btRefreshNetworks_clicked()
{
_backend->setDefaultSetup();
showSetupDialog(_backend->getSetup());
}

View File

@@ -0,0 +1,101 @@
/*
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
This file is part of cangaroo.
cangaroo 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.
cangaroo 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 cangaroo. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QDialog>
#include <QAction>
class Backend;
class MeasurementSetup;
class MeasurementNetwork;
class MeasurementInterface;
class QItemSelection;
class SetupDialogTreeItem;
class SetupDialogTreeModel;
namespace Ui {
class SetupDialog;
}
class SetupDialog : public QDialog
{
Q_OBJECT
public:
explicit SetupDialog(Backend &backend, QWidget *parent = 0);
~SetupDialog();
bool showSetupDialog(MeasurementSetup &setup);
void addPage(QWidget *widget);
void displayPage(QWidget *widget);
signals:
void onShowInterfacePage(SetupDialog &dlg, MeasurementInterface *mi);
public slots:
void treeViewSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected);
void treeViewContextMenu(const QPoint& pos);
private slots:
void edNetworkNameChanged();
void on_btAddInterface_clicked();
void on_btRemoveInterface_clicked();
void on_btAddDatabase_clicked();
void on_btRemoveDatabase_clicked();
void updateButtons();
void executeAddCanDb();
void executeReloadCanDbs();
void executeDeleteCanDb();
void executeAddInterface();
void executeDeleteInterface();
void on_btAddNetwork_clicked();
void on_btRemoveNetwork_clicked();
void on_btRefreshNetworks_clicked();
private:
Ui::SetupDialog *ui;
Backend *_backend;
QAction *_actionDeleteInterface;
QAction *_actionDeleteCanDb;
QAction *_actionAddInterface;
QAction *_actionAddCanDb;
QAction *_actionReloadCanDbs;
SetupDialogTreeModel *model;
MeasurementNetwork *_currentNetwork;
QModelIndex getSelectedIndex();
SetupDialogTreeItem *getSelectedItem();
void addCanDb(const QModelIndex &parent);
void reloadCanDbs(const QModelIndex &parent);
void addInterface(const QModelIndex &parent);
};

View File

@@ -0,0 +1,15 @@
SOURCES += \
$$PWD/SetupDialog.cpp \
$$PWD/SetupDialogTreeModel.cpp \
$$PWD/SetupDialogTreeItem.cpp \
$$PWD/SelectCanInterfacesDialog.cpp
HEADERS += \
$$PWD/SetupDialog.h \
$$PWD/SetupDialogTreeModel.h \
$$PWD/SetupDialogTreeItem.h \
$$PWD/SelectCanInterfacesDialog.h
FORMS += \
$$PWD/SetupDialog.ui \
$$PWD/SelectCanInterfacesDialog.ui

View File

@@ -0,0 +1,315 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SetupDialog</class>
<widget class="QDialog" name="SetupDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1036</width>
<height>835</height>
</rect>
</property>
<property name="windowTitle">
<string>Measurement Setup</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QWidget" name="widget_4" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTreeView" name="treeView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_5" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="btAddNetwork">
<property name="text">
<string>Add Network</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btRemoveNetwork">
<property name="text">
<string>Remove Network</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btRefreshNetworks">
<property name="text">
<string>Refresh</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QStackedWidget" name="stackedWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>3</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="emptyPage"/>
<widget class="QWidget" name="networkPage">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Network name:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="edNetworkName"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="interfacesPage">
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>CAN interfaces assigned to this network:</string>
</property>
</widget>
</item>
<item>
<widget class="QTreeView" name="interfacesTreeView"/>
</item>
<item>
<widget class="QWidget" name="widget_2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="btAddInterface">
<property name="text">
<string>Add &amp;Interface...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btRemoveInterface">
<property name="text">
<string>&amp;Remove Interface</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="candbsPage">
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTreeView" name="candbsTreeView">
<property name="alternatingRowColors">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_3" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="btAddDatabase">
<property name="text">
<string>Add &amp;Database...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btRemoveDatabase">
<property name="text">
<string>&amp;Remove Database</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btReloadDatabases">
<property name="text">
<string>Reload Databases</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SetupDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>266</x>
<y>825</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SetupDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>334</x>
<y>825</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,117 @@
/*
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
This file is part of cangaroo.
cangaroo 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.
cangaroo 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 cangaroo. If not, see <http://www.gnu.org/licenses/>.
*/
#include "SetupDialogTreeItem.h"
#include <QModelIndex>
#include <driver/CanDriver.h>
#include "SetupDialogTreeModel.h"
SetupDialogTreeItem::SetupDialogTreeItem(item_type type, Backend *backend, SetupDialogTreeItem *parent)
: setup(0), network(0), intf(0), candb(0), _backend(backend), _type(type), _parent(parent)
{
}
SetupDialogTreeItem::~SetupDialogTreeItem()
{
qDeleteAll(_children);
}
SetupDialogTreeItem *SetupDialogTreeItem::getParentItem() const
{
return _parent;
}
int SetupDialogTreeItem::getChildCount() const
{
return _children.length();
}
void SetupDialogTreeItem::appendChild(SetupDialogTreeItem *child)
{
_children.append(child);
}
void SetupDialogTreeItem::removeChild(SetupDialogTreeItem *child)
{
_children.removeAll(child);
}
SetupDialogTreeItem *SetupDialogTreeItem::child(int row) const
{
return _children.value(row);
}
int SetupDialogTreeItem::row() const
{
if (_parent) {
return _parent->_children.indexOf(const_cast<SetupDialogTreeItem*>(this));
} else {
return 0;
}
}
QVariant SetupDialogTreeItem::dataInterface(const QModelIndex &index) const
{
switch (index.column()) {
case SetupDialogTreeModel::column_device:
return _backend->getInterfaceName(intf->canInterface());
case SetupDialogTreeModel::column_driver:
return _backend->getDriverName(intf->canInterface());
case SetupDialogTreeModel::column_bitrate:
return intf->bitrate();
default:
return QVariant();
}
}
QVariant SetupDialogTreeItem::dataCanDb(const QModelIndex &index) const
{
switch (index.column()) {
case SetupDialogTreeModel::column_device:
return candb->getFileName();
case SetupDialogTreeModel::column_filename:
return candb->getFileName();
case SetupDialogTreeModel::column_path:
return candb->getDirectory();
default:
return QVariant();
}
}
QVariant SetupDialogTreeItem::dataDisplayRole(const QModelIndex &index) const
{
switch (_type) {
case type_root: return "Setup";
case type_network: return (network!=0) ? network->name() : QVariant();
case type_interface_root: return "Interfaces";
case type_interface: return dataInterface(index);
case type_candb_root: return "Can Databases";
case type_candb: return dataCanDb(index);
}
return QVariant();
}
SetupDialogTreeItem::item_type SetupDialogTreeItem::getType()
{
return _type;
}

View File

@@ -0,0 +1,74 @@
/*
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
This file is part of cangaroo.
cangaroo 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.
cangaroo 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 cangaroo. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QList>
#include <QVariant>
#include <core/Backend.h>
#include <core/MeasurementSetup.h>
#include <core/MeasurementNetwork.h>
#include <core/MeasurementInterface.h>
#include <core/CanDb.h>
class SetupDialogTreeItem
{
public:
typedef enum {
type_root,
type_network,
type_interface_root,
type_interface,
type_candb_root,
type_candb,
} item_type;
public:
SetupDialogTreeItem(item_type type, Backend *backend, SetupDialogTreeItem *parent=0);
virtual ~SetupDialogTreeItem();
MeasurementSetup *setup;
MeasurementNetwork *network;
MeasurementInterface *intf;
pCanDb candb;
SetupDialogTreeItem *getParentItem() const;
int getChildCount() const;
void appendChild(SetupDialogTreeItem *child);
void removeChild(SetupDialogTreeItem *child);
SetupDialogTreeItem *child(int row) const;
int row() const;
QVariant dataDisplayRole(const QModelIndex &index) const;
item_type getType();
private:
Backend *_backend;
item_type _type;
SetupDialogTreeItem *_parent;
QList<SetupDialogTreeItem*> _children;
QVariant dataInterface(const QModelIndex &index) const;
QVariant dataCanDb(const QModelIndex &index) const;
};

View File

@@ -0,0 +1,263 @@
/*
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
This file is part of cangaroo.
cangaroo 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.
cangaroo 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 cangaroo. If not, see <http://www.gnu.org/licenses/>.
*/
#include "SetupDialogTreeModel.h"
SetupDialogTreeModel::SetupDialogTreeModel(Backend *backend, QObject *parent)
: QAbstractItemModel(parent),
_backend(backend),
_rootItem(0)
{
}
SetupDialogTreeModel::~SetupDialogTreeModel()
{
if (_rootItem) {
delete _rootItem;
}
}
QVariant SetupDialogTreeModel::data(const QModelIndex &index, int role) const
{
SetupDialogTreeItem *item = static_cast<SetupDialogTreeItem*>(index.internalPointer());
if (item) {
if (role==Qt::DisplayRole) {
return item->dataDisplayRole(index);
}
}
return QVariant();
}
QVariant SetupDialogTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
(void) orientation;
if (role==Qt::DisplayRole) {
switch (section) {
case column_device: return "Device";
case column_driver: return "Driver";
case column_bitrate: return "Bitrate";
case column_filename: return "Filename";
case column_path: return "Path";
default: return "";
}
} else {
return QVariant();
}
}
QModelIndex SetupDialogTreeModel::index(int row, int column, const QModelIndex &parent) const
{
if (!hasIndex(row, column, parent)) {
return QModelIndex();
} else {
SetupDialogTreeItem *parentItem = itemOrRoot(parent);
SetupDialogTreeItem *childItem = parentItem->child(row);
return childItem ? createIndex(row, column, childItem) : QModelIndex();
}
}
QModelIndex SetupDialogTreeModel::parent(const QModelIndex &index) const
{
if (!index.isValid()) { return QModelIndex(); }
SetupDialogTreeItem *childItem = static_cast<SetupDialogTreeItem*>(index.internalPointer());
SetupDialogTreeItem *parentItem = childItem->getParentItem();
return (parentItem == _rootItem) ? QModelIndex() : createIndex(parentItem->row(), 0, parentItem);
}
int SetupDialogTreeModel::rowCount(const QModelIndex &parent) const
{
int retval = 0;
if (parent.column() <= 0) {
SetupDialogTreeItem *item = itemOrRoot(parent);
if (item) {
retval = item->getChildCount();
}
}
return retval;
}
int SetupDialogTreeModel::columnCount(const QModelIndex &parent) const
{
(void) parent;
return column_count;
}
QModelIndex SetupDialogTreeModel::indexOfItem(const SetupDialogTreeItem *item) const
{
return createIndex(item->row(), 0, (void*)item);
}
SetupDialogTreeItem *SetupDialogTreeModel::addNetwork()
{
QString s;
int i=0;
while (true) {
s = QString("Network %1").arg(++i);
if (_rootItem->setup->getNetworkByName(s)==0) {
break;
}
}
beginInsertRows(QModelIndex(), _rootItem->getChildCount(), _rootItem->getChildCount());
MeasurementNetwork *network = _rootItem->setup->createNetwork();
network->setName(s);
SetupDialogTreeItem *item = loadNetwork(_rootItem, *network);
endInsertRows();
return item;
}
void SetupDialogTreeModel::deleteNetwork(const QModelIndex &index)
{
SetupDialogTreeItem *item = static_cast<SetupDialogTreeItem*>(index.internalPointer());
beginRemoveRows(index.parent(), index.row(), index.row());
_rootItem->removeChild(item);
_rootItem->setup->removeNetwork(item->network);
endRemoveRows();
}
SetupDialogTreeItem *SetupDialogTreeModel::addCanDb(const QModelIndex &parent, pCanDb db)
{
SetupDialogTreeItem *parentItem = static_cast<SetupDialogTreeItem*>(parent.internalPointer());
if (!parentItem) { return 0; }
SetupDialogTreeItem *item = 0;
if (parentItem->network) {
beginInsertRows(parent, rowCount(parent), rowCount(parent));
parentItem->network->addCanDb(db);
item = loadCanDb(*parentItem, db);
endInsertRows();
}
return item;
}
void SetupDialogTreeModel::deleteCanDb(const QModelIndex &index)
{
SetupDialogTreeItem *item = static_cast<SetupDialogTreeItem*>(index.internalPointer());
if (!item) { return; }
SetupDialogTreeItem *parentItem = item->getParentItem();
if (parentItem && parentItem->network && parentItem->network->_canDbs.contains(item->candb)) {
parentItem->network->_canDbs.removeAll(item->candb);
beginRemoveRows(index.parent(), item->row(), item->row());
item->getParentItem()->removeChild(item);
endRemoveRows();
}
}
SetupDialogTreeItem *SetupDialogTreeModel::addInterface(const QModelIndex &parent, CanInterfaceId &interface)
{
SetupDialogTreeItem *parentItem = static_cast<SetupDialogTreeItem*>(parent.internalPointer());
if (!parentItem) { return 0; }
SetupDialogTreeItem *item = 0;
if (parentItem && parentItem->network) {
beginInsertRows(parent, parentItem->getChildCount(), parentItem->getChildCount());
MeasurementInterface *mi = parentItem->network->addCanInterface(interface);
item = loadMeasurementInterface(*parentItem, mi);
endInsertRows();
}
return item;
}
void SetupDialogTreeModel::deleteInterface(const QModelIndex &index)
{
SetupDialogTreeItem *item = static_cast<SetupDialogTreeItem*>(index.internalPointer());
if (!item) { return; }
SetupDialogTreeItem *parentItem = item->getParentItem();
if (parentItem && parentItem->network && parentItem->network->interfaces().contains(item->intf)) {
parentItem->network->removeInterface(item->intf);
beginRemoveRows(index.parent(), item->row(), item->row());
item->getParentItem()->removeChild(item);
endRemoveRows();
}
}
SetupDialogTreeItem *SetupDialogTreeModel::itemOrRoot(const QModelIndex &index) const
{
return index.isValid() ? static_cast<SetupDialogTreeItem*>(index.internalPointer()) : _rootItem;
}
SetupDialogTreeItem *SetupDialogTreeModel::loadMeasurementInterface(SetupDialogTreeItem &parent, MeasurementInterface *intf)
{
SetupDialogTreeItem *item = new SetupDialogTreeItem(SetupDialogTreeItem::type_interface, _backend, &parent);
item->intf = intf;
parent.appendChild(item);
return item;
}
SetupDialogTreeItem *SetupDialogTreeModel::loadCanDb(SetupDialogTreeItem &parent, pCanDb &db)
{
SetupDialogTreeItem *item = new SetupDialogTreeItem(SetupDialogTreeItem::type_candb, _backend, &parent);
item->candb = db;
parent.appendChild(item);
return item;
}
SetupDialogTreeItem *SetupDialogTreeModel::loadNetwork(SetupDialogTreeItem *root, MeasurementNetwork &network)
{
SetupDialogTreeItem *item_network = new SetupDialogTreeItem(SetupDialogTreeItem::type_network, _backend, root);
item_network->network = &network;
SetupDialogTreeItem *item_intf_root = new SetupDialogTreeItem(SetupDialogTreeItem::type_interface_root, _backend, item_network);
item_intf_root->network = &network;
item_network->appendChild(item_intf_root);
SetupDialogTreeItem *item_candb_root = new SetupDialogTreeItem(SetupDialogTreeItem::type_candb_root, _backend, item_network);
item_candb_root->network = &network;
item_network->appendChild(item_candb_root);
foreach (MeasurementInterface *intf, network.interfaces()) {
loadMeasurementInterface(*item_intf_root, intf);
}
foreach (pCanDb candb, network._canDbs) {
loadCanDb(*item_candb_root, candb);
}
root->appendChild(item_network);
return item_network;
}
void SetupDialogTreeModel::load(MeasurementSetup &setup)
{
SetupDialogTreeItem *_newRoot = new SetupDialogTreeItem(SetupDialogTreeItem::type_root, 0);
_newRoot->setup = &setup;
foreach (MeasurementNetwork *network, setup.getNetworks()) {
loadNetwork(_newRoot, *network);
}
beginResetModel();
SetupDialogTreeItem *_oldRoot = _rootItem;
_rootItem = _newRoot;
delete _oldRoot;
endResetModel();
}

View File

@@ -0,0 +1,77 @@
/*
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
This file is part of cangaroo.
cangaroo 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.
cangaroo 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 cangaroo. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "SetupDialogTreeItem.h"
#include <QAbstractItemModel>
#include <core/Backend.h>
#include <core/MeasurementSetup.h>
class SetupDialogTreeModel : public QAbstractItemModel
{
Q_OBJECT
public:
enum {
column_device,
column_driver,
column_bitrate,
column_filename,
column_path,
column_count
};
public:
explicit SetupDialogTreeModel(Backend *backend, QObject *parent=0);
virtual ~SetupDialogTreeModel();
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE;
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
QModelIndex indexOfItem(const SetupDialogTreeItem *item) const;
void load(MeasurementSetup &setup);
SetupDialogTreeItem *addNetwork();
void deleteNetwork(const QModelIndex &index);
int getNetworkCount();
SetupDialogTreeItem *addCanDb(const QModelIndex &parent, pCanDb db);
void deleteCanDb(const QModelIndex &index);
SetupDialogTreeItem *addInterface(const QModelIndex &parent, CanInterfaceId &interface);
void deleteInterface(const QModelIndex &index);
private:
Backend *_backend;
SetupDialogTreeItem *_rootItem;
SetupDialogTreeItem *itemOrRoot(const QModelIndex &index) const;
SetupDialogTreeItem *loadNetwork(SetupDialogTreeItem *root, MeasurementNetwork &network);
SetupDialogTreeItem *loadMeasurementInterface(SetupDialogTreeItem &parent, MeasurementInterface *intf);
SetupDialogTreeItem *loadCanDb(SetupDialogTreeItem &parent, pCanDb &db);
};