2013-02-17 16:27:25 +00:00
|
|
|
#include "enumdelegate.hpp"
|
|
|
|
|
2013-03-23 12:13:34 +00:00
|
|
|
#include <cassert>
|
2022-10-19 17:02:00 +00:00
|
|
|
#include <memory>
|
2013-02-17 16:27:25 +00:00
|
|
|
|
|
|
|
#include <QApplication>
|
|
|
|
#include <QComboBox>
|
|
|
|
|
|
|
|
#include "../../model/world/commands.hpp"
|
|
|
|
|
2022-10-19 17:02:00 +00:00
|
|
|
#include <apps/opencs/view/world/util.hpp>
|
|
|
|
|
2015-06-16 12:39:54 +00:00
|
|
|
int CSVWorld::EnumDelegate::getValueIndex(const QModelIndex& index, int role) const
|
|
|
|
{
|
|
|
|
if (index.isValid() && index.data(role).isValid())
|
|
|
|
{
|
|
|
|
int value = index.data(role).toInt();
|
|
|
|
|
|
|
|
int size = static_cast<int>(mValues.size());
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
|
|
{
|
|
|
|
if (value == mValues.at(i).first)
|
|
|
|
{
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-02-17 16:27:25 +00:00
|
|
|
void CSVWorld::EnumDelegate::setModelDataImp(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
|
|
|
|
{
|
2014-03-11 17:38:37 +00:00
|
|
|
if (QComboBox* comboBox = dynamic_cast<QComboBox*>(editor))
|
2013-02-17 16:27:25 +00:00
|
|
|
{
|
|
|
|
QString value = comboBox->currentText();
|
|
|
|
|
|
|
|
for (std::vector<std::pair<int, QString>>::const_iterator iter(mValues.begin()); iter != mValues.end(); ++iter)
|
|
|
|
if (iter->second == value)
|
|
|
|
{
|
2015-04-17 21:13:02 +00:00
|
|
|
// do nothing if the value has not changed
|
|
|
|
if (model->data(index).toInt() != iter->first)
|
|
|
|
addCommands(model, index, iter->first);
|
2013-02-17 16:27:25 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSVWorld::EnumDelegate::addCommands(QAbstractItemModel* model, const QModelIndex& index, int type) const
|
|
|
|
{
|
|
|
|
getUndoStack().push(new CSMWorld::ModifyCommand(*model, index, type));
|
|
|
|
}
|
|
|
|
|
|
|
|
CSVWorld::EnumDelegate::EnumDelegate(const std::vector<std::pair<int, QString>>& values,
|
2015-01-15 13:24:33 +00:00
|
|
|
CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent)
|
|
|
|
: CommandDelegate(dispatcher, document, parent)
|
|
|
|
, mValues(values)
|
2013-02-17 16:27:25 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-03-11 17:38:37 +00:00
|
|
|
QWidget* CSVWorld::EnumDelegate::createEditor(
|
|
|
|
QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
2013-02-17 16:27:25 +00:00
|
|
|
{
|
2014-03-11 17:38:37 +00:00
|
|
|
return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_None);
|
2013-02-17 16:27:25 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 08:38:53 +00:00
|
|
|
QWidget* CSVWorld::EnumDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option,
|
2014-03-11 17:38:37 +00:00
|
|
|
const QModelIndex& index, CSMWorld::ColumnBase::Display display) const
|
2014-03-11 08:38:53 +00:00
|
|
|
{
|
2014-03-11 17:38:37 +00:00
|
|
|
if (!index.data(Qt::EditRole).isValid() && !index.data(Qt::DisplayRole).isValid())
|
2020-11-13 07:39:47 +00:00
|
|
|
return nullptr;
|
2014-03-11 08:38:53 +00:00
|
|
|
|
|
|
|
QComboBox* comboBox = new QComboBox(parent);
|
2022-09-22 18:26:05 +00:00
|
|
|
|
2014-03-11 08:38:53 +00:00
|
|
|
for (std::vector<std::pair<int, QString>>::const_iterator iter(mValues.begin()); iter != mValues.end(); ++iter)
|
|
|
|
comboBox->addItem(iter->second);
|
|
|
|
|
2021-10-03 19:13:51 +00:00
|
|
|
comboBox->setMaxVisibleItems(20);
|
2014-03-11 08:38:53 +00:00
|
|
|
|
|
|
|
return comboBox;
|
|
|
|
}
|
|
|
|
|
2014-03-10 08:47:41 +00:00
|
|
|
void CSVWorld::EnumDelegate::setEditorData(QWidget* editor, const QModelIndex& index, bool tryDisplay) const
|
2013-02-17 16:27:25 +00:00
|
|
|
{
|
2015-06-16 12:39:54 +00:00
|
|
|
if (QComboBox* comboBox = dynamic_cast<QComboBox*>(editor))
|
2013-02-17 16:27:25 +00:00
|
|
|
{
|
2015-06-16 12:39:54 +00:00
|
|
|
int role = Qt::EditRole;
|
|
|
|
if (tryDisplay && !index.data(role).isValid())
|
2014-03-08 15:54:05 +00:00
|
|
|
{
|
2015-06-16 12:39:54 +00:00
|
|
|
role = Qt::DisplayRole;
|
|
|
|
if (!index.data(role).isValid())
|
2014-03-10 08:37:53 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2014-03-08 15:54:05 +00:00
|
|
|
}
|
|
|
|
|
2015-06-16 12:39:54 +00:00
|
|
|
int valueIndex = getValueIndex(index, role);
|
|
|
|
if (valueIndex != -1)
|
|
|
|
{
|
|
|
|
comboBox->setCurrentIndex(valueIndex);
|
|
|
|
}
|
2013-02-17 16:27:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSVWorld::EnumDelegate::paint(
|
|
|
|
QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
|
|
|
{
|
2015-06-16 12:39:54 +00:00
|
|
|
int valueIndex = getValueIndex(index);
|
2020-06-22 11:48:35 +00:00
|
|
|
if (valueIndex != -1)
|
|
|
|
{
|
2018-06-28 07:13:32 +00:00
|
|
|
QStyleOptionViewItem itemOption(option);
|
2015-06-16 12:39:54 +00:00
|
|
|
itemOption.text = mValues.at(valueIndex).second;
|
|
|
|
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &itemOption, painter);
|
2013-05-13 10:51:27 +00:00
|
|
|
}
|
2013-02-17 16:27:25 +00:00
|
|
|
}
|
|
|
|
|
2015-06-16 11:18:47 +00:00
|
|
|
QSize CSVWorld::EnumDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
|
|
|
|
{
|
2015-06-16 12:39:54 +00:00
|
|
|
int valueIndex = getValueIndex(index);
|
|
|
|
if (valueIndex != -1)
|
2015-06-16 11:18:47 +00:00
|
|
|
{
|
|
|
|
// Calculate the size hint as for a combobox.
|
|
|
|
// So, the whole text is visible (isn't elided) when the editor is created
|
|
|
|
QStyleOptionComboBox itemOption;
|
|
|
|
itemOption.fontMetrics = option.fontMetrics;
|
|
|
|
itemOption.palette = option.palette;
|
|
|
|
itemOption.rect = option.rect;
|
|
|
|
itemOption.state = option.state;
|
|
|
|
|
2015-06-16 12:39:54 +00:00
|
|
|
const QString& valueText = mValues.at(valueIndex).second;
|
2019-11-28 04:34:18 +00:00
|
|
|
QSize valueSize = QSize(itemOption.fontMetrics.horizontalAdvance(valueText), itemOption.fontMetrics.height());
|
2015-06-16 12:39:54 +00:00
|
|
|
itemOption.currentText = valueText;
|
|
|
|
return QApplication::style()->sizeFromContents(QStyle::CT_ComboBox, &itemOption, valueSize);
|
2015-06-16 11:18:47 +00:00
|
|
|
}
|
|
|
|
return option.rect.size();
|
|
|
|
}
|
2013-02-17 16:27:25 +00:00
|
|
|
|
2013-04-02 12:15:22 +00:00
|
|
|
CSVWorld::EnumDelegateFactory::EnumDelegateFactory(const char** names, bool allowNone)
|
2013-03-23 12:13:34 +00:00
|
|
|
{
|
|
|
|
assert(names);
|
|
|
|
|
2013-04-02 12:15:22 +00:00
|
|
|
if (allowNone)
|
|
|
|
add(-1, "");
|
|
|
|
|
2013-03-23 12:13:34 +00:00
|
|
|
for (int i = 0; names[i]; ++i)
|
|
|
|
add(i, names[i]);
|
|
|
|
}
|
|
|
|
|
2019-01-22 06:08:48 +00:00
|
|
|
CSVWorld::EnumDelegateFactory::EnumDelegateFactory(
|
|
|
|
const std::vector<std::pair<int, std::string>>& names, bool allowNone)
|
2013-09-02 09:58:05 +00:00
|
|
|
{
|
|
|
|
if (allowNone)
|
|
|
|
add(-1, "");
|
|
|
|
|
|
|
|
int size = static_cast<int>(names.size());
|
|
|
|
|
|
|
|
for (int i = 0; i < size; ++i)
|
2019-01-22 06:08:48 +00:00
|
|
|
add(names[i].first, names[i].second.c_str());
|
2013-09-02 09:58:05 +00:00
|
|
|
}
|
|
|
|
|
2014-08-23 10:25:12 +00:00
|
|
|
CSVWorld::CommandDelegate* CSVWorld::EnumDelegateFactory::makeDelegate(
|
2015-01-15 13:24:33 +00:00
|
|
|
CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) const
|
2013-02-17 16:27:25 +00:00
|
|
|
{
|
2015-01-15 13:24:33 +00:00
|
|
|
return new EnumDelegate(mValues, dispatcher, document, parent);
|
2013-02-17 16:27:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CSVWorld::EnumDelegateFactory::add(int value, const QString& name)
|
|
|
|
{
|
2018-07-02 22:52:23 +00:00
|
|
|
auto pair = std::make_pair(value, name);
|
|
|
|
|
|
|
|
for (auto it = mValues.begin(); it != mValues.end(); ++it)
|
|
|
|
{
|
|
|
|
if (it->second > name)
|
|
|
|
{
|
|
|
|
mValues.insert(it, pair);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-17 08:26:35 +00:00
|
|
|
mValues.emplace_back(value, name);
|
2013-02-17 16:27:25 +00:00
|
|
|
}
|