mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-25 06:35:30 +00:00
factored out command creation from table view into a separate class
This commit is contained in:
parent
a28a2bc2fe
commit
83d5f2aaeb
@ -18,7 +18,7 @@ opencs_hdrs_noqt (model/doc
|
||||
|
||||
|
||||
opencs_units (model/world
|
||||
idtable idtableproxymodel regionmap data
|
||||
idtable idtableproxymodel regionmap data commanddispatcher
|
||||
)
|
||||
|
||||
|
||||
|
157
apps/opencs/model/world/commanddispatcher.cpp
Normal file
157
apps/opencs/model/world/commanddispatcher.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
|
||||
#include "commanddispatcher.hpp"
|
||||
|
||||
#include "../doc/document.hpp"
|
||||
|
||||
#include "idtable.hpp"
|
||||
#include "record.hpp"
|
||||
#include "commands.hpp"
|
||||
|
||||
std::vector<int> CSMWorld::CommandDispatcher::getDeletableRecords() const
|
||||
{
|
||||
std::vector<int> result;
|
||||
|
||||
IdTable& model = dynamic_cast<IdTable&> (*mDocument.getData().getTableModel (mId));
|
||||
|
||||
for (std::vector<int>::const_iterator iter (mSelection.begin());
|
||||
iter!=mSelection.end(); ++iter)
|
||||
{
|
||||
// check record state
|
||||
RecordBase::State state =
|
||||
static_cast<RecordBase::State> (model.data (model.index (*iter, 1)).toInt());
|
||||
|
||||
if (state==RecordBase::State_Deleted)
|
||||
continue;
|
||||
|
||||
// check other columns (only relevant for a subset of the tables)
|
||||
int dialogueTypeIndex = model.searchColumnIndex (Columns::ColumnId_DialogueType);
|
||||
|
||||
if (dialogueTypeIndex!=-1)
|
||||
{
|
||||
int type = model.data (model.index (*iter, dialogueTypeIndex)).toInt();
|
||||
|
||||
if (type!=ESM::Dialogue::Topic && type!=ESM::Dialogue::Journal)
|
||||
continue;
|
||||
}
|
||||
|
||||
result.push_back (*iter);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<int> CSMWorld::CommandDispatcher::getRevertableRecords() const
|
||||
{
|
||||
std::vector<int> result;
|
||||
|
||||
IdTable& model = dynamic_cast<IdTable&> (*mDocument.getData().getTableModel (mId));
|
||||
|
||||
/// \todo Reverting temporarily disabled on tables that support reordering, because
|
||||
/// revert logic currently can not handle reordering.
|
||||
if (model.getFeatures() & IdTable::Feature_ReorderWithinTopic)
|
||||
return result;
|
||||
|
||||
for (std::vector<int>::const_iterator iter (mSelection.begin());
|
||||
iter!=mSelection.end(); ++iter)
|
||||
{
|
||||
// check record state
|
||||
RecordBase::State state =
|
||||
static_cast<RecordBase::State> (model.data (model.index (*iter, 1)).toInt());
|
||||
|
||||
if (state==RecordBase::State_BaseOnly)
|
||||
continue;
|
||||
|
||||
result.push_back (*iter);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CSMWorld::CommandDispatcher::CommandDispatcher (CSMDoc::Document& document,
|
||||
const CSMWorld::UniversalId& id, QObject *parent)
|
||||
: QObject (parent), mDocument (document), mId (id), mLocked (false)
|
||||
{}
|
||||
|
||||
void CSMWorld::CommandDispatcher::setEditLock (bool locked)
|
||||
{
|
||||
mLocked = locked;
|
||||
}
|
||||
|
||||
void CSMWorld::CommandDispatcher::setSelection (const std::vector<int>& selection)
|
||||
{
|
||||
mSelection = selection;
|
||||
}
|
||||
|
||||
bool CSMWorld::CommandDispatcher::canDelete() const
|
||||
{
|
||||
if (mLocked)
|
||||
return false;
|
||||
|
||||
return getDeletableRecords().size()!=0;
|
||||
}
|
||||
|
||||
bool CSMWorld::CommandDispatcher::canRevert() const
|
||||
{
|
||||
if (mLocked)
|
||||
return false;
|
||||
|
||||
return getRevertableRecords().size()!=0;
|
||||
}
|
||||
|
||||
void CSMWorld::CommandDispatcher::executeDelete()
|
||||
{
|
||||
if (mLocked)
|
||||
return;
|
||||
|
||||
std::vector<int> rows = getDeletableRecords();
|
||||
|
||||
if (rows.empty())
|
||||
return;
|
||||
|
||||
IdTable& model = dynamic_cast<IdTable&> (*mDocument.getData().getTableModel (mId));
|
||||
|
||||
int columnIndex = model.findColumnIndex (Columns::ColumnId_Id);
|
||||
|
||||
if (rows.size()>1)
|
||||
mDocument.getUndoStack().beginMacro (tr ("Delete multiple records"));
|
||||
|
||||
for (std::vector<int>::const_iterator iter (rows.begin()); iter!=rows.end(); ++iter)
|
||||
{
|
||||
std::string id = model.data (model.index (*iter, columnIndex)).
|
||||
toString().toUtf8().constData();
|
||||
|
||||
mDocument.getUndoStack().push (new CSMWorld::DeleteCommand (model, id));
|
||||
}
|
||||
|
||||
if (rows.size()>1)
|
||||
mDocument.getUndoStack().endMacro();
|
||||
}
|
||||
|
||||
void CSMWorld::CommandDispatcher::executeRevert()
|
||||
{
|
||||
if (mLocked)
|
||||
return;
|
||||
|
||||
std::vector<int> rows = getRevertableRecords();
|
||||
|
||||
if (rows.empty())
|
||||
return;
|
||||
|
||||
IdTable& model = dynamic_cast<IdTable&> (*mDocument.getData().getTableModel (mId));
|
||||
|
||||
int columnIndex = model.findColumnIndex (Columns::ColumnId_Id);
|
||||
|
||||
if (rows.size()>1)
|
||||
mDocument.getUndoStack().beginMacro (tr ("Revert multiple records"));
|
||||
|
||||
for (std::vector<int>::const_iterator iter (rows.begin()); iter!=rows.end(); ++iter)
|
||||
{
|
||||
std::string id = model.data (model.index (*iter, columnIndex)).
|
||||
toString().toUtf8().constData();
|
||||
|
||||
mDocument.getUndoStack().push (new CSMWorld::RevertCommand (model, id));
|
||||
}
|
||||
|
||||
if (rows.size()>1)
|
||||
mDocument.getUndoStack().endMacro();
|
||||
}
|
53
apps/opencs/model/world/commanddispatcher.hpp
Normal file
53
apps/opencs/model/world/commanddispatcher.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef CSM_WOLRD_COMMANDDISPATCHER_H
|
||||
#define CSM_WOLRD_COMMANDDISPATCHER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "universalid.hpp"
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class CommandDispatcher : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
bool mLocked;
|
||||
CSMDoc::Document& mDocument;
|
||||
UniversalId mId;
|
||||
std::vector<int> mSelection;
|
||||
|
||||
std::vector<int> getDeletableRecords() const;
|
||||
|
||||
std::vector<int> getRevertableRecords() const;
|
||||
|
||||
public:
|
||||
|
||||
CommandDispatcher (CSMDoc::Document& document, const CSMWorld::UniversalId& id,
|
||||
QObject *parent = 0);
|
||||
///< \param id ID of the table the commands should operate on primarily.
|
||||
|
||||
void setEditLock (bool locked);
|
||||
|
||||
void setSelection (const std::vector<int>& selection);
|
||||
|
||||
bool canDelete() const;
|
||||
|
||||
bool canRevert() const;
|
||||
|
||||
public slots:
|
||||
|
||||
void executeDelete();
|
||||
|
||||
void executeRevert();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -19,14 +19,28 @@
|
||||
#include "../../model/world/columns.hpp"
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
#include "../../model/world/commanddispatcher.hpp"
|
||||
|
||||
#include "recordstatusdelegate.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||
{
|
||||
// configure dispatcher
|
||||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||
|
||||
std::vector<int> rows;
|
||||
|
||||
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end();
|
||||
++iter)
|
||||
{
|
||||
QModelIndex index = mProxyModel->mapToSource (mProxyModel->index (iter->row(), 0));
|
||||
rows.push_back (index.row());
|
||||
}
|
||||
|
||||
mDispatcher->setSelection (rows);
|
||||
|
||||
// create context menu
|
||||
QMenu menu (this);
|
||||
|
||||
/// \todo add menu items for select all and clear selection
|
||||
@ -44,13 +58,10 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||
if (mCreateAction)
|
||||
menu.addAction (mCreateAction);
|
||||
|
||||
/// \todo Reverting temporarily disabled on tables that support reordering, because
|
||||
/// revert logic currently can not handle reordering.
|
||||
if (!(mModel->getFeatures() & CSMWorld::IdTable::Feature_ReorderWithinTopic))
|
||||
if (listRevertableSelectedIds().size()>0)
|
||||
menu.addAction (mRevertAction);
|
||||
if (mDispatcher->canRevert())
|
||||
menu.addAction (mRevertAction);
|
||||
|
||||
if (listDeletableSelectedIds().size()>0)
|
||||
if (mDispatcher->canDelete())
|
||||
menu.addAction (mDeleteAction);
|
||||
|
||||
if (mModel->getFeatures() & CSMWorld::IdTable::Feature_ReorderWithinTopic)
|
||||
@ -108,84 +119,6 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||
menu.exec (event->globalPos());
|
||||
}
|
||||
|
||||
std::vector<std::string> CSVWorld::Table::listRevertableSelectedIds() const
|
||||
{
|
||||
std::vector<std::string> revertableIds;
|
||||
|
||||
if (mProxyModel->columnCount()>0)
|
||||
{
|
||||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||
|
||||
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end();
|
||||
++iter)
|
||||
{
|
||||
QModelIndex index = mProxyModel->mapToSource (mProxyModel->index (iter->row(), 0));
|
||||
|
||||
CSMWorld::RecordBase::State state =
|
||||
static_cast<CSMWorld::RecordBase::State> (
|
||||
mModel->data (mModel->index (index.row(), 1)).toInt());
|
||||
|
||||
if (state!=CSMWorld::RecordBase::State_BaseOnly)
|
||||
{
|
||||
int columnIndex = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Id);
|
||||
|
||||
std::string id = mModel->data (mModel->index (index.row(), columnIndex)).
|
||||
toString().toUtf8().constData();
|
||||
|
||||
revertableIds.push_back (id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return revertableIds;
|
||||
}
|
||||
|
||||
std::vector<std::string> CSVWorld::Table::listDeletableSelectedIds() const
|
||||
{
|
||||
std::vector<std::string> deletableIds;
|
||||
|
||||
if (mProxyModel->columnCount()>0)
|
||||
{
|
||||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||
|
||||
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end();
|
||||
++iter)
|
||||
{
|
||||
QModelIndex index = mProxyModel->mapToSource (mProxyModel->index (iter->row(), 0));
|
||||
|
||||
// check record state
|
||||
CSMWorld::RecordBase::State state =
|
||||
static_cast<CSMWorld::RecordBase::State> (
|
||||
mModel->data (mModel->index (index.row(), 1)).toInt());
|
||||
|
||||
if (state==CSMWorld::RecordBase::State_Deleted)
|
||||
continue;
|
||||
|
||||
// check other columns (only relevant for a subset of the tables)
|
||||
int dialogueTypeIndex =
|
||||
mModel->searchColumnIndex (CSMWorld::Columns::ColumnId_DialogueType);
|
||||
|
||||
if (dialogueTypeIndex!=-1)
|
||||
{
|
||||
int type = mModel->data (mModel->index (index.row(), dialogueTypeIndex)).toInt();
|
||||
|
||||
if (type!=ESM::Dialogue::Topic && type!=ESM::Dialogue::Journal)
|
||||
continue;
|
||||
}
|
||||
|
||||
// add the id to the collection
|
||||
int columnIndex = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Id);
|
||||
|
||||
std::string id = mModel->data (mModel->index (index.row(), columnIndex)).
|
||||
toString().toUtf8().constData();
|
||||
|
||||
deletableIds.push_back (id);
|
||||
}
|
||||
}
|
||||
|
||||
return deletableIds;
|
||||
}
|
||||
|
||||
CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
||||
bool createAndDelete, bool sorting, CSMDoc::Document& document)
|
||||
: mCreateAction (0), mCloneAction(0), mRecordStatusDisplay (0),
|
||||
@ -196,6 +129,8 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
||||
mProxyModel = new CSMWorld::IdTableProxyModel (this);
|
||||
mProxyModel->setSourceModel (mModel);
|
||||
|
||||
mDispatcher = new CSMWorld::CommandDispatcher (document, id, this);
|
||||
|
||||
setModel (mProxyModel);
|
||||
horizontalHeader()->setResizeMode (QHeaderView::Interactive);
|
||||
verticalHeader()->hide();
|
||||
@ -240,11 +175,11 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
||||
}
|
||||
|
||||
mRevertAction = new QAction (tr ("Revert Record"), this);
|
||||
connect (mRevertAction, SIGNAL (triggered()), this, SLOT (revertRecord()));
|
||||
connect (mRevertAction, SIGNAL (triggered()), mDispatcher, SLOT (executeRevert()));
|
||||
addAction (mRevertAction);
|
||||
|
||||
mDeleteAction = new QAction (tr ("Delete Record"), this);
|
||||
connect (mDeleteAction, SIGNAL (triggered()), this, SLOT (deleteRecord()));
|
||||
connect (mDeleteAction, SIGNAL (triggered()), mDispatcher, SLOT (executeDelete()));
|
||||
addAction (mDeleteAction);
|
||||
|
||||
mMoveUpAction = new QAction (tr ("Move Up"), this);
|
||||
@ -283,6 +218,7 @@ void CSVWorld::Table::setEditLock (bool locked)
|
||||
(*iter)->setEditLock (locked);
|
||||
|
||||
DragRecordTable::setEditLock(locked);
|
||||
mDispatcher->setEditLock (locked);
|
||||
}
|
||||
|
||||
CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const
|
||||
@ -292,46 +228,6 @@ CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const
|
||||
mProxyModel->data (mProxyModel->index (row, 0)).toString().toUtf8().constData());
|
||||
}
|
||||
|
||||
void CSVWorld::Table::revertRecord()
|
||||
{
|
||||
if (!mEditLock)
|
||||
{
|
||||
std::vector<std::string> revertableIds = listRevertableSelectedIds();
|
||||
|
||||
if (!revertableIds.empty())
|
||||
{
|
||||
if (revertableIds.size()>1)
|
||||
mDocument.getUndoStack().beginMacro (tr ("Revert multiple records"));
|
||||
|
||||
for (std::vector<std::string>::const_iterator iter (revertableIds.begin()); iter!=revertableIds.end(); ++iter)
|
||||
mDocument.getUndoStack().push (new CSMWorld::RevertCommand (*mModel, *iter));
|
||||
|
||||
if (revertableIds.size()>1)
|
||||
mDocument.getUndoStack().endMacro();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::Table::deleteRecord()
|
||||
{
|
||||
if (!mEditLock)
|
||||
{
|
||||
std::vector<std::string> deletableIds = listDeletableSelectedIds();
|
||||
|
||||
if (!deletableIds.empty())
|
||||
{
|
||||
if (deletableIds.size()>1)
|
||||
mDocument.getUndoStack().beginMacro (tr ("Delete multiple records"));
|
||||
|
||||
for (std::vector<std::string>::const_iterator iter (deletableIds.begin()); iter!=deletableIds.end(); ++iter)
|
||||
mDocument.getUndoStack().push (new CSMWorld::DeleteCommand (*mModel, *iter));
|
||||
|
||||
if (deletableIds.size()>1)
|
||||
mDocument.getUndoStack().endMacro();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::Table::editRecord()
|
||||
{
|
||||
if (!mEditLock)
|
||||
|
@ -24,6 +24,7 @@ namespace CSMWorld
|
||||
class UniversalId;
|
||||
class IdTableProxyModel;
|
||||
class IdTable;
|
||||
class CommandDispatcher;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
@ -48,15 +49,12 @@ namespace CSVWorld
|
||||
CSMWorld::IdTableProxyModel *mProxyModel;
|
||||
CSMWorld::IdTable *mModel;
|
||||
int mRecordStatusDisplay;
|
||||
CSMWorld::CommandDispatcher *mDispatcher;
|
||||
|
||||
private:
|
||||
|
||||
void contextMenuEvent (QContextMenuEvent *event);
|
||||
|
||||
std::vector<std::string> listRevertableSelectedIds() const;
|
||||
|
||||
std::vector<std::string> listDeletableSelectedIds() const;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
|
||||
void dropEvent(QDropEvent *event);
|
||||
@ -93,10 +91,6 @@ namespace CSVWorld
|
||||
|
||||
private slots:
|
||||
|
||||
void revertRecord();
|
||||
|
||||
void deleteRecord();
|
||||
|
||||
void editRecord();
|
||||
|
||||
void cloneRecord();
|
||||
|
Loading…
x
Reference in New Issue
Block a user