2012-12-13 12:35:08 +00:00
|
|
|
|
|
|
|
#include "dialoguesubview.hpp"
|
|
|
|
|
2014-03-07 16:15:43 +00:00
|
|
|
#include <utility>
|
|
|
|
#include <memory>
|
|
|
|
|
2012-12-30 13:01:52 +00:00
|
|
|
#include <QGridLayout>
|
|
|
|
#include <QLabel>
|
2014-03-07 16:15:43 +00:00
|
|
|
#include <QSize>
|
2013-03-21 09:07:25 +00:00
|
|
|
#include <QAbstractItemModel>
|
2013-01-08 13:59:40 +00:00
|
|
|
#include <QDoubleSpinBox>
|
|
|
|
#include <QSpinBox>
|
|
|
|
#include <QLineEdit>
|
2014-03-07 16:15:43 +00:00
|
|
|
#include <QEvent>
|
2013-01-08 13:59:40 +00:00
|
|
|
#include <QDataWidgetMapper>
|
2014-03-10 13:11:49 +00:00
|
|
|
#include <QCheckBox>
|
|
|
|
#include <QLineEdit>
|
|
|
|
#include <QPlainTextEdit>
|
|
|
|
#include <QComboBox>
|
2012-12-30 13:01:52 +00:00
|
|
|
|
|
|
|
#include "../../model/world/columnbase.hpp"
|
2013-01-19 13:29:14 +00:00
|
|
|
#include "../../model/world/idtable.hpp"
|
2014-03-08 14:27:43 +00:00
|
|
|
#include "../../model/world/columns.hpp"
|
2012-12-30 13:01:52 +00:00
|
|
|
|
2014-03-06 19:10:13 +00:00
|
|
|
#include "recordstatusdelegate.hpp"
|
|
|
|
#include "util.hpp"
|
|
|
|
|
2014-03-07 21:17:40 +00:00
|
|
|
/*
|
|
|
|
==============================DialogueDelegateDispatcherProxy==========================================
|
|
|
|
*/
|
2014-03-08 14:10:55 +00:00
|
|
|
CSVWorld::DialogueDelegateDispatcherProxy::refWrapper::refWrapper(const QModelIndex& index) :
|
2014-03-07 21:17:40 +00:00
|
|
|
mIndex(index)
|
|
|
|
{}
|
|
|
|
|
|
|
|
CSVWorld::DialogueDelegateDispatcherProxy::DialogueDelegateDispatcherProxy(QWidget* editor, CSMWorld::ColumnBase::Display display) :
|
|
|
|
mEditor(editor),
|
|
|
|
mDisplay(display),
|
|
|
|
mIndexWrapper(NULL)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSVWorld::DialogueDelegateDispatcherProxy::editorDataCommited()
|
|
|
|
{
|
2014-03-08 15:50:42 +00:00
|
|
|
if (mIndexWrapper.get())
|
|
|
|
{
|
|
|
|
emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay);
|
|
|
|
}
|
2014-03-07 21:17:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CSVWorld::DialogueDelegateDispatcherProxy::setIndex(const QModelIndex& index)
|
|
|
|
{
|
|
|
|
mIndexWrapper.reset(new refWrapper(index));
|
|
|
|
}
|
|
|
|
|
|
|
|
QWidget* CSVWorld::DialogueDelegateDispatcherProxy::getEditor() const
|
|
|
|
{
|
|
|
|
return mEditor;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
==============================DialogueDelegateDispatcher==========================================
|
|
|
|
*/
|
|
|
|
|
2014-03-07 16:15:43 +00:00
|
|
|
CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, QUndoStack& undoStack) :
|
|
|
|
mParent(parent),
|
|
|
|
mTable(table),
|
|
|
|
mUndoStack(undoStack)
|
2014-03-07 21:17:40 +00:00
|
|
|
{
|
|
|
|
}
|
2014-03-07 16:15:43 +00:00
|
|
|
|
|
|
|
CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CSMWorld::ColumnBase::Display display)
|
|
|
|
{
|
|
|
|
CommandDelegate *delegate = NULL;
|
|
|
|
std::map<int, CommandDelegate*>::const_iterator delegateIt(mDelegates.find(display));
|
|
|
|
if (delegateIt == mDelegates.end())
|
|
|
|
{
|
|
|
|
delegate = CommandDelegateFactoryCollection::get().makeDelegate (
|
|
|
|
display, mUndoStack, mParent);
|
|
|
|
mDelegates.insert(std::make_pair<int, CommandDelegate*>(display, delegate));
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
delegate = delegateIt->second;
|
|
|
|
}
|
|
|
|
return delegate;
|
|
|
|
}
|
|
|
|
|
2014-03-07 21:17:40 +00:00
|
|
|
void CSVWorld::DialogueDelegateDispatcher::editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display)
|
2014-03-07 16:15:43 +00:00
|
|
|
{
|
2014-03-07 21:17:40 +00:00
|
|
|
setModelData(editor, mTable, index, display);
|
2014-03-07 16:15:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CSVWorld::DialogueDelegateDispatcher::setEditorData (QWidget* editor, const QModelIndex& index) const
|
|
|
|
{
|
|
|
|
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display>
|
|
|
|
(mTable->headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
|
|
|
|
2014-03-10 16:52:45 +00:00
|
|
|
QLabel* label = qobject_cast<QLabel*>(editor);
|
|
|
|
if(label)
|
|
|
|
{
|
|
|
|
QVariant v = index.data(Qt::EditRole);
|
|
|
|
if (!v.isValid())
|
|
|
|
{
|
|
|
|
v = index.data(Qt::DisplayRole);
|
|
|
|
if (!v.isValid())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (CSMWorld::Columns::hasEnums(static_cast<CSMWorld::Columns::ColumnId>(mTable->getColumnId(index.column()))))
|
|
|
|
{
|
|
|
|
int data = v.toInt();
|
|
|
|
std::vector<std::string> enumNames (CSMWorld::Columns::getEnums (static_cast<CSMWorld::Columns::ColumnId> (mTable->getColumnId (index.column()))));
|
|
|
|
label->setText(QString::fromUtf8(enumNames.at(data).c_str()));
|
|
|
|
} else
|
|
|
|
{
|
2014-03-10 16:57:40 +00:00
|
|
|
if (QVariant::String == v.type())
|
|
|
|
{
|
|
|
|
label->setText(v.toString());
|
|
|
|
}
|
2014-03-10 16:52:45 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-07 16:15:43 +00:00
|
|
|
std::map<int, CommandDelegate*>::const_iterator delegateIt(mDelegates.find(display));
|
|
|
|
if (delegateIt != mDelegates.end())
|
|
|
|
{
|
2014-03-10 08:47:41 +00:00
|
|
|
delegateIt->second->setEditorData(editor, index, true);
|
2014-03-07 16:15:43 +00:00
|
|
|
}
|
2014-03-07 21:17:40 +00:00
|
|
|
|
|
|
|
for (unsigned i = 0; i < mProxys.size(); ++i)
|
|
|
|
{
|
|
|
|
if (mProxys[i]->getEditor() == editor)
|
|
|
|
{
|
|
|
|
mProxys[i]->setIndex(index);
|
|
|
|
}
|
|
|
|
}
|
2014-03-07 16:15:43 +00:00
|
|
|
}
|
|
|
|
|
2014-03-07 21:17:40 +00:00
|
|
|
void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const
|
2014-03-07 16:15:43 +00:00
|
|
|
{
|
|
|
|
std::map<int, CommandDelegate*>::const_iterator delegateIt(mDelegates.find(display));
|
|
|
|
if (delegateIt != mDelegates.end())
|
|
|
|
{
|
|
|
|
delegateIt->second->setModelData(editor, model, index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSVWorld::DialogueDelegateDispatcher::paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
|
|
|
{
|
|
|
|
//Does nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
QSize CSVWorld::DialogueDelegateDispatcher::sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const
|
|
|
|
{
|
|
|
|
return QSize(); //silencing warning, otherwise does nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index)
|
|
|
|
{
|
2014-03-10 12:25:01 +00:00
|
|
|
QVariant variant = index.data();
|
|
|
|
if (!variant.isValid())
|
2014-03-08 15:50:42 +00:00
|
|
|
{
|
2014-03-10 12:25:01 +00:00
|
|
|
variant = index.data(Qt::DisplayRole);
|
|
|
|
if (!variant.isValid())
|
|
|
|
{
|
2014-03-10 13:11:49 +00:00
|
|
|
return NULL;
|
2014-03-10 12:25:01 +00:00
|
|
|
}
|
2014-03-08 15:50:42 +00:00
|
|
|
}
|
|
|
|
|
2014-03-07 16:15:43 +00:00
|
|
|
QWidget* editor = NULL;
|
2014-03-10 16:52:45 +00:00
|
|
|
if (! (mTable->flags (index) & Qt::ItemIsEditable))
|
|
|
|
{
|
|
|
|
editor = new QLabel(qobject_cast<QWidget*>(mParent));
|
|
|
|
return editor;
|
|
|
|
}
|
|
|
|
|
2014-03-07 16:15:43 +00:00
|
|
|
std::map<int, CommandDelegate*>::iterator delegateIt(mDelegates.find(display));
|
|
|
|
if (delegateIt != mDelegates.end())
|
|
|
|
{
|
2014-03-10 16:52:45 +00:00
|
|
|
editor = delegateIt->second->createEditor(qobject_cast<QWidget*>(mParent), QStyleOptionViewItem(), index, display);
|
2014-03-07 21:17:40 +00:00
|
|
|
DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display);
|
2014-03-10 13:11:49 +00:00
|
|
|
|
|
|
|
bool skip = false;
|
|
|
|
if (qobject_cast<QLineEdit*>(editor))
|
|
|
|
{
|
|
|
|
connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited()));
|
|
|
|
skip = true;
|
|
|
|
}
|
|
|
|
if(!skip && qobject_cast<QCheckBox*>(editor))
|
|
|
|
{
|
|
|
|
connect(editor, SIGNAL(stateChanged(int)), proxy, SLOT(editorDataCommited()));
|
|
|
|
skip = true;
|
|
|
|
}
|
|
|
|
if(!skip && qobject_cast<QPlainTextEdit*>(editor))
|
|
|
|
{
|
|
|
|
connect(editor, SIGNAL(textChanged()), proxy, SLOT(editorDataCommited()));
|
|
|
|
skip = true;
|
|
|
|
}
|
|
|
|
if(!skip && qobject_cast<QComboBox*>(editor))
|
|
|
|
{
|
|
|
|
connect(editor, SIGNAL(currentIndexChanged (int)), proxy, SLOT(editorDataCommited()));
|
|
|
|
skip = true;
|
|
|
|
}
|
|
|
|
|
2014-03-07 21:17:40 +00:00
|
|
|
connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)));
|
|
|
|
mProxys.push_back(proxy); //deleted in the destructor
|
2014-03-07 16:15:43 +00:00
|
|
|
}
|
|
|
|
return editor;
|
|
|
|
}
|
|
|
|
|
2014-03-07 21:17:40 +00:00
|
|
|
CSVWorld::DialogueDelegateDispatcher::~DialogueDelegateDispatcher()
|
|
|
|
{
|
|
|
|
for (unsigned i = 0; i < mProxys.size(); ++i)
|
|
|
|
{
|
|
|
|
delete mProxys[i]; //unique_ptr could be handy
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
==============================DialogueSubView==========================================
|
|
|
|
*/
|
|
|
|
|
2012-12-13 12:35:08 +00:00
|
|
|
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
|
2014-03-07 16:15:43 +00:00
|
|
|
bool createAndDelete) :
|
|
|
|
|
|
|
|
SubView (id),
|
2014-03-07 21:17:40 +00:00
|
|
|
mDispatcher(this, dynamic_cast<CSMWorld::IdTable*>(document.getData().getTableModel (id)), document.getUndoStack())
|
2014-03-07 16:15:43 +00:00
|
|
|
|
2012-12-13 12:35:08 +00:00
|
|
|
{
|
2012-12-30 13:01:52 +00:00
|
|
|
QWidget *widget = new QWidget (this);
|
|
|
|
|
|
|
|
setWidget (widget);
|
|
|
|
|
2014-03-09 17:44:04 +00:00
|
|
|
QFrame* line = new QFrame(this);
|
|
|
|
line->setObjectName(QString::fromUtf8("line"));
|
|
|
|
line->setGeometry(QRect(320, 150, 118, 3));
|
|
|
|
line->setFrameShape(QFrame::HLine);
|
|
|
|
line->setFrameShadow(QFrame::Sunken);
|
|
|
|
|
|
|
|
QVBoxLayout *mainLayout = new QVBoxLayout;
|
|
|
|
QGridLayout *unlockedLayout = new QGridLayout;
|
|
|
|
QGridLayout *lockedLayout = new QGridLayout;
|
|
|
|
mainLayout->addLayout(lockedLayout, 0);
|
|
|
|
mainLayout->addWidget(line, 1);
|
|
|
|
mainLayout->addLayout(unlockedLayout, 2);
|
|
|
|
mainLayout->addStretch(1);
|
|
|
|
|
|
|
|
widget->setLayout (mainLayout);
|
2012-12-30 13:01:52 +00:00
|
|
|
|
2013-03-21 09:07:25 +00:00
|
|
|
QAbstractItemModel *model = document.getData().getTableModel (id);
|
2012-12-30 13:01:52 +00:00
|
|
|
|
|
|
|
int columns = model->columnCount();
|
|
|
|
|
2013-01-08 13:59:40 +00:00
|
|
|
mWidgetMapper = new QDataWidgetMapper (this);
|
|
|
|
mWidgetMapper->setModel (model);
|
2014-03-07 21:17:40 +00:00
|
|
|
mWidgetMapper->setItemDelegate(&mDispatcher);
|
2013-01-08 13:59:40 +00:00
|
|
|
|
2014-03-09 17:44:04 +00:00
|
|
|
int unlocked = 0;
|
|
|
|
int locked = 0;
|
|
|
|
std::vector<QWidget*> editors;
|
2012-12-30 13:01:52 +00:00
|
|
|
for (int i=0; i<columns; ++i)
|
|
|
|
{
|
|
|
|
int flags = model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt();
|
2012-12-13 12:35:08 +00:00
|
|
|
|
2012-12-30 13:01:52 +00:00
|
|
|
if (flags & CSMWorld::ColumnBase::Flag_Dialogue)
|
|
|
|
{
|
2013-01-08 13:59:40 +00:00
|
|
|
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display>
|
|
|
|
(model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
|
|
|
|
2014-03-07 21:17:40 +00:00
|
|
|
mDispatcher.makeDelegate(display);
|
2014-03-09 17:44:04 +00:00
|
|
|
QWidget *editor = mDispatcher.makeEditor(display, (model->index (0, i)));
|
2013-01-08 13:59:40 +00:00
|
|
|
|
2014-03-09 17:44:04 +00:00
|
|
|
if (editor)
|
2013-01-08 13:59:40 +00:00
|
|
|
{
|
2014-03-09 17:44:04 +00:00
|
|
|
editors.push_back(editor);
|
|
|
|
mWidgetMapper->addMapping (editor, i);
|
|
|
|
QLabel* label = new QLabel(model->headerData (i, Qt::Horizontal).toString());
|
|
|
|
label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
|
|
|
|
editor->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
2014-03-08 14:18:40 +00:00
|
|
|
if (! (model->flags (model->index (0, i)) & Qt::ItemIsEditable))
|
|
|
|
{
|
2014-03-09 17:44:04 +00:00
|
|
|
lockedLayout->addWidget (label, locked, 0);
|
|
|
|
lockedLayout->addWidget (editor, locked, 1);
|
|
|
|
++locked;
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
unlockedLayout->addWidget (label, unlocked, 0);
|
|
|
|
unlockedLayout->addWidget (editor, unlocked, 1);
|
|
|
|
++unlocked;
|
2014-03-08 14:18:40 +00:00
|
|
|
}
|
2013-01-08 13:59:40 +00:00
|
|
|
}
|
2012-12-30 13:01:52 +00:00
|
|
|
}
|
|
|
|
}
|
2013-01-08 13:59:40 +00:00
|
|
|
|
2013-01-19 13:29:14 +00:00
|
|
|
mWidgetMapper->setCurrentModelIndex (
|
|
|
|
dynamic_cast<CSMWorld::IdTable&> (*model).getModelIndex (id.getId(), 0));
|
2012-12-13 12:35:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CSVWorld::DialogueSubView::setEditLock (bool locked)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|