Changed: #1302 Added "delete primitive" undo command.
This commit is contained in:
parent
2eb3dd3c11
commit
55f0a2ad09
13 changed files with 166 additions and 46 deletions
|
@ -68,7 +68,7 @@ QString ObjectViewerPlugin::version() const
|
|||
|
||||
QString ObjectViewerPlugin::vendor() const
|
||||
{
|
||||
return Core::Constants::OVQT_VENDOR;
|
||||
return "GSoC2010_dnk-88";
|
||||
}
|
||||
|
||||
QString ObjectViewerPlugin::description() const
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace WorldEditor
|
|||
Node::Node()
|
||||
: m_parent(0)
|
||||
{
|
||||
setData(Constants::PRIMITIVE_IS_VISIBLE, true);
|
||||
}
|
||||
|
||||
Node::~Node()
|
||||
|
@ -102,6 +103,18 @@ void Node::insertChildNodeAfter(Node *node, Node *after)
|
|||
node->m_parent = this;
|
||||
}
|
||||
|
||||
void Node::insertChildNode(int pos, Node *node)
|
||||
{
|
||||
// Node is already a child
|
||||
nlassert(!m_children.contains(node));
|
||||
|
||||
// Node already has a parent
|
||||
nlassert(!m_children.contains(node));
|
||||
|
||||
m_children.insert(pos, node);
|
||||
node->m_parent = this;
|
||||
}
|
||||
|
||||
void Node::removeChildNode(Node *node)
|
||||
{
|
||||
nlassert(m_children.contains(node));
|
||||
|
|
|
@ -72,6 +72,9 @@ public:
|
|||
/// Insert node in back of the node pointed to by the pointer after.
|
||||
void insertChildNodeAfter(Node *node, Node *after);
|
||||
|
||||
/// Insert node in pos
|
||||
void insertChildNode(int pos, Node *node);
|
||||
|
||||
/// Return the node at index position row in the child list.
|
||||
Node *child(int row);
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ Path PrimitivesTreeModel::createLandscapeNode(const QString &fileName)
|
|||
}
|
||||
|
||||
|
||||
Path PrimitivesTreeModel::createRootPrimitiveNode(const QString &fileName, NLLIGO::CPrimitives *primitives)
|
||||
Path PrimitivesTreeModel::createRootPrimitiveNode(const QString &fileName, NLLIGO::CPrimitives *primitives, int pos)
|
||||
{
|
||||
if (m_worldEditNode == 0)
|
||||
createWorldEditNode("NewWorldEdit");
|
||||
|
@ -223,42 +223,48 @@ Path PrimitivesTreeModel::createRootPrimitiveNode(const QString &fileName, NLLIG
|
|||
if (!fileName.isEmpty())
|
||||
name = fileName;
|
||||
|
||||
int insPos = pos;
|
||||
|
||||
// Get position
|
||||
int pos = m_worldEditNode->childCount();
|
||||
if (pos == AtTheEnd)
|
||||
insPos = m_worldEditNode->childCount();
|
||||
|
||||
QModelIndex parentIndex = index(0, 0, QModelIndex());
|
||||
|
||||
// Add root node in tree model
|
||||
beginInsertRows(parentIndex, pos, pos);
|
||||
beginInsertRows(parentIndex, insPos, insPos);
|
||||
RootPrimitiveNode *newNode = new RootPrimitiveNode(name, primitives);
|
||||
m_worldEditNode->appendChildNode(newNode);
|
||||
m_worldEditNode->insertChildNode(insPos, newNode);
|
||||
endInsertRows();
|
||||
|
||||
newNode->setData(Constants::PRIMITIVE_FILE_IS_CREATED, !fileName.isEmpty());
|
||||
newNode->setData(Constants::PRIMITIVE_IS_MODIFIED, false);
|
||||
|
||||
QModelIndex rootPrimIndex = index(pos, 0, parentIndex);
|
||||
QModelIndex rootPrimIndex = index(insPos, 0, parentIndex);
|
||||
|
||||
// Scan childs items and add in the tree model
|
||||
for (uint i = 0; i < primitives->RootNode->getNumChildren(); ++i)
|
||||
{
|
||||
NLLIGO::IPrimitive *childPrim;
|
||||
primitives->RootNode->getChild(childPrim, i);
|
||||
createChildNodes(childPrim, rootPrimIndex);
|
||||
createChildNodes(childPrim, i, rootPrimIndex);
|
||||
}
|
||||
|
||||
return pathFromIndex(rootPrimIndex);
|
||||
}
|
||||
|
||||
Path PrimitivesTreeModel::createPrimitiveNode(NLLIGO::IPrimitive *primitive, const Path &parent)
|
||||
Path PrimitivesTreeModel::createPrimitiveNode(NLLIGO::IPrimitive *primitive, const Path &parent, int pos)
|
||||
{
|
||||
QModelIndex parentIndex = pathToIndex(parent);
|
||||
Node *parentNode = static_cast<Node *>(parentIndex.internalPointer());
|
||||
int pos = parentNode->childCount();
|
||||
|
||||
createChildNodes(primitive, parentIndex);
|
||||
int insPos = pos;
|
||||
if (pos == AtTheEnd)
|
||||
insPos = parentNode->childCount();
|
||||
|
||||
return pathFromIndex(index(pos, 0, parentIndex));
|
||||
createChildNodes(primitive, insPos, parentIndex);
|
||||
|
||||
return pathFromIndex(index(insPos, 0, parentIndex));
|
||||
}
|
||||
|
||||
void PrimitivesTreeModel::deleteNode(const Path &path)
|
||||
|
@ -271,16 +277,14 @@ void PrimitivesTreeModel::deleteNode(const Path &path)
|
|||
removeChildNodes(node, parentIndex);
|
||||
}
|
||||
|
||||
void PrimitivesTreeModel::createChildNodes(NLLIGO::IPrimitive *primitive, const QModelIndex &parent)
|
||||
void PrimitivesTreeModel::createChildNodes(NLLIGO::IPrimitive *primitive, int pos, const QModelIndex &parent)
|
||||
{
|
||||
Node *parentNode = static_cast<Node *>(parent.internalPointer());
|
||||
|
||||
int pos = parentNode->childCount();
|
||||
|
||||
// Add node in the tree model
|
||||
beginInsertRows(parent, pos, pos);
|
||||
PrimitiveNode *newNode = new PrimitiveNode(primitive);
|
||||
parentNode->appendChildNode(newNode);
|
||||
parentNode->insertChildNode(pos, newNode);
|
||||
endInsertRows();
|
||||
|
||||
// Scan childs items and add in the tree model
|
||||
|
@ -289,7 +293,7 @@ void PrimitivesTreeModel::createChildNodes(NLLIGO::IPrimitive *primitive, const
|
|||
{
|
||||
NLLIGO::IPrimitive *childPrim;
|
||||
primitive->getChild(childPrim, i);
|
||||
createChildNodes(childPrim, childIndex);
|
||||
createChildNodes(childPrim, i, childIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@ namespace WorldEditor
|
|||
class Node;
|
||||
class WorldEditNode;
|
||||
|
||||
const int AtTheEnd = -1;
|
||||
|
||||
typedef QPair<int, int> PathItem;
|
||||
/*
|
||||
@typedef Path
|
||||
|
@ -81,16 +83,16 @@ public:
|
|||
Path createLandscapeNode(const QString &fileName);
|
||||
|
||||
/// Add new root primitive node and all sub-primitives in the tree model.
|
||||
Path createRootPrimitiveNode(const QString &fileName, NLLIGO::CPrimitives *primitives);
|
||||
Path createRootPrimitiveNode(const QString &fileName, NLLIGO::CPrimitives *primitives, int pos = AtTheEnd);
|
||||
|
||||
/// Add new primitive node and all sub-primitives in the tree model.
|
||||
Path createPrimitiveNode(NLLIGO::IPrimitive *primitive, const Path &parent);
|
||||
Path createPrimitiveNode(NLLIGO::IPrimitive *primitive, const Path &parent, int pos = AtTheEnd);
|
||||
|
||||
/// Delete node and all child nodes from the tree model
|
||||
void deleteNode(const Path &path);
|
||||
|
||||
private:
|
||||
void createChildNodes(NLLIGO::IPrimitive *primitive, const QModelIndex &parent);
|
||||
void createChildNodes(NLLIGO::IPrimitive *primitive, int pos, const QModelIndex &parent);
|
||||
|
||||
void removeChildNodes(Node *node, const QModelIndex &parent);
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ PrimitivesView::PrimitivesView(QWidget *parent)
|
|||
m_newPrimitiveAction = new QAction("New primitive", this);
|
||||
|
||||
m_deleteAction = new QAction("Delete", this);
|
||||
m_deleteAction->setEnabled(false);
|
||||
//m_deleteAction->setEnabled(false);
|
||||
|
||||
m_selectChildrenAction = new QAction("Select children", this);
|
||||
|
||||
|
@ -243,6 +243,14 @@ void PrimitivesView::deletePrimitives()
|
|||
nlassert(m_primitivesTreeModel);
|
||||
|
||||
QModelIndexList indexList = selectionModel()->selectedRows();
|
||||
|
||||
QModelIndex index = indexList.first();
|
||||
|
||||
PrimitiveNode *node = static_cast<PrimitiveNode *>(index.internalPointer());
|
||||
|
||||
if (node->primitiveClass()->Deletable)
|
||||
m_undoStack->push(new DeletePrimitiveCommand(index, m_primitivesTreeModel, m_worldEditorScene, this));
|
||||
|
||||
}
|
||||
|
||||
void PrimitivesView::addNewPrimitiveByClass(int value)
|
||||
|
|
|
@ -95,7 +95,7 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode
|
|||
radius = atof(strRadius.c_str());
|
||||
qreal angle = ((2 * NLMISC::Pi - primPoint->Angle) * 180 / NLMISC::Pi);
|
||||
item = scene->addWorldItemPoint(QPointF(vec->x, -vec->y + cellSize),
|
||||
primPoint->Angle, radius, showArrow);
|
||||
angle, radius, showArrow);
|
||||
break;
|
||||
}
|
||||
case NLLIGO::CPrimitiveClass::Path:
|
||||
|
@ -430,6 +430,85 @@ void AddPrimitiveByClassCommand::redo()
|
|||
addNewGraphicsItems(m_model->pathToIndex(m_newPrimIndex), m_model, m_scene);
|
||||
}
|
||||
|
||||
DeletePrimitiveCommand::DeletePrimitiveCommand(const QModelIndex &index, PrimitivesTreeModel *model,
|
||||
WorldEditorScene *scene, QTreeView *view, QUndoCommand *parent)
|
||||
: QUndoCommand(parent),
|
||||
m_scene(scene),
|
||||
m_model(model),
|
||||
m_view(view)
|
||||
{
|
||||
setText("Delete primitive");
|
||||
|
||||
// Save path to primitive
|
||||
m_path = m_model->pathFromIndex(index);
|
||||
m_parentPath = m_model->pathFromIndex(index.parent());
|
||||
|
||||
PrimitiveNode *node = static_cast<PrimitiveNode *>(index.internalPointer());
|
||||
|
||||
NLLIGO::IPrimitive *primitive = node->primitive();
|
||||
|
||||
// Backup primitive
|
||||
m_oldPrimitive = primitive->copy();
|
||||
|
||||
// Backup position primitive
|
||||
primitive->getParent()->getChildId(m_posPrimitive, primitive);
|
||||
}
|
||||
|
||||
DeletePrimitiveCommand::~DeletePrimitiveCommand()
|
||||
{
|
||||
delete m_oldPrimitive;
|
||||
}
|
||||
|
||||
void DeletePrimitiveCommand::undo()
|
||||
{
|
||||
m_scene->setEnabledEditPoints(false);
|
||||
m_view->selectionModel()->clearSelection();
|
||||
|
||||
QModelIndex parentIndex = m_model->pathToIndex(m_parentPath);
|
||||
PrimitiveNode *parentNode = static_cast<PrimitiveNode *>(parentIndex.internalPointer());
|
||||
|
||||
// set the primitive context
|
||||
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = parentNode->rootPrimitiveNode()->primitives();
|
||||
|
||||
NLLIGO::IPrimitive *newPrimitive = m_oldPrimitive->copy();
|
||||
if (!parentNode->primitive()->insertChild(newPrimitive, m_posPrimitive))
|
||||
nlerror("Primitive can't insert, m_posPrimitive is not a valid.");
|
||||
|
||||
// Insert primitive node in tree model
|
||||
Path newPath = m_model->createPrimitiveNode(newPrimitive, m_parentPath, m_path.back().first);
|
||||
|
||||
// Scan graphics model
|
||||
addNewGraphicsItems(m_model->pathToIndex(newPath), m_model, m_scene);
|
||||
|
||||
// unset the context
|
||||
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL;
|
||||
}
|
||||
|
||||
void DeletePrimitiveCommand::redo()
|
||||
{
|
||||
m_scene->setEnabledEditPoints(false);
|
||||
m_view->selectionModel()->clearSelection();
|
||||
|
||||
QModelIndex index = m_model->pathToIndex(m_path);
|
||||
PrimitiveNode *node = static_cast<PrimitiveNode *>(index.internalPointer());
|
||||
NLLIGO::IPrimitive *primitive = node->primitive();
|
||||
|
||||
// Removes all graphics items
|
||||
removeGraphicsItems(index, m_model, m_scene);
|
||||
|
||||
// set the primitive context
|
||||
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = node->rootPrimitiveNode()->primitives();
|
||||
|
||||
// Delete primitive
|
||||
Utils::deletePrimitive(primitive);
|
||||
|
||||
// unset the context
|
||||
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL;
|
||||
|
||||
// Remove primitive from tree model
|
||||
m_model->deleteNode(m_path);
|
||||
}
|
||||
|
||||
AbstractWorldItemCommand::AbstractWorldItemCommand(const QList<QGraphicsItem *> &items,
|
||||
WorldEditorScene *scene,
|
||||
PrimitivesTreeModel *model,
|
||||
|
|
|
@ -156,9 +156,33 @@ private:
|
|||
float m_delta;
|
||||
const QString m_className;
|
||||
Path m_parentIndex, m_newPrimIndex;
|
||||
WorldEditorScene *m_scene;
|
||||
PrimitivesTreeModel *m_model;
|
||||
QTreeView *m_view;
|
||||
WorldEditorScene *const m_scene;
|
||||
PrimitivesTreeModel *const m_model;
|
||||
QTreeView *const m_view;
|
||||
};
|
||||
|
||||
/**
|
||||
@class DeletePrimitiveCommand
|
||||
@brief
|
||||
@details
|
||||
*/
|
||||
class DeletePrimitiveCommand: public QUndoCommand
|
||||
{
|
||||
public:
|
||||
DeletePrimitiveCommand(const QModelIndex &index, PrimitivesTreeModel *model,
|
||||
WorldEditorScene *scene, QTreeView *view, QUndoCommand *parent = 0);
|
||||
virtual ~DeletePrimitiveCommand();
|
||||
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
private:
|
||||
|
||||
Path m_path, m_parentPath;
|
||||
uint m_posPrimitive;
|
||||
NLLIGO::IPrimitive *m_oldPrimitive;
|
||||
WorldEditorScene *const m_scene;
|
||||
PrimitivesTreeModel *const m_model;
|
||||
QTreeView *const m_view;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -186,7 +210,7 @@ private:
|
|||
|
||||
const QList<Path> m_listPaths;
|
||||
PrimitivesTreeModel *const m_model;
|
||||
WorldEditorScene *m_scene;
|
||||
WorldEditorScene *const m_scene;
|
||||
bool m_firstRun;
|
||||
};
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ const int GRAPHICS_DATA_QT4_2D = USER_TYPE + 3;
|
|||
const int GRAPHICS_DATA_NEL3D = USER_TYPE + 4;
|
||||
const int PRIMITIVE_IS_MODIFIED = USER_TYPE + 5;
|
||||
const int PRIMITIVE_FILE_IS_CREATED = USER_TYPE + 6;
|
||||
const int PRIMITIVE_IS_VISIBLE = USER_TYPE + 7;
|
||||
|
||||
//settings
|
||||
const char *const WORLD_EDITOR_SECTION = "WorldEditor";
|
||||
|
|
|
@ -65,9 +65,6 @@ NLLIGO::IPrimitive *createPrimitive(const char *className, const char *primName,
|
|||
const std::vector<NLLIGO::CPrimitiveClass::CInitParameters> &initParameters,
|
||||
NLLIGO::IPrimitive *parent);
|
||||
|
||||
// Remove the primitive and don't delete it.
|
||||
//void takeAtPrimitive(NLLIGO::IPrimitive *primitive);
|
||||
|
||||
void deletePrimitive(NLLIGO::IPrimitive *primitive);
|
||||
|
||||
bool updateDefaultValues(NLLIGO::IPrimitive *primitive);
|
||||
|
|
|
@ -74,7 +74,6 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent)
|
|||
sceneModeGroup->addAction(m_ui.rotateAction);
|
||||
sceneModeGroup->addAction(m_ui.scaleAction);
|
||||
sceneModeGroup->addAction(m_ui.turnAction);
|
||||
sceneModeGroup->addAction(m_ui.radiusAction);
|
||||
m_ui.selectAction->setChecked(true);
|
||||
|
||||
m_ui.newWorldEditAction->setIcon(QIcon(Core::Constants::ICON_NEW));
|
||||
|
@ -95,8 +94,6 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent)
|
|||
m_modeMapper->setMapping(m_ui.scaleAction, 3);
|
||||
connect(m_ui.turnAction, SIGNAL(triggered()), m_modeMapper, SLOT(map()));
|
||||
m_modeMapper->setMapping(m_ui.turnAction, 4);
|
||||
connect(m_ui.radiusAction, SIGNAL(triggered()), m_modeMapper, SLOT(map()));
|
||||
m_modeMapper->setMapping(m_ui.radiusAction, 5);
|
||||
|
||||
connect(m_modeMapper, SIGNAL(mapped(int)), this, SLOT(setMode(int)));
|
||||
connect(m_ui.pointsAction, SIGNAL(triggered(bool)), m_worldEditorScene, SLOT(setEnabledEditPoints(bool)));
|
||||
|
@ -384,9 +381,10 @@ void WorldEditorWindow::readSettings()
|
|||
restoreGeometry(settings->value(Constants::WORLD_WINDOW_GEOMETRY).toByteArray());
|
||||
|
||||
// Use OpenGL graphics system instead raster graphics system
|
||||
if (settings->value(Constants::WORLD_EDITOR_USE_OPENGL, false).toBool())
|
||||
if (settings->value(Constants::WORLD_EDITOR_USE_OPENGL, true).toBool())
|
||||
{
|
||||
m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer));
|
||||
//m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer));
|
||||
m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers));
|
||||
m_ui.graphicsView->setViewport(m_oglWidget);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="renderHints">
|
||||
<set>QPainter::Antialiasing|QPainter::SmoothPixmapTransform|QPainter::TextAntialiasing</set>
|
||||
</property>
|
||||
<property name="dragMode">
|
||||
<enum>QGraphicsView::NoDrag</enum>
|
||||
</property>
|
||||
|
@ -72,7 +75,6 @@
|
|||
<addaction name="rotateAction"/>
|
||||
<addaction name="scaleAction"/>
|
||||
<addaction name="turnAction"/>
|
||||
<addaction name="radiusAction"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="pointsAction"/>
|
||||
</widget>
|
||||
|
@ -316,17 +318,6 @@
|
|||
<string>Turn</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="radiusAction">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Radius</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="pointsAction">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
|
|
Loading…
Reference in a new issue