Changed: #1302 Added "delete primitive" undo command.

This commit is contained in:
dnk-88 2011-08-20 16:10:35 +03:00
parent 74ca89ab38
commit 8c14b55871
13 changed files with 166 additions and 46 deletions

View file

@ -52,7 +52,7 @@ public:
QStringList listPixmaps() const; QStringList listPixmaps() const;
/// Get original pixmap /// Get original pixmap
/// @return QPixmap* if the image is in the database ; /// @return QPixmap* if the image is in the database ;
/// otherwise returns pixmap which contains error message. /// otherwise returns pixmap which contains error message.
QPixmap *pixmap(const QString &zoneName) const; QPixmap *pixmap(const QString &zoneName) const;

View file

@ -68,7 +68,7 @@ QString ObjectViewerPlugin::version() const
QString ObjectViewerPlugin::vendor() const QString ObjectViewerPlugin::vendor() const
{ {
return Core::Constants::OVQT_VENDOR; return "GSoC2010_dnk-88";
} }
QString ObjectViewerPlugin::description() const QString ObjectViewerPlugin::description() const

View file

@ -34,6 +34,7 @@ namespace WorldEditor
Node::Node() Node::Node()
: m_parent(0) : m_parent(0)
{ {
setData(Constants::PRIMITIVE_IS_VISIBLE, true);
} }
Node::~Node() Node::~Node()
@ -102,6 +103,18 @@ void Node::insertChildNodeAfter(Node *node, Node *after)
node->m_parent = this; 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) void Node::removeChildNode(Node *node)
{ {
nlassert(m_children.contains(node)); nlassert(m_children.contains(node));

View file

@ -72,6 +72,9 @@ public:
/// Insert node in back of the node pointed to by the pointer after. /// Insert node in back of the node pointed to by the pointer after.
void insertChildNodeAfter(Node *node, Node *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. /// Return the node at index position row in the child list.
Node *child(int row); Node *child(int row);

View file

@ -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) if (m_worldEditNode == 0)
createWorldEditNode("NewWorldEdit"); createWorldEditNode("NewWorldEdit");
@ -223,42 +223,48 @@ Path PrimitivesTreeModel::createRootPrimitiveNode(const QString &fileName, NLLIG
if (!fileName.isEmpty()) if (!fileName.isEmpty())
name = fileName; name = fileName;
int insPos = pos;
// Get position // Get position
int pos = m_worldEditNode->childCount(); if (pos == AtTheEnd)
insPos = m_worldEditNode->childCount();
QModelIndex parentIndex = index(0, 0, QModelIndex()); QModelIndex parentIndex = index(0, 0, QModelIndex());
// Add root node in tree model // Add root node in tree model
beginInsertRows(parentIndex, pos, pos); beginInsertRows(parentIndex, insPos, insPos);
RootPrimitiveNode *newNode = new RootPrimitiveNode(name, primitives); RootPrimitiveNode *newNode = new RootPrimitiveNode(name, primitives);
m_worldEditNode->appendChildNode(newNode); m_worldEditNode->insertChildNode(insPos, newNode);
endInsertRows(); endInsertRows();
newNode->setData(Constants::PRIMITIVE_FILE_IS_CREATED, !fileName.isEmpty()); newNode->setData(Constants::PRIMITIVE_FILE_IS_CREATED, !fileName.isEmpty());
newNode->setData(Constants::PRIMITIVE_IS_MODIFIED, false); 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 // Scan childs items and add in the tree model
for (uint i = 0; i < primitives->RootNode->getNumChildren(); ++i) for (uint i = 0; i < primitives->RootNode->getNumChildren(); ++i)
{ {
NLLIGO::IPrimitive *childPrim; NLLIGO::IPrimitive *childPrim;
primitives->RootNode->getChild(childPrim, i); primitives->RootNode->getChild(childPrim, i);
createChildNodes(childPrim, rootPrimIndex); createChildNodes(childPrim, i, rootPrimIndex);
} }
return pathFromIndex(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); QModelIndex parentIndex = pathToIndex(parent);
Node *parentNode = static_cast<Node *>(parentIndex.internalPointer()); 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) void PrimitivesTreeModel::deleteNode(const Path &path)
@ -271,16 +277,14 @@ void PrimitivesTreeModel::deleteNode(const Path &path)
removeChildNodes(node, parentIndex); 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()); Node *parentNode = static_cast<Node *>(parent.internalPointer());
int pos = parentNode->childCount();
// Add node in the tree model // Add node in the tree model
beginInsertRows(parent, pos, pos); beginInsertRows(parent, pos, pos);
PrimitiveNode *newNode = new PrimitiveNode(primitive); PrimitiveNode *newNode = new PrimitiveNode(primitive);
parentNode->appendChildNode(newNode); parentNode->insertChildNode(pos, newNode);
endInsertRows(); endInsertRows();
// Scan childs items and add in the tree model // Scan childs items and add in the tree model
@ -289,7 +293,7 @@ void PrimitivesTreeModel::createChildNodes(NLLIGO::IPrimitive *primitive, const
{ {
NLLIGO::IPrimitive *childPrim; NLLIGO::IPrimitive *childPrim;
primitive->getChild(childPrim, i); primitive->getChild(childPrim, i);
createChildNodes(childPrim, childIndex); createChildNodes(childPrim, i, childIndex);
} }
} }

View file

@ -34,6 +34,8 @@ namespace WorldEditor
class Node; class Node;
class WorldEditNode; class WorldEditNode;
const int AtTheEnd = -1;
typedef QPair<int, int> PathItem; typedef QPair<int, int> PathItem;
/* /*
@typedef Path @typedef Path
@ -81,16 +83,16 @@ public:
Path createLandscapeNode(const QString &fileName); Path createLandscapeNode(const QString &fileName);
/// Add new root primitive node and all sub-primitives in the tree model. /// 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. /// 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 /// Delete node and all child nodes from the tree model
void deleteNode(const Path &path); void deleteNode(const Path &path);
private: 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); void removeChildNodes(Node *node, const QModelIndex &parent);

View file

@ -66,7 +66,7 @@ PrimitivesView::PrimitivesView(QWidget *parent)
m_newPrimitiveAction = new QAction("New primitive", this); m_newPrimitiveAction = new QAction("New primitive", this);
m_deleteAction = new QAction("Delete", this); m_deleteAction = new QAction("Delete", this);
m_deleteAction->setEnabled(false); //m_deleteAction->setEnabled(false);
m_selectChildrenAction = new QAction("Select children", this); m_selectChildrenAction = new QAction("Select children", this);
@ -243,6 +243,14 @@ void PrimitivesView::deletePrimitives()
nlassert(m_primitivesTreeModel); nlassert(m_primitivesTreeModel);
QModelIndexList indexList = selectionModel()->selectedRows(); 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) void PrimitivesView::addNewPrimitiveByClass(int value)

View file

@ -95,7 +95,7 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode
radius = atof(strRadius.c_str()); radius = atof(strRadius.c_str());
qreal angle = ((2 * NLMISC::Pi - primPoint->Angle) * 180 / NLMISC::Pi); qreal angle = ((2 * NLMISC::Pi - primPoint->Angle) * 180 / NLMISC::Pi);
item = scene->addWorldItemPoint(QPointF(vec->x, -vec->y + cellSize), item = scene->addWorldItemPoint(QPointF(vec->x, -vec->y + cellSize),
primPoint->Angle, radius, showArrow); angle, radius, showArrow);
break; break;
} }
case NLLIGO::CPrimitiveClass::Path: case NLLIGO::CPrimitiveClass::Path:
@ -430,6 +430,85 @@ void AddPrimitiveByClassCommand::redo()
addNewGraphicsItems(m_model->pathToIndex(m_newPrimIndex), m_model, m_scene); 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, AbstractWorldItemCommand::AbstractWorldItemCommand(const QList<QGraphicsItem *> &items,
WorldEditorScene *scene, WorldEditorScene *scene,
PrimitivesTreeModel *model, PrimitivesTreeModel *model,

View file

@ -156,9 +156,33 @@ private:
float m_delta; float m_delta;
const QString m_className; const QString m_className;
Path m_parentIndex, m_newPrimIndex; Path m_parentIndex, m_newPrimIndex;
WorldEditorScene *m_scene; WorldEditorScene *const m_scene;
PrimitivesTreeModel *m_model; PrimitivesTreeModel *const m_model;
QTreeView *m_view; 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; const QList<Path> m_listPaths;
PrimitivesTreeModel *const m_model; PrimitivesTreeModel *const m_model;
WorldEditorScene *m_scene; WorldEditorScene *const m_scene;
bool m_firstRun; bool m_firstRun;
}; };

View file

@ -30,6 +30,7 @@ const int GRAPHICS_DATA_QT4_2D = USER_TYPE + 3;
const int GRAPHICS_DATA_NEL3D = USER_TYPE + 4; const int GRAPHICS_DATA_NEL3D = USER_TYPE + 4;
const int PRIMITIVE_IS_MODIFIED = USER_TYPE + 5; const int PRIMITIVE_IS_MODIFIED = USER_TYPE + 5;
const int PRIMITIVE_FILE_IS_CREATED = USER_TYPE + 6; const int PRIMITIVE_FILE_IS_CREATED = USER_TYPE + 6;
const int PRIMITIVE_IS_VISIBLE = USER_TYPE + 7;
//settings //settings
const char *const WORLD_EDITOR_SECTION = "WorldEditor"; const char *const WORLD_EDITOR_SECTION = "WorldEditor";

View file

@ -65,9 +65,6 @@ NLLIGO::IPrimitive *createPrimitive(const char *className, const char *primName,
const std::vector<NLLIGO::CPrimitiveClass::CInitParameters> &initParameters, const std::vector<NLLIGO::CPrimitiveClass::CInitParameters> &initParameters,
NLLIGO::IPrimitive *parent); NLLIGO::IPrimitive *parent);
// Remove the primitive and don't delete it.
//void takeAtPrimitive(NLLIGO::IPrimitive *primitive);
void deletePrimitive(NLLIGO::IPrimitive *primitive); void deletePrimitive(NLLIGO::IPrimitive *primitive);
bool updateDefaultValues(NLLIGO::IPrimitive *primitive); bool updateDefaultValues(NLLIGO::IPrimitive *primitive);

View file

@ -74,7 +74,6 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent)
sceneModeGroup->addAction(m_ui.rotateAction); sceneModeGroup->addAction(m_ui.rotateAction);
sceneModeGroup->addAction(m_ui.scaleAction); sceneModeGroup->addAction(m_ui.scaleAction);
sceneModeGroup->addAction(m_ui.turnAction); sceneModeGroup->addAction(m_ui.turnAction);
sceneModeGroup->addAction(m_ui.radiusAction);
m_ui.selectAction->setChecked(true); m_ui.selectAction->setChecked(true);
m_ui.newWorldEditAction->setIcon(QIcon(Core::Constants::ICON_NEW)); m_ui.newWorldEditAction->setIcon(QIcon(Core::Constants::ICON_NEW));
@ -95,8 +94,6 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent)
m_modeMapper->setMapping(m_ui.scaleAction, 3); m_modeMapper->setMapping(m_ui.scaleAction, 3);
connect(m_ui.turnAction, SIGNAL(triggered()), m_modeMapper, SLOT(map())); connect(m_ui.turnAction, SIGNAL(triggered()), m_modeMapper, SLOT(map()));
m_modeMapper->setMapping(m_ui.turnAction, 4); 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_modeMapper, SIGNAL(mapped(int)), this, SLOT(setMode(int)));
connect(m_ui.pointsAction, SIGNAL(triggered(bool)), m_worldEditorScene, SLOT(setEnabledEditPoints(bool))); 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()); restoreGeometry(settings->value(Constants::WORLD_WINDOW_GEOMETRY).toByteArray());
// Use OpenGL graphics system instead raster graphics system // 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); m_ui.graphicsView->setViewport(m_oglWidget);
} }

View file

@ -27,6 +27,9 @@
<property name="alignment"> <property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property> </property>
<property name="renderHints">
<set>QPainter::Antialiasing|QPainter::SmoothPixmapTransform|QPainter::TextAntialiasing</set>
</property>
<property name="dragMode"> <property name="dragMode">
<enum>QGraphicsView::NoDrag</enum> <enum>QGraphicsView::NoDrag</enum>
</property> </property>
@ -72,7 +75,6 @@
<addaction name="rotateAction"/> <addaction name="rotateAction"/>
<addaction name="scaleAction"/> <addaction name="scaleAction"/>
<addaction name="turnAction"/> <addaction name="turnAction"/>
<addaction name="radiusAction"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="pointsAction"/> <addaction name="pointsAction"/>
</widget> </widget>
@ -316,17 +318,6 @@
<string>Turn</string> <string>Turn</string>
</property> </property>
</action> </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"> <action name="pointsAction">
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>