forked from len0rd/rockbox
qeditor: port to the new hwstub library and add features
This commit adds support for the version of the hwstub library, which requires a lot of changes. It also adds some editing features, such as register access and much better editing of fields using the mouse (double click on a field to be able to resize and move it). Change-Id: I3c4e4cc855cb44911c72bc8127bad841b68efe52
This commit is contained in:
parent
cc4c9b70bc
commit
5ac0166388
11 changed files with 1412 additions and 347 deletions
|
@ -79,7 +79,7 @@ struct soc_t
|
||||||
#define PIN_GROUP_PREFIX_NONE ""
|
#define PIN_GROUP_PREFIX_NONE ""
|
||||||
|
|
||||||
#define R(group,name,block) {PIN_GROUP_PREFIX_##group name, PIN_GROUP_##group, block}
|
#define R(group,name,block) {PIN_GROUP_PREFIX_##group name, PIN_GROUP_##group, block}
|
||||||
#define Q(group,block,name) R(group,STR(block)"_"name, block)
|
#define Q(group,block,name) R(group,STR(block) "_" name, block)
|
||||||
#define P(group,name) R(group,name,PIN_NO_BLOCK)
|
#define P(group,name) R(group,name,PIN_NO_BLOCK)
|
||||||
|
|
||||||
#define IO P(GPIO,"gpio")
|
#define IO P(GPIO,"gpio")
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#include <QFont>
|
||||||
#include "backend.h"
|
#include "backend.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -336,111 +337,437 @@ QString FileIoBackend::GetFileName()
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_HWSTUB
|
#ifdef HAVE_HWSTUB
|
||||||
|
/**
|
||||||
|
* HWStubManager
|
||||||
|
*/
|
||||||
|
HWStubManager *HWStubManager::g_inst = nullptr;
|
||||||
|
|
||||||
|
HWStubManager::HWStubManager()
|
||||||
|
{
|
||||||
|
Add("Default", QString::fromStdString(hwstub::uri::default_uri().full_uri()));
|
||||||
|
}
|
||||||
|
|
||||||
|
HWStubManager::~HWStubManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HWStubManager *HWStubManager::Get()
|
||||||
|
{
|
||||||
|
if(g_inst == nullptr)
|
||||||
|
g_inst = new HWStubManager();
|
||||||
|
return g_inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HWStubManager::Add(const QString& name, const QString& uri)
|
||||||
|
{
|
||||||
|
struct Context ctx;
|
||||||
|
ctx.name = name;
|
||||||
|
ctx.uri = uri;
|
||||||
|
ctx.context = hwstub::uri::create_context(uri.toStdString());
|
||||||
|
if(!ctx.context)
|
||||||
|
return false;
|
||||||
|
ctx.context->start_polling();
|
||||||
|
beginInsertRows(QModelIndex(), m_list.size(), m_list.size());
|
||||||
|
m_list.push_back(ctx);
|
||||||
|
endInsertRows();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HWStubManager::Clear()
|
||||||
|
{
|
||||||
|
m_list.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
int HWStubManager::rowCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
return m_list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int HWStubManager::columnCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr< hwstub::context > HWStubManager::GetContext(int row)
|
||||||
|
{
|
||||||
|
if(row < 0 || (size_t)row >= m_list.size())
|
||||||
|
return std::shared_ptr< hwstub::context >();
|
||||||
|
else
|
||||||
|
return m_list[row].context;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant HWStubManager::data(const QModelIndex& index, int role) const
|
||||||
|
{
|
||||||
|
if(index.row() < 0 || (size_t)index.row() >= m_list.size())
|
||||||
|
return QVariant();
|
||||||
|
int section = index.column();
|
||||||
|
const Context& ctx = m_list[index.row()];
|
||||||
|
if(section == GetNameColumn())
|
||||||
|
{
|
||||||
|
if(role == Qt::DisplayRole || role == Qt::EditRole)
|
||||||
|
return QVariant(ctx.name);
|
||||||
|
}
|
||||||
|
else if(section == GetUriColumn())
|
||||||
|
{
|
||||||
|
if(role == Qt::DisplayRole)
|
||||||
|
return QVariant(ctx.uri);
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant HWStubManager::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
if(orientation == Qt::Vertical)
|
||||||
|
return QVariant();
|
||||||
|
if(role != Qt::DisplayRole)
|
||||||
|
return QVariant();
|
||||||
|
if(section == GetNameColumn())
|
||||||
|
return QVariant("Name");
|
||||||
|
else if(section == GetUriColumn())
|
||||||
|
return QVariant("URI");
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags HWStubManager::flags(const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||||
|
int section = index.column();
|
||||||
|
if(section == GetNameColumn())
|
||||||
|
flags |= Qt::ItemIsEditable;
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HWStubManager::setData(const QModelIndex& index, const QVariant& value, int role)
|
||||||
|
{
|
||||||
|
if(role != Qt::EditRole)
|
||||||
|
return false;
|
||||||
|
if(index.row() < 0 || (size_t)index.row() >= m_list.size())
|
||||||
|
return false;
|
||||||
|
if(index.column() != GetNameColumn())
|
||||||
|
return false;
|
||||||
|
m_list[index.row()].name = value.toString();
|
||||||
|
emit dataChanged(index, index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HWStubManager::GetNameColumn() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HWStubManager::GetUriColumn() const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString HWStubManager::GetFriendlyName(std::shared_ptr< hwstub::device > device)
|
||||||
|
{
|
||||||
|
/* try to open the device */
|
||||||
|
std::shared_ptr< hwstub::handle > handle;
|
||||||
|
hwstub::error err = device->open(handle);
|
||||||
|
if(err != hwstub::error::SUCCESS)
|
||||||
|
goto Lfallback;
|
||||||
|
/* get target descriptor */
|
||||||
|
struct hwstub_target_desc_t target_desc;
|
||||||
|
err = handle->get_target_desc(target_desc);
|
||||||
|
if(err != hwstub::error::SUCCESS)
|
||||||
|
goto Lfallback;
|
||||||
|
return QString::fromStdString(target_desc.bName);
|
||||||
|
|
||||||
|
/* fallback: don't open the device */
|
||||||
|
Lfallback:
|
||||||
|
hwstub::usb::device *udev = dynamic_cast< hwstub::usb::device* >(device.get());
|
||||||
|
if(udev)
|
||||||
|
{
|
||||||
|
return QString("USB Bus %1 Device %2: ID %3:%4")
|
||||||
|
.arg(udev->get_bus_number()).arg(udev->get_address(), 3, 10, QChar('0'))
|
||||||
|
.arg(udev->get_vid(), 4, 16, QChar('0')).arg(udev->get_pid(), 4, 16, QChar('0'));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return QString("<Unknown device>");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HWStubContextModel
|
||||||
|
*/
|
||||||
|
HWStubContextModel::HWStubContextModel(QObject *parent)
|
||||||
|
:QAbstractTableModel(parent), m_has_dummy(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HWStubContextModel::~HWStubContextModel()
|
||||||
|
{
|
||||||
|
SetContext(std::shared_ptr< hwstub::context >());
|
||||||
|
}
|
||||||
|
|
||||||
|
void HWStubContextModel::SetContext(std::shared_ptr< hwstub::context > context)
|
||||||
|
{
|
||||||
|
int first_row = m_has_dummy ? 1: 0;
|
||||||
|
/* clear previous model if any */
|
||||||
|
if(m_list.size() > 0)
|
||||||
|
{
|
||||||
|
beginRemoveRows(QModelIndex(), first_row, first_row + m_list.size() - 1);
|
||||||
|
m_list.clear();
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
/* don't forget to unregister callback if context still exists */
|
||||||
|
std::shared_ptr< hwstub::context > ctx = m_context.lock();
|
||||||
|
if(ctx)
|
||||||
|
ctx->unregister_callback(m_callback_ref);
|
||||||
|
/* get new context */
|
||||||
|
m_context = context;
|
||||||
|
if(context)
|
||||||
|
{
|
||||||
|
/* register new callback */
|
||||||
|
m_callback_ref = context->register_callback(
|
||||||
|
std::bind(&HWStubContextModel::OnDevChangeLow, this, std::placeholders::_1,
|
||||||
|
std::placeholders::_2, std::placeholders::_3));
|
||||||
|
/* get dev list */
|
||||||
|
std::vector< std::shared_ptr< hwstub::device > > list;
|
||||||
|
hwstub::error err = context->get_device_list(list);
|
||||||
|
if(err == hwstub::error::SUCCESS)
|
||||||
|
{
|
||||||
|
beginInsertRows(QModelIndex(), first_row, first_row + list.size() - 1);
|
||||||
|
for(auto& d : list)
|
||||||
|
{
|
||||||
|
Device dev;
|
||||||
|
dev.name = GetFriendlyName(d);
|
||||||
|
dev.device = d;
|
||||||
|
m_list.push_back(dev);
|
||||||
|
}
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HWStubContextModel::EnableDummy(bool en, const QString& text)
|
||||||
|
{
|
||||||
|
/* if needed, create/remove raw */
|
||||||
|
if(m_has_dummy && !en)
|
||||||
|
{
|
||||||
|
/* remove row */
|
||||||
|
beginRemoveRows(QModelIndex(), 0, 0);
|
||||||
|
m_has_dummy = false;
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
else if(!m_has_dummy && en)
|
||||||
|
{
|
||||||
|
/* add row */
|
||||||
|
beginInsertRows(QModelIndex(), 0, 0);
|
||||||
|
m_has_dummy = true;
|
||||||
|
m_dummy_text = text;
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
else if(en)
|
||||||
|
{
|
||||||
|
/* text change only */
|
||||||
|
emit dataChanged(index(0, GetNameColumn()), index(0, GetNameColumn()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int HWStubContextModel::rowCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
return m_list.size() + (m_has_dummy ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int HWStubContextModel::columnCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant HWStubContextModel::data(const QModelIndex& index, int role) const
|
||||||
|
{
|
||||||
|
int first_row = m_has_dummy ? 1: 0;
|
||||||
|
/* special case for dummy */
|
||||||
|
if(m_has_dummy && index.row() == 0)
|
||||||
|
{
|
||||||
|
int section = index.column();
|
||||||
|
if(section == GetNameColumn())
|
||||||
|
{
|
||||||
|
if(role == Qt::DisplayRole)
|
||||||
|
return QVariant(m_dummy_text);
|
||||||
|
else if(role == Qt::FontRole)
|
||||||
|
{
|
||||||
|
QFont font;
|
||||||
|
font.setItalic(true);
|
||||||
|
return QVariant(font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(index.row() < first_row || (size_t)index.row() >= first_row + m_list.size())
|
||||||
|
return QVariant();
|
||||||
|
int section = index.column();
|
||||||
|
if(section == GetNameColumn())
|
||||||
|
{
|
||||||
|
if(role == Qt::DisplayRole)
|
||||||
|
return QVariant(m_list[index.row() - first_row].name);
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant HWStubContextModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
if(orientation == Qt::Vertical)
|
||||||
|
return QVariant();
|
||||||
|
if(role != Qt::DisplayRole)
|
||||||
|
return QVariant();
|
||||||
|
if(section == GetNameColumn())
|
||||||
|
return QVariant("Friendly name");
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags HWStubContextModel::flags(const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(index);
|
||||||
|
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HWStubContextModel::GetNameColumn() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr< hwstub::device > HWStubContextModel::GetDevice(int row)
|
||||||
|
{
|
||||||
|
int first_row = m_has_dummy ? 1: 0;
|
||||||
|
/* special case for dummy */
|
||||||
|
if(row < first_row || (size_t)row >= first_row + m_list.size())
|
||||||
|
return std::shared_ptr< hwstub::device >();
|
||||||
|
else
|
||||||
|
return m_list[row - first_row].device;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString HWStubContextModel::GetFriendlyName(std::shared_ptr< hwstub::device > device)
|
||||||
|
{
|
||||||
|
return HWStubManager::GetFriendlyName(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct dev_change_t
|
||||||
|
{
|
||||||
|
std::shared_ptr< hwstub::context > ctx;
|
||||||
|
bool arrived;
|
||||||
|
std::shared_ptr< hwstub::device > device;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void HWStubContextModel::OnDevChangeLow(std::shared_ptr< hwstub::context > ctx,
|
||||||
|
bool arrived, std::shared_ptr< hwstub::device > device)
|
||||||
|
{
|
||||||
|
/* calling Qt function from non-Qt thread is unsafe. Since the polling thread
|
||||||
|
* is a pthread, the safest way to use Qt invoke mecanism to make it run
|
||||||
|
* on the event loop */
|
||||||
|
dev_change_t *evt = new dev_change_t;
|
||||||
|
evt->ctx = ctx;
|
||||||
|
evt->arrived = arrived;
|
||||||
|
evt->device = device;
|
||||||
|
QMetaObject::invokeMethod(this, "OnDevChangeUnsafe", Q_ARG(void *, (void *)evt));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HWStubContextModel::OnDevChangeUnsafe(void *data)
|
||||||
|
{
|
||||||
|
dev_change_t *evt = (dev_change_t *)data;
|
||||||
|
OnDevChange(evt->ctx, evt->arrived, evt->device);
|
||||||
|
delete evt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HWStubContextModel::OnDevChange(std::shared_ptr< hwstub::context > ctx, bool arrived,
|
||||||
|
std::shared_ptr< hwstub::device > device)
|
||||||
|
{
|
||||||
|
int first_row = m_has_dummy ? 1: 0;
|
||||||
|
Q_UNUSED(ctx);
|
||||||
|
if(arrived)
|
||||||
|
{
|
||||||
|
Device dev;
|
||||||
|
dev.name = GetFriendlyName(device);
|
||||||
|
dev.device = device;
|
||||||
|
beginInsertRows(QModelIndex(), first_row + m_list.size(),
|
||||||
|
first_row + m_list.size());
|
||||||
|
m_list.push_back(dev);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* find device in the list */
|
||||||
|
auto it = m_list.begin();
|
||||||
|
int idx = 0;
|
||||||
|
for(; it != m_list.end(); ++it, ++idx)
|
||||||
|
if(it->device == device)
|
||||||
|
break;
|
||||||
|
if(it == m_list.end())
|
||||||
|
return;
|
||||||
|
/* remove it */
|
||||||
|
beginRemoveRows(QModelIndex(), first_row + idx, first_row + idx);
|
||||||
|
m_list.erase(it);
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HWStubDevice
|
* HWStubDevice
|
||||||
*/
|
*/
|
||||||
HWStubDevice::HWStubDevice(struct libusb_device *dev)
|
HWStubDevice::HWStubDevice(std::shared_ptr< hwstub::device > device)
|
||||||
{
|
{
|
||||||
Init(dev);
|
m_valid = Probe(device);
|
||||||
}
|
|
||||||
|
|
||||||
HWStubDevice::HWStubDevice(const HWStubDevice *dev)
|
|
||||||
{
|
|
||||||
Init(dev->m_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HWStubDevice::Init(struct libusb_device *dev)
|
|
||||||
{
|
|
||||||
libusb_ref_device(dev);
|
|
||||||
m_dev = dev;
|
|
||||||
m_handle = 0;
|
|
||||||
m_hwdev = 0;
|
|
||||||
m_valid = Probe();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HWStubDevice::~HWStubDevice()
|
HWStubDevice::~HWStubDevice()
|
||||||
{
|
{
|
||||||
Close();
|
|
||||||
libusb_unref_device(m_dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int HWStubDevice::GetBusNumber()
|
bool HWStubDevice::Probe(std::shared_ptr<hwstub::device> device)
|
||||||
{
|
{
|
||||||
return libusb_get_bus_number(m_dev);
|
if(!device)
|
||||||
}
|
|
||||||
|
|
||||||
int HWStubDevice::GetDevAddress()
|
|
||||||
{
|
|
||||||
return libusb_get_device_address(m_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HWStubDevice::Probe()
|
|
||||||
{
|
|
||||||
if(!Open())
|
|
||||||
return false;
|
return false;
|
||||||
// get target
|
hwstub::error err = device->open(m_handle);
|
||||||
int ret = hwstub_get_desc(m_hwdev, HWSTUB_DT_TARGET, &m_hwdev_target, sizeof(m_hwdev_target));
|
if(err != hwstub::error::SUCCESS)
|
||||||
if(ret != sizeof(m_hwdev_target))
|
return false;
|
||||||
goto Lerr;
|
// get target information
|
||||||
// get STMP information
|
err = m_handle->get_target_desc(m_hwdev_target);
|
||||||
|
if(err != hwstub::error::SUCCESS)
|
||||||
|
return false;
|
||||||
|
// get STMP/PP information
|
||||||
if(m_hwdev_target.dID == HWSTUB_TARGET_STMP)
|
if(m_hwdev_target.dID == HWSTUB_TARGET_STMP)
|
||||||
{
|
{
|
||||||
ret = hwstub_get_desc(m_hwdev, HWSTUB_DT_STMP, &m_hwdev_stmp, sizeof(m_hwdev_stmp));
|
err = m_handle->get_stmp_desc(m_hwdev_stmp);
|
||||||
if(ret != sizeof(m_hwdev_stmp))
|
if(err != hwstub::error::SUCCESS)
|
||||||
goto Lerr;
|
return false;
|
||||||
}
|
}
|
||||||
else if(m_hwdev_target.dID == HWSTUB_TARGET_PP)
|
else if(m_hwdev_target.dID == HWSTUB_TARGET_PP)
|
||||||
{
|
{
|
||||||
ret = hwstub_get_desc(m_hwdev, HWSTUB_DT_PP, &m_hwdev_pp, sizeof(m_hwdev_pp));
|
err = m_handle->get_pp_desc(m_hwdev_pp);
|
||||||
if(ret != sizeof(m_hwdev_pp))
|
if(err != hwstub::error::SUCCESS)
|
||||||
goto Lerr;
|
return false;
|
||||||
}
|
}
|
||||||
Close();
|
else if(m_hwdev_target.dID == HWSTUB_TARGET_JZ)
|
||||||
return true;
|
|
||||||
|
|
||||||
Lerr:
|
|
||||||
Close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HWStubDevice::Open()
|
|
||||||
{
|
|
||||||
if(libusb_open(m_dev, &m_handle))
|
|
||||||
return false;
|
|
||||||
m_hwdev = hwstub_open(m_handle);
|
|
||||||
if(m_hwdev == 0)
|
|
||||||
{
|
{
|
||||||
libusb_close(m_handle);
|
err = m_handle->get_jz_desc(m_hwdev_jz);
|
||||||
m_handle = 0;
|
if(err != hwstub::error::SUCCESS)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
m_name = HWStubManager::GetFriendlyName(device);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HWStubDevice::Close()
|
|
||||||
{
|
|
||||||
if(m_hwdev)
|
|
||||||
hwstub_release(m_hwdev);
|
|
||||||
m_hwdev = 0;
|
|
||||||
if(m_handle)
|
|
||||||
libusb_close(m_handle);
|
|
||||||
m_handle = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HWStubDevice::ReadMem(soc_addr_t addr, size_t length, void *buffer)
|
bool HWStubDevice::ReadMem(soc_addr_t addr, size_t length, void *buffer)
|
||||||
{
|
{
|
||||||
if(!m_hwdev)
|
size_t len = length;
|
||||||
return false;
|
hwstub::error err = m_handle->read(addr, buffer, len, true);
|
||||||
int ret = hwstub_rw_mem_atomic(m_hwdev, 1, addr, buffer, length);
|
return err == hwstub::error::SUCCESS && len == length;
|
||||||
return ret >= 0 && (size_t)ret == length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HWStubDevice::WriteMem(soc_addr_t addr, size_t length, void *buffer)
|
bool HWStubDevice::WriteMem(soc_addr_t addr, size_t length, void *buffer)
|
||||||
{
|
{
|
||||||
if(!m_hwdev)
|
size_t len = length;
|
||||||
return false;
|
hwstub::error err = m_handle->write(addr, buffer, len, true);
|
||||||
int ret = hwstub_rw_mem_atomic(m_hwdev, 0, addr, buffer, length);
|
return err == hwstub::error::SUCCESS && len == length;
|
||||||
return ret >= 0 && (size_t)ret == length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HWStubDevice::IsValid()
|
bool HWStubDevice::IsValid()
|
||||||
|
@ -448,6 +775,10 @@ bool HWStubDevice::IsValid()
|
||||||
return m_valid;
|
return m_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString HWStubDevice::GetFriendlyName()
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HWStubIoBackend
|
* HWStubIoBackend
|
||||||
|
@ -456,7 +787,7 @@ bool HWStubDevice::IsValid()
|
||||||
HWStubIoBackend::HWStubIoBackend(HWStubDevice *dev)
|
HWStubIoBackend::HWStubIoBackend(HWStubDevice *dev)
|
||||||
{
|
{
|
||||||
m_dev = dev;
|
m_dev = dev;
|
||||||
m_dev->Open();
|
|
||||||
struct hwstub_target_desc_t target = m_dev->GetTargetInfo();
|
struct hwstub_target_desc_t target = m_dev->GetTargetInfo();
|
||||||
if(target.dID == HWSTUB_TARGET_STMP)
|
if(target.dID == HWSTUB_TARGET_STMP)
|
||||||
{
|
{
|
||||||
|
@ -470,6 +801,13 @@ HWStubIoBackend::HWStubIoBackend(HWStubDevice *dev)
|
||||||
else
|
else
|
||||||
m_soc = QString("stmp%1").arg(stmp.wChipID, 4, 16, QChar('0'));
|
m_soc = QString("stmp%1").arg(stmp.wChipID, 4, 16, QChar('0'));
|
||||||
}
|
}
|
||||||
|
else if(target.dID == HWSTUB_TARGET_JZ)
|
||||||
|
{
|
||||||
|
struct hwstub_jz_desc_t jz = m_dev->GetJZInfo();
|
||||||
|
m_soc = QString("jz%1").arg(jz.wChipID, 4, 16, QChar('0'));
|
||||||
|
if(jz.bRevision != 0)
|
||||||
|
m_soc.append(QChar(jz.bRevision).toLower());
|
||||||
|
}
|
||||||
else if(target.dID == HWSTUB_TARGET_RK27)
|
else if(target.dID == HWSTUB_TARGET_RK27)
|
||||||
m_soc = "rk27x";
|
m_soc = "rk27x";
|
||||||
else if(target.dID == HWSTUB_TARGET_PP)
|
else if(target.dID == HWSTUB_TARGET_PP)
|
||||||
|
@ -549,95 +887,6 @@ bool HWStubIoBackend::Reload()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* HWStubBackendHelper
|
|
||||||
*/
|
|
||||||
HWStubBackendHelper::HWStubBackendHelper()
|
|
||||||
{
|
|
||||||
#ifdef LIBUSB_NO_HOTPLUG
|
|
||||||
m_hotplug = false;
|
|
||||||
#else
|
|
||||||
m_hotplug = libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG);
|
|
||||||
if(m_hotplug)
|
|
||||||
{
|
|
||||||
int evt = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
|
|
||||||
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT;
|
|
||||||
m_hotplug = LIBUSB_SUCCESS == libusb_hotplug_register_callback(
|
|
||||||
NULL, (libusb_hotplug_event)evt, LIBUSB_HOTPLUG_ENUMERATE,
|
|
||||||
LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY,
|
|
||||||
&HWStubBackendHelper::HotPlugCallback, reinterpret_cast< void* >(this),
|
|
||||||
&m_hotplug_handle);
|
|
||||||
}
|
|
||||||
#endif /* LIBUSB_NO_HOTPLUG */
|
|
||||||
}
|
|
||||||
|
|
||||||
HWStubBackendHelper::~HWStubBackendHelper()
|
|
||||||
{
|
|
||||||
#ifndef LIBUSB_NO_HOTPLUG
|
|
||||||
if(m_hotplug)
|
|
||||||
libusb_hotplug_deregister_callback(NULL, m_hotplug_handle);
|
|
||||||
#endif /* LIBUSB_NO_HOTPLUG */
|
|
||||||
}
|
|
||||||
|
|
||||||
QList< HWStubDevice* > HWStubBackendHelper::GetDevList()
|
|
||||||
{
|
|
||||||
QList< HWStubDevice* > list;
|
|
||||||
libusb_device **dev_list;
|
|
||||||
ssize_t cnt = hwstub_get_device_list(NULL, &dev_list);
|
|
||||||
for(int i = 0; i < cnt; i++)
|
|
||||||
{
|
|
||||||
HWStubDevice *dev = new HWStubDevice(dev_list[i]);
|
|
||||||
/* filter out non-hwstub devices */
|
|
||||||
if(dev->IsValid())
|
|
||||||
list.push_back(dev);
|
|
||||||
else
|
|
||||||
delete dev;
|
|
||||||
}
|
|
||||||
libusb_free_device_list(dev_list, 1);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef LIBUSB_NO_HOTPLUG
|
|
||||||
void HWStubBackendHelper::OnHotPlug(bool arrived, struct libusb_device *dev)
|
|
||||||
{
|
|
||||||
/* signal it */
|
|
||||||
emit OnDevListChanged(arrived, dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
int HWStubBackendHelper::HotPlugCallback(struct libusb_context *ctx, struct libusb_device *dev,
|
|
||||||
libusb_hotplug_event event, void *user_data)
|
|
||||||
{
|
|
||||||
Q_UNUSED(ctx);
|
|
||||||
HWStubBackendHelper *helper = reinterpret_cast< HWStubBackendHelper* >(user_data);
|
|
||||||
switch(event)
|
|
||||||
{
|
|
||||||
case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: helper->OnHotPlug(true, dev); break;
|
|
||||||
case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: helper->OnHotPlug(false, dev); break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* LIBUSB_NO_HOTPLUG */
|
|
||||||
|
|
||||||
bool HWStubBackendHelper::HasHotPlugSupport()
|
|
||||||
{
|
|
||||||
return m_hotplug;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
class lib_usb_init
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
lib_usb_init()
|
|
||||||
{
|
|
||||||
libusb_init(NULL);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
lib_usb_init __lib_usb_init;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HAVE_HWSTUB */
|
#endif /* HAVE_HWSTUB */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,7 +28,9 @@
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
#ifdef HAVE_HWSTUB
|
#ifdef HAVE_HWSTUB
|
||||||
#include "hwstub.h"
|
#include "hwstub.hpp"
|
||||||
|
#include "hwstub_usb.hpp"
|
||||||
|
#include "hwstub_uri.hpp"
|
||||||
#endif
|
#endif
|
||||||
#include "soc_desc.hpp"
|
#include "soc_desc.hpp"
|
||||||
|
|
||||||
|
@ -139,41 +141,124 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_HWSTUB
|
#ifdef HAVE_HWSTUB
|
||||||
|
/* HWStub context manager: provides a centralized place to add/remove/get
|
||||||
|
* contexts */
|
||||||
|
class HWStubManager : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
protected:
|
||||||
|
HWStubManager();
|
||||||
|
public:
|
||||||
|
virtual ~HWStubManager();
|
||||||
|
/* Get manager */
|
||||||
|
static HWStubManager *Get();
|
||||||
|
/* Clear the context list */
|
||||||
|
void Clear();
|
||||||
|
bool Add(const QString& name, const QString& uri);
|
||||||
|
/* Model */
|
||||||
|
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
|
||||||
|
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const;
|
||||||
|
virtual QVariant data(const QModelIndex& index, int role) const;
|
||||||
|
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||||
|
virtual Qt::ItemFlags flags(const QModelIndex& index) const;
|
||||||
|
virtual bool setData(const QModelIndex& index, const QVariant& value, int role);
|
||||||
|
/* return predefined columns */
|
||||||
|
int GetNameColumn() const;
|
||||||
|
int GetUriColumn() const;
|
||||||
|
std::shared_ptr< hwstub::context > GetContext(int row);
|
||||||
|
/* return a friendly name for a device */
|
||||||
|
static QString GetFriendlyName(std::shared_ptr< hwstub::device > device);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
struct Context
|
||||||
|
{
|
||||||
|
std::shared_ptr< hwstub::context > context;
|
||||||
|
QString name;
|
||||||
|
QString uri;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector< Context > m_list; /* list of context */
|
||||||
|
static HWStubManager *g_inst; /* unique instance */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* HWStub context model: provides access to the device list using Qt MVC model. */
|
||||||
|
class HWStubContextModel : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
HWStubContextModel(QObject *parent = 0);
|
||||||
|
virtual ~HWStubContextModel();
|
||||||
|
void SetContext(std::shared_ptr< hwstub::context > context);
|
||||||
|
/* Model */
|
||||||
|
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
|
||||||
|
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const;
|
||||||
|
virtual QVariant data(const QModelIndex& index, int role) const;
|
||||||
|
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||||
|
virtual Qt::ItemFlags flags(const QModelIndex& index) const;
|
||||||
|
/* return predefined columns */
|
||||||
|
int GetNameColumn() const;
|
||||||
|
std::shared_ptr< hwstub::device > GetDevice(int row);
|
||||||
|
/* Add an entry in the model for "no selection", which will correspond to
|
||||||
|
* a dummy device. This function also allows the text to be customised. */
|
||||||
|
void EnableDummy(bool en, const QString& text = "");
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void OnDevChangeUnsafe(void *data);
|
||||||
|
protected:
|
||||||
|
QString GetFriendlyName(std::shared_ptr< hwstub::device > device);
|
||||||
|
void OnDevChangeLow(std::shared_ptr< hwstub::context > ctx, bool arrived,
|
||||||
|
std::shared_ptr< hwstub::device > device);
|
||||||
|
void OnDevChange(std::shared_ptr< hwstub::context > ctx, bool arrived,
|
||||||
|
std::shared_ptr< hwstub::device > device);
|
||||||
|
|
||||||
|
struct Device
|
||||||
|
{
|
||||||
|
QString name;
|
||||||
|
std::shared_ptr< hwstub::device > device;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector< Device > m_list;
|
||||||
|
std::weak_ptr< hwstub::context > m_context;
|
||||||
|
hwstub::context::callback_ref_t m_callback_ref;
|
||||||
|
bool m_has_dummy;
|
||||||
|
QString m_dummy_text;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Abstract Virtual Class from where TCP and USB backend
|
||||||
|
* child classes are derived
|
||||||
|
*/
|
||||||
class HWStubDevice
|
class HWStubDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HWStubDevice(struct libusb_device *dev);
|
HWStubDevice(std::shared_ptr<hwstub::device> device);
|
||||||
HWStubDevice(const HWStubDevice *dev);
|
virtual ~HWStubDevice();
|
||||||
~HWStubDevice();
|
|
||||||
|
QString GetFriendlyName();
|
||||||
bool IsValid();
|
bool IsValid();
|
||||||
bool Open();
|
/* Calls below are cached */
|
||||||
void Close();
|
|
||||||
int GetBusNumber();
|
|
||||||
int GetDevAddress();
|
|
||||||
/* Calls below are cached and do not require the device to be opened */
|
|
||||||
inline struct hwstub_version_desc_t GetVersionInfo() { return m_hwdev_ver; }
|
inline struct hwstub_version_desc_t GetVersionInfo() { return m_hwdev_ver; }
|
||||||
inline struct hwstub_target_desc_t GetTargetInfo() { return m_hwdev_target; }
|
inline struct hwstub_target_desc_t GetTargetInfo() { return m_hwdev_target; }
|
||||||
inline struct hwstub_stmp_desc_t GetSTMPInfo() { return m_hwdev_stmp; }
|
inline struct hwstub_stmp_desc_t GetSTMPInfo() { return m_hwdev_stmp; }
|
||||||
inline struct hwstub_pp_desc_t GetPPInfo() { return m_hwdev_pp; }
|
inline struct hwstub_pp_desc_t GetPPInfo() { return m_hwdev_pp; }
|
||||||
/* Calls below require the device to be opened */
|
inline struct hwstub_jz_desc_t GetJZInfo() { return m_hwdev_jz; }
|
||||||
bool ReadMem(soc_addr_t addr, size_t length, void *buffer);
|
bool ReadMem(soc_addr_t addr, size_t length, void *buffer);
|
||||||
bool WriteMem(soc_addr_t addr, size_t length, void *buffer);
|
bool WriteMem(soc_addr_t addr, size_t length, void *buffer);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool Probe();
|
bool Probe(std::shared_ptr<hwstub::device> device);
|
||||||
void Init(struct libusb_device *dev);
|
|
||||||
|
|
||||||
|
std::shared_ptr<hwstub::handle> m_handle;
|
||||||
bool m_valid;
|
bool m_valid;
|
||||||
struct libusb_device *m_dev;
|
|
||||||
libusb_device_handle *m_handle;
|
|
||||||
struct hwstub_device_t *m_hwdev;
|
struct hwstub_device_t *m_hwdev;
|
||||||
struct hwstub_version_desc_t m_hwdev_ver;
|
struct hwstub_version_desc_t m_hwdev_ver;
|
||||||
struct hwstub_target_desc_t m_hwdev_target;
|
struct hwstub_target_desc_t m_hwdev_target;
|
||||||
struct hwstub_stmp_desc_t m_hwdev_stmp;
|
struct hwstub_stmp_desc_t m_hwdev_stmp;
|
||||||
struct hwstub_pp_desc_t m_hwdev_pp;
|
struct hwstub_pp_desc_t m_hwdev_pp;
|
||||||
|
struct hwstub_jz_desc_t m_hwdev_jz;
|
||||||
|
QString m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** NOTE the HWStub backend is never dirty: all writes are immediately committed */
|
/** NOTE the HWStub backend is never dirty: all wrnew ites are immediately committed */
|
||||||
class HWStubIoBackend : public IoBackend
|
class HWStubIoBackend : public IoBackend
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -197,32 +282,6 @@ protected:
|
||||||
QString m_soc;
|
QString m_soc;
|
||||||
HWStubDevice *m_dev;
|
HWStubDevice *m_dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if LIBUSB_API_VERSION < 0x01000102
|
|
||||||
#define LIBUSB_NO_HOTPLUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class HWStubBackendHelper : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
HWStubBackendHelper();
|
|
||||||
~HWStubBackendHelper();
|
|
||||||
bool HasHotPlugSupport();
|
|
||||||
QList< HWStubDevice* > GetDevList();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void OnDevListChanged(bool arrived, struct libusb_device *dev);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
#ifndef LIBUSB_NO_HOTPLUG
|
|
||||||
void OnHotPlug(bool arrived, struct libusb_device *dev);
|
|
||||||
static int HotPlugCallback(struct libusb_context *ctx, struct libusb_device *dev,
|
|
||||||
libusb_hotplug_event event, void *user_data);
|
|
||||||
libusb_hotplug_callback_handle m_hotplug_handle;
|
|
||||||
#endif
|
|
||||||
bool m_hotplug;
|
|
||||||
};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class SocFile
|
class SocFile
|
||||||
|
|
|
@ -107,12 +107,18 @@ void DocumentTabWidget::OnCloseTab(int index)
|
||||||
MainWindow::MainWindow(Backend *backend)
|
MainWindow::MainWindow(Backend *backend)
|
||||||
:m_backend(backend)
|
:m_backend(backend)
|
||||||
{
|
{
|
||||||
QAction *new_regtab_act = new QAction(QIcon::fromTheme("document-new"), tr("Register &Tab"), this);
|
QAction *new_regtab_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::DocumentNew),
|
||||||
QAction *new_regedit_act = new QAction(QIcon::fromTheme("document-edit"), tr("Register &Editor"), this);
|
tr("Register &Tab"), this);
|
||||||
QAction *load_desc_act = new QAction(QIcon::fromTheme("document-open"), tr("&Soc Description"), this);
|
QAction *new_regedit_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::DocumentEdit),
|
||||||
QAction *quit_act = new QAction(QIcon::fromTheme("application-exit"), tr("&Quit"), this);
|
tr("Register &Editor"), this);
|
||||||
QAction *about_act = new QAction(QIcon::fromTheme("help-about"), tr("&About"), this);
|
QAction *load_desc_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::DocumentOpen),
|
||||||
QAction *about_qt_act = new QAction(QIcon::fromTheme("help-about"), tr("About &Qt"), this);
|
tr("&Soc Description"), this);
|
||||||
|
QAction *quit_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::ApplicationExit),
|
||||||
|
tr("&Quit"), this);
|
||||||
|
QAction *about_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::HelpAbout),
|
||||||
|
tr("&About"), this);
|
||||||
|
QAction *about_qt_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::HelpAbout),
|
||||||
|
tr("About &Qt"), this);
|
||||||
|
|
||||||
connect(new_regtab_act, SIGNAL(triggered()), this, SLOT(OnNewRegTab()));
|
connect(new_regtab_act, SIGNAL(triggered()), this, SLOT(OnNewRegTab()));
|
||||||
connect(new_regedit_act, SIGNAL(triggered()), this, SLOT(OnNewRegEdit()));
|
connect(new_regedit_act, SIGNAL(triggered()), this, SLOT(OnNewRegEdit()));
|
||||||
|
@ -121,9 +127,10 @@ MainWindow::MainWindow(Backend *backend)
|
||||||
connect(about_act, SIGNAL(triggered()), this, SLOT(OnAbout()));
|
connect(about_act, SIGNAL(triggered()), this, SLOT(OnAbout()));
|
||||||
connect(about_qt_act, SIGNAL(triggered()), this, SLOT(OnAboutQt()));
|
connect(about_qt_act, SIGNAL(triggered()), this, SLOT(OnAboutQt()));
|
||||||
|
|
||||||
QMenu *file_menu = menuBar()->addMenu(tr("&File"));
|
QMenu *app_menu = new QMenu;
|
||||||
QMenu *new_submenu = file_menu->addMenu(QIcon::fromTheme("document-new"), "&New");
|
QMenu *file_menu = app_menu->addMenu(tr("&File"));
|
||||||
QMenu *load_submenu = file_menu->addMenu(QIcon::fromTheme("document-open"), "&Load");
|
QMenu *new_submenu = file_menu->addMenu(YIconManager::Get()->GetIcon(YIconManager::DocumentNew), "&New");
|
||||||
|
QMenu *load_submenu = file_menu->addMenu(YIconManager::Get()->GetIcon(YIconManager::DocumentOpen), "&Load");
|
||||||
file_menu->addAction(quit_act);
|
file_menu->addAction(quit_act);
|
||||||
|
|
||||||
new_submenu->addAction(new_regtab_act);
|
new_submenu->addAction(new_regtab_act);
|
||||||
|
@ -131,17 +138,24 @@ MainWindow::MainWindow(Backend *backend)
|
||||||
|
|
||||||
load_submenu->addAction(load_desc_act);
|
load_submenu->addAction(load_desc_act);
|
||||||
|
|
||||||
QMenu *about_menu = menuBar()->addMenu(tr("&About"));
|
QMenu *about_menu = app_menu->addMenu(tr("&About"));
|
||||||
about_menu->addAction(about_act);
|
about_menu->addAction(about_act);
|
||||||
about_menu->addAction(about_qt_act);
|
about_menu->addAction(about_qt_act);
|
||||||
|
|
||||||
m_tab = new DocumentTabWidget();
|
m_tab = new DocumentTabWidget();
|
||||||
m_tab->setTabOpenable(true);
|
m_tab->setTabOpenable(true);
|
||||||
m_tab->setTabOpenMenu(new_submenu);
|
m_tab->setTabOpenMenu(new_submenu);
|
||||||
|
m_tab->setOtherMenu(app_menu);
|
||||||
|
|
||||||
setCentralWidget(m_tab);
|
setCentralWidget(m_tab);
|
||||||
|
|
||||||
ReadSettings();
|
ReadSettings();
|
||||||
|
#ifdef HAVE_HWSTUB
|
||||||
|
/* acquire hwstub manager */
|
||||||
|
HWStubManager::Get()->setParent(this);
|
||||||
|
#endif
|
||||||
|
/* acquire icon manager */
|
||||||
|
YIconManager::Get()->setParent(this);
|
||||||
|
|
||||||
OnNewRegTab();
|
OnNewRegTab();
|
||||||
}
|
}
|
||||||
|
@ -167,12 +181,12 @@ void MainWindow::OnAbout()
|
||||||
.arg(soc_desc::MINOR_VERSION).arg(soc_desc::REVISION_VERSION);
|
.arg(soc_desc::MINOR_VERSION).arg(soc_desc::REVISION_VERSION);
|
||||||
QMessageBox::about(this, "About",
|
QMessageBox::about(this, "About",
|
||||||
"<h1>QEditor</h1>"
|
"<h1>QEditor</h1>"
|
||||||
"<h2>Version "APP_VERSION"</h2>"
|
"<h2>Version " APP_VERSION "</h2>"
|
||||||
"<p>Written by Amaury Pouly</p>"
|
"<p>Written by Amaury Pouly</p>"
|
||||||
"<p>Libraries:</p>"
|
"<p>Libraries:</p>"
|
||||||
"<ul><li>soc_desc: " + soc_desc_ver + "</li>"
|
"<ul><li>soc_desc: " + soc_desc_ver + "</li>"
|
||||||
#ifdef HAVE_HWSTUB
|
#ifdef HAVE_HWSTUB
|
||||||
"<li>hwstub: "HWSTUB_VERSION"</li>"
|
"<li>hwstub: " HWSTUB_VERSION "</li>"
|
||||||
#else
|
#else
|
||||||
"<li>hwstub: not compiled in</li>"
|
"<li>hwstub: not compiled in</li>"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,8 +5,9 @@ HEADERS += mainwindow.h backend.h regtab.h analyser.h settings.h \
|
||||||
SOURCES += main.cpp mainwindow.cpp regtab.cpp backend.cpp analyser.cpp \
|
SOURCES += main.cpp mainwindow.cpp regtab.cpp backend.cpp analyser.cpp \
|
||||||
std_analysers.cpp settings.cpp utils.cpp regdisplaypanel.cpp regedit.cpp
|
std_analysers.cpp settings.cpp utils.cpp regdisplaypanel.cpp regedit.cpp
|
||||||
LIBS += -L../lib/ -lsocdesc -lxml2
|
LIBS += -L../lib/ -lsocdesc -lxml2
|
||||||
INCLUDEPATH += ../include/ ../../hwstub/lib
|
INCLUDEPATH += ../include/ ../../hwstub/include
|
||||||
DEPENDPATH += ../
|
DEPENDPATH += ../
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
libsocdesc.commands = cd ../lib && make
|
libsocdesc.commands = cd ../lib && make
|
||||||
QMAKE_EXTRA_TARGETS += libsocdesc
|
QMAKE_EXTRA_TARGETS += libsocdesc
|
||||||
|
|
|
@ -46,7 +46,7 @@ SocDisplayPanel::SocDisplayPanel(QWidget *parent, IoBackend *io_backend,
|
||||||
right_layout->addWidget(m_desc, 0);
|
right_layout->addWidget(m_desc, 0);
|
||||||
right_layout->addStretch(1);
|
right_layout->addStretch(1);
|
||||||
|
|
||||||
setTitle("System-on-Chip Description");
|
setTitle("");
|
||||||
setLayout(right_layout);
|
setLayout(right_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ NodeDisplayPanel::NodeDisplayPanel(QWidget *parent, IoBackend *io_backend,
|
||||||
right_layout->addWidget(m_inst_desc, 0);
|
right_layout->addWidget(m_inst_desc, 0);
|
||||||
right_layout->addStretch(1);
|
right_layout->addStretch(1);
|
||||||
|
|
||||||
setTitle("Device Description");
|
setTitle("");
|
||||||
setLayout(right_layout);
|
setLayout(right_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +126,21 @@ QWidget *NodeDisplayPanel::GetWidget()
|
||||||
* RegDisplayPanel
|
* RegDisplayPanel
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
QString access_string(soc_desc::access_t acc, QString dflt = "")
|
||||||
|
{
|
||||||
|
switch(acc)
|
||||||
|
{
|
||||||
|
case soc_desc::UNSPECIFIED: return dflt;
|
||||||
|
case soc_desc::READ_ONLY: return "Read only";
|
||||||
|
case soc_desc::READ_WRITE: return "Read-write";
|
||||||
|
case soc_desc::WRITE_ONLY: return "Write-only";
|
||||||
|
default: return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend,
|
RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend,
|
||||||
const soc_desc::node_inst_t& ref)
|
const soc_desc::node_inst_t& ref)
|
||||||
:QGroupBox(parent), m_io_backend(io_backend), m_node(ref), m_reg_font(font())
|
:QGroupBox(parent), m_io_backend(io_backend), m_node(ref), m_reg_font(font())
|
||||||
|
@ -139,16 +154,18 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend,
|
||||||
m_reg_font.setKerning(false);
|
m_reg_font.setKerning(false);
|
||||||
|
|
||||||
QString reg_name = helper.GetPath(ref);
|
QString reg_name = helper.GetPath(ref);
|
||||||
QStringList names;
|
QStringList names, access;
|
||||||
QVector< soc_addr_t > addresses;
|
QVector< soc_addr_t > addresses;
|
||||||
names.append(reg_name);
|
names.append(reg_name);
|
||||||
addresses.append(ref.addr());
|
addresses.append(ref.addr());
|
||||||
|
access.append(access_string(ref.node().reg().get()->access));
|
||||||
|
|
||||||
std::vector< soc_desc::variant_ref_t > variants = ref.node().reg().variants();
|
std::vector< soc_desc::variant_ref_t > variants = ref.node().reg().variants();
|
||||||
for(size_t i = 0; i < variants.size(); i++)
|
for(size_t i = 0; i < variants.size(); i++)
|
||||||
{
|
{
|
||||||
names.append(reg_name + "/" + QString::fromStdString(variants[i].get()->type));
|
names.append(reg_name + "/" + QString::fromStdString(variants[i].get()->type));
|
||||||
addresses.append(ref.addr() + variants[i].get()->offset);
|
addresses.append(ref.addr() + variants[i].get()->offset);
|
||||||
|
access.append(access_string(ref.node().reg().get()->access, access[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString str;
|
QString str;
|
||||||
|
@ -169,10 +186,20 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend,
|
||||||
label_addr->setTextFormat(Qt::RichText);
|
label_addr->setTextFormat(Qt::RichText);
|
||||||
label_addr->setText(str_addr);
|
label_addr->setText(str_addr);
|
||||||
|
|
||||||
|
QString str_acc;
|
||||||
|
str_acc += "<table align=left>";
|
||||||
|
for(int i = 0; i < names.size(); i++)
|
||||||
|
str_acc += "<tr><td><b>" + access[i] + "</b></td></tr>";
|
||||||
|
str_acc += "</table>";
|
||||||
|
QLabel *label_access = new QLabel;
|
||||||
|
label_access->setTextFormat(Qt::RichText);
|
||||||
|
label_access->setText(str_acc);
|
||||||
|
|
||||||
QHBoxLayout *top_layout = new QHBoxLayout;
|
QHBoxLayout *top_layout = new QHBoxLayout;
|
||||||
top_layout->addStretch();
|
top_layout->addStretch();
|
||||||
top_layout->addWidget(label_names);
|
top_layout->addWidget(label_names);
|
||||||
top_layout->addWidget(label_addr);
|
top_layout->addWidget(label_addr);
|
||||||
|
top_layout->addWidget(label_access);
|
||||||
top_layout->addStretch();
|
top_layout->addStretch();
|
||||||
|
|
||||||
m_raw_val_name = new QLabel;
|
m_raw_val_name = new QLabel;
|
||||||
|
@ -250,7 +277,7 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend,
|
||||||
right_layout->addWidget(m_value_table);
|
right_layout->addWidget(m_value_table);
|
||||||
right_layout->addStretch();
|
right_layout->addStretch();
|
||||||
|
|
||||||
setTitle("Register Description");
|
setTitle("");
|
||||||
m_viewport = new QWidget;
|
m_viewport = new QWidget;
|
||||||
m_viewport->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
m_viewport->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
m_viewport->setLayout(right_layout);
|
m_viewport->setLayout(right_layout);
|
||||||
|
|
|
@ -107,14 +107,15 @@ SocEditPanel::SocEditPanel(const soc_desc::soc_ref_t& ref, QWidget *parent)
|
||||||
for(size_t i = 0; i < authors.size(); i++)
|
for(size_t i = 0; i < authors.size(); i++)
|
||||||
{
|
{
|
||||||
QTableWidgetItem *item = new QTableWidgetItem(
|
QTableWidgetItem *item = new QTableWidgetItem(
|
||||||
QIcon::fromTheme("list-remove"), "", SocEditPanelDelType);
|
YIconManager::Get()->GetIcon(YIconManager::ListRemove), "", SocEditPanelDelType);
|
||||||
|
item->setToolTip("Remove this author");
|
||||||
item->setFlags(Qt::ItemIsEnabled);
|
item->setFlags(Qt::ItemIsEnabled);
|
||||||
m_authors_list->setItem(i, 0, item);
|
m_authors_list->setItem(i, 0, item);
|
||||||
item = new QTableWidgetItem(QString::fromStdString(authors[i]));
|
item = new QTableWidgetItem(QString::fromStdString(authors[i]));
|
||||||
m_authors_list->setItem(i, 1, item);
|
m_authors_list->setItem(i, 1, item);
|
||||||
}
|
}
|
||||||
QTableWidgetItem *new_item = new QTableWidgetItem(
|
QTableWidgetItem *new_item = new QTableWidgetItem(
|
||||||
QIcon::fromTheme("list-add"), "", SocEditPanelAddType);
|
YIconManager::Get()->GetIcon(YIconManager::ListAdd), "", SocEditPanelAddType);
|
||||||
new_item->setFlags(Qt::ItemIsEnabled);
|
new_item->setFlags(Qt::ItemIsEnabled);
|
||||||
m_authors_list->setItem(authors.size(), 0, new_item);
|
m_authors_list->setItem(authors.size(), 0, new_item);
|
||||||
new_item = new QTableWidgetItem("New author...", QTableWidgetItem::UserType);
|
new_item = new QTableWidgetItem("New author...", QTableWidgetItem::UserType);
|
||||||
|
@ -188,7 +189,8 @@ void SocEditPanel::OnAuthorActivated(QTableWidgetItem *item)
|
||||||
m_ref.get()->author.push_back("Anonymous");
|
m_ref.get()->author.push_back("Anonymous");
|
||||||
m_authors_list->insertRow(row);
|
m_authors_list->insertRow(row);
|
||||||
QTableWidgetItem *item = new QTableWidgetItem(
|
QTableWidgetItem *item = new QTableWidgetItem(
|
||||||
QIcon::fromTheme("list-remove"), "", SocEditPanelDelType);
|
YIconManager::Get()->GetIcon(YIconManager::ListRemove), "", SocEditPanelDelType);
|
||||||
|
item->setToolTip("Remove this author");
|
||||||
item->setFlags(Qt::ItemIsEnabled);
|
item->setFlags(Qt::ItemIsEnabled);
|
||||||
m_authors_list->setItem(row, 0, item);
|
m_authors_list->setItem(row, 0, item);
|
||||||
item = new QTableWidgetItem(QString::fromStdString(m_ref.get()->author.back()));
|
item = new QTableWidgetItem(QString::fromStdString(m_ref.get()->author.back()));
|
||||||
|
@ -386,7 +388,8 @@ NodeInstanceEditPanel::NodeInstanceEditPanel(const soc_desc::node_ref_t& ref,
|
||||||
for(size_t i = 0; i < addrs.size(); i++)
|
for(size_t i = 0; i < addrs.size(); i++)
|
||||||
{
|
{
|
||||||
QTableWidgetItem *item = new QTableWidgetItem(
|
QTableWidgetItem *item = new QTableWidgetItem(
|
||||||
QIcon::fromTheme("list-remove"), "", NodeInstEditPanelDelType);
|
YIconManager::Get()->GetIcon(YIconManager::ListRemove), "", NodeInstEditPanelDelType);
|
||||||
|
item->setToolTip("Remove this address");
|
||||||
item->setFlags(Qt::ItemIsEnabled);
|
item->setFlags(Qt::ItemIsEnabled);
|
||||||
addr_list->setItem(i, 0, item);
|
addr_list->setItem(i, 0, item);
|
||||||
item = new QTableWidgetItem();
|
item = new QTableWidgetItem();
|
||||||
|
@ -394,7 +397,7 @@ NodeInstanceEditPanel::NodeInstanceEditPanel(const soc_desc::node_ref_t& ref,
|
||||||
addr_list->setItem(i, 1, item);
|
addr_list->setItem(i, 1, item);
|
||||||
}
|
}
|
||||||
QTableWidgetItem *new_item = new QTableWidgetItem(
|
QTableWidgetItem *new_item = new QTableWidgetItem(
|
||||||
QIcon::fromTheme("list-add"), "", NodeInstEditPanelAddType);
|
YIconManager::Get()->GetIcon(YIconManager::ListAdd), "", NodeInstEditPanelAddType);
|
||||||
new_item->setFlags(Qt::ItemIsEnabled);
|
new_item->setFlags(Qt::ItemIsEnabled);
|
||||||
addr_list->setItem(addrs.size(), 0, new_item);
|
addr_list->setItem(addrs.size(), 0, new_item);
|
||||||
new_item = new QTableWidgetItem("New address...", QTableWidgetItem::UserType);
|
new_item = new QTableWidgetItem("New address...", QTableWidgetItem::UserType);
|
||||||
|
@ -535,7 +538,8 @@ void NodeInstanceEditPanel::OnAddressActivated(QTableWidgetItem *item)
|
||||||
GetInstance().range.list.push_back(new_addr);
|
GetInstance().range.list.push_back(new_addr);
|
||||||
table->insertRow(row);
|
table->insertRow(row);
|
||||||
QTableWidgetItem *item = new QTableWidgetItem(
|
QTableWidgetItem *item = new QTableWidgetItem(
|
||||||
QIcon::fromTheme("list-remove"), "", NodeInstEditPanelDelType);
|
YIconManager::Get()->GetIcon(YIconManager::ListRemove), "", NodeInstEditPanelDelType);
|
||||||
|
item->setToolTip("Remove this address");
|
||||||
item->setFlags(Qt::ItemIsEnabled);
|
item->setFlags(Qt::ItemIsEnabled);
|
||||||
table->setItem(row, 0, item);
|
table->setItem(row, 0, item);
|
||||||
item = new QTableWidgetItem();
|
item = new QTableWidgetItem();
|
||||||
|
@ -828,7 +832,8 @@ RegFieldEditPanel::RegFieldEditPanel(const soc_desc::field_ref_t& ref, QWidget *
|
||||||
for(size_t i = 0; i < field.enum_.size(); i++)
|
for(size_t i = 0; i < field.enum_.size(); i++)
|
||||||
{
|
{
|
||||||
QTableWidgetItem *item = new QTableWidgetItem(
|
QTableWidgetItem *item = new QTableWidgetItem(
|
||||||
QIcon::fromTheme("list-remove"), "", RegFieldEditPanelDelType);
|
YIconManager::Get()->GetIcon(YIconManager::ListRemove), "", RegFieldEditPanelDelType);
|
||||||
|
item->setToolTip("Remove this enum");
|
||||||
item->setFlags(Qt::ItemIsEnabled);
|
item->setFlags(Qt::ItemIsEnabled);
|
||||||
m_enum_table->setItem(i, 0, item);
|
m_enum_table->setItem(i, 0, item);
|
||||||
item = new QTableWidgetItem(QString::fromStdString(field.enum_[i].name));
|
item = new QTableWidgetItem(QString::fromStdString(field.enum_[i].name));
|
||||||
|
@ -840,7 +845,7 @@ RegFieldEditPanel::RegFieldEditPanel(const soc_desc::field_ref_t& ref, QWidget *
|
||||||
m_enum_table->setItem(i, 3, item);
|
m_enum_table->setItem(i, 3, item);
|
||||||
}
|
}
|
||||||
QTableWidgetItem *new_item = new QTableWidgetItem(
|
QTableWidgetItem *new_item = new QTableWidgetItem(
|
||||||
QIcon::fromTheme("list-add"), "", RegFieldEditPanelAddType);
|
YIconManager::Get()->GetIcon(YIconManager::ListAdd), "", RegFieldEditPanelAddType);
|
||||||
new_item->setFlags(Qt::ItemIsEnabled);
|
new_item->setFlags(Qt::ItemIsEnabled);
|
||||||
m_enum_table->setItem(field.enum_.size(), 0, new_item);
|
m_enum_table->setItem(field.enum_.size(), 0, new_item);
|
||||||
new_item = new QTableWidgetItem("New field...");
|
new_item = new QTableWidgetItem("New field...");
|
||||||
|
@ -875,6 +880,13 @@ void RegFieldEditPanel::UpdateWidth()
|
||||||
m_range_validator->setWidth(m_ref.reg().get()->width);
|
m_range_validator->setWidth(m_ref.reg().get()->width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegFieldEditPanel::UpdateRange()
|
||||||
|
{
|
||||||
|
soc_desc::field_t *field = m_ref.get();
|
||||||
|
m_range_edit->setText(m_range_validator->generate(
|
||||||
|
field->pos + field->width - 1, field->pos));
|
||||||
|
}
|
||||||
|
|
||||||
void RegFieldEditPanel::OnFieldValueActivated(QTableWidgetItem *item)
|
void RegFieldEditPanel::OnFieldValueActivated(QTableWidgetItem *item)
|
||||||
{
|
{
|
||||||
if(item->type() == RegFieldEditPanelDelType)
|
if(item->type() == RegFieldEditPanelDelType)
|
||||||
|
@ -895,7 +907,8 @@ void RegFieldEditPanel::OnFieldValueActivated(QTableWidgetItem *item)
|
||||||
field.enum_.push_back(new_enum);
|
field.enum_.push_back(new_enum);
|
||||||
m_enum_table->insertRow(row);
|
m_enum_table->insertRow(row);
|
||||||
QTableWidgetItem *item = new QTableWidgetItem(
|
QTableWidgetItem *item = new QTableWidgetItem(
|
||||||
QIcon::fromTheme("list-remove"), "", RegFieldEditPanelDelType);
|
YIconManager::Get()->GetIcon(YIconManager::ListRemove), "", RegFieldEditPanelDelType);
|
||||||
|
item->setToolTip("Remove this enum");
|
||||||
item->setFlags(Qt::ItemIsEnabled);
|
item->setFlags(Qt::ItemIsEnabled);
|
||||||
m_enum_table->setItem(row, 0, item);
|
m_enum_table->setItem(row, 0, item);
|
||||||
item = new QTableWidgetItem(QString::fromStdString(new_enum.name));
|
item = new QTableWidgetItem(QString::fromStdString(new_enum.name));
|
||||||
|
@ -977,7 +990,7 @@ RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent)
|
||||||
|
|
||||||
m_value_model = new RegFieldTableModel(this); // view takes ownership
|
m_value_model = new RegFieldTableModel(this); // view takes ownership
|
||||||
m_value_model->SetRegister(*ref.get());
|
m_value_model->SetRegister(*ref.get());
|
||||||
m_value_model->SetReadOnly(true);
|
m_value_model->SetReadOnly(false);
|
||||||
|
|
||||||
m_sexy_display2 = new Unscroll<YRegDisplay>(this);
|
m_sexy_display2 = new Unscroll<YRegDisplay>(this);
|
||||||
m_sexy_display2->setFont(m_reg_font);
|
m_sexy_display2->setFont(m_reg_font);
|
||||||
|
@ -1016,29 +1029,61 @@ RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent)
|
||||||
width_group_layout->addWidget(reg_size_32);
|
width_group_layout->addWidget(reg_size_32);
|
||||||
width_group_layout->addWidget(reg_size_16);
|
width_group_layout->addWidget(reg_size_16);
|
||||||
width_group_layout->addWidget(reg_size_8);
|
width_group_layout->addWidget(reg_size_8);
|
||||||
width_group_layout->addStretch(0);
|
|
||||||
QGroupBox *width_group = new QGroupBox("Width");
|
QGroupBox *width_group = new QGroupBox("Width");
|
||||||
width_group->setLayout(width_group_layout);
|
width_group->setLayout(width_group_layout);
|
||||||
|
|
||||||
|
m_reg_access_group = new QButtonGroup(this);
|
||||||
|
QRadioButton *reg_dflt = new QRadioButton("Unspecified");
|
||||||
|
QRadioButton *reg_rw = new QRadioButton("Read-Write");
|
||||||
|
QRadioButton *reg_ro = new QRadioButton("Read-Only");
|
||||||
|
QRadioButton *reg_wo = new QRadioButton("Write-Only");
|
||||||
|
m_reg_access_group->addButton(reg_dflt, soc_desc::UNSPECIFIED);
|
||||||
|
m_reg_access_group->addButton(reg_rw, soc_desc::READ_WRITE);
|
||||||
|
m_reg_access_group->addButton(reg_ro, soc_desc::READ_ONLY);
|
||||||
|
m_reg_access_group->addButton(reg_wo, soc_desc::WRITE_ONLY);
|
||||||
|
if(m_reg_access_group->button(m_ref.get()->access))
|
||||||
|
m_reg_access_group->button(m_ref.get()->access)->click();
|
||||||
|
QVBoxLayout *access_group_layout = new QVBoxLayout;
|
||||||
|
access_group_layout->addWidget(reg_dflt);
|
||||||
|
access_group_layout->addWidget(reg_rw);
|
||||||
|
access_group_layout->addWidget(reg_ro);
|
||||||
|
access_group_layout->addWidget(reg_wo);
|
||||||
|
QGroupBox *access_group = new QGroupBox("Access");
|
||||||
|
access_group->setLayout(access_group_layout);
|
||||||
|
|
||||||
|
QVBoxLayout *width_access_layout = new QVBoxLayout;
|
||||||
|
width_access_layout->addWidget(width_group);
|
||||||
|
width_access_layout->addWidget(access_group);
|
||||||
|
width_access_layout->addStretch(0);
|
||||||
|
|
||||||
m_variant_table = new QTableWidget;
|
m_variant_table = new QTableWidget;
|
||||||
m_variant_table->setColumnCount(3);
|
m_variant_table->setColumnCount(4);
|
||||||
m_variant_table->setHorizontalHeaderItem(0, new QTableWidgetItem(""));
|
m_variant_table->setHorizontalHeaderItem(0, new QTableWidgetItem(""));
|
||||||
m_variant_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Type"));
|
m_variant_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Type"));
|
||||||
m_variant_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Offset"));
|
m_variant_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Offset"));
|
||||||
|
m_variant_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Access"));
|
||||||
m_variant_table->verticalHeader()->setVisible(false);
|
m_variant_table->verticalHeader()->setVisible(false);
|
||||||
m_variant_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
m_variant_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
m_variant_delegate = new SocFieldItemDelegate(this);
|
m_variant_delegate = new SocFieldItemDelegate(this);
|
||||||
m_variant_delegate->setItemEditorFactory(new QItemEditorFactory);
|
m_variant_delegate->setItemEditorFactory(new QItemEditorFactory);
|
||||||
m_variant_editor = new SocFieldEditorCreator;
|
m_variant_delegate->itemEditorFactory()->registerEditor(QVariant::UInt,
|
||||||
m_variant_delegate->itemEditorFactory()->registerEditor(QVariant::UInt, m_variant_editor);
|
new SocFieldEditorCreator);
|
||||||
m_variant_table->setItemDelegate(m_variant_delegate);
|
m_variant_table->setItemDelegate(m_variant_delegate);
|
||||||
|
m_access_delegate = new SocAccessItemDelegate("Unspecified", this);
|
||||||
|
m_access_delegate->setItemEditorFactory(new QItemEditorFactory);
|
||||||
|
// FIXME see QTBUG-30392
|
||||||
|
m_access_delegate->itemEditorFactory()->registerEditor(
|
||||||
|
(QVariant::Type)qMetaTypeId< soc_desc::access_t >(),
|
||||||
|
new SocAccessEditorCreator);
|
||||||
|
m_variant_table->setItemDelegateForColumn(3, m_access_delegate);
|
||||||
|
|
||||||
std::vector< soc_desc::variant_ref_t > variants = m_ref.variants();
|
std::vector< soc_desc::variant_ref_t > variants = m_ref.variants();
|
||||||
m_variant_table->setRowCount(variants.size() + 1);
|
m_variant_table->setRowCount(variants.size() + 1);
|
||||||
for(size_t i = 0; i < variants.size(); i++)
|
for(size_t i = 0; i < variants.size(); i++)
|
||||||
{
|
{
|
||||||
QTableWidgetItem *item = new QTableWidgetItem(
|
QTableWidgetItem *item = new QTableWidgetItem(
|
||||||
QIcon::fromTheme("list-remove"), "", RegVariantEditPanelDelType);
|
YIconManager::Get()->GetIcon(YIconManager::ListRemove), "", RegVariantEditPanelDelType);
|
||||||
|
item->setToolTip("Remove this variant");
|
||||||
item->setFlags(Qt::ItemIsEnabled);
|
item->setFlags(Qt::ItemIsEnabled);
|
||||||
m_variant_table->setItem(i, 0, item);
|
m_variant_table->setItem(i, 0, item);
|
||||||
item = new QTableWidgetItem(QString::fromStdString(variants[i].get()->type));
|
item = new QTableWidgetItem(QString::fromStdString(variants[i].get()->type));
|
||||||
|
@ -1046,9 +1091,12 @@ RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent)
|
||||||
item = new QTableWidgetItem();
|
item = new QTableWidgetItem();
|
||||||
item->setData(Qt::EditRole, QVariant(variants[i].get()->offset));
|
item->setData(Qt::EditRole, QVariant(variants[i].get()->offset));
|
||||||
m_variant_table->setItem(i, 2, item);
|
m_variant_table->setItem(i, 2, item);
|
||||||
|
item = new QTableWidgetItem();
|
||||||
|
item->setData(Qt::EditRole, QVariant::fromValue(variants[i].get()->access));
|
||||||
|
m_variant_table->setItem(i, 3, item);
|
||||||
}
|
}
|
||||||
QTableWidgetItem *new_item = new QTableWidgetItem(
|
QTableWidgetItem *new_item = new QTableWidgetItem(
|
||||||
QIcon::fromTheme("list-add"), "", RegVariantEditPanelAddType);
|
YIconManager::Get()->GetIcon(YIconManager::ListAdd), "", RegVariantEditPanelAddType);
|
||||||
new_item->setFlags(Qt::ItemIsEnabled);
|
new_item->setFlags(Qt::ItemIsEnabled);
|
||||||
m_variant_table->setItem(variants.size(), 0, new_item);
|
m_variant_table->setItem(variants.size(), 0, new_item);
|
||||||
new_item = new QTableWidgetItem("New variant...");
|
new_item = new QTableWidgetItem("New variant...");
|
||||||
|
@ -1069,7 +1117,7 @@ RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent)
|
||||||
m_desc_edit->SetTextHtml(QString::fromStdString(ref.get()->desc));
|
m_desc_edit->SetTextHtml(QString::fromStdString(ref.get()->desc));
|
||||||
|
|
||||||
QHBoxLayout *top_info_layout = new QHBoxLayout;
|
QHBoxLayout *top_info_layout = new QHBoxLayout;
|
||||||
top_info_layout->addWidget(width_group);
|
top_info_layout->addLayout(width_access_layout);
|
||||||
top_info_layout->addWidget(Misc::EncloseInBox("Variants", m_variant_table));
|
top_info_layout->addWidget(Misc::EncloseInBox("Variants", m_variant_table));
|
||||||
top_info_layout->addWidget(Misc::EncloseInBox("Description", m_desc_edit));
|
top_info_layout->addWidget(Misc::EncloseInBox("Description", m_desc_edit));
|
||||||
|
|
||||||
|
@ -1087,9 +1135,9 @@ RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent)
|
||||||
main_layout->addWidget(m_view_tab, 2);
|
main_layout->addWidget(m_view_tab, 2);
|
||||||
|
|
||||||
m_delete_action = new QAction("&Delete", this);
|
m_delete_action = new QAction("&Delete", this);
|
||||||
m_delete_action->setIcon(QIcon::fromTheme("list-remove"));
|
m_delete_action->setIcon(YIconManager::Get()->GetIcon(YIconManager::ListRemove));
|
||||||
m_new_action = new QAction("&New field", this);
|
m_new_action = new QAction("&New field", this);
|
||||||
m_new_action->setIcon(QIcon::fromTheme("list-add"));
|
m_new_action->setIcon(YIconManager::Get()->GetIcon(YIconManager::ListAdd));
|
||||||
|
|
||||||
setLayout(main_layout);
|
setLayout(main_layout);
|
||||||
|
|
||||||
|
@ -1101,6 +1149,7 @@ RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent)
|
||||||
connect(m_sexy_display2, SIGNAL(customContextMenuRequested(QPoint)), this,
|
connect(m_sexy_display2, SIGNAL(customContextMenuRequested(QPoint)), this,
|
||||||
SLOT(OnRegDisplayContextMenu(QPoint)));
|
SLOT(OnRegDisplayContextMenu(QPoint)));
|
||||||
connect(m_reg_size_group, SIGNAL(buttonClicked(int)), this, SLOT(OnWidthChanged(int)));
|
connect(m_reg_size_group, SIGNAL(buttonClicked(int)), this, SLOT(OnWidthChanged(int)));
|
||||||
|
connect(m_reg_access_group, SIGNAL(buttonClicked(int)), this, SLOT(OnAccessChanged(int)));
|
||||||
connect(m_delete_action, SIGNAL(triggered()), this, SLOT(OnRegFieldDelete()));
|
connect(m_delete_action, SIGNAL(triggered()), this, SLOT(OnRegFieldDelete()));
|
||||||
connect(m_new_action, SIGNAL(triggered()), this, SLOT(OnRegFieldNew()));
|
connect(m_new_action, SIGNAL(triggered()), this, SLOT(OnRegFieldNew()));
|
||||||
connect(m_variant_table, SIGNAL(itemActivated(QTableWidgetItem *)), this,
|
connect(m_variant_table, SIGNAL(itemActivated(QTableWidgetItem *)), this,
|
||||||
|
@ -1110,6 +1159,7 @@ RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent)
|
||||||
connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited()));
|
connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited()));
|
||||||
connect(m_fields_tab, SIGNAL(tabCloseRequested(int)), this, SLOT(OnFieldRemove(int)));
|
connect(m_fields_tab, SIGNAL(tabCloseRequested(int)), this, SLOT(OnFieldRemove(int)));
|
||||||
connect(m_fields_tab, SIGNAL(tabOpenRequested()), this, SLOT(OnFieldCreate()));
|
connect(m_fields_tab, SIGNAL(tabOpenRequested()), this, SLOT(OnFieldCreate()));
|
||||||
|
connect(m_value_model, SIGNAL(OnBitrangeModified(int)), this, SLOT(OnBitrangeModified(int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegEditPanel::UpdateWidthRestrictions()
|
void RegEditPanel::UpdateWidthRestrictions()
|
||||||
|
@ -1148,6 +1198,22 @@ void RegEditPanel::OnWidthChanged(int w)
|
||||||
OnModified();
|
OnModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegEditPanel::OnBitrangeModified(int index)
|
||||||
|
{
|
||||||
|
soc_desc::register_t reg = m_value_model->GetRegister();
|
||||||
|
m_ref.get()->field[index].pos = reg.field[index].pos;
|
||||||
|
m_ref.get()->field[index].width = reg.field[index].width;
|
||||||
|
for(int i = 0; i < m_fields_tab->count(); i++)
|
||||||
|
dynamic_cast< RegFieldEditPanel * >(m_fields_tab->widget(i))->UpdateRange();
|
||||||
|
OnModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegEditPanel::OnAccessChanged(int acc)
|
||||||
|
{
|
||||||
|
m_ref.get()->access = (soc_desc::access_t)acc;
|
||||||
|
OnModified();
|
||||||
|
}
|
||||||
|
|
||||||
void RegEditPanel::OnDescEdited()
|
void RegEditPanel::OnDescEdited()
|
||||||
{
|
{
|
||||||
m_ref.get()->desc = m_desc_edit->GetTextHtml().toStdString();
|
m_ref.get()->desc = m_desc_edit->GetTextHtml().toStdString();
|
||||||
|
@ -1169,9 +1235,11 @@ void RegEditPanel::OnVariantActivated(QTableWidgetItem *item)
|
||||||
soc_desc::variant_t& variant = *m_ref.create_variant().get();
|
soc_desc::variant_t& variant = *m_ref.create_variant().get();
|
||||||
variant.type = "untyped";
|
variant.type = "untyped";
|
||||||
variant.offset = 0;
|
variant.offset = 0;
|
||||||
|
variant.access = soc_desc::UNSPECIFIED;
|
||||||
m_variant_table->insertRow(row);
|
m_variant_table->insertRow(row);
|
||||||
QTableWidgetItem *item = new QTableWidgetItem(
|
QTableWidgetItem *item = new QTableWidgetItem(
|
||||||
QIcon::fromTheme("list-remove"), "", RegVariantEditPanelDelType);
|
YIconManager::Get()->GetIcon(YIconManager::ListRemove), "", RegVariantEditPanelDelType);
|
||||||
|
item->setToolTip("Remove this variant");
|
||||||
item->setFlags(Qt::ItemIsEnabled);
|
item->setFlags(Qt::ItemIsEnabled);
|
||||||
m_variant_table->setItem(row, 0, item);
|
m_variant_table->setItem(row, 0, item);
|
||||||
item = new QTableWidgetItem(QString::fromStdString(variant.type));
|
item = new QTableWidgetItem(QString::fromStdString(variant.type));
|
||||||
|
@ -1179,6 +1247,9 @@ void RegEditPanel::OnVariantActivated(QTableWidgetItem *item)
|
||||||
item = new QTableWidgetItem();
|
item = new QTableWidgetItem();
|
||||||
item->setData(Qt::EditRole, QVariant(variant.offset));
|
item->setData(Qt::EditRole, QVariant(variant.offset));
|
||||||
m_variant_table->setItem(row, 2, item);
|
m_variant_table->setItem(row, 2, item);
|
||||||
|
item = new QTableWidgetItem();
|
||||||
|
item->setData(Qt::EditRole, QVariant::fromValue(variant.access));
|
||||||
|
m_variant_table->setItem(row, 3, item);
|
||||||
OnModified();
|
OnModified();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1193,6 +1264,8 @@ void RegEditPanel::OnVariantValueChanged(QTableWidgetItem *item)
|
||||||
var.type = item->text().toStdString();
|
var.type = item->text().toStdString();
|
||||||
else if(item->column() == 2)
|
else if(item->column() == 2)
|
||||||
var.offset = item->data(Qt::EditRole).value< soc_word_t >();
|
var.offset = item->data(Qt::EditRole).value< soc_word_t >();
|
||||||
|
else if(item->column() == 3)
|
||||||
|
var.access = item->data(Qt::EditRole).value< soc_desc::access_t >();
|
||||||
OnModified();
|
OnModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1346,20 +1419,22 @@ RegEdit::RegEdit(Backend *backend, QWidget *parent)
|
||||||
m_file_edit->setReadOnly(true);
|
m_file_edit->setReadOnly(true);
|
||||||
m_file_open = new QToolButton(this);
|
m_file_open = new QToolButton(this);
|
||||||
m_file_open->setText("Open");
|
m_file_open->setText("Open");
|
||||||
m_file_open->setIcon(QIcon::fromTheme("document-open"));
|
m_file_open->setIcon(YIconManager::Get()->GetIcon(YIconManager::DocumentOpen));
|
||||||
m_file_open->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
m_file_open->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||||
QMenu *file_open_menu = new QMenu(this);
|
QMenu *file_open_menu = new QMenu(this);
|
||||||
QAction *new_act = file_open_menu->addAction(QIcon::fromTheme("document-new"), "New...");
|
QAction *new_act = file_open_menu->addAction(YIconManager::Get()->GetIcon(YIconManager::DocumentNew),
|
||||||
|
"New...");
|
||||||
m_file_open->setPopupMode(QToolButton::MenuButtonPopup);
|
m_file_open->setPopupMode(QToolButton::MenuButtonPopup);
|
||||||
m_file_open->setMenu(file_open_menu);
|
m_file_open->setMenu(file_open_menu);
|
||||||
|
|
||||||
m_file_save = new QToolButton(this);
|
m_file_save = new QToolButton(this);
|
||||||
m_file_save->setText("Save");
|
m_file_save->setText("Save");
|
||||||
m_file_save->setIcon(QIcon::fromTheme("document-save"));
|
m_file_save->setIcon(YIconManager::Get()->GetIcon(YIconManager::DocumentSave));
|
||||||
m_file_save->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
m_file_save->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||||
m_file_save->setPopupMode(QToolButton::MenuButtonPopup);
|
m_file_save->setPopupMode(QToolButton::MenuButtonPopup);
|
||||||
QMenu *file_save_menu = new QMenu(this);
|
QMenu *file_save_menu = new QMenu(this);
|
||||||
QAction *saveas_act = file_save_menu->addAction(QIcon::fromTheme("document-save-as"), "Save as...");
|
QAction *saveas_act = file_save_menu->addAction(YIconManager::Get()->GetIcon(YIconManager::DocumentSaveAs),
|
||||||
|
"Save as...");
|
||||||
m_file_save->setMenu(file_save_menu);
|
m_file_save->setMenu(file_save_menu);
|
||||||
|
|
||||||
QHBoxLayout *file_group_layout = new QHBoxLayout();
|
QHBoxLayout *file_group_layout = new QHBoxLayout();
|
||||||
|
@ -1375,11 +1450,11 @@ RegEdit::RegEdit(Backend *backend, QWidget *parent)
|
||||||
m_soc_tree->setContextMenuPolicy(Qt::CustomContextMenu);
|
m_soc_tree->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
|
||||||
m_delete_action = new QAction("&Delete", this);
|
m_delete_action = new QAction("&Delete", this);
|
||||||
m_delete_action->setIcon(QIcon::fromTheme("list-remove"));
|
m_delete_action->setIcon(YIconManager::Get()->GetIcon(YIconManager::ListRemove));
|
||||||
m_new_action = new QAction("&New", this);
|
m_new_action = new QAction("&New", this);
|
||||||
m_new_action->setIcon(QIcon::fromTheme("list-add"));
|
m_new_action->setIcon(YIconManager::Get()->GetIcon(YIconManager::ListAdd));
|
||||||
m_create_action = new QAction("&Create register", this);
|
m_create_action = new QAction("&Create register", this);
|
||||||
m_create_action->setIcon(QIcon::fromTheme("folder-new"));
|
m_create_action->setIcon(YIconManager::Get()->GetIcon(YIconManager::FolderNew));
|
||||||
|
|
||||||
m_splitter->addWidget(m_soc_tree);
|
m_splitter->addWidget(m_soc_tree);
|
||||||
m_splitter->setStretchFactor(0, 0);
|
m_splitter->setStretchFactor(0, 0);
|
||||||
|
@ -1605,8 +1680,8 @@ QIcon RegEdit::GetIconFromType(int type)
|
||||||
{
|
{
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case SocTreeSocType: return QIcon::fromTheme("computer");
|
case SocTreeSocType: return YIconManager::Get()->GetIcon(YIconManager::Computer);
|
||||||
case SocTreeNodeType: return QIcon::fromTheme("cpu");
|
case SocTreeNodeType: return YIconManager::Get()->GetIcon(YIconManager::Cpu);
|
||||||
case SocTreeRegType: return style()->standardIcon(QStyle::SP_ArrowRight);
|
case SocTreeRegType: return style()->standardIcon(QStyle::SP_ArrowRight);
|
||||||
default: return QIcon();
|
default: return QIcon();
|
||||||
}
|
}
|
||||||
|
@ -1627,7 +1702,7 @@ void RegEdit::FixupItem(QTreeWidgetItem *item)
|
||||||
UpdateName(item);
|
UpdateName(item);
|
||||||
if(!ValidateName(item->text(0)))
|
if(!ValidateName(item->text(0)))
|
||||||
{
|
{
|
||||||
item->setIcon(0, QIcon::fromTheme("dialog-error"));
|
item->setIcon(0, YIconManager::Get()->GetIcon(YIconManager::DialogError));
|
||||||
if(item->text(0).size() == 0)
|
if(item->text(0).size() == 0)
|
||||||
{
|
{
|
||||||
MakeItalic(item, true);
|
MakeItalic(item, true);
|
||||||
|
@ -1688,6 +1763,7 @@ void RegEdit::OnSocItemCreate()
|
||||||
return;
|
return;
|
||||||
soc_desc::register_t reg;
|
soc_desc::register_t reg;
|
||||||
reg.width = 32;
|
reg.width = 32;
|
||||||
|
reg.access = soc_desc::UNSPECIFIED;
|
||||||
soc_desc::node_ref_t node = SocTreeItemVal< soc_desc::node_ref_t >(current);
|
soc_desc::node_ref_t node = SocTreeItemVal< soc_desc::node_ref_t >(current);
|
||||||
node.get()->register_.push_back(reg);
|
node.get()->register_.push_back(reg);
|
||||||
QTreeWidgetItem *reg_item = MakeSocTreeItem(SocTreeRegType, node.reg());
|
QTreeWidgetItem *reg_item = MakeSocTreeItem(SocTreeRegType, node.reg());
|
||||||
|
|
|
@ -165,6 +165,7 @@ public:
|
||||||
RegFieldEditPanel(const soc_desc::field_ref_t& ref, QWidget *parent = 0);
|
RegFieldEditPanel(const soc_desc::field_ref_t& ref, QWidget *parent = 0);
|
||||||
soc_desc::field_ref_t GetField();
|
soc_desc::field_ref_t GetField();
|
||||||
void UpdateWidth();
|
void UpdateWidth();
|
||||||
|
void UpdateRange();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void OnModified();
|
void OnModified();
|
||||||
|
@ -203,12 +204,14 @@ protected slots:
|
||||||
void OnRegFieldDelete();
|
void OnRegFieldDelete();
|
||||||
void OnRegFieldNew();
|
void OnRegFieldNew();
|
||||||
void OnWidthChanged(int size);
|
void OnWidthChanged(int size);
|
||||||
|
void OnAccessChanged(int access);
|
||||||
void OnFieldModified();
|
void OnFieldModified();
|
||||||
void OnDescEdited();
|
void OnDescEdited();
|
||||||
void OnVariantActivated(QTableWidgetItem *item);
|
void OnVariantActivated(QTableWidgetItem *item);
|
||||||
void OnVariantValueChanged(QTableWidgetItem *item);
|
void OnVariantValueChanged(QTableWidgetItem *item);
|
||||||
void OnFieldRemove(int index);
|
void OnFieldRemove(int index);
|
||||||
void OnFieldCreate();
|
void OnFieldCreate();
|
||||||
|
void OnBitrangeModified(int index);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void DoModify();
|
void DoModify();
|
||||||
|
@ -228,8 +231,10 @@ protected:
|
||||||
QAction *m_delete_action;
|
QAction *m_delete_action;
|
||||||
QPoint m_menu_point;
|
QPoint m_menu_point;
|
||||||
SocFieldItemDelegate *m_variant_delegate;
|
SocFieldItemDelegate *m_variant_delegate;
|
||||||
|
SocAccessItemDelegate *m_access_delegate;
|
||||||
SocFieldEditorCreator *m_variant_editor;
|
SocFieldEditorCreator *m_variant_editor;
|
||||||
QButtonGroup *m_reg_size_group;
|
QButtonGroup *m_reg_size_group;
|
||||||
|
QButtonGroup *m_reg_access_group;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RegEdit : public QWidget, public DocumentTab
|
class RegEdit : public QWidget, public DocumentTab
|
||||||
|
|
|
@ -75,10 +75,11 @@ RegTab::RegTab(Backend *backend, QWidget *parent)
|
||||||
QVBoxLayout *left_layout = new QVBoxLayout;
|
QVBoxLayout *left_layout = new QVBoxLayout;
|
||||||
left->setLayout(left_layout);
|
left->setLayout(left_layout);
|
||||||
|
|
||||||
QGroupBox *top_group = new QGroupBox("SOC selection");
|
QGroupBox *top_group = new QGroupBox("");
|
||||||
QVBoxLayout *top_group_layout = new QVBoxLayout;
|
QHBoxLayout *top_group_layout = new QHBoxLayout;
|
||||||
m_soc_selector = new QComboBox;
|
m_soc_selector = new QComboBox;
|
||||||
top_group_layout->addWidget(m_soc_selector);
|
top_group_layout->addWidget(new QLabel("SOC:"));
|
||||||
|
top_group_layout->addWidget(m_soc_selector, 1);
|
||||||
top_group->setLayout(top_group_layout);
|
top_group->setLayout(top_group_layout);
|
||||||
|
|
||||||
m_reg_tree = new QTreeWidget();
|
m_reg_tree = new QTreeWidget();
|
||||||
|
@ -96,7 +97,7 @@ RegTab::RegTab(Backend *backend, QWidget *parent)
|
||||||
left_layout->addWidget(m_type_selector);
|
left_layout->addWidget(m_type_selector);
|
||||||
|
|
||||||
m_right_panel = new QVBoxLayout;
|
m_right_panel = new QVBoxLayout;
|
||||||
QGroupBox *data_sel_group = new QGroupBox("Data selection");
|
QGroupBox *data_sel_group = new QGroupBox("");
|
||||||
QHBoxLayout *data_sel_layout = new QHBoxLayout;
|
QHBoxLayout *data_sel_layout = new QHBoxLayout;
|
||||||
m_backend_selector = new BackendSelector(m_backend, this);
|
m_backend_selector = new BackendSelector(m_backend, this);
|
||||||
m_backend_selector->SetNothingMessage("<i>Select a data source to analyse its content.</i>");
|
m_backend_selector->SetNothingMessage("<i>Select a data source to analyse its content.</i>");
|
||||||
|
@ -108,6 +109,7 @@ RegTab::RegTab(Backend *backend, QWidget *parent)
|
||||||
m_data_sel_reload = new QPushButton(this);
|
m_data_sel_reload = new QPushButton(this);
|
||||||
m_data_sel_reload->setIcon(QIcon::fromTheme("view-refresh"));
|
m_data_sel_reload->setIcon(QIcon::fromTheme("view-refresh"));
|
||||||
m_data_sel_reload->setToolTip("Reload data");
|
m_data_sel_reload->setToolTip("Reload data");
|
||||||
|
data_sel_layout->addWidget(new QLabel("Data:"));
|
||||||
data_sel_layout->addWidget(m_backend_selector);
|
data_sel_layout->addWidget(m_backend_selector);
|
||||||
data_sel_layout->addWidget(m_readonly_check);
|
data_sel_layout->addWidget(m_readonly_check);
|
||||||
data_sel_layout->addWidget(m_data_soc_label);
|
data_sel_layout->addWidget(m_data_soc_label);
|
||||||
|
@ -146,7 +148,9 @@ RegTab::RegTab(Backend *backend, QWidget *parent)
|
||||||
connect(m_type_selector, SIGNAL(currentChanged(int)), this, SLOT(OnTypeChanged(int)));
|
connect(m_type_selector, SIGNAL(currentChanged(int)), this, SLOT(OnTypeChanged(int)));
|
||||||
|
|
||||||
m_msg_select_id = SetMessage(MessageWidget::Information,
|
m_msg_select_id = SetMessage(MessageWidget::Information,
|
||||||
"You can browse the registers. Select a data source to analyse the values.");
|
"You can browse the registers using the left panel. "
|
||||||
|
"Select a data source at the top to analyse the values. "
|
||||||
|
"You can also use the analyzers available in the left panel, if any.");
|
||||||
m_msg_error_id = 0;
|
m_msg_error_id = 0;
|
||||||
|
|
||||||
QList< SocFileRef > socs = m_backend->GetSocFileList();
|
QList< SocFileRef > socs = m_backend->GetSocFileList();
|
||||||
|
@ -215,8 +219,7 @@ void RegTab::UpdateTabName()
|
||||||
else if(hwstub)
|
else if(hwstub)
|
||||||
{
|
{
|
||||||
HWStubDevice *dev = hwstub->GetDevice();
|
HWStubDevice *dev = hwstub->GetDevice();
|
||||||
SetTabName(QString("HWStub %1.%2").arg(dev->GetBusNumber())
|
SetTabName(dev->GetFriendlyName());
|
||||||
.arg(dev->GetDevAddress()));
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
|
@ -231,11 +234,21 @@ void RegTab::OnBackendSelect(IoBackend *backend)
|
||||||
HideMessage(m_msg_select_id);
|
HideMessage(m_msg_select_id);
|
||||||
HideMessage(m_msg_error_id);
|
HideMessage(m_msg_error_id);
|
||||||
m_io_backend = backend;
|
m_io_backend = backend;
|
||||||
|
/* Check if the backend is valid, otherwise it might confuse the user */
|
||||||
|
if(m_io_backend->IsValid())
|
||||||
|
{
|
||||||
SetReadOnlyIndicator();
|
SetReadOnlyIndicator();
|
||||||
SetDataSocName(m_io_backend->GetSocName());
|
SetDataSocName(m_io_backend->GetSocName());
|
||||||
OnDataSocActivated(m_io_backend->GetSocName());
|
OnDataSocActivated(m_io_backend->GetSocName());
|
||||||
OnDataChanged();
|
OnDataChanged();
|
||||||
UpdateTabName();
|
UpdateTabName();
|
||||||
|
}
|
||||||
|
/* But don't display it for the dummy backend either */
|
||||||
|
else if(dynamic_cast< DummyIoBackend * >(m_io_backend) == 0)
|
||||||
|
{
|
||||||
|
m_msg_error_id = SetMessage(MessageWidget::Error,
|
||||||
|
"Data source is not available.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegTab::SetReadOnlyIndicator()
|
void RegTab::SetReadOnlyIndicator()
|
||||||
|
@ -267,6 +280,7 @@ void RegTab::OnAnalyserClicked(QListWidgetItem *current)
|
||||||
|
|
||||||
void RegTab::DisplayNode(const soc_desc::node_inst_t& ref)
|
void RegTab::DisplayNode(const soc_desc::node_inst_t& ref)
|
||||||
{
|
{
|
||||||
|
HideMessage(m_msg_select_id);
|
||||||
if(ref.node().is_root())
|
if(ref.node().is_root())
|
||||||
SetPanel(new SocDisplayPanel(this, m_io_backend, ref.soc()));
|
SetPanel(new SocDisplayPanel(this, m_io_backend, ref.soc()));
|
||||||
else if(ref.node().reg().valid())
|
else if(ref.node().reg().valid())
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
#include <QXmlStreamWriter>
|
#include <QXmlStreamWriter>
|
||||||
#include <QTextBlock>
|
#include <QTextBlock>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SocBitRangeValidator
|
* SocBitRangeValidator
|
||||||
|
@ -406,6 +409,11 @@ bool SocFieldBitRange::operator<(const SocFieldBitRange& o) const
|
||||||
return m_last_bit < o.m_last_bit;
|
return m_last_bit < o.m_last_bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SocFieldBitRange::operator!=(const SocFieldBitRange& o) const
|
||||||
|
{
|
||||||
|
return m_first_bit != o.m_first_bit || m_last_bit != o.m_last_bit;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SocFieldCachedItemDelegate
|
* SocFieldCachedItemDelegate
|
||||||
*/
|
*/
|
||||||
|
@ -475,6 +483,53 @@ void SocFieldCachedEditor::setValue(SocFieldCachedValue val)
|
||||||
setField(m_value.value());
|
setField(m_value.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SocAccessItemDelegate
|
||||||
|
*/
|
||||||
|
QString SocAccessItemDelegate::displayText(const QVariant& value, const QLocale& locale) const
|
||||||
|
{
|
||||||
|
if(isUserType< soc_desc::access_t >(value))
|
||||||
|
{
|
||||||
|
soc_desc::access_t acc = value.value< soc_desc::access_t >();
|
||||||
|
switch(acc)
|
||||||
|
{
|
||||||
|
case soc_desc::UNSPECIFIED: return m_unspec_text;
|
||||||
|
case soc_desc::READ_ONLY: return "Read-Only";
|
||||||
|
case soc_desc::READ_WRITE: return "Read-Write";
|
||||||
|
case soc_desc::WRITE_ONLY: return "Write-Only";
|
||||||
|
default: return "<bug>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return QStyledItemDelegate::displayText(value, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SocAccessEditor
|
||||||
|
*/
|
||||||
|
SocAccessEditor::SocAccessEditor(const QString& unspec_text, QWidget *parent)
|
||||||
|
:QComboBox(parent)
|
||||||
|
{
|
||||||
|
addItem(unspec_text, QVariant::fromValue(soc_desc::UNSPECIFIED));
|
||||||
|
addItem("Read-Only", QVariant::fromValue(soc_desc::READ_ONLY));
|
||||||
|
addItem("Read-Write", QVariant::fromValue(soc_desc::READ_WRITE));
|
||||||
|
addItem("Write-Only", QVariant::fromValue(soc_desc::WRITE_ONLY));
|
||||||
|
}
|
||||||
|
|
||||||
|
SocAccessEditor::~SocAccessEditor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
soc_desc::access_t SocAccessEditor::access() const
|
||||||
|
{
|
||||||
|
return itemData(currentIndex()).value< soc_desc::access_t >();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocAccessEditor::setAccess(soc_desc::access_t acc)
|
||||||
|
{
|
||||||
|
setCurrentIndex(findData(QVariant::fromValue(acc)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SocFieldEditorCreator
|
* SocFieldEditorCreator
|
||||||
*/
|
*/
|
||||||
|
@ -493,6 +548,19 @@ void SocFieldEditorCreator::setWidth(int bitcount)
|
||||||
m_field.width = bitcount;
|
m_field.width = bitcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SocAccessEditorCreator
|
||||||
|
*/
|
||||||
|
QWidget *SocAccessEditorCreator::createWidget(QWidget *parent) const
|
||||||
|
{
|
||||||
|
return new SocAccessEditor(m_unspec_text, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray SocAccessEditorCreator::valuePropertyName() const
|
||||||
|
{
|
||||||
|
return QByteArray("access");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SocFieldCachedEditorCreator
|
* SocFieldCachedEditorCreator
|
||||||
*/
|
*/
|
||||||
|
@ -602,8 +670,22 @@ bool RegFieldTableModel::setData(const QModelIndex& idx, const QVariant& value,
|
||||||
if(role != Qt::EditRole)
|
if(role != Qt::EditRole)
|
||||||
return false;
|
return false;
|
||||||
int section = idx.column();
|
int section = idx.column();
|
||||||
if(section < FirstValueColumn || section >= FirstValueColumn + m_value.size())
|
if(section == BitRangeColumn)
|
||||||
|
{
|
||||||
|
if(idx.row() < 0 || idx.row() >= rowCount())
|
||||||
return false;
|
return false;
|
||||||
|
if(value.type() != QVariant::UserType && value.userType() == qMetaTypeId< SocFieldBitRange >())
|
||||||
|
return false;
|
||||||
|
SocFieldBitRange bitrange = value.value< SocFieldBitRange >();
|
||||||
|
m_reg.field[idx.row()].pos = bitrange.GetFirstBit();
|
||||||
|
m_reg.field[idx.row()].width = bitrange.GetLastBit() - bitrange.GetFirstBit() + 1;
|
||||||
|
emit OnBitrangeModified(idx.row());
|
||||||
|
}
|
||||||
|
if(section < FirstValueColumn || section >= FirstValueColumn + m_value.size())
|
||||||
|
{
|
||||||
|
qDebug() << "ignore setData to column " << section;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
section -= FirstValueColumn;
|
section -= FirstValueColumn;
|
||||||
const SocFieldCachedValue& v = value.value< SocFieldCachedValue >();
|
const SocFieldCachedValue& v = value.value< SocFieldCachedValue >();
|
||||||
if(!m_value[section].isValid())
|
if(!m_value[section].isValid())
|
||||||
|
@ -622,7 +704,12 @@ Qt::ItemFlags RegFieldTableModel::flags(const QModelIndex& index) const
|
||||||
Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||||
int section = index.column();
|
int section = index.column();
|
||||||
if(section < FirstValueColumn || section >= FirstValueColumn + m_value.size())
|
if(section < FirstValueColumn || section >= FirstValueColumn + m_value.size())
|
||||||
|
{
|
||||||
|
/* bitrange or name */
|
||||||
|
if(!m_read_only)
|
||||||
|
flags |= Qt::ItemIsEditable;
|
||||||
return flags;
|
return flags;
|
||||||
|
}
|
||||||
section -= FirstValueColumn;
|
section -= FirstValueColumn;
|
||||||
if(m_value[section].isValid() && !m_read_only)
|
if(m_value[section].isValid() && !m_read_only)
|
||||||
flags |= Qt::ItemIsEditable;
|
flags |= Qt::ItemIsEditable;
|
||||||
|
@ -763,6 +850,207 @@ bool RegFieldProxyModel::lessThan(const QModelIndex& left,
|
||||||
return QSortFilterProxyModel::lessThan(left, right);
|
return QSortFilterProxyModel::lessThan(left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* YRegDisplayItemEditor
|
||||||
|
*/
|
||||||
|
YRegDisplayItemEditor::YRegDisplayItemEditor(QWidget *parent, YRegDisplay *display,
|
||||||
|
YRegDisplayItemDelegate *delegate, QModelIndex bitrange_index,
|
||||||
|
QModelIndex name_index)
|
||||||
|
:QWidget(parent), m_display_delegate(delegate),
|
||||||
|
m_display(display), m_state(Idle)
|
||||||
|
{
|
||||||
|
m_col_width = m_display->BitrangeRect(SocFieldBitRange(0, 0)).width();
|
||||||
|
m_resize_margin = m_col_width / 4;
|
||||||
|
setEditorData(bitrange_index, name_index);
|
||||||
|
setMouseTracking(true);
|
||||||
|
setAutoFillBackground(true);
|
||||||
|
setFocusPolicy(Qt::StrongFocus); // QItemDelegate says it's important
|
||||||
|
}
|
||||||
|
|
||||||
|
void YRegDisplayItemEditor::setEditorData(QModelIndex bitrange_index, QModelIndex name_index)
|
||||||
|
{
|
||||||
|
if(m_state != Idle)
|
||||||
|
{
|
||||||
|
m_state = Idle;
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
}
|
||||||
|
m_bitrange_index = bitrange_index;
|
||||||
|
m_name_index = name_index;
|
||||||
|
m_bitrange = bitrange_index.data().value< SocFieldBitRange >();
|
||||||
|
}
|
||||||
|
|
||||||
|
void YRegDisplayItemEditor::getEditorData(QVariant& name, QVariant& bitrange)
|
||||||
|
{
|
||||||
|
name = QVariant(); /* don't touch the name */
|
||||||
|
bitrange = QVariant::fromValue(m_bitrange);
|
||||||
|
}
|
||||||
|
|
||||||
|
YRegDisplayItemEditor::~YRegDisplayItemEditor()
|
||||||
|
{
|
||||||
|
/* make sure to restore cursor if modified */
|
||||||
|
if(m_state != Idle)
|
||||||
|
{
|
||||||
|
m_state = Idle;
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
YRegDisplayItemEditor::Zone YRegDisplayItemEditor::GetZone(const QPoint& pt)
|
||||||
|
{
|
||||||
|
if(!rect().contains(pt))
|
||||||
|
return NoZone;
|
||||||
|
if(pt.x() >= 0 && pt.x() <= m_resize_margin)
|
||||||
|
return ResizeLeftZone;
|
||||||
|
if(pt.x() >= width() - m_resize_margin && pt.x() <= width())
|
||||||
|
return ResizeRightZone;
|
||||||
|
return MoveZone;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YRegDisplayItemEditor::mouseMoveEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
Zone zone = GetZone(event->pos());
|
||||||
|
bool in_resize_zone = (zone == ResizeLeftZone || zone == ResizeRightZone);
|
||||||
|
/* resizing/moving has priority */
|
||||||
|
if(m_state == ResizingLeft || m_state == ResizingRight || m_state == Moving)
|
||||||
|
{
|
||||||
|
SocFieldBitRange new_bitrange = m_bitrange;
|
||||||
|
if(m_state == Moving)
|
||||||
|
{
|
||||||
|
/* Compute new bitrange: we know the offset of the mouse relative to the
|
||||||
|
* left of the register: use that offset to compute the new position of
|
||||||
|
* the MSB bit. To make it more natural, add half of a column of margin
|
||||||
|
* so that the register does not move until half of a bit column displacement
|
||||||
|
* was made */
|
||||||
|
int bit = m_display->bitColumnAt(mapTo(m_display,
|
||||||
|
event->pos() - QPoint(m_move_offset - m_col_width / 2, 0)));
|
||||||
|
new_bitrange.SetLastBit(bit);
|
||||||
|
int w = m_bitrange.GetLastBit() - m_bitrange.GetFirstBit();
|
||||||
|
/* make sure range is valid */
|
||||||
|
if(bit - w < 0)
|
||||||
|
return;
|
||||||
|
new_bitrange.SetFirstBit(bit - w);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Compute new bitrange. To make it more natural, add quarter of a column of margin
|
||||||
|
* so that the register does not resize until quarter of a bit column displacement
|
||||||
|
* was made */
|
||||||
|
int bit = m_display->bitColumnAt(mapTo(m_display, event->pos()
|
||||||
|
+ QPoint(m_col_width / 4, 0)));
|
||||||
|
if(m_state == ResizingLeft)
|
||||||
|
new_bitrange.SetLastBit(bit);
|
||||||
|
else
|
||||||
|
new_bitrange.SetFirstBit(bit);
|
||||||
|
/* make sure range is valid */
|
||||||
|
if(new_bitrange.GetLastBit() < new_bitrange.GetFirstBit())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* make sure range does not overlap with other fields */
|
||||||
|
/* TODO */
|
||||||
|
/* update current bitrange (display only) and resize widget */
|
||||||
|
if(m_bitrange != new_bitrange)
|
||||||
|
{
|
||||||
|
m_bitrange = new_bitrange;
|
||||||
|
/* resize widget */
|
||||||
|
QRect rect = m_display->BitrangeRect(m_bitrange);
|
||||||
|
rect.moveTopLeft(parentWidget()->mapFromGlobal(m_display->mapToGlobal(rect.topLeft())));
|
||||||
|
setGeometry(rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* any zone -> resize zone */
|
||||||
|
else if(in_resize_zone)
|
||||||
|
{
|
||||||
|
/* don't do unnecessary changes */
|
||||||
|
if(m_state != InResizeZone)
|
||||||
|
{
|
||||||
|
/* restore old cursor if needed */
|
||||||
|
if(m_state != Idle)
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
m_state = InResizeZone;
|
||||||
|
QApplication::setOverrideCursor(QCursor(Qt::SizeHorCursor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* any zone -> move zone */
|
||||||
|
else if(zone == MoveZone)
|
||||||
|
{
|
||||||
|
/* don't do unnecessary changes */
|
||||||
|
if(m_state != InMoveZone)
|
||||||
|
{
|
||||||
|
/* restore old cursor if needed */
|
||||||
|
if(m_state != Idle)
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
m_state = InMoveZone;
|
||||||
|
QApplication::setOverrideCursor(QCursor(Qt::SizeAllCursor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* any zone -> no zone */
|
||||||
|
else if(zone == NoZone)
|
||||||
|
{
|
||||||
|
if(m_state != Idle)
|
||||||
|
{
|
||||||
|
m_state = Idle;
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void YRegDisplayItemEditor::leaveEvent(QEvent *event)
|
||||||
|
{
|
||||||
|
Q_UNUSED(event);
|
||||||
|
if(m_state == InResizeZone)
|
||||||
|
{
|
||||||
|
m_state = Idle;
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void YRegDisplayItemEditor::mousePressEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
/* just in case the mouseMove event was not done */
|
||||||
|
mouseMoveEvent(event);
|
||||||
|
/* we need to track mouse outside of widget but Qt already grabs the mouse
|
||||||
|
* for us on mouse press in widget */
|
||||||
|
if(m_state == InResizeZone)
|
||||||
|
{
|
||||||
|
if(GetZone(event->pos()) == ResizeLeftZone)
|
||||||
|
m_state = ResizingLeft;
|
||||||
|
else
|
||||||
|
m_state = ResizingRight;
|
||||||
|
}
|
||||||
|
else if(m_state == InMoveZone)
|
||||||
|
{
|
||||||
|
m_state = Moving;
|
||||||
|
/* store offset from the left, to keep relative position of the register
|
||||||
|
* with respect to the mouse */
|
||||||
|
m_move_offset = event->pos().x();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void YRegDisplayItemEditor::mouseReleaseEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
if(m_state == ResizingLeft || m_state == ResizingRight || m_state == Moving)
|
||||||
|
{
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
m_state = Idle;
|
||||||
|
/* update cursor */
|
||||||
|
mouseMoveEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void YRegDisplayItemEditor::paintEvent(QPaintEvent *event)
|
||||||
|
{
|
||||||
|
Q_UNUSED(event);
|
||||||
|
QPainter painter(this);
|
||||||
|
/* reuse delegate code to paint */
|
||||||
|
QStyleOptionViewItemV4 opt = m_display->viewOptions();
|
||||||
|
opt.state |= QStyle::State_HasFocus | QStyle::State_Selected | QStyle::State_Active;
|
||||||
|
opt.displayAlignment = Qt::AlignHCenter | Qt::AlignVCenter;
|
||||||
|
opt.rect = rect();
|
||||||
|
opt.showDecorationSelected = true;
|
||||||
|
m_display_delegate->initStyleOption(&opt, m_name_index);
|
||||||
|
m_display_delegate->MyPaint(&painter, opt);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* YRegDisplayItemDelegate
|
* YRegDisplayItemDelegate
|
||||||
*/
|
*/
|
||||||
|
@ -772,14 +1060,9 @@ YRegDisplayItemDelegate::YRegDisplayItemDelegate(QObject *parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void YRegDisplayItemDelegate::paint(QPainter *painter,
|
void YRegDisplayItemDelegate::MyPaint(QPainter *painter, const QStyleOptionViewItemV4& option) const
|
||||||
const QStyleOptionViewItem& option, const QModelIndex& index) const
|
|
||||||
{
|
{
|
||||||
QStyleOptionViewItemV4 opt = option;
|
QStyleOptionViewItemV4 opt = option;
|
||||||
// default alignment is centered unless specified
|
|
||||||
opt.displayAlignment = Qt::AlignHCenter | Qt::AlignVCenter;
|
|
||||||
initStyleOption(&opt, index);
|
|
||||||
|
|
||||||
painter->save();
|
painter->save();
|
||||||
// draw everything rotated, requires careful manipulation of the
|
// draw everything rotated, requires careful manipulation of the
|
||||||
// rects involved
|
// rects involved
|
||||||
|
@ -789,17 +1072,58 @@ YRegDisplayItemDelegate::YRegDisplayItemDelegate(QObject *parent)
|
||||||
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
|
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
|
||||||
style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
|
style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
|
||||||
painter->restore();
|
painter->restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void YRegDisplayItemDelegate::paint(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
QStyleOptionViewItemV4 opt = option;
|
||||||
|
// default alignment is centered unless specified
|
||||||
|
opt.displayAlignment = Qt::AlignHCenter | Qt::AlignVCenter;
|
||||||
|
initStyleOption(&opt, index);
|
||||||
|
|
||||||
|
MyPaint(painter, opt);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize YRegDisplayItemDelegate::sizeHint(const QStyleOptionViewItem& option,
|
QSize YRegDisplayItemDelegate::sizeHint(const QStyleOptionViewItem& option,
|
||||||
const QModelIndex& index) const
|
const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
|
/* useless in our case, the view ignores this */
|
||||||
Q_UNUSED(option);
|
Q_UNUSED(option);
|
||||||
Q_UNUSED(index);
|
Q_UNUSED(index);
|
||||||
return QSize();
|
return QSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWidget *YRegDisplayItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option,
|
||||||
|
const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(option);
|
||||||
|
Q_UNUSED(index);
|
||||||
|
YRegDisplay *display = dynamic_cast< YRegDisplay* >(parent->parent());
|
||||||
|
Q_ASSERT(display != nullptr);
|
||||||
|
/* column 0 is name, column 1 is range */
|
||||||
|
return new YRegDisplayItemEditor(parent, display, const_cast< YRegDisplayItemDelegate* >(this),
|
||||||
|
index.sibling(index.row(), 0), index.sibling(index.row(), 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void YRegDisplayItemDelegate::setEditorData(QWidget *editor, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
dynamic_cast< YRegDisplayItemEditor* >(editor)->setEditorData(
|
||||||
|
index.sibling(index.row(), 0), index.sibling(index.row(), 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void YRegDisplayItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||||
|
const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
QVariant name, bitrange;
|
||||||
|
dynamic_cast< YRegDisplayItemEditor* >(editor)->getEditorData(name, bitrange);
|
||||||
|
if(name.isValid())
|
||||||
|
model->setData(index.sibling(index.row(), 1), name);
|
||||||
|
if(bitrange.isValid())
|
||||||
|
model->setData(index.sibling(index.row(), 0), bitrange);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* YRegDisplay
|
* YRegDisplay
|
||||||
*/
|
*/
|
||||||
|
@ -814,7 +1138,8 @@ YRegDisplay::YRegDisplay(QWidget *parent)
|
||||||
// the frame around the register is ugly, disable it
|
// the frame around the register is ugly, disable it
|
||||||
setFrameShape(QFrame::NoFrame);
|
setFrameShape(QFrame::NoFrame);
|
||||||
setSelectionMode(SingleSelection);
|
setSelectionMode(SingleSelection);
|
||||||
setItemDelegate(new YRegDisplayItemDelegate());
|
setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked);
|
||||||
|
setItemDelegate(new YRegDisplayItemDelegate(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
void YRegDisplay::setWidth(int nr_bits)
|
void YRegDisplay::setWidth(int nr_bits)
|
||||||
|
@ -1055,6 +1380,11 @@ QRect YRegDisplay::itemRect(const QModelIndex& index) const
|
||||||
return itemRect(range, index.column());
|
return itemRect(range, index.column());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRect YRegDisplay::BitrangeRect(const SocFieldBitRange& range) const
|
||||||
|
{
|
||||||
|
return itemRect(range, m_data_col);
|
||||||
|
}
|
||||||
|
|
||||||
QRect YRegDisplay::itemRect(const SocFieldBitRange& range, int col) const
|
QRect YRegDisplay::itemRect(const SocFieldBitRange& range, int col) const
|
||||||
{
|
{
|
||||||
int top, bot;
|
int top, bot;
|
||||||
|
@ -1276,17 +1606,17 @@ MyTextEditor::MyTextEditor(QWidget *parent)
|
||||||
m_edit->setAutoFormatting(QTextEdit::AutoAll);
|
m_edit->setAutoFormatting(QTextEdit::AutoAll);
|
||||||
|
|
||||||
m_bold_button = new QToolButton(this);
|
m_bold_button = new QToolButton(this);
|
||||||
m_bold_button->setIcon(QIcon::fromTheme("format-text-bold"));
|
m_bold_button->setIcon(YIconManager::Get()->GetIcon(YIconManager::FormatTextBold));
|
||||||
m_bold_button->setText("bold");
|
m_bold_button->setText("bold");
|
||||||
m_bold_button->setCheckable(true);
|
m_bold_button->setCheckable(true);
|
||||||
|
|
||||||
m_italic_button = new QToolButton(this);
|
m_italic_button = new QToolButton(this);
|
||||||
m_italic_button->setIcon(QIcon::fromTheme("format-text-italic"));
|
m_italic_button->setIcon(YIconManager::Get()->GetIcon(YIconManager::FormatTextItalic));
|
||||||
m_italic_button->setText("italic");
|
m_italic_button->setText("italic");
|
||||||
m_italic_button->setCheckable(true);
|
m_italic_button->setCheckable(true);
|
||||||
|
|
||||||
m_underline_button = new QToolButton(this);
|
m_underline_button = new QToolButton(this);
|
||||||
m_underline_button->setIcon(QIcon::fromTheme("format-text-underline"));
|
m_underline_button->setIcon(YIconManager::Get()->GetIcon(YIconManager::FormatTextUnderline));
|
||||||
m_underline_button->setText("underline");
|
m_underline_button->setText("underline");
|
||||||
m_underline_button->setCheckable(true);
|
m_underline_button->setCheckable(true);
|
||||||
|
|
||||||
|
@ -1419,10 +1749,13 @@ BackendSelector::BackendSelector(Backend *backend, QWidget *parent)
|
||||||
:QWidget(parent), m_backend(backend)
|
:QWidget(parent), m_backend(backend)
|
||||||
{
|
{
|
||||||
m_data_selector = new QComboBox(this);
|
m_data_selector = new QComboBox(this);
|
||||||
m_data_selector->addItem(QIcon::fromTheme("text-x-generic"), "Nothing...", QVariant(DataSelNothing));
|
m_data_selector->addItem(YIconManager::Get()->GetIcon(YIconManager::TextGeneric),
|
||||||
m_data_selector->addItem(QIcon::fromTheme("document-open"), "File...", QVariant(DataSelFile));
|
"Nothing...", QVariant(DataSelNothing));
|
||||||
|
m_data_selector->addItem(YIconManager::Get()->GetIcon(YIconManager::DocumentOpen),
|
||||||
|
"File...", QVariant(DataSelFile));
|
||||||
#ifdef HAVE_HWSTUB
|
#ifdef HAVE_HWSTUB
|
||||||
m_data_selector->addItem(QIcon::fromTheme("multimedia-player"), "Device...", QVariant(DataSelDevice));
|
m_data_selector->addItem(YIconManager::Get()->GetIcon(YIconManager::MultimediaPlayer),
|
||||||
|
"USB Device...", QVariant(DataSelDevice));
|
||||||
#endif
|
#endif
|
||||||
m_data_sel_edit = new QLineEdit(this);
|
m_data_sel_edit = new QLineEdit(this);
|
||||||
m_data_sel_edit->setReadOnly(true);
|
m_data_sel_edit->setReadOnly(true);
|
||||||
|
@ -1435,7 +1768,18 @@ BackendSelector::BackendSelector(Backend *backend, QWidget *parent)
|
||||||
data_sel_layout->addStretch(0);
|
data_sel_layout->addStretch(0);
|
||||||
#ifdef HAVE_HWSTUB
|
#ifdef HAVE_HWSTUB
|
||||||
m_dev_selector = new QComboBox;
|
m_dev_selector = new QComboBox;
|
||||||
|
m_ctx_model = new HWStubContextModel;
|
||||||
|
m_ctx_model->EnableDummy(true, "Please select a device...");
|
||||||
|
m_dev_selector->setModel(m_ctx_model); /* m_dev_selector will delete m_ctx_model */
|
||||||
|
m_ctx_selector = new QComboBox;
|
||||||
|
m_ctx_manager = HWStubManager::Get();
|
||||||
|
m_ctx_selector->setModel(m_ctx_manager);
|
||||||
|
m_ctx_manage_button = new QPushButton();
|
||||||
|
m_ctx_manage_button->setIcon(YIconManager::Get()->GetIcon(YIconManager::Preferences));
|
||||||
|
m_ctx_manage_button->setToolTip("Manage contexts");
|
||||||
data_sel_layout->addWidget(m_dev_selector, 1);
|
data_sel_layout->addWidget(m_dev_selector, 1);
|
||||||
|
data_sel_layout->addWidget(m_ctx_selector);
|
||||||
|
data_sel_layout->addWidget(m_ctx_manage_button);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_io_backend = m_backend->CreateDummyIoBackend();
|
m_io_backend = m_backend->CreateDummyIoBackend();
|
||||||
|
@ -1443,18 +1787,25 @@ BackendSelector::BackendSelector(Backend *backend, QWidget *parent)
|
||||||
connect(m_data_selector, SIGNAL(activated(int)),
|
connect(m_data_selector, SIGNAL(activated(int)),
|
||||||
this, SLOT(OnDataSelChanged(int)));
|
this, SLOT(OnDataSelChanged(int)));
|
||||||
#ifdef HAVE_HWSTUB
|
#ifdef HAVE_HWSTUB
|
||||||
connect(m_dev_selector, SIGNAL(currentIndexChanged(int)),
|
connect(m_ctx_selector, SIGNAL(currentIndexChanged(int)), this,
|
||||||
this, SLOT(OnDevChanged(int)));
|
SLOT(OnContextSelChanged(int)));
|
||||||
connect(&m_hwstub_helper, SIGNAL(OnDevListChanged(bool, struct libusb_device *)),
|
connect(m_dev_selector, SIGNAL(currentIndexChanged(int)), this,
|
||||||
this, SLOT(OnDevListChanged2(bool, struct libusb_device *)));
|
SLOT(OnDeviceSelChanged(int)));
|
||||||
|
connect(m_dev_selector, SIGNAL(activated(int)), this,
|
||||||
|
SLOT(OnDeviceSelActivated(int)));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_HWSTUB
|
||||||
|
OnContextSelChanged(0);
|
||||||
#endif
|
#endif
|
||||||
OnDataSelChanged(0);
|
OnDataSelChanged(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
BackendSelector::~BackendSelector()
|
BackendSelector::~BackendSelector()
|
||||||
{
|
{
|
||||||
|
/* avoid m_ctx_selector from deleting HWStubManager */
|
||||||
#ifdef HAVE_HWSTUB
|
#ifdef HAVE_HWSTUB
|
||||||
ClearDevList();
|
m_ctx_selector->setModel(new QStandardItemModel());
|
||||||
#endif
|
#endif
|
||||||
delete m_io_backend;
|
delete m_io_backend;
|
||||||
}
|
}
|
||||||
|
@ -1475,6 +1826,8 @@ void BackendSelector::OnDataSelChanged(int index)
|
||||||
m_data_sel_edit->show();
|
m_data_sel_edit->show();
|
||||||
#ifdef HAVE_HWSTUB
|
#ifdef HAVE_HWSTUB
|
||||||
m_dev_selector->hide();
|
m_dev_selector->hide();
|
||||||
|
m_ctx_selector->hide();
|
||||||
|
m_ctx_manage_button->hide();
|
||||||
#endif
|
#endif
|
||||||
QFileDialog *fd = new QFileDialog(m_data_selector);
|
QFileDialog *fd = new QFileDialog(m_data_selector);
|
||||||
QStringList filters;
|
QStringList filters;
|
||||||
|
@ -1496,7 +1849,10 @@ void BackendSelector::OnDataSelChanged(int index)
|
||||||
m_nothing_text->hide();
|
m_nothing_text->hide();
|
||||||
m_data_sel_edit->hide();
|
m_data_sel_edit->hide();
|
||||||
m_dev_selector->show();
|
m_dev_selector->show();
|
||||||
OnDevListChanged();
|
m_ctx_selector->show();
|
||||||
|
m_ctx_manage_button->show();
|
||||||
|
/* explicitely change the backend now */
|
||||||
|
OnDeviceSelActivated(m_dev_selector->currentIndex());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
|
@ -1505,59 +1861,14 @@ void BackendSelector::OnDataSelChanged(int index)
|
||||||
m_nothing_text->show();
|
m_nothing_text->show();
|
||||||
#ifdef HAVE_HWSTUB
|
#ifdef HAVE_HWSTUB
|
||||||
m_dev_selector->hide();
|
m_dev_selector->hide();
|
||||||
|
m_ctx_selector->hide();
|
||||||
|
m_ctx_manage_button->hide();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ChangeBackend(m_backend->CreateDummyIoBackend());
|
ChangeBackend(m_backend->CreateDummyIoBackend());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_HWSTUB
|
|
||||||
void BackendSelector::OnDevListChanged2(bool arrived, struct libusb_device *dev)
|
|
||||||
{
|
|
||||||
Q_UNUSED(arrived);
|
|
||||||
Q_UNUSED(dev);
|
|
||||||
OnDevListChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackendSelector::OnDevListChanged()
|
|
||||||
{
|
|
||||||
ClearDevList();
|
|
||||||
QList< HWStubDevice* > list = m_hwstub_helper.GetDevList();
|
|
||||||
foreach(HWStubDevice *dev, list)
|
|
||||||
{
|
|
||||||
QString name = QString("Bus %1 Device %2: %3").arg(dev->GetBusNumber())
|
|
||||||
.arg(dev->GetDevAddress()).arg(dev->GetTargetInfo().bName);
|
|
||||||
m_dev_selector->addItem(QIcon::fromTheme("multimedia-player"), name,
|
|
||||||
QVariant::fromValue((void *)dev));
|
|
||||||
}
|
|
||||||
if(list.size() > 0)
|
|
||||||
m_dev_selector->setCurrentIndex(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackendSelector::OnDevChanged(int index)
|
|
||||||
{
|
|
||||||
if(index == -1)
|
|
||||||
return;
|
|
||||||
HWStubDevice *dev = reinterpret_cast< HWStubDevice* >(m_dev_selector->itemData(index).value< void* >());
|
|
||||||
delete m_io_backend;
|
|
||||||
/* NOTE: make a copy of the HWStubDevice device because the one in the list
|
|
||||||
* might get destroyed when clearing the list while the backend is still
|
|
||||||
* active: this would result in a double free when the backend is also destroyed */
|
|
||||||
m_io_backend = m_backend->CreateHWStubIoBackend(new HWStubDevice(dev));
|
|
||||||
emit OnSelect(m_io_backend);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BackendSelector::ClearDevList()
|
|
||||||
{
|
|
||||||
while(m_dev_selector->count() > 0)
|
|
||||||
{
|
|
||||||
HWStubDevice *dev = reinterpret_cast< HWStubDevice* >(m_dev_selector->itemData(0).value< void* >());
|
|
||||||
delete dev;
|
|
||||||
m_dev_selector->removeItem(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
IoBackend *BackendSelector::GetBackend()
|
IoBackend *BackendSelector::GetBackend()
|
||||||
{
|
{
|
||||||
return m_io_backend;
|
return m_io_backend;
|
||||||
|
@ -1572,16 +1883,46 @@ void BackendSelector::ChangeBackend(IoBackend *new_backend)
|
||||||
m_io_backend = new_backend;
|
m_io_backend = new_backend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_HWSTUB
|
||||||
|
void BackendSelector::OnContextSelChanged(int index)
|
||||||
|
{
|
||||||
|
m_ctx_model->SetContext(m_ctx_manager->GetContext(index));
|
||||||
|
m_dev_selector->setCurrentIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackendSelector::OnDeviceSelChanged(int index)
|
||||||
|
{
|
||||||
|
/* if current selection is -1, because device was removed or a new context
|
||||||
|
* was selected, select entry 0, which is dummy. Not that this will not
|
||||||
|
* call activate(), we don't want to change the current backend if the user
|
||||||
|
* is using another type of backend. */
|
||||||
|
if(index == -1)
|
||||||
|
m_dev_selector->setCurrentIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackendSelector::OnDeviceSelActivated(int index)
|
||||||
|
{
|
||||||
|
auto dev = new HWStubDevice(m_ctx_model->GetDevice(index));
|
||||||
|
if(!dev->IsValid())
|
||||||
|
{
|
||||||
|
delete dev;
|
||||||
|
ChangeBackend(m_backend->CreateDummyIoBackend());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ChangeBackend(new HWStubIoBackend(dev));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* YTabWidget
|
* YTabWidget
|
||||||
*/
|
*/
|
||||||
YTabWidget::YTabWidget(QTabBar *bar, QWidget *parent)
|
YTabWidget::YTabWidget(QTabBar *bar, QWidget *parent)
|
||||||
:QTabWidget(parent)
|
:QTabWidget(parent), m_other_button(0)
|
||||||
{
|
{
|
||||||
if(bar != 0)
|
if(bar != 0)
|
||||||
setTabBar(bar);
|
setTabBar(bar);
|
||||||
m_tab_open_button = new QToolButton(this);
|
m_tab_open_button = new QToolButton(this);
|
||||||
m_tab_open_button->setIcon(QIcon::fromTheme("list-add"));
|
m_tab_open_button->setIcon(YIconManager::Get()->GetIcon(YIconManager::ListAdd));
|
||||||
m_tab_open_button->setAutoRaise(true);
|
m_tab_open_button->setAutoRaise(true);
|
||||||
m_tab_open_button->setPopupMode(QToolButton::InstantPopup);
|
m_tab_open_button->setPopupMode(QToolButton::InstantPopup);
|
||||||
/* the arrow with an icon only is pretty ugly and QToolButton has no way
|
/* the arrow with an icon only is pretty ugly and QToolButton has no way
|
||||||
|
@ -1592,8 +1933,8 @@ YTabWidget::YTabWidget(QTabBar *bar, QWidget *parent)
|
||||||
connect(m_tab_open_button, SIGNAL(clicked(bool)), this, SLOT(OnOpenButton(bool)));
|
connect(m_tab_open_button, SIGNAL(clicked(bool)), this, SLOT(OnOpenButton(bool)));
|
||||||
/* there is a quirk in the default QStyle: if the tab bar is empty, it
|
/* there is a quirk in the default QStyle: if the tab bar is empty, it
|
||||||
* returns the minimum size of the corner widget, which is 0 for tool buttons */
|
* returns the minimum size of the corner widget, which is 0 for tool buttons */
|
||||||
//setMinimumHeight(m_tab_open_button->height());
|
m_tab_open_button->setMinimumSize(m_tab_open_button->sizeHint());
|
||||||
//m_tab_open_button->setMinimumHeight(m_tab_open_button->sizeHint().height());
|
setMinimumSize(m_tab_open_button->sizeHint());
|
||||||
}
|
}
|
||||||
|
|
||||||
void YTabWidget::setTabOpenable(bool openable)
|
void YTabWidget::setTabOpenable(bool openable)
|
||||||
|
@ -1613,6 +1954,28 @@ void YTabWidget::setTabOpenMenu(QMenu *menu)
|
||||||
m_tab_open_button->setMenu(menu);
|
m_tab_open_button->setMenu(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void YTabWidget::setOtherMenu(QMenu *menu)
|
||||||
|
{
|
||||||
|
if(menu == nullptr)
|
||||||
|
{
|
||||||
|
if(m_other_button)
|
||||||
|
delete m_other_button;
|
||||||
|
m_other_button = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(m_other_button == nullptr)
|
||||||
|
{
|
||||||
|
m_other_button = new QToolButton(this);
|
||||||
|
m_other_button->setText("Menu");
|
||||||
|
m_other_button->setAutoRaise(true);
|
||||||
|
m_other_button->setPopupMode(QToolButton::InstantPopup);
|
||||||
|
setCornerWidget(m_other_button, Qt::TopRightCorner);
|
||||||
|
}
|
||||||
|
m_other_button->setMenu(menu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MessageWidget
|
* MessageWidget
|
||||||
*/
|
*/
|
||||||
|
@ -1625,6 +1988,7 @@ MessageWidget::MessageWidget(QWidget *parent)
|
||||||
m_icon->hide();
|
m_icon->hide();
|
||||||
m_text = new QLabel(this);
|
m_text = new QLabel(this);
|
||||||
m_text->setTextFormat(Qt::RichText);
|
m_text->setTextFormat(Qt::RichText);
|
||||||
|
m_text->setWordWrap(true);
|
||||||
m_close = new QToolButton(this);
|
m_close = new QToolButton(this);
|
||||||
m_close->setText("close");
|
m_close->setText("close");
|
||||||
m_close->setIcon(style()->standardIcon(QStyle::SP_DialogCloseButton));
|
m_close->setIcon(style()->standardIcon(QStyle::SP_DialogCloseButton));
|
||||||
|
@ -1702,6 +2066,102 @@ void MessageWidget::OnClose(bool clicked)
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* YIconManager
|
||||||
|
*/
|
||||||
|
YIconManager *YIconManager::m_singleton = nullptr;
|
||||||
|
|
||||||
|
YIconManager::YIconManager()
|
||||||
|
{
|
||||||
|
m_icon_name[ListAdd] = "list-add";
|
||||||
|
m_icon_name[ListRemove] = "list-remove";
|
||||||
|
m_icon_name[DocumentNew] = "document-new";
|
||||||
|
m_icon_name[DocumentEdit] = "document-edit";
|
||||||
|
m_icon_name[DocumentOpen] = "document-open";
|
||||||
|
m_icon_name[DocumentSave] = "document-save";
|
||||||
|
m_icon_name[DocumentSaveAs] = "document-save-as";
|
||||||
|
m_icon_name[Preferences] = "preferences-system";
|
||||||
|
m_icon_name[FolderNew] = "folder-new";
|
||||||
|
m_icon_name[Computer] = "computer";
|
||||||
|
m_icon_name[Cpu] = "cpu";
|
||||||
|
m_icon_name[DialogError] = "dialog-error";
|
||||||
|
m_icon_name[ViewRefresh] = "view-refresh";
|
||||||
|
m_icon_name[SytemRun] = "system-run";
|
||||||
|
m_icon_name[ApplicationExit] = "application-exit";
|
||||||
|
m_icon_name[HelpAbout] = "help-about";
|
||||||
|
m_icon_name[FormatTextBold] = "format-text-bold";
|
||||||
|
m_icon_name[FormatTextItalic] = "format-text-italic";
|
||||||
|
m_icon_name[FormatTextUnderline] = "format-text-underline";
|
||||||
|
m_icon_name[TextGeneric] = "text-x-generic";
|
||||||
|
m_icon_name[MultimediaPlayer] = "multimedia-player";
|
||||||
|
}
|
||||||
|
|
||||||
|
YIconManager::~YIconManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
YIconManager *YIconManager::Get()
|
||||||
|
{
|
||||||
|
if(m_singleton == nullptr)
|
||||||
|
m_singleton = new YIconManager();
|
||||||
|
return m_singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon YIconManager::GetIcon(IconType type)
|
||||||
|
{
|
||||||
|
if(type < 0 || type >= MaxIcon)
|
||||||
|
return QIcon();
|
||||||
|
if(QIcon::hasThemeIcon(m_icon_name[type]))
|
||||||
|
return QIcon::fromTheme(m_icon_name[type]);
|
||||||
|
/* render icon if needed */
|
||||||
|
if(m_icon[type].isNull())
|
||||||
|
Render(type);
|
||||||
|
return m_icon[type];
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void RenderListAdd(QIcon& icon)
|
||||||
|
{
|
||||||
|
QPixmap pix(64, 64);
|
||||||
|
pix.fill(Qt::transparent);
|
||||||
|
QPainter paint(&pix);
|
||||||
|
paint.fillRect(30, 12, 4, 40, QColor(255, 0, 0));
|
||||||
|
paint.fillRect(12, 30, 40, 4, QColor(255, 0, 0));
|
||||||
|
icon = QIcon(pix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderListRemove(QIcon& icon)
|
||||||
|
{
|
||||||
|
QPixmap pix(64, 64);
|
||||||
|
pix.fill(Qt::transparent);
|
||||||
|
QPainter paint(&pix);
|
||||||
|
paint.setPen(QColor(255, 0, 0));
|
||||||
|
paint.drawLine(12, 12, 52, 52);
|
||||||
|
paint.drawLine(12, 52, 52, 16);
|
||||||
|
icon = QIcon(pix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderUnknown(QIcon& icon)
|
||||||
|
{
|
||||||
|
QPixmap pix(64, 64);
|
||||||
|
pix.fill();
|
||||||
|
QPainter paint(&pix);
|
||||||
|
paint.fillRect(0, 0, 64, 64, QColor(255, 0, 0));
|
||||||
|
icon = QIcon(pix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void YIconManager::Render(IconType type)
|
||||||
|
{
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case ListAdd: RenderListAdd(m_icon[type]); break;
|
||||||
|
case ListRemove: RenderListRemove(m_icon[type]); break;
|
||||||
|
default: RenderUnknown(m_icon[type]); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Misc
|
* Misc
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
|
#include <QDebug>
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "backend.h"
|
#include "backend.h"
|
||||||
|
|
||||||
|
@ -180,6 +181,50 @@ protected:
|
||||||
soc_desc::field_t m_field;
|
soc_desc::field_t m_field;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(soc_desc::access_t)
|
||||||
|
|
||||||
|
class SocAccessItemDelegate: public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SocAccessItemDelegate(const QString& unspec_text, QObject *parent = 0)
|
||||||
|
:QStyledItemDelegate(parent), m_unspec_text(unspec_text) {}
|
||||||
|
|
||||||
|
virtual QString displayText(const QVariant& value, const QLocale& locale) const;
|
||||||
|
protected:
|
||||||
|
QString m_unspec_text;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SocAccessEditor : public QComboBox
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(soc_desc::access_t access READ access WRITE setAccess USER true)
|
||||||
|
public:
|
||||||
|
SocAccessEditor(const QString& unspec_text, QWidget *parent = 0);
|
||||||
|
virtual ~SocAccessEditor();
|
||||||
|
|
||||||
|
soc_desc::access_t access() const;
|
||||||
|
void setAccess(soc_desc::access_t acc);
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
/* bla */
|
||||||
|
|
||||||
|
protected:
|
||||||
|
soc_desc::access_t m_access;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SocAccessEditorCreator : public QItemEditorCreatorBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SocAccessEditorCreator(const QString& unspec_text = "Unspecified")
|
||||||
|
:m_unspec_text(unspec_text) {}
|
||||||
|
|
||||||
|
virtual QWidget *createWidget(QWidget *parent) const;
|
||||||
|
virtual QByteArray valuePropertyName() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QString m_unspec_text;
|
||||||
|
};
|
||||||
|
|
||||||
class SocFieldCachedValue
|
class SocFieldCachedValue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -209,8 +254,11 @@ public:
|
||||||
SocFieldBitRange(int first, int last):m_first_bit(first), m_last_bit(last) {}
|
SocFieldBitRange(int first, int last):m_first_bit(first), m_last_bit(last) {}
|
||||||
unsigned GetFirstBit() const { return m_first_bit; }
|
unsigned GetFirstBit() const { return m_first_bit; }
|
||||||
unsigned GetLastBit() const { return m_last_bit; }
|
unsigned GetLastBit() const { return m_last_bit; }
|
||||||
|
void SetFirstBit(unsigned bit) { m_first_bit = bit; }
|
||||||
|
void SetLastBit(unsigned bit) { m_last_bit = bit; }
|
||||||
|
|
||||||
bool operator<(const SocFieldBitRange& o) const;
|
bool operator<(const SocFieldBitRange& o) const;
|
||||||
|
bool operator!=(const SocFieldBitRange& o) const;
|
||||||
protected:
|
protected:
|
||||||
unsigned m_first_bit, m_last_bit;
|
unsigned m_first_bit, m_last_bit;
|
||||||
};
|
};
|
||||||
|
@ -301,6 +349,7 @@ public:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void OnValueModified(int index);
|
void OnValueModified(int index);
|
||||||
|
void OnBitrangeModified(int index);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void RecomputeTheme();
|
void RecomputeTheme();
|
||||||
|
@ -337,19 +386,79 @@ protected:
|
||||||
bool lessThan(const QModelIndex& left, const QModelIndex& right) const;
|
bool lessThan(const QModelIndex& left, const QModelIndex& right) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class YRegDisplay;
|
||||||
|
class YRegDisplayItemDelegate;
|
||||||
|
|
||||||
|
class YRegDisplayItemEditor : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
YRegDisplayItemEditor(QWidget *parent, YRegDisplay *display,
|
||||||
|
YRegDisplayItemDelegate *delegate, QModelIndex bitrange_index,
|
||||||
|
QModelIndex name_index);
|
||||||
|
virtual ~YRegDisplayItemEditor();
|
||||||
|
void setEditorData(QModelIndex bitrange_index, QModelIndex name_index);
|
||||||
|
void getEditorData(QVariant& name, QVariant& birange);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void paintEvent(QPaintEvent *event);
|
||||||
|
virtual void mouseMoveEvent(QMouseEvent *event);
|
||||||
|
virtual void mousePressEvent(QMouseEvent *event);
|
||||||
|
virtual void mouseReleaseEvent(QMouseEvent *event);
|
||||||
|
virtual void leaveEvent(QEvent *event);
|
||||||
|
|
||||||
|
enum Zone
|
||||||
|
{
|
||||||
|
NoZone,
|
||||||
|
MoveZone,
|
||||||
|
ResizeLeftZone,
|
||||||
|
ResizeRightZone
|
||||||
|
};
|
||||||
|
|
||||||
|
Zone GetZone(const QPoint& pt);
|
||||||
|
|
||||||
|
YRegDisplayItemDelegate *m_display_delegate;
|
||||||
|
YRegDisplay *m_display;
|
||||||
|
QModelIndex m_bitrange_index, m_name_index;
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Idle,
|
||||||
|
InResizeZone,
|
||||||
|
InMoveZone,
|
||||||
|
Moving,
|
||||||
|
ResizingLeft,
|
||||||
|
ResizingRight,
|
||||||
|
}m_state;
|
||||||
|
int m_col_width;
|
||||||
|
int m_resize_margin;
|
||||||
|
int m_move_offset;
|
||||||
|
SocFieldBitRange m_bitrange;
|
||||||
|
};
|
||||||
|
|
||||||
class YRegDisplayItemDelegate : public QStyledItemDelegate
|
class YRegDisplayItemDelegate : public QStyledItemDelegate
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
friend class YRegDisplayItemEditor;
|
||||||
public:
|
public:
|
||||||
YRegDisplayItemDelegate(QObject *parent = 0);
|
YRegDisplayItemDelegate(QObject *parent = 0);
|
||||||
virtual void paint(QPainter * painter, const QStyleOptionViewItem& option,
|
virtual void paint(QPainter *painter, const QStyleOptionViewItem& option,
|
||||||
const QModelIndex & index) const;
|
const QModelIndex& index) const;
|
||||||
|
virtual void MyPaint(QPainter *painter, const QStyleOptionViewItemV4& option) const;
|
||||||
virtual QSize sizeHint(const QStyleOptionViewItem& option,
|
virtual QSize sizeHint(const QStyleOptionViewItem& option,
|
||||||
const QModelIndex & index) const;
|
const QModelIndex& index) const;
|
||||||
|
/* don't bother using the item factory and such, we only use this delegate
|
||||||
|
* for very specific models anyway */
|
||||||
|
virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option,
|
||||||
|
const QModelIndex& index) const;
|
||||||
|
virtual void setEditorData(QWidget *editor, const QModelIndex& index) const;
|
||||||
|
virtual void setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||||
|
const QModelIndex& index) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class YRegDisplay : public QAbstractItemView
|
class YRegDisplay : public QAbstractItemView
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
friend class YRegDisplayItemEditor;
|
||||||
public:
|
public:
|
||||||
YRegDisplay(QWidget *parent = 0);
|
YRegDisplay(QWidget *parent = 0);
|
||||||
virtual QModelIndex indexAt(const QPoint& point) const;
|
virtual QModelIndex indexAt(const QPoint& point) const;
|
||||||
|
@ -360,6 +469,8 @@ public:
|
||||||
void setWidth(int nr_bits);
|
void setWidth(int nr_bits);
|
||||||
/* returns the bit column at a point, or -1 if none except if closest=true */
|
/* returns the bit column at a point, or -1 if none except if closest=true */
|
||||||
int bitColumnAt(const QPoint& point, bool closest = true) const;
|
int bitColumnAt(const QPoint& point, bool closest = true) const;
|
||||||
|
/* return rect for a bitrange */
|
||||||
|
QRect BitrangeRect(const SocFieldBitRange& range) const;
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
virtual void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
virtual void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
@ -509,18 +620,20 @@ protected:
|
||||||
QLineEdit *m_data_sel_edit;
|
QLineEdit *m_data_sel_edit;
|
||||||
#ifdef HAVE_HWSTUB
|
#ifdef HAVE_HWSTUB
|
||||||
QComboBox *m_dev_selector;
|
QComboBox *m_dev_selector;
|
||||||
HWStubBackendHelper m_hwstub_helper;
|
QComboBox *m_ctx_selector;
|
||||||
|
QPushButton *m_ctx_manage_button;
|
||||||
|
HWStubContextModel *m_ctx_model;
|
||||||
|
HWStubManager *m_ctx_manager;
|
||||||
#endif
|
#endif
|
||||||
QLabel *m_nothing_text;
|
QLabel *m_nothing_text;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
#ifdef HAVE_HWSTUB
|
|
||||||
void OnDevListChanged();
|
|
||||||
void OnDevChanged(int index);
|
|
||||||
void OnDevListChanged2(bool, struct libusb_device *);
|
|
||||||
void ClearDevList();
|
|
||||||
#endif
|
|
||||||
void OnDataSelChanged(int index);
|
void OnDataSelChanged(int index);
|
||||||
|
#ifdef HAVE_HWSTUB
|
||||||
|
void OnContextSelChanged(int index);
|
||||||
|
void OnDeviceSelChanged(int index);
|
||||||
|
void OnDeviceSelActivated(int index);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class MessageWidget : public QFrame
|
class MessageWidget : public QFrame
|
||||||
|
@ -567,6 +680,7 @@ public:
|
||||||
inline bool tabOpenable() const { return m_tab_openable; }
|
inline bool tabOpenable() const { return m_tab_openable; }
|
||||||
void setTabOpenable(bool openable);
|
void setTabOpenable(bool openable);
|
||||||
void setTabOpenMenu(QMenu *menu);
|
void setTabOpenMenu(QMenu *menu);
|
||||||
|
void setOtherMenu(QMenu *menu);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void tabOpenRequested();
|
void tabOpenRequested();
|
||||||
|
@ -577,6 +691,52 @@ protected slots:
|
||||||
protected:
|
protected:
|
||||||
bool m_tab_openable;
|
bool m_tab_openable;
|
||||||
QToolButton *m_tab_open_button;
|
QToolButton *m_tab_open_button;
|
||||||
|
QToolButton *m_other_button;
|
||||||
|
};
|
||||||
|
|
||||||
|
class YIconManager : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
protected:
|
||||||
|
YIconManager();
|
||||||
|
public:
|
||||||
|
virtual ~YIconManager();
|
||||||
|
/* list of icons */
|
||||||
|
enum IconType
|
||||||
|
{
|
||||||
|
ListAdd = 0,
|
||||||
|
ListRemove,
|
||||||
|
DocumentNew,
|
||||||
|
DocumentEdit,
|
||||||
|
DocumentOpen,
|
||||||
|
DocumentSave,
|
||||||
|
DocumentSaveAs,
|
||||||
|
Preferences,
|
||||||
|
FolderNew,
|
||||||
|
Computer,
|
||||||
|
Cpu,
|
||||||
|
DialogError,
|
||||||
|
ViewRefresh,
|
||||||
|
SytemRun,
|
||||||
|
ApplicationExit,
|
||||||
|
HelpAbout,
|
||||||
|
FormatTextBold,
|
||||||
|
FormatTextItalic,
|
||||||
|
FormatTextUnderline,
|
||||||
|
TextGeneric,
|
||||||
|
MultimediaPlayer,
|
||||||
|
MaxIcon
|
||||||
|
};
|
||||||
|
/* return instance */
|
||||||
|
static YIconManager *Get();
|
||||||
|
QIcon GetIcon(IconType it);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void Render(IconType type);
|
||||||
|
|
||||||
|
static YIconManager *m_singleton; // single instance
|
||||||
|
QIcon m_icon[MaxIcon]; /* list add icon */
|
||||||
|
QString m_icon_name[MaxIcon]; /* icon name from theme */
|
||||||
};
|
};
|
||||||
|
|
||||||
class Misc
|
class Misc
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue