mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-13 12:40:04 +00:00
added pop-up menu with create record action
This commit is contained in:
parent
db29e411c4
commit
49d6239004
@ -5,7 +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
|
||||
model/world/commands.cpp model/world/idtableproxymodel.cpp
|
||||
|
||||
view/doc/viewmanager.cpp view/doc/view.cpp view/doc/operations.cpp view/doc/operation.cpp
|
||||
|
||||
@ -18,10 +18,10 @@ set (OPENCS_HDR
|
||||
model/doc/documentmanager.hpp model/doc/document.hpp
|
||||
|
||||
model/world/universalid.hpp model/world/record.hpp model/world/idcollection.hpp model/world/data.hpp
|
||||
model/world/idtable.hpp model/world/columns.hpp
|
||||
model/world/idtable.hpp model/world/columns.hpp model/world/idtableproxymodel.hpp
|
||||
model/world/commands.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/table.hpp view/world/globals.hpp
|
||||
)
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
#include "idtableproxymodel.hpp"
|
||||
|
||||
CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index,
|
||||
const QVariant& new_, QUndoCommand *parent)
|
||||
: QUndoCommand (parent), mModel (model), mIndex (index), mNew (new_)
|
||||
@ -21,3 +23,19 @@ void CSMWorld::ModifyCommand::undo()
|
||||
{
|
||||
mModel.setData (mIndex, mOld);
|
||||
}
|
||||
|
||||
CSMWorld::CreateCommand::CreateCommand (IdTableProxyModel& model, const std::string& id, QUndoCommand *parent)
|
||||
: QUndoCommand (parent), mModel (model), mId (id)
|
||||
{
|
||||
setText (("Create record " + id).c_str());
|
||||
}
|
||||
|
||||
void CSMWorld::CreateCommand::redo()
|
||||
{
|
||||
mModel.addRecord (mId);
|
||||
}
|
||||
|
||||
void CSMWorld::CreateCommand::undo()
|
||||
{
|
||||
mModel.removeRow (mModel.getModelIndex (mId, 0).row());
|
||||
}
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include "record.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <QVariant>
|
||||
#include <QUndoCommand>
|
||||
#include <QModelIndex>
|
||||
@ -12,6 +14,8 @@ class QAbstractItemModel;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class IdTableProxyModel;
|
||||
|
||||
class ModifyCommand : public QUndoCommand
|
||||
{
|
||||
QAbstractItemModel& mModel;
|
||||
@ -28,6 +32,20 @@ namespace CSMWorld
|
||||
|
||||
virtual void undo();
|
||||
};
|
||||
|
||||
class CreateCommand : public QUndoCommand
|
||||
{
|
||||
IdTableProxyModel& mModel;
|
||||
std::string mId;
|
||||
|
||||
public:
|
||||
|
||||
CreateCommand (IdTableProxyModel& model, const std::string& id, QUndoCommand *parent = 0);
|
||||
|
||||
virtual void redo();
|
||||
|
||||
virtual void undo();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -50,6 +50,8 @@ namespace CSMWorld
|
||||
|
||||
virtual std::string getId (int index) const = 0;
|
||||
|
||||
virtual int getIndex (const std::string& id) const = 0;
|
||||
|
||||
virtual int getColumns() const = 0;
|
||||
|
||||
virtual std::string getTitle (int column) const = 0;
|
||||
@ -65,6 +67,10 @@ namespace CSMWorld
|
||||
|
||||
virtual void purge() = 0;
|
||||
///< Remove records that are flagged as erased.
|
||||
|
||||
virtual void removeRows (int index, int count) = 0;
|
||||
|
||||
virtual void appendBlankRecord (const std::string& id) = 0;
|
||||
};
|
||||
|
||||
///< \brief Collection of ID-based records
|
||||
@ -92,6 +98,8 @@ namespace CSMWorld
|
||||
|
||||
virtual std::string getId (int index) const;
|
||||
|
||||
virtual int getIndex (const std::string& id) const;
|
||||
|
||||
virtual int getColumns() const;
|
||||
|
||||
virtual QVariant getData (int index, int column) const;
|
||||
@ -108,6 +116,10 @@ namespace CSMWorld
|
||||
virtual void purge();
|
||||
///< Remove records that are flagged as erased.
|
||||
|
||||
virtual void removeRows (int index, int count) ;
|
||||
|
||||
virtual void appendBlankRecord (const std::string& id);
|
||||
|
||||
void addColumn (Column<ESXRecordT> *column);
|
||||
};
|
||||
|
||||
@ -159,6 +171,17 @@ namespace CSMWorld
|
||||
return mRecords.at (index).get().mId;
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
int IdCollection<ESXRecordT>::getIndex (const std::string& id) const
|
||||
{
|
||||
std::map<std::string, int>::const_iterator iter = mIndex.find (id);
|
||||
|
||||
if (iter==mIndex.end())
|
||||
throw std::runtime_error ("invalid ID: " + id);
|
||||
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
int IdCollection<ESXRecordT>::getColumns() const
|
||||
{
|
||||
@ -211,6 +234,39 @@ namespace CSMWorld
|
||||
std::mem_fun_ref (&Record<ESXRecordT>::isErased) // I want lambda :(
|
||||
), mRecords.end());
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
void IdCollection<ESXRecordT>::removeRows (int index, int count)
|
||||
{
|
||||
mRecords.erase (mRecords.begin()+index, mRecords.begin()+index+count);
|
||||
|
||||
typename std::map<std::string, int>::iterator iter = mIndex.begin();
|
||||
|
||||
while (iter!=mIndex.end())
|
||||
{
|
||||
if (iter->second>=index)
|
||||
{
|
||||
if (iter->second>=index+count)
|
||||
{
|
||||
iter->second -= count;
|
||||
}
|
||||
else
|
||||
{
|
||||
mIndex.erase (iter++);
|
||||
}
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
void IdCollection<ESXRecordT>::appendBlankRecord (const std::string& id)
|
||||
{
|
||||
ESXRecordT record;
|
||||
record.mId = id;
|
||||
add (record);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -72,3 +72,33 @@ Qt::ItemFlags CSMWorld::IdTable::flags (const QModelIndex & index) const
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& parent)
|
||||
{
|
||||
if (parent.isValid())
|
||||
return false;
|
||||
|
||||
beginRemoveRows (parent, row, row+count-1);
|
||||
|
||||
mIdCollection->removeRows (row, count);
|
||||
|
||||
endRemoveRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CSMWorld::IdTable::addRecord (const std::string& id)
|
||||
{
|
||||
int index = mIdCollection->getSize();
|
||||
|
||||
beginInsertRows (QModelIndex(), index, index);
|
||||
|
||||
mIdCollection->appendBlankRecord (id);
|
||||
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
QModelIndex CSMWorld::IdTable::getModelIndex (const std::string& id, int column) const
|
||||
{
|
||||
return index (mIdCollection->getIndex (id), column);
|
||||
}
|
@ -24,17 +24,23 @@ namespace CSMWorld
|
||||
|
||||
virtual ~IdTable();
|
||||
|
||||
int rowCount (const QModelIndex & parent = QModelIndex()) const;
|
||||
virtual int rowCount (const QModelIndex & parent = QModelIndex()) const;
|
||||
|
||||
int columnCount (const QModelIndex & parent = QModelIndex()) const;
|
||||
virtual int columnCount (const QModelIndex & parent = QModelIndex()) const;
|
||||
|
||||
QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const;
|
||||
virtual QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const;
|
||||
|
||||
QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
|
||||
bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
|
||||
virtual bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
|
||||
|
||||
Qt::ItemFlags flags (const QModelIndex & index) const;
|
||||
virtual Qt::ItemFlags flags (const QModelIndex & index) const;
|
||||
|
||||
virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex());
|
||||
|
||||
void addRecord (const std::string& id);
|
||||
|
||||
QModelIndex getModelIndex (const std::string& id, int column) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
18
apps/opencs/model/world/idtableproxymodel.cpp
Normal file
18
apps/opencs/model/world/idtableproxymodel.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
#include "idtableproxymodel.hpp"
|
||||
|
||||
#include "idtable.hpp"
|
||||
|
||||
CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent)
|
||||
: QSortFilterProxyModel (parent)
|
||||
{}
|
||||
|
||||
void CSMWorld::IdTableProxyModel::addRecord (const std::string& id)
|
||||
{
|
||||
dynamic_cast<IdTable&> (*sourceModel()).addRecord (id);
|
||||
}
|
||||
|
||||
QModelIndex CSMWorld::IdTableProxyModel::getModelIndex (const std::string& id, int column) const
|
||||
{
|
||||
return mapFromSource (dynamic_cast<IdTable&> (*sourceModel()).getModelIndex (id, column));
|
||||
}
|
24
apps/opencs/model/world/idtableproxymodel.hpp
Normal file
24
apps/opencs/model/world/idtableproxymodel.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef CSM_WOLRD_IDTABLEPROXYMODEL_H
|
||||
#define CSM_WOLRD_IDTABLEPROXYMODEL_H
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class IdTableProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
IdTableProxyModel (QObject *parent = 0);
|
||||
|
||||
virtual void addRecord (const std::string& id);
|
||||
|
||||
virtual QModelIndex getModelIndex (const std::string& id, int column) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -5,18 +5,21 @@
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
template <typename ESXRecordT>
|
||||
struct Record
|
||||
struct RecordBase
|
||||
{
|
||||
enum State
|
||||
{
|
||||
State_BaseOnly, // defined in base only
|
||||
State_Modified, // exists in base, but has been modified
|
||||
State_ModifiedOnly, // newly created in modified
|
||||
State_Deleted, // exists in base, but has been deleted
|
||||
State_Erased // does not exist at all (we mostly treat that the same way as deleted)
|
||||
State_BaseOnly = 0, // defined in base only
|
||||
State_Modified = 1, // exists in base, but has been modified
|
||||
State_ModifiedOnly = 2, // newly created in modified
|
||||
State_Deleted = 3, // exists in base, but has been deleted
|
||||
State_Erased = 4 // does not exist at all (we mostly treat that the same way as deleted)
|
||||
};
|
||||
};
|
||||
|
||||
template <typename ESXRecordT>
|
||||
struct Record : public RecordBase
|
||||
{
|
||||
ESXRecordT mBase;
|
||||
ESXRecordT mModified;
|
||||
State mState;
|
||||
|
@ -6,7 +6,7 @@
|
||||
CSVWorld::Globals::Globals (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack)
|
||||
: SubView (id)
|
||||
{
|
||||
setWidget (mTable = new Table (id, data, undoStack));
|
||||
setWidget (mTable = new Table (id, data, undoStack, true));
|
||||
}
|
||||
|
||||
void CSVWorld::Globals::setEditLock (bool locked)
|
||||
|
@ -3,12 +3,14 @@
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QHeaderView>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QUndoStack>
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
#include <QContextMenuEvent>
|
||||
|
||||
#include "../../model/world/data.hpp"
|
||||
|
||||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/world/idtableproxymodel.hpp"
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
@ -104,7 +106,19 @@ void CSVWorld::CommandDelegate::setEditLock (bool locked)
|
||||
}
|
||||
|
||||
|
||||
CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack)
|
||||
void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||
{
|
||||
QMenu menu (this);
|
||||
|
||||
if (mCreateAction)
|
||||
menu.addAction (mCreateAction);
|
||||
|
||||
menu.exec (event->globalPos());
|
||||
}
|
||||
|
||||
CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack,
|
||||
bool createAndDelete)
|
||||
: mUndoStack (undoStack), mCreateAction (0)
|
||||
{
|
||||
QAbstractTableModel *model = data.getTableModel (id);
|
||||
|
||||
@ -117,10 +131,10 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, Q
|
||||
setItemDelegateForColumn (i, delegate);
|
||||
}
|
||||
|
||||
QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel (this);
|
||||
proxyModel->setSourceModel (model);
|
||||
mModel = new CSMWorld::IdTableProxyModel (this);
|
||||
mModel->setSourceModel (model);
|
||||
|
||||
setModel (proxyModel);
|
||||
setModel (mModel);
|
||||
horizontalHeader()->setResizeMode (QHeaderView::Interactive);
|
||||
verticalHeader()->hide();
|
||||
setSortingEnabled (true);
|
||||
@ -128,6 +142,13 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, Q
|
||||
setSelectionMode (QAbstractItemView::ExtendedSelection);
|
||||
|
||||
/// \todo make initial layout fill the whole width of the table
|
||||
|
||||
if (createAndDelete)
|
||||
{
|
||||
mCreateAction = new QAction (tr ("CreateRecord"), this);
|
||||
connect (mCreateAction, SIGNAL (triggered()), this, SLOT (createRecord()));
|
||||
addAction (mCreateAction);
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::Table::setEditLock (bool locked)
|
||||
@ -135,3 +156,15 @@ void CSVWorld::Table::setEditLock (bool locked)
|
||||
for (std::vector<CommandDelegate *>::iterator iter (mDelegates.begin()); iter!=mDelegates.end(); ++iter)
|
||||
(*iter)->setEditLock (locked);
|
||||
}
|
||||
|
||||
#include <sstream> /// \todo remove
|
||||
void CSVWorld::Table::createRecord()
|
||||
{
|
||||
/// \todo ask the user for an ID instead.
|
||||
static int index = 0;
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << "id" << index++;
|
||||
|
||||
mUndoStack.push (new CSMWorld::CreateCommand (*mModel, stream.str()));
|
||||
}
|
@ -6,11 +6,13 @@
|
||||
#include <QTableView>
|
||||
|
||||
class QUndoStack;
|
||||
class QAction;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class Data;
|
||||
class UniversalId;
|
||||
class IdTableProxyModel;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
@ -20,13 +22,27 @@ namespace CSVWorld
|
||||
///< Table widget
|
||||
class Table : public QTableView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
std::vector<CommandDelegate *> mDelegates;
|
||||
QUndoStack& mUndoStack;
|
||||
QAction *mCreateAction;
|
||||
CSMWorld::IdTableProxyModel *mModel;
|
||||
|
||||
private:
|
||||
|
||||
void contextMenuEvent (QContextMenuEvent *event);
|
||||
|
||||
public:
|
||||
|
||||
Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack);
|
||||
Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack, bool createAndDelete);
|
||||
///< \param createAndDelete Allow creation and deletion of records.
|
||||
|
||||
void setEditLock (bool locked);
|
||||
|
||||
private slots:
|
||||
|
||||
void createRecord();
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user