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

--HG--
branch : gsoc2011-worldeditorqt
This commit is contained in:
dnk-88 2011-08-20 16:10:35 +03:00
parent da6828daf0
commit 3ccb85e0a4
13 changed files with 166 additions and 46 deletions

View file

@ -52,7 +52,7 @@ public:
QStringList listPixmaps() const;
/// 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.
QPixmap *pixmap(const QString &zoneName) const;

View file

@ -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

View file

@ -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));

View file

@ -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);

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)
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);
}
}

View file

@ -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);

View file

@ -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)

View file

@ -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,

View file

@ -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;
};

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 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";

View file

@ -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);

View file

@ -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);
}

View file

@ -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>