1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-06-24 21:11:34 +00:00

Merge branch 'globals'

This commit is contained in:
Marc Zinnschlag 2012-12-28 23:42:02 +01:00
commit e2a8e2107b
18 changed files with 308 additions and 149 deletions

View file

@ -13,7 +13,8 @@ set (OPENCS_SRC
view/doc/viewmanager.cpp view/doc/view.cpp view/doc/operations.cpp view/doc/operation.cpp view/doc/subviewfactory.cpp view/doc/viewmanager.cpp view/doc/view.cpp view/doc/operations.cpp view/doc/operation.cpp view/doc/subviewfactory.cpp
view/doc/subview.cpp view/doc/subview.cpp
view/world/table.cpp view/world/tablesubview.cpp view/world/subviews.cpp view/world/table.cpp view/world/tablesubview.cpp view/world/subviews.cpp view/world/util.cpp
view/world/dialoguesubview.cpp
view/tools/reportsubview.cpp view/tools/subviews.cpp view/tools/reportsubview.cpp view/tools/subviews.cpp
) )
@ -33,7 +34,8 @@ set (OPENCS_HDR
view/doc/viewmanager.hpp view/doc/view.hpp view/doc/operations.hpp view/doc/operation.hpp view/doc/subviewfactory.hpp view/doc/viewmanager.hpp view/doc/view.hpp view/doc/operations.hpp view/doc/operation.hpp view/doc/subviewfactory.hpp
view/doc/subview.hpp view/doc/subviewfactoryimp.hpp view/doc/subview.hpp view/doc/subviewfactoryimp.hpp
view/world/table.hpp view/world/tablesubview.hpp view/world/subviews.hpp view/world/table.hpp view/world/tablesubview.hpp view/world/subviews.hpp view/world/util.hpp
view/world/dialoguesubview.hpp
view/tools/reportsubview.hpp view/tools/subviews.hpp view/tools/reportsubview.hpp view/tools/subviews.hpp
) )

View file

@ -0,0 +1,13 @@
#include "columnbase.hpp"
CSMWorld::ColumnBase::ColumnBase (const std::string& title, int flags)
: mTitle (title), mFlags (flags)
{}
CSMWorld::ColumnBase::~ColumnBase() {}
bool CSMWorld::ColumnBase::isUserEditable() const
{
return isEditable();
}

View file

@ -0,0 +1,57 @@
#ifndef CSM_WOLRD_COLUMNBASE_H
#define CSM_WOLRD_COLUMNBASE_H
#include <string>
#include <Qt>
#include <QVariant>
#include "record.hpp"
namespace CSMWorld
{
struct ColumnBase
{
enum Roles
{
Role_Flags = Qt::UserRole
};
enum Flags
{
Flag_Table = 1, // column should be displayed in table view
Flag_Dialogue = 2 // column should be displayed in dialogue view
};
std::string mTitle;
int mFlags;
ColumnBase (const std::string& title, int flag);
virtual ~ColumnBase();
virtual bool isEditable() const = 0;
virtual bool isUserEditable() const;
///< Can this column be edited directly by the user?
};
template<typename ESXRecordT>
struct Column : public ColumnBase
{
std::string mTitle;
int mFlags;
Column (const std::string& title, int flags = Flag_Table | Flag_Dialogue)
: ColumnBase (title, flags) {}
virtual QVariant get (const Record<ESXRecordT>& record) const = 0;
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
throw std::logic_error ("Column " + mTitle + " is not editable");
}
};
}
#endif

View file

@ -66,6 +66,29 @@ namespace CSMWorld
{ {
return true; return true;
} }
virtual bool isUserEditable() const
{
return false;
}
};
template<typename ESXRecordT>
struct FixedRecordTypeColumn : public Column<ESXRecordT>
{
int mType;
FixedRecordTypeColumn (int type) : Column<ESXRecordT> ("Type", 0), mType (type) {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return mType;
}
virtual bool isEditable() const
{
return false;
}
}; };
} }

View file

@ -14,6 +14,7 @@ CSMWorld::Data::Data()
{ {
mGlobals.addColumn (new StringIdColumn<ESM::Global>); mGlobals.addColumn (new StringIdColumn<ESM::Global>);
mGlobals.addColumn (new RecordStateColumn<ESM::Global>); mGlobals.addColumn (new RecordStateColumn<ESM::Global>);
mGlobals.addColumn (new FixedRecordTypeColumn<ESM::Global> (UniversalId::Type_Global));
mGlobals.addColumn (new FloatValueColumn<ESM::Global>); mGlobals.addColumn (new FloatValueColumn<ESM::Global>);
mModels.insert (std::make_pair ( mModels.insert (std::make_pair (

View file

@ -11,29 +11,10 @@
#include <QVariant> #include <QVariant>
#include "record.hpp" #include "columnbase.hpp"
namespace CSMWorld namespace CSMWorld
{ {
template<typename ESXRecordT>
struct Column
{
std::string mTitle;
Column (const std::string& title) : mTitle (title) {}
virtual ~Column() {}
virtual QVariant get (const Record<ESXRecordT>& record) const = 0;
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
throw std::logic_error ("Column " + mTitle + " is not editable");
}
virtual bool isEditable() const = 0;
};
class IdCollectionBase class IdCollectionBase
{ {
// not implemented // not implemented
@ -54,14 +35,12 @@ namespace CSMWorld
virtual int getColumns() const = 0; virtual int getColumns() const = 0;
virtual std::string getTitle (int column) const = 0; virtual const ColumnBase& getColumn (int column) const = 0;
virtual QVariant getData (int index, int column) const = 0; virtual QVariant getData (int index, int column) const = 0;
virtual void setData (int index, int column, const QVariant& data) = 0; virtual void setData (int index, int column, const QVariant& data) = 0;
virtual bool isEditable (int column) const = 0;
virtual void merge() = 0; virtual void merge() = 0;
///< Merge modified into base. ///< Merge modified into base.
@ -125,9 +104,7 @@ namespace CSMWorld
virtual void setData (int index, int column, const QVariant& data); virtual void setData (int index, int column, const QVariant& data);
virtual std::string getTitle (int column) const; virtual const ColumnBase& getColumn (int column) const;
virtual bool isEditable (int column) const;
virtual void merge(); virtual void merge();
///< Merge modified into base. ///< Merge modified into base.
@ -239,15 +216,9 @@ namespace CSMWorld
} }
template<typename ESXRecordT> template<typename ESXRecordT>
std::string IdCollection<ESXRecordT>::getTitle (int column) const const ColumnBase& IdCollection<ESXRecordT>::getColumn (int column) const
{ {
return mColumns.at (column)->mTitle; return *mColumns.at (column);
}
template<typename ESXRecordT>
bool IdCollection<ESXRecordT>::isEditable (int column) const
{
return mColumns.at (column)->isEditable();
} }
template<typename ESXRecordT> template<typename ESXRecordT>

View file

@ -34,7 +34,7 @@ QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const
if (role!=Qt::DisplayRole && role!=Qt::EditRole) if (role!=Qt::DisplayRole && role!=Qt::EditRole)
return QVariant(); return QVariant();
if (role==Qt::EditRole && !mIdCollection->isEditable (index.column())) if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable())
return QVariant(); return QVariant();
return mIdCollection->getData (index.row(), index.column()); return mIdCollection->getData (index.row(), index.column());
@ -42,18 +42,21 @@ QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const
QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation, int role) const QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation, int role) const
{ {
if (role!=Qt::DisplayRole)
return QVariant();
if (orientation==Qt::Vertical) if (orientation==Qt::Vertical)
return QVariant(); return QVariant();
return tr (mIdCollection->getTitle (section).c_str()); if (role==Qt::DisplayRole)
return tr (mIdCollection->getColumn (section).mTitle.c_str());
if (role==ColumnBase::Role_Flags)
return mIdCollection->getColumn (section).mFlags;
return QVariant();
} }
bool CSMWorld::IdTable::setData ( const QModelIndex &index, const QVariant &value, int role) bool CSMWorld::IdTable::setData ( const QModelIndex &index, const QVariant &value, int role)
{ {
if (mIdCollection->isEditable (index.column()) && role==Qt::EditRole) if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole)
{ {
mIdCollection->setData (index.row(), index.column(), value); mIdCollection->setData (index.row(), index.column(), value);
@ -70,7 +73,7 @@ Qt::ItemFlags CSMWorld::IdTable::flags (const QModelIndex & index) const
{ {
Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
if (mIdCollection->isEditable (index.column())) if (mIdCollection->getColumn (index.column()).isUserEditable())
flags |= Qt::ItemIsEditable; flags |= Qt::ItemIsEditable;
return flags; return flags;

View file

@ -24,6 +24,7 @@ namespace
static const TypeData sIdArg[] = static const TypeData sIdArg[] =
{ {
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable" },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
}; };
@ -208,8 +209,8 @@ std::string CSMWorld::UniversalId::toString() const
switch (mArgumentType) switch (mArgumentType)
{ {
case ArgumentType_None: break; case ArgumentType_None: break;
case ArgumentType_Id: stream << ": " << mId; case ArgumentType_Id: stream << ": " << mId; break;
case ArgumentType_Index: stream << ": " << mIndex; case ArgumentType_Index: stream << ": " << mIndex; break;
} }
return stream.str(); return stream.str();

View file

@ -36,6 +36,8 @@ namespace CSMWorld
Type_Globals, Type_Globals,
Type_Global,
Type_VerificationResults Type_VerificationResults
}; };

View file

@ -0,0 +1,14 @@
#include "dialoguesubview.hpp"
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
bool createAndDelete)
: SubView (id)
{
}
void CSVWorld::DialogueSubView::setEditLock (bool locked)
{
}

View file

@ -0,0 +1,24 @@
#ifndef CSV_WORLD_DIALOGUESUBVIEW_H
#define CSV_WORLD_DIALOGUESUBVIEW_H
#include "../doc/subview.hpp"
namespace CSMDoc
{
class Document;
}
namespace CSVWorld
{
class DialogueSubView : public CSVDoc::SubView
{
public:
DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete);
virtual void setEditLock (bool locked);
};
}
#endif

View file

@ -4,9 +4,13 @@
#include "../doc/subviewfactoryimp.hpp" #include "../doc/subviewfactoryimp.hpp"
#include "tablesubview.hpp" #include "tablesubview.hpp"
#include "dialoguesubview.hpp"
void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
{ {
manager.add (CSMWorld::UniversalId::Type_Globals, manager.add (CSMWorld::UniversalId::Type_Globals,
new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (true)); new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (true));
manager.add (CSMWorld::UniversalId::Type_Global,
new CSVDoc::SubViewFactoryWithCreateFlag<DialogueSubView> (true));
} }

View file

@ -1,9 +1,8 @@
#include "table.hpp" #include "table.hpp"
#include <QStyledItemDelegate>
#include <QHeaderView> #include <QHeaderView>
#include <QUndoStack>
#include <QAction> #include <QAction>
#include <QMenu> #include <QMenu>
#include <QContextMenuEvent> #include <QContextMenuEvent>
@ -14,98 +13,7 @@
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/world/record.hpp" #include "../../model/world/record.hpp"
namespace CSVWorld #include "util.hpp"
{
///< \brief Getting the data out of an editor widget
///
/// Really, Qt? Really?
class NastyTableModelHack : public QAbstractTableModel
{
QAbstractItemModel& mModel;
QVariant mData;
public:
NastyTableModelHack (QAbstractItemModel& model);
int rowCount (const QModelIndex & parent = QModelIndex()) const;
int columnCount (const QModelIndex & parent = QModelIndex()) const;
QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const;
bool setData (const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
QVariant getData() const;
};
///< \brief Use commands instead of manipulating the model directly
class CommandDelegate : public QStyledItemDelegate
{
QUndoStack& mUndoStack;
bool mEditLock;
public:
CommandDelegate (QUndoStack& undoStack, QObject *parent);
void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const;
void setEditLock (bool locked);
};
}
CSVWorld::NastyTableModelHack::NastyTableModelHack (QAbstractItemModel& model)
: mModel (model)
{}
int CSVWorld::NastyTableModelHack::rowCount (const QModelIndex & parent) const
{
return mModel.rowCount (parent);
}
int CSVWorld::NastyTableModelHack::columnCount (const QModelIndex & parent) const
{
return mModel.columnCount (parent);
}
QVariant CSVWorld::NastyTableModelHack::data (const QModelIndex & index, int role) const
{
return mModel.data (index, role);
}
bool CSVWorld::NastyTableModelHack::setData ( const QModelIndex &index, const QVariant &value, int role)
{
mData = value;
return true;
}
QVariant CSVWorld::NastyTableModelHack::getData() const
{
return mData;
}
CSVWorld::CommandDelegate::CommandDelegate (QUndoStack& undoStack, QObject *parent)
: QStyledItemDelegate (parent), mUndoStack (undoStack), mEditLock (false)
{}
void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemModel *model,
const QModelIndex& index) const
{
if (!mEditLock)
{
NastyTableModelHack hack (*model);
QStyledItemDelegate::setModelData (editor, &hack, index);
mUndoStack.push (new CSMWorld::ModifyCommand (*model, index, hack.getData()));
}
///< \todo provide some kind of feedback to the user, indicating that editing is currently not possible.
}
void CSVWorld::CommandDelegate::setEditLock (bool locked)
{
mEditLock = locked;
}
void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
{ {
@ -176,15 +84,6 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, Q
{ {
mModel = &dynamic_cast<CSMWorld::IdTable&> (*data.getTableModel (id)); mModel = &dynamic_cast<CSMWorld::IdTable&> (*data.getTableModel (id));
int columns = mModel->columnCount();
for (int i=0; i<columns; ++i)
{
CommandDelegate *delegate = new CommandDelegate (undoStack, this);
mDelegates.push_back (delegate);
setItemDelegateForColumn (i, delegate);
}
mProxyModel = new CSMWorld::IdTableProxyModel (this); mProxyModel = new CSMWorld::IdTableProxyModel (this);
mProxyModel->setSourceModel (mModel); mProxyModel->setSourceModel (mModel);
@ -195,6 +94,22 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, Q
setSelectionBehavior (QAbstractItemView::SelectRows); setSelectionBehavior (QAbstractItemView::SelectRows);
setSelectionMode (QAbstractItemView::ExtendedSelection); setSelectionMode (QAbstractItemView::ExtendedSelection);
int columns = mModel->columnCount();
for (int i=0; i<columns; ++i)
{
int flags = mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt();
if (flags & CSMWorld::ColumnBase::Flag_Table)
{
CommandDelegate *delegate = new CommandDelegate (undoStack, this);
mDelegates.push_back (delegate);
setItemDelegateForColumn (i, delegate);
}
else
hideColumn (i);
}
/// \todo make initial layout fill the whole width of the table /// \todo make initial layout fill the whole width of the table
if (createAndDelete) if (createAndDelete)
@ -221,6 +136,13 @@ void CSVWorld::Table::setEditLock (bool locked)
mEditLock = locked; mEditLock = locked;
} }
CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const
{
return CSMWorld::UniversalId (
static_cast<CSMWorld::UniversalId::Type> (mProxyModel->data (mProxyModel->index (row, 2)).toInt()),
mProxyModel->data (mProxyModel->index (row, 0)).toString().toStdString());
}
#include <sstream> /// \todo remove #include <sstream> /// \todo remove
void CSVWorld::Table::createRecord() void CSVWorld::Table::createRecord()
{ {

View file

@ -50,6 +50,8 @@ namespace CSVWorld
void setEditLock (bool locked); void setEditLock (bool locked);
CSMWorld::UniversalId getUniversalId (int row) const;
private slots: private slots:
void createRecord(); void createRecord();

View file

@ -10,9 +10,16 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D
: SubView (id) : SubView (id)
{ {
setWidget (mTable = new Table (id, document.getData(), document.getUndoStack(), createAndDelete)); setWidget (mTable = new Table (id, document.getData(), document.getUndoStack(), createAndDelete));
connect (mTable, SIGNAL (doubleClicked (const QModelIndex&)), this, SLOT (rowActivated (const QModelIndex&)));
} }
void CSVWorld::TableSubView::setEditLock (bool locked) void CSVWorld::TableSubView::setEditLock (bool locked)
{ {
mTable->setEditLock (locked); mTable->setEditLock (locked);
} }
void CSVWorld::TableSubView::rowActivated (const QModelIndex& index)
{
focusId (mTable->getUniversalId (index.row()));
}

View file

@ -3,7 +3,7 @@
#include "../doc/subview.hpp" #include "../doc/subview.hpp"
class QUndoStack; class QModelIndex;
namespace CSMDoc namespace CSMDoc
{ {
@ -16,6 +16,8 @@ namespace CSVWorld
class TableSubView : public CSVDoc::SubView class TableSubView : public CSVDoc::SubView
{ {
Q_OBJECT
Table *mTable; Table *mTable;
public: public:
@ -23,6 +25,10 @@ namespace CSVWorld
TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete); TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete);
virtual void setEditLock (bool locked); virtual void setEditLock (bool locked);
private slots:
void rowActivated (const QModelIndex& index);
}; };
} }

View file

@ -0,0 +1,57 @@
#include "util.hpp"
#include <QUndoStack>
#include "../../model/world/commands.hpp"
CSVWorld::NastyTableModelHack::NastyTableModelHack (QAbstractItemModel& model)
: mModel (model)
{}
int CSVWorld::NastyTableModelHack::rowCount (const QModelIndex & parent) const
{
return mModel.rowCount (parent);
}
int CSVWorld::NastyTableModelHack::columnCount (const QModelIndex & parent) const
{
return mModel.columnCount (parent);
}
QVariant CSVWorld::NastyTableModelHack::data (const QModelIndex & index, int role) const
{
return mModel.data (index, role);
}
bool CSVWorld::NastyTableModelHack::setData ( const QModelIndex &index, const QVariant &value, int role)
{
mData = value;
return true;
}
QVariant CSVWorld::NastyTableModelHack::getData() const
{
return mData;
}
CSVWorld::CommandDelegate::CommandDelegate (QUndoStack& undoStack, QObject *parent)
: QStyledItemDelegate (parent), mUndoStack (undoStack), mEditLock (false)
{}
void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemModel *model,
const QModelIndex& index) const
{
if (!mEditLock)
{
NastyTableModelHack hack (*model);
QStyledItemDelegate::setModelData (editor, &hack, index);
mUndoStack.push (new CSMWorld::ModifyCommand (*model, index, hack.getData()));
}
///< \todo provide some kind of feedback to the user, indicating that editing is currently not possible.
}
void CSVWorld::CommandDelegate::setEditLock (bool locked)
{
mEditLock = locked;
}

View file

@ -0,0 +1,50 @@
#ifndef CSV_WORLD_UTIL_H
#define CSV_WORLD_UTIL_H
#include <QAbstractTableModel>
#include <QStyledItemDelegate>
class QUndoStack;
namespace CSVWorld
{
///< \brief Getting the data out of an editor widget
///
/// Really, Qt? Really?
class NastyTableModelHack : public QAbstractTableModel
{
QAbstractItemModel& mModel;
QVariant mData;
public:
NastyTableModelHack (QAbstractItemModel& model);
int rowCount (const QModelIndex & parent = QModelIndex()) const;
int columnCount (const QModelIndex & parent = QModelIndex()) const;
QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const;
bool setData (const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
QVariant getData() const;
};
///< \brief Use commands instead of manipulating the model directly
class CommandDelegate : public QStyledItemDelegate
{
QUndoStack& mUndoStack;
bool mEditLock;
public:
CommandDelegate (QUndoStack& undoStack, QObject *parent);
void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const;
void setEditLock (bool locked);
};
}
#endif