##// END OF EJS Templates
Fix the close button on the graphs and multi selection in the same graph
Fix the close button on the graphs and multi selection in the same graph

File last commit:

r1077:c90049fe7bc2
r1094:f391b1d9fb19
Show More
DataSourceTreeWidgetItem.cpp
225 lines | 6.9 KiB | text/x-c | CppLexer
/ gui / src / DataSource / DataSourceTreeWidgetItem.cpp
#include <DataSource/DataSourceItem.h>
#include <DataSource/DataSourceItemAction.h>
#include <DataSource/DataSourceTreeWidgetItem.h>
#include <QAction>
Q_LOGGING_CATEGORY(LOG_DataSourceTreeWidgetItem, "DataSourceTreeWidgetItem")
namespace {
// Column indexes
const auto NAME_COLUMN = 0;
/**
* Generates the full name of an item.
*
* The full name of an item is its name possibly suffixed by the name of its plugin, in case there
* are items of the same name in its relatives
* @param item the item for which to generate the complete name
* @return the complete name of the item
*/
QString completeName(const DataSourceItem &item)
{
auto name = item.name();
if (item.type() == DataSourceItemType::NODE) {
return name;
}
auto parentItem = item.parentItem();
if (!parentItem) {
return name;
}
// Finds in item's relatives items that have the same name
bool foundSameName = false;
for (auto i = 0, count = parentItem->childCount(); i < count && !foundSameName; ++i) {
auto child = parentItem->child(i);
foundSameName = child != &item
&& QString::compare(child->name(), item.name(), Qt::CaseInsensitive) == 0;
}
// If the name of the item is not unique, it is completed by the plugin suffix
return foundSameName
? QString{"%1 (%2)"}.arg(name, item.data(DataSourceItem::PLUGIN_DATA_KEY).toString())
: name;
}
QIcon itemIcon(const DataSourceItem *dataSource)
{
if (dataSource) {
auto dataSourceType = dataSource->type();
switch (dataSourceType) {
case DataSourceItemType::NODE: {
return dataSource->isRoot() ? QIcon{":/icones/dataSourceRoot.png"}
: QIcon{":/icones/dataSourceNode.png"};
}
case DataSourceItemType::PRODUCT:
return QIcon{":/icones/dataSourceProduct.png"};
case DataSourceItemType::COMPONENT:
return QIcon{":/icones/dataSourceComponent.png"};
default:
// No action
break;
}
qCWarning(LOG_DataSourceTreeWidgetItem())
<< QObject::tr("Can't set data source icon : unknown data source type");
}
else {
qCCritical(LOG_DataSourceTreeWidgetItem())
<< QObject::tr("Can't set data source icon : the data source is null");
}
// Default cases
return QIcon{};
}
/// @return the tooltip text for a variant. The text depends on whether the data is a simple variant
/// or a list of variants
QString tooltipValue(const QVariant &variant) noexcept
{
// If the variant is a list of variants, the text of the tooltip is of the form: {val1, val2,
// ...}
if (variant.canConvert<QVariantList>()) {
auto valueString = QStringLiteral("{");
auto variantList = variant.value<QVariantList>();
for (auto it = variantList.cbegin(), end = variantList.cend(); it != end; ++it) {
valueString.append(it->toString());
if (std::distance(it, end) != 1) {
valueString.append(", ");
}
}
valueString.append(QStringLiteral("}"));
return valueString;
}
else {
return variant.toString();
}
}
QString itemTooltip(const DataSourceItem *dataSource) noexcept
{
// The tooltip displays all item's data
if (dataSource) {
auto result = QString{};
const auto &data = dataSource->data();
for (auto it = data.cbegin(), end = data.cend(); it != end; ++it) {
result.append(QString{"<b>%1:</b> %2<br/>"}.arg(it.key(), tooltipValue(it.value())));
}
return result;
}
else {
qCCritical(LOG_DataSourceTreeWidgetItem())
<< QObject::tr("Can't set data source tooltip : the data source is null");
return QString{};
}
}
} // namespace
struct DataSourceTreeWidgetItem::DataSourceTreeWidgetItemPrivate {
explicit DataSourceTreeWidgetItemPrivate(const DataSourceItem *data)
: m_Data{data}, m_Name{completeName(*m_Data)}
{
}
/// Model used to retrieve data source information
const DataSourceItem *m_Data;
/// Name displayed
QString m_Name;
/// Actions associated to the item. The parent of the item (QTreeWidget) takes the ownership of
/// the actions
QList<QAction *> m_Actions;
};
DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(const DataSourceItem *data, int type)
: DataSourceTreeWidgetItem{nullptr, data, type}
{
}
DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(QTreeWidget *parent, const DataSourceItem *data,
int type)
: QTreeWidgetItem{parent, type},
impl{spimpl::make_unique_impl<DataSourceTreeWidgetItemPrivate>(data)}
{
// Sets the icon and the tooltip depending on the data source
setIcon(0, itemIcon(impl->m_Data));
setToolTip(0, itemTooltip(impl->m_Data));
// Generates tree actions based on the item actions
auto createTreeAction = [this, &parent](const auto &itemAction) {
auto treeAction = new QAction{itemAction->name(), parent};
// Executes item action when tree action is triggered
QObject::connect(treeAction, &QAction::triggered, itemAction,
&DataSourceItemAction::execute);
return treeAction;
};
auto itemActions = impl->m_Data->actions();
std::transform(std::cbegin(itemActions), std::cend(itemActions),
std::back_inserter(impl->m_Actions), createTreeAction);
// Sets the flags of the items
auto flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
if (data->type() == DataSourceItemType::COMPONENT
|| data->type() == DataSourceItemType::PRODUCT) {
flags |= Qt::ItemIsDragEnabled;
}
setFlags(flags);
}
const DataSourceItem *DataSourceTreeWidgetItem::data() const
{
return impl->m_Data;
}
QVariant DataSourceTreeWidgetItem::data(int column, int role) const
{
if (role == Qt::DisplayRole) {
if (impl->m_Data) {
switch (column) {
case NAME_COLUMN:
return impl->m_Name;
default:
// No action
break;
}
qCWarning(LOG_DataSourceTreeWidgetItem())
<< QObject::tr("Can't get data (unknown column %1)").arg(column);
}
else {
qCCritical(LOG_DataSourceTreeWidgetItem()) << QObject::tr("Can't get data (null item)");
}
return QVariant{};
}
else {
return QTreeWidgetItem::data(column, role);
}
}
void DataSourceTreeWidgetItem::setData(int column, int role, const QVariant &value)
{
// Data can't be changed by edition
if (role != Qt::EditRole) {
QTreeWidgetItem::setData(column, role, value);
}
}
QList<QAction *> DataSourceTreeWidgetItem::actions() const noexcept
{
return impl->m_Actions;
}