mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 06:53:53 +00:00
Changes to support dialogue only items but in a list view via QDataWidgetMapper.
This commit is contained in:
parent
1c7ed795c2
commit
a2d824bfa6
7 changed files with 134 additions and 44 deletions
|
@ -23,7 +23,8 @@ namespace CSMWorld
|
|||
enum Flags
|
||||
{
|
||||
Flag_Table = 1, // column should be displayed in table view
|
||||
Flag_Dialogue = 2 // column should be displayed in dialogue view
|
||||
Flag_Dialogue = 2, // column should be displayed in dialogue view
|
||||
Flag_Dialogue_List = 4 // column should be diaplyed in dialogue view
|
||||
};
|
||||
|
||||
enum Display
|
||||
|
@ -94,11 +95,11 @@ namespace CSMWorld
|
|||
Display_QuestStatusType,
|
||||
|
||||
//Those are top level columns that nest other columns
|
||||
Display_NestedItemList,
|
||||
Display_NestedSpellList,
|
||||
Display_NestedDestinationsList,
|
||||
Display_PathgridPointList,
|
||||
Display_PathgridEdgeList,
|
||||
Display_NestedItemList, // delete?
|
||||
Display_NestedSpellList, // delete?
|
||||
Display_NestedDestinationsList, // delete?
|
||||
Display_PathgridPointList, // delete?
|
||||
Display_PathgridEdgeList, // delete?
|
||||
Display_NestedHeader,
|
||||
|
||||
Display_EnchantmentType,
|
||||
|
|
|
@ -93,8 +93,7 @@ bool CSMWorld::IdTree::setData (const QModelIndex &index, const QVariant &value,
|
|||
mNestedCollection->setNestedData(parentAddress.first, parentAddress.second, value, index.row(), index.column());
|
||||
|
||||
emit dataChanged (CSMWorld::IdTree::index (parentAddress.first, 0),
|
||||
CSMWorld::IdTree::index (parentAddress.second, idCollection()->getColumns()-1));
|
||||
|
||||
CSMWorld::IdTree::index (parentAddress.first, idCollection()->getColumns()-1));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -32,12 +32,15 @@ CSMWorld::NestedTableProxyModel::NestedTableProxyModel(const QModelIndex& parent
|
|||
|
||||
connect(mMainModel, SIGNAL(resetEnd(const QString&)),
|
||||
this, SLOT(forwardResetEnd(const QString&)));
|
||||
|
||||
connect(mMainModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
|
||||
this, SLOT(forwardDataChanged(const QModelIndex &, const QModelIndex &)));
|
||||
}
|
||||
|
||||
QModelIndex CSMWorld::NestedTableProxyModel::mapFromSource(const QModelIndex& sourceIndex) const
|
||||
{
|
||||
const QModelIndex& testedParent = mMainModel->parent(sourceIndex);
|
||||
const QModelIndex& parent = mMainModel->getModelIndex (mId, mParentColumn);
|
||||
const QModelIndex& parent = mMainModel->getNestedModelIndex (mId, mParentColumn);
|
||||
if (testedParent == parent)
|
||||
{
|
||||
return createIndex(sourceIndex.row(), sourceIndex.column());
|
||||
|
@ -75,13 +78,8 @@ QModelIndex CSMWorld::NestedTableProxyModel::index(int row, int column, const QM
|
|||
int rows = mMainModel->rowCount(parent);
|
||||
int columns = mMainModel->columnCount(parent);
|
||||
|
||||
if (row < 0 ||
|
||||
row >= rows ||
|
||||
column < 0 ||
|
||||
column >= columns)
|
||||
{
|
||||
if (row < 0 || row >= rows || column < 0 || column >= columns)
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
return createIndex(row, column);
|
||||
}
|
||||
|
@ -103,6 +101,9 @@ QVariant CSMWorld::NestedTableProxyModel::data(const QModelIndex& index, int rol
|
|||
return mMainModel->data(mapToSource(index), role);
|
||||
}
|
||||
|
||||
// NOTE: Due to mapToSouce(index) the dataChanged() signal resulting from setData() will have the
|
||||
// source model's index values. The indicies need to be converted to the proxy space values.
|
||||
// See forwardDataChanged()
|
||||
bool CSMWorld::NestedTableProxyModel::setData (const QModelIndex & index, const QVariant & value, int role)
|
||||
{
|
||||
return mMainModel->setData(mapToSource(index), value, role);
|
||||
|
@ -128,7 +129,8 @@ CSMWorld::IdTree* CSMWorld::NestedTableProxyModel::model() const
|
|||
return mMainModel;
|
||||
}
|
||||
|
||||
void CSMWorld::NestedTableProxyModel::forwardRowsAboutToInserted(const QModelIndex& parent, int first, int last)
|
||||
void CSMWorld::NestedTableProxyModel::forwardRowsAboutToInserted(const QModelIndex& parent,
|
||||
int first, int last)
|
||||
{
|
||||
if (indexIsParent(parent))
|
||||
{
|
||||
|
@ -151,7 +153,8 @@ bool CSMWorld::NestedTableProxyModel::indexIsParent(const QModelIndex& index)
|
|||
mMainModel->data(mMainModel->index(index.row(), 0)).toString().toUtf8().constData() == mId);
|
||||
}
|
||||
|
||||
void CSMWorld::NestedTableProxyModel::forwardRowsAboutToRemoved(const QModelIndex& parent, int first, int last)
|
||||
void CSMWorld::NestedTableProxyModel::forwardRowsAboutToRemoved(const QModelIndex& parent,
|
||||
int first, int last)
|
||||
{
|
||||
if (indexIsParent(parent))
|
||||
{
|
||||
|
@ -178,3 +181,15 @@ void CSMWorld::NestedTableProxyModel::forwardResetEnd(const QString& id)
|
|||
if (id.toUtf8() == mId.c_str())
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void CSMWorld::NestedTableProxyModel::forwardDataChanged (const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight)
|
||||
{
|
||||
const QModelIndex& parent = mMainModel->getNestedModelIndex (mId, mParentColumn);
|
||||
|
||||
if (topLeft.column() <= parent.column() && bottomRight.column() >= parent.column())
|
||||
{
|
||||
emit dataChanged(index(0,0),
|
||||
index(mMainModel->rowCount(parent)-1, mMainModel->columnCount(parent)-1));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace CSMWorld
|
|||
|
||||
virtual int columnCount(const QModelIndex& parent) const;
|
||||
|
||||
virtual QModelIndex index(int row, int column, const QModelIndex& parent) const;
|
||||
virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
|
||||
|
||||
virtual QModelIndex parent(const QModelIndex& index) const;
|
||||
|
||||
|
@ -76,6 +76,8 @@ namespace CSMWorld
|
|||
void forwardResetStart(const QString& id);
|
||||
|
||||
void forwardResetEnd(const QString& id);
|
||||
|
||||
void forwardDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "../../model/world/columns.hpp"
|
||||
#include "../../model/world/record.hpp"
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
#include "../../model/world/idtree.hpp"
|
||||
#include "../../model/doc/document.hpp"
|
||||
#include "../../model/world/commands.hpp"
|
||||
|
||||
|
@ -175,9 +176,10 @@ void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std::
|
|||
==============================DialogueDelegateDispatcher==========================================
|
||||
*/
|
||||
|
||||
CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, CSMDoc::Document& document) :
|
||||
CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent,
|
||||
CSMWorld::IdTable* table, CSMDoc::Document& document, QAbstractItemModel *model) :
|
||||
mParent(parent),
|
||||
mTable(table),
|
||||
mTable(model ? model : table),
|
||||
mDocument (document),
|
||||
mNotEditableDelegate(table, parent)
|
||||
{
|
||||
|
@ -199,7 +201,8 @@ CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CS
|
|||
return delegate;
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueDelegateDispatcher::editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display)
|
||||
void CSVWorld::DialogueDelegateDispatcher::editorDataCommited(QWidget* editor,
|
||||
const QModelIndex& index, CSMWorld::ColumnBase::Display display)
|
||||
{
|
||||
setModelData(editor, mTable, index, display);
|
||||
}
|
||||
|
@ -231,12 +234,14 @@ void CSVWorld::DialogueDelegateDispatcher::setEditorData (QWidget* editor, const
|
|||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
|
||||
void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor,
|
||||
QAbstractItemModel* model, const QModelIndex& index) const
|
||||
{
|
||||
setModelData(editor, model, index, CSMWorld::ColumnBase::Display_None);
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const
|
||||
void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor,
|
||||
QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const
|
||||
{
|
||||
std::map<int, CommandDelegate*>::const_iterator delegateIt(mDelegates.find(display));
|
||||
if (delegateIt != mDelegates.end())
|
||||
|
@ -245,17 +250,20 @@ void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstra
|
|||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueDelegateDispatcher::paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
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
|
||||
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)
|
||||
QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::Display display,
|
||||
const QModelIndex& index)
|
||||
{
|
||||
QVariant variant = index.data();
|
||||
if (!variant.isValid())
|
||||
|
@ -270,14 +278,16 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::
|
|||
QWidget* editor = NULL;
|
||||
if (! (mTable->flags (index) & Qt::ItemIsEditable))
|
||||
{
|
||||
return mNotEditableDelegate.createEditor(qobject_cast<QWidget*>(mParent), QStyleOptionViewItem(), index);
|
||||
return mNotEditableDelegate.createEditor(qobject_cast<QWidget*>(mParent),
|
||||
QStyleOptionViewItem(), index);
|
||||
}
|
||||
|
||||
std::map<int, CommandDelegate*>::iterator delegateIt(mDelegates.find(display));
|
||||
|
||||
if (delegateIt != mDelegates.end())
|
||||
{
|
||||
editor = delegateIt->second->createEditor(qobject_cast<QWidget*>(mParent), QStyleOptionViewItem(), index, display);
|
||||
editor = delegateIt->second->createEditor(qobject_cast<QWidget*>(mParent),
|
||||
QStyleOptionViewItem(), index, display);
|
||||
|
||||
DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display);
|
||||
|
||||
|
@ -339,12 +349,15 @@ CSVWorld::EditWidget::~EditWidget()
|
|||
{
|
||||
delete mNestedModels[i];
|
||||
}
|
||||
delete mNestedTableDispatcher;
|
||||
}
|
||||
|
||||
CSVWorld::EditWidget::EditWidget(QWidget *parent, int row, CSMWorld::IdTable* table, CSMDoc::Document& document, bool createAndDelete) :
|
||||
mDispatcher(this, table, document),
|
||||
mNestedTableDispatcher(NULL),
|
||||
QScrollArea(parent),
|
||||
mWidgetMapper(NULL),
|
||||
mNestedTableMapper(NULL),
|
||||
mMainWidget(NULL),
|
||||
mDocument (document),
|
||||
mTable(table)
|
||||
|
@ -362,6 +375,7 @@ void CSVWorld::EditWidget::remake(int row)
|
|||
delete mNestedModels[i];
|
||||
}
|
||||
mNestedModels.clear();
|
||||
delete mNestedTableDispatcher;
|
||||
|
||||
if (mMainWidget)
|
||||
{
|
||||
|
@ -376,6 +390,11 @@ void CSVWorld::EditWidget::remake(int row)
|
|||
delete mWidgetMapper;
|
||||
mWidgetMapper = 0;
|
||||
}
|
||||
if (mNestedTableMapper)
|
||||
{
|
||||
delete mNestedTableMapper;
|
||||
mNestedTableMapper = 0;
|
||||
}
|
||||
mWidgetMapper = new QDataWidgetMapper (this);
|
||||
|
||||
mWidgetMapper->setModel(mTable);
|
||||
|
@ -417,7 +436,8 @@ void CSVWorld::EditWidget::remake(int row)
|
|||
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display>
|
||||
(mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
||||
|
||||
if (mTable->hasChildren(mTable->index(row, i)))
|
||||
if (mTable->hasChildren(mTable->index(row, i)) &&
|
||||
!(flags & CSMWorld::ColumnBase::Flag_Dialogue_List))
|
||||
{
|
||||
mNestedModels.push_back(new CSMWorld::NestedTableProxyModel (mTable->index(row, i), display, dynamic_cast<CSMWorld::IdTree*>(mTable)));
|
||||
|
||||
|
@ -425,14 +445,15 @@ void CSVWorld::EditWidget::remake(int row)
|
|||
table->resizeColumnsToContents();
|
||||
|
||||
|
||||
QLabel* label = new QLabel (mTable->headerData (i, Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget);
|
||||
QLabel* label =
|
||||
new QLabel (mTable->headerData (i, Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget);
|
||||
|
||||
label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
|
||||
tablesLayout->addWidget(label);
|
||||
tablesLayout->addWidget(table);
|
||||
}
|
||||
else
|
||||
else if (!(flags & CSMWorld::ColumnBase::Flag_Dialogue_List))
|
||||
{
|
||||
mDispatcher.makeDelegate (display);
|
||||
QWidget* editor = mDispatcher.makeEditor (display, (mTable->index (row, i)));
|
||||
|
@ -460,6 +481,55 @@ void CSVWorld::EditWidget::remake(int row)
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mNestedModels.push_back(new CSMWorld::NestedTableProxyModel (
|
||||
static_cast<CSMWorld::IdTree *>(mTable)->index(row, i),
|
||||
display, static_cast<CSMWorld::IdTree *>(mTable)));
|
||||
mNestedTableMapper = new QDataWidgetMapper (this);
|
||||
|
||||
mNestedTableMapper->setModel(mNestedModels.back());
|
||||
// FIXME: lack MIME support?
|
||||
mNestedTableDispatcher =
|
||||
new DialogueDelegateDispatcher (this, mTable, mDocument, mNestedModels.back());
|
||||
mNestedTableMapper->setItemDelegate(mNestedTableDispatcher);
|
||||
|
||||
int columnCount =
|
||||
mTable->columnCount(mTable->getModelIndex (mNestedModels.back()->getParentId(), i));
|
||||
for (int col = 0; col < columnCount; ++col)
|
||||
{
|
||||
int displayRole = mNestedModels.back()->headerData (col,
|
||||
Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt();
|
||||
|
||||
CSMWorld::ColumnBase::Display display =
|
||||
static_cast<CSMWorld::ColumnBase::Display> (displayRole);
|
||||
|
||||
mNestedTableDispatcher->makeDelegate (display);
|
||||
|
||||
// FIXME: assumed all columns are editable
|
||||
QWidget* editor =
|
||||
mNestedTableDispatcher->makeEditor (display, mNestedModels.back()->index (0, col));
|
||||
if (editor)
|
||||
{
|
||||
mNestedTableMapper->addMapping (editor, col);
|
||||
|
||||
std::string disString = mNestedModels.back()->headerData (col,
|
||||
Qt::Horizontal, Qt::DisplayRole).toString().toStdString();
|
||||
// Need ot use Qt::DisplayRole in order to get the correct string
|
||||
// from CSMWorld::Columns
|
||||
QLabel* label = new QLabel (mNestedModels.back()->headerData (col,
|
||||
Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget);
|
||||
|
||||
label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
editor->setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||
|
||||
unlockedLayout->addWidget (label, unlocked, 0);
|
||||
unlockedLayout->addWidget (editor, unlocked, 1);
|
||||
++unlocked;
|
||||
}
|
||||
}
|
||||
mNestedTableMapper->setCurrentModelIndex(mNestedModels.back()->index(0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ namespace CSVWorld
|
|||
|
||||
QObject* mParent;
|
||||
|
||||
CSMWorld::IdTable* mTable;
|
||||
QAbstractItemModel* mTable;
|
||||
|
||||
CSMDoc::Document& mDocument;
|
||||
|
||||
|
@ -119,22 +119,25 @@ namespace CSVWorld
|
|||
public:
|
||||
DialogueDelegateDispatcher(QObject* parent,
|
||||
CSMWorld::IdTable* table,
|
||||
CSMDoc::Document& document);
|
||||
CSMDoc::Document& document,
|
||||
QAbstractItemModel* model = 0);
|
||||
|
||||
~DialogueDelegateDispatcher();
|
||||
|
||||
CSVWorld::CommandDelegate* makeDelegate(CSMWorld::ColumnBase::Display display);
|
||||
|
||||
QWidget* makeEditor(CSMWorld::ColumnBase::Display display,
|
||||
const QModelIndex& index);
|
||||
///< will return null if delegate is not present, parent of the widget is same as for dispatcher itself
|
||||
QWidget* makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index);
|
||||
///< will return null if delegate is not present, parent of the widget is
|
||||
//same as for dispatcher itself
|
||||
|
||||
virtual void setEditorData (QWidget* editor,
|
||||
virtual void setEditorData (QWidget* editor, const QModelIndex& index) const;
|
||||
|
||||
virtual void setModelData (QWidget* editor, QAbstractItemModel* model,
|
||||
const QModelIndex& index) const;
|
||||
|
||||
virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;
|
||||
|
||||
virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const;
|
||||
virtual void setModelData (QWidget* editor,
|
||||
QAbstractItemModel* model, const QModelIndex& index,
|
||||
CSMWorld::ColumnBase::Display display) const;
|
||||
|
||||
virtual void paint (QPainter* painter,
|
||||
const QStyleOptionViewItem& option,
|
||||
|
@ -153,15 +156,15 @@ namespace CSVWorld
|
|||
void tableMimeDataDropped(QWidget* editor, const QModelIndex& index,
|
||||
const CSMWorld::UniversalId& id,
|
||||
const CSMDoc::Document* document);
|
||||
|
||||
|
||||
};
|
||||
|
||||
class EditWidget : public QScrollArea
|
||||
{
|
||||
Q_OBJECT
|
||||
QDataWidgetMapper *mWidgetMapper;
|
||||
QDataWidgetMapper *mNestedTableMapper;
|
||||
DialogueDelegateDispatcher mDispatcher;
|
||||
DialogueDelegateDispatcher *mNestedTableDispatcher;
|
||||
QWidget* mMainWidget;
|
||||
CSMWorld::IdTable* mTable;
|
||||
CSMDoc::Document& mDocument;
|
||||
|
|
|
@ -180,7 +180,7 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO
|
|||
case CSMWorld::ColumnBase::Display_Float:
|
||||
{
|
||||
QDoubleSpinBox *dsb = new QDoubleSpinBox(parent);
|
||||
dsb->setRange(FLT_MIN, FLT_MAX);
|
||||
dsb->setRange(-FLT_MAX, FLT_MAX);
|
||||
dsb->setSingleStep(0.01f);
|
||||
dsb->setDecimals(3);
|
||||
return dsb;
|
||||
|
|
Loading…
Reference in a new issue