diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 92fd859bed..61580461fc 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -5,6 +5,7 @@ set (OPENCS_SRC model/doc/documentmanager.cpp model/doc/document.cpp model/world/universalid.cpp model/world/idcollection.cpp model/world/data.cpp model/world/idtable.cpp + model/world/commands.cpp view/doc/viewmanager.cpp view/doc/view.cpp view/doc/operations.cpp view/doc/operation.cpp @@ -20,6 +21,7 @@ set (OPENCS_HDR model/world/idtable.hpp model/world/columns.hpp view/doc/viewmanager.hpp view/doc/view.hpp view/doc/operations.hpp view/doc/operation.hpp + model/world/commands.hpp view/world/subview.hpp view/world/globals.hpp ) diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp new file mode 100644 index 0000000000..a15d00619f --- /dev/null +++ b/apps/opencs/model/world/commands.cpp @@ -0,0 +1,23 @@ + +#include "commands.hpp" + +#include + +CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, + const QVariant& new_, QUndoCommand *parent) +: QUndoCommand (parent), mModel (model), mIndex (index), mNew (new_) +{ + mOld = mModel.data (mIndex, Qt::EditRole); + + setText ("Modify " + mModel.headerData (mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString()); +} + +void CSMWorld::ModifyCommand::redo() +{ + mModel.setData (mIndex, mNew); +} + +void CSMWorld::ModifyCommand::undo() +{ + mModel.setData (mIndex, mOld); +} \ No newline at end of file diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp new file mode 100644 index 0000000000..ffaee59ef5 --- /dev/null +++ b/apps/opencs/model/world/commands.hpp @@ -0,0 +1,33 @@ +#ifndef CSM_WOLRD_COMMANDS_H +#define CSM_WOLRD_COMMANDS_H + +#include "record.hpp" + +#include +#include +#include + +class QModelIndex; +class QAbstractItemModel; + +namespace CSMWorld +{ + class ModifyCommand : public QUndoCommand + { + QAbstractItemModel& mModel; + QModelIndex mIndex; + QVariant mNew; + QVariant mOld; + + public: + + ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_, + QUndoCommand *parent = 0); + + virtual void redo(); + + virtual void undo(); + }; +} + +#endif \ No newline at end of file diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 18d58bbf58..c81ba2ba14 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -193,7 +193,7 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id) if (iter==mSubViewFactories.end()) throw std::logic_error ("can't create subview for " + id.toString()); - CSVWorld::SubView *view = iter->second->makeSubView (id, mDocument->getData()); + CSVWorld::SubView *view = iter->second->makeSubView (id, mDocument->getData(), mDocument->getUndoStack()); addDockWidget (Qt::TopDockWidgetArea, view); view->show(); } diff --git a/apps/opencs/view/world/globals.cpp b/apps/opencs/view/world/globals.cpp index 1f68a57fe6..a57f63dffe 100644 --- a/apps/opencs/view/world/globals.cpp +++ b/apps/opencs/view/world/globals.cpp @@ -4,18 +4,73 @@ #include #include #include +#include #include "../../model/world/data.hpp" -CSVWorld::Globals::Globals (const CSMWorld::UniversalId& id, CSMWorld::Data& data) +#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) +{} + +void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemModel *model, + const QModelIndex& index) const +{ + NastyTableModelHack hack (*model); + QStyledItemDelegate::setModelData (editor, &hack, index); + mUndoStack.push (new CSMWorld::ModifyCommand (*model, index, hack.getData())); +} + +CSVWorld::Globals::Globals (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack) : SubView (id) { QTableView *table = new QTableView(); setWidget (table); + QAbstractTableModel *model = data.getTableModel (id); + + int columns = model->columnCount(); + + for (int i=1; isetItemDelegateForColumn (i, delegate); + } + QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel (this); - proxyModel->setSourceModel (data.getTableModel (id)); + proxyModel->setSourceModel (model); table->setModel (proxyModel); table->horizontalHeader()->setResizeMode (QHeaderView::Interactive); diff --git a/apps/opencs/view/world/globals.hpp b/apps/opencs/view/world/globals.hpp index c54716255a..11ab7b6aa1 100644 --- a/apps/opencs/view/world/globals.hpp +++ b/apps/opencs/view/world/globals.hpp @@ -3,14 +3,52 @@ #include "subview.hpp" +#include + +class QUndoStack; + namespace CSVWorld { - class Globals : public SubView + ///< \brief Getting the data out of an editor widget + /// + /// Really, Qt? Really? + class NastyTableModelHack : public QAbstractTableModel { + QAbstractItemModel& mModel; + QVariant mData; public: - Globals (const CSMWorld::UniversalId& id, CSMWorld::Data& data); + 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; + + public: + + CommandDelegate (QUndoStack& undoStack, QObject *parent); + + void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const; + }; + + class Globals : public SubView + { + public: + + Globals (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack); }; } diff --git a/apps/opencs/view/world/subview.hpp b/apps/opencs/view/world/subview.hpp index 95cbe4243f..fd7a516315 100644 --- a/apps/opencs/view/world/subview.hpp +++ b/apps/opencs/view/world/subview.hpp @@ -5,6 +5,8 @@ #include +class QUndoStack; + namespace CSMWorld { class Data; @@ -31,19 +33,21 @@ namespace CSVWorld struct SubViewFactoryBase { - virtual SubView *makeSubView (const CSMWorld::UniversalId& id, CSMWorld::Data& data) = 0; + virtual SubView *makeSubView (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack) + = 0; }; template struct SubViewFactory : public SubViewFactoryBase { - virtual SubView *makeSubView (const CSMWorld::UniversalId& id, CSMWorld::Data& data); + virtual SubView *makeSubView (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack); }; template - SubView *SubViewFactory::makeSubView (const CSMWorld::UniversalId& id, CSMWorld::Data& data) + SubView *SubViewFactory::makeSubView (const CSMWorld::UniversalId& id, CSMWorld::Data& data, + QUndoStack& undoStack) { - return new SubViewT (id, data); + return new SubViewT (id, data, undoStack); } }