From 3ccfad6d6b259c39ca9d8edc7dbc75653a913f40 Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Thu, 2 Jun 2011 16:57:10 +0300
Subject: [PATCH 01/19] Added: #1301 Added pixmap database

---
 .../plugins/landscape_editor/CMakeLists.txt   |   6 +-
 .../plugins/landscape_editor/builder_zone.cpp | 104 +++++++
 .../plugins/landscape_editor/builder_zone.h   |  75 +++++
 .../landscape_editor/builder_zone_region.cpp  |  28 ++
 .../landscape_editor/builder_zone_region.h    |  33 +++
 .../landscape_editor_plugin.h                 |   2 +-
 .../landscape_editor_window.cpp               |   7 +-
 .../landscape_editor_window.h                 |   2 +
 .../landscape_editor_window.ui                |  17 ++
 .../landscape_editor/landscape_scene.cpp      |  38 +++
 .../landscape_editor/landscape_scene.h        |  42 +++
 .../landscape_editor/zone_list_model.cpp      | 165 +++++++++++
 .../landscape_editor/zone_list_model.h        |  82 ++++++
 .../landscape_editor/zone_list_widget.cpp     |  44 +++
 .../landscape_editor/zone_list_widget.h       |  54 ++++
 .../landscape_editor/zone_list_widget.ui      | 266 ++++++++++++++++++
 16 files changed, 962 insertions(+), 3 deletions(-)
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.cpp
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.h
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.cpp
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.h
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.ui

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
index 3b6a61c5e..2f7487fe7 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
@@ -11,9 +11,13 @@ SET(OVQT_EXT_SYS_SRC	${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin.
 
 SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR	landscape_editor_plugin.h
 					landscape_editor_window.h
+					landscape_scene.h
+					zone_list_model.h
+					zone_list_widget.h
 )
 
 SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_UIS	landscape_editor_window.ui
+					zone_list_widget.ui
 )
 
 SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_RCS landscape_editor.qrc)
@@ -37,7 +41,7 @@ ADD_LIBRARY(ovqt_plugin_landscape_editor MODULE ${SRC}
 						${OVQT_PLUGIN_LANDSCAPE_EDITOR_UI_HDRS}
 						${OVQT_PLUGIN_LANDSCAPE_EDITOR_RC_SRCS})
 
-TARGET_LINK_LIBRARIES(ovqt_plugin_landscape_editor ovqt_plugin_core nelmisc nel3d ${QT_LIBRARIES} ${QT_QTOPENGL_LIBRARY})
+TARGET_LINK_LIBRARIES(ovqt_plugin_landscape_editor ovqt_plugin_core nelmisc nel3d nelgeorges nelligo ${QT_LIBRARIES} ${QT_QTOPENGL_LIBRARY})
 
 NL_DEFAULT_PROPS(ovqt_plugin_landscape_editor "NeL, Tools, 3D: Object Viewer Qt Plugin: Landscape Editor")
 NL_ADD_RUNTIME_FLAGS(ovqt_plugin_landscape_editor)
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
new file mode 100644
index 000000000..d79770cf3
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
@@ -0,0 +1,104 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+// Project includes
+#include "builder_zone.h"
+#include "zone_list_model.h"
+
+// NeL includes
+#include <nel/misc/debug.h>
+
+// Qt includes
+#include <QtCore/QDir>
+#include <QtGui/QMessageBox>
+
+namespace LandscapeEditor
+{
+
+ZoneBuilder::ZoneBuilder()
+	: m_zoneListModel(0)
+{
+	m_zoneListModel = new ZoneListModel();
+	m_lastPathName = "";
+}
+
+ZoneBuilder::~ZoneBuilder()
+{
+	delete m_zoneListModel;
+}
+
+bool ZoneBuilder::init(const QString &pathName, bool makeAZone)
+{
+	bool bRet = true;
+	if (pathName != m_lastPathName)
+	{
+		m_lastPathName = pathName;
+		QString zoneBankPath = pathName;
+		zoneBankPath += "/zoneligos/";
+
+		// Init the ZoneBank
+		m_zoneBank.reset ();
+		if (!initZoneBank (zoneBankPath))
+		{
+			m_zoneBank.reset ();
+			return false;
+		}
+		// Construct the DataBase from the ZoneBank
+		QString zoneBitmapPath = pathName;
+		zoneBitmapPath += "/zonebitmaps/";
+		m_zoneListModel->resetModel();
+		if (!m_zoneListModel->rebuildModel(zoneBitmapPath, m_zoneBank))
+		{
+			m_zoneBank.reset();
+			return false;
+		}
+	}
+
+	if ((makeAZone) && (bRet))
+		newZone();
+	return bRet;
+}
+
+bool ZoneBuilder::initZoneBank (const QString &pathName)
+{
+	QDir *dir = new QDir(pathName);
+	QStringList filters;
+	filters << "*.ligozone";
+
+	// Find all ligozone files in dir
+	QStringList listFiles = dir->entryList(filters, QDir::Files);
+
+	std::string error;
+	Q_FOREACH(QString file, listFiles)
+	{
+		//nlinfo(file.toStdString().c_str());
+		if (!m_zoneBank.addElement((pathName + file).toStdString(), error))
+			QMessageBox::critical(0, QObject::tr("Landscape editor"), QString(error.c_str()), QMessageBox::Ok);
+	}
+	return true;
+}
+
+ZoneListModel *ZoneBuilder::zoneModel() const
+{
+	return m_zoneListModel;
+}
+
+void ZoneBuilder::newZone (bool bDisplay)
+{
+}
+
+} /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
new file mode 100644
index 000000000..b578a2bb2
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
@@ -0,0 +1,75 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef BUILDER_ZONE_H
+#define BUILDER_ZONE_H
+
+// Project includes
+
+// NeL includes
+#include <nel/ligo/zone_bank.h>
+
+// STL includes
+#include <string>
+#include <vector>
+
+// Qt includes
+#include <QtCore/QString>
+
+namespace LandscapeEditor
+{
+class ZoneListModel;
+
+/**
+@class ZoneBuilder
+@brief ZoneBuilder contains all the shared data between the tools and the engine
+@details ZoneBank contains the macro zones that is composed of several zones plus a mask
+ZoneListModel contains the graphics for the zones
+*/
+class ZoneBuilder
+{
+public:
+	ZoneBuilder();
+	~ZoneBuilder();
+
+	// Init zoneBank and init zone pixmap database
+	bool init(const QString &pathName, bool bMakeAZone);
+
+	void newZone(bool bDisplay=true);
+
+	// Accessors
+	NLLIGO::CZoneBank &getZoneBank()
+	{
+		return m_zoneBank;
+	}
+	ZoneListModel *zoneModel() const;
+private:
+
+	// Scan ./zoneligos dir and add all *.ligozone files to zoneBank
+	bool initZoneBank (const QString &path);
+
+	sint32 m_minX, m_maxX, m_minY, m_maxY;
+	QString m_lastPathName;
+
+	ZoneListModel *m_zoneListModel;
+	NLLIGO::CZoneBank m_zoneBank;
+	std::vector<NLLIGO::CZoneBankElement*> m_currentSelection;
+};
+
+} /* namespace LandscapeEditor */
+
+#endif // BUILDER_ZONE_H
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp
new file mode 100644
index 000000000..4dbd3e9e1
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp
@@ -0,0 +1,28 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+// Project includes
+#include "builder_zone_region.h"
+
+// NeL includes
+#include <nel/misc/debug.h>
+
+// Qt includes
+
+namespace LandscapeEditor
+{
+} /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h
new file mode 100644
index 000000000..158c72715
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h
@@ -0,0 +1,33 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef BUILDER_ZONE_REGION_H
+#define BUILDER_ZONE_REGION_H
+
+// Project includes
+
+// NeL includes
+#include <nel/ligo/zone_bank.h>
+
+// Qt includes
+
+namespace LandscapeEditor
+{
+
+} /* namespace LandscapeEditor */
+
+#endif // BUILDER_ZONE_REGION_H
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h
index 67a3172ee..8f9f811cf 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h
@@ -91,7 +91,7 @@ public:
 	}
 	virtual QIcon icon() const
 	{
-		return QIcon();
+		return QIcon(Constants::ICON_LANDSCAPE_ITEM);
 	}
 
 	virtual void open();
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
index 4b075adfc..c46278f38 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
@@ -18,6 +18,7 @@
 // Project includes
 #include "landscape_editor_window.h"
 #include "landscape_editor_constants.h"
+#include "zone_list_model.h"
 
 #include "../core/icore.h"
 #include "../core/imenu_manager.h"
@@ -40,7 +41,11 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
 	m_ui.setupUi(this);
 
 	m_undoStack = new QUndoStack(this);
-
+	/*
+		m_zoneBuilder = new ZoneBuilder();
+		m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", false);
+		m_ui.zoneListWidget->setModel(m_zoneBuilder->zoneModel());
+	*/
 	createMenus();
 	readSettings();
 }
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
index cc17e6cbc..61e0c7eb1 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
@@ -20,6 +20,7 @@
 
 // Project includes
 #include "ui_landscape_editor_window.h"
+#include "builder_zone.h"
 
 // Qt includes
 #include <QtGui/QUndoStack>
@@ -47,6 +48,7 @@ private:
 	void readSettings();
 	void writeSettings();
 
+	ZoneBuilder *m_zoneBuilder;
 	QUndoStack *m_undoStack;
 	Ui::LandscapeEditorWindow m_ui;
 }; /* class LandscapeEditorWindow */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
index 5d9606ddf..ce6e905a3 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
@@ -35,7 +35,24 @@
     <bool>false</bool>
    </attribute>
   </widget>
+  <widget class="QDockWidget" name="dockWidget">
+   <property name="windowTitle">
+    <string>Zones</string>
+   </property>
+   <attribute name="dockWidgetArea">
+    <number>2</number>
+   </attribute>
+   <widget class="LandscapeEditor::ZoneListWidget" name="zoneListWidget"/>
+  </widget>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>LandscapeEditor::ZoneListWidget</class>
+   <extends>QWidget</extends>
+   <header>zone_list_widget.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
  <resources>
   <include location="landscape_editor.qrc"/>
  </resources>
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
new file mode 100644
index 000000000..f491dfa2b
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
@@ -0,0 +1,38 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+// Project includes
+#include "landscape_scene.h"
+
+// NeL includes
+#include <nel/misc/debug.h>
+
+// Qt includes
+
+namespace LandscapeEditor
+{
+
+LandscapeScene::LandscapeScene(QObject *parent)
+	: QGraphicsScene(parent)
+{
+}
+
+LandscapeScene::~LandscapeScene()
+{
+}
+
+} /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
new file mode 100644
index 000000000..d4fb91c78
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
@@ -0,0 +1,42 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef LANDSCAPE_SCENE_H
+#define LANDSCAPE_SCENE_H
+
+// Project includes
+
+// NeL includes
+
+// Qt includes
+#include <QGraphicsScene>
+
+namespace LandscapeEditor
+{
+
+class LandscapeScene : public QGraphicsScene
+{
+	Q_OBJECT
+
+public:
+	LandscapeScene(QObject *parent = 0);
+	virtual ~LandscapeScene();
+};
+
+} /* namespace LandscapeEditor */
+
+#endif // LANDSCAPE_SCENE_H
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.cpp
new file mode 100644
index 000000000..32dded570
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.cpp
@@ -0,0 +1,165 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+// Project includes
+#include "zone_list_model.h"
+
+// NeL includes
+#include <nel/misc/debug.h>
+
+// STL includes
+#include <string>
+#include <vector>
+
+// Qt includes
+#include <QApplication>
+#include <QSize>
+#include <QtGui/QProgressDialog>
+
+namespace LandscapeEditor
+{
+
+ZoneListModel::ZoneListModel(int pixmapSize, QObject *parent)
+	: QAbstractListModel(parent),
+	  m_pixmapSize(pixmapSize)
+{
+
+}
+ZoneListModel::~ZoneListModel()
+{
+	resetModel();
+}
+
+int ZoneListModel::rowCount(const QModelIndex & /* parent */) const
+{
+	return m_pixmapMap.count();
+}
+
+int ZoneListModel::columnCount(const QModelIndex & /* parent */) const
+{
+	return 1;
+}
+
+QVariant ZoneListModel::data(const QModelIndex &index, int role) const
+{
+	if (!index.isValid())
+		return QVariant();
+
+	if (role == Qt::TextAlignmentRole)
+	{
+		return int(Qt::AlignLeft | Qt::AlignVCenter);
+	}
+	else if (role == Qt::DisplayRole)
+	{
+		return m_pixmapNameList.at(index.row());
+	}
+	else if (role == Qt::DecorationRole)
+	{
+		QPixmap *pixmap = getSmallPixmap(m_pixmapNameList.at(index.row()));
+		return qVariantFromValue(*pixmap);
+	}
+	return QVariant();
+}
+
+QVariant ZoneListModel::headerData(int section,
+								   Qt::Orientation /* orientation */,
+								   int role) const
+{
+	if (role != Qt::DisplayRole)
+		return QVariant();
+	return QVariant();
+}
+
+void ZoneListModel::setSmallPixmapSize(int pixmapSize)
+{
+	m_pixmapSize = pixmapSize;
+}
+
+void ZoneListModel::resetModel()
+{
+	beginResetModel();
+	Q_FOREACH(QString name, m_pixmapNameList)
+	{
+		QPixmap *pixmap = m_pixmapMap.value(name);
+		delete pixmap;
+		QPixmap *smallPixmap = m_smallPixmapMap.value(name);
+		delete smallPixmap;
+	}
+	m_pixmapMap.clear();
+	m_pixmapNameList.clear();
+	m_smallPixmapMap.clear();
+	endResetModel();
+}
+
+bool ZoneListModel::rebuildModel(const QString &zonePath, NLLIGO::CZoneBank &zoneBank)
+{
+	beginResetModel();
+	m_zonePath = zonePath;
+
+	QProgressDialog *progressDialog = new QProgressDialog();
+
+	std::vector<std::string> zoneNames;
+	zoneBank.getCategoryValues ("zone", zoneNames);
+	progressDialog->setRange(0, zoneNames.size());
+	for (uint i = 0; i < zoneNames.size(); ++i)
+	{
+		QApplication::processEvents();
+		progressDialog->setValue(i);
+
+		NLLIGO::CZoneBankElement *zoneBankItem = zoneBank.getElementByZoneName (zoneNames[i]);
+
+		// Read the texture file
+		QString zonePixmapName(zoneNames[i].c_str());
+		uint8 sizeX = zoneBankItem->getSizeX();
+		uint8 sizeY = zoneBankItem->getSizeY();
+		const std::vector<bool> &rMask = zoneBankItem->getMask();
+
+		QPixmap *pixmap = new QPixmap(zonePath + zonePixmapName + ".png");
+		QPixmap *smallPixmap = new QPixmap(pixmap->scaled(m_pixmapSize * sizeX, m_pixmapSize * sizeY));
+
+		m_pixmapMap.insert(zonePixmapName, pixmap);
+		m_smallPixmapMap.insert(zonePixmapName, smallPixmap);
+
+	}
+	m_pixmapNameList = m_pixmapMap.keys();
+	endResetModel();
+	delete progressDialog;
+	return false;
+}
+
+QPixmap *ZoneListModel::getPixmap(const QString &zoneName) const
+{
+	QPixmap *result = 0;
+	if (!m_pixmapMap.contains(zoneName))
+		nlwarning("QPixmap %s not found", zoneName.toStdString().c_str());
+	else
+		result = m_pixmapMap.value(zoneName);
+	return result;
+}
+
+QPixmap *ZoneListModel::getSmallPixmap(const QString &zoneName) const
+{
+	QPixmap *result = 0;
+	if (!m_pixmapMap.contains(zoneName))
+		nlwarning("QPixmap %s not found", zoneName.toStdString().c_str());
+	else
+		result = m_smallPixmapMap.value(zoneName);
+	return result;
+}
+
+
+} /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.h
new file mode 100644
index 000000000..1bfb0f93f
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.h
@@ -0,0 +1,82 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef ZONE_LIST_MODEL_H
+#define ZONE_LIST_MODEL_H
+
+// Project includes
+
+// NeL includes
+#include <nel/ligo/zone_bank.h>
+
+// Qt includes
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtGui/QPixmap>
+#include <QAbstractListModel>
+
+namespace LandscapeEditor
+{
+
+/**
+@class ZoneListModel
+@brief ZoneListModel contains the image database for QGraphicsScene and
+small images for QListView
+@details
+*/
+class ZoneListModel : public QAbstractListModel
+{
+	Q_OBJECT
+public:
+	ZoneListModel(int pixmapSize = 64, QObject *parent = 0);
+	~ZoneListModel();
+
+	int rowCount(const QModelIndex &parent) const;
+	int columnCount(const QModelIndex &parent) const;
+	QVariant data(const QModelIndex &index, int role) const;
+	QVariant headerData(int section, Qt::Orientation orientation,
+						int role) const;
+
+	/// Set size for small pixmaps
+	/// Value should be set before calling rebuildModel
+	void setSmallPixmapSize(int pixmapSize);
+
+	/// Unload all images and reset model
+	void resetModel();
+
+	/// Load all images(png) from zonePath, list images gets from zoneBank
+	bool rebuildModel(const QString &zonePath, NLLIGO::CZoneBank &zoneBank);
+
+	/// Get original pixmap
+	/// @return QPixmap* if the image is in the database ; otherwise returns 0.
+	QPixmap *getPixmap(const QString &zoneName) const;
+
+	/// Get scaled pixmap (pixmapSize * zoneSize.sizeX, pixmapSize * zoneSize.sizeY)
+	/// @return QPixmap* if the image is in the database ; otherwise returns 0.
+	QPixmap *getSmallPixmap(const QString &zoneName) const;
+private:
+
+	QString m_zonePath;
+	int m_pixmapSize;
+	QMap<QString, QPixmap*> m_pixmapMap;
+	QMap<QString, QPixmap*> m_smallPixmapMap;
+	QList<QString> m_pixmapNameList;
+};
+
+} /* namespace LandscapeEditor */
+
+#endif // ZONE_LIST_MODEL_H
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.cpp
new file mode 100644
index 000000000..423c2c50f
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.cpp
@@ -0,0 +1,44 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+// Project includes
+#include "zone_list_widget.h"
+
+// NeL includes
+#include <nel/misc/debug.h>
+
+// Qt includes
+
+namespace LandscapeEditor
+{
+
+ZoneListWidget::ZoneListWidget(QWidget *parent)
+	: QWidget(parent)
+{
+	m_ui.setupUi(this);
+}
+
+ZoneListWidget::~ZoneListWidget()
+{
+}
+
+void ZoneListWidget::setModel(QAbstractItemModel *model)
+{
+	m_ui.listView->setModel(model);
+}
+
+} /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.h
new file mode 100644
index 000000000..5b90f81d6
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.h
@@ -0,0 +1,54 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef ZONE_LIST_WIDGET_H
+#define ZONE_LIST_WIDGET_H
+
+// Project includes
+#include "ui_zone_list_widget.h"
+
+// NeL includes
+
+// Qt includes
+
+namespace LandscapeEditor
+{
+/**
+@class ZoneListWidget
+@brief ZoneListWidget
+@details
+*/
+class ZoneListWidget: public QWidget
+{
+	Q_OBJECT
+
+public:
+	ZoneListWidget(QWidget *parent = 0);
+	~ZoneListWidget();
+
+	void setModel(QAbstractItemModel *model);
+
+Q_SIGNALS:
+public Q_SLOTS:
+private Q_SLOTS:
+private:
+	Ui::ZoneListWidget m_ui;
+}; /* ZoneListWidget */
+
+} /* namespace LandscapeEditor */
+
+#endif // ZONE_LIST_WIDGET_H
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.ui
new file mode 100644
index 000000000..725e6cf83
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.ui
@@ -0,0 +1,266 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ZoneListWidget</class>
+ <widget class="QWidget" name="ZoneListWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>359</width>
+    <height>579</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout_3">
+   <property name="margin">
+    <number>3</number>
+   </property>
+   <property name="spacing">
+    <number>3</number>
+   </property>
+   <item row="0" column="0">
+    <widget class="QGroupBox" name="groupBox_2">
+     <property name="title">
+      <string>Filter</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_2">
+      <property name="margin">
+       <number>6</number>
+      </property>
+      <property name="spacing">
+       <number>3</number>
+      </property>
+      <item row="0" column="0">
+       <widget class="QComboBox" name="comboBox_3">
+        <item>
+         <property name="text">
+          <string>&lt;Unused&gt;</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QComboBox" name="comboBox_7"/>
+      </item>
+      <item row="0" column="2">
+       <widget class="QComboBox" name="comboBox_11">
+        <item>
+         <property name="text">
+          <string>Random</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Fyll cycle</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QComboBox" name="comboBox_6">
+        <property name="enabled">
+         <bool>true</bool>
+        </property>
+        <item>
+         <property name="text">
+          <string>&lt;Unused&gt;</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QComboBox" name="comboBox_8">
+        <property name="enabled">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="2">
+       <widget class="QComboBox" name="comboBox_12">
+        <property name="enabled">
+         <bool>true</bool>
+        </property>
+        <item>
+         <property name="text">
+          <string>And</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Or</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="2" column="0">
+       <widget class="QComboBox" name="comboBox_4">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <item>
+         <property name="text">
+          <string>&lt;Unused&gt;</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QComboBox" name="comboBox_9">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="2">
+       <widget class="QComboBox" name="comboBox_13">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <item>
+         <property name="text">
+          <string>And</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Or</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="3" column="0">
+       <widget class="QComboBox" name="comboBox_5">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <item>
+         <property name="text">
+          <string>&lt;Unused&gt;</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="3" column="1">
+       <widget class="QComboBox" name="comboBox_10">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="2">
+       <widget class="QComboBox" name="comboBox_14">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <item>
+         <property name="text">
+          <string>And</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Or</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
+      <string>Placement</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <property name="margin">
+       <number>6</number>
+      </property>
+      <property name="spacing">
+       <number>3</number>
+      </property>
+      <item row="0" column="0">
+       <widget class="QComboBox" name="comboBox">
+        <item>
+         <property name="text">
+          <string>0°</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>90°</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>180°</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>170°</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Random</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Full cycle</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QComboBox" name="comboBox_2">
+        <item>
+         <property name="text">
+          <string>NoFlip</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Flip</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Random</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Fyll cycle</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="0" column="2">
+       <widget class="QCheckBox" name="checkBox">
+        <property name="text">
+         <string>Force</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="3">
+       <widget class="QCheckBox" name="checkBox_2">
+        <property name="text">
+         <string>Not propogate</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QListView" name="listView"/>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

From cd729782990d031f2d7f965ed7741f2a83c48603 Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Thu, 2 Jun 2011 23:31:21 +0300
Subject: [PATCH 02/19] Added: #1301 Added filter for list zones in landscape
 editor.

---
 .../plugins/landscape_editor/CMakeLists.txt   |   7 +-
 .../plugins/landscape_editor/builder_zone.cpp |   7 +-
 .../plugins/landscape_editor/builder_zone.h   |   6 +-
 ..._list_widget.cpp => landscape_actions.cpp} |  18 +-
 ...zone_list_widget.h => landscape_actions.h} |  28 +-
 .../landscape_editor_window.cpp               |  12 +-
 .../landscape_editor_window.ui                |   6 +-
 ...ne_list_model.cpp => list_zones_model.cpp} |  46 +-
 .../{zone_list_model.h => list_zones_model.h} |  18 +-
 .../landscape_editor/list_zones_widget.cpp    | 219 ++++++++
 .../landscape_editor/list_zones_widget.h      |  68 +++
 .../landscape_editor/list_zones_widget.ui     | 478 ++++++++++++++++++
 .../landscape_editor/zone_list_widget.ui      | 266 ----------
 13 files changed, 827 insertions(+), 352 deletions(-)
 rename code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/{zone_list_widget.cpp => landscape_actions.cpp} (76%)
 rename code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/{zone_list_widget.h => landscape_actions.h} (68%)
 rename code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/{zone_list_model.cpp => list_zones_model.cpp} (73%)
 rename code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/{zone_list_model.h => list_zones_model.h} (86%)
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui
 delete mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.ui

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
index 2f7487fe7..714d1f125 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
@@ -12,12 +12,13 @@ SET(OVQT_EXT_SYS_SRC	${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin.
 SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR	landscape_editor_plugin.h
 					landscape_editor_window.h
 					landscape_scene.h
-					zone_list_model.h
-					zone_list_widget.h
+					list_zones_model.h
+					list_zones_widget.h
+					landscape_actions.h
 )
 
 SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_UIS	landscape_editor_window.ui
-					zone_list_widget.ui
+					list_zones_widget.ui
 )
 
 SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_RCS landscape_editor.qrc)
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
index d79770cf3..42242921e 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
@@ -17,7 +17,7 @@
 
 // Project includes
 #include "builder_zone.h"
-#include "zone_list_model.h"
+#include "list_zones_model.h"
 
 // NeL includes
 #include <nel/misc/debug.h>
@@ -32,7 +32,7 @@ namespace LandscapeEditor
 ZoneBuilder::ZoneBuilder()
 	: m_zoneListModel(0)
 {
-	m_zoneListModel = new ZoneListModel();
+	m_zoneListModel = new ListZonesModel();
 	m_lastPathName = "";
 }
 
@@ -67,7 +67,6 @@ bool ZoneBuilder::init(const QString &pathName, bool makeAZone)
 			return false;
 		}
 	}
-
 	if ((makeAZone) && (bRet))
 		newZone();
 	return bRet;
@@ -92,7 +91,7 @@ bool ZoneBuilder::initZoneBank (const QString &pathName)
 	return true;
 }
 
-ZoneListModel *ZoneBuilder::zoneModel() const
+ListZonesModel *ZoneBuilder::zoneModel() const
 {
 	return m_zoneListModel;
 }
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
index b578a2bb2..97c4d8d3a 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
@@ -32,7 +32,7 @@
 
 namespace LandscapeEditor
 {
-class ZoneListModel;
+class ListZonesModel;
 
 /**
 @class ZoneBuilder
@@ -56,7 +56,7 @@ public:
 	{
 		return m_zoneBank;
 	}
-	ZoneListModel *zoneModel() const;
+	ListZonesModel *zoneModel() const;
 private:
 
 	// Scan ./zoneligos dir and add all *.ligozone files to zoneBank
@@ -65,7 +65,7 @@ private:
 	sint32 m_minX, m_maxX, m_minY, m_maxY;
 	QString m_lastPathName;
 
-	ZoneListModel *m_zoneListModel;
+	ListZonesModel *m_zoneListModel;
 	NLLIGO::CZoneBank m_zoneBank;
 	std::vector<NLLIGO::CZoneBankElement*> m_currentSelection;
 };
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
similarity index 76%
rename from code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.cpp
rename to code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
index 423c2c50f..f0b86dd8e 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
@@ -16,7 +16,7 @@
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 // Project includes
-#include "zone_list_widget.h"
+#include "landscape_actions.h"
 
 // NeL includes
 #include <nel/misc/debug.h>
@@ -25,20 +25,4 @@
 
 namespace LandscapeEditor
 {
-
-ZoneListWidget::ZoneListWidget(QWidget *parent)
-	: QWidget(parent)
-{
-	m_ui.setupUi(this);
-}
-
-ZoneListWidget::~ZoneListWidget()
-{
-}
-
-void ZoneListWidget::setModel(QAbstractItemModel *model)
-{
-	m_ui.listView->setModel(model);
-}
-
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
similarity index 68%
rename from code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.h
rename to code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
index 5b90f81d6..fdcda5451 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
@@ -15,11 +15,10 @@
 // You should have received a copy of the GNU Affero General Public License
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#ifndef ZONE_LIST_WIDGET_H
-#define ZONE_LIST_WIDGET_H
+#ifndef LANDSCAPE_ACTIONS_H
+#define LANDSCAPE_ACTIONS_H
 
 // Project includes
-#include "ui_zone_list_widget.h"
 
 // NeL includes
 
@@ -27,28 +26,7 @@
 
 namespace LandscapeEditor
 {
-/**
-@class ZoneListWidget
-@brief ZoneListWidget
-@details
-*/
-class ZoneListWidget: public QWidget
-{
-	Q_OBJECT
-
-public:
-	ZoneListWidget(QWidget *parent = 0);
-	~ZoneListWidget();
-
-	void setModel(QAbstractItemModel *model);
-
-Q_SIGNALS:
-public Q_SLOTS:
-private Q_SLOTS:
-private:
-	Ui::ZoneListWidget m_ui;
-}; /* ZoneListWidget */
 
 } /* namespace LandscapeEditor */
 
-#endif // ZONE_LIST_WIDGET_H
+#endif // LANDSCAPE_ACTIONS_H
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
index c46278f38..eb9b8b8e8 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
@@ -18,7 +18,7 @@
 // Project includes
 #include "landscape_editor_window.h"
 #include "landscape_editor_constants.h"
-#include "zone_list_model.h"
+#include "list_zones_model.h"
 
 #include "../core/icore.h"
 #include "../core/imenu_manager.h"
@@ -41,11 +41,11 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
 	m_ui.setupUi(this);
 
 	m_undoStack = new QUndoStack(this);
-	/*
-		m_zoneBuilder = new ZoneBuilder();
-		m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", false);
-		m_ui.zoneListWidget->setModel(m_zoneBuilder->zoneModel());
-	*/
+	m_zoneBuilder = new ZoneBuilder();
+	m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", false);
+	m_ui.zoneListWidget->setModel(m_zoneBuilder->zoneModel());
+	m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder);
+	m_ui.zoneListWidget->updateUi();
 	createMenus();
 	readSettings();
 }
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
index ce6e905a3..ac16ad9fd 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
@@ -42,14 +42,14 @@
    <attribute name="dockWidgetArea">
     <number>2</number>
    </attribute>
-   <widget class="LandscapeEditor::ZoneListWidget" name="zoneListWidget"/>
+   <widget class="LandscapeEditor::ListZonesWidget" name="zoneListWidget"/>
   </widget>
  </widget>
  <customwidgets>
   <customwidget>
-   <class>LandscapeEditor::ZoneListWidget</class>
+   <class>LandscapeEditor::ListZonesWidget</class>
    <extends>QWidget</extends>
-   <header>zone_list_widget.h</header>
+   <header>list_zones_widget.h</header>
    <container>1</container>
   </customwidget>
  </customwidgets>
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp
similarity index 73%
rename from code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.cpp
rename to code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp
index 32dded570..ffcb7617b 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp
@@ -16,7 +16,7 @@
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 // Project includes
-#include "zone_list_model.h"
+#include "list_zones_model.h"
 
 // NeL includes
 #include <nel/misc/debug.h>
@@ -33,28 +33,28 @@
 namespace LandscapeEditor
 {
 
-ZoneListModel::ZoneListModel(int pixmapSize, QObject *parent)
+ListZonesModel::ListZonesModel(int pixmapSize, QObject *parent)
 	: QAbstractListModel(parent),
 	  m_pixmapSize(pixmapSize)
 {
 
 }
-ZoneListModel::~ZoneListModel()
+ListZonesModel::~ListZonesModel()
 {
 	resetModel();
 }
 
-int ZoneListModel::rowCount(const QModelIndex & /* parent */) const
+int ListZonesModel::rowCount(const QModelIndex & /* parent */) const
 {
-	return m_pixmapMap.count();
+	return m_pixmapNameList.count();
 }
 
-int ZoneListModel::columnCount(const QModelIndex & /* parent */) const
+int ListZonesModel::columnCount(const QModelIndex & /* parent */) const
 {
 	return 1;
 }
 
-QVariant ZoneListModel::data(const QModelIndex &index, int role) const
+QVariant ListZonesModel::data(const QModelIndex &index, int role) const
 {
 	if (!index.isValid())
 		return QVariant();
@@ -75,21 +75,29 @@ QVariant ZoneListModel::data(const QModelIndex &index, int role) const
 	return QVariant();
 }
 
-QVariant ZoneListModel::headerData(int section,
-								   Qt::Orientation /* orientation */,
-								   int role) const
+QVariant ListZonesModel::headerData(int section,
+									Qt::Orientation /* orientation */,
+									int role) const
 {
 	if (role != Qt::DisplayRole)
 		return QVariant();
 	return QVariant();
 }
 
-void ZoneListModel::setSmallPixmapSize(int pixmapSize)
+void ListZonesModel::setSmallPixmapSize(int pixmapSize)
 {
 	m_pixmapSize = pixmapSize;
 }
 
-void ZoneListModel::resetModel()
+void ListZonesModel::setListZones(QStringList &listZones)
+{
+	beginResetModel();
+	m_pixmapNameList.clear();
+	m_pixmapNameList = listZones;
+	endResetModel();
+}
+
+void ListZonesModel::resetModel()
 {
 	beginResetModel();
 	Q_FOREACH(QString name, m_pixmapNameList)
@@ -105,12 +113,13 @@ void ZoneListModel::resetModel()
 	endResetModel();
 }
 
-bool ZoneListModel::rebuildModel(const QString &zonePath, NLLIGO::CZoneBank &zoneBank)
+bool ListZonesModel::rebuildModel(const QString &zonePath, NLLIGO::CZoneBank &zoneBank)
 {
 	beginResetModel();
 	m_zonePath = zonePath;
 
 	QProgressDialog *progressDialog = new QProgressDialog();
+	progressDialog->show();
 
 	std::vector<std::string> zoneNames;
 	zoneBank.getCategoryValues ("zone", zoneNames);
@@ -129,19 +138,22 @@ bool ZoneListModel::rebuildModel(const QString &zonePath, NLLIGO::CZoneBank &zon
 		const std::vector<bool> &rMask = zoneBankItem->getMask();
 
 		QPixmap *pixmap = new QPixmap(zonePath + zonePixmapName + ".png");
+		if (pixmap->isNull())
+		{
+			// Generate filled pixmap
+		}
 		QPixmap *smallPixmap = new QPixmap(pixmap->scaled(m_pixmapSize * sizeX, m_pixmapSize * sizeY));
 
 		m_pixmapMap.insert(zonePixmapName, pixmap);
 		m_smallPixmapMap.insert(zonePixmapName, smallPixmap);
 
 	}
-	m_pixmapNameList = m_pixmapMap.keys();
 	endResetModel();
 	delete progressDialog;
-	return false;
+	return true;
 }
 
-QPixmap *ZoneListModel::getPixmap(const QString &zoneName) const
+QPixmap *ListZonesModel::getPixmap(const QString &zoneName) const
 {
 	QPixmap *result = 0;
 	if (!m_pixmapMap.contains(zoneName))
@@ -151,7 +163,7 @@ QPixmap *ZoneListModel::getPixmap(const QString &zoneName) const
 	return result;
 }
 
-QPixmap *ZoneListModel::getSmallPixmap(const QString &zoneName) const
+QPixmap *ListZonesModel::getSmallPixmap(const QString &zoneName) const
 {
 	QPixmap *result = 0;
 	if (!m_pixmapMap.contains(zoneName))
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h
similarity index 86%
rename from code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.h
rename to code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h
index 1bfb0f93f..16a28bf07 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h
@@ -15,8 +15,8 @@
 // You should have received a copy of the GNU Affero General Public License
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#ifndef ZONE_LIST_MODEL_H
-#define ZONE_LIST_MODEL_H
+#ifndef LIST_ZONES_MODEL_H
+#define LIST_ZONES_MODEL_H
 
 // Project includes
 
@@ -33,17 +33,17 @@ namespace LandscapeEditor
 {
 
 /**
-@class ZoneListModel
-@brief ZoneListModel contains the image database for QGraphicsScene and
+@class ListZonesModel
+@brief ListZonesModel contains the image database for QGraphicsScene and
 small images for QListView
 @details
 */
-class ZoneListModel : public QAbstractListModel
+class ListZonesModel : public QAbstractListModel
 {
 	Q_OBJECT
 public:
-	ZoneListModel(int pixmapSize = 64, QObject *parent = 0);
-	~ZoneListModel();
+	ListZonesModel(int pixmapSize = 64, QObject *parent = 0);
+	~ListZonesModel();
 
 	int rowCount(const QModelIndex &parent) const;
 	int columnCount(const QModelIndex &parent) const;
@@ -58,6 +58,8 @@ public:
 	/// Unload all images and reset model
 	void resetModel();
 
+	void setListZones(QStringList &listZones);
+
 	/// Load all images(png) from zonePath, list images gets from zoneBank
 	bool rebuildModel(const QString &zonePath, NLLIGO::CZoneBank &zoneBank);
 
@@ -79,4 +81,4 @@ private:
 
 } /* namespace LandscapeEditor */
 
-#endif // ZONE_LIST_MODEL_H
+#endif // LIST_ZONES_MODEL_H
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
new file mode 100644
index 000000000..8dcb87383
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
@@ -0,0 +1,219 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+// Project includes
+#include "list_zones_widget.h"
+#include "builder_zone.h"
+#include "list_zones_model.h"
+
+// NeL includes
+#include <nel/misc/debug.h>
+#include <nel/ligo/zone_bank.h>
+#include <nel/ligo/zone_region.h>
+
+// STL includes
+#include <vector>
+#include <string>
+
+// Qt includes
+#include <QtGui/QIcon>
+
+namespace LandscapeEditor
+{
+
+ListZonesWidget::ListZonesWidget(QWidget *parent)
+	: QWidget(parent),
+	  m_zoneBuilder(0)
+{
+	m_ui.setupUi(this);
+
+	m_ui.addFilterButton_1->setChecked(false);
+	m_ui.addFilterButton_2->setChecked(false);
+	m_ui.addFilterButton_3->setChecked(false);
+
+	connect(m_ui.categoryTypeComboBox_1, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateFilters_1(QString)));
+	connect(m_ui.categoryTypeComboBox_2, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateFilters_2(QString)));
+	connect(m_ui.categoryTypeComboBox_3, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateFilters_3(QString)));
+	connect(m_ui.categoryTypeComboBox_4, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateFilters_4(QString)));
+	connect(m_ui.categoryValueComboBox_1, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
+	connect(m_ui.categoryValueComboBox_2, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
+	connect(m_ui.categoryValueComboBox_3, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
+	connect(m_ui.categoryValueComboBox_4, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
+	connect(m_ui.logicComboBox_2, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
+	connect(m_ui.logicComboBox_3, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
+	connect(m_ui.logicComboBox_4, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
+}
+
+ListZonesWidget::~ListZonesWidget()
+{
+}
+
+void ListZonesWidget::updateUi()
+{
+	if (m_zoneBuilder == 0)
+		return;
+
+	disableSignals(true);
+	std::vector<std::string> listCategoryType;
+	m_zoneBuilder->getZoneBank().getCategoriesType(listCategoryType);
+
+	QStringList listCategories;
+
+	listCategories << STRING_UNUSED;
+	for (size_t i = 0; i < listCategoryType.size(); ++i)
+		listCategories << QString(listCategoryType[i].c_str());
+
+	m_ui.categoryTypeComboBox_1->clear();
+	m_ui.categoryTypeComboBox_2->clear();
+	m_ui.categoryTypeComboBox_3->clear();
+	m_ui.categoryTypeComboBox_4->clear();
+
+	m_ui.categoryTypeComboBox_1->addItems(listCategories);
+	m_ui.categoryTypeComboBox_2->addItems(listCategories);
+	m_ui.categoryTypeComboBox_3->addItems(listCategories);
+	m_ui.categoryTypeComboBox_4->addItems(listCategories);
+
+	disableSignals(false);
+}
+
+void ListZonesWidget::setModel(QAbstractItemModel *model)
+{
+	m_ui.listView->setModel(model);
+}
+
+void ListZonesWidget::setZoneBuilder(ZoneBuilder *zoneBuilder)
+{
+	m_zoneBuilder = zoneBuilder;
+}
+
+void ListZonesWidget::updateFilters_1(const QString &value)
+{
+	disableSignals(true);
+	std::vector<std::string> allCategoryValues;
+	m_zoneBuilder->getZoneBank().getCategoryValues(value.toStdString(), allCategoryValues);
+	m_ui.categoryValueComboBox_1->clear();
+	for(size_t i = 0; i < allCategoryValues.size(); ++i)
+		m_ui.categoryValueComboBox_1->addItem(QString(allCategoryValues[i].c_str()));
+
+	disableSignals(false);
+	updateListZones();
+}
+
+void ListZonesWidget::updateFilters_2(const QString &value)
+{
+	disableSignals(true);
+	std::vector<std::string> allCategoryValues;
+	m_zoneBuilder->getZoneBank().getCategoryValues(value.toStdString(), allCategoryValues);
+
+	m_ui.categoryValueComboBox_2->clear();
+	for(size_t i = 0; i < allCategoryValues.size(); ++i)
+		m_ui.categoryValueComboBox_2->addItem(QString(allCategoryValues[i].c_str()));
+
+	disableSignals(false);
+	updateListZones();
+}
+
+void ListZonesWidget::updateFilters_3(const QString &value)
+{
+	disableSignals(true);
+	std::vector<std::string> allCategoryValues;
+	m_zoneBuilder->getZoneBank().getCategoryValues(value.toStdString(), allCategoryValues);
+
+	m_ui.categoryValueComboBox_3->clear();
+	for(size_t i = 0; i < allCategoryValues.size(); ++i)
+		m_ui.categoryValueComboBox_3->addItem(QString(allCategoryValues[i].c_str()));
+
+	disableSignals(false);
+	updateListZones();
+}
+
+void ListZonesWidget::updateFilters_4(const QString &value)
+{
+	disableSignals(true);
+	std::vector<std::string> allCategoryValues;
+	m_zoneBuilder->getZoneBank().getCategoryValues(value.toStdString(), allCategoryValues);
+
+	m_ui.categoryValueComboBox_4->clear();
+	for(size_t i = 0; i < allCategoryValues.size(); ++i)
+		m_ui.categoryValueComboBox_4->addItem(QString(allCategoryValues[i].c_str()));
+
+	disableSignals(false);
+	updateListZones();
+}
+
+void ListZonesWidget::updateListZones()
+{
+	// Execute the filter
+	NLLIGO::CZoneBank &zoneBank = m_zoneBuilder->getZoneBank();
+	zoneBank.resetSelection ();
+
+	if(m_ui.categoryTypeComboBox_1->currentIndex() > 0 )
+		zoneBank.addOrSwitch (m_ui.categoryTypeComboBox_1->currentText().toStdString()
+							  , m_ui.categoryValueComboBox_1->currentText().toStdString());
+
+	if(m_ui.categoryTypeComboBox_2->currentIndex() > 0 )
+	{
+		if (m_ui.logicComboBox_2->currentIndex() == 0) // AND switch wanted
+			zoneBank.addAndSwitch(m_ui.categoryTypeComboBox_2->currentText().toStdString()
+								  ,m_ui.categoryValueComboBox_2->currentText().toStdString());
+		else // OR switch wanted
+			zoneBank.addOrSwitch(m_ui.categoryTypeComboBox_2->currentText().toStdString()
+								 ,m_ui.categoryValueComboBox_2->currentText().toStdString());
+	}
+
+	if(m_ui.categoryTypeComboBox_3->currentIndex() > 0 )
+	{
+		if (m_ui.logicComboBox_3->currentIndex() == 0) // AND switch wanted
+			zoneBank.addAndSwitch(m_ui.categoryTypeComboBox_3->currentText().toStdString()
+								  ,m_ui.categoryValueComboBox_3->currentText().toStdString());
+		else // OR switch wanted
+			zoneBank.addOrSwitch(m_ui.categoryTypeComboBox_3->currentText().toStdString()
+								 ,m_ui.categoryValueComboBox_3->currentText().toStdString());
+	}
+
+	if(m_ui.categoryTypeComboBox_4->currentIndex() > 0 )
+	{
+		if (m_ui.logicComboBox_4->currentIndex() == 0) // AND switch wanted
+			zoneBank.addAndSwitch(m_ui.categoryTypeComboBox_4->currentText().toStdString()
+								  ,m_ui.categoryValueComboBox_4->currentText().toStdString());
+		else // OR switch wanted
+			zoneBank.addOrSwitch(m_ui.categoryTypeComboBox_4->currentText().toStdString()
+								 ,m_ui.categoryValueComboBox_4->currentText().toStdString());
+	}
+
+	std::vector<NLLIGO::CZoneBankElement *> currentSelection;
+	zoneBank.getSelection (currentSelection);
+
+	QStringList listSelection;
+	for (size_t i = 0; i < currentSelection.size(); ++i)
+		listSelection << currentSelection[i]->getName().c_str();
+	m_zoneBuilder->zoneModel()->setListZones(listSelection);
+}
+
+void ListZonesWidget::disableSignals(bool block)
+{
+	m_ui.categoryTypeComboBox_1->blockSignals(block);
+	m_ui.categoryTypeComboBox_2->blockSignals(block);
+	m_ui.categoryTypeComboBox_3->blockSignals(block);
+	m_ui.categoryTypeComboBox_4->blockSignals(block);
+	m_ui.categoryValueComboBox_1->blockSignals(block);
+	m_ui.categoryValueComboBox_2->blockSignals(block);
+	m_ui.categoryValueComboBox_3->blockSignals(block);
+	m_ui.categoryValueComboBox_4->blockSignals(block);
+}
+
+} /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
new file mode 100644
index 000000000..fed0134cf
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
@@ -0,0 +1,68 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef LIST_ZONES_WIDGET_H
+#define LIST_ZONES_WIDGET_H
+
+// Project includes
+#include "ui_list_zones_widget.h"
+
+// NeL includes
+
+// Qt includes
+
+namespace LandscapeEditor
+{
+class ZoneBuilder;
+
+/**
+@class ZoneListWidget
+@brief ZoneListWidget
+@details
+*/
+class ListZonesWidget: public QWidget
+{
+	Q_OBJECT
+
+public:
+	ListZonesWidget(QWidget *parent = 0);
+	~ListZonesWidget();
+
+	void updateUi();
+	void setZoneBuilder(ZoneBuilder *zoneBuilder);
+	void setModel(QAbstractItemModel *model);
+
+Q_SIGNALS:
+public Q_SLOTS:
+	void updateFilters_1(const QString &value);
+	void updateFilters_2(const QString &value);
+	void updateFilters_3(const QString &value);
+	void updateFilters_4(const QString &value);
+
+private Q_SLOTS:
+	void updateListZones();
+
+private:
+	void disableSignals(bool block);
+
+	ZoneBuilder *m_zoneBuilder;
+	Ui::ListZonesWidget m_ui;
+}; /* ZoneListWidget */
+
+} /* namespace LandscapeEditor */
+
+#endif // LIST_ZONES_WIDGET_H
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui
new file mode 100644
index 000000000..585371cb7
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui
@@ -0,0 +1,478 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ListZonesWidget</class>
+ <widget class="QWidget" name="ListZonesWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>359</width>
+    <height>579</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout_3">
+   <property name="margin">
+    <number>3</number>
+   </property>
+   <property name="spacing">
+    <number>3</number>
+   </property>
+   <item row="0" column="0">
+    <widget class="QGroupBox" name="groupBox_2">
+     <property name="title">
+      <string>Filter</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_2">
+      <property name="margin">
+       <number>6</number>
+      </property>
+      <property name="spacing">
+       <number>3</number>
+      </property>
+      <item row="0" column="1">
+       <widget class="QComboBox" name="categoryTypeComboBox_1"/>
+      </item>
+      <item row="0" column="2">
+       <widget class="QComboBox" name="categoryValueComboBox_1"/>
+      </item>
+      <item row="0" column="3">
+       <widget class="QComboBox" name="comboBox_11">
+        <item>
+         <property name="text">
+          <string>Random</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Fyll cycle</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QComboBox" name="categoryTypeComboBox_2">
+        <property name="enabled">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="2">
+       <widget class="QComboBox" name="categoryValueComboBox_2">
+        <property name="enabled">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="3">
+       <widget class="QComboBox" name="logicComboBox_2">
+        <property name="enabled">
+         <bool>true</bool>
+        </property>
+        <item>
+         <property name="text">
+          <string>And</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Or</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QComboBox" name="categoryTypeComboBox_3">
+        <property name="enabled">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="2">
+       <widget class="QComboBox" name="categoryValueComboBox_3">
+        <property name="enabled">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="3">
+       <widget class="QComboBox" name="logicComboBox_3">
+        <property name="enabled">
+         <bool>true</bool>
+        </property>
+        <item>
+         <property name="text">
+          <string>And</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Or</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="3" column="1">
+       <widget class="QComboBox" name="categoryTypeComboBox_4">
+        <property name="enabled">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="2">
+       <widget class="QComboBox" name="categoryValueComboBox_4">
+        <property name="enabled">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="3">
+       <widget class="QComboBox" name="logicComboBox_4">
+        <property name="enabled">
+         <bool>true</bool>
+        </property>
+        <item>
+         <property name="text">
+          <string>And</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Or</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="0" column="0">
+       <widget class="QToolButton" name="addFilterButton_1">
+        <property name="text">
+         <string>...</string>
+        </property>
+        <property name="icon">
+         <iconset resource="../core/core.qrc">
+          <normaloff>:/core/icons/ic_nel_add_item.png</normaloff>
+          <normalon>:/core/icons/ic_nel_delete_item.png</normalon>:/core/icons/ic_nel_add_item.png</iconset>
+        </property>
+        <property name="checkable">
+         <bool>true</bool>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QToolButton" name="addFilterButton_2">
+        <property name="text">
+         <string>...</string>
+        </property>
+        <property name="icon">
+         <iconset resource="../core/core.qrc">
+          <normaloff>:/core/icons/ic_nel_add_item.png</normaloff>
+          <normalon>:/core/icons/ic_nel_delete_item.png</normalon>:/core/icons/ic_nel_add_item.png</iconset>
+        </property>
+        <property name="checkable">
+         <bool>true</bool>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0">
+       <widget class="QToolButton" name="addFilterButton_3">
+        <property name="text">
+         <string>...</string>
+        </property>
+        <property name="icon">
+         <iconset resource="../core/core.qrc">
+          <normaloff>:/core/icons/ic_nel_add_item.png</normaloff>
+          <normalon>:/core/icons/ic_nel_delete_item.png</normalon>:/core/icons/ic_nel_add_item.png</iconset>
+        </property>
+        <property name="checkable">
+         <bool>true</bool>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
+      <string>Placement</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <property name="margin">
+       <number>6</number>
+      </property>
+      <property name="spacing">
+       <number>3</number>
+      </property>
+      <item row="0" column="0">
+       <widget class="QComboBox" name="comboBox">
+        <item>
+         <property name="text">
+          <string>0°</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>90°</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>180°</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>170°</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Random</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Full cycle</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QComboBox" name="comboBox_2">
+        <item>
+         <property name="text">
+          <string>NoFlip</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Flip</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Random</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Fyll cycle</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="0" column="2">
+       <widget class="QCheckBox" name="checkBox">
+        <property name="text">
+         <string>Force</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="3">
+       <widget class="QCheckBox" name="checkBox_2">
+        <property name="text">
+         <string>Not propogate</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QListView" name="listView"/>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../core/core.qrc"/>
+ </resources>
+ <connections>
+  <connection>
+   <sender>addFilterButton_1</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>categoryTypeComboBox_2</receiver>
+   <slot>setVisible(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>20</x>
+     <y>36</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>81</x>
+     <y>53</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>addFilterButton_1</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>categoryValueComboBox_2</receiver>
+   <slot>setVisible(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>24</x>
+     <y>32</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>181</x>
+     <y>50</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>addFilterButton_1</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>logicComboBox_2</receiver>
+   <slot>setVisible(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>20</x>
+     <y>31</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>301</x>
+     <y>55</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>addFilterButton_2</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>categoryTypeComboBox_3</receiver>
+   <slot>setVisible(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>27</x>
+     <y>62</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>57</x>
+     <y>75</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>addFilterButton_2</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>categoryValueComboBox_3</receiver>
+   <slot>setVisible(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>23</x>
+     <y>58</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>156</x>
+     <y>76</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>addFilterButton_2</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>logicComboBox_3</receiver>
+   <slot>setVisible(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>23</x>
+     <y>53</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>255</x>
+     <y>77</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>addFilterButton_3</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>categoryTypeComboBox_4</receiver>
+   <slot>setVisible(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>32</x>
+     <y>94</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>44</x>
+     <y>104</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>addFilterButton_3</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>categoryValueComboBox_4</receiver>
+   <slot>setVisible(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>32</x>
+     <y>94</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>207</x>
+     <y>103</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>addFilterButton_3</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>logicComboBox_4</receiver>
+   <slot>setVisible(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>21</x>
+     <y>81</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>278</x>
+     <y>104</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>addFilterButton_2</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>addFilterButton_3</receiver>
+   <slot>setVisible(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>15</x>
+     <y>59</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>16</x>
+     <y>80</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>addFilterButton_1</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>addFilterButton_2</receiver>
+   <slot>setVisible(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>13</x>
+     <y>35</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>17</x>
+     <y>60</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.ui
deleted file mode 100644
index 725e6cf83..000000000
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.ui
+++ /dev/null
@@ -1,266 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ZoneListWidget</class>
- <widget class="QWidget" name="ZoneListWidget">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>359</width>
-    <height>579</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Form</string>
-  </property>
-  <layout class="QGridLayout" name="gridLayout_3">
-   <property name="margin">
-    <number>3</number>
-   </property>
-   <property name="spacing">
-    <number>3</number>
-   </property>
-   <item row="0" column="0">
-    <widget class="QGroupBox" name="groupBox_2">
-     <property name="title">
-      <string>Filter</string>
-     </property>
-     <layout class="QGridLayout" name="gridLayout_2">
-      <property name="margin">
-       <number>6</number>
-      </property>
-      <property name="spacing">
-       <number>3</number>
-      </property>
-      <item row="0" column="0">
-       <widget class="QComboBox" name="comboBox_3">
-        <item>
-         <property name="text">
-          <string>&lt;Unused&gt;</string>
-         </property>
-        </item>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <widget class="QComboBox" name="comboBox_7"/>
-      </item>
-      <item row="0" column="2">
-       <widget class="QComboBox" name="comboBox_11">
-        <item>
-         <property name="text">
-          <string>Random</string>
-         </property>
-        </item>
-        <item>
-         <property name="text">
-          <string>Fyll cycle</string>
-         </property>
-        </item>
-       </widget>
-      </item>
-      <item row="1" column="0">
-       <widget class="QComboBox" name="comboBox_6">
-        <property name="enabled">
-         <bool>true</bool>
-        </property>
-        <item>
-         <property name="text">
-          <string>&lt;Unused&gt;</string>
-         </property>
-        </item>
-       </widget>
-      </item>
-      <item row="1" column="1">
-       <widget class="QComboBox" name="comboBox_8">
-        <property name="enabled">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="2">
-       <widget class="QComboBox" name="comboBox_12">
-        <property name="enabled">
-         <bool>true</bool>
-        </property>
-        <item>
-         <property name="text">
-          <string>And</string>
-         </property>
-        </item>
-        <item>
-         <property name="text">
-          <string>Or</string>
-         </property>
-        </item>
-       </widget>
-      </item>
-      <item row="2" column="0">
-       <widget class="QComboBox" name="comboBox_4">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-        <item>
-         <property name="text">
-          <string>&lt;Unused&gt;</string>
-         </property>
-        </item>
-       </widget>
-      </item>
-      <item row="2" column="1">
-       <widget class="QComboBox" name="comboBox_9">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="2">
-       <widget class="QComboBox" name="comboBox_13">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-        <item>
-         <property name="text">
-          <string>And</string>
-         </property>
-        </item>
-        <item>
-         <property name="text">
-          <string>Or</string>
-         </property>
-        </item>
-       </widget>
-      </item>
-      <item row="3" column="0">
-       <widget class="QComboBox" name="comboBox_5">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-        <item>
-         <property name="text">
-          <string>&lt;Unused&gt;</string>
-         </property>
-        </item>
-       </widget>
-      </item>
-      <item row="3" column="1">
-       <widget class="QComboBox" name="comboBox_10">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-       </widget>
-      </item>
-      <item row="3" column="2">
-       <widget class="QComboBox" name="comboBox_14">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-        <item>
-         <property name="text">
-          <string>And</string>
-         </property>
-        </item>
-        <item>
-         <property name="text">
-          <string>Or</string>
-         </property>
-        </item>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item row="1" column="0">
-    <widget class="QGroupBox" name="groupBox">
-     <property name="title">
-      <string>Placement</string>
-     </property>
-     <layout class="QGridLayout" name="gridLayout">
-      <property name="margin">
-       <number>6</number>
-      </property>
-      <property name="spacing">
-       <number>3</number>
-      </property>
-      <item row="0" column="0">
-       <widget class="QComboBox" name="comboBox">
-        <item>
-         <property name="text">
-          <string>0°</string>
-         </property>
-        </item>
-        <item>
-         <property name="text">
-          <string>90°</string>
-         </property>
-        </item>
-        <item>
-         <property name="text">
-          <string>180°</string>
-         </property>
-        </item>
-        <item>
-         <property name="text">
-          <string>170°</string>
-         </property>
-        </item>
-        <item>
-         <property name="text">
-          <string>Random</string>
-         </property>
-        </item>
-        <item>
-         <property name="text">
-          <string>Full cycle</string>
-         </property>
-        </item>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <widget class="QComboBox" name="comboBox_2">
-        <item>
-         <property name="text">
-          <string>NoFlip</string>
-         </property>
-        </item>
-        <item>
-         <property name="text">
-          <string>Flip</string>
-         </property>
-        </item>
-        <item>
-         <property name="text">
-          <string>Random</string>
-         </property>
-        </item>
-        <item>
-         <property name="text">
-          <string>Fyll cycle</string>
-         </property>
-        </item>
-       </widget>
-      </item>
-      <item row="0" column="2">
-       <widget class="QCheckBox" name="checkBox">
-        <property name="text">
-         <string>Force</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="3">
-       <widget class="QCheckBox" name="checkBox_2">
-        <property name="text">
-         <string>Not propogate</string>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item row="2" column="0">
-    <widget class="QListView" name="listView"/>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>

From f02f5525aa0978376857f0e9c36d9b1395928077 Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Sat, 4 Jun 2011 17:29:08 +0300
Subject: [PATCH 03/19] Changed: #1301 Added project settings dialog.

---
 .../plugins/landscape_editor/CMakeLists.txt   |  2 +
 .../plugins/landscape_editor/builder_zone.cpp | 97 +++++++++++++++++--
 .../plugins/landscape_editor/builder_zone.h   | 43 +++++++-
 .../landscape_editor_window.cpp               | 33 ++++++-
 .../landscape_editor_window.h                 |  3 +
 .../landscape_editor_window.ui                | 23 ++++-
 .../landscape_editor/list_zones_model.cpp     | 80 +++++----------
 .../landscape_editor/list_zones_model.h       | 27 +++---
 .../landscape_editor/list_zones_widget.cpp    | 16 ++-
 .../landscape_editor/list_zones_widget.h      |  9 +-
 .../project_settings_dialog.cpp               | 52 ++++++++++
 .../project_settings_dialog.h                 | 46 +++++++++
 .../project_settings_dialog.ui                | 97 +++++++++++++++++++
 13 files changed, 429 insertions(+), 99 deletions(-)
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
index 714d1f125..227210366 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
@@ -15,10 +15,12 @@ SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR	landscape_editor_plugin.h
 					list_zones_model.h
 					list_zones_widget.h
 					landscape_actions.h
+					project_settings_dialog.h
 )
 
 SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_UIS	landscape_editor_window.ui
 					list_zones_widget.ui
+					project_settings_dialog.ui
 )
 
 SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_RCS landscape_editor.qrc)
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
index 42242921e..3db771224 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
@@ -17,7 +17,6 @@
 
 // Project includes
 #include "builder_zone.h"
-#include "list_zones_model.h"
 
 // NeL includes
 #include <nel/misc/debug.h>
@@ -25,20 +24,97 @@
 // Qt includes
 #include <QtCore/QDir>
 #include <QtGui/QMessageBox>
+#include <QtGui/QApplication>
+#include <QtGui/QProgressDialog>
 
 namespace LandscapeEditor
 {
+const int PixmapScale = 256;
+
+PixmapDatabase::PixmapDatabase()
+{
+}
+
+PixmapDatabase::~PixmapDatabase()
+{
+	reset();
+}
+
+bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zoneBank)
+{
+	QProgressDialog *progressDialog = new QProgressDialog();
+	progressDialog->show();
+
+	std::vector<std::string> listNames;
+	zoneBank.getCategoryValues ("zone", listNames);
+	progressDialog->setRange(0, listNames.size());
+	for (uint i = 0; i < listNames.size(); ++i)
+	{
+		QApplication::processEvents();
+		progressDialog->setValue(i);
+
+		NLLIGO::CZoneBankElement *zoneBankItem = zoneBank.getElementByZoneName (listNames[i]);
+
+		// Read the texture file
+		QString zonePixmapName(listNames[i].c_str());
+		uint8 sizeX = zoneBankItem->getSizeX();
+		uint8 sizeY = zoneBankItem->getSizeY();
+
+		QPixmap *pixmap = new QPixmap(zonePath + zonePixmapName + ".png");
+		if (pixmap->isNull())
+		{
+			// Generate filled pixmap
+		}
+		// All pixmaps must be have same size
+		if (pixmap->width() != sizeX * PixmapScale)
+		{
+			QPixmap *scaledPixmap = new QPixmap(pixmap->scaled(sizeX * PixmapScale, sizeY * PixmapScale));
+			delete pixmap;
+			m_pixmapMap.insert(zonePixmapName, scaledPixmap);
+		}
+		else
+			m_pixmapMap.insert(zonePixmapName, pixmap);
+	}
+	delete progressDialog;
+	return true;
+}
+
+void PixmapDatabase::reset()
+{
+	QStringList listNames(m_pixmapMap.keys());
+	Q_FOREACH(QString name, listNames)
+	{
+		QPixmap *pixmap = m_pixmapMap.value(name);
+		delete pixmap;
+	}
+	m_pixmapMap.clear();
+}
+
+QStringList PixmapDatabase::listPixmaps() const
+{
+	return m_pixmapMap.keys();
+}
+
+QPixmap *PixmapDatabase::pixmap(const QString &zoneName) const
+{
+	QPixmap *result = 0;
+	if (!m_pixmapMap.contains(zoneName))
+		nlwarning("QPixmap %s not found", zoneName.toStdString().c_str());
+	else
+		result = m_pixmapMap.value(zoneName);
+	return result;
+}
 
 ZoneBuilder::ZoneBuilder()
-	: m_zoneListModel(0)
+	: m_pixmapDatabase(0)
 {
-	m_zoneListModel = new ListZonesModel();
+	m_pixmapDatabase = new PixmapDatabase();
 	m_lastPathName = "";
 }
 
 ZoneBuilder::~ZoneBuilder()
 {
-	delete m_zoneListModel;
+	delete m_pixmapDatabase;
 }
 
 bool ZoneBuilder::init(const QString &pathName, bool makeAZone)
@@ -60,8 +136,8 @@ bool ZoneBuilder::init(const QString &pathName, bool makeAZone)
 		// Construct the DataBase from the ZoneBank
 		QString zoneBitmapPath = pathName;
 		zoneBitmapPath += "/zonebitmaps/";
-		m_zoneListModel->resetModel();
-		if (!m_zoneListModel->rebuildModel(zoneBitmapPath, m_zoneBank))
+		m_pixmapDatabase->reset();
+		if (!m_pixmapDatabase->loadPixmaps(zoneBitmapPath, m_zoneBank))
 		{
 			m_zoneBank.reset();
 			return false;
@@ -91,9 +167,14 @@ bool ZoneBuilder::initZoneBank (const QString &pathName)
 	return true;
 }
 
-ListZonesModel *ZoneBuilder::zoneModel() const
+PixmapDatabase *ZoneBuilder::pixmapDatabase() const
 {
-	return m_zoneListModel;
+	return m_pixmapDatabase;
+}
+
+QString ZoneBuilder::dataPath() const
+{
+	return m_lastPathName;
 }
 
 void ZoneBuilder::newZone (bool bDisplay)
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
index 97c4d8d3a..f69c2f7fb 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
@@ -29,16 +29,47 @@
 
 // Qt includes
 #include <QtCore/QString>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtGui/QPixmap>
 
 namespace LandscapeEditor
 {
-class ListZonesModel;
+
+/**
+@class PixmapDatabase
+@brief PixmapDatabase contains the image database
+@details
+*/
+class PixmapDatabase
+{
+public:
+	PixmapDatabase();
+	~PixmapDatabase();
+
+	/// Load all images(png) from zonePath, list images gets from zoneBank
+	bool loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zoneBank);
+
+	/// Unload all images
+	void reset();
+
+	/// Get list names all loaded pixmaps
+	QStringList listPixmaps() const;
+
+	/// Get original pixmap
+	/// @return QPixmap* if the image is in the database ; otherwise returns 0.
+	QPixmap *pixmap(const QString &zoneName) const;
+private:
+
+	QMap<QString, QPixmap*> m_pixmapMap;
+};
+
 
 /**
 @class ZoneBuilder
 @brief ZoneBuilder contains all the shared data between the tools and the engine
 @details ZoneBank contains the macro zones that is composed of several zones plus a mask
-ZoneListModel contains the graphics for the zones
+PixmapDatabase contains the graphics for the zones
 */
 class ZoneBuilder
 {
@@ -56,7 +87,11 @@ public:
 	{
 		return m_zoneBank;
 	}
-	ListZonesModel *zoneModel() const;
+
+	PixmapDatabase *pixmapDatabase() const;
+
+	QString dataPath() const;
+
 private:
 
 	// Scan ./zoneligos dir and add all *.ligozone files to zoneBank
@@ -65,7 +100,7 @@ private:
 	sint32 m_minX, m_maxX, m_minY, m_maxY;
 	QString m_lastPathName;
 
-	ListZonesModel *m_zoneListModel;
+	PixmapDatabase *m_pixmapDatabase;
 	NLLIGO::CZoneBank m_zoneBank;
 	std::vector<NLLIGO::CZoneBankElement*> m_currentSelection;
 };
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
index eb9b8b8e8..1b8716326 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
@@ -18,7 +18,7 @@
 // Project includes
 #include "landscape_editor_window.h"
 #include "landscape_editor_constants.h"
-#include "list_zones_model.h"
+#include "project_settings_dialog.h"
 
 #include "../core/icore.h"
 #include "../core/imenu_manager.h"
@@ -43,15 +43,18 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
 	m_undoStack = new QUndoStack(this);
 	m_zoneBuilder = new ZoneBuilder();
 	m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", false);
-	m_ui.zoneListWidget->setModel(m_zoneBuilder->zoneModel());
 	m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder);
 	m_ui.zoneListWidget->updateUi();
 	createMenus();
+	createToolBars();
 	readSettings();
+
+	connect(m_ui.projectSettingsAction, SIGNAL(triggered()), this, SLOT(openProjectSettings()));
 }
 
 LandscapeEditorWindow::~LandscapeEditorWindow()
 {
+	delete m_zoneBuilder;
 	writeSettings();
 }
 
@@ -75,11 +78,37 @@ void LandscapeEditorWindow::open()
 	setCursor(Qt::ArrowCursor);
 }
 
+void LandscapeEditorWindow::openProjectSettings()
+{
+	ProjectSettingsDialog *dialog = new ProjectSettingsDialog(m_zoneBuilder->dataPath(), this);
+	dialog->show();
+	int ok = dialog->exec();
+	if (ok == QDialog::Accepted)
+	{
+		m_zoneBuilder->init(dialog->dataPath(), false);
+		m_ui.zoneListWidget->updateUi();
+	}
+	delete dialog;
+}
+
 void LandscapeEditorWindow::createMenus()
 {
 	Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager();
 }
 
+void LandscapeEditorWindow::createToolBars()
+{
+	Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager();
+	//QAction *action = menuManager->action(Core::Constants::NEW);
+	//m_ui.fileToolBar->addAction(action);
+	QAction *action = menuManager->action(Core::Constants::OPEN);
+	m_ui.fileToolBar->addAction(action);
+	//action = menuManager->action(Core::Constants::SAVE);
+	//m_ui.fileToolBar->addAction(action);
+	//action = menuManager->action(Core::Constants::SAVE_AS);
+	//m_ui.fileToolBar->addAction(action);
+}
+
 void LandscapeEditorWindow::readSettings()
 {
 	QSettings *settings = Core::ICore::instance()->settings();
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
index 61e0c7eb1..9b2ae0335 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
@@ -43,8 +43,11 @@ public Q_SLOTS:
 	void open();
 
 private Q_SLOTS:
+	void openProjectSettings();
+
 private:
 	void createMenus();
+	void createToolBars();
 	void readSettings();
 	void writeSettings();
 
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
index ac16ad9fd..3877d9732 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
@@ -24,7 +24,7 @@
     </item>
    </layout>
   </widget>
-  <widget class="QToolBar" name="toolBar">
+  <widget class="QToolBar" name="fileToolBar">
    <property name="windowTitle">
     <string>toolBar</string>
    </property>
@@ -44,6 +44,27 @@
    </attribute>
    <widget class="LandscapeEditor::ListZonesWidget" name="zoneListWidget"/>
   </widget>
+  <widget class="QToolBar" name="landToolBar">
+   <property name="windowTitle">
+    <string>toolBar_2</string>
+   </property>
+   <attribute name="toolBarArea">
+    <enum>TopToolBarArea</enum>
+   </attribute>
+   <attribute name="toolBarBreak">
+    <bool>false</bool>
+   </attribute>
+   <addaction name="projectSettingsAction"/>
+  </widget>
+  <action name="projectSettingsAction">
+   <property name="icon">
+    <iconset resource="landscape_editor.qrc">
+     <normaloff>:/icons/ic_nel_landscape_settings.png</normaloff>:/icons/ic_nel_landscape_settings.png</iconset>
+   </property>
+   <property name="text">
+    <string>Project settings</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp
index ffcb7617b..622fd8fb8 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp
@@ -17,6 +17,7 @@
 
 // Project includes
 #include "list_zones_model.h"
+#include "builder_zone.h"
 
 // NeL includes
 #include <nel/misc/debug.h>
@@ -27,15 +28,14 @@
 
 // Qt includes
 #include <QApplication>
-#include <QSize>
 #include <QtGui/QProgressDialog>
 
 namespace LandscapeEditor
 {
 
-ListZonesModel::ListZonesModel(int pixmapSize, QObject *parent)
+ListZonesModel::ListZonesModel(int scaleRatio, QObject *parent)
 	: QAbstractListModel(parent),
-	  m_pixmapSize(pixmapSize)
+	  m_scaleRatio(scaleRatio)
 {
 
 }
@@ -46,7 +46,7 @@ ListZonesModel::~ListZonesModel()
 
 int ListZonesModel::rowCount(const QModelIndex & /* parent */) const
 {
-	return m_pixmapNameList.count();
+	return m_listNames.count();
 }
 
 int ListZonesModel::columnCount(const QModelIndex & /* parent */) const
@@ -65,11 +65,11 @@ QVariant ListZonesModel::data(const QModelIndex &index, int role) const
 	}
 	else if (role == Qt::DisplayRole)
 	{
-		return m_pixmapNameList.at(index.row());
+		return m_listNames.at(index.row());
 	}
 	else if (role == Qt::DecorationRole)
 	{
-		QPixmap *pixmap = getSmallPixmap(m_pixmapNameList.at(index.row()));
+		QPixmap *pixmap = getPixmap(m_listNames.at(index.row()));
 		return qVariantFromValue(*pixmap);
 	}
 	return QVariant();
@@ -84,73 +84,48 @@ QVariant ListZonesModel::headerData(int section,
 	return QVariant();
 }
 
-void ListZonesModel::setSmallPixmapSize(int pixmapSize)
+void ListZonesModel::setScaleRatio(int scaleRatio)
 {
-	m_pixmapSize = pixmapSize;
+	m_scaleRatio = scaleRatio;
 }
 
 void ListZonesModel::setListZones(QStringList &listZones)
 {
 	beginResetModel();
-	m_pixmapNameList.clear();
-	m_pixmapNameList = listZones;
+	m_listNames.clear();
+	m_listNames = listZones;
 	endResetModel();
 }
 
 void ListZonesModel::resetModel()
 {
 	beginResetModel();
-	Q_FOREACH(QString name, m_pixmapNameList)
+	QStringList listNames(m_pixmapMap.keys());
+	Q_FOREACH(QString name, listNames)
 	{
 		QPixmap *pixmap = m_pixmapMap.value(name);
 		delete pixmap;
-		QPixmap *smallPixmap = m_smallPixmapMap.value(name);
-		delete smallPixmap;
 	}
 	m_pixmapMap.clear();
-	m_pixmapNameList.clear();
-	m_smallPixmapMap.clear();
+	m_listNames.clear();
 	endResetModel();
 }
 
-bool ListZonesModel::rebuildModel(const QString &zonePath, NLLIGO::CZoneBank &zoneBank)
+void ListZonesModel::rebuildModel(PixmapDatabase *pixmapDatabase)
 {
+	resetModel();
+
 	beginResetModel();
-	m_zonePath = zonePath;
+	QStringList listNames;
+	listNames = pixmapDatabase->listPixmaps();
 
-	QProgressDialog *progressDialog = new QProgressDialog();
-	progressDialog->show();
-
-	std::vector<std::string> zoneNames;
-	zoneBank.getCategoryValues ("zone", zoneNames);
-	progressDialog->setRange(0, zoneNames.size());
-	for (uint i = 0; i < zoneNames.size(); ++i)
+	Q_FOREACH(QString name, listNames)
 	{
-		QApplication::processEvents();
-		progressDialog->setValue(i);
-
-		NLLIGO::CZoneBankElement *zoneBankItem = zoneBank.getElementByZoneName (zoneNames[i]);
-
-		// Read the texture file
-		QString zonePixmapName(zoneNames[i].c_str());
-		uint8 sizeX = zoneBankItem->getSizeX();
-		uint8 sizeY = zoneBankItem->getSizeY();
-		const std::vector<bool> &rMask = zoneBankItem->getMask();
-
-		QPixmap *pixmap = new QPixmap(zonePath + zonePixmapName + ".png");
-		if (pixmap->isNull())
-		{
-			// Generate filled pixmap
-		}
-		QPixmap *smallPixmap = new QPixmap(pixmap->scaled(m_pixmapSize * sizeX, m_pixmapSize * sizeY));
-
-		m_pixmapMap.insert(zonePixmapName, pixmap);
-		m_smallPixmapMap.insert(zonePixmapName, smallPixmap);
-
+		QPixmap *pixmap = pixmapDatabase->pixmap(name);
+		QPixmap *smallPixmap = new QPixmap(pixmap->scaled(pixmap->width() / m_scaleRatio, pixmap->height() / m_scaleRatio));
+		m_pixmapMap.insert(name, smallPixmap);
 	}
 	endResetModel();
-	delete progressDialog;
-	return true;
 }
 
 QPixmap *ListZonesModel::getPixmap(const QString &zoneName) const
@@ -163,15 +138,4 @@ QPixmap *ListZonesModel::getPixmap(const QString &zoneName) const
 	return result;
 }
 
-QPixmap *ListZonesModel::getSmallPixmap(const QString &zoneName) const
-{
-	QPixmap *result = 0;
-	if (!m_pixmapMap.contains(zoneName))
-		nlwarning("QPixmap %s not found", zoneName.toStdString().c_str());
-	else
-		result = m_smallPixmapMap.value(zoneName);
-	return result;
-}
-
-
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h
index 16a28bf07..475416887 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h
@@ -31,18 +31,18 @@
 
 namespace LandscapeEditor
 {
+class PixmapDatabase;
 
 /**
 @class ListZonesModel
-@brief ListZonesModel contains the image database for QGraphicsScene and
-small images for QListView
+@brief ListZonesModel contains the small images for QListView
 @details
 */
 class ListZonesModel : public QAbstractListModel
 {
 	Q_OBJECT
 public:
-	ListZonesModel(int pixmapSize = 64, QObject *parent = 0);
+	ListZonesModel(int scaleRatio = 4, QObject *parent = 0);
 	~ListZonesModel();
 
 	int rowCount(const QModelIndex &parent) const;
@@ -53,30 +53,25 @@ public:
 
 	/// Set size for small pixmaps
 	/// Value should be set before calling rebuildModel
-	void setSmallPixmapSize(int pixmapSize);
+	void setScaleRatio(int scaleRatio);
 
 	/// Unload all images and reset model
 	void resetModel();
 
+	/// Set current list zones which will be available in QListView
 	void setListZones(QStringList &listZones);
 
-	/// Load all images(png) from zonePath, list images gets from zoneBank
-	bool rebuildModel(const QString &zonePath, NLLIGO::CZoneBank &zoneBank);
+	/// Build own pixmaps database(all images are scaled: width/scaleRatio, height/scaleRatio) from pixmapDatabase
+	void rebuildModel(PixmapDatabase *pixmapDatabase);
 
-	/// Get original pixmap
+private:
+	/// Get pixmap
 	/// @return QPixmap* if the image is in the database ; otherwise returns 0.
 	QPixmap *getPixmap(const QString &zoneName) const;
 
-	/// Get scaled pixmap (pixmapSize * zoneSize.sizeX, pixmapSize * zoneSize.sizeY)
-	/// @return QPixmap* if the image is in the database ; otherwise returns 0.
-	QPixmap *getSmallPixmap(const QString &zoneName) const;
-private:
-
-	QString m_zonePath;
-	int m_pixmapSize;
+	int m_scaleRatio;
 	QMap<QString, QPixmap*> m_pixmapMap;
-	QMap<QString, QPixmap*> m_smallPixmapMap;
-	QList<QString> m_pixmapNameList;
+	QStringList m_listNames;
 };
 
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
index 8dcb87383..e4e3fae0d 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
@@ -37,10 +37,14 @@ namespace LandscapeEditor
 
 ListZonesWidget::ListZonesWidget(QWidget *parent)
 	: QWidget(parent),
+	  m_listZonesModel(0),
 	  m_zoneBuilder(0)
 {
 	m_ui.setupUi(this);
 
+	m_listZonesModel = new ListZonesModel(4, this);
+	m_ui.listView->setModel(m_listZonesModel);
+
 	m_ui.addFilterButton_1->setChecked(false);
 	m_ui.addFilterButton_2->setChecked(false);
 	m_ui.addFilterButton_3->setChecked(false);
@@ -81,6 +85,10 @@ void ListZonesWidget::updateUi()
 	m_ui.categoryTypeComboBox_2->clear();
 	m_ui.categoryTypeComboBox_3->clear();
 	m_ui.categoryTypeComboBox_4->clear();
+	m_ui.categoryValueComboBox_1->clear();
+	m_ui.categoryValueComboBox_2->clear();
+	m_ui.categoryValueComboBox_3->clear();
+	m_ui.categoryValueComboBox_4->clear();
 
 	m_ui.categoryTypeComboBox_1->addItems(listCategories);
 	m_ui.categoryTypeComboBox_2->addItems(listCategories);
@@ -88,11 +96,8 @@ void ListZonesWidget::updateUi()
 	m_ui.categoryTypeComboBox_4->addItems(listCategories);
 
 	disableSignals(false);
-}
 
-void ListZonesWidget::setModel(QAbstractItemModel *model)
-{
-	m_ui.listView->setModel(model);
+	m_listZonesModel->rebuildModel(m_zoneBuilder->pixmapDatabase());
 }
 
 void ListZonesWidget::setZoneBuilder(ZoneBuilder *zoneBuilder)
@@ -201,7 +206,8 @@ void ListZonesWidget::updateListZones()
 	QStringList listSelection;
 	for (size_t i = 0; i < currentSelection.size(); ++i)
 		listSelection << currentSelection[i]->getName().c_str();
-	m_zoneBuilder->zoneModel()->setListZones(listSelection);
+
+	m_listZonesModel->setListZones(listSelection);
 }
 
 void ListZonesWidget::disableSignals(bool block)
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
index fed0134cf..049f0ebcb 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
@@ -28,10 +28,11 @@
 namespace LandscapeEditor
 {
 class ZoneBuilder;
+class ListZonesModel;
 
 /**
 @class ZoneListWidget
-@brief ZoneListWidget
+@brief ZoneListWidget displays list available zones in accordance with the filter settings
 @details
 */
 class ListZonesWidget: public QWidget
@@ -44,21 +45,19 @@ public:
 
 	void updateUi();
 	void setZoneBuilder(ZoneBuilder *zoneBuilder);
-	void setModel(QAbstractItemModel *model);
 
 Q_SIGNALS:
-public Q_SLOTS:
+private Q_SLOTS:
 	void updateFilters_1(const QString &value);
 	void updateFilters_2(const QString &value);
 	void updateFilters_3(const QString &value);
 	void updateFilters_4(const QString &value);
-
-private Q_SLOTS:
 	void updateListZones();
 
 private:
 	void disableSignals(bool block);
 
+	ListZonesModel *m_listZonesModel;
 	ZoneBuilder *m_zoneBuilder;
 	Ui::ListZonesWidget m_ui;
 }; /* ZoneListWidget */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp
new file mode 100644
index 000000000..bf095e6cf
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp
@@ -0,0 +1,52 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+// Project includes
+#include "project_settings_dialog.h"
+#include "landscape_editor_constants.h"
+
+#include "../core/icore.h"
+#include "../core/core_constants.h"
+
+// NeL includes
+#include <nel/misc/debug.h>
+
+// Qt includes
+#include <QtCore/QSettings>
+#include <QtGui/QFileDialog>
+
+namespace LandscapeEditor
+{
+
+ProjectSettingsDialog::ProjectSettingsDialog(const QString &dataPath, QWidget *parent)
+	: QDialog(parent)
+{
+	m_ui.setupUi(this);
+	m_ui.pathLineEdit->setText(dataPath);
+	setFixedHeight(sizeHint().height());
+}
+
+ProjectSettingsDialog::~ProjectSettingsDialog()
+{
+}
+
+QString ProjectSettingsDialog::dataPath() const
+{
+	return m_ui.pathLineEdit->text();
+}
+
+} /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h
new file mode 100644
index 000000000..74443e3f1
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h
@@ -0,0 +1,46 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef PROJECT_SETTINGS_DIALOG_H
+#define PROJECT_SETTINGS_DIALOG_H
+
+// Project includes
+#include "ui_project_settings_dialog.h"
+
+// Qt includes
+
+namespace LandscapeEditor
+{
+
+class ProjectSettingsDialog: public QDialog
+{
+	Q_OBJECT
+
+public:
+	ProjectSettingsDialog(const QString &dataPath, QWidget *parent = 0);
+	~ProjectSettingsDialog();
+
+	QString dataPath() const;
+
+private:
+
+	Ui::ProjectSettingsDialog m_ui;
+}; /* class ProjectSettingsDialog */
+
+} /* namespace LandscapeEditor */
+
+#endif // PROJECT_SETTINGS_DIALOG_H
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui
new file mode 100644
index 000000000..bb94fcc0d
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ProjectSettingsDialog</class>
+ <widget class="QDialog" name="ProjectSettingsDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>419</width>
+    <height>93</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Project settings</string>
+  </property>
+  <property name="windowIcon">
+   <iconset resource="landscape_editor.qrc">
+    <normaloff>:/icons/ic_nel_landscape_settings.png</normaloff>:/icons/ic_nel_landscape_settings.png</iconset>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Data directory:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1">
+    <widget class="QLineEdit" name="pathLineEdit"/>
+   </item>
+   <item row="0" column="2">
+    <widget class="QToolButton" name="selectPathButton">
+     <property name="text">
+      <string>...</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="label_2">
+     <property name="text">
+      <string>Context:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1" colspan="2">
+    <widget class="QComboBox" name="contextComboBox"/>
+   </item>
+   <item row="2" column="0" colspan="3">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="landscape_editor.qrc"/>
+ </resources>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>ProjectSettingsDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>ProjectSettingsDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>

From 8903f6ca4b0ba73c9eccdd1c428edb5691164fc8 Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Thu, 9 Jun 2011 02:11:50 +0300
Subject: [PATCH 04/19] Changed: #1301 Added select path button in project
 settings dialog. Main window landscape editor is saving own state.

---
 .../plugins/landscape_editor/CMakeLists.txt   |  1 +
 .../plugins/landscape_editor/builder_zone.cpp |  1 +
 .../plugins/landscape_editor/builder_zone.h   |  4 +-
 .../landscape_editor_constants.h              |  2 +
 .../landscape_editor_window.cpp               | 14 +++++
 .../landscape_editor_window.h                 |  5 +-
 .../landscape_editor_window.ui                | 17 +++++-
 .../landscape_editor/landscape_view.cpp       | 52 +++++++++++++++++++
 .../plugins/landscape_editor/landscape_view.h | 49 +++++++++++++++++
 .../landscape_editor/list_zones_model.cpp     | 16 +++---
 .../landscape_editor/list_zones_widget.ui     |  9 +++-
 .../project_settings_dialog.cpp               |  9 ++++
 .../project_settings_dialog.h                 |  3 ++
 13 files changed, 168 insertions(+), 14 deletions(-)
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
index 227210366..e189af74b 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
@@ -15,6 +15,7 @@ SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR	landscape_editor_plugin.h
 					list_zones_model.h
 					list_zones_widget.h
 					landscape_actions.h
+					landscape_view.h
 					project_settings_dialog.h
 )
 
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
index 3db771224..288a4b1be 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
@@ -164,6 +164,7 @@ bool ZoneBuilder::initZoneBank (const QString &pathName)
 		if (!m_zoneBank.addElement((pathName + file).toStdString(), error))
 			QMessageBox::critical(0, QObject::tr("Landscape editor"), QString(error.c_str()), QMessageBox::Ok);
 	}
+	delete dir;
 	return true;
 }
 
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
index f69c2f7fb..f43bb7d7e 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
@@ -67,8 +67,8 @@ private:
 
 /**
 @class ZoneBuilder
-@brief ZoneBuilder contains all the shared data between the tools and the engine
-@details ZoneBank contains the macro zones that is composed of several zones plus a mask
+@brief ZoneBuilder contains all the shared data between the tools and the engine.
+@details ZoneBank contains the macro zones that is composed of several zones plus a mask.
 PixmapDatabase contains the graphics for the zones
 */
 class ZoneBuilder
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h
index 52775f4c4..6875ddfab 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h
@@ -26,6 +26,8 @@ const char * const LANDSCAPE_EDITOR_PLUGIN	= "LandscapeEditor";
 
 //settings
 const char * const LANDSCAPE_EDITOR_SECTION = "LandscapeEditor";
+const char * const LANDSCAPE_WINDOW_STATE = "LandscapeWindowState";
+const char * const LANDSCAPE_WINDOW_GEOMETRY = "LandscapeWindowGeometry";
 
 //resources
 const char * const ICON_LANDSCAPE_ITEM = ":/icons/ic_nel_landscape_item.png";
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
index 1b8716326..c17de1f43 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
@@ -18,6 +18,8 @@
 // Project includes
 #include "landscape_editor_window.h"
 #include "landscape_editor_constants.h"
+#include "builder_zone.h"
+#include "landscape_scene.h"
 #include "project_settings_dialog.h"
 
 #include "../core/icore.h"
@@ -30,6 +32,8 @@
 // Qt includes
 #include <QtCore/QSettings>
 #include <QtGui/QFileDialog>
+#include <QtOpenGL/QGLWidget>
+#include <QtGui/QGraphicsPixmapItem>
 
 namespace LandscapeEditor
 {
@@ -45,6 +49,12 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
 	m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", false);
 	m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder);
 	m_ui.zoneListWidget->updateUi();
+
+	m_landscapeScene = new LandscapeScene(this);
+	m_ui.graphicsView->setScene(m_landscapeScene);
+	m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers)));
+
+
 	createMenus();
 	createToolBars();
 	readSettings();
@@ -113,6 +123,8 @@ void LandscapeEditorWindow::readSettings()
 {
 	QSettings *settings = Core::ICore::instance()->settings();
 	settings->beginGroup(Constants::LANDSCAPE_EDITOR_SECTION);
+	restoreState(settings->value(Constants::LANDSCAPE_WINDOW_STATE).toByteArray());
+	restoreGeometry(settings->value(Constants::LANDSCAPE_WINDOW_GEOMETRY).toByteArray());
 	settings->endGroup();
 }
 
@@ -120,6 +132,8 @@ void LandscapeEditorWindow::writeSettings()
 {
 	QSettings *settings = Core::ICore::instance()->settings();
 	settings->beginGroup(Constants::LANDSCAPE_EDITOR_SECTION);
+	settings->setValue(Constants::LANDSCAPE_WINDOW_STATE, saveState());
+	settings->setValue(Constants::LANDSCAPE_WINDOW_GEOMETRY, saveGeometry());
 	settings->endGroup();
 	settings->sync();
 }
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
index 9b2ae0335..1fecd9f03 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
@@ -20,7 +20,6 @@
 
 // Project includes
 #include "ui_landscape_editor_window.h"
-#include "builder_zone.h"
 
 // Qt includes
 #include <QtGui/QUndoStack>
@@ -28,6 +27,9 @@
 namespace LandscapeEditor
 {
 
+class LandscapeScene;
+class ZoneBuilder;
+
 class LandscapeEditorWindow: public QMainWindow
 {
 	Q_OBJECT
@@ -51,6 +53,7 @@ private:
 	void readSettings();
 	void writeSettings();
 
+	LandscapeScene *m_landscapeScene;
 	ZoneBuilder *m_zoneBuilder;
 	QUndoStack *m_undoStack;
 	Ui::LandscapeEditorWindow m_ui;
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
index 3877d9732..1361cd2bc 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
@@ -19,8 +19,18 @@
   </property>
   <widget class="QWidget" name="centralwidget">
    <layout class="QGridLayout" name="gridLayout">
+    <property name="margin">
+     <number>3</number>
+    </property>
+    <property name="spacing">
+     <number>3</number>
+    </property>
     <item row="0" column="0">
-     <widget class="QGraphicsView" name="graphicsView"/>
+     <widget class="LandscapeEditor::LandscapeView" name="graphicsView">
+      <property name="dragMode">
+       <enum>QGraphicsView::NoDrag</enum>
+      </property>
+     </widget>
     </item>
    </layout>
   </widget>
@@ -73,6 +83,11 @@
    <header>list_zones_widget.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>LandscapeEditor::LandscapeView</class>
+   <extends>QGraphicsView</extends>
+   <header>landscape_view.h</header>
+  </customwidget>
  </customwidgets>
  <resources>
   <include location="landscape_editor.qrc"/>
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
new file mode 100644
index 000000000..79b33599e
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
@@ -0,0 +1,52 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+// Project includes
+#include "landscape_view.h"
+#include "landscape_editor_constants.h"
+
+#include "../core/icore.h"
+#include "../core/core_constants.h"
+
+// NeL includes
+#include <nel/misc/debug.h>
+
+// Qt includes
+
+
+namespace LandscapeEditor
+{
+
+LandscapeView::LandscapeView(QWidget *parent)
+	: QGraphicsView(parent)
+{
+    setDragMode(ScrollHandDrag);
+}
+
+LandscapeView::~LandscapeView()
+{
+}
+
+void LandscapeView::wheelEvent(QWheelEvent *event)
+{
+    double numDegrees = event->delta() / 8.0;
+    double numSteps = numDegrees / 15.0;
+    double factor = std::pow(1.125, numSteps);
+    scale(factor, factor);
+}
+
+} /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h
new file mode 100644
index 000000000..db79b79ff
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h
@@ -0,0 +1,49 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef LANDSCAPE_VIEW_H
+#define LANDSCAPE_VIEW_H
+
+// Project includes
+
+// Qt includes
+#include <QtGui/QGraphicsView>
+#include <QtGui/QWheelEvent>
+
+namespace LandscapeEditor
+{
+
+class LandscapeView: public QGraphicsView
+{
+	Q_OBJECT
+
+public:
+	LandscapeView(QWidget *parent = 0);
+	~LandscapeView();
+
+protected:
+    void wheelEvent(QWheelEvent *event); 
+
+private Q_SLOTS:
+
+private:
+
+}; /* class LandscapeView */
+
+} /* namespace LandscapeEditor */
+
+#endif // LANDSCAPE_VIEW_H
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp
index 622fd8fb8..57e8683c0 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp
@@ -59,28 +59,26 @@ QVariant ListZonesModel::data(const QModelIndex &index, int role) const
 	if (!index.isValid())
 		return QVariant();
 
-	if (role == Qt::TextAlignmentRole)
+	switch (role)
 	{
+	case Qt::TextAlignmentRole:
 		return int(Qt::AlignLeft | Qt::AlignVCenter);
-	}
-	else if (role == Qt::DisplayRole)
-	{
+	case Qt::DisplayRole:
 		return m_listNames.at(index.row());
-	}
-	else if (role == Qt::DecorationRole)
+	case Qt::DecorationRole:
 	{
 		QPixmap *pixmap = getPixmap(m_listNames.at(index.row()));
 		return qVariantFromValue(*pixmap);
 	}
-	return QVariant();
+	default:
+		return QVariant();
+	}
 }
 
 QVariant ListZonesModel::headerData(int section,
 									Qt::Orientation /* orientation */,
 									int role) const
 {
-	if (role != Qt::DisplayRole)
-		return QVariant();
 	return QVariant();
 }
 
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui
index 585371cb7..289cb45dd 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui
@@ -290,7 +290,14 @@
     </widget>
    </item>
    <item row="2" column="0">
-    <widget class="QListView" name="listView"/>
+    <widget class="QListView" name="listView">
+     <property name="alternatingRowColors">
+      <bool>false</bool>
+     </property>
+     <property name="verticalScrollMode">
+      <enum>QAbstractItemView::ScrollPerPixel</enum>
+     </property>
+    </widget>
    </item>
   </layout>
  </widget>
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp
index bf095e6cf..3acd3ff66 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp
@@ -28,6 +28,7 @@
 // Qt includes
 #include <QtCore/QSettings>
 #include <QtGui/QFileDialog>
+#include <QtGui/QFileDialog>
 
 namespace LandscapeEditor
 {
@@ -38,6 +39,7 @@ ProjectSettingsDialog::ProjectSettingsDialog(const QString &dataPath, QWidget *p
 	m_ui.setupUi(this);
 	m_ui.pathLineEdit->setText(dataPath);
 	setFixedHeight(sizeHint().height());
+	connect(m_ui.selectPathButton, SIGNAL(clicked()), this, SLOT(selectPath()));
 }
 
 ProjectSettingsDialog::~ProjectSettingsDialog()
@@ -49,4 +51,11 @@ QString ProjectSettingsDialog::dataPath() const
 	return m_ui.pathLineEdit->text();
 }
 
+void ProjectSettingsDialog::selectPath()
+{
+	QString dataPath = QFileDialog::getExistingDirectory(this, tr("Select data path"), m_ui.pathLineEdit->text());
+	if (!dataPath.isEmpty())
+		m_ui.pathLineEdit->setText(dataPath);
+}
+
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h
index 74443e3f1..abb93ab81 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h
@@ -36,6 +36,9 @@ public:
 
 	QString dataPath() const;
 
+private Q_SLOTS:
+	void selectPath();
+
 private:
 
 	Ui::ProjectSettingsDialog m_ui;

From c3867d1699220f332d9a0550ecadcbf254f60ad6 Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Tue, 14 Jun 2011 12:26:41 +0300
Subject: [PATCH 05/19] Changed: #1301 Experiments with undo\redo and
 QGraphicsScene.

---
 .../plugins/landscape_editor/builder_zone.h   | 29 +++++++++++
 .../landscape_editor/landscape_actions.cpp    | 31 ++++++++++++
 .../landscape_editor/landscape_actions.h      | 22 ++++++++
 .../landscape_editor_window.cpp               |  6 +--
 .../landscape_editor_window.ui                |  8 +++
 .../landscape_editor/landscape_scene.cpp      | 50 ++++++++++++++++++-
 .../landscape_editor/landscape_scene.h        | 19 ++++++-
 .../landscape_editor/landscape_view.cpp       | 43 ++++++++++++----
 .../plugins/landscape_editor/landscape_view.h |  6 ++-
 .../landscape_editor/list_zones_widget.cpp    | 12 ++++-
 .../landscape_editor/list_zones_widget.h      |  3 +-
 11 files changed, 209 insertions(+), 20 deletions(-)

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
index f43bb7d7e..0ccbf4e23 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
@@ -36,6 +36,35 @@
 namespace LandscapeEditor
 {
 
+// Data
+struct LigoData
+{
+	uint32			PosX;
+	uint32			PosY;
+	qreal			Scale;
+	uint8			Rot;
+	uint8			Flip;
+	std::string		ZoneName;
+	std::string		SharingMatNames[4];
+	uint8			SharingCutEdges[4];
+	bool operator!= (const LigoData& other) const
+	{
+		return (PosX != other.PosX) ||
+			   (PosY != other.PosY) ||
+			   (Rot != other.Rot) ||
+			   (Flip != other.Flip) ||
+			   (ZoneName != other.ZoneName) ||
+			   (SharingMatNames[0] != other.SharingMatNames[0]) ||
+			   (SharingMatNames[1] != other.SharingMatNames[1]) ||
+			   (SharingMatNames[2] != other.SharingMatNames[2]) ||
+			   (SharingMatNames[3] != other.SharingMatNames[3]) ||
+			   (SharingCutEdges[0] != other.SharingCutEdges[0]) ||
+			   (SharingCutEdges[1] != other.SharingCutEdges[1]) ||
+			   (SharingCutEdges[2] != other.SharingCutEdges[2]) ||
+			   (SharingCutEdges[3] != other.SharingCutEdges[3]);
+	}
+};
+
 /**
 @class PixmapDatabase
 @brief PixmapDatabase contains the image database
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
index f0b86dd8e..14cdb4f4b 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
@@ -17,6 +17,7 @@
 
 // Project includes
 #include "landscape_actions.h"
+#include "builder_zone.h"
 
 // NeL includes
 #include <nel/misc/debug.h>
@@ -25,4 +26,34 @@
 
 namespace LandscapeEditor
 {
+
+ActionLigoTile::ActionLigoTile(const LigoData &data, ZoneBuilder *zoneBuilder, QGraphicsScene *scene, QUndoCommand *parent)
+	: QUndoCommand(parent),
+	  m_item(0),
+	  m_zoneBuilder(zoneBuilder),
+	  m_scene(scene)
+{
+	m_ligoData = data;
+}
+
+ActionLigoTile::~ActionLigoTile()
+{
+}
+
+void ActionLigoTile::undo()
+{
+	m_scene->removeItem(m_item);
+	delete m_item;
+	m_item = 0;
+}
+
+void ActionLigoTile::redo()
+{
+	QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(m_ligoData.ZoneName.c_str()));
+	m_item = new QGraphicsPixmapItem(*pixmap, 0, m_scene);
+	m_item->setPos(m_ligoData.PosX, m_ligoData.PosY);
+	m_item->setScale(m_ligoData.Scale);
+	setText(QObject::tr("Add tile(%1, %2)").arg(m_ligoData.PosX).arg(m_ligoData.PosY));
+}
+
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
index fdcda5451..76cb92762 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
@@ -19,13 +19,35 @@
 #define LANDSCAPE_ACTIONS_H
 
 // Project includes
+#include "builder_zone.h"
 
 // NeL includes
 
 // Qt includes
+#include <QtGui/QUndoCommand>
+#include <QtGui/QGraphicsScene>
+#include <QtGui/QGraphicsPixmapItem>
 
 namespace LandscapeEditor
 {
+class ZoneBuilder;
+
+class ActionLigoTile : public QUndoCommand
+{
+public:
+	ActionLigoTile(const LigoData &data, ZoneBuilder *zoneBuilder, QGraphicsScene *scene, QUndoCommand *parent = 0);
+	~ActionLigoTile();
+
+	virtual void undo();
+	virtual void redo();
+
+private:
+
+	LigoData m_ligoData;
+	QGraphicsPixmapItem *m_item;
+	ZoneBuilder *m_zoneBuilder;
+	QGraphicsScene *m_scene;
+};
 
 } /* namespace LandscapeEditor */
 
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
index c17de1f43..90c712e6c 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
@@ -33,7 +33,6 @@
 #include <QtCore/QSettings>
 #include <QtGui/QFileDialog>
 #include <QtOpenGL/QGLWidget>
-#include <QtGui/QGraphicsPixmapItem>
 
 namespace LandscapeEditor
 {
@@ -50,10 +49,9 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
 	m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder);
 	m_ui.zoneListWidget->updateUi();
 
-	m_landscapeScene = new LandscapeScene(this);
+	m_landscapeScene = new LandscapeScene(m_undoStack, m_ui.zoneListWidget, m_zoneBuilder, this);
 	m_ui.graphicsView->setScene(m_landscapeScene);
-	m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers)));
-
+	//m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers)));
 
 	createMenus();
 	createToolBars();
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
index 1361cd2bc..bb14576a2 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
@@ -27,6 +27,14 @@
     </property>
     <item row="0" column="0">
      <widget class="LandscapeEditor::LandscapeView" name="graphicsView">
+      <property name="sceneRect">
+       <rectf>
+        <x>0.000000000000000</x>
+        <y>0.000000000000000</y>
+        <width>99999.000000000000000</width>
+        <height>99999.000000000000000</height>
+       </rectf>
+      </property>
       <property name="dragMode">
        <enum>QGraphicsView::NoDrag</enum>
       </property>
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
index f491dfa2b..993b6ec9c 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
@@ -17,22 +17,68 @@
 
 // Project includes
 #include "landscape_scene.h"
+#include "builder_zone.h"
+#include "landscape_actions.h"
+#include "list_zones_widget.h"
 
 // NeL includes
 #include <nel/misc/debug.h>
 
 // Qt includes
+#include <QtGui/QPainter>
+#include <QtGui/QGraphicsPixmapItem>
 
 namespace LandscapeEditor
 {
 
-LandscapeScene::LandscapeScene(QObject *parent)
-	: QGraphicsScene(parent)
+LandscapeScene::LandscapeScene(QUndoStack *undoStack, ListZonesWidget *listZonesWidget, ZoneBuilder *zoneBuilder, QObject *parent)
+	: QGraphicsScene(parent),
+	  m_undoStack(undoStack),
+	  m_listZonesWidget(listZonesWidget),
+	  m_zoneBuilder(zoneBuilder)
 {
+	m_cellSize = 160;
+	createBackgroundPixmap();
 }
 
 LandscapeScene::~LandscapeScene()
 {
 }
 
+void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
+{
+	if (mouseEvent->button() != Qt::LeftButton)
+		return;
+
+	qreal x = mouseEvent->scenePos().rx();
+	qreal y = mouseEvent->scenePos().ry();
+	if ((x < 0) || (y < 0))
+		return;
+
+	LigoData ligoData = m_listZonesWidget->currentLigoData();
+	if (ligoData.ZoneName == "")
+		return;
+
+	ligoData.PosX = m_cellSize * int(x / m_cellSize);;
+	ligoData.PosY = m_cellSize * int(y / m_cellSize);
+	ligoData.Scale = m_cellSize / 256.0;
+
+	ActionLigoTile *action = new ActionLigoTile(ligoData, m_zoneBuilder, this);
+	m_undoStack->push(action);
+
+	QGraphicsScene::mousePressEvent(mouseEvent);
+}
+
+void LandscapeScene::createBackgroundPixmap()
+{
+	QPixmap pixmap(QSize(m_cellSize, m_cellSize));
+	QPainter painter(&pixmap);
+	//painter.setRenderHint(QPainter::Antialiasing, true);
+	painter.setBrush(QBrush(Qt::lightGray));
+	painter.setPen(QPen(Qt::black, 3, Qt::DotLine));
+	painter.drawRect(0, 0, pixmap.width(), pixmap.height());
+
+	setBackgroundBrush(pixmap);
+}
+
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
index d4fb91c78..b4a7a68de 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
@@ -23,18 +23,33 @@
 // NeL includes
 
 // Qt includes
-#include <QGraphicsScene>
+#include <QtGui/QGraphicsScene>
+#include <QtGui/QGraphicsSceneMouseEvent>
+#include <QtGui/QUndoStack>
 
 namespace LandscapeEditor
 {
+class ZoneBuilder;
+class ListZonesWidget;
 
 class LandscapeScene : public QGraphicsScene
 {
 	Q_OBJECT
 
 public:
-	LandscapeScene(QObject *parent = 0);
+	LandscapeScene(QUndoStack *undoStack, ListZonesWidget *listZonesWidget, ZoneBuilder *zoneBuilder, QObject *parent = 0);
 	virtual ~LandscapeScene();
+
+protected:
+	void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
+
+private:
+	void createBackgroundPixmap();
+
+	int m_cellSize;
+	ListZonesWidget *m_listZonesWidget;
+	QUndoStack *m_undoStack;
+	ZoneBuilder *m_zoneBuilder;
 };
 
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
index 79b33599e..4bd202b7c 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
@@ -26,27 +26,52 @@
 #include <nel/misc/debug.h>
 
 // Qt includes
-
+#include <QApplication>
 
 namespace LandscapeEditor
 {
 
 LandscapeView::LandscapeView(QWidget *parent)
-	: QGraphicsView(parent)
+	: QGraphicsView(parent),
+	  m_moveMouse(false)
 {
-    setDragMode(ScrollHandDrag);
+	setDragMode(ScrollHandDrag);
+	setTransformationAnchor(AnchorUnderMouse);
 }
 
 LandscapeView::~LandscapeView()
 {
 }
 
-void LandscapeView::wheelEvent(QWheelEvent *event)
-{
-    double numDegrees = event->delta() / 8.0;
-    double numSteps = numDegrees / 15.0;
-    double factor = std::pow(1.125, numSteps);
-    scale(factor, factor);
+void LandscapeView::wheelEvent(QWheelEvent *event)
+{
+	double numDegrees = event->delta() / 8.0;
+	double numSteps = numDegrees / 15.0;
+	double factor = std::pow(1.125, numSteps);
+	scale(factor, factor);
+}
+
+void LandscapeView::mousePressEvent(QMouseEvent *event)
+{
+	QGraphicsView::mousePressEvent(event);
+	if (event->button() != Qt::MiddleButton)
+		return;
+	m_moveMouse = true;
+	QApplication::setOverrideCursor(Qt::ClosedHandCursor);
+}
+
+void LandscapeView::mouseMoveEvent(QMouseEvent *event)
+{
+	if (m_moveMouse)
+		translate(0.001, 0.001);
+	QGraphicsView::mouseMoveEvent(event);
+}
+
+void LandscapeView::mouseReleaseEvent(QMouseEvent *event)
+{
+	QApplication::restoreOverrideCursor();
+	m_moveMouse = false;
+	QGraphicsView::mouseReleaseEvent(event);
 }
 
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h
index db79b79ff..4ac090af6 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h
@@ -36,12 +36,16 @@ public:
 	~LandscapeView();
 
 protected:
-    void wheelEvent(QWheelEvent *event); 
+	virtual void wheelEvent(QWheelEvent *event);
+	virtual void mousePressEvent(QMouseEvent *event);
+	virtual void mouseMoveEvent(QMouseEvent *event);
+	virtual void mouseReleaseEvent(QMouseEvent *event);
 
 private Q_SLOTS:
 
 private:
 
+	bool m_moveMouse;
 }; /* class LandscapeView */
 
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
index e4e3fae0d..56e362181 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
@@ -17,7 +17,6 @@
 
 // Project includes
 #include "list_zones_widget.h"
-#include "builder_zone.h"
 #include "list_zones_model.h"
 
 // NeL includes
@@ -31,6 +30,7 @@
 
 // Qt includes
 #include <QtGui/QIcon>
+#include <QtCore/QModelIndex>
 
 namespace LandscapeEditor
 {
@@ -100,6 +100,16 @@ void ListZonesWidget::updateUi()
 	m_listZonesModel->rebuildModel(m_zoneBuilder->pixmapDatabase());
 }
 
+LigoData ListZonesWidget::currentLigoData() const
+{
+	LigoData ligoData;
+	ligoData.ZoneName = "";
+	QModelIndex index = m_ui.listView->currentIndex();
+	if (index.isValid())
+		ligoData.ZoneName = index.data().toString().toStdString();
+	return ligoData;
+}
+
 void ListZonesWidget::setZoneBuilder(ZoneBuilder *zoneBuilder)
 {
 	m_zoneBuilder = zoneBuilder;
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
index 049f0ebcb..b1a6525fc 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
@@ -20,6 +20,7 @@
 
 // Project includes
 #include "ui_list_zones_widget.h"
+#include "builder_zone.h"
 
 // NeL includes
 
@@ -27,7 +28,6 @@
 
 namespace LandscapeEditor
 {
-class ZoneBuilder;
 class ListZonesModel;
 
 /**
@@ -45,6 +45,7 @@ public:
 
 	void updateUi();
 	void setZoneBuilder(ZoneBuilder *zoneBuilder);
+	LigoData currentLigoData() const;
 
 Q_SIGNALS:
 private Q_SLOTS:

From c0c6700dd013074085fb42b28c727fe65b4066d8 Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Thu, 16 Jun 2011 09:32:49 +0300
Subject: [PATCH 06/19] Changed: #1301 Added max\min scale view. Improved
 drawing of the grid.

---
 .../landscape_editor/landscape_actions.cpp    | 44 +++++++++++--
 .../landscape_editor/landscape_actions.h      | 28 ++++++++-
 .../landscape_editor_window.cpp               |  3 +-
 .../landscape_editor_window.ui                | 18 ++++++
 .../landscape_editor/landscape_scene.cpp      | 15 +----
 .../landscape_editor/landscape_scene.h        |  3 +-
 .../landscape_editor/landscape_view.cpp       | 61 +++++++++++++++++++
 .../plugins/landscape_editor/landscape_view.h | 17 ++++--
 8 files changed, 161 insertions(+), 28 deletions(-)

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
index 14cdb4f4b..5582de2d7 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
@@ -27,7 +27,42 @@
 namespace LandscapeEditor
 {
 
-ActionLigoTile::ActionLigoTile(const LigoData &data, ZoneBuilder *zoneBuilder, QGraphicsScene *scene, QUndoCommand *parent)
+OpenLandscapeCommand::OpenLandscapeCommand(const QString &fileName, QUndoCommand *parent)
+	: QUndoCommand(parent),
+	  m_fileName(fileName)
+{
+}
+
+OpenLandscapeCommand::~OpenLandscapeCommand()
+{
+}
+
+void OpenLandscapeCommand::undo()
+{
+}
+
+void OpenLandscapeCommand::redo()
+{
+}
+
+NewLandscapeCommand::NewLandscapeCommand(QUndoCommand *parent)
+	: QUndoCommand(parent)
+{
+}
+
+NewLandscapeCommand::~NewLandscapeCommand()
+{
+}
+
+void NewLandscapeCommand::undo()
+{
+}
+
+void NewLandscapeCommand::redo()
+{
+}
+
+LigoTileCommand::LigoTileCommand(const LigoData &data, ZoneBuilder *zoneBuilder, QGraphicsScene *scene, QUndoCommand *parent)
 	: QUndoCommand(parent),
 	  m_item(0),
 	  m_zoneBuilder(zoneBuilder),
@@ -36,23 +71,24 @@ ActionLigoTile::ActionLigoTile(const LigoData &data, ZoneBuilder *zoneBuilder, Q
 	m_ligoData = data;
 }
 
-ActionLigoTile::~ActionLigoTile()
+LigoTileCommand::~LigoTileCommand()
 {
 }
 
-void ActionLigoTile::undo()
+void LigoTileCommand::undo()
 {
 	m_scene->removeItem(m_item);
 	delete m_item;
 	m_item = 0;
 }
 
-void ActionLigoTile::redo()
+void LigoTileCommand::redo()
 {
 	QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(m_ligoData.ZoneName.c_str()));
 	m_item = new QGraphicsPixmapItem(*pixmap, 0, m_scene);
 	m_item->setPos(m_ligoData.PosX, m_ligoData.PosY);
 	m_item->setScale(m_ligoData.Scale);
+	m_item->setTransformationMode(Qt::SmoothTransformation);
 	setText(QObject::tr("Add tile(%1, %2)").arg(m_ligoData.PosX).arg(m_ligoData.PosY));
 }
 
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
index 76cb92762..ff9c9dde0 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
@@ -32,11 +32,33 @@ namespace LandscapeEditor
 {
 class ZoneBuilder;
 
-class ActionLigoTile : public QUndoCommand
+class OpenLandscapeCommand: public QUndoCommand
 {
 public:
-	ActionLigoTile(const LigoData &data, ZoneBuilder *zoneBuilder, QGraphicsScene *scene, QUndoCommand *parent = 0);
-	~ActionLigoTile();
+	OpenLandscapeCommand(const QString &fileName, QUndoCommand *parent = 0);
+	~OpenLandscapeCommand();
+	virtual void undo();
+	virtual void redo();
+private:
+
+	QString m_fileName;
+};
+
+class NewLandscapeCommand: public QUndoCommand
+{
+public:
+	NewLandscapeCommand(QUndoCommand *parent = 0);
+	~NewLandscapeCommand();
+	virtual void undo();
+	virtual void redo();
+private:
+};
+
+class LigoTileCommand: public QUndoCommand
+{
+public:
+	LigoTileCommand(const LigoData &data, ZoneBuilder *zoneBuilder, QGraphicsScene *scene, QUndoCommand *parent = 0);
+	~LigoTileCommand();
 
 	virtual void undo();
 	virtual void redo();
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
index 90c712e6c..59a4553b9 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
@@ -51,13 +51,14 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
 
 	m_landscapeScene = new LandscapeScene(m_undoStack, m_ui.zoneListWidget, m_zoneBuilder, this);
 	m_ui.graphicsView->setScene(m_landscapeScene);
-	//m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers)));
+	m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers)));
 
 	createMenus();
 	createToolBars();
 	readSettings();
 
 	connect(m_ui.projectSettingsAction, SIGNAL(triggered()), this, SLOT(openProjectSettings()));
+	connect(m_ui.enableGridAction, SIGNAL(toggled(bool)), m_ui.graphicsView, SLOT(setVisibleGrid(bool)));
 }
 
 LandscapeEditorWindow::~LandscapeEditorWindow()
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
index bb14576a2..ff3121d04 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
@@ -73,6 +73,7 @@
     <bool>false</bool>
    </attribute>
    <addaction name="projectSettingsAction"/>
+   <addaction name="enableGridAction"/>
   </widget>
   <action name="projectSettingsAction">
    <property name="icon">
@@ -83,6 +84,23 @@
     <string>Project settings</string>
    </property>
   </action>
+  <action name="enableGridAction">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>EnableGrid</string>
+   </property>
+   <property name="toolTip">
+    <string>Show/Hide Grid</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+G</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
index 993b6ec9c..3b1ddd9fb 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
@@ -38,7 +38,6 @@ LandscapeScene::LandscapeScene(QUndoStack *undoStack, ListZonesWidget *listZones
 	  m_zoneBuilder(zoneBuilder)
 {
 	m_cellSize = 160;
-	createBackgroundPixmap();
 }
 
 LandscapeScene::~LandscapeScene()
@@ -63,22 +62,10 @@ void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
 	ligoData.PosY = m_cellSize * int(y / m_cellSize);
 	ligoData.Scale = m_cellSize / 256.0;
 
-	ActionLigoTile *action = new ActionLigoTile(ligoData, m_zoneBuilder, this);
+	LigoTileCommand *action = new LigoTileCommand(ligoData, m_zoneBuilder, this);
 	m_undoStack->push(action);
 
 	QGraphicsScene::mousePressEvent(mouseEvent);
 }
 
-void LandscapeScene::createBackgroundPixmap()
-{
-	QPixmap pixmap(QSize(m_cellSize, m_cellSize));
-	QPainter painter(&pixmap);
-	//painter.setRenderHint(QPainter::Antialiasing, true);
-	painter.setBrush(QBrush(Qt::lightGray));
-	painter.setPen(QPen(Qt::black, 3, Qt::DotLine));
-	painter.drawRect(0, 0, pixmap.width(), pixmap.height());
-
-	setBackgroundBrush(pixmap);
-}
-
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
index b4a7a68de..80417d4ff 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
@@ -41,10 +41,9 @@ public:
 	virtual ~LandscapeScene();
 
 protected:
-	void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
+	virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
 
 private:
-	void createBackgroundPixmap();
 
 	int m_cellSize;
 	ListZonesWidget *m_listZonesWidget;
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
index 4bd202b7c..26dd386ed 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
@@ -33,21 +33,55 @@ namespace LandscapeEditor
 
 LandscapeView::LandscapeView(QWidget *parent)
 	: QGraphicsView(parent),
+	  m_visibleGrid(true),
 	  m_moveMouse(false)
 {
 	setDragMode(ScrollHandDrag);
 	setTransformationAnchor(AnchorUnderMouse);
+	setBackgroundBrush(QBrush(Qt::lightGray));
+	//setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
+	//setRenderHints(QPainter::Antialiasing);
+	m_cellSize = 160;
+	m_numSteps = 0;
+	m_maxSteps = 20;
 }
 
 LandscapeView::~LandscapeView()
 {
 }
 
+bool LandscapeView::isVisibleGrid() const
+{
+	return m_visibleGrid;
+}
+
+void LandscapeView::setVisibleGrid(bool visible)
+{
+	m_visibleGrid = visible;
+
+	// hack for repaint view
+	translate(0.0001, 0.0001);
+}
+
 void LandscapeView::wheelEvent(QWheelEvent *event)
 {
 	double numDegrees = event->delta() / 8.0;
 	double numSteps = numDegrees / 15.0;
 	double factor = std::pow(1.125, numSteps);
+	if (factor > 1.0)
+	{
+		// check max scale view
+		if (m_numSteps > m_maxSteps)
+			return;
+		++m_numSteps;
+	}
+	else
+	{
+		// check min scale view
+		if (m_numSteps < -m_maxSteps)
+			return;
+		--m_numSteps;
+	}
 	scale(factor, factor);
 }
 
@@ -74,4 +108,31 @@ void LandscapeView::mouseReleaseEvent(QMouseEvent *event)
 	QGraphicsView::mouseReleaseEvent(event);
 }
 
+void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect)
+{
+	if (!m_visibleGrid)
+		return;
+
+	qreal scaleFactor = transform().m11();
+	painter->setPen(QPen(Qt::white, 1 / scaleFactor, Qt::SolidLine));
+
+	// draw grid
+	qreal left = m_cellSize * int(rect.left() / m_cellSize);
+	qreal top = m_cellSize * int(rect.top() / m_cellSize);
+
+	// draw vertical lines
+	while (left < rect.right())
+	{
+		painter->drawLine(int(left), int(rect.bottom()), int(left), int(rect.top()));
+		left += m_cellSize;
+	}
+
+	// draw horizontal lines
+	while (top < rect.bottom())
+	{
+		painter->drawLine(int(rect.left()), int(top), int(rect.right()), int(top));
+		top += m_cellSize;
+	}
+}
+
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h
index 4ac090af6..2ae251fee 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h
@@ -19,6 +19,7 @@
 #define LANDSCAPE_VIEW_H
 
 // Project includes
+#include "landscape_editor_global.h"
 
 // Qt includes
 #include <QtGui/QGraphicsView>
@@ -27,24 +28,32 @@
 namespace LandscapeEditor
 {
 
-class LandscapeView: public QGraphicsView
+class LANDSCAPE_EDITOR_EXPORT LandscapeView: public QGraphicsView
 {
 	Q_OBJECT
 
 public:
 	LandscapeView(QWidget *parent = 0);
-	~LandscapeView();
+	virtual ~LandscapeView();
 
+	bool isVisibleGrid() const;
+
+public Q_SLOTS:
+	void setVisibleGrid(bool visible);
+
+private Q_SLOTS:
 protected:
 	virtual void wheelEvent(QWheelEvent *event);
 	virtual void mousePressEvent(QMouseEvent *event);
 	virtual void mouseMoveEvent(QMouseEvent *event);
 	virtual void mouseReleaseEvent(QMouseEvent *event);
-
-private Q_SLOTS:
+	virtual void drawForeground(QPainter *painter, const QRectF &rect);
 
 private:
 
+	bool m_visibleGrid;
+	int m_numSteps, m_maxSteps;
+	int m_cellSize;
 	bool m_moveMouse;
 }; /* class LandscapeView */
 

From 4306ab94b5e869002161c0a89ac6c37c56e41232 Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Tue, 21 Jun 2011 10:14:46 +0300
Subject: [PATCH 07/19] Changed: #1301 Added load landscape from file. Added
 initial snapshot dialog.

---
 .../plugins/landscape_editor/CMakeLists.txt   |   2 +
 .../plugins/landscape_editor/builder_zone.h   |  29 ---
 .../landscape_editor/landscape_actions.cpp    |  40 +++-
 .../landscape_editor/landscape_actions.h      |  37 +++-
 .../landscape_editor_window.cpp               |  29 +++
 .../landscape_editor_window.h                 |   4 +
 .../landscape_editor_window.ui                |   6 +
 .../landscape_editor/landscape_scene.cpp      | 164 +++++++++++++-
 .../landscape_editor/landscape_scene.h        |  39 ++++
 .../landscape_editor/landscape_view.cpp       |   6 +-
 .../landscape_editor/list_zones_widget.cpp    |   3 +
 .../landscape_editor/list_zones_widget.h      |   1 +
 .../landscape_editor/list_zones_widget.ui     |  10 +-
 .../project_settings_dialog.ui                |  14 +-
 .../landscape_editor/shapshot_dialog.ui       | 208 ++++++++++++++++++
 .../landscape_editor/snapshot_dialog.cpp      |  45 ++++
 .../landscape_editor/snapshot_dialog.h        |  47 ++++
 .../landscape_editor/zone_region_editor.cpp   | 119 ++++++++++
 .../landscape_editor/zone_region_editor.h     |  62 ++++++
 19 files changed, 793 insertions(+), 72 deletions(-)
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
index e189af74b..8c4278c46 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
@@ -17,11 +17,13 @@ SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR	landscape_editor_plugin.h
 					landscape_actions.h
 					landscape_view.h
 					project_settings_dialog.h
+					snapshot_dialog.h
 )
 
 SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_UIS	landscape_editor_window.ui
 					list_zones_widget.ui
 					project_settings_dialog.ui
+					shapshot_dialog.ui
 )
 
 SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_RCS landscape_editor.qrc)
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
index 0ccbf4e23..f43bb7d7e 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
@@ -36,35 +36,6 @@
 namespace LandscapeEditor
 {
 
-// Data
-struct LigoData
-{
-	uint32			PosX;
-	uint32			PosY;
-	qreal			Scale;
-	uint8			Rot;
-	uint8			Flip;
-	std::string		ZoneName;
-	std::string		SharingMatNames[4];
-	uint8			SharingCutEdges[4];
-	bool operator!= (const LigoData& other) const
-	{
-		return (PosX != other.PosX) ||
-			   (PosY != other.PosY) ||
-			   (Rot != other.Rot) ||
-			   (Flip != other.Flip) ||
-			   (ZoneName != other.ZoneName) ||
-			   (SharingMatNames[0] != other.SharingMatNames[0]) ||
-			   (SharingMatNames[1] != other.SharingMatNames[1]) ||
-			   (SharingMatNames[2] != other.SharingMatNames[2]) ||
-			   (SharingMatNames[3] != other.SharingMatNames[3]) ||
-			   (SharingCutEdges[0] != other.SharingCutEdges[0]) ||
-			   (SharingCutEdges[1] != other.SharingCutEdges[1]) ||
-			   (SharingCutEdges[2] != other.SharingCutEdges[2]) ||
-			   (SharingCutEdges[3] != other.SharingCutEdges[3]);
-	}
-};
-
 /**
 @class PixmapDatabase
 @brief PixmapDatabase contains the image database
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
index 5582de2d7..84d59ba8d 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
@@ -62,34 +62,54 @@ void NewLandscapeCommand::redo()
 {
 }
 
-LigoTileCommand::LigoTileCommand(const LigoData &data, ZoneBuilder *zoneBuilder, QGraphicsScene *scene, QUndoCommand *parent)
+AddLigoTileCommand::AddLigoTileCommand(const LigoData &data, LandscapeScene *scene, QUndoCommand *parent)
 	: QUndoCommand(parent),
 	  m_item(0),
-	  m_zoneBuilder(zoneBuilder),
 	  m_scene(scene)
 {
 	m_ligoData = data;
 }
 
-LigoTileCommand::~LigoTileCommand()
+AddLigoTileCommand::~AddLigoTileCommand()
 {
 }
 
-void LigoTileCommand::undo()
+void AddLigoTileCommand::undo()
 {
 	m_scene->removeItem(m_item);
 	delete m_item;
 	m_item = 0;
 }
 
-void LigoTileCommand::redo()
+void AddLigoTileCommand::redo()
 {
-	QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(m_ligoData.ZoneName.c_str()));
-	m_item = new QGraphicsPixmapItem(*pixmap, 0, m_scene);
-	m_item->setPos(m_ligoData.PosX, m_ligoData.PosY);
-	m_item->setScale(m_ligoData.Scale);
-	m_item->setTransformationMode(Qt::SmoothTransformation);
+	m_item = m_scene->createZoneItem(m_ligoData);
 	setText(QObject::tr("Add tile(%1, %2)").arg(m_ligoData.PosX).arg(m_ligoData.PosY));
 }
 
+DelLigoTileCommand::DelLigoTileCommand(const LigoData &data, LandscapeScene *scene, QUndoCommand *parent)
+	: QUndoCommand(parent),
+	  m_item(0),
+	  m_scene(scene)
+{
+	m_ligoData = data;
+}
+
+DelLigoTileCommand::~DelLigoTileCommand()
+{
+}
+
+void DelLigoTileCommand::undo()
+{
+	m_item = m_scene->createZoneItem(m_ligoData);
+}
+
+void DelLigoTileCommand::redo()
+{
+	m_item = m_scene->itemAt(m_ligoData.PosX * m_scene->cellSize(), m_ligoData.PosY * m_scene->cellSize());
+	delete m_item;
+	m_item = 0;
+	setText(QObject::tr("Del tile(%1, %2)").arg(m_ligoData.PosX).arg(m_ligoData.PosY));
+}
+
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
index ff9c9dde0..7bbd1bd96 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
@@ -20,23 +20,24 @@
 
 // Project includes
 #include "builder_zone.h"
+#include "landscape_scene.h"
 
 // NeL includes
 
 // Qt includes
 #include <QtGui/QUndoCommand>
 #include <QtGui/QGraphicsScene>
-#include <QtGui/QGraphicsPixmapItem>
+#include <QtGui/QGraphicsItem>
 
 namespace LandscapeEditor
 {
-class ZoneBuilder;
 
 class OpenLandscapeCommand: public QUndoCommand
 {
 public:
 	OpenLandscapeCommand(const QString &fileName, QUndoCommand *parent = 0);
-	~OpenLandscapeCommand();
+	virtual ~OpenLandscapeCommand();
+
 	virtual void undo();
 	virtual void redo();
 private:
@@ -48,17 +49,18 @@ class NewLandscapeCommand: public QUndoCommand
 {
 public:
 	NewLandscapeCommand(QUndoCommand *parent = 0);
-	~NewLandscapeCommand();
+	virtual ~NewLandscapeCommand();
+
 	virtual void undo();
 	virtual void redo();
 private:
 };
 
-class LigoTileCommand: public QUndoCommand
+class AddLigoTileCommand: public QUndoCommand
 {
 public:
-	LigoTileCommand(const LigoData &data, ZoneBuilder *zoneBuilder, QGraphicsScene *scene, QUndoCommand *parent = 0);
-	~LigoTileCommand();
+	AddLigoTileCommand(const LigoData &data, LandscapeScene *scene, QUndoCommand *parent = 0);
+	virtual ~AddLigoTileCommand();
 
 	virtual void undo();
 	virtual void redo();
@@ -66,9 +68,24 @@ public:
 private:
 
 	LigoData m_ligoData;
-	QGraphicsPixmapItem *m_item;
-	ZoneBuilder *m_zoneBuilder;
-	QGraphicsScene *m_scene;
+	QGraphicsItem *m_item;
+	LandscapeScene *m_scene;
+};
+
+class DelLigoTileCommand: public QUndoCommand
+{
+public:
+	DelLigoTileCommand(const LigoData &data, LandscapeScene *scene, QUndoCommand *parent = 0);
+	virtual ~DelLigoTileCommand();
+
+	virtual void undo();
+	virtual void redo();
+
+private:
+
+	LigoData m_ligoData;
+	QGraphicsItem *m_item;
+	LandscapeScene *m_scene;
 };
 
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
index 59a4553b9..5ec3f6196 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
@@ -21,6 +21,7 @@
 #include "builder_zone.h"
 #include "landscape_scene.h"
 #include "project_settings_dialog.h"
+#include "snapshot_dialog.h"
 
 #include "../core/icore.h"
 #include "../core/imenu_manager.h"
@@ -51,6 +52,7 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
 
 	m_landscapeScene = new LandscapeScene(m_undoStack, m_ui.zoneListWidget, m_zoneBuilder, this);
 	m_ui.graphicsView->setScene(m_landscapeScene);
+	//m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer)));
 	m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers)));
 
 	createMenus();
@@ -58,6 +60,7 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
 	readSettings();
 
 	connect(m_ui.projectSettingsAction, SIGNAL(triggered()), this, SLOT(openProjectSettings()));
+	connect(m_ui.snapshotAction, SIGNAL(triggered()), this, SLOT(openSnapshotDialog()));
 	connect(m_ui.enableGridAction, SIGNAL(toggled(bool)), m_ui.graphicsView, SLOT(setVisibleGrid(bool)));
 }
 
@@ -83,6 +86,14 @@ void LandscapeEditorWindow::open()
 	{
 		QStringList list = fileNames;
 		_lastDir = QFileInfo(list.front()).absolutePath();
+		Q_FOREACH(QString fileName, fileNames)
+		{
+			m_zoneRegionEditor.load(fileName.toStdString());
+			m_landscapeScene->processZoneRegion(m_zoneRegionEditor.zoneRegion());
+			m_landscapeScene->setCurrentZoneRegion(&m_zoneRegionEditor.zoneRegion());
+			m_ui.graphicsView->centerOn(m_zoneRegionEditor.zoneRegion().getMinX() * m_landscapeScene->cellSize(),
+										abs(m_zoneRegionEditor.zoneRegion().getMinY()) * m_landscapeScene->cellSize());
+		}
 	}
 	setCursor(Qt::ArrowCursor);
 }
@@ -100,6 +111,24 @@ void LandscapeEditorWindow::openProjectSettings()
 	delete dialog;
 }
 
+void LandscapeEditorWindow::openSnapshotDialog()
+{
+	SnapshotDialog *dialog = new SnapshotDialog(this);
+	dialog->show();
+	int ok = dialog->exec();
+	if (ok == QDialog::Accepted)
+	{
+		QString fileName = QFileDialog::getSaveFileName(this,
+						   tr("Save screenshot landscape"), _lastDir,
+						   tr("Image file (*.png)"));
+
+		setCursor(Qt::WaitCursor);
+		m_landscapeScene->snapshot(fileName, 128);
+		setCursor(Qt::ArrowCursor);
+	}
+	delete dialog;
+}
+
 void LandscapeEditorWindow::createMenus()
 {
 	Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager();
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
index 1fecd9f03..311a65013 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
@@ -20,6 +20,7 @@
 
 // Project includes
 #include "ui_landscape_editor_window.h"
+#include "zone_region_editor.h"
 
 // Qt includes
 #include <QtGui/QUndoStack>
@@ -46,6 +47,7 @@ public Q_SLOTS:
 
 private Q_SLOTS:
 	void openProjectSettings();
+	void openSnapshotDialog();
 
 private:
 	void createMenus();
@@ -53,6 +55,8 @@ private:
 	void readSettings();
 	void writeSettings();
 
+	ZoneRegionEditor m_zoneRegionEditor;
+
 	LandscapeScene *m_landscapeScene;
 	ZoneBuilder *m_zoneBuilder;
 	QUndoStack *m_undoStack;
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
index ff3121d04..212d0eb13 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
@@ -72,6 +72,7 @@
    <attribute name="toolBarBreak">
     <bool>false</bool>
    </attribute>
+   <addaction name="snapshotAction"/>
    <addaction name="projectSettingsAction"/>
    <addaction name="enableGridAction"/>
   </widget>
@@ -101,6 +102,11 @@
     <string>Ctrl+G</string>
    </property>
   </action>
+  <action name="snapshotAction">
+   <property name="text">
+    <string>snapshot</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
index 3b1ddd9fb..96ad0879b 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
@@ -27,6 +27,7 @@
 // Qt includes
 #include <QtGui/QPainter>
 #include <QtGui/QGraphicsPixmapItem>
+#include <QtGui/QGraphicsSimpleTextItem>
 
 namespace LandscapeEditor
 {
@@ -35,7 +36,8 @@ LandscapeScene::LandscapeScene(QUndoStack *undoStack, ListZonesWidget *listZones
 	: QGraphicsScene(parent),
 	  m_undoStack(undoStack),
 	  m_listZonesWidget(listZonesWidget),
-	  m_zoneBuilder(zoneBuilder)
+	  m_zoneBuilder(zoneBuilder),
+	  m_zoneRegion(0)
 {
 	m_cellSize = 160;
 }
@@ -44,27 +46,167 @@ LandscapeScene::~LandscapeScene()
 {
 }
 
-void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
+int LandscapeScene::cellSize() const
 {
-	if (mouseEvent->button() != Qt::LeftButton)
+	return m_cellSize;
+}
+
+QGraphicsItem *LandscapeScene::createZoneItem(const LigoData &data)
+{
+	// Get image from pixmap database
+	QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(data.ZoneName.c_str()));
+	if (pixmap == 0)
+		return 0;
+
+	// Rotate the image counterclockwise
+	QMatrix matrix;
+	matrix.rotate(-data.Rot * 90.0);
+
+	QGraphicsPixmapItem *item;
+
+	if (data.Flip == 0)
+	{
+		item = new QGraphicsPixmapItem(pixmap->transformed(matrix, Qt::SmoothTransformation), 0, this);
+	}
+	else
+	{
+		// mirror image
+		QImage mirrorImage = pixmap->toImage();
+		QPixmap mirrorPixmap = QPixmap::fromImage(mirrorImage.mirrored(true, false));
+		item = new QGraphicsPixmapItem(mirrorPixmap.transformed(matrix, Qt::SmoothTransformation), 0, this);
+	}
+	// Enable bilinear filtering
+	item->setTransformationMode(Qt::SmoothTransformation);
+
+	// Set position graphics item with offset for large piece
+	NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.ZoneName);
+	item->setPos(data.PosX * m_cellSize, (abs(data.PosY) - zoneBankItem->getSizeY() + 1) * m_cellSize);
+
+	// The size graphics item should be equal or proportional m_cellSize
+	item->setScale(m_cellSize / 256.0);
+
+	// add debug info
+	QGraphicsSimpleTextItem *itemText = addSimpleText(QString("%1,%2 R-%3 F-%4").
+										arg(data.PosX).arg(data.PosY).
+										arg(data.Rot * 90.0).
+										arg(data.Flip),
+										QFont("Helvetica [Cronyx]", 14));
+
+	itemText->setZValue(2);
+	itemText->setPos(data.PosX * m_cellSize + 10, (abs(data.PosY) - zoneBankItem->getSizeY() + 1) * m_cellSize + 10);
+	itemText->setBrush(QBrush(Qt::white));
+
+	return item;
+}
+
+void LandscapeScene::processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
+{
+	for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i)
+	{
+		for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
+		{
+			std::string zoneName = zoneRegion.getName(i, j);
+			if ((!zoneName.empty()) &&
+					(zoneName != STRING_UNUSED) &&
+					(zoneRegion.getPosX(i, j) == 0) &&
+					(zoneRegion.getPosY(i, j) == 0))
+			{
+				LigoData data;
+				data.PosX = i;
+				data.PosY = j;
+				data.ZoneName = zoneName;
+				data.Rot = zoneRegion.getRot(i, j);
+				data.Flip = zoneRegion.getFlip(i, j);
+				QGraphicsItem *item = createZoneItem(data);
+			}
+		}
+	}
+}
+
+void LandscapeScene::setCurrentZoneRegion(NLLIGO::CZoneRegion *zoneRegion)
+{
+	m_zoneRegion = zoneRegion;
+}
+
+void LandscapeScene::snapshot(const QString &fileName, int sizeSource)
+{
+	if (m_zoneRegion == 0)
 		return;
 
+	sint32 regionMinX = m_zoneRegion->getMinX();
+	sint32 regionMaxX = m_zoneRegion->getMaxX();
+	sint32 regionMinY = m_zoneRegion->getMinY();
+	sint32 regionMaxY = m_zoneRegion->getMaxY();
+
+	int regionWidth = (regionMaxX - regionMinX + 1);
+	int regionHeight = (regionMaxY - regionMinY + 1);
+
+	snapshot(fileName, regionWidth * sizeSource, regionHeight * sizeSource);
+}
+
+void LandscapeScene::snapshot(const QString &fileName, int width, int height)
+{
+	if (m_zoneRegion == 0)
+		return;
+
+	sint32 regionMinX = m_zoneRegion->getMinX();
+	sint32 regionMaxX = m_zoneRegion->getMaxX();
+	sint32 regionMinY = m_zoneRegion->getMinY();
+	sint32 regionMaxY = m_zoneRegion->getMaxY();
+
+	int regionWidth = (regionMaxX - regionMinX + 1);
+	int regionHeight = (regionMaxY - regionMinY + 1);
+
+	QImage image(width, height, QImage::Format_RGB888);
+	QPainter painter(&image);
+	painter.setRenderHint(QPainter::Antialiasing, true);
+
+	// add white background
+	painter.setBrush(QBrush(Qt::white));
+	painter.setPen(Qt::NoPen);
+	painter.drawRect(0, 0, width, height);
+
+	render(&painter, QRectF(0, 0, width, height),
+		   QRectF(regionMinX * m_cellSize, abs(regionMaxY) * m_cellSize, regionWidth * m_cellSize, regionHeight * m_cellSize));
+
+	image.save(fileName);
+
+}
+
+void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
+{
 	qreal x = mouseEvent->scenePos().rx();
 	qreal y = mouseEvent->scenePos().ry();
 	if ((x < 0) || (y < 0))
 		return;
 
-	LigoData ligoData = m_listZonesWidget->currentLigoData();
-	if (ligoData.ZoneName == "")
-		return;
+	if (mouseEvent->button() == Qt::LeftButton)
+	{
+		// Add new zone brick
+		LigoData ligoData = m_listZonesWidget->currentLigoData();
+		if (ligoData.ZoneName == "")
+			return;
 
-	ligoData.PosX = m_cellSize * int(x / m_cellSize);;
-	ligoData.PosY = m_cellSize * int(y / m_cellSize);
-	ligoData.Scale = m_cellSize / 256.0;
+		ligoData.PosX = int(floor(x / m_cellSize));
+		ligoData.PosY = int(-floor(y / m_cellSize));
 
-	LigoTileCommand *action = new LigoTileCommand(ligoData, m_zoneBuilder, this);
-	m_undoStack->push(action);
+		AddLigoTileCommand *action = new AddLigoTileCommand(ligoData, this);
+		m_undoStack->push(action);
+	}
 
+	/*if (mouseEvent->button() == Qt::RightButton)
+	{
+		// Delete zone brick
+		LigoData ligoData;
+
+		ligoData.PosX = int(floor(x / m_cellSize));
+		ligoData.PosY = int(floor(y / m_cellSize));
+		ligoData.ZoneName = m_zoneRegion->getName(ligoData.PosX, -ligoData.PosY);
+		ligoData.Flip = m_zoneRegion->getFlip(ligoData.PosX, -ligoData.PosY);
+		ligoData.Rot = m_zoneRegion->getRot(ligoData.PosX, -ligoData.PosY);
+		DelLigoTileCommand *action = new DelLigoTileCommand(ligoData, this);
+		m_undoStack->push(action);
+	}*/
 	QGraphicsScene::mousePressEvent(mouseEvent);
 }
 
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
index 80417d4ff..2af45bf4b 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
@@ -21,6 +21,7 @@
 // Project includes
 
 // NeL includes
+#include <nel/ligo/zone_region.h>
 
 // Qt includes
 #include <QtGui/QGraphicsScene>
@@ -32,6 +33,34 @@ namespace LandscapeEditor
 class ZoneBuilder;
 class ListZonesWidget;
 
+// Data
+struct LigoData
+{
+	sint32			PosX;
+	sint32			PosY;
+	uint8			Rot;
+	uint8			Flip;
+	std::string		ZoneName;
+	std::string		SharingMatNames[4];
+	uint8			SharingCutEdges[4];
+	bool operator!= (const LigoData& other) const
+	{
+		return (PosX != other.PosX) ||
+			   (PosY != other.PosY) ||
+			   (Rot != other.Rot) ||
+			   (Flip != other.Flip) ||
+			   (ZoneName != other.ZoneName) ||
+			   (SharingMatNames[0] != other.SharingMatNames[0]) ||
+			   (SharingMatNames[1] != other.SharingMatNames[1]) ||
+			   (SharingMatNames[2] != other.SharingMatNames[2]) ||
+			   (SharingMatNames[3] != other.SharingMatNames[3]) ||
+			   (SharingCutEdges[0] != other.SharingCutEdges[0]) ||
+			   (SharingCutEdges[1] != other.SharingCutEdges[1]) ||
+			   (SharingCutEdges[2] != other.SharingCutEdges[2]) ||
+			   (SharingCutEdges[3] != other.SharingCutEdges[3]);
+	}
+};
+
 class LandscapeScene : public QGraphicsScene
 {
 	Q_OBJECT
@@ -40,6 +69,15 @@ public:
 	LandscapeScene(QUndoStack *undoStack, ListZonesWidget *listZonesWidget, ZoneBuilder *zoneBuilder, QObject *parent = 0);
 	virtual ~LandscapeScene();
 
+	int cellSize() const;
+
+	QGraphicsItem *createZoneItem(const LigoData &data);
+	void processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
+	void setCurrentZoneRegion(NLLIGO::CZoneRegion *zoneRegion);
+
+	void snapshot(const QString &fileName, int sizeSource);
+	void snapshot(const QString &fileName, int width, int height);
+
 protected:
 	virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
 
@@ -49,6 +87,7 @@ private:
 	ListZonesWidget *m_listZonesWidget;
 	QUndoStack *m_undoStack;
 	ZoneBuilder *m_zoneBuilder;
+	NLLIGO::CZoneRegion *m_zoneRegion;
 };
 
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
index 26dd386ed..610028762 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
@@ -114,11 +114,11 @@ void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect)
 		return;
 
 	qreal scaleFactor = transform().m11();
-	painter->setPen(QPen(Qt::white, 1 / scaleFactor, Qt::SolidLine));
+	painter->setPen(QPen(Qt::white, 0, Qt::SolidLine));
 
 	// draw grid
-	qreal left = m_cellSize * int(rect.left() / m_cellSize);
-	qreal top = m_cellSize * int(rect.top() / m_cellSize);
+	qreal left = m_cellSize * floor(rect.left() / m_cellSize);
+	qreal top = m_cellSize * floor(rect.top() / m_cellSize);
 
 	// draw vertical lines
 	while (left < rect.right())
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
index 56e362181..66d31479b 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
@@ -107,6 +107,9 @@ LigoData ListZonesWidget::currentLigoData() const
 	QModelIndex index = m_ui.listView->currentIndex();
 	if (index.isValid())
 		ligoData.ZoneName = index.data().toString().toStdString();
+
+	ligoData.Rot = m_ui.rotComboBox->currentIndex();
+	ligoData.Flip = m_ui.flipComboBox->currentIndex();
 	return ligoData;
 }
 
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
index b1a6525fc..8ad5d4c25 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
@@ -21,6 +21,7 @@
 // Project includes
 #include "ui_list_zones_widget.h"
 #include "builder_zone.h"
+#include "landscape_scene.h"
 
 // NeL includes
 
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui
index 289cb45dd..4d9f63129 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui
@@ -215,7 +215,7 @@
        <number>3</number>
       </property>
       <item row="0" column="0">
-       <widget class="QComboBox" name="comboBox">
+       <widget class="QComboBox" name="rotComboBox">
         <item>
          <property name="text">
           <string>0°</string>
@@ -233,7 +233,7 @@
         </item>
         <item>
          <property name="text">
-          <string>170°</string>
+          <string>270°</string>
          </property>
         </item>
         <item>
@@ -249,7 +249,7 @@
        </widget>
       </item>
       <item row="0" column="1">
-       <widget class="QComboBox" name="comboBox_2">
+       <widget class="QComboBox" name="flipComboBox">
         <item>
          <property name="text">
           <string>NoFlip</string>
@@ -273,14 +273,14 @@
        </widget>
       </item>
       <item row="0" column="2">
-       <widget class="QCheckBox" name="checkBox">
+       <widget class="QCheckBox" name="forceCheckBox">
         <property name="text">
          <string>Force</string>
         </property>
        </widget>
       </item>
       <item row="0" column="3">
-       <widget class="QCheckBox" name="checkBox_2">
+       <widget class="QCheckBox" name="propogateCheckBox">
         <property name="text">
          <string>Not propogate</string>
         </property>
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui
index bb94fcc0d..8be20c9aa 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui
@@ -23,6 +23,9 @@
      <property name="text">
       <string>Data directory:</string>
      </property>
+     <property name="buddy">
+      <cstring>pathLineEdit</cstring>
+     </property>
     </widget>
    </item>
    <item row="0" column="1">
@@ -40,6 +43,9 @@
      <property name="text">
       <string>Context:</string>
      </property>
+     <property name="buddy">
+      <cstring>contextComboBox</cstring>
+     </property>
     </widget>
    </item>
    <item row="1" column="1" colspan="2">
@@ -68,8 +74,8 @@
    <slot>accept()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>248</x>
-     <y>254</y>
+     <x>257</x>
+     <y>83</y>
     </hint>
     <hint type="destinationlabel">
      <x>157</x>
@@ -84,8 +90,8 @@
    <slot>reject()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>316</x>
-     <y>260</y>
+     <x>325</x>
+     <y>83</y>
     </hint>
     <hint type="destinationlabel">
      <x>286</x>
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui
new file mode 100644
index 000000000..792d9f7a4
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SnapshotDialog</class>
+ <widget class="QDialog" name="SnapshotDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>286</width>
+    <height>182</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Snapshot</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout_2">
+   <item row="0" column="0">
+    <widget class="QRadioButton" name="originalSizeRadioButton">
+     <property name="text">
+      <string>Original size</string>
+     </property>
+     <property name="checked">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QRadioButton" name="customSizeRadioButton">
+     <property name="enabled">
+      <bool>false</bool>
+     </property>
+     <property name="text">
+      <string>Custom size</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QGroupBox" name="groupBox">
+     <property name="enabled">
+      <bool>false</bool>
+     </property>
+     <property name="title">
+      <string/>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="0" column="1">
+       <widget class="QSpinBox" name="widthSpinBox">
+        <property name="maximum">
+         <number>99999</number>
+        </property>
+        <property name="value">
+         <number>512</number>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="label_2">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="text">
+         <string>TextLabel</string>
+        </property>
+        <property name="buddy">
+         <cstring>heightSpinBox</cstring>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QSpinBox" name="heightSpinBox">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="maximum">
+         <number>99999</number>
+        </property>
+        <property name="value">
+         <number>512</number>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="0">
+       <widget class="QLabel" name="label">
+        <property name="text">
+         <string>TextLabel</string>
+        </property>
+        <property name="buddy">
+         <cstring>widthSpinBox</cstring>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0" colspan="2">
+       <widget class="QCheckBox" name="keepRatioCheckBox">
+        <property name="text">
+         <string>Keep bitmap ratio</string>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="3" column="0">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <tabstops>
+  <tabstop>originalSizeRadioButton</tabstop>
+  <tabstop>customSizeRadioButton</tabstop>
+  <tabstop>widthSpinBox</tabstop>
+  <tabstop>heightSpinBox</tabstop>
+  <tabstop>keepRatioCheckBox</tabstop>
+  <tabstop>buttonBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>SnapshotDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>227</x>
+     <y>164</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>158</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>SnapshotDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>276</x>
+     <y>170</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>285</x>
+     <y>158</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>customSizeRadioButton</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>groupBox</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>59</x>
+     <y>39</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>78</x>
+     <y>62</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>keepRatioCheckBox</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>heightSpinBox</receiver>
+   <slot>setDisabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>84</x>
+     <y>122</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>178</x>
+     <y>106</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>keepRatioCheckBox</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>label_2</receiver>
+   <slot>setDisabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>55</x>
+     <y>129</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>48</x>
+     <y>103</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp
new file mode 100644
index 000000000..ff6ef1673
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp
@@ -0,0 +1,45 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+// Project includes
+#include "snapshot_dialog.h"
+#include "landscape_editor_constants.h"
+
+#include "../core/icore.h"
+#include "../core/core_constants.h"
+
+// NeL includes
+#include <nel/misc/debug.h>
+
+// Qt includes
+#include <QtCore/QSettings>
+#include <QtGui/QFileDialog>
+
+namespace LandscapeEditor
+{
+
+SnapshotDialog::SnapshotDialog(QWidget *parent)
+	: QDialog(parent)
+{
+	m_ui.setupUi(this);
+}
+
+SnapshotDialog::~SnapshotDialog()
+{
+}
+
+} /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h
new file mode 100644
index 000000000..906d59498
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h
@@ -0,0 +1,47 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef SNAPSHOT_DIALOG_H
+#define SNAPSHOT_DIALOG_H
+
+// Project includes
+#include "ui_shapshot_dialog.h"
+
+// Qt includes
+
+namespace LandscapeEditor
+{
+
+class SnapshotDialog: public QDialog
+{
+	Q_OBJECT
+
+public:
+	SnapshotDialog(QWidget *parent = 0);
+	~SnapshotDialog();
+
+private Q_SLOTS:
+
+
+private:
+
+	Ui::SnapshotDialog m_ui;
+}; /* class SnapshotDialog */
+
+} /* namespace LandscapeEditor */
+
+#endif // SNAPSHOT_DIALOG_H
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp
new file mode 100644
index 000000000..a3f109ada
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp
@@ -0,0 +1,119 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+// Project includes
+#include "zone_region_editor.h"
+
+// NeL includes
+#include <nel/misc/debug.h>
+#include <nel/misc/file.h>
+#include <nel/misc/i_xml.h>
+#include <nel/misc/o_xml.h>
+
+// Qt includes
+#include <QtGui/QMessageBox>
+
+namespace LandscapeEditor
+{
+
+ZoneRegionEditor::ZoneRegionEditor()
+{
+	m_fileName = "";
+}
+
+ZoneRegionEditor::~ZoneRegionEditor()
+{
+}
+
+bool ZoneRegionEditor::load(const std::string &fileName)
+{
+	bool result = true;
+	try
+	{
+		// Open it
+		NLMISC::CIFile fileIn;
+		if (fileIn.open(fileName))
+		{
+			NLMISC::CIXml xml(true);
+			xml.init(fileIn);
+			m_zoneRegion.serial(xml);
+		}
+		else
+		{
+			nlwarning("Can't open file %s for reading", fileName.c_str());
+			result = false;
+		}
+	}
+	catch (NLMISC::Exception& e)
+	{
+		nlwarning("Error reading file %s : %s", fileName.c_str(), e.what ());
+		result = false;
+	}
+	if (result)
+		m_fileName = fileName;
+	return result;
+}
+
+bool ZoneRegionEditor::save()
+{
+	if (m_fileName.empty())
+		return false;
+
+	bool result = true;
+	// Save the landscape
+	try
+	{
+
+		// Open file for writing
+		NLMISC::COFile fileOut;
+		if (fileOut.open(m_fileName, false, false, true))
+		{
+			// Be careful with the flushing of the COXml object
+			{
+				NLMISC::COXml xmlOut;
+				xmlOut.init(&fileOut);
+				m_zoneRegion.serial(xmlOut);
+				// Done
+				m_modified = false;
+			}
+			fileOut.close();
+		}
+		else
+		{
+			nlwarning("Can't open file %s for writing.", m_fileName.c_str());
+			result = false;
+		}
+	}
+	catch (NLMISC::Exception& e)
+	{
+		nlwarning("Error writing file %s : %s", m_fileName.c_str(), e.what());
+		result = false;
+	}
+	return result;
+}
+
+void ZoneRegionEditor::setFileName(const std::string &fileName)
+{
+	m_fileName = fileName;
+}
+
+NLLIGO::CZoneRegion &ZoneRegionEditor::zoneRegion()
+{
+	return m_zoneRegion;
+}
+
+} /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h
new file mode 100644
index 000000000..fd53d5483
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h
@@ -0,0 +1,62 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef LANDSCAPE_EDITOR_H
+#define LANDSCAPE_EDITOR_H
+
+// Project includes
+
+// NeL includes
+#include <nel/ligo/zone_bank.h>
+#include <nel/ligo/zone_region.h>
+
+// STL includes
+#include <string>
+
+// Qt includes
+
+namespace LandscapeEditor
+{
+
+class ZoneRegionEditor
+{
+public:
+	ZoneRegionEditor();
+	~ZoneRegionEditor();
+
+	// Load landscape data from file
+	bool load(const std::string &fileName);
+
+	// Save landscape data to file
+	bool save();
+
+	// Set file name
+	void setFileName(const std::string &fileName);
+
+	NLLIGO::CZoneRegion &zoneRegion();
+
+private:
+
+	bool m_modified;
+	bool m_editable;
+	std::string m_fileName;
+	NLLIGO::CZoneRegion m_zoneRegion;
+};
+
+} /* namespace LandscapeEditor */
+
+#endif // LANDSCAPE_EDITOR_H

From 5951c39cda535827810f44c159faca070f7b9e51 Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Tue, 28 Jun 2011 02:55:38 +0300
Subject: [PATCH 08/19] Changed: #1301 Binding 2d renderer to NELLIGO.

---
 .../plugins/landscape_editor/builder_zone.cpp |  256 +-
 .../plugins/landscape_editor/builder_zone.h   |   77 +-
 .../landscape_editor/builder_zone_region.cpp  | 2084 +++++++++++++++++
 .../landscape_editor/builder_zone_region.h    |  134 +-
 .../landscape_editor/landscape_actions.cpp    |  103 +-
 .../landscape_editor/landscape_actions.h      |   56 +-
 .../landscape_editor_window.cpp               |   22 +-
 .../landscape_editor_window.h                 |    3 -
 .../landscape_editor/landscape_scene.cpp      |  213 +-
 .../landscape_editor/landscape_scene.h        |   45 +-
 .../landscape_editor/list_zones_widget.cpp    |   32 +-
 .../landscape_editor/list_zones_widget.h      |    9 +-
 .../landscape_editor/zone_region_editor.cpp   |   66 +
 .../landscape_editor/zone_region_editor.h     |   36 +
 14 files changed, 2904 insertions(+), 232 deletions(-)

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
index 288a4b1be..8271fe37c 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
@@ -17,6 +17,8 @@
 
 // Project includes
 #include "builder_zone.h"
+#include "list_zones_widget.h"
+#include "landscape_actions.h"
 
 // NeL includes
 #include <nel/misc/debug.h>
@@ -29,9 +31,9 @@
 
 namespace LandscapeEditor
 {
-const int PixmapScale = 256;
 
 PixmapDatabase::PixmapDatabase()
+	: m_textureSize(256)
 {
 }
 
@@ -66,15 +68,21 @@ bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zon
 			// Generate filled pixmap
 		}
 		// All pixmaps must be have same size
-		if (pixmap->width() != sizeX * PixmapScale)
+		if (pixmap->width() != sizeX * m_textureSize)
 		{
-			QPixmap *scaledPixmap = new QPixmap(pixmap->scaled(sizeX * PixmapScale, sizeY * PixmapScale));
+			QPixmap *scaledPixmap = new QPixmap(pixmap->scaled(sizeX * m_textureSize, sizeY * m_textureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
 			delete pixmap;
 			m_pixmapMap.insert(zonePixmapName, scaledPixmap);
 		}
 		else
 			m_pixmapMap.insert(zonePixmapName, pixmap);
 	}
+
+	QPixmap *pixmap = new QPixmap(zonePath + "_UNUSED_.png");
+	QPixmap *scaledPixmap = new QPixmap(pixmap->scaled(m_textureSize, m_textureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+	delete pixmap;
+	m_pixmapMap.insert(QString(STRING_UNUSED), scaledPixmap);
+
 	delete progressDialog;
 	return true;
 }
@@ -105,8 +113,17 @@ QPixmap *PixmapDatabase::pixmap(const QString &zoneName) const
 	return result;
 }
 
-ZoneBuilder::ZoneBuilder()
-	: m_pixmapDatabase(0)
+int PixmapDatabase::textureSize() const
+{
+	return m_textureSize;
+}
+
+ZoneBuilder::ZoneBuilder(ListZonesWidget *listZonesWidget, LandscapeScene *landscapeScene, QUndoStack *undoStack)
+	: m_currentZoneRegion(-1),
+	  m_pixmapDatabase(0),
+	  m_listZonesWidget(listZonesWidget),
+	  m_landscapeScene(landscapeScene),
+	  m_undoStack(undoStack)
 {
 	m_pixmapDatabase = new PixmapDatabase();
 	m_lastPathName = "";
@@ -144,10 +161,131 @@ bool ZoneBuilder::init(const QString &pathName, bool makeAZone)
 		}
 	}
 	if ((makeAZone) && (bRet))
-		newZone();
+		createZoneRegion();
 	return bRet;
 }
 
+void ZoneBuilder::actionLigoTile(const LigoData &data, const ZonePosition &zonePos)
+{
+	nlinfo(QString("%1 %2 %3 (%4 %5)").arg(data.zoneName.c_str()).arg(zonePos.x).arg(zonePos.y).arg(data.posX).arg(data.posY).toStdString().c_str());
+	m_undoStack->push(new LigoTileCommand(data, zonePos, this, m_landscapeScene));
+}
+
+void ZoneBuilder::actionLigoMove(uint index, sint32 deltaX, sint32 deltaY)
+{
+	nlinfo("ligoMove");
+	//m_undoStack->push(new LigoMoveCommand(index, deltaX, deltaY, this));
+}
+
+void ZoneBuilder::actionLigoResize(uint index, sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY)
+{
+	nlinfo(QString("minX=%1 maxX=%2 minY=%3 maxY=%4").arg(newMinX).arg(newMaxX).arg(newMinY).arg(newMaxY).toStdString().c_str());
+	m_undoStack->push(new LigoResizeCommand(index, newMinX, newMaxX, newMinY, newMaxY, this));
+}
+
+void ZoneBuilder::addZone(sint32 posX, sint32 posY)
+{
+	if (m_builderZoneRegions.empty())
+		return;
+
+	std::string zoneName = m_listZonesWidget->currentZoneName().toStdString();
+	if (zoneName.empty())
+		return;
+
+	std::string error;
+	BuilderZoneRegion *builderZoneRegion = m_builderZoneRegions.at(m_currentZoneRegion);
+	builderZoneRegion->init(this, error);
+
+	uint8 rot = uint8(m_listZonesWidget->currentRot());
+	uint8 flip = uint8(m_listZonesWidget->currentFlip());
+
+	NLLIGO::CZoneBankElement *zoneBankElement = getZoneBank().getElementByZoneName(zoneName);
+
+	m_undoStack->beginMacro(QString("Add zone %1,%2").arg(posX).arg(posY));
+	if (m_listZonesWidget->isForce())
+	{
+		builderZoneRegion->addForce(posX, posY, rot, flip, zoneBankElement);
+	}
+	else
+	{
+		if (m_listZonesWidget->isNotPropogate())
+			builderZoneRegion->addNotPropagate(posX, posY, rot, flip, zoneBankElement);
+		else
+			builderZoneRegion->add(posX, posY, rot, flip, zoneBankElement);
+	}
+	m_undoStack->endMacro();
+}
+
+void ZoneBuilder::addTransition(const sint32 posX, const sint32 posY)
+{
+}
+
+void ZoneBuilder::delZone(const sint32 posX, const sint32 posY)
+{
+	if (m_builderZoneRegions.empty())
+		return;
+
+	m_undoStack->beginMacro(QString("Del zone %1,%2").arg(posX).arg(posY));
+	BuilderZoneRegion *builderZoneRegion = m_builderZoneRegions.at(m_currentZoneRegion);
+	std::string error;
+	builderZoneRegion->init(this, error);
+	builderZoneRegion->del(posX, posY);
+	m_undoStack->endMacro();
+}
+
+int ZoneBuilder::createZoneRegion()
+{
+	ZoneRegionEditor *newZoneRegion = new ZoneRegionEditor();
+	m_zoneRegions.push_back(newZoneRegion);
+	if (m_currentZoneRegion == -1)
+		m_currentZoneRegion = m_zoneRegions.indexOf(newZoneRegion);
+
+	newZone();
+	return m_zoneRegions.indexOf(newZoneRegion);
+}
+
+void ZoneBuilder::deleteZoneRegion(int id)
+{
+	if ((0 <= id) && (id < m_zoneRegions.size()))
+		delete m_zoneRegions.takeAt(id);
+}
+
+void ZoneBuilder::setCurrentZoneRegion(int id)
+{
+	if ((0 <= id) && (id < m_zoneRegions.size()))
+		m_currentZoneRegion = id;
+}
+
+int ZoneBuilder::currentIdZoneRegion() const
+{
+	return m_currentZoneRegion;
+}
+
+ZoneRegionEditor *ZoneBuilder::currentZoneRegion() const
+{
+	return m_zoneRegions.at(m_currentZoneRegion);
+}
+
+int ZoneBuilder::countZoneRegion() const
+{
+	return m_zoneRegions.size();
+}
+
+ZoneRegionEditor *ZoneBuilder::zoneRegion(int id) const
+{
+	return m_zoneRegions.at(id);
+}
+
+void ZoneBuilder::ligoData(LigoData &data, const ZonePosition &zonePos)
+{
+	m_zoneRegions.at(zonePos.region)->ligoData(data, zonePos.x, zonePos.y);
+}
+
+void ZoneBuilder::setLigoData(LigoData &data, const ZonePosition &zonePos)
+{
+	m_zoneRegions.at(zonePos.region)->setLigoData(data, zonePos.x, zonePos.y);
+}
+
 bool ZoneBuilder::initZoneBank (const QString &pathName)
 {
 	QDir *dir = new QDir(pathName);
@@ -178,8 +316,112 @@ QString ZoneBuilder::dataPath() const
 	return m_lastPathName;
 }
 
-void ZoneBuilder::newZone (bool bDisplay)
+void ZoneBuilder::newZone()
 {
+	BuilderZoneRegion *builderZoneRegion = new BuilderZoneRegion(m_builderZoneRegions.size());
+	m_builderZoneRegions.push_back(builderZoneRegion);
+
+	// Select starting point for the moment 0,0
+	sint32 x = 0, y = 0;
+
+	// If there are some zone already present increase x until free
+	for (int i = 0; i < m_zoneRegions.size(); ++i)
+	{
+		const NLLIGO::CZoneRegion &zoneRegion = m_zoneRegions.at(i)->zoneRegion();
+		const std::string &zoneName = zoneRegion.getName (x, y);
+		if ((zoneName != STRING_OUT_OF_BOUND) && (zoneName != STRING_UNUSED))
+		{
+			++x;
+			i = -1;
+		}
+	}
+	calcMask();
+}
+
+bool ZoneBuilder::getZoneMask(sint32 x, sint32 y)
+{
+	if ((x < m_minX) || (x > m_maxX) ||
+			(y < m_minY) || (y > m_maxY))
+	{
+		return true;
+	}
+	else
+	{
+		return m_zoneMask[(x - m_minX) + (y - m_minY) * (1 + m_maxX - m_minX)];
+	}
+}
+
+void ZoneBuilder::calcMask()
+{
+	sint32 i;
+	sint32 x, y;
+
+	m_minY = m_minX = 1000000;
+	m_maxY = m_maxX = -1000000;
+
+	if (m_builderZoneRegions.size() == 0)
+		return;
+
+	for (i = 0; i < (sint32)m_builderZoneRegions.size(); ++i)
+	{
+		const NLLIGO::CZoneRegion &region = zoneRegion(i)->zoneRegion();
+
+		if (m_minX > region.getMinX())
+			m_minX = region.getMinX();
+		if (m_minY > region.getMinY())
+			m_minY = region.getMinY();
+		if (m_maxX < region.getMaxX())
+			m_maxX = region.getMaxX();
+		if (m_maxY < region.getMaxY())
+			m_maxY = region.getMaxY();
+	}
+
+	m_zoneMask.resize ((1 + m_maxX - m_minX) * (1 + m_maxY - m_minY));
+	sint32 stride = (1 + m_maxX - m_minX);
+	for (y = m_minY; y <= m_maxY; ++y)
+		for (x = m_minX; x <= m_maxX; ++x)
+		{
+			m_zoneMask[x - m_minX + (y - m_minY) * stride] = true;
+
+			for (i = 0; i < (sint32)m_builderZoneRegions.size(); ++i)
+				if (i != m_currentZoneRegion)
+				{
+					const NLLIGO::CZoneRegion &region = zoneRegion(i)->zoneRegion();
+
+					const std::string &rSZone = region.getName (x, y);
+					if ((rSZone != STRING_OUT_OF_BOUND) && (rSZone != STRING_UNUSED))
+					{
+						m_zoneMask[x - m_minX + (y - m_minY) * stride] = false;
+					}
+				}
+		}
+}
+
+bool ZoneBuilder::getZoneAmongRegions (ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y)
+{
+	Q_FOREACH(ZoneRegionEditor *zoneRegion, m_zoneRegions)
+	{
+		const NLLIGO::CZoneRegion &region = zoneRegion->zoneRegion();
+		if ((x < region.getMinX()) || (x > region.getMaxX()) ||
+				(y < region.getMinY()) || (y > region.getMaxY()))
+			continue;
+		if (region.getName(x, y) != STRING_UNUSED)
+		{
+			int index = m_zoneRegions.indexOf(zoneRegion);
+			builderZoneRegionFrom = m_builderZoneRegions.at(index);
+			zonePos = ZonePosition(x, y, index);
+			return true;
+		}
+	}
+
+	// The zone is not present in other region so it is an empty or oob zone of the current region
+	const NLLIGO::CZoneRegion &region = zoneRegion(builderZoneRegionFrom->getRegionId())->zoneRegion();
+	if ((x < region.getMinX()) || (x > region.getMaxX()) ||
+			(y < region.getMinY()) || (y > region.getMaxY()))
+		return false; // Out Of Bound
+
+	zonePos = ZonePosition(x, y, builderZoneRegionFrom->getRegionId());
+	return true;
 }
 
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
index f43bb7d7e..54cdb3b73 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
@@ -19,9 +19,12 @@
 #define BUILDER_ZONE_H
 
 // Project includes
+#include "builder_zone_region.h"
+#include "zone_region_editor.h"
 
 // NeL includes
 #include <nel/ligo/zone_bank.h>
+#include <nel/ligo/zone_region.h>
 
 // STL includes
 #include <string>
@@ -30,11 +33,38 @@
 // Qt includes
 #include <QtCore/QString>
 #include <QtCore/QMap>
+#include <QtCore/QList>
 #include <QtCore/QString>
 #include <QtGui/QPixmap>
+#include <QtGui/QUndoStack>
 
 namespace LandscapeEditor
 {
+class ListZonesWidget;
+class LandscapeScene;
+
+// Data
+struct ZonePosition
+{
+	// Absolute position
+	sint32 x;
+	sint32 y;
+	int region;
+
+	ZonePosition()
+	{
+		x = 0xffffffff;
+		y = 0xffffffff;
+		region = -1;
+	}
+
+	ZonePosition(const sint32 posX, const sint32 posY, const int id)
+	{
+		x = posX;
+		y = posY;
+		region = id;
+	}
+};
 
 /**
 @class PixmapDatabase
@@ -59,8 +89,12 @@ public:
 	/// Get original pixmap
 	/// @return QPixmap* if the image is in the database ; otherwise returns 0.
 	QPixmap *pixmap(const QString &zoneName) const;
+
+	int textureSize() const;
+
 private:
 
+	int m_textureSize;
 	QMap<QString, QPixmap*> m_pixmapMap;
 };
 
@@ -74,13 +108,37 @@ PixmapDatabase contains the graphics for the zones
 class ZoneBuilder
 {
 public:
-	ZoneBuilder();
+	ZoneBuilder(ListZonesWidget *listZonesWidget, LandscapeScene *landscapeScene, QUndoStack *undoStack);
 	~ZoneBuilder();
 
-	// Init zoneBank and init zone pixmap database
+	/// Init zoneBank and init zone pixmap database
 	bool init(const QString &pathName, bool bMakeAZone);
 
-	void newZone(bool bDisplay=true);
+	void calcMask();
+	void newZone();
+	bool getZoneMask (sint32 x, sint32 y);
+	bool getZoneAmongRegions(ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y);
+
+	// Ligo Actions
+	void actionLigoTile(const LigoData &data, const ZonePosition &zonePos);
+	void actionLigoMove(uint index, sint32 deltaX, sint32 deltaY);
+	void actionLigoResize(uint index, sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY);
+
+	// Zone Bricks
+	void addZone(sint32 posX, sint32 posY);
+	void addTransition(const sint32 posX, const sint32 posY);
+	void delZone(const sint32 posX, const sint32 posY);
+
+	// Zone Region
+	int createZoneRegion();
+	void deleteZoneRegion(int id);
+	void setCurrentZoneRegion(int id);
+	int currentIdZoneRegion() const;
+	ZoneRegionEditor *currentZoneRegion() const;
+	int countZoneRegion() const;
+	ZoneRegionEditor *zoneRegion(int id) const;
+	void ligoData(LigoData &data, const ZonePosition &zonePos);
+	void setLigoData(LigoData &data, const ZonePosition &zonePos);
 
 	// Accessors
 	NLLIGO::CZoneBank &getZoneBank()
@@ -94,15 +152,24 @@ public:
 
 private:
 
-	// Scan ./zoneligos dir and add all *.ligozone files to zoneBank
+	/// Scan ./zoneligos dir and add all *.ligozone files to zoneBank
 	bool initZoneBank (const QString &path);
 
 	sint32 m_minX, m_maxX, m_minY, m_maxY;
+	std::vector<bool> m_zoneMask;
+
 	QString m_lastPathName;
 
+	QList<ZoneRegionEditor *> m_zoneRegions;
+	int m_currentZoneRegion;
+
+	std::vector<BuilderZoneRegion *> m_builderZoneRegions;
+
 	PixmapDatabase *m_pixmapDatabase;
 	NLLIGO::CZoneBank m_zoneBank;
-	std::vector<NLLIGO::CZoneBankElement*> m_currentSelection;
+	ListZonesWidget *m_listZonesWidget;
+	LandscapeScene *m_landscapeScene;
+	QUndoStack *m_undoStack;
 };
 
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp
index 4dbd3e9e1..2a4fc204a 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp
@@ -17,6 +17,8 @@
 
 // Project includes
 #include "builder_zone_region.h"
+#include "builder_zone.h"
+#include "zone_region_editor.h"
 
 // NeL includes
 #include <nel/misc/debug.h>
@@ -25,4 +27,2086 @@
 
 namespace LandscapeEditor
 {
+
+BuilderZoneRegion::BuilderZoneRegion(uint regionId)
+	: m_regionId(regionId),
+	  m_zoneBuilder(0),
+	  m_firstInit(false)
+{
+}
+
+bool BuilderZoneRegion::init(ZoneBuilder *zoneBuilder, std::string &error)
+{
+	if (m_firstInit)
+		return true;
+
+	m_zoneBuilder = zoneBuilder;
+
+	uint32 j, k;
+	SMatNode mn;
+	std::vector<std::string> AllValues;
+
+	// Build the material tree
+	m_zoneBuilder->getZoneBank().getCategoryValues("material", AllValues);
+	for (uint32 i = 0; i < AllValues.size(); ++i)
+	{
+		mn.Name = AllValues[i];
+		m_matTree.push_back(mn);
+	}
+
+	// Link between materials
+	AllValues.clear ();
+	m_zoneBuilder->getZoneBank().getCategoryValues("transname", AllValues);
+	for (uint32 i = 0; i < AllValues.size(); ++i)
+	{
+		// Get the 2 materials linked together
+		std::string matAstr, matBstr;
+		for (j = 0; j < AllValues[i].size(); ++j)
+		{
+			if (AllValues[i][j] == '-')
+				break;
+			else
+				matAstr += AllValues[i][j];
+		}
+		++j;
+		for (; j < AllValues[i].size(); ++j)
+			matBstr += AllValues[i][j];
+
+		// Find matA
+		for (j = 0; j < m_matTree.size(); ++j)
+			if (m_matTree[j].Name == matAstr)
+				break;
+
+		if (j < m_matTree.size())
+		{
+			// Find matB
+			for (k = 0; k < m_matTree.size(); ++k)
+				if (m_matTree[k].Name == matBstr)
+					break;
+
+			if (k < m_matTree.size())
+			{
+				// Add a ref to matB in node matA
+				m_matTree[j].Arcs.push_back(k);
+
+				// Add a ref to matA in node matB
+				m_matTree[k].Arcs.push_back(j);
+			}
+		}
+	}
+
+	m_firstInit = true;
+	return true;
+}
+
+class ToUpdate
+{
+	struct SElement
+	{
+		sint32 x, y;
+
+		// Material put into the cell to update
+		std::string matPut;
+
+		BuilderZoneRegion *builderZoneRegion;
+	};
+
+	std::vector<SElement> m_elements;
+
+public:
+
+	void add(BuilderZoneRegion *builderZoneRegion, sint32 x, sint32 y, const std::string &matName)
+	{
+		bool bFound = false;
+		for (uint32 m = 0; m < m_elements.size(); ++m)
+			if ((m_elements[m].x == x) && (m_elements[m].y == y))
+			{
+				bFound = true;
+				break;
+			}
+		if (!bFound)
+		{
+			SElement newElement;
+			newElement.x = x;
+			newElement.y = y;
+			newElement.matPut = matName;
+			newElement.builderZoneRegion = builderZoneRegion;
+			m_elements.push_back (newElement);
+		}
+	}
+
+	void del(sint32 x, sint32 y)
+	{
+		bool bFound = false;
+		uint32 m;
+		for (m = 0; m < m_elements.size(); ++m)
+			if ((m_elements[m].x == x) && (m_elements[m].y == y))
+			{
+				bFound = true;
+				break;
+			}
+		if (bFound)
+		{
+			for (; m < m_elements.size() - 1; ++m)
+				m_elements[m] = m_elements[m + 1];
+			m_elements.resize (m_elements.size() - 1);
+		}
+	}
+
+	uint32 size()
+	{
+		return m_elements.size();
+	}
+
+	sint32 getX(uint32 m)
+	{
+		return m_elements[m].x;
+	}
+
+	sint32 getY(uint32 m)
+	{
+		return m_elements[m].y;
+	}
+
+	BuilderZoneRegion* getBuilderZoneRegion(uint32 m)
+	{
+		return m_elements[m].builderZoneRegion;
+	}
+
+	const std::string& getMat (uint32 m)
+	{
+		return m_elements[m].matPut;
+	}
+};
+
+void BuilderZoneRegion::add(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement)
+{
+	sint32 sizeX = zoneBankElement->getSizeX(), sizeY = zoneBankElement->getSizeY();
+	sint32 i, j;
+	NLLIGO::SPiece sMask, sPosX, sPosY;
+	ToUpdate tUpdate; // Transition to update
+
+	if (!m_zoneBuilder->getZoneMask (x,y))
+		return;
+
+	if (zoneBankElement->getCategory("transname") != STRING_NO_CAT_TYPE)
+	{
+		addTransition (x, y, rot, flip, zoneBankElement);
+		return;
+	}
+
+	// Create the mask in the good rotation and flip
+	sMask.Tab.resize(sizeX * sizeY);
+	sPosX.Tab.resize(sizeX * sizeY);
+	sPosY.Tab.resize(sizeX * sizeY);
+
+	for(j = 0; j < sizeY; ++j)
+		for(i = 0; i < sizeX; ++i)
+		{
+			sPosX.Tab[i + j * sizeX] = (uint8)i;
+			sPosY.Tab[i + j * sizeX] = (uint8)j;
+			sMask.Tab[i + j * sizeX] = zoneBankElement->getMask()[i + j * sizeX];
+		}
+	sPosX.w = sPosY.w = sMask.w = sizeX;
+	sPosX.h = sPosY.h = sMask.h = sizeY;
+	sMask.rotFlip(rot, flip);
+	sPosX.rotFlip(rot, flip);
+	sPosY.rotFlip(rot, flip);
+
+	// Test if the pieces can be put (due to mask)
+	for (j = 0; j < sMask.h; ++j)
+		for (i = 0; i < sMask.w; ++i)
+			if (sMask.Tab[i + j * sMask.w])
+			{
+				if (m_zoneBuilder->getZoneMask(x + i, y + j) == false)
+					return;
+			}
+
+	// Delete all pieces that are under the mask
+	for (j = 0; j < sMask.h; ++j)
+		for (i = 0; i < sMask.w; ++i)
+			if (sMask.Tab[i + j * sMask.w])
+			{
+				del(x + i, y + j, true, &tUpdate);
+			}
+
+	// Delete all around all material that are not from the same as us
+	const std::string &curMat = zoneBankElement->getCategory ("material");
+
+	if (curMat != STRING_NO_CAT_TYPE)
+	{
+		// This element is a valid material
+		// Place the piece
+		const std::string &eltName = zoneBankElement->getName ();
+		for (j = 0; j < sMask.h; ++j)
+			for (i = 0; i < sMask.w; ++i)
+				if (sMask.Tab[i + j * sMask.w])
+				{
+					set(x + i, y + j, sPosX.Tab[i + j * sPosX.w], sPosY.Tab[i + j * sPosY.w], eltName);
+					setRot(x + i, y + j, rot);
+					setFlip(x + i, y + j, flip);
+				}
+
+		// Put all transitions between different materials
+		putTransitions (x, y, sMask, curMat, &tUpdate);
+
+		// Place the piece
+		for (j = 0; j < sMask.h; ++j)
+			for (i = 0; i < sMask.w; ++i)
+				if (sMask.Tab[i + j * sMask.w])
+				{
+					set(x + i, y + j, sPosX.Tab[i + j * sPosX.w], sPosY.Tab[i + j * sPosY.w], eltName);
+					setRot(x + i, y + j, rot);
+					setFlip(x + i, y + j, flip);
+				}
+	}
+}
+
+void BuilderZoneRegion::invertCutEdge(sint32 x, sint32 y, uint8 cePos)
+{
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	if ((x < zoneRegion.getMinX ()) || (x > zoneRegion.getMaxX ()) ||
+			(y < zoneRegion.getMinY ()) || (y > zoneRegion.getMaxY ()))
+		return;
+
+	NLLIGO::CZoneBankElement *zoneBankElement = m_zoneBuilder->getZoneBank().getElementByZoneName(zoneRegion.getName(x, y));
+	if (zoneBankElement == NULL)
+		return;
+	if (zoneBankElement->getCategory("transname") == STRING_NO_CAT_TYPE)
+		return;
+
+
+	ZonePosition zonePos(x, y, m_regionId);
+	LigoData dataZone;
+
+	m_zoneBuilder->ligoData(dataZone, zonePos);
+	if (dataZone.sharingCutEdges[cePos] != 3 - dataZone.sharingCutEdges[cePos])
+	{
+		dataZone.sharingCutEdges[cePos] = 3 - dataZone.sharingCutEdges[cePos];
+
+		m_zoneBuilder->actionLigoTile(dataZone, zonePos);
+	}
+	updateTrans(x, y);
+
+	// If the transition number is not the same propagate the change
+	// Propagate where the edge is cut (1/3 or 2/3) and update the transition
+	if (cePos == 2)
+		if (dataZone.sharingMatNames[0] != dataZone.sharingMatNames[2])
+		{
+			if (x > zoneRegion.getMinX ())
+			{
+				// [x-1][y].right = [x][y].left
+				// _Zones[(x-1-zoneRegion->getMinX ())+(y-zoneRegion->getMinY ())*stride].SharingCutEdges[3] = dataZonePos.SharingCutEdges[2];
+				ZonePosition zonePosTemp(x - 1, y, m_regionId);
+				LigoData dataZoneTemp;
+				m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp);
+				if (dataZoneTemp.sharingCutEdges[3] != dataZone.sharingCutEdges[2])
+				{
+					dataZoneTemp.sharingCutEdges[3] = dataZone.sharingCutEdges[2];
+
+					// Add modification landscape
+					m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp);
+				}
+			}
+			updateTrans (x - 1, y);
+		}
+	if (cePos == 3)
+		if (dataZone.sharingMatNames[1] != dataZone.sharingMatNames[3])
+		{
+			if (x < zoneRegion.getMaxX ())
+			{
+				// [x+1][y].left = [x][y].right
+				ZonePosition zonePosTemp(x + 1, y, m_regionId);
+				LigoData dataZoneTemp;
+				m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp);
+				if (dataZoneTemp.sharingCutEdges[2] != dataZone.sharingCutEdges[3])
+				{
+					dataZoneTemp.sharingCutEdges[2] = dataZone.sharingCutEdges[3];
+
+					// Add modification landscape
+					m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp);
+				}
+			}
+			updateTrans (x + 1, y);
+		}
+	if (cePos == 1)
+		if (dataZone.sharingMatNames[0] != dataZone.sharingMatNames[1])
+		{
+			if (y > zoneRegion.getMinY ())
+			{
+				// [x][y-1].up = [x][y].down
+				ZonePosition zonePosTemp(x, y - 1, m_regionId);
+				LigoData dataZoneTemp;
+				m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp);
+				if (dataZoneTemp.sharingCutEdges[0] != dataZone.sharingCutEdges[1])
+				{
+					dataZoneTemp.sharingCutEdges[0] = dataZone.sharingCutEdges[1];
+
+					// Add modification landscape
+					m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp);
+				}
+			}
+			updateTrans (x, y-1);
+		}
+	if (cePos == 0)
+		if (dataZone.sharingMatNames[2] != dataZone.sharingMatNames[3])
+		{
+			if (y < zoneRegion.getMaxY ())
+			{
+				// [x][y+1].down = [x][y].up
+				ZonePosition zonePosTemp(x, y + 1, m_regionId);
+				LigoData dataZoneTemp;
+				m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp);
+				if (dataZoneTemp.sharingCutEdges[1] != dataZone.sharingCutEdges[0])
+				{
+					dataZoneTemp.sharingCutEdges[1] = dataZone.sharingCutEdges[0];
+
+					// Add modification landscape
+					m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp);
+				}
+			}
+			updateTrans (x, y + 1);
+		}
+}
+
+void BuilderZoneRegion::cycleTransition(sint32 x, sint32 y)
+{
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	if ((x < zoneRegion.getMinX ()) || (x > zoneRegion.getMaxX ()) ||
+			(y < zoneRegion.getMinY ()) || (y > zoneRegion.getMaxY ()))
+		return;
+
+	NLLIGO::CZoneBankElement *zoneBankElement = m_zoneBuilder->getZoneBank().getElementByZoneName (zoneRegion.getName (x, y));
+	if (zoneBankElement == NULL)
+		return;
+	if (zoneBankElement->getCategory("transname") == STRING_NO_CAT_TYPE)
+		return;
+
+	// \todo trap -> choose the good transition in function of the transition under the current location
+	// Choose the next possible transition if not the same as the first one
+	// Choose among all transition of the same number
+
+	updateTrans (x, y);
+}
+
+bool BuilderZoneRegion::addNotPropagate (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement)
+{
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	sint32 sizeX = zoneBankElement->getSizeX(), sizeY = zoneBankElement->getSizeY();
+	sint32 i, j;
+	NLLIGO::SPiece sMask, sPosX, sPosY;
+	ToUpdate tUpdate; // Transition to update
+
+	if (!m_zoneBuilder->getZoneMask (x, y))
+		return false;
+
+	if (zoneBankElement->getCategory("transname") != STRING_NO_CAT_TYPE)
+	{
+		addTransition (x, y, rot, flip, zoneBankElement);
+		return true;
+	}
+
+	// Create the mask in the good rotation and flip
+	sMask.Tab.resize (sizeX * sizeY);
+	sPosX.Tab.resize (sizeX * sizeY);
+	sPosY.Tab.resize (sizeX * sizeY);
+
+	for (j = 0; j < sizeY; ++j)
+		for (i = 0; i < sizeX; ++i)
+		{
+			sPosX.Tab[i + j * sizeX] = (uint8)i;
+			sPosY.Tab[i + j * sizeX] = (uint8)j;
+			sMask.Tab[i + j * sizeX] = zoneBankElement->getMask()[i + j * sizeX];
+		}
+	sPosX.w = sPosY.w = sMask.w = sizeX;
+	sPosX.h = sPosY.h = sMask.h = sizeY;
+	sMask.rotFlip (rot, flip);
+	sPosX.rotFlip (rot, flip);
+	sPosY.rotFlip (rot, flip);
+
+	// Test if the pieces can be put (due to mask)
+	sint32 stride = (1 + zoneRegion.getMaxX () - zoneRegion.getMinX ());
+	for (j = 0; j < sMask.h; ++j)
+		for (i = 0; i < sMask.w; ++i)
+			if (sMask.Tab[i+j*sMask.w])
+			{
+				if (m_zoneBuilder->getZoneMask(x + i, y + j) == false)
+					return false;
+				if (((x + i) < zoneRegion.getMinX ()) || ((x + i) > zoneRegion.getMaxX ()) ||
+						((y + j) < zoneRegion.getMinY ()) || ((y + j) > zoneRegion.getMaxY ()))
+					return false;
+				NLLIGO::CZoneBankElement *zoneBankElementUnder = m_zoneBuilder->getZoneBank().getElementByZoneName(zoneRegion.getName (x + i, y + j));
+				if (zoneBankElementUnder == NULL)
+					return false;
+				if (zoneBankElementUnder->getCategory("material") != zoneBankElement->getCategory("material"))
+					return false;
+			}
+
+	// Delete all pieces that are under the mask
+	for (j = 0; j < sMask.h; ++j)
+		for (i = 0; i < sMask.w; ++i)
+			if (sMask.Tab[i + j * sMask.w])
+			{
+				del(x + i, y + j, true, &tUpdate);
+			}
+
+	const std::string &curMat = zoneBankElement->getCategory ("material");
+
+	if (curMat != STRING_NO_CAT_TYPE)
+	{
+		// This element is a valid material
+		// Place the piece
+		const std::string &EltName = zoneBankElement->getName ();
+		for (j = 0; j < sMask.h; ++j)
+			for (i = 0; i < sMask.w; ++i)
+				if (sMask.Tab[i + j * sMask.w])
+				{
+					set (x + i, y + j, sPosX.Tab[i + j * sPosX.w], sPosY.Tab[i + j * sPosY.w], EltName);
+					setRot (x + i, y + j, rot);
+					setFlip (x + i, y + j, flip);
+				}
+	}
+
+	return true;
+}
+
+void BuilderZoneRegion::addForce (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement)
+{
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	sint32 sizeX = zoneBankElement->getSizeX(), sizeY = zoneBankElement->getSizeY();
+	sint32 i, j;
+	NLLIGO::SPiece sMask, sPosX, sPosY;
+	ToUpdate tUpdate; // Transition to update
+
+	if (!m_zoneBuilder->getZoneMask (x, y))
+		return;
+
+	/*
+	if (pElt->getCategory("transname") != STRING_NO_CAT_TYPE)
+	{
+		addTransition (x, y, nRot, nFlip, pElt);
+		return;
+	}*/
+
+	// Create the mask in the good rotation and flip
+	sMask.Tab.resize (sizeX * sizeY);
+	sPosX.Tab.resize (sizeX * sizeY);
+	sPosY.Tab.resize (sizeX * sizeY);
+
+	for (j = 0; j < sizeY; ++j)
+		for (i = 0; i < sizeX; ++i)
+		{
+			sPosX.Tab[i + j * sizeX] = (uint8)i;
+			sPosY.Tab[i + j * sizeX] = (uint8)j;
+			sMask.Tab[i + j * sizeX] = zoneBankElement->getMask()[i + j * sizeX];
+		}
+	sPosX.w = sPosY.w = sMask.w = sizeX;
+	sPosX.h = sPosY.h = sMask.h = sizeY;
+	sMask.rotFlip (rot, flip);
+	sPosX.rotFlip (rot, flip);
+	sPosY.rotFlip (rot, flip);
+
+	// Test if the pieces can be put (due to mask)
+	// All space under the mask must be empty
+	sint32 stride = (1 + zoneRegion.getMaxX () - zoneRegion.getMinX ());
+	for (j = 0; j < sMask.h; ++j)
+		for (i = 0; i < sMask.w; ++i)
+			if (sMask.Tab[i+j*sMask.w])
+			{
+				if (m_zoneBuilder->getZoneMask(x+i, y+j) == false)
+					return;
+				if (((x+i) < zoneRegion.getMinX ()) || ((x+i) > zoneRegion.getMaxX ()) ||
+						((y+j) < zoneRegion.getMinY ()) || ((y+j) > zoneRegion.getMaxY ()))
+					return;
+				NLLIGO::CZoneBankElement *zoneBankElementUnder = m_zoneBuilder->getZoneBank().getElementByZoneName(zoneRegion.getName (x + i, y + i));
+				if (zoneBankElementUnder != NULL)
+					return;
+			}
+
+	// Delete all pieces that are under the mask
+	for (j = 0; j < sMask.h; ++j)
+		for (i = 0; i < sMask.w; ++i)
+			if (sMask.Tab[i+j*sMask.w])
+			{
+				del(x+i, y+j, true, &tUpdate);
+			}
+
+	const std::string &curMat = zoneBankElement->getCategory ("material");
+	const bool transition = zoneBankElement->getCategory("transname") != STRING_NO_CAT_TYPE;
+
+	if (curMat != STRING_NO_CAT_TYPE || transition)
+	{
+		// This element is a valid material
+		// Place the piece
+		const std::string &eltName = zoneBankElement->getName();
+		for (j = 0; j < sMask.h; ++j)
+			for (i = 0; i < sMask.w; ++i)
+				if (sMask.Tab[i + j * sMask.w])
+				{
+					set(x + i, y + j, sPosX.Tab[i + j * sPosX.w], sPosY.Tab[i + j * sPosY.w], eltName, transition);
+					setRot(x + i, y + j, rot);
+					setFlip(x + i, y + j, flip);
+				}
+	}
+}
+
+uint8 TransToEdge[72][4] =
+{
+	{ 0, 0, 1, 1 }, // TransNum = 0, Flip = 0, Rot = 0
+	{ 2, 2, 0, 0 }, // TransNum = 0, Flip = 0, Rot = 1
+	{ 0, 0, 2, 2 }, // TransNum = 0, Flip = 0, Rot = 2
+	{ 1, 1, 0, 0 }, // TransNum = 0, Flip = 0, Rot = 3
+	{ 0, 0, 1, 1 }, // TransNum = 0, Flip = 1, Rot = 0
+	{ 2, 2, 0, 0 }, // TransNum = 0, Flip = 1, Rot = 1
+	{ 0, 0, 2, 2 }, // TransNum = 0, Flip = 1, Rot = 2
+	{ 1, 1, 0, 0 }, // TransNum = 0, Flip = 1, Rot = 3
+
+	{ 0, 0, 1, 2 }, // TransNum = 1, Flip = 0, Rot = 0
+	{ 1, 2, 0, 0 }, // TransNum = 1, Flip = 0, Rot = 1
+	{ 0, 0, 1, 2 }, // TransNum = 1, Flip = 0, Rot = 2
+	{ 1, 2, 0, 0 }, // TransNum = 1, Flip = 0, Rot = 3
+	{ 0, 0, 2, 1 }, // TransNum = 1, Flip = 1, Rot = 0
+	{ 2, 1, 0, 0 }, // TransNum = 1, Flip = 1, Rot = 1
+	{ 0, 0, 2, 1 }, // TransNum = 1, Flip = 1, Rot = 2
+	{ 2, 1, 0, 0 }, // TransNum = 1, Flip = 1, Rot = 3
+
+	{ 0, 0, 2, 2 }, // TransNum = 2, Flip = 0, Rot = 0
+	{ 1, 1, 0, 0 }, // TransNum = 2, Flip = 0, Rot = 1
+	{ 0, 0, 1, 1 }, // TransNum = 2, Flip = 0, Rot = 2
+	{ 2, 2, 0, 0 }, // TransNum = 2, Flip = 0, Rot = 3
+	{ 0, 0, 2, 2 }, // TransNum = 2, Flip = 1, Rot = 0
+	{ 1, 1, 0, 0 }, // TransNum = 2, Flip = 1, Rot = 1
+	{ 0, 0, 1, 1 }, // TransNum = 2, Flip = 1, Rot = 2
+	{ 2, 2, 0, 0 }, // TransNum = 2, Flip = 1, Rot = 3
+
+	{ 0, 1, 1, 0 }, // TransNum = 3, Flip = 0, Rot = 0
+	{ 0, 2, 0, 1 }, // TransNum = 3, Flip = 0, Rot = 1
+	{ 2, 0, 0, 2 }, // TransNum = 3, Flip = 0, Rot = 2
+	{ 1, 0, 2, 0 }, // TransNum = 3, Flip = 0, Rot = 3
+	{ 0, 2, 0, 1 }, // TransNum = 3, Flip = 1, Rot = 0
+	{ 2, 0, 0, 2 }, // TransNum = 3, Flip = 1, Rot = 1
+	{ 1, 0, 2, 0 }, // TransNum = 3, Flip = 1, Rot = 2
+	{ 0, 1, 1, 0 }, // TransNum = 3, Flip = 1, Rot = 3
+
+	{ 0, 2, 1, 0 }, // TransNum = 4, Flip = 0, Rot = 0
+	{ 0, 2, 0, 2 }, // TransNum = 4, Flip = 0, Rot = 1
+	{ 1, 0, 0, 2 }, // TransNum = 4, Flip = 0, Rot = 2
+	{ 1, 0, 1, 0 }, // TransNum = 4, Flip = 0, Rot = 3
+	{ 0, 1, 0, 1 }, // TransNum = 4, Flip = 1, Rot = 0
+	{ 2, 0, 0, 1 }, // TransNum = 4, Flip = 1, Rot = 1
+	{ 2, 0, 2, 0 }, // TransNum = 4, Flip = 1, Rot = 2
+	{ 0, 1, 2, 0 }, // TransNum = 4, Flip = 1, Rot = 3
+
+	{ 0, 2, 2, 0 }, // TransNum = 5, Flip = 0, Rot = 0
+	{ 0, 1, 0, 2 }, // TransNum = 5, Flip = 0, Rot = 1
+	{ 1, 0, 0, 1 }, // TransNum = 5, Flip = 0, Rot = 2
+	{ 2, 0, 1, 0 }, // TransNum = 5, Flip = 0, Rot = 3
+	{ 0, 1, 0, 2 }, // TransNum = 5, Flip = 1, Rot = 0
+	{ 1, 0, 0, 1 }, // TransNum = 5, Flip = 1, Rot = 1
+	{ 2, 0, 1, 0 }, // TransNum = 5, Flip = 1, Rot = 2
+	{ 0, 2, 2, 0 }, // TransNum = 5, Flip = 1, Rot = 3
+
+	{ 0, 1, 1, 0 }, // TransNum = 6, Flip = 0, Rot = 0
+	{ 0, 2, 0, 1 }, // TransNum = 6, Flip = 0, Rot = 1
+	{ 2, 0, 0, 2 }, // TransNum = 6, Flip = 0, Rot = 2
+	{ 1, 0, 2, 0 }, // TransNum = 6, Flip = 0, Rot = 3
+	{ 0, 2, 0, 1 }, // TransNum = 6, Flip = 1, Rot = 0
+	{ 2, 0, 0, 2 }, // TransNum = 6, Flip = 1, Rot = 1
+	{ 1, 0, 2, 0 }, // TransNum = 6, Flip = 1, Rot = 2
+	{ 0, 1, 1, 0 }, // TransNum = 6, Flip = 1, Rot = 3
+
+	{ 0, 2, 1, 0 }, // TransNum = 7, Flip = 0, Rot = 0
+	{ 0, 2, 0, 2 }, // TransNum = 7, Flip = 0, Rot = 1
+	{ 1, 0, 0, 2 }, // TransNum = 7, Flip = 0, Rot = 2
+	{ 1, 0, 1, 0 }, // TransNum = 7, Flip = 0, Rot = 3
+	{ 0, 1, 0, 1 }, // TransNum = 7, Flip = 1, Rot = 0
+	{ 2, 0, 0, 1 }, // TransNum = 7, Flip = 1, Rot = 1
+	{ 2, 0, 2, 0 }, // TransNum = 7, Flip = 1, Rot = 2
+	{ 0, 1, 2, 0 }, // TransNum = 7, Flip = 1, Rot = 3
+
+	{ 0, 2, 2, 0 }, // TransNum = 8, Flip = 0, Rot = 0
+	{ 0, 1, 0, 2 }, // TransNum = 8, Flip = 0, Rot = 1
+	{ 1, 0, 0, 1 }, // TransNum = 8, Flip = 0, Rot = 2
+	{ 2, 0, 1, 0 }, // TransNum = 8, Flip = 0, Rot = 3
+	{ 0, 1, 0, 2 }, // TransNum = 8, Flip = 1, Rot = 0
+	{ 1, 0, 0, 1 }, // TransNum = 8, Flip = 1, Rot = 1
+	{ 2, 0, 1, 0 }, // TransNum = 8, Flip = 1, Rot = 2
+	{ 0, 2, 2, 0 }, // TransNum = 8, Flip = 1, Rot = 3
+};
+
+void BuilderZoneRegion::addTransition (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement)
+{
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	uint32 i;
+	// Check that we write in an already defined place
+	if ((x < zoneRegion.getMinX ()) || (x > zoneRegion.getMaxX ()) ||
+			(y < zoneRegion.getMinY ()) || (y > zoneRegion.getMaxY ()))
+		return;
+
+	// Check size
+	if ((zoneBankElement->getSizeX() != 1) || (zoneBankElement->getSizeY() != 1))
+		return;
+
+	// Check that an element already exist at position we want put the transition
+	NLLIGO::CZoneBankElement *zoneBankElementUnder = m_zoneBuilder->getZoneBank().getElementByZoneName(zoneRegion.getName(x, y));
+	if (zoneBankElementUnder == NULL)
+		return;
+
+	// And check that this element is also a transition and the same transition
+	if (zoneBankElementUnder->getCategory ("transname") == STRING_NO_CAT_TYPE)
+		return;
+	if (zoneBankElementUnder->getCategory ("transname") != zoneBankElement->getCategory("transname"))
+		return;
+
+	std::string underType = zoneBankElementUnder->getCategory("transtype");
+	std::string overType = zoneBankElement->getCategory("transtype");
+	std::string underNum = zoneBankElementUnder->getCategory("transnum");
+	std::string overNum = zoneBankElement ->getCategory("transnum");
+
+	ZonePosition zonePosTemp(x, y, m_regionId);
+	LigoData dataZoneTemp;
+	m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp);
+	LigoData dataZoneOriginal = dataZoneTemp;
+
+	bool bMustPropagate = false;
+	// Same type of transition ?
+	if (zoneBankElementUnder->getCategory("transtype") != zoneBankElement->getCategory("transtype"))
+	{
+		// No so random the cutEdges
+		for (i = 0; i < 4; ++i)
+		{
+			uint8 nCut = (uint8)(1.0f + NLMISC::frand(2.0f));
+			NLMISC::clamp(nCut, (uint8)1, (uint8)2);
+
+			dataZoneTemp.sharingCutEdges[i] = nCut;
+		}
+		zoneBankElement = NULL;
+		bMustPropagate = true;
+	}
+	else
+	{
+		// Put exactly the transition as given
+		sint32 transnum = atoi(zoneBankElement->getCategory("transnum").c_str());
+		sint32 flip = zoneRegion.getFlip(x, y);
+		sint32 rot = zoneRegion.getRot(x, y);
+		sint32 pos1 = -1, pos2 = -1;
+
+		for (i = 0; i < 4; ++i)
+		{
+			if ((TransToEdge[transnum * 8 + flip * 4 + rot][i] != 0) &&
+					(TransToEdge[transnum * 8 + flip * 4 + rot][i] != dataZoneTemp.sharingCutEdges[i]))
+				bMustPropagate = true;
+
+			dataZoneTemp.sharingCutEdges[i] = TransToEdge[transnum * 8 + flip * 4 + rot][i];
+
+			if ((pos1 != -1) && (dataZoneTemp.sharingCutEdges[i] != 0))
+				pos2 = i;
+			if ((pos1 == -1) && (dataZoneTemp.sharingCutEdges[i] != 0))
+				pos1 = i;
+		}
+		// Exchange cutedges != 0 one time /2 to permit all positions
+		if ((transnum == 1) || (transnum == 4) || (transnum == 7))
+			if (zoneBankElement->getName() == zoneBankElementUnder->getName())
+			{
+				bMustPropagate = true;
+
+				dataZoneTemp.sharingCutEdges[pos1] = 3 - dataZoneTemp.sharingCutEdges[pos1];
+				dataZoneTemp.sharingCutEdges[pos2] = 3 - dataZoneTemp.sharingCutEdges[pos2];
+			}
+	}
+	if (dataZoneTemp != dataZoneOriginal)
+	{
+		// Add modification landscape
+		m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp);
+	}
+	updateTrans (x, y, zoneBankElement);
+
+	// If the transition number is not the same propagate the change
+	if (bMustPropagate)
+	{
+		// Propagate where the edge is cut (1/3 or 2/3) and update the transition
+		if (dataZoneTemp.sharingMatNames[0] != dataZoneTemp.sharingMatNames[2])
+		{
+			if (x > zoneRegion.getMinX ())
+			{
+				// [x-1][y].right = [x][y].left
+				// _Zones[(x-1-pBZR->getMinX ())+(y-pBZR->getMinY ())*stride].SharingCutEdges[3] = dataZoneTemp.SharingCutEdges[2];
+				ZonePosition zonePosTemp2(x - 1, y, m_regionId);
+				LigoData dataZoneTemp2;
+				m_zoneBuilder->ligoData(dataZoneTemp2, zonePosTemp2);
+				if (dataZoneTemp2.sharingCutEdges[3] != dataZoneTemp.sharingCutEdges[2])
+				{
+					dataZoneTemp2.sharingCutEdges[3] = dataZoneTemp.sharingCutEdges[2];
+
+					// Add modification landscape
+					m_zoneBuilder->actionLigoTile(dataZoneTemp2, zonePosTemp2);
+				}
+			}
+			updateTrans (x - 1, y);
+		}
+		if (dataZoneTemp.sharingMatNames[1] != dataZoneTemp.sharingMatNames[3])
+		{
+			if (x < zoneRegion.getMaxX ())
+			{
+				// [x+1][y].left = [x][y].right
+				//_Zones[(x+1-pBZR->getMinX ())+(y-pBZR->getMinY ())*stride].SharingCutEdges[2] = dataZoneTemp.SharingCutEdges[3];
+				ZonePosition zonePosTemp2(x + 1, y, m_regionId);
+				LigoData dataZoneTemp2;
+				m_zoneBuilder->ligoData(dataZoneTemp2, zonePosTemp2);
+				if (dataZoneTemp2.sharingCutEdges[2] != dataZoneTemp.sharingCutEdges[3])
+				{
+					dataZoneTemp2.sharingCutEdges[2] = dataZoneTemp.sharingCutEdges[3];
+
+					// Add modification landscape
+					m_zoneBuilder->actionLigoTile(dataZoneTemp2, zonePosTemp2);
+				}
+			}
+			updateTrans (x + 1, y);
+		}
+		if (dataZoneTemp.sharingMatNames[0] != dataZoneTemp.sharingMatNames[1])
+		{
+			if (y > zoneRegion.getMinY ())
+			{
+				// [x][y-1].up = [x][y].down
+				//_Zones[(x-pBZR->getMinX ())+(y-1-pBZR->getMinY ())*stride].SharingCutEdges[0] = dataZoneTemp.SharingCutEdges[1];
+				ZonePosition zonePosTemp2(x, y - 1, m_regionId);
+				LigoData dataZoneTemp2;
+				m_zoneBuilder->ligoData(dataZoneTemp2, zonePosTemp2);
+				if (dataZoneTemp2.sharingCutEdges[0] != dataZoneTemp.sharingCutEdges[1])
+				{
+					dataZoneTemp2.sharingCutEdges[0] = dataZoneTemp.sharingCutEdges[1];
+
+					// Add modification landscape
+					m_zoneBuilder->actionLigoTile(dataZoneTemp2, zonePosTemp2);
+				}
+			}
+			updateTrans (x, y - 1);
+		}
+		if (dataZoneTemp.sharingMatNames[2] != dataZoneTemp.sharingMatNames[3])
+		{
+			if (y < zoneRegion.getMaxY ())
+			{
+				// [x][y+1].down = [x][y].up
+				//_Zones[(x-pBZR->getMinX ())+(y+1-pBZR->getMinY ())*stride].SharingCutEdges[1] = dataZoneTemp.SharingCutEdges[0];
+				ZonePosition zonePosTemp2(x, y + 1, m_regionId);
+				LigoData dataZoneTemp2;
+				m_zoneBuilder->ligoData(dataZoneTemp2, zonePosTemp2);
+				if (dataZoneTemp2.sharingCutEdges[1] != dataZoneTemp.sharingCutEdges[0])
+				{
+					dataZoneTemp2.sharingCutEdges[1] = dataZoneTemp.sharingCutEdges[0];
+
+					// Add modification landscape
+					m_zoneBuilder->actionLigoTile(dataZoneTemp2, zonePosTemp2);
+				}
+			}
+			updateTrans (x, y + 1);
+		}
+	}
+}
+
+void BuilderZoneRegion::addToUpdateAndCreate(BuilderZoneRegion* builderZoneRegion, sint32 sharePos, sint32 x, sint32 y, const std::string &newMat, void *pInt1, void *pInt2)
+{
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	ToUpdate *ptCreate = reinterpret_cast<ToUpdate *>(pInt1);
+	ToUpdate *ptUpdate = reinterpret_cast<ToUpdate *>(pInt2);
+	sint32 stride = (1 + zoneRegion.getMaxX() - zoneRegion.getMinX());
+
+	ZonePosition zonePos;
+	if (m_zoneBuilder->getZoneAmongRegions(zonePos, builderZoneRegion, x, y))
+	{
+		LigoData data;
+		m_zoneBuilder->ligoData(data, zonePos);
+		if (data.sharingMatNames[sharePos] != newMat)
+		{
+			data.sharingMatNames[sharePos] = newMat;
+
+			// Add modification landscape
+			m_zoneBuilder->actionLigoTile(data, zonePos);
+		}
+		builderZoneRegion->del(x, y, true, ptUpdate);
+		ptCreate->add(builderZoneRegion, x, y, newMat);
+	}
+}
+
+void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SPiece &mask, const std::string &matName,
+										void *pInternal)
+{
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	ToUpdate tCreate; // Transition to create
+	ToUpdate *ptUpdate = reinterpret_cast<ToUpdate *>(pInternal); // Transition to update
+
+	sint32 i, j, k, l, m;
+	sint32 x = inX, y = inY;
+	for (j = 0; j < mask.h; ++j)
+		for (i = 0; i < mask.w; ++i)
+			if (mask.Tab[i + j * mask.w])
+			{
+				for (k = -1; k <= 1; ++k)
+					for (l = -1; l <= 1; ++l)
+					{
+						BuilderZoneRegion *builderZoneRegion2 = this;
+						ZonePosition zonePos;
+						if (m_zoneBuilder->getZoneAmongRegions(zonePos, builderZoneRegion2, inX + i + l, inY + j + k))
+							tCreate.add(builderZoneRegion2, inX + i + l, inY + j + k, matName);
+					}
+			}
+
+	// Check coherency of the transition to update
+	for (m = 0; m < (sint32)tCreate.size(); ++m)
+	{
+		BuilderZoneRegion *builderZoneRegion2 = tCreate.getBuilderZoneRegion(m);
+		x = tCreate.getX(m);
+		y = tCreate.getY(m);
+		std::string putMat = tCreate.getMat(m);
+
+		//if ((x < pBZR->getMinX ())||(x > pBZR->getMaxX ())||(y < pBZR->getMinY ())||(y > pBZR->getMaxY ()))
+		//	continue;
+
+		ZonePosition zoneTemp(x, y, builderZoneRegion2->getRegionId());
+		LigoData dataZoneTemp;
+		m_zoneBuilder->ligoData(dataZoneTemp, zoneTemp);
+
+		if (!((dataZoneTemp.sharingMatNames[0] == dataZoneTemp.sharingMatNames[1])&&
+				(dataZoneTemp.sharingMatNames[1] == dataZoneTemp.sharingMatNames[2])&&
+				(dataZoneTemp.sharingMatNames[2] == dataZoneTemp.sharingMatNames[3])))
+			builderZoneRegion2->del(x, y, true, ptUpdate);
+
+		// Check to see material can be posed
+		uint corner;
+		for (corner = 0; corner < 4; corner++)
+		{
+			std::string newMat = getNextMatInTree (putMat, dataZoneTemp.sharingMatNames[corner]);
+
+			// Can't be posed ?
+			if (newMat == STRING_UNUSED)
+				break;
+		}
+		if ( (corner < 4) && (m != 0) )
+		{
+			// The material can't be paused
+			dataZoneTemp.sharingMatNames[0] = STRING_UNUSED;
+			dataZoneTemp.sharingMatNames[1] = STRING_UNUSED;
+			dataZoneTemp.sharingMatNames[2] = STRING_UNUSED;
+			dataZoneTemp.sharingMatNames[3] = STRING_UNUSED;
+
+			// Don't propagate any more
+		}
+		else
+		{
+			// Expand material for the 1st quarter
+			std::string newMat = getNextMatInTree(putMat, dataZoneTemp.sharingMatNames[0]);
+			if (newMat != dataZoneTemp.sharingMatNames[0])
+			{
+				// Update the quarter
+				if (dataZoneTemp.sharingMatNames[0] != newMat)
+				{
+					dataZoneTemp.sharingMatNames[0] = newMat;
+
+					// Add modification landscape
+					m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp);
+				}
+
+				addToUpdateAndCreate(builderZoneRegion2, 1, x - 1, y, newMat, &tCreate, ptUpdate);
+				addToUpdateAndCreate(builderZoneRegion2, 3, x - 1, y - 1, newMat, &tCreate, ptUpdate);
+				addToUpdateAndCreate(builderZoneRegion2, 2, x, y - 1, newMat, &tCreate, ptUpdate);
+			}
+
+			// Expand material for the 2nd quarter
+			newMat = getNextMatInTree(putMat, dataZoneTemp.sharingMatNames[1]);
+			if (newMat != dataZoneTemp.sharingMatNames[1])
+			{
+				// Update the quarter
+				//if (_Builder->getZoneMask(x,y))
+				if (dataZoneTemp.sharingMatNames[1] != newMat)
+				{
+					dataZoneTemp.sharingMatNames[1] = newMat;
+
+					// Add modification landscape
+					m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp);
+				}
+
+				addToUpdateAndCreate(builderZoneRegion2, 0, x + 1, y, newMat, &tCreate, ptUpdate);
+				addToUpdateAndCreate(builderZoneRegion2, 2, x + 1, y - 1, newMat, &tCreate, ptUpdate);
+				addToUpdateAndCreate(builderZoneRegion2, 3, x, y - 1, newMat, &tCreate, ptUpdate);
+			}
+
+			// Expand material for the 3rd quarter
+			newMat = getNextMatInTree(putMat, dataZoneTemp.sharingMatNames[2]);
+			if (newMat != dataZoneTemp.sharingMatNames[2])
+			{
+				// Update the quarter
+				//if (_Builder->getZoneMask(x,y))
+				if (dataZoneTemp.sharingMatNames[2] != newMat)
+				{
+					dataZoneTemp.sharingMatNames[2] = newMat;
+
+					// Add modification landscape
+					m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp);
+				}
+
+				addToUpdateAndCreate(builderZoneRegion2, 3, x - 1, y, newMat, &tCreate, ptUpdate);
+				addToUpdateAndCreate(builderZoneRegion2, 1, x - 1, y + 1, newMat, &tCreate, ptUpdate);
+				addToUpdateAndCreate(builderZoneRegion2, 0, x, y + 1, newMat, &tCreate, ptUpdate);
+			}
+
+			// Expand material for the 4th quarter
+			newMat = getNextMatInTree(putMat, dataZoneTemp.sharingMatNames[3]);
+			if (newMat != dataZoneTemp.sharingMatNames[3])
+			{
+				// Update the quarter
+				//if (_Builder->getZoneMask(x,y))
+				if (dataZoneTemp.sharingMatNames[3] != newMat)
+				{
+					dataZoneTemp.sharingMatNames[3] = newMat;
+
+					// Add modification landscape
+					m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp);
+				}
+
+				addToUpdateAndCreate(builderZoneRegion2, 2, x + 1, y, newMat, &tCreate, ptUpdate);
+				addToUpdateAndCreate(builderZoneRegion2, 0, x + 1, y + 1, newMat, &tCreate, ptUpdate);
+				addToUpdateAndCreate(builderZoneRegion2, 1, x, y + 1, newMat, &tCreate, ptUpdate);
+			}
+		}
+
+		// Add modification landscape
+		m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp);
+	}
+
+	// Delete transitions that are inside the mask
+	for (j = 0; j < mask.h; ++j)
+		for (i = 0; i < mask.w; ++i)
+			if (mask.Tab[i + j * mask.w])
+			{
+				tCreate.del(inX + i, inY + j);
+			}
+
+	// For all transition to update choose the cut edge
+	for (m = 0; m < (sint32)tCreate.size(); ++m)
+	{
+		const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->zoneRegion();
+		x = tCreate.getX(m);
+		y = tCreate.getY(m);
+
+		if ((x < zoneRegion.getMinX()) || (x > zoneRegion.getMaxX()) ||
+				(y < zoneRegion.getMinY()) || (y > zoneRegion.getMaxY()))
+			continue;
+
+		ZonePosition zoneTemp(x, y, tCreate.getBuilderZoneRegion(m)->getRegionId());
+		LigoData dataZoneTemp;
+		m_zoneBuilder->ligoData(dataZoneTemp, zoneTemp);
+		LigoData dataZoneTempOriginal = dataZoneTemp;
+
+		for (i = 0; i < 4; ++i)
+		{
+			uint8 nCut = (uint8)(1.0f + NLMISC::frand(2.0f));
+			NLMISC::clamp(nCut, (uint8)1, (uint8)2);
+			dataZoneTemp.sharingCutEdges[i] = nCut;
+		}
+
+		// Add modification landscape
+		if (dataZoneTempOriginal != dataZoneTemp)
+			m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp);
+
+		// Propagate
+		if (dataZoneTemp.sharingMatNames[0] != dataZoneTemp.sharingMatNames[2])
+		{
+			// [x-1][y].right = [x][y].left
+			BuilderZoneRegion *builderZoneRegion3 = tCreate.getBuilderZoneRegion(m);
+			ZonePosition zonePosU;
+			if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion3, x - 1, y))
+			{
+				LigoData data;
+				m_zoneBuilder->ligoData(data, zonePosU);
+				if (data.sharingCutEdges[3] != dataZoneTemp.sharingCutEdges[2])
+				{
+					data.sharingCutEdges[3] = dataZoneTemp.sharingCutEdges[2];
+
+					// Add modification landscape
+					m_zoneBuilder->actionLigoTile(data, zonePosU);
+				}
+				ptUpdate->add(builderZoneRegion3, x - 1, y, "");
+			}
+		}
+		else
+		{
+			m_zoneBuilder->ligoData(dataZoneTemp, zoneTemp);
+			if (dataZoneTemp.sharingCutEdges[2] != 0)
+			{
+				dataZoneTemp.sharingCutEdges[2] = 0;
+
+				// Add modification landscape
+				m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp);
+			}
+		}
+
+		if (dataZoneTemp.sharingMatNames[0] != dataZoneTemp.sharingMatNames[1])
+		{
+			// [x][y-1].up = [x][y].down
+			BuilderZoneRegion *builderZoneRegion3 = tCreate.getBuilderZoneRegion(m);
+			ZonePosition zonePosU;
+			if (m_zoneBuilder->getZoneAmongRegions (zonePosU, builderZoneRegion3, x, y - 1))
+			{
+				LigoData data;
+				m_zoneBuilder->ligoData(data, zonePosU);
+				if (data.sharingCutEdges[0] != dataZoneTemp.sharingCutEdges[1])
+				{
+					data.sharingCutEdges[0] = dataZoneTemp.sharingCutEdges[1];
+
+					// Add modification landscape
+					m_zoneBuilder->actionLigoTile(data, zonePosU);
+				}
+				ptUpdate->add (builderZoneRegion3, x, y - 1, "");
+			}
+		}
+		else
+		{
+			m_zoneBuilder->ligoData(dataZoneTemp, zoneTemp);
+			if (dataZoneTemp.sharingCutEdges[1] != 0)
+			{
+				dataZoneTemp.sharingCutEdges[1] = 0;
+
+				// Add modification landscape
+				m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp);
+			}
+		}
+
+		if (dataZoneTemp.sharingMatNames[3] != dataZoneTemp.sharingMatNames[1])
+		{
+			// [x+1][y].left = [x][y].right
+			BuilderZoneRegion *builderZoneRegion3 = tCreate.getBuilderZoneRegion(m);
+			ZonePosition zonePosU;
+			if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion3, x + 1, y))
+			{
+				LigoData data;
+				m_zoneBuilder->ligoData(data, zonePosU);
+				if (data.sharingCutEdges[2] != dataZoneTemp.sharingCutEdges[3])
+				{
+					data.sharingCutEdges[2] = dataZoneTemp.sharingCutEdges[3];
+
+					// Add modification landscape
+					m_zoneBuilder->actionLigoTile(data, zonePosU);
+				}
+				ptUpdate->add(builderZoneRegion3, x + 1, y, "");
+			}
+		}
+		else
+		{
+			m_zoneBuilder->ligoData(dataZoneTemp, zoneTemp);
+			if (dataZoneTemp.sharingCutEdges[3] != 0)
+			{
+				dataZoneTemp.sharingCutEdges[3] = 0;
+
+				// Add modification landscape
+				m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp);
+			}
+		}
+
+		if (dataZoneTemp.sharingMatNames[2] != dataZoneTemp.sharingMatNames[3])
+		{
+			// [x][y+1].down = [x][y].up
+			BuilderZoneRegion *builderZoneRegion3 = tCreate.getBuilderZoneRegion(m);
+			ZonePosition  zonePosU;
+			if (m_zoneBuilder->getZoneAmongRegions (zonePosU, builderZoneRegion3, x, y+1))
+			{
+				LigoData data;
+				m_zoneBuilder->ligoData(data, zonePosU);
+				if (data.sharingCutEdges[1] = dataZoneTemp.sharingCutEdges[0])
+				{
+					data.sharingCutEdges[1] = dataZoneTemp.sharingCutEdges[0];
+
+					// Add modification landscape
+					m_zoneBuilder->actionLigoTile(data, zonePosU);
+				}
+				ptUpdate->add (builderZoneRegion3, x, y + 1, "");
+			}
+		}
+		else
+		{
+			m_zoneBuilder->ligoData(dataZoneTemp, zoneTemp);
+			if (dataZoneTemp.sharingCutEdges[0] = 0)
+			{
+				dataZoneTemp.sharingCutEdges[0] = 0;
+
+				// Add modification landscape
+				m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp);
+			}
+		}
+	}
+
+	// Delete in tUpdate each element in common with tCreate
+	for (m = 0; m < (sint32)tCreate.size(); ++m)
+	{
+		x = tCreate.getX(m);
+		y = tCreate.getY(m);
+		ptUpdate->del (x,y);
+	}
+
+	// Finally update all transition
+	for (m = 0; m < (sint32)tCreate.size(); ++m)
+	{
+		const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->zoneRegion();
+		x = tCreate.getX(m);
+		y = tCreate.getY(m);
+
+		if ((x >= zoneRegion2.getMinX()) && (x <= zoneRegion2.getMaxX()) &&
+				(y >= zoneRegion2.getMinY()) && (y <= zoneRegion2.getMaxY()))
+			tCreate.getBuilderZoneRegion(m)->updateTrans(x, y);
+	}
+	for (m = 0; m < (sint32)ptUpdate->size(); ++m)
+	{
+		const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->zoneRegion();
+		x = ptUpdate->getX(m);
+		y = ptUpdate->getY(m);
+		if ((x >= zoneRegion2.getMinX()) && (x <= zoneRegion2.getMaxX()) &&
+				(y >= zoneRegion2.getMinY()) && (y <= zoneRegion2.getMaxY()))
+			tCreate.getBuilderZoneRegion(m)->updateTrans(x, y);
+	}
+
+	// Cross material
+	for (m = 0; m < (sint32)tCreate.size(); ++m)
+	{
+		const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->zoneRegion();
+		x = tCreate.getX(m);
+		y = tCreate.getY(m);
+
+
+		ZonePosition zoneTemp(x, y, m_regionId);
+		LigoData dataZoneTemp;
+		m_zoneBuilder->ligoData(dataZoneTemp, zoneTemp);
+
+		std::set<std::string> matNameSet;
+		for (i = 0; i < 4; ++i)
+			matNameSet.insert(dataZoneTemp.sharingMatNames[i]);
+
+		if (((dataZoneTemp.sharingMatNames[0] == dataZoneTemp.sharingMatNames[3]) &&
+				(dataZoneTemp.sharingMatNames[1] == dataZoneTemp.sharingMatNames[2]) &&
+				(dataZoneTemp.sharingMatNames[0] != dataZoneTemp.sharingMatNames[1]))
+				|| (matNameSet.size()>2))
+		{
+			NLLIGO::CZoneBank &zoneBank = m_zoneBuilder->getZoneBank();
+			zoneBank.resetSelection();
+			zoneBank.addOrSwitch("material", tCreate.getMat(m));
+			zoneBank.addAndSwitch("size", "1x1");
+			std::vector<NLLIGO::CZoneBankElement *> vElts;
+			zoneBank.getSelection(vElts);
+			if (vElts.size() == 0)
+				return;
+			sint32 nRan = (sint32)(NLMISC::frand((float)vElts.size()));
+			NLMISC::clamp(nRan, (sint32)0, (sint32)(vElts.size() - 1));
+			NLLIGO::CZoneBankElement *zoneBankElement = vElts[nRan];
+			nRan = (uint32)(NLMISC::frand (1.0) * 4);
+			NLMISC::clamp(nRan, (sint32)0, (sint32)3);
+			uint8 rot = (uint8)nRan;
+			nRan = (uint32)(NLMISC::frand (1.0) * 2);
+			NLMISC::clamp (nRan, (sint32)0, (sint32)1);
+			uint8 flip = (uint8)nRan;
+
+			tCreate.getBuilderZoneRegion(m)->add(x, y, rot, flip, zoneBankElement);
+		}
+	}
+}
+
+struct STrans
+{
+	uint8 Num;
+	uint8 Rot;
+	uint8 Flip;
+};
+
+STrans TranConvTable[128] =
+{
+	{ 0,0,0 }, // Quart = 0, CutEdge = 0, Np = 0 UNUSED
+	{ 0,0,0 }, // Quart = 0, CutEdge = 0, Np = 1 UNUSED
+	{ 0,0,0 }, // Quart = 0, CutEdge = 1, Np = 0 UNUSED
+	{ 0,0,0 }, // Quart = 0, CutEdge = 1, Np = 1 UNUSED
+	{ 0,0,0 }, // Quart = 0, CutEdge = 2, Np = 0 UNUSED
+	{ 0,0,0 }, // Quart = 0, CutEdge = 2, Np = 1 UNUSED
+	{ 0,0,0 }, // Quart = 0, CutEdge = 3, Np = 0 UNUSED
+	{ 0,0,0 }, // Quart = 0, CutEdge = 3, Np = 1 UNUSED
+
+	{ 6,0,0 }, // Quart = 1, CutEdge = 0, Np = 0
+	{ 6,3,1 }, // Quart = 1, CutEdge = 0, Np = 1
+	{ 7,0,0 }, // Quart = 1, CutEdge = 1, Np = 0
+	{ 7,0,0 }, // Quart = 1, CutEdge = 1, Np = 1
+	{ 7,3,1 }, // Quart = 1, CutEdge = 2, Np = 0
+	{ 7,3,1 }, // Quart = 1, CutEdge = 2, Np = 1
+	{ 8,0,0 }, // Quart = 1, CutEdge = 3, Np = 0
+	{ 8,3,1 }, // Quart = 1, CutEdge = 3, Np = 1
+
+	{ 7,0,1 }, // Quart = 2, CutEdge = 0, Np = 0
+	{ 7,0,1 }, // Quart = 2, CutEdge = 0, Np = 1
+	{ 6,0,1 }, // Quart = 2, CutEdge = 1, Np = 0
+	{ 6,1,0 }, // Quart = 2, CutEdge = 1, Np = 1
+	{ 8,1,0 }, // Quart = 2, CutEdge = 2, Np = 0
+	{ 8,0,1 }, // Quart = 2, CutEdge = 2, Np = 1
+	{ 7,1,0 }, // Quart = 2, CutEdge = 3, Np = 0
+	{ 7,1,0 }, // Quart = 2, CutEdge = 3, Np = 1
+
+	{ 0,0,0 }, // Quart = 3, CutEdge = 0, Np = 0
+	{ 0,0,1 }, // Quart = 3, CutEdge = 0, Np = 1
+	{ 1,0,1 }, // Quart = 3, CutEdge = 1, Np = 0
+	{ 1,0,1 }, // Quart = 3, CutEdge = 1, Np = 1
+	{ 1,0,0 }, // Quart = 3, CutEdge = 2, Np = 0
+	{ 1,0,0 }, // Quart = 3, CutEdge = 2, Np = 1
+	{ 2,0,0 }, // Quart = 3, CutEdge = 3, Np = 0
+	{ 2,0,1 }, // Quart = 3, CutEdge = 3, Np = 1
+
+	{ 7,3,0 }, // Quart = 4, CutEdge = 0, Np = 0
+	{ 7,3,0 }, // Quart = 4, CutEdge = 0, Np = 1
+	{ 8,3,0 }, // Quart = 4, CutEdge = 1, Np = 0
+	{ 8,2,1 }, // Quart = 4, CutEdge = 1, Np = 1
+	{ 6,3,0 }, // Quart = 4, CutEdge = 2, Np = 0
+	{ 6,2,1 }, // Quart = 4, CutEdge = 2, Np = 1
+	{ 7,2,1 }, // Quart = 4, CutEdge = 3, Np = 0
+	{ 7,2,1 }, // Quart = 4, CutEdge = 3, Np = 1
+
+	{ 0,3,0 }, // Quart = 5, CutEdge = 0, Np = 0
+	{ 0,3,1 }, // Quart = 5, CutEdge = 0, Np = 1
+	{ 1,3,1 }, // Quart = 5, CutEdge = 1, Np = 0
+	{ 1,3,1 }, // Quart = 5, CutEdge = 1, Np = 1
+	{ 1,3,0 }, // Quart = 5, CutEdge = 2, Np = 0
+	{ 1,3,0 }, // Quart = 5, CutEdge = 2, Np = 1
+	{ 2,3,0 }, // Quart = 5, CutEdge = 3, Np = 0
+	{ 2,3,1 }, // Quart = 5, CutEdge = 3, Np = 1
+
+	{ 0,0,0 }, // Quart = 6, CutEdge = 0, Np = 0 UNUSED
+	{ 0,0,0 }, // Quart = 6, CutEdge = 0, Np = 1 UNUSED
+	{ 0,0,0 }, // Quart = 6, CutEdge = 1, Np = 0 UNUSED
+	{ 0,0,0 }, // Quart = 6, CutEdge = 1, Np = 1 UNUSED
+	{ 0,0,0 }, // Quart = 6, CutEdge = 2, Np = 0 UNUSED
+	{ 0,0,0 }, // Quart = 6, CutEdge = 2, Np = 1 UNUSED
+	{ 0,0,0 }, // Quart = 6, CutEdge = 3, Np = 0 UNUSED
+	{ 0,0,0 }, // Quart = 6, CutEdge = 3, Np = 1 UNUSED
+
+	{ 5,2,0 }, // Quart = 7, CutEdge = 0, Np = 0
+	{ 5,1,1 }, // Quart = 7, CutEdge = 0, Np = 1
+	{ 4,1,1 }, // Quart = 7, CutEdge = 1, Np = 0
+	{ 4,1,1 }, // Quart = 7, CutEdge = 1, Np = 1
+	{ 4,2,0 }, // Quart = 7, CutEdge = 2, Np = 0
+	{ 4,2,0 }, // Quart = 7, CutEdge = 2, Np = 1
+	{ 3,2,0 }, // Quart = 7, CutEdge = 3, Np = 0
+	{ 3,1,1 }, // Quart = 7, CutEdge = 3, Np = 1
+
+	{ 8,2,0 }, // Quart = 8, CutEdge = 0, Np = 0
+	{ 8,1,1 }, // Quart = 8, CutEdge = 0, Np = 1
+	{ 7,1,1 }, // Quart = 8, CutEdge = 1, Np = 0
+	{ 7,1,1 }, // Quart = 8, CutEdge = 1, Np = 1
+	{ 7,2,0 }, // Quart = 8, CutEdge = 2, Np = 0
+	{ 7,2,0 }, // Quart = 8, CutEdge = 2, Np = 1
+	{ 6,2,0 }, // Quart = 8, CutEdge = 3, Np = 0
+	{ 6,1,1 }, // Quart = 8, CutEdge = 3, Np = 1
+
+	{ 0,0,0 }, // Quart = 9, CutEdge = 0, Np = 0 UNUSED
+	{ 0,0,0 }, // Quart = 9, CutEdge = 0, Np = 1 UNUSED
+	{ 0,0,0 }, // Quart = 9, CutEdge = 1, Np = 0 UNUSED
+	{ 0,0,0 }, // Quart = 9, CutEdge = 1, Np = 1 UNUSED
+	{ 0,0,0 }, // Quart = 9, CutEdge = 2, Np = 0 UNUSED
+	{ 0,0,0 }, // Quart = 9, CutEdge = 2, Np = 1 UNUSED
+	{ 0,0,0 }, // Quart = 9, CutEdge = 3, Np = 0 UNUSED
+	{ 0,0,0 }, // Quart = 9, CutEdge = 3, Np = 1 UNUSED
+
+	{ 2,1,0 }, // Quart = 10, CutEdge = 0, Np = 0
+	{ 2,1,1 }, // Quart = 10, CutEdge = 0, Np = 1
+	{ 1,1,1 }, // Quart = 10, CutEdge = 1, Np = 0
+	{ 1,1,1 }, // Quart = 10, CutEdge = 1, Np = 1
+	{ 1,1,0 }, // Quart = 10, CutEdge = 2, Np = 0
+	{ 1,1,0 }, // Quart = 10, CutEdge = 2, Np = 1
+	{ 0,1,0 }, // Quart = 10, CutEdge = 3, Np = 0
+	{ 0,1,1 }, // Quart = 10, CutEdge = 3, Np = 1
+
+	{ 4,3,0 }, // Quart = 11, CutEdge = 0, Np = 0
+	{ 4,3,0 }, // Quart = 11, CutEdge = 0, Np = 1
+	{ 5,3,0 }, // Quart = 11, CutEdge = 1, Np = 0
+	{ 5,2,1 }, // Quart = 11, CutEdge = 1, Np = 1
+	{ 3,3,0 }, // Quart = 11, CutEdge = 2, Np = 0
+	{ 3,2,1 }, // Quart = 11, CutEdge = 2, Np = 1
+	{ 4,2,1 }, // Quart = 11, CutEdge = 3, Np = 0
+	{ 4,2,1 }, // Quart = 11, CutEdge = 3, Np = 1
+
+	{ 2,2,0 }, // Quart = 12, CutEdge = 0, Np = 0
+	{ 2,2,1 }, // Quart = 12, CutEdge = 0, Np = 1
+	{ 1,2,1 }, // Quart = 12, CutEdge = 1, Np = 0
+	{ 1,2,1 }, // Quart = 12, CutEdge = 1, Np = 1
+	{ 1,2,0 }, // Quart = 12, CutEdge = 2, Np = 0
+	{ 1,2,0 }, // Quart = 12, CutEdge = 2, Np = 1
+	{ 0,2,0 }, // Quart = 12, CutEdge = 3, Np = 0
+	{ 0,2,1 }, // Quart = 12, CutEdge = 3, Np = 1
+
+	{ 4,0,1 }, // Quart = 13, CutEdge = 0, Np = 0
+	{ 4,0,1 }, // Quart = 13, CutEdge = 0, Np = 1
+	{ 3,1,0 }, // Quart = 13, CutEdge = 1, Np = 0
+	{ 3,0,1 }, // Quart = 13, CutEdge = 1, Np = 1
+	{ 5,1,0 }, // Quart = 13, CutEdge = 2, Np = 0
+	{ 5,0,1 }, // Quart = 13, CutEdge = 2, Np = 1
+	{ 4,1,0 }, // Quart = 13, CutEdge = 3, Np = 0
+	{ 4,1,0 }, // Quart = 13, CutEdge = 3, Np = 1
+
+	{ 3,0,0 }, // Quart = 14, CutEdge = 0, Np = 0
+	{ 3,3,1 }, // Quart = 14, CutEdge = 0, Np = 1
+	{ 4,0,0 }, // Quart = 14, CutEdge = 1, Np = 0
+	{ 4,0,0 }, // Quart = 14, CutEdge = 1, Np = 1
+	{ 4,3,1 }, // Quart = 14, CutEdge = 2, Np = 0
+	{ 4,3,1 }, // Quart = 14, CutEdge = 2, Np = 1
+	{ 5,0,0 }, // Quart = 14, CutEdge = 3, Np = 0
+	{ 5,3,1 }, // Quart = 14, CutEdge = 3, Np = 1
+
+	{ 0,0,0 }, // Quart = 15, CutEdge = 0, Np = 0 UNUSED
+	{ 0,0,0 }, // Quart = 15, CutEdge = 0, Np = 1 UNUSED
+	{ 0,0,0 }, // Quart = 15, CutEdge = 1, Np = 0 UNUSED
+	{ 0,0,0 }, // Quart = 15, CutEdge = 1, Np = 1 UNUSED
+	{ 0,0,0 }, // Quart = 15, CutEdge = 2, Np = 0 UNUSED
+	{ 0,0,0 }, // Quart = 15, CutEdge = 2, Np = 1 UNUSED
+	{ 0,0,0 }, // Quart = 15, CutEdge = 3, Np = 0 UNUSED
+	{ 0,0,0 }  // Quart = 15, CutEdge = 3, Np = 1 UNUSED
+};
+
+void BuilderZoneRegion::updateTrans (sint32 x, sint32 y, NLLIGO::CZoneBankElement *zoneBankElement)
+{
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	if ((x < zoneRegion.getMinX()) || (x > zoneRegion.getMaxX()) ||
+			(y < zoneRegion.getMinY()) || (y > zoneRegion.getMaxY()))
+		return;
+
+	//if (!_Builder->getZoneMask(x,y))
+	//	return;
+
+	// Interpret the transition info
+	x -= zoneRegion.getMinX ();
+	y -= zoneRegion.getMinY ();
+	sint32 m;
+
+	// Calculate the number of material around with transition info
+	std::set<std::string> matNameSet;
+
+	ZonePosition zonePosTemp(x + zoneRegion.getMinX(), y + zoneRegion.getMinY(), m_regionId);
+	LigoData dataZoneTemp;
+	m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp);
+	LigoData dataZoneTempOriginal = dataZoneTemp;
+
+	for (m = 0; m < 4; ++m)
+		matNameSet.insert(dataZoneTemp.sharingMatNames[m]);
+
+	if (matNameSet.size() == 1)
+	{
+		if (dataZoneTemp.sharingMatNames[0] == STRING_UNUSED)
+		{
+			del(x + zoneRegion.getMinX (), y + zoneRegion.getMinY ());
+			// set (x+pBZR->getMinX (), y+pBZR->getMinY (), 0, 0, STRING_UNUSED, false);
+			return;
+		}
+		else
+		{
+			NLLIGO::CZoneBankElement *zoneBankElement2 = m_zoneBuilder->getZoneBank().getElementByZoneName(dataZoneTemp.zoneName);
+			if ((zoneBankElement != NULL) && (zoneBankElement2->getCategory("material") == dataZoneTemp.sharingMatNames[0]))
+				return;
+
+			NLLIGO::CZoneBank &zoneBank = m_zoneBuilder->getZoneBank();
+			zoneBank.resetSelection ();
+			zoneBank.addOrSwitch ("material", dataZoneTemp.sharingMatNames[0]);
+			zoneBank.addAndSwitch ("size", "1x1");
+			std::vector<NLLIGO::CZoneBankElement *> vElts;
+			zoneBank.getSelection (vElts);
+			if (vElts.size() == 0)
+				return;
+			sint32 nRan = (sint32)(NLMISC::frand((float)vElts.size()));
+			NLMISC::clamp (nRan, (sint32)0, (sint32)(vElts.size()-1));
+			zoneBankElement = vElts[nRan];
+			nRan = (uint32)(NLMISC::frand(1.0) * 4);
+			NLMISC::clamp (nRan, (sint32)0, (sint32)3);
+			uint8 rot = (uint8)nRan;
+			nRan = (uint32)(NLMISC::frand(1.0) * 2);
+			NLMISC::clamp (nRan, (sint32)0, (sint32)1);
+			uint8 flip = (uint8)nRan;
+
+			set(x + zoneRegion.getMinX(), y + zoneRegion.getMinY(), 0, 0, zoneBankElement->getName(), false);
+			setRot(x + zoneRegion.getMinX(), y + zoneRegion.getMinY(), rot);
+			setFlip(x + zoneRegion.getMinX(), y + zoneRegion.getMinY(), flip);
+			return;
+		}
+	}
+
+	// No 2 materials so the transition system dont work
+	if (matNameSet.size() != 2)
+		return;
+
+	std::set<std::string>::iterator it = matNameSet.begin();
+	std::string matA = *it;
+	++it;
+	std::string matB = *it;
+
+	NLLIGO::CZoneBank &zoneBank = m_zoneBuilder->getZoneBank();
+	zoneBank.resetSelection ();
+	zoneBank.addOrSwitch("transname", matA + "-" + matB);
+	std::vector<NLLIGO::CZoneBankElement *> selection;
+	zoneBank.getSelection(selection);
+	if (selection.size() == 0)
+	{
+		std::string matTmp = matA;
+		matA = matB;
+		matB = matTmp;
+		zoneBank.resetSelection ();
+		zoneBank.addOrSwitch ("transname", matA + "-" + matB);
+		zoneBank.getSelection (selection);
+	}
+
+	if (selection.size() == 0)
+		return;
+
+	// Convert the sharingCutEdges and SharingNames to the num and type of transition
+	uint8 nQuart = 0; // 0-MatA 1-MatB
+	for (m = 0; m < 4; ++m)
+		if (dataZoneTemp.sharingMatNames[m] == matB)
+			nQuart |= (1 << m);
+
+	if ((nQuart == 0) || (nQuart == 6) ||
+			(nQuart == 9) || (nQuart == 15))
+		return; // No transition for those types
+
+	uint8 nCutEdge = 0;
+	uint8 nPosCorner = 0;
+
+	// If up edge is cut write the cut position in nCutEdge bitfield (1->0, 2->1)
+	if ((nQuart == 4) || (nQuart == 5) ||
+			(nQuart == 7) || (nQuart == 8) ||
+			(nQuart == 10) || (nQuart == 11))
+	{
+		if (dataZoneTemp.sharingCutEdges[0] == 2)
+			nCutEdge |= 1 << nPosCorner;
+		++nPosCorner;
+	}
+	else
+	{
+		dataZoneTemp.sharingCutEdges[0] = 0;
+	}
+
+	// Same for down edge
+	if ((nQuart == 1) || (nQuart == 2) ||
+			(nQuart == 5) || (nQuart == 10) ||
+			(nQuart == 13) || (nQuart == 14))
+	{
+		if (dataZoneTemp.sharingCutEdges[1] == 2)
+			nCutEdge |= 1 << nPosCorner;
+		++nPosCorner;
+	}
+	else
+	{
+		dataZoneTemp.sharingCutEdges[1] = 0;
+	}
+
+	// Same for left edge
+	if ((nQuart == 1) || (nQuart == 3) ||
+			(nQuart == 4) ||(nQuart == 11) ||
+			(nQuart == 12) || (nQuart == 14))
+	{
+		if (dataZoneTemp.sharingCutEdges[2] == 2)
+			nCutEdge |= 1 << nPosCorner;
+		++nPosCorner;
+	}
+	else
+	{
+		dataZoneTemp.sharingCutEdges[2] = 0;
+	}
+
+	// Same for right edge
+	if ((nQuart == 2) || (nQuart == 3) ||
+			(nQuart == 7) || (nQuart == 8) ||
+			(nQuart == 12) || (nQuart == 13))
+	{
+		if (dataZoneTemp.sharingCutEdges[3] == 2)
+			nCutEdge |= 1 << nPosCorner;
+		++nPosCorner;
+	}
+	else
+	{
+		dataZoneTemp.sharingCutEdges[3] = 0;
+	}
+
+	nlassert (nPosCorner == 2); // If not this means that more than 2 edges are cut which is not possible
+
+	STrans Trans, TransTmp1, TransTmp2;
+
+	TransTmp1 = TranConvTable[nQuart * 8 + 2 * nCutEdge + 0];
+	TransTmp2 = TranConvTable[nQuart * 8 + 2 * nCutEdge + 1];
+
+	// Choose one or the two
+	sint32 nTrans = (sint32)(NLMISC::frand(2.0f));
+	NLMISC::clamp(nTrans, (sint32)0, (sint32)1);
+	if (nTrans == 0)
+		Trans = TransTmp1;
+	else
+		Trans = TransTmp2;
+
+	zoneBank.addAndSwitch ("transnum", NLMISC::toString(Trans.Num));
+	zoneBank.getSelection (selection);
+
+	if (selection.size() > 0)
+	{
+		if (zoneBankElement != NULL)
+		{
+			dataZoneTemp.zoneName = zoneBankElement->getName();
+		}
+		else
+		{
+			nTrans = (uint32)(NLMISC::frand (1.0) * selection.size());
+			NLMISC::clamp(nTrans, (sint32)0, (sint32)(selection.size() - 1));
+			dataZoneTemp.zoneName = selection[nTrans]->getName();
+		}
+		dataZoneTemp.posX = dataZoneTemp.posY = 0;
+		dataZoneTemp.rot = Trans.Rot;
+		dataZoneTemp.flip = Trans.Flip;
+	}
+
+	// Add modification landscape
+	if (dataZoneTempOriginal != dataZoneTemp)
+		m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp);
+}
+
+std::string BuilderZoneRegion::getNextMatInTree (const std::string &matA, const std::string &matB)
+{
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	uint32 i, posA = 10000, posB = 10000;
+
+	if (matA == matB)
+		return matA;
+
+	for (i = 0; i < m_matTree.size(); ++i)
+	{
+		if (m_matTree[i].Name == matA)
+			posA = i;
+		if (m_matTree[i].Name == matB)
+			posB = i;
+	}
+	if ((posA == 10000) || (posB == 10000))
+		return STRING_UNUSED;
+
+	std::vector<uint32> vTemp;
+	tryPath (posA, posB, vTemp);
+	if (vTemp.size() <= 1)
+		return STRING_UNUSED;
+	else
+		return m_matTree[vTemp[1]].Name;
+}
+
+struct SNode
+{
+	sint32 NodePos, Dist, PrevNodePos;
+
+	SNode()
+	{
+		NodePos = Dist = PrevNodePos = -1;
+	}
+};
+
+void BuilderZoneRegion::tryPath(uint32 posA, uint32 posB, std::vector<uint32> &path)
+{
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+
+	// Build the adjascence matrix
+	std::vector<sint32> matAdj;
+	sint32 numNodes = m_matTree.size();
+	sint32 i, j, cost;
+	matAdj.resize(numNodes * numNodes, -1);
+	for (i = 0; i < numNodes; ++i)
+		for (j = 0; j < (sint32)m_matTree[i].Arcs.size(); ++j)
+			matAdj[i + m_matTree[i].Arcs[j] * numNodes] = 1;
+
+	std::vector<SNode> vNodes; // NodesPos == index
+	vNodes.resize (numNodes);
+	for (i = 0; i < numNodes; ++i)
+		vNodes[i].NodePos = i;
+	vNodes[posA].Dist = 0;
+
+	std::queue<SNode> qNodes;
+	qNodes.push (vNodes[posA]);
+
+	while (qNodes.size() > 0)
+	{
+		SNode node = qNodes.front();
+		qNodes.pop ();
+
+		for (i = 0; i < numNodes; ++i)
+		{
+			cost = matAdj[node.NodePos + i * numNodes];
+			if (cost != -1)
+			{
+				if ((vNodes[i].Dist == -1) || (vNodes[i].Dist > (cost + node.Dist)))
+				{
+					vNodes[i].Dist = cost + node.Dist;
+					vNodes[i].PrevNodePos = node.NodePos;
+					qNodes.push(vNodes[i]);
+				}
+			}
+		}
+	}
+
+	// Get path length
+	i = posB;
+	j = 0;
+	while (i != -1)
+	{
+		++j;
+		i = vNodes[i].PrevNodePos;
+	}
+
+	// Write the path in the good order (from posA to posB)
+	path.resize(j);
+	i = posB;
+	while (i != -1)
+	{
+		--j;
+		path[j] = i;
+		i = vNodes[i].PrevNodePos;
+	}
+}
+
+void BuilderZoneRegion::del(sint32 x, sint32 y, bool transition, void *pInternal)
+{
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	if (!m_zoneBuilder->getZoneMask(x, y))
+		return;
+
+	const std::string &nameZone = zoneRegion.getName(x, y);
+
+	ToUpdate *pUpdate = reinterpret_cast<ToUpdate *>(pInternal);
+
+	NLLIGO::CZoneBankElement *zoneBankElement = m_zoneBuilder->getZoneBank().getElementByZoneName(nameZone);
+	if (zoneBankElement != NULL)
+	{
+		sint32 sizeX = zoneBankElement->getSizeX(), sizeY = zoneBankElement->getSizeY();
+		sint32 posX = zoneRegion.getPosX (x, y), posY = zoneRegion.getPosY (x, y);
+		uint8 rot = zoneRegion.getRot (x, y);
+		uint8 flip = zoneRegion.getFlip (x, y);
+		sint32 i, j;
+		sint32 deltaX, deltaY;
+
+		if (flip == 0)
+		{
+			switch (rot)
+			{
+			case 0:
+				deltaX = -posX;
+				deltaY = -posY;
+				break;
+			case 1:
+				deltaX = -(sizeY - 1 - posY);
+				deltaY = -posX;
+				break;
+			case 2:
+				deltaX = -(sizeX - 1 - posX);
+				deltaY = -(sizeY - 1 - posY);
+				break;
+			case 3:
+				deltaX = -posY;
+				deltaY = -(sizeX - 1 - posX);
+				break;
+			}
+		}
+		else
+		{
+			switch (rot)
+			{
+			case 0:
+				deltaX = -(sizeX - 1 - posX);
+				deltaY = -posY;
+				break;
+			case 1:
+				deltaX = -(sizeY - 1 - posY);
+				deltaY = -(sizeX - 1 - posX);
+				break;
+			case 2:
+				deltaX = -posX;
+				deltaY = -(sizeY - 1 - posY);
+				break;
+			case 3:
+				deltaX = -posY;
+				deltaY = -posX;
+				break;
+			}
+		}
+
+		NLLIGO::SPiece mask;
+		mask.Tab.resize (sizeX * sizeY);
+		for(i = 0; i < sizeX * sizeY; ++i)
+			mask.Tab[i] = zoneBankElement->getMask()[i];
+		mask.w = sizeX;
+		mask.h = sizeY;
+		mask.rotFlip (rot, flip);
+
+		for (j = 0; j < mask.h; ++j)
+			for (i = 0; i < mask.w; ++i)
+				if (mask.Tab[i + j * mask.w])
+				{
+					set(x + deltaX + i, y + deltaY + j, 0, 0, STRING_UNUSED, true);
+					setRot(x + deltaX + i, y + deltaY + j, 0);
+					setFlip(x + deltaX + i, y + deltaY + j, 0);
+					if (pUpdate != NULL)
+					{
+						pUpdate->add(this, x + deltaX + i, y + deltaY + j, "");
+					}
+				}
+		if (!transition)
+			reduceMin ();
+	}
+	else
+	{
+		if ((x < zoneRegion.getMinX()) || (x > zoneRegion.getMaxX()) ||
+				(y < zoneRegion.getMinY()) || (y > zoneRegion.getMaxY()))
+			return;
+
+		ZonePosition zonePosTemp(x, y, m_regionId);
+		LigoData dataZoneTemp;
+		m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp);
+		LigoData dataZoneTempOriginal = dataZoneTemp;
+
+		dataZoneTemp.zoneName = STRING_UNUSED;
+		dataZoneTemp.posX = 0;
+		dataZoneTemp.posY = 0;
+
+		for (uint32 i = 0; i < 4; ++i)
+		{
+			dataZoneTemp.sharingMatNames[i] = STRING_UNUSED;
+			dataZoneTemp.sharingCutEdges[i] = 0;
+		}
+
+		// Add modification landscape
+		if (dataZoneTempOriginal != dataZoneTemp)
+			m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp);
+
+	}
+}
+
+void BuilderZoneRegion::move (sint32 x, sint32 y)
+{
+	m_zoneBuilder->actionLigoMove(m_regionId, x, y);
+}
+
+uint32 BuilderZoneRegion::countZones ()
+{
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	sint32 x, y;
+
+	uint32 counter = 0;
+
+	for (y = zoneRegion.getMinY (); y <= zoneRegion.getMaxY (); ++y)
+		for (x = zoneRegion.getMinX (); x <= zoneRegion.getMaxX (); ++x)
+			if (zoneRegion.getName (x, y) != STRING_UNUSED)
+				++counter;
+
+	return counter;
+}
+
+void BuilderZoneRegion::set(sint32 x, sint32 y, sint32 posX, sint32 posY,
+							const std::string &zoneName, bool transition)
+{
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+
+	// Do we need to resize ?
+	if ((x < zoneRegion.getMinX()) || (x > zoneRegion.getMaxX()) ||
+			(y < zoneRegion.getMinY()) || (y > zoneRegion.getMaxY()))
+	{
+		sint32 newMinX = (x < zoneRegion.getMinX() ? x: zoneRegion.getMinX()), newMinY = (y < zoneRegion.getMinY() ? y: zoneRegion.getMinY());
+		sint32 newMaxX = (x > zoneRegion.getMaxX() ? x: zoneRegion.getMaxX()), newMaxY = (y > zoneRegion.getMaxY() ? y: zoneRegion.getMaxY());
+
+		resize(newMinX, newMaxX, newMinY, newMaxY);
+	}
+
+	ZonePosition zonePosTemp(x, y, m_regionId);
+	LigoData dataZoneTemp;
+	m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp);
+	LigoData dataZoneTempOriginal = dataZoneTemp;
+
+	dataZoneTemp.zoneName = zoneName;
+	dataZoneTemp.posX = (uint8)posX;
+	dataZoneTemp.posY = (uint8)posY;
+
+	if (!transition)
+	{
+		NLLIGO::CZoneBankElement *zoneBankElem = m_zoneBuilder->getZoneBank().getElementByZoneName(zoneName);
+		if (zoneBankElem == NULL)
+			return;
+
+		const std::string &matName = zoneBankElem->getCategory ("material");
+		if (matName == STRING_NO_CAT_TYPE)
+			return;
+		for (uint32 i = 0; i < 4; ++i)
+		{
+			dataZoneTemp.sharingMatNames[i] = matName;
+			dataZoneTemp.sharingCutEdges[i] = 0;
+		}
+
+		// Add modification landscape
+		if (dataZoneTempOriginal != dataZoneTemp)
+			m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp);
+
+		BuilderZoneRegion *builderZoneRegion = this;
+		ZonePosition zonePosU;
+		if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion, x - 1, y - 1))
+		{
+			LigoData data;
+			m_zoneBuilder->ligoData(data, zonePosU);
+			if (data.sharingMatNames[3] != matName)
+			{
+				data.sharingMatNames[3] = matName;
+
+				// Add modification landscape
+				m_zoneBuilder->actionLigoTile(data, zonePosU);
+			}
+		}
+		builderZoneRegion = this;
+		if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion, x, y - 1))
+		{
+			LigoData data;
+			m_zoneBuilder->ligoData(data, zonePosU);
+			if ((data.sharingMatNames[2] != matName) || (data.sharingMatNames[3] != matName))
+			{
+				data.sharingMatNames[2] = matName;
+				data.sharingMatNames[3] = matName;
+
+				// Add modification landscape
+				m_zoneBuilder->actionLigoTile(data, zonePosU);
+			}
+		}
+		builderZoneRegion = this;
+		if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion, x + 1, y - 1))
+		{
+			LigoData data;
+			m_zoneBuilder->ligoData(data, zonePosU);
+			if (data.sharingMatNames[2] != matName)
+			{
+				data.sharingMatNames[2] = matName;
+
+				// Add modification landscape
+				m_zoneBuilder->actionLigoTile(data, zonePosU);
+			}
+		}
+		builderZoneRegion = this;
+		if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion, x - 1, y))
+		{
+			LigoData data;
+			m_zoneBuilder->ligoData(data, zonePosU);
+			if ((data.sharingMatNames[1] != matName) || (data.sharingMatNames[3] != matName))
+			{
+				data.sharingMatNames[1] = matName;
+				data.sharingMatNames[3] = matName;
+
+				// Add modification landscape
+				m_zoneBuilder->actionLigoTile(data, zonePosU);
+			}
+		}
+		builderZoneRegion = this;
+		if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion, x + 1, y))
+		{
+			LigoData data;
+			m_zoneBuilder->ligoData(data, zonePosU);
+			if ((data.sharingMatNames[0] != matName) || (data.sharingMatNames[2] != matName))
+			{
+				data.sharingMatNames[0] = matName;
+				data.sharingMatNames[2] = matName;
+
+				// Add modification landscape
+				m_zoneBuilder->actionLigoTile(data, zonePosU);
+			}
+		}
+		builderZoneRegion = this;
+		if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion, x - 1, y + 1))
+		{
+			LigoData data;
+			m_zoneBuilder->ligoData(data, zonePosU);
+			if (data.sharingMatNames[1] != matName)
+			{
+				data.sharingMatNames[1] = matName;
+
+				// Add modification landscape
+				m_zoneBuilder->actionLigoTile(data, zonePosU);
+			}
+		}
+		builderZoneRegion = this;
+		if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion, x, y + 1))
+		{
+			LigoData data;
+			m_zoneBuilder->ligoData(data, zonePosU);
+			if ((data.sharingMatNames[0] != matName) || (data.sharingMatNames[1] != matName))
+			{
+				data.sharingMatNames[0] = matName;
+				data.sharingMatNames[1] = matName;
+
+				// Add modification landscape
+				m_zoneBuilder->actionLigoTile(data, zonePosU);
+			}
+		}
+		builderZoneRegion = this;
+		if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion, x + 1, y + 1))
+		{
+			LigoData data;
+			m_zoneBuilder->ligoData(data, zonePosU);
+			if (data.sharingMatNames[0] != matName)
+			{
+				data.sharingMatNames[0] = matName;
+
+				// Add modification landscape
+				m_zoneBuilder->actionLigoTile(data, zonePosU);
+			}
+		}
+	}
+	else
+	{
+		// Add modification landscape
+		if (dataZoneTempOriginal != dataZoneTemp)
+			m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp);
+	}
+}
+
+void BuilderZoneRegion::setRot (sint32 x, sint32 y, uint8 rot)
+{
+	ZonePosition zonePosTemp(x, y, m_regionId);
+	LigoData dataZoneTemp;
+	m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp);
+	if (dataZoneTemp.rot != rot)
+	{
+		dataZoneTemp.rot = rot;
+
+		// Add modification landscape
+		m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp);
+	}
+}
+
+void BuilderZoneRegion::setFlip(sint32 x, sint32 y, uint8 flip)
+{
+	ZonePosition zonePosTemp(x, y, m_regionId);
+	LigoData dataZoneTemp;
+	m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp);
+	if (dataZoneTemp.flip != flip)
+	{
+		dataZoneTemp.flip = flip;
+
+		// Add modification landscape
+		m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp);
+	}
+}
+
+
+void BuilderZoneRegion::reduceMin ()
+{
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	sint32 i, j;
+
+	sint32 newMinX = zoneRegion.getMinX(), newMinY = zoneRegion.getMinY ();
+	sint32 newMaxX = zoneRegion.getMaxX(), newMaxY = zoneRegion.getMaxY ();
+	bool bCanSuppr;
+
+	// Reduce the MinY
+	while (true)
+	{
+		if (newMinY == newMaxY)
+			break;
+		j = newMinY;
+		bCanSuppr = true;
+		for (i = newMinX; i <= newMaxX; ++i)
+		{
+			std::string str = zoneRegion.getName (i, j) ;
+			if (!str.empty() && (str != STRING_UNUSED))
+			{
+				bCanSuppr = false;
+				break;
+			}
+		}
+		if (bCanSuppr)
+			++newMinY;
+		else
+			break;
+	}
+
+	// Reduce the MaxY
+	while (true)
+	{
+		if (newMinY == newMaxY)
+			break;
+		j = newMaxY;
+		bCanSuppr = true;
+		for (i = newMinX; i <= newMaxX; ++i)
+		{
+			std::string str = zoneRegion.getName (i, j) ;
+			if (!str.empty() && (str != STRING_UNUSED))
+			{
+				bCanSuppr = false;
+				break;
+			}
+		}
+		if (bCanSuppr)
+			--newMaxY;
+		else
+			break;
+	}
+
+	// Reduce the MinX
+	while (true)
+	{
+		if (newMinX == newMaxX)
+			break;
+		i = newMinX;
+		bCanSuppr = true;
+		for (j = newMinY; j <= newMaxY; ++j)
+		{
+			std::string str = zoneRegion.getName (i, j) ;
+			if (!str.empty() && (str != STRING_UNUSED))
+			{
+				bCanSuppr = false;
+				break;
+			}
+		}
+		if (bCanSuppr)
+			++newMinX;
+		else
+			break;
+	}
+
+	// Reduce the MaxX
+	while (true)
+	{
+		if (newMinX == newMaxX)
+			break;
+		i = newMaxX;
+		bCanSuppr = true;
+		for (j = newMinY; j <= newMaxY; ++j)
+		{
+			std::string str = zoneRegion.getName (i, j) ;
+			if (!str.empty() && (str != STRING_UNUSED))
+			{
+				bCanSuppr = false;
+				break;
+			}
+		}
+		if (bCanSuppr)
+			--newMaxX;
+		else
+			break;
+	}
+
+	if ((newMinX != zoneRegion.getMinX ()) ||
+			(newMinY != zoneRegion.getMinY ()) ||
+			(newMaxX != zoneRegion.getMaxX ()) ||
+			(newMaxY != zoneRegion.getMaxY ()))
+	{
+		resize(newMinX, newMaxX, newMinY, newMaxY);
+	}
+}
+
+uint BuilderZoneRegion::getRegionId() const
+{
+	return m_regionId;
+}
+
+void BuilderZoneRegion::resize (sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY)
+{
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	if ((zoneRegion.getMinX ()!= newMinX) ||
+			(zoneRegion.getMaxX ()!= newMaxX) ||
+			(zoneRegion.getMinY ()!= newMinY) ||
+			(zoneRegion.getMaxY ()!= newMaxY))
+	{
+		m_zoneBuilder->actionLigoResize(m_regionId, newMinX, newMaxX, newMinY, newMaxY);
+	}
+}
+
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h
index 158c72715..7322e47b6 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h
@@ -1,33 +1,101 @@
-// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
-// Copyright (C) 2010  Winch Gate Property Limited
-// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-#ifndef BUILDER_ZONE_REGION_H
-#define BUILDER_ZONE_REGION_H
-
-// Project includes
-
-// NeL includes
-#include <nel/ligo/zone_bank.h>
-
-// Qt includes
-
-namespace LandscapeEditor
-{
-
-} /* namespace LandscapeEditor */
-
-#endif // BUILDER_ZONE_REGION_H
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef BUILDER_ZONE_REGION_H
+#define BUILDER_ZONE_REGION_H
+
+// Project includes
+
+// NeL includes
+#include <nel/ligo/zone_bank.h>
+#include <nel/ligo/zone_region.h>
+
+// STL includes
+#include <string>
+#include <vector>
+#include <queue>
+
+// Qt includes
+
+namespace LandscapeEditor
+{
+class ZoneBuilder;
+
+// CZoneRegion contains informations about the zones painted
+class BuilderZoneRegion
+{
+public:
+
+	BuilderZoneRegion(uint regionId);
+
+	// New interface
+	bool init(ZoneBuilder *zoneBuilder, std::string &error);
+	void add(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
+	void invertCutEdge(sint32 x, sint32 y, uint8 cePos);
+	void cycleTransition(sint32 x, sint32 y);
+	bool addNotPropagate(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
+
+	/// Brutal adding a zone over empty space do not propagate in any way -> can result
+	/// in inconsistency when trying the propagation mode
+	void addForce (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
+	void del(sint32 x, sint32 y, bool transition = false, void *pInternal = NULL);
+	void move(sint32 x, sint32 y);
+	uint32 countZones();
+	void reduceMin();
+	uint getRegionId() const;
+
+private:
+
+	// An element of the graph
+	struct SMatNode
+	{
+		std::string			Name;
+		// Position in the tree (vector of nodes)
+		std::vector<uint32>	Arcs;
+	};
+
+	void addTransition(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
+
+	void addToUpdateAndCreate(BuilderZoneRegion* builderZoneRegion, sint32 sharePos, sint32 x, sint32 y, const std::string &newMat, void *pInt1, void *pInt2);
+
+	void putTransitions(sint32 x, sint32 y, const NLLIGO::SPiece &mask, const std::string &matName, void *pInternal);
+	void updateTrans(sint32 x, sint32 y, NLLIGO::CZoneBankElement *zoneBankElement = NULL);
+
+	std::string getNextMatInTree(const std::string &matA, const std::string &matB);
+
+	/// Find the fastest way between posA and posB in the MatTree (Dijkstra)
+	void tryPath(uint32 posA, uint32 posB, std::vector<uint32> &path);
+
+	void set(sint32 x, sint32 y, sint32 posX, sint32 posY, const std::string &zoneName, bool transition=false);
+	void setRot(sint32 x, sint32 y, uint8 rot);
+	void setFlip(sint32 x, sint32 y, uint8 flip);
+	void resize(sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY);
+
+	uint m_regionId;
+
+	// To use the global mask
+	ZoneBuilder *m_zoneBuilder;
+
+	// The tree of transition between materials
+	std::vector<SMatNode> m_matTree;
+
+	bool m_firstInit;
+};
+
+} /* namespace LandscapeEditor */
+
+#endif // BUILDER_ZONE_REGION_H
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
index 84d59ba8d..95f030631 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
@@ -62,54 +62,111 @@ void NewLandscapeCommand::redo()
 {
 }
 
-AddLigoTileCommand::AddLigoTileCommand(const LigoData &data, LandscapeScene *scene, QUndoCommand *parent)
+LigoTileCommand::LigoTileCommand(const LigoData &data, const ZonePosition &zonePos,
+								 ZoneBuilder *zoneBuilder, LandscapeScene *scene,
+								 QUndoCommand *parent)
 	: QUndoCommand(parent),
-	  m_item(0),
+	  m_zoneBuilder(zoneBuilder),
 	  m_scene(scene)
 {
-	m_ligoData = data;
+	// Backup position
+	m_zonePos = zonePos;
+
+	// Backup new data
+	m_newLigoData = data;
+
+	// Backup old data
+	m_zoneBuilder->ligoData(m_oldLigoData, m_zonePos);
 }
 
-AddLigoTileCommand::~AddLigoTileCommand()
+LigoTileCommand::~LigoTileCommand()
 {
 }
 
-void AddLigoTileCommand::undo()
+void LigoTileCommand::undo ()
 {
-	m_scene->removeItem(m_item);
-	delete m_item;
-	m_item = 0;
+	m_zoneBuilder->setLigoData(m_oldLigoData, m_zonePos);
+	m_scene->createZoneItem(m_oldLigoData, m_zonePos);
 }
 
-void AddLigoTileCommand::redo()
+void LigoTileCommand::redo ()
 {
-	m_item = m_scene->createZoneItem(m_ligoData);
-	setText(QObject::tr("Add tile(%1, %2)").arg(m_ligoData.PosX).arg(m_ligoData.PosY));
+	m_zoneBuilder->setLigoData(m_newLigoData, m_zonePos);
+	m_scene->createZoneItem(m_newLigoData, m_zonePos);
 }
 
-DelLigoTileCommand::DelLigoTileCommand(const LigoData &data, LandscapeScene *scene, QUndoCommand *parent)
+LigoResizeCommand::LigoResizeCommand(int index, sint32 newMinX, sint32 newMaxX,
+									 sint32 newMinY, sint32 newMaxY, ZoneBuilder *zoneBuilder,
+									 QUndoCommand *parent)
 	: QUndoCommand(parent),
-	  m_item(0),
-	  m_scene(scene)
+	  m_zoneBuilder(zoneBuilder)
 {
-	m_ligoData = data;
+	m_index = index;
+	m_newMinX = newMinX;
+	m_newMaxX = newMaxX;
+	m_newMinY = newMinY;
+	m_newMaxY = newMaxY;
+
+	// Backup old region zone
+	m_oldZoneRegion = m_zoneBuilder->zoneRegion(m_index)->zoneRegion();
 }
 
-DelLigoTileCommand::~DelLigoTileCommand()
+LigoResizeCommand::~LigoResizeCommand()
 {
 }
 
-void DelLigoTileCommand::undo()
+void LigoResizeCommand::undo ()
 {
-	m_item = m_scene->createZoneItem(m_ligoData);
+	// Restore old region zone
+	m_zoneBuilder->zoneRegion(m_index)->setZoneRegion(m_oldZoneRegion);
 }
 
-void DelLigoTileCommand::redo()
+void LigoResizeCommand::redo ()
 {
-	m_item = m_scene->itemAt(m_ligoData.PosX * m_scene->cellSize(), m_ligoData.PosY * m_scene->cellSize());
-	delete m_item;
-	m_item = 0;
-	setText(QObject::tr("Del tile(%1, %2)").arg(m_ligoData.PosX).arg(m_ligoData.PosY));
+	// Get the zone region
+	NLLIGO::CZoneRegion &region = m_zoneBuilder->zoneRegion(m_index)->zoneRegion();
+
+	sint32 i, j;
+	std::vector<LigoData> newZones;
+	newZones.resize((1 + m_newMaxX - m_newMinX) * (1 + m_newMaxY - m_newMinY));
+
+	sint32 newStride = 1 + m_newMaxX - m_newMinX;
+	sint32 Stride = 1 + region.getMaxX() - region.getMinX();
+
+	for (j = m_newMinY; j <= m_newMaxY; ++j)
+		for (i = m_newMinX; i <= m_newMaxX; ++i)
+		{
+			// Ref on the new value
+			LigoData &data = newZones[(i - m_newMinX) + (j - m_newMinY) * newStride];
+
+			// In the old array ?
+			if ((i >= region.getMinX()) && (i <= region.getMaxX()) &&
+					(j >= region.getMinY()) && (j <= region.getMaxY()))
+			{
+				// Backup values
+				m_zoneBuilder->ligoData(data, ZonePosition(i, j, m_index));
+			}
+		}
+	region.resize(m_newMinX, m_newMaxX, m_newMinY, m_newMaxY);
+
+	for (j = m_newMinY; j <= m_newMaxY; ++j)
+		for (i = m_newMinX; i <= m_newMaxX; ++i)
+		{
+			// Ref on the new value
+			const LigoData &data = newZones[(i - m_newMinX) + (j - m_newMinY) * newStride];
+
+			region.setName(i, j, data.zoneName);
+			region.setPosX(i, j, data.posX);
+			region.setPosY(i, j, data.posY);
+			region.setRot(i, j, data.rot);
+			region.setFlip(i, j, data.flip);
+			uint k;
+			for (k = 0; k < 4; k++)
+			{
+				region.setSharingMatNames(i, j, k, data.sharingMatNames[k]);
+				region.setSharingCutEdges(i, j, k, data.sharingCutEdges[k]);
+			}
+		}
 }
 
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
index 7bbd1bd96..e7a39d8b1 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
@@ -56,36 +56,64 @@ public:
 private:
 };
 
-class AddLigoTileCommand: public QUndoCommand
+// Modify the landscape
+class LigoTileCommand: public QUndoCommand
 {
 public:
-	AddLigoTileCommand(const LigoData &data, LandscapeScene *scene, QUndoCommand *parent = 0);
-	virtual ~AddLigoTileCommand();
+	LigoTileCommand(const LigoData &data, const ZonePosition &zonePos,
+					ZoneBuilder *zoneBuilder, LandscapeScene *scene,
+					QUndoCommand *parent = 0);
+	virtual ~LigoTileCommand();
 
 	virtual void undo();
 	virtual void redo();
 
 private:
-
-	LigoData m_ligoData;
-	QGraphicsItem *m_item;
+	ZonePosition m_zonePos;
+	LigoData m_newLigoData;
+	LigoData m_oldLigoData;
+	ZoneBuilder *m_zoneBuilder;
 	LandscapeScene *m_scene;
 };
-
-class DelLigoTileCommand: public QUndoCommand
+/*
+// Move the landscape
+class LigoMoveCommand: public QUndoCommand
 {
 public:
-	DelLigoTileCommand(const LigoData &data, LandscapeScene *scene, QUndoCommand *parent = 0);
-	virtual ~DelLigoTileCommand();
+
+	LigoMoveCommand(int index, sint32 deltaX, sint32 deltaY, ZoneBuilder *zoneBuilder, QUndoCommand *parent = 0);
+	virtual ~LigoMoveCommand();
+
+	virtual void undo();
+	virtual void redo();
+private:
+
+	int m_index;
+	sint32 m_deltaX;
+	sint32 m_deltaY;
+	ZoneBuilder *m_zoneBuilder;
+};
+*/
+// Modify the landscape
+class LigoResizeCommand: public QUndoCommand
+{
+public:
+	LigoResizeCommand(int index, sint32 newMinX, sint32 newMaxX,
+					  sint32 newMinY, sint32 newMaxY, ZoneBuilder *zoneBuilder,
+					  QUndoCommand *parent = 0);
+	virtual ~LigoResizeCommand();
 
 	virtual void undo();
 	virtual void redo();
 
 private:
-
-	LigoData m_ligoData;
-	QGraphicsItem *m_item;
-	LandscapeScene *m_scene;
+	int m_index;
+	sint32 m_newMinX;
+	sint32 m_newMaxX;
+	sint32 m_newMinY;
+	sint32 m_newMaxY;
+	NLLIGO::CZoneRegion m_oldZoneRegion;
+	ZoneBuilder *m_zoneBuilder;
 };
 
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
index 5ec3f6196..0c38adbf6 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
@@ -19,6 +19,7 @@
 #include "landscape_editor_window.h"
 #include "landscape_editor_constants.h"
 #include "builder_zone.h"
+#include "zone_region_editor.h"
 #include "landscape_scene.h"
 #include "project_settings_dialog.h"
 #include "snapshot_dialog.h"
@@ -45,12 +46,14 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
 	m_ui.setupUi(this);
 
 	m_undoStack = new QUndoStack(this);
-	m_zoneBuilder = new ZoneBuilder();
-	m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", false);
+	m_landscapeScene = new LandscapeScene(this);
+
+	m_zoneBuilder = new ZoneBuilder(m_ui.zoneListWidget, m_landscapeScene, m_undoStack);
+	m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", true);
 	m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder);
 	m_ui.zoneListWidget->updateUi();
 
-	m_landscapeScene = new LandscapeScene(m_undoStack, m_ui.zoneListWidget, m_zoneBuilder, this);
+	m_landscapeScene->setZoneBuilder(m_zoneBuilder);
 	m_ui.graphicsView->setScene(m_landscapeScene);
 	//m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer)));
 	m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers)));
@@ -88,11 +91,14 @@ void LandscapeEditorWindow::open()
 		_lastDir = QFileInfo(list.front()).absolutePath();
 		Q_FOREACH(QString fileName, fileNames)
 		{
-			m_zoneRegionEditor.load(fileName.toStdString());
-			m_landscapeScene->processZoneRegion(m_zoneRegionEditor.zoneRegion());
-			m_landscapeScene->setCurrentZoneRegion(&m_zoneRegionEditor.zoneRegion());
-			m_ui.graphicsView->centerOn(m_zoneRegionEditor.zoneRegion().getMinX() * m_landscapeScene->cellSize(),
-										abs(m_zoneRegionEditor.zoneRegion().getMinY()) * m_landscapeScene->cellSize());
+			int id = m_zoneBuilder->createZoneRegion();
+			ZoneRegionEditor *zoneRegion = m_zoneBuilder->zoneRegion(id);
+			zoneRegion->load(fileName.toStdString());
+			m_landscapeScene->processZoneRegion(zoneRegion->zoneRegion());
+			m_ui.graphicsView->centerOn(zoneRegion->zoneRegion().getMinX() * m_landscapeScene->cellSize(),
+										abs(zoneRegion->zoneRegion().getMinY()) * m_landscapeScene->cellSize());
+
+			m_zoneBuilder->setCurrentZoneRegion(id);
 		}
 	}
 	setCursor(Qt::ArrowCursor);
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
index 311a65013..3a35b90f4 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
@@ -20,7 +20,6 @@
 
 // Project includes
 #include "ui_landscape_editor_window.h"
-#include "zone_region_editor.h"
 
 // Qt includes
 #include <QtGui/QUndoStack>
@@ -55,8 +54,6 @@ private:
 	void readSettings();
 	void writeSettings();
 
-	ZoneRegionEditor m_zoneRegionEditor;
-
 	LandscapeScene *m_landscapeScene;
 	ZoneBuilder *m_zoneBuilder;
 	QUndoStack *m_undoStack;
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
index 96ad0879b..3aa2bbc9a 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
@@ -17,9 +17,6 @@
 
 // Project includes
 #include "landscape_scene.h"
-#include "builder_zone.h"
-#include "landscape_actions.h"
-#include "list_zones_widget.h"
 
 // NeL includes
 #include <nel/misc/debug.h>
@@ -32,12 +29,9 @@
 namespace LandscapeEditor
 {
 
-LandscapeScene::LandscapeScene(QUndoStack *undoStack, ListZonesWidget *listZonesWidget, ZoneBuilder *zoneBuilder, QObject *parent)
+LandscapeScene::LandscapeScene(QObject *parent)
 	: QGraphicsScene(parent),
-	  m_undoStack(undoStack),
-	  m_listZonesWidget(listZonesWidget),
-	  m_zoneBuilder(zoneBuilder),
-	  m_zoneRegion(0)
+	  m_zoneBuilder(0)
 {
 	m_cellSize = 160;
 }
@@ -51,20 +45,34 @@ int LandscapeScene::cellSize() const
 	return m_cellSize;
 }
 
-QGraphicsItem *LandscapeScene::createZoneItem(const LigoData &data)
+void LandscapeScene::setZoneBuilder(ZoneBuilder *zoneBuilder)
 {
+	m_zoneBuilder = zoneBuilder;
+}
+
+QGraphicsItem *LandscapeScene::createZoneItem(const LigoData &data, const ZonePosition &zonePos)
+{
+	if (data.zoneName == STRING_UNUSED)
+		return createEmptyZoneItem(zonePos);
+
+	if ((m_zoneBuilder == 0) || (data.zoneName.empty()) ||
+			(data.posX != 0) || (data.posY != 0))
+		return 0;
+
+	checkUnderZone(data, zonePos);
+
 	// Get image from pixmap database
-	QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(data.ZoneName.c_str()));
+	QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(data.zoneName.c_str()));
 	if (pixmap == 0)
 		return 0;
 
 	// Rotate the image counterclockwise
 	QMatrix matrix;
-	matrix.rotate(-data.Rot * 90.0);
+	matrix.rotate(-data.rot * 90.0);
 
 	QGraphicsPixmapItem *item;
 
-	if (data.Flip == 0)
+	if (data.flip == 0)
 	{
 		item = new QGraphicsPixmapItem(pixmap->transformed(matrix, Qt::SmoothTransformation), 0, this);
 	}
@@ -79,135 +87,156 @@ QGraphicsItem *LandscapeScene::createZoneItem(const LigoData &data)
 	item->setTransformationMode(Qt::SmoothTransformation);
 
 	// Set position graphics item with offset for large piece
-	NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.ZoneName);
-	item->setPos(data.PosX * m_cellSize, (abs(data.PosY) - zoneBankItem->getSizeY() + 1) * m_cellSize);
+	NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.zoneName);
+	item->setPos(zonePos.x * m_cellSize, (abs(zonePos.y) - zoneBankItem->getSizeY() + 1) * m_cellSize);
 
 	// The size graphics item should be equal or proportional m_cellSize
-	item->setScale(m_cellSize / 256.0);
-
-	// add debug info
-	QGraphicsSimpleTextItem *itemText = addSimpleText(QString("%1,%2 R-%3 F-%4").
-										arg(data.PosX).arg(data.PosY).
-										arg(data.Rot * 90.0).
-										arg(data.Flip),
-										QFont("Helvetica [Cronyx]", 14));
-
-	itemText->setZValue(2);
-	itemText->setPos(data.PosX * m_cellSize + 10, (abs(data.PosY) - zoneBankItem->getSizeY() + 1) * m_cellSize + 10);
-	itemText->setBrush(QBrush(Qt::white));
+	item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize());
 
 	return item;
 }
 
+QGraphicsItem *LandscapeScene::createEmptyZoneItem(const ZonePosition &zonePos)
+{
+	if (m_zoneBuilder == 0)
+		return 0;
+
+	deleteZoneItem(zonePos);
+
+	// Get image from pixmap database
+	QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(STRING_UNUSED));
+	if (pixmap == 0)
+		return 0;
+
+	QGraphicsPixmapItem *item = new QGraphicsPixmapItem(*pixmap, 0, this);
+
+	// Enable bilinear filtering
+	item->setTransformationMode(Qt::SmoothTransformation);
+
+	// Set position graphics item
+	item->setPos(zonePos.x * m_cellSize, abs(int(zonePos.y)) * m_cellSize);
+
+	// The size graphics item should be equal or proportional m_cellSize
+	item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize());
+
+	return item;
+}
+
+void LandscapeScene::deleteZoneItem(const ZonePosition &zonePos)
+{
+	QGraphicsItem *item = itemAt(zonePos.x * m_cellSize, abs(zonePos.y) * m_cellSize);
+	if (item != 0)
+	{
+		removeItem(item);
+		delete item;
+	}
+}
+
 void LandscapeScene::processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
 {
 	for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i)
 	{
 		for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
 		{
+			nlinfo(QString("%1 %2 %3").arg(i).arg(j).arg(zoneRegion.getName(i, j).c_str()).toStdString().c_str());
 			std::string zoneName = zoneRegion.getName(i, j);
-			if ((!zoneName.empty()) &&
-					(zoneName != STRING_UNUSED) &&
-					(zoneRegion.getPosX(i, j) == 0) &&
-					(zoneRegion.getPosY(i, j) == 0))
+			if (zoneName == STRING_UNUSED)
+			{
+				ZonePosition zonePos(i, j, -1);
+				QGraphicsItem *item = createEmptyZoneItem(zonePos);
+			}
+			else if (!zoneName.empty())
 			{
 				LigoData data;
-				data.PosX = i;
-				data.PosY = j;
-				data.ZoneName = zoneName;
-				data.Rot = zoneRegion.getRot(i, j);
-				data.Flip = zoneRegion.getFlip(i, j);
-				QGraphicsItem *item = createZoneItem(data);
+				ZonePosition zonePos(i, j, -1);
+				data.zoneName = zoneName;
+				data.rot = zoneRegion.getRot(i, j);
+				data.flip = zoneRegion.getFlip(i, j);
+				data.posX = zoneRegion.getPosX(i, j);
+				data.posY = zoneRegion.getPosY(i, j);
+				QGraphicsItem *item = createZoneItem(data, zonePos);
 			}
 		}
 	}
 }
 
-void LandscapeScene::setCurrentZoneRegion(NLLIGO::CZoneRegion *zoneRegion)
-{
-	m_zoneRegion = zoneRegion;
-}
-
 void LandscapeScene::snapshot(const QString &fileName, int sizeSource)
 {
-	if (m_zoneRegion == 0)
-		return;
+	/*	if (m_zoneRegion == 0)
+			return;
 
-	sint32 regionMinX = m_zoneRegion->getMinX();
-	sint32 regionMaxX = m_zoneRegion->getMaxX();
-	sint32 regionMinY = m_zoneRegion->getMinY();
-	sint32 regionMaxY = m_zoneRegion->getMaxY();
+		sint32 regionMinX = m_zoneRegion->getMinX();
+		sint32 regionMaxX = m_zoneRegion->getMaxX();
+		sint32 regionMinY = m_zoneRegion->getMinY();
+		sint32 regionMaxY = m_zoneRegion->getMaxY();
 
-	int regionWidth = (regionMaxX - regionMinX + 1);
-	int regionHeight = (regionMaxY - regionMinY + 1);
+		int regionWidth = (regionMaxX - regionMinX + 1);
+		int regionHeight = (regionMaxY - regionMinY + 1);
 
-	snapshot(fileName, regionWidth * sizeSource, regionHeight * sizeSource);
+		snapshot(fileName, regionWidth * sizeSource, regionHeight * sizeSource);
+		*/
 }
 
 void LandscapeScene::snapshot(const QString &fileName, int width, int height)
 {
-	if (m_zoneRegion == 0)
+	if (m_zoneBuilder == 0)
 		return;
 
-	sint32 regionMinX = m_zoneRegion->getMinX();
-	sint32 regionMaxX = m_zoneRegion->getMaxX();
-	sint32 regionMinY = m_zoneRegion->getMinY();
-	sint32 regionMaxY = m_zoneRegion->getMaxY();
+	/*	if (m_zoneRegion == 0)
+			return;
 
-	int regionWidth = (regionMaxX - regionMinX + 1);
-	int regionHeight = (regionMaxY - regionMinY + 1);
+		sint32 regionMinX = m_zoneRegion->getMinX();
+		sint32 regionMaxX = m_zoneRegion->getMaxX();
+		sint32 regionMinY = m_zoneRegion->getMinY();
+		sint32 regionMaxY = m_zoneRegion->getMaxY();
 
-	QImage image(width, height, QImage::Format_RGB888);
-	QPainter painter(&image);
-	painter.setRenderHint(QPainter::Antialiasing, true);
+		int regionWidth = (regionMaxX - regionMinX + 1);
+		int regionHeight = (regionMaxY - regionMinY + 1);
 
-	// add white background
-	painter.setBrush(QBrush(Qt::white));
-	painter.setPen(Qt::NoPen);
-	painter.drawRect(0, 0, width, height);
+		QImage image(width, height, QImage::Format_RGB888);
+		QPainter painter(&image);
+		painter.setRenderHint(QPainter::Antialiasing, true);
 
-	render(&painter, QRectF(0, 0, width, height),
-		   QRectF(regionMinX * m_cellSize, abs(regionMaxY) * m_cellSize, regionWidth * m_cellSize, regionHeight * m_cellSize));
+		// add white background
+		painter.setBrush(QBrush(Qt::white));
+		painter.setPen(Qt::NoPen);
+		painter.drawRect(0, 0, width, height);
 
-	image.save(fileName);
+		render(&painter, QRectF(0, 0, width, height),
+			   QRectF(regionMinX * m_cellSize, abs(regionMaxY) * m_cellSize, regionWidth * m_cellSize, regionHeight * m_cellSize));
 
+		image.save(fileName);
+	*/
 }
 
 void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
 {
+	if (m_zoneBuilder == 0)
+		return;
+
 	qreal x = mouseEvent->scenePos().rx();
 	qreal y = mouseEvent->scenePos().ry();
 	if ((x < 0) || (y < 0))
 		return;
 
+	sint32 posX = sint32(floor(x / m_cellSize));
+	sint32 posY = sint32(-floor(y / m_cellSize));
+
 	if (mouseEvent->button() == Qt::LeftButton)
-	{
-		// Add new zone brick
-		LigoData ligoData = m_listZonesWidget->currentLigoData();
-		if (ligoData.ZoneName == "")
-			return;
+		m_zoneBuilder->addZone(posX, posY);
+	else if (mouseEvent->button() == Qt::RightButton)
+		m_zoneBuilder->delZone(posX, posY);
 
-		ligoData.PosX = int(floor(x / m_cellSize));
-		ligoData.PosY = int(-floor(y / m_cellSize));
-
-		AddLigoTileCommand *action = new AddLigoTileCommand(ligoData, this);
-		m_undoStack->push(action);
-	}
-
-	/*if (mouseEvent->button() == Qt::RightButton)
-	{
-		// Delete zone brick
-		LigoData ligoData;
-
-		ligoData.PosX = int(floor(x / m_cellSize));
-		ligoData.PosY = int(floor(y / m_cellSize));
-		ligoData.ZoneName = m_zoneRegion->getName(ligoData.PosX, -ligoData.PosY);
-		ligoData.Flip = m_zoneRegion->getFlip(ligoData.PosX, -ligoData.PosY);
-		ligoData.Rot = m_zoneRegion->getRot(ligoData.PosX, -ligoData.PosY);
-		DelLigoTileCommand *action = new DelLigoTileCommand(ligoData, this);
-		m_undoStack->push(action);
-	}*/
 	QGraphicsScene::mousePressEvent(mouseEvent);
 }
 
+void LandscapeScene::checkUnderZone(const LigoData &data, const ZonePosition &zonePos)
+{
+//	NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.zoneName);
+//	uint8 sizeX = zoneBankItem->getSizeX();
+//	uint8 sizeY = zoneBankItem->getSizeY();
+//	std::vector<bool> &mask = zoneBankItem->getMask();
+	deleteZoneItem(zonePos);
+}
+
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
index 2af45bf4b..ea314faac 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
@@ -19,6 +19,8 @@
 #define LANDSCAPE_SCENE_H
 
 // Project includes
+#include "zone_region_editor.h"
+#include "builder_zone.h"
 
 // NeL includes
 #include <nel/ligo/zone_region.h>
@@ -26,54 +28,25 @@
 // Qt includes
 #include <QtGui/QGraphicsScene>
 #include <QtGui/QGraphicsSceneMouseEvent>
-#include <QtGui/QUndoStack>
 
 namespace LandscapeEditor
 {
-class ZoneBuilder;
-class ListZonesWidget;
-
-// Data
-struct LigoData
-{
-	sint32			PosX;
-	sint32			PosY;
-	uint8			Rot;
-	uint8			Flip;
-	std::string		ZoneName;
-	std::string		SharingMatNames[4];
-	uint8			SharingCutEdges[4];
-	bool operator!= (const LigoData& other) const
-	{
-		return (PosX != other.PosX) ||
-			   (PosY != other.PosY) ||
-			   (Rot != other.Rot) ||
-			   (Flip != other.Flip) ||
-			   (ZoneName != other.ZoneName) ||
-			   (SharingMatNames[0] != other.SharingMatNames[0]) ||
-			   (SharingMatNames[1] != other.SharingMatNames[1]) ||
-			   (SharingMatNames[2] != other.SharingMatNames[2]) ||
-			   (SharingMatNames[3] != other.SharingMatNames[3]) ||
-			   (SharingCutEdges[0] != other.SharingCutEdges[0]) ||
-			   (SharingCutEdges[1] != other.SharingCutEdges[1]) ||
-			   (SharingCutEdges[2] != other.SharingCutEdges[2]) ||
-			   (SharingCutEdges[3] != other.SharingCutEdges[3]);
-	}
-};
 
 class LandscapeScene : public QGraphicsScene
 {
 	Q_OBJECT
 
 public:
-	LandscapeScene(QUndoStack *undoStack, ListZonesWidget *listZonesWidget, ZoneBuilder *zoneBuilder, QObject *parent = 0);
+	LandscapeScene(QObject *parent = 0);
 	virtual ~LandscapeScene();
 
 	int cellSize() const;
+	void setZoneBuilder(ZoneBuilder *zoneBuilder);
 
-	QGraphicsItem *createZoneItem(const LigoData &data);
+	QGraphicsItem *createZoneItem(const LigoData &data, const ZonePosition &zonePos);
+	QGraphicsItem *createEmptyZoneItem(const ZonePosition &zonePos);
+	void deleteZoneItem(const ZonePosition &zonePos);
 	void processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
-	void setCurrentZoneRegion(NLLIGO::CZoneRegion *zoneRegion);
 
 	void snapshot(const QString &fileName, int sizeSource);
 	void snapshot(const QString &fileName, int width, int height);
@@ -82,12 +55,10 @@ protected:
 	virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
 
 private:
+	void checkUnderZone(const LigoData &data, const ZonePosition &zonePos);
 
 	int m_cellSize;
-	ListZonesWidget *m_listZonesWidget;
-	QUndoStack *m_undoStack;
 	ZoneBuilder *m_zoneBuilder;
-	NLLIGO::CZoneRegion *m_zoneRegion;
 };
 
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
index 66d31479b..7ce3f5421 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
@@ -18,6 +18,7 @@
 // Project includes
 #include "list_zones_widget.h"
 #include "list_zones_model.h"
+#include "builder_zone.h"
 
 // NeL includes
 #include <nel/misc/debug.h>
@@ -100,17 +101,34 @@ void ListZonesWidget::updateUi()
 	m_listZonesModel->rebuildModel(m_zoneBuilder->pixmapDatabase());
 }
 
-LigoData ListZonesWidget::currentLigoData() const
+QString ListZonesWidget::currentZoneName() const
 {
-	LigoData ligoData;
-	ligoData.ZoneName = "";
+	QString zoneName = "";
 	QModelIndex index = m_ui.listView->currentIndex();
 	if (index.isValid())
-		ligoData.ZoneName = index.data().toString().toStdString();
+		zoneName = index.data().toString();
 
-	ligoData.Rot = m_ui.rotComboBox->currentIndex();
-	ligoData.Flip = m_ui.flipComboBox->currentIndex();
-	return ligoData;
+	return zoneName;
+}
+
+int ListZonesWidget::currentRot() const
+{
+	return m_ui.rotComboBox->currentIndex();
+}
+
+int ListZonesWidget::currentFlip() const
+{
+	return m_ui.flipComboBox->currentIndex();
+}
+
+bool ListZonesWidget::isNotPropogate() const
+{
+	return m_ui.propogateCheckBox->isChecked();
+}
+
+bool ListZonesWidget::isForce() const
+{
+	return m_ui.forceCheckBox->isChecked();
 }
 
 void ListZonesWidget::setZoneBuilder(ZoneBuilder *zoneBuilder)
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
index 8ad5d4c25..c35e7b0fa 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
@@ -20,8 +20,6 @@
 
 // Project includes
 #include "ui_list_zones_widget.h"
-#include "builder_zone.h"
-#include "landscape_scene.h"
 
 // NeL includes
 
@@ -30,6 +28,7 @@
 namespace LandscapeEditor
 {
 class ListZonesModel;
+class ZoneBuilder;
 
 /**
 @class ZoneListWidget
@@ -46,7 +45,11 @@ public:
 
 	void updateUi();
 	void setZoneBuilder(ZoneBuilder *zoneBuilder);
-	LigoData currentLigoData() const;
+	QString currentZoneName() const;
+	int currentRot() const;
+	int currentFlip() const;
+	bool isNotPropogate() const;
+	bool isForce() const;
 
 Q_SIGNALS:
 private Q_SLOTS:
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp
index a3f109ada..045b342fd 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp
@@ -30,6 +30,23 @@
 namespace LandscapeEditor
 {
 
+LigoData::LigoData()
+{
+	posX = 0;
+	posY = 0;
+	zoneName = "";
+	rot = 0;
+	flip = 0;
+	sharingMatNames[0] = "";
+	sharingMatNames[1] = "";
+	sharingMatNames[2] = "";
+	sharingMatNames[3] = "";
+	sharingCutEdges[0] = 0;
+	sharingCutEdges[1] = 0;
+	sharingCutEdges[2] = 0;
+	sharingCutEdges[3] = 0;
+}
+
 ZoneRegionEditor::ZoneRegionEditor()
 {
 	m_fileName = "";
@@ -111,9 +128,58 @@ void ZoneRegionEditor::setFileName(const std::string &fileName)
 	m_fileName = fileName;
 }
 
+void ZoneRegionEditor::ligoData(LigoData &data, const sint32 x, const sint32 y)
+{
+	nlassert((x >= m_zoneRegion.getMinX()) &&
+			 (x <= m_zoneRegion.getMaxX()) &&
+			 (y >= m_zoneRegion.getMinY()) &&
+			 (y <= m_zoneRegion.getMaxY()));
+
+	data.posX = m_zoneRegion.getPosX(x, y);
+	data.posY = m_zoneRegion.getPosY(x, y);
+	data.zoneName = m_zoneRegion.getName(x, y);
+	data.rot = m_zoneRegion.getRot(x, y);
+	data.flip = m_zoneRegion.getFlip(x, y);
+	data.sharingMatNames[0] = m_zoneRegion.getSharingMatNames(x, y, 0);
+	data.sharingMatNames[1] = m_zoneRegion.getSharingMatNames(x, y, 1);
+	data.sharingMatNames[2] = m_zoneRegion.getSharingMatNames(x, y, 2);
+	data.sharingMatNames[3] = m_zoneRegion.getSharingMatNames(x, y, 3);
+	data.sharingCutEdges[0] = m_zoneRegion.getSharingCutEdges(x, y, 0);
+	data.sharingCutEdges[1] = m_zoneRegion.getSharingCutEdges(x, y, 1);
+	data.sharingCutEdges[2] = m_zoneRegion.getSharingCutEdges(x, y, 2);
+	data.sharingCutEdges[3] = m_zoneRegion.getSharingCutEdges(x, y, 3);
+}
+
+void ZoneRegionEditor::setLigoData(const LigoData &data, const sint32 x, const sint32 y)
+{
+	nlassert((x >= m_zoneRegion.getMinX()) &&
+			 (x <= m_zoneRegion.getMaxX()) &&
+			 (y >= m_zoneRegion.getMinY()) &&
+			 (y <= m_zoneRegion.getMaxY()));
+
+	m_zoneRegion.setPosX(x, y, data.posX);
+	m_zoneRegion.setPosY(x, y, data.posY);
+	m_zoneRegion.setName(x, y, data.zoneName);
+	m_zoneRegion.setRot(x, y, data.rot);
+	m_zoneRegion.setFlip(x, y, data.flip);
+	m_zoneRegion.setSharingMatNames(x, y, 0, data.sharingMatNames[0]);
+	m_zoneRegion.setSharingMatNames(x, y, 1, data.sharingMatNames[1]);
+	m_zoneRegion.setSharingMatNames(x, y, 2, data.sharingMatNames[2]);
+	m_zoneRegion.setSharingMatNames(x, y, 3, data.sharingMatNames[3]);
+	m_zoneRegion.setSharingCutEdges(x, y, 0, data.sharingCutEdges[0]);
+	m_zoneRegion.setSharingCutEdges(x, y, 1, data.sharingCutEdges[1]);
+	m_zoneRegion.setSharingCutEdges(x, y, 2, data.sharingCutEdges[2]);
+	m_zoneRegion.setSharingCutEdges(x, y, 3, data.sharingCutEdges[3]);
+}
+
 NLLIGO::CZoneRegion &ZoneRegionEditor::zoneRegion()
 {
 	return m_zoneRegion;
 }
 
+void ZoneRegionEditor::setZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
+{
+	m_zoneRegion = zoneRegion;
+}
+
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h
index fd53d5483..50fab0e58 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h
@@ -32,6 +32,36 @@
 namespace LandscapeEditor
 {
 
+struct LigoData
+{
+	uint8			posX;
+	uint8			posY;
+	uint8			rot;
+	uint8			flip;
+	std::string		zoneName;
+	std::string		sharingMatNames[4];
+	uint8			sharingCutEdges[4];
+
+	LigoData();
+
+	bool operator!= (const LigoData& other) const
+	{
+		return (posX != other.posX) ||
+			   (posY != other.posY) ||
+			   (rot != other.rot) ||
+			   (flip != other.flip) ||
+			   (zoneName != other.zoneName) ||
+			   (sharingMatNames[0] != other.sharingMatNames[0]) ||
+			   (sharingMatNames[1] != other.sharingMatNames[1]) ||
+			   (sharingMatNames[2] != other.sharingMatNames[2]) ||
+			   (sharingMatNames[3] != other.sharingMatNames[3]) ||
+			   (sharingCutEdges[0] != other.sharingCutEdges[0]) ||
+			   (sharingCutEdges[1] != other.sharingCutEdges[1]) ||
+			   (sharingCutEdges[2] != other.sharingCutEdges[2]) ||
+			   (sharingCutEdges[3] != other.sharingCutEdges[3]);
+	}
+};
+
 class ZoneRegionEditor
 {
 public:
@@ -44,11 +74,17 @@ public:
 	// Save landscape data to file
 	bool save();
 
+	void ligoData(LigoData &data, const sint32 x, const sint32 y);
+
+	void setLigoData(const LigoData &data, const sint32 x, const sint32 y);
+
 	// Set file name
 	void setFileName(const std::string &fileName);
 
 	NLLIGO::CZoneRegion &zoneRegion();
 
+	void setZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
+
 private:
 
 	bool m_modified;

From c647a72abb218c67c09d0218309acb927eaa599b Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Thu, 30 Jun 2011 00:25:43 +0300
Subject: [PATCH 09/19] Changed: #1301 Improved 2d render. Fixed adding empty
 undo/redo operations in command list, improved performance when adding new
 zones.

---
 .../plugins/landscape_editor/builder_zone.cpp | 50 ++++++++++--
 .../plugins/landscape_editor/builder_zone.h   | 15 +++-
 .../landscape_editor/landscape_actions.cpp    | 70 +++++++++++++++-
 .../landscape_editor/landscape_actions.h      | 35 ++++++++
 .../landscape_editor_window.cpp               | 17 +++-
 .../landscape_editor_window.h                 |  1 +
 .../landscape_editor_window.ui                |  6 ++
 .../landscape_editor/landscape_scene.cpp      | 79 +++++++++++++++----
 .../landscape_editor/landscape_scene.h        | 11 ++-
 .../landscape_editor/landscape_view.cpp       |  2 +
 .../landscape_editor/zone_region_editor.cpp   | 70 +++++++++++-----
 .../landscape_editor/zone_region_editor.h     | 27 ++-----
 12 files changed, 310 insertions(+), 73 deletions(-)

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
index 8271fe37c..0e00d72be 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
@@ -167,18 +167,22 @@ bool ZoneBuilder::init(const QString &pathName, bool makeAZone)
 
 void ZoneBuilder::actionLigoTile(const LigoData &data, const ZonePosition &zonePos)
 {
+	checkBeginMacro();
 	nlinfo(QString("%1 %2 %3 (%4 %5)").arg(data.zoneName.c_str()).arg(zonePos.x).arg(zonePos.y).arg(data.posX).arg(data.posY).toStdString().c_str());
+	m_zonePositionList.push_back(zonePos);
 	m_undoStack->push(new LigoTileCommand(data, zonePos, this, m_landscapeScene));
 }
 
 void ZoneBuilder::actionLigoMove(uint index, sint32 deltaX, sint32 deltaY)
 {
+	checkBeginMacro();
 	nlinfo("ligoMove");
 	//m_undoStack->push(new LigoMoveCommand(index, deltaX, deltaY, this));
 }
 
 void ZoneBuilder::actionLigoResize(uint index, sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY)
 {
+	checkBeginMacro();
 	nlinfo(QString("minX=%1 maxX=%2 minY=%3 maxY=%4").arg(newMinX).arg(newMaxX).arg(newMinY).arg(newMaxY).toStdString().c_str());
 	m_undoStack->push(new LigoResizeCommand(index, newMinX, newMaxX, newMinY, newMaxY, this));
 }
@@ -201,7 +205,11 @@ void ZoneBuilder::addZone(sint32 posX, sint32 posY)
 
 	NLLIGO::CZoneBankElement *zoneBankElement = getZoneBank().getElementByZoneName(zoneName);
 
-	m_undoStack->beginMacro(QString("Add zone %1,%2").arg(posX).arg(posY));
+	m_titleAction = QString("Add zone %1,%2").arg(posX).arg(posY);
+	m_createdAction = false;
+	m_zonePositionList.clear();
+
+	nlinfo("---------");
 	if (m_listZonesWidget->isForce())
 	{
 		builderZoneRegion->addForce(posX, posY, rot, flip, zoneBankElement);
@@ -213,7 +221,7 @@ void ZoneBuilder::addZone(sint32 posX, sint32 posY)
 		else
 			builderZoneRegion->add(posX, posY, rot, flip, zoneBankElement);
 	}
-	m_undoStack->endMacro();
+	checkEndMacro();
 }
 
 void ZoneBuilder::addTransition(const sint32 posX, const sint32 posY)
@@ -225,17 +233,20 @@ void ZoneBuilder::delZone(const sint32 posX, const sint32 posY)
 	if (m_builderZoneRegions.empty())
 		return;
 
-	m_undoStack->beginMacro(QString("Del zone %1,%2").arg(posX).arg(posY));
+	m_titleAction = QString("Del zone %1,%2").arg(posX).arg(posY);
+	m_createdAction = false;
+
 	BuilderZoneRegion *builderZoneRegion = m_builderZoneRegions.at(m_currentZoneRegion);
 	std::string error;
+	nlinfo("---------");
 	builderZoneRegion->init(this, error);
 	builderZoneRegion->del(posX, posY);
-	m_undoStack->endMacro();
+	checkEndMacro();
 }
 
 int ZoneBuilder::createZoneRegion()
 {
-	ZoneRegionEditor *newZoneRegion = new ZoneRegionEditor();
+	ZoneRegionObject *newZoneRegion = new ZoneRegionObject();
 	m_zoneRegions.push_back(newZoneRegion);
 	if (m_currentZoneRegion == -1)
 		m_currentZoneRegion = m_zoneRegions.indexOf(newZoneRegion);
@@ -261,7 +272,7 @@ int ZoneBuilder::currentIdZoneRegion() const
 	return m_currentZoneRegion;
 }
 
-ZoneRegionEditor *ZoneBuilder::currentZoneRegion() const
+ZoneRegionObject *ZoneBuilder::currentZoneRegion() const
 {
 	return m_zoneRegions.at(m_currentZoneRegion);
 }
@@ -271,7 +282,7 @@ int ZoneBuilder::countZoneRegion() const
 	return m_zoneRegions.size();
 }
 
-ZoneRegionEditor *ZoneBuilder::zoneRegion(int id) const
+ZoneRegionObject *ZoneBuilder::zoneRegion(int id) const
 {
 	return m_zoneRegions.at(id);
 }
@@ -399,7 +410,7 @@ void ZoneBuilder::calcMask()
 
 bool ZoneBuilder::getZoneAmongRegions (ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y)
 {
-	Q_FOREACH(ZoneRegionEditor *zoneRegion, m_zoneRegions)
+	Q_FOREACH(ZoneRegionObject *zoneRegion, m_zoneRegions)
 	{
 		const NLLIGO::CZoneRegion &region = zoneRegion->zoneRegion();
 		if ((x < region.getMinX()) || (x > region.getMaxX()) ||
@@ -424,4 +435,27 @@ bool ZoneBuilder::getZoneAmongRegions (ZonePosition &zonePos, BuilderZoneRegion
 	return true;
 }
 
+void ZoneBuilder::checkBeginMacro()
+{
+	if (!m_createdAction)
+	{
+		m_createdAction = true;
+		m_undoStack->beginMacro(m_titleAction);
+		m_undoScanRegionCommand = new UndoScanRegionCommand(this, m_landscapeScene);
+		m_undoStack->push(m_undoScanRegionCommand);
+	}
+}
+
+void ZoneBuilder::checkEndMacro()
+{
+	if (m_createdAction)
+	{
+		RedoScanRegionCommand *redoScanRegionCommand = new RedoScanRegionCommand(this, m_landscapeScene);
+		m_undoScanRegionCommand->setScanList(m_zonePositionList);
+		redoScanRegionCommand->setScanList(m_zonePositionList);
+		m_undoStack->push(redoScanRegionCommand);
+		m_undoStack->endMacro();
+	}
+}
+
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
index 54cdb3b73..ecc47976f 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
@@ -42,6 +42,7 @@ namespace LandscapeEditor
 {
 class ListZonesWidget;
 class LandscapeScene;
+class UndoScanRegionCommand;
 
 // Data
 struct ZonePosition
@@ -134,9 +135,9 @@ public:
 	void deleteZoneRegion(int id);
 	void setCurrentZoneRegion(int id);
 	int currentIdZoneRegion() const;
-	ZoneRegionEditor *currentZoneRegion() const;
+	ZoneRegionObject *currentZoneRegion() const;
 	int countZoneRegion() const;
-	ZoneRegionEditor *zoneRegion(int id) const;
+	ZoneRegionObject *zoneRegion(int id) const;
 	void ligoData(LigoData &data, const ZonePosition &zonePos);
 	void setLigoData(LigoData &data, const ZonePosition &zonePos);
 
@@ -155,16 +156,24 @@ private:
 	/// Scan ./zoneligos dir and add all *.ligozone files to zoneBank
 	bool initZoneBank (const QString &path);
 
+	void checkBeginMacro();
+	void checkEndMacro();
+
 	sint32 m_minX, m_maxX, m_minY, m_maxY;
 	std::vector<bool> m_zoneMask;
 
 	QString m_lastPathName;
 
-	QList<ZoneRegionEditor *> m_zoneRegions;
+	QList<ZoneRegionObject *> m_zoneRegions;
 	int m_currentZoneRegion;
 
 	std::vector<BuilderZoneRegion *> m_builderZoneRegions;
 
+	bool m_createdAction;
+	QString m_titleAction;
+	QList<ZonePosition> m_zonePositionList;
+	UndoScanRegionCommand *m_undoScanRegionCommand;
+
 	PixmapDatabase *m_pixmapDatabase;
 	NLLIGO::CZoneBank m_zoneBank;
 	ListZonesWidget *m_listZonesWidget;
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
index 95f030631..8aea79933 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
@@ -86,13 +86,79 @@ LigoTileCommand::~LigoTileCommand()
 void LigoTileCommand::undo ()
 {
 	m_zoneBuilder->setLigoData(m_oldLigoData, m_zonePos);
-	m_scene->createZoneItem(m_oldLigoData, m_zonePos);
 }
 
 void LigoTileCommand::redo ()
 {
 	m_zoneBuilder->setLigoData(m_newLigoData, m_zonePos);
-	m_scene->createZoneItem(m_newLigoData, m_zonePos);
+}
+
+UndoScanRegionCommand::UndoScanRegionCommand(ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent)
+	: QUndoCommand(parent),
+	  m_zoneBuilder(zoneBuilder),
+	  m_scene(scene)
+{
+}
+
+UndoScanRegionCommand::~UndoScanRegionCommand()
+{
+	m_zonePositionList.clear();
+}
+
+void UndoScanRegionCommand::setScanList(const QList<ZonePosition> &zonePositionList)
+{
+	m_zonePositionList = zonePositionList;
+}
+
+void UndoScanRegionCommand::undo()
+{
+	for (int i = 0; i < m_zonePositionList.size(); ++i)
+		m_scene->deleteItemZone(m_zonePositionList.at(i));
+	nlinfo("------");
+	for (int i = 0; i < m_zonePositionList.size(); ++i)
+	{
+		LigoData data;
+		m_zoneBuilder->ligoData(data, m_zonePositionList.at(i));
+		m_scene->createItemZone(data, m_zonePositionList.at(i));
+	}
+}
+
+void UndoScanRegionCommand::redo()
+{
+}
+
+RedoScanRegionCommand::RedoScanRegionCommand(ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent)
+	: QUndoCommand(parent),
+	  m_zoneBuilder(zoneBuilder),
+	  m_scene(scene)
+{
+}
+
+RedoScanRegionCommand::~RedoScanRegionCommand()
+{
+	m_zonePositionList.clear();
+}
+
+void RedoScanRegionCommand::setScanList(const QList<ZonePosition> &zonePositionList)
+{
+	m_zonePositionList = zonePositionList;
+}
+
+void RedoScanRegionCommand::undo()
+{
+}
+
+void RedoScanRegionCommand::redo()
+{
+	for (int i = 0; i < m_zonePositionList.size(); ++i)
+		m_scene->deleteItemZone(m_zonePositionList.at(i));
+	nlinfo("------");
+	for (int i = 0; i < m_zonePositionList.size(); ++i)
+	{
+		LigoData data;
+		m_zoneBuilder->ligoData(data, m_zonePositionList.at(i));
+		m_scene->createItemZone(data, m_zonePositionList.at(i));
+	}
 }
 
 LigoResizeCommand::LigoResizeCommand(int index, sint32 newMinX, sint32 newMaxX,
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
index e7a39d8b1..c4afcc801 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h
@@ -75,6 +75,41 @@ private:
 	ZoneBuilder *m_zoneBuilder;
 	LandscapeScene *m_scene;
 };
+
+class UndoScanRegionCommand: public QUndoCommand
+{
+public:
+	UndoScanRegionCommand(ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent = 0);
+	virtual ~UndoScanRegionCommand();
+
+	void setScanList(const QList<ZonePosition> &zonePositionList);
+	virtual void undo();
+	virtual void redo();
+
+private:
+
+	QList<ZonePosition> m_zonePositionList;
+	ZoneBuilder *m_zoneBuilder;
+	LandscapeScene *m_scene;
+};
+
+class RedoScanRegionCommand: public QUndoCommand
+{
+public:
+	RedoScanRegionCommand(ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent = 0);
+	virtual ~RedoScanRegionCommand();
+
+	void setScanList(const QList<ZonePosition> &zonePositionList);
+	virtual void undo();
+	virtual void redo();
+
+private:
+
+	QList<ZonePosition> m_zonePositionList;
+	ZoneBuilder *m_zoneBuilder;
+	LandscapeScene *m_scene;
+};
+
 /*
 // Move the landscape
 class LigoMoveCommand: public QUndoCommand
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
index 0c38adbf6..facf90264 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
@@ -62,6 +62,7 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
 	createToolBars();
 	readSettings();
 
+	connect(m_ui.saveAction, SIGNAL(triggered()), this, SLOT(save()));
 	connect(m_ui.projectSettingsAction, SIGNAL(triggered()), this, SLOT(openProjectSettings()));
 	connect(m_ui.snapshotAction, SIGNAL(triggered()), this, SLOT(openSnapshotDialog()));
 	connect(m_ui.enableGridAction, SIGNAL(toggled(bool)), m_ui.graphicsView, SLOT(setVisibleGrid(bool)));
@@ -92,7 +93,7 @@ void LandscapeEditorWindow::open()
 		Q_FOREACH(QString fileName, fileNames)
 		{
 			int id = m_zoneBuilder->createZoneRegion();
-			ZoneRegionEditor *zoneRegion = m_zoneBuilder->zoneRegion(id);
+			ZoneRegionObject *zoneRegion = m_zoneBuilder->zoneRegion(id);
 			zoneRegion->load(fileName.toStdString());
 			m_landscapeScene->processZoneRegion(zoneRegion->zoneRegion());
 			m_ui.graphicsView->centerOn(zoneRegion->zoneRegion().getMinX() * m_landscapeScene->cellSize(),
@@ -104,6 +105,20 @@ void LandscapeEditorWindow::open()
 	setCursor(Qt::ArrowCursor);
 }
 
+void LandscapeEditorWindow::save()
+{
+	ZoneRegionObject *zoneRegion = m_zoneBuilder->currentZoneRegion();
+	if (zoneRegion->fileName().empty())
+	{
+		QString fileName = QFileDialog::getSaveFileName(this,
+						   tr("Save NeL Ligo land file"), _lastDir,
+						   tr("NeL Ligo land file (*.land)"));
+		if (!fileName.isEmpty())
+			zoneRegion->setFileName(fileName.toStdString());
+	}
+	zoneRegion->save();
+}
+
 void LandscapeEditorWindow::openProjectSettings()
 {
 	ProjectSettingsDialog *dialog = new ProjectSettingsDialog(m_zoneBuilder->dataPath(), this);
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
index 3a35b90f4..ccfcf2778 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
@@ -43,6 +43,7 @@ public:
 Q_SIGNALS:
 public Q_SLOTS:
 	void open();
+	void save();
 
 private Q_SLOTS:
 	void openProjectSettings();
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
index 212d0eb13..57eadda73 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
@@ -72,6 +72,7 @@
    <attribute name="toolBarBreak">
     <bool>false</bool>
    </attribute>
+   <addaction name="saveAction"/>
    <addaction name="snapshotAction"/>
    <addaction name="projectSettingsAction"/>
    <addaction name="enableGridAction"/>
@@ -107,6 +108,11 @@
     <string>snapshot</string>
    </property>
   </action>
+  <action name="saveAction">
+   <property name="text">
+    <string>Save</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
index 3aa2bbc9a..9970032a7 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
@@ -29,8 +29,12 @@
 namespace LandscapeEditor
 {
 
+static const int ZoneName = 0;
+
 LandscapeScene::LandscapeScene(QObject *parent)
 	: QGraphicsScene(parent),
+	  m_mouseX(0.0),
+	  m_mouseY(0.0),
 	  m_zoneBuilder(0)
 {
 	m_cellSize = 160;
@@ -50,16 +54,21 @@ void LandscapeScene::setZoneBuilder(ZoneBuilder *zoneBuilder)
 	m_zoneBuilder = zoneBuilder;
 }
 
-QGraphicsItem *LandscapeScene::createZoneItem(const LigoData &data, const ZonePosition &zonePos)
+QGraphicsItem *LandscapeScene::createItemZone(const LigoData &data, const ZonePosition &zonePos)
 {
+	nlinfo(QString("%1,%2 (%3,%4)-%7 (%5,%6)").arg(zonePos.x).arg(zonePos.y).arg(data.posX).arg(data.posY).arg(data.rot).arg(data.flip).arg(data.zoneName.c_str()).toStdString().c_str());
+	if ((data.zoneName == STRING_OUT_OF_BOUND) || (checkUnderZone(zonePos.x, zonePos.y)))
+		return 0;
+
 	if (data.zoneName == STRING_UNUSED)
-		return createEmptyZoneItem(zonePos);
+		return createItemEmptyZone(zonePos);
 
 	if ((m_zoneBuilder == 0) || (data.zoneName.empty()) ||
 			(data.posX != 0) || (data.posY != 0))
 		return 0;
 
-	checkUnderZone(data, zonePos);
+//	if ((m_zoneBuilder == 0) || (data.zoneName.empty()))
+//		return 0;
 
 	// Get image from pixmap database
 	QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(data.zoneName.c_str()));
@@ -88,21 +97,27 @@ QGraphicsItem *LandscapeScene::createZoneItem(const LigoData &data, const ZonePo
 
 	// Set position graphics item with offset for large piece
 	NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.zoneName);
-	item->setPos(zonePos.x * m_cellSize, (abs(zonePos.y) - zoneBankItem->getSizeY() + 1) * m_cellSize);
+
+	int delta = zoneBankItem->getSizeY() - 1;
+	if ((data.rot == 1) || (data.rot == 3))
+		delta = zoneBankItem->getSizeX() - 1;
+
+	//item->setPos((zonePos.x - data.posX) * m_cellSize, (abs(int(zonePos.y)) + data.posY - delta) * m_cellSize);
+	item->setPos((zonePos.x) * m_cellSize, (abs(int(zonePos.y)) - delta) * m_cellSize);
 
 	// The size graphics item should be equal or proportional m_cellSize
 	item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize());
 
+	item->setData(ZoneName, QString(data.zoneName.c_str()));
+	nlinfo("render");
 	return item;
 }
 
-QGraphicsItem *LandscapeScene::createEmptyZoneItem(const ZonePosition &zonePos)
+QGraphicsItem *LandscapeScene::createItemEmptyZone(const ZonePosition &zonePos)
 {
 	if (m_zoneBuilder == 0)
 		return 0;
 
-	deleteZoneItem(zonePos);
-
 	// Get image from pixmap database
 	QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(STRING_UNUSED));
 	if (pixmap == 0)
@@ -118,11 +133,11 @@ QGraphicsItem *LandscapeScene::createEmptyZoneItem(const ZonePosition &zonePos)
 
 	// The size graphics item should be equal or proportional m_cellSize
 	item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize());
-
+	nlinfo("render");
 	return item;
 }
 
-void LandscapeScene::deleteZoneItem(const ZonePosition &zonePos)
+void LandscapeScene::deleteItemZone(const ZonePosition &zonePos)
 {
 	QGraphicsItem *item = itemAt(zonePos.x * m_cellSize, abs(zonePos.y) * m_cellSize);
 	if (item != 0)
@@ -143,7 +158,7 @@ void LandscapeScene::processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
 			if (zoneName == STRING_UNUSED)
 			{
 				ZonePosition zonePos(i, j, -1);
-				QGraphicsItem *item = createEmptyZoneItem(zonePos);
+				QGraphicsItem *item = createItemEmptyZone(zonePos);
 			}
 			else if (!zoneName.empty())
 			{
@@ -154,7 +169,7 @@ void LandscapeScene::processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
 				data.flip = zoneRegion.getFlip(i, j);
 				data.posX = zoneRegion.getPosX(i, j);
 				data.posY = zoneRegion.getPosY(i, j);
-				QGraphicsItem *item = createZoneItem(data, zonePos);
+				QGraphicsItem *item = createItemZone(data, zonePos);
 			}
 		}
 	}
@@ -230,13 +245,43 @@ void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
 	QGraphicsScene::mousePressEvent(mouseEvent);
 }
 
-void LandscapeScene::checkUnderZone(const LigoData &data, const ZonePosition &zonePos)
+void LandscapeScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent)
 {
-//	NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.zoneName);
-//	uint8 sizeX = zoneBankItem->getSizeX();
-//	uint8 sizeY = zoneBankItem->getSizeY();
-//	std::vector<bool> &mask = zoneBankItem->getMask();
-	deleteZoneItem(zonePos);
+	m_mouseX = mouseEvent->scenePos().x();
+	m_mouseY = mouseEvent->scenePos().y();
+	QGraphicsScene::mouseMoveEvent(mouseEvent);
+}
+
+bool LandscapeScene::checkUnderZone(const int posX, const int posY)
+{
+	/*	QGraphicsItem *item = itemAt((posX * m_cellSize), abs(posY) * m_cellSize);
+		if (item != 0)
+		{
+			QString zoneName = item->data(ZoneName).toString();
+			return true;
+		}
+	*/	return false;
+}
+
+void LandscapeScene::drawForeground(QPainter *painter, const QRectF &rect)
+{
+	QGraphicsScene::drawForeground(painter, rect);
+	painter->setPen(QPen(Qt::white, 0.5, Qt::SolidLine));
+
+	int left = int(floor(rect.left() / m_cellSize));
+	int right = int(floor(rect.right() / m_cellSize));
+	int top = int(floor(rect.top() / m_cellSize));
+	int bottom = int(floor(rect.bottom() / m_cellSize));
+
+	for (int i = left; i < right; ++i)
+	{
+		for (int j = top; j < bottom; ++j)
+		{
+			LigoData data;
+			m_zoneBuilder->currentZoneRegion()->ligoData(data, i, -j);
+			painter->drawText(i * m_cellSize + 10, j * m_cellSize + 10, QString("%1 %2 %3 %4").arg(i).arg(j).arg(data.posX).arg(data.posY));
+		}
+	}
 }
 
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
index ea314faac..525971999 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
@@ -43,9 +43,9 @@ public:
 	int cellSize() const;
 	void setZoneBuilder(ZoneBuilder *zoneBuilder);
 
-	QGraphicsItem *createZoneItem(const LigoData &data, const ZonePosition &zonePos);
-	QGraphicsItem *createEmptyZoneItem(const ZonePosition &zonePos);
-	void deleteZoneItem(const ZonePosition &zonePos);
+	QGraphicsItem *createItemZone(const LigoData &data, const ZonePosition &zonePos);
+	QGraphicsItem *createItemEmptyZone(const ZonePosition &zonePos);
+	void deleteItemZone(const ZonePosition &zonePos);
 	void processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
 
 	void snapshot(const QString &fileName, int sizeSource);
@@ -53,11 +53,14 @@ public:
 
 protected:
 	virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
+	virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent);
+	virtual void drawForeground(QPainter *painter, const QRectF &rect);
 
 private:
-	void checkUnderZone(const LigoData &data, const ZonePosition &zonePos);
+	bool checkUnderZone(const int posX, const int posY);
 
 	int m_cellSize;
+	qreal m_mouseX, m_mouseY;
 	ZoneBuilder *m_zoneBuilder;
 };
 
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
index 610028762..e32f4ae6d 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
@@ -110,6 +110,8 @@ void LandscapeView::mouseReleaseEvent(QMouseEvent *event)
 
 void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect)
 {
+	QGraphicsView::drawForeground(painter, rect);
+
 	if (!m_visibleGrid)
 		return;
 
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp
index 045b342fd..81e4b687c 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp
@@ -47,16 +47,33 @@ LigoData::LigoData()
 	sharingCutEdges[3] = 0;
 }
 
-ZoneRegionEditor::ZoneRegionEditor()
+bool LigoData::operator!= (const LigoData& other) const
+{
+	return (posX != other.posX) ||
+		   (posY != other.posY) ||
+		   (rot != other.rot) ||
+		   (flip != other.flip) ||
+		   (zoneName != other.zoneName) ||
+		   (sharingMatNames[0] != other.sharingMatNames[0]) ||
+		   (sharingMatNames[1] != other.sharingMatNames[1]) ||
+		   (sharingMatNames[2] != other.sharingMatNames[2]) ||
+		   (sharingMatNames[3] != other.sharingMatNames[3]) ||
+		   (sharingCutEdges[0] != other.sharingCutEdges[0]) ||
+		   (sharingCutEdges[1] != other.sharingCutEdges[1]) ||
+		   (sharingCutEdges[2] != other.sharingCutEdges[2]) ||
+		   (sharingCutEdges[3] != other.sharingCutEdges[3]);
+}
+
+ZoneRegionObject::ZoneRegionObject()
 {
 	m_fileName = "";
 }
 
-ZoneRegionEditor::~ZoneRegionEditor()
+ZoneRegionObject::~ZoneRegionObject()
 {
 }
 
-bool ZoneRegionEditor::load(const std::string &fileName)
+bool ZoneRegionObject::load(const std::string &fileName)
 {
 	bool result = true;
 	try
@@ -85,7 +102,7 @@ bool ZoneRegionEditor::load(const std::string &fileName)
 	return result;
 }
 
-bool ZoneRegionEditor::save()
+bool ZoneRegionObject::save()
 {
 	if (m_fileName.empty())
 		return false;
@@ -123,18 +140,24 @@ bool ZoneRegionEditor::save()
 	return result;
 }
 
-void ZoneRegionEditor::setFileName(const std::string &fileName)
+std::string ZoneRegionObject::fileName() const
+{
+	return m_fileName;
+}
+
+void ZoneRegionObject::setFileName(const std::string &fileName)
 {
 	m_fileName = fileName;
 }
 
-void ZoneRegionEditor::ligoData(LigoData &data, const sint32 x, const sint32 y)
+void ZoneRegionObject::ligoData(LigoData &data, const sint32 x, const sint32 y)
 {
-	nlassert((x >= m_zoneRegion.getMinX()) &&
-			 (x <= m_zoneRegion.getMaxX()) &&
-			 (y >= m_zoneRegion.getMinY()) &&
-			 (y <= m_zoneRegion.getMaxY()));
-
+	/*
+		nlassert((x >= m_zoneRegion.getMinX()) &&
+				 (x <= m_zoneRegion.getMaxX()) &&
+				 (y >= m_zoneRegion.getMinY()) &&
+				 (y <= m_zoneRegion.getMaxY()));
+	*/
 	data.posX = m_zoneRegion.getPosX(x, y);
 	data.posY = m_zoneRegion.getPosY(x, y);
 	data.zoneName = m_zoneRegion.getName(x, y);
@@ -150,13 +173,14 @@ void ZoneRegionEditor::ligoData(LigoData &data, const sint32 x, const sint32 y)
 	data.sharingCutEdges[3] = m_zoneRegion.getSharingCutEdges(x, y, 3);
 }
 
-void ZoneRegionEditor::setLigoData(const LigoData &data, const sint32 x, const sint32 y)
+void ZoneRegionObject::setLigoData(const LigoData &data, const sint32 x, const sint32 y)
 {
-	nlassert((x >= m_zoneRegion.getMinX()) &&
-			 (x <= m_zoneRegion.getMaxX()) &&
-			 (y >= m_zoneRegion.getMinY()) &&
-			 (y <= m_zoneRegion.getMaxY()));
-
+	/*
+		nlassert((x >= m_zoneRegion.getMinX()) &&
+				 (x <= m_zoneRegion.getMaxX()) &&
+				 (y >= m_zoneRegion.getMinY()) &&
+				 (y <= m_zoneRegion.getMaxY()));
+	*/
 	m_zoneRegion.setPosX(x, y, data.posX);
 	m_zoneRegion.setPosY(x, y, data.posY);
 	m_zoneRegion.setName(x, y, data.zoneName);
@@ -172,14 +196,22 @@ void ZoneRegionEditor::setLigoData(const LigoData &data, const sint32 x, const s
 	m_zoneRegion.setSharingCutEdges(x, y, 3, data.sharingCutEdges[3]);
 }
 
-NLLIGO::CZoneRegion &ZoneRegionEditor::zoneRegion()
+NLLIGO::CZoneRegion &ZoneRegionObject::zoneRegion()
 {
 	return m_zoneRegion;
 }
 
-void ZoneRegionEditor::setZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
+void ZoneRegionObject::setZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
 {
 	m_zoneRegion = zoneRegion;
 }
 
+bool ZoneRegionObject::checkPos(const sint32 x, const sint32 y)
+{
+	return ((x >= m_zoneRegion.getMinX()) &&
+			(x <= m_zoneRegion.getMaxX()) &&
+			(y >= m_zoneRegion.getMinY()) &&
+			(y <= m_zoneRegion.getMaxY()));
+}
+
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h
index 50fab0e58..2d4f063aa 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h
@@ -44,29 +44,14 @@ struct LigoData
 
 	LigoData();
 
-	bool operator!= (const LigoData& other) const
-	{
-		return (posX != other.posX) ||
-			   (posY != other.posY) ||
-			   (rot != other.rot) ||
-			   (flip != other.flip) ||
-			   (zoneName != other.zoneName) ||
-			   (sharingMatNames[0] != other.sharingMatNames[0]) ||
-			   (sharingMatNames[1] != other.sharingMatNames[1]) ||
-			   (sharingMatNames[2] != other.sharingMatNames[2]) ||
-			   (sharingMatNames[3] != other.sharingMatNames[3]) ||
-			   (sharingCutEdges[0] != other.sharingCutEdges[0]) ||
-			   (sharingCutEdges[1] != other.sharingCutEdges[1]) ||
-			   (sharingCutEdges[2] != other.sharingCutEdges[2]) ||
-			   (sharingCutEdges[3] != other.sharingCutEdges[3]);
-	}
+	bool operator!= (const LigoData& other) const;
 };
 
-class ZoneRegionEditor
+class ZoneRegionObject
 {
 public:
-	ZoneRegionEditor();
-	~ZoneRegionEditor();
+	ZoneRegionObject();
+	~ZoneRegionObject();
 
 	// Load landscape data from file
 	bool load(const std::string &fileName);
@@ -78,6 +63,8 @@ public:
 
 	void setLigoData(const LigoData &data, const sint32 x, const sint32 y);
 
+	std::string fileName() const;
+
 	// Set file name
 	void setFileName(const std::string &fileName);
 
@@ -85,6 +72,8 @@ public:
 
 	void setZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
 
+	bool checkPos(const sint32 x, const sint32 y);
+
 private:
 
 	bool m_modified;

From d1988c74146cd952d79a2b75aef0d6f6f93b568c Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Thu, 30 Jun 2011 01:51:18 +0300
Subject: [PATCH 10/19] Changed: #1301 Fixed incorrect rendering of rotated
 elements.

---
 .../landscape_editor/landscape_scene.cpp      | 115 +++++++++++++-----
 1 file changed, 82 insertions(+), 33 deletions(-)

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
index 9970032a7..65316d9f7 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
@@ -56,20 +56,15 @@ void LandscapeScene::setZoneBuilder(ZoneBuilder *zoneBuilder)
 
 QGraphicsItem *LandscapeScene::createItemZone(const LigoData &data, const ZonePosition &zonePos)
 {
-	nlinfo(QString("%1,%2 (%3,%4)-%7 (%5,%6)").arg(zonePos.x).arg(zonePos.y).arg(data.posX).arg(data.posY).arg(data.rot).arg(data.flip).arg(data.zoneName.c_str()).toStdString().c_str());
 	if ((data.zoneName == STRING_OUT_OF_BOUND) || (checkUnderZone(zonePos.x, zonePos.y)))
 		return 0;
 
 	if (data.zoneName == STRING_UNUSED)
 		return createItemEmptyZone(zonePos);
 
-	if ((m_zoneBuilder == 0) || (data.zoneName.empty()) ||
-			(data.posX != 0) || (data.posY != 0))
+	if ((m_zoneBuilder == 0) || (data.zoneName.empty()))
 		return 0;
 
-//	if ((m_zoneBuilder == 0) || (data.zoneName.empty()))
-//		return 0;
-
 	// Get image from pixmap database
 	QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(data.zoneName.c_str()));
 	if (pixmap == 0)
@@ -98,18 +93,69 @@ QGraphicsItem *LandscapeScene::createItemZone(const LigoData &data, const ZonePo
 	// Set position graphics item with offset for large piece
 	NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.zoneName);
 
-	int delta = zoneBankItem->getSizeY() - 1;
-	if ((data.rot == 1) || (data.rot == 3))
-		delta = zoneBankItem->getSizeX() - 1;
+	sint32 deltaX = 0, deltaY = 0;
 
-	//item->setPos((zonePos.x - data.posX) * m_cellSize, (abs(int(zonePos.y)) + data.posY - delta) * m_cellSize);
-	item->setPos((zonePos.x) * m_cellSize, (abs(int(zonePos.y)) - delta) * m_cellSize);
+	// Calculate offset for graphics item (for items with size that are larger than 1)
+	if ((zoneBankItem->getSizeX() > 1) || (zoneBankItem->getSizeY() > 1))
+	{
+		sint32 sizeX = zoneBankItem->getSizeX(), sizeY = zoneBankItem->getSizeY();
+		if (data.flip == 0)
+		{
+			switch (data.rot)
+			{
+			case 0:
+				deltaX = -data.posX;
+				deltaY = -data.posY + sizeY - 1;
+				break;
+			case 1:
+				deltaX = -(sizeY - 1 - data.posY);
+				deltaY = -data.posX + sizeX - 1;
+				break;
+			case 2:
+				deltaX = -(sizeX - 1 - data.posX);
+				deltaY = data.posY;
+				break;
+			case 3:
+				deltaX = -data.posY;
+				deltaY = data.posX;
+				break;
+			}
+		}
+		else
+		{
+			switch (data.rot)
+			{
+			case 0:
+				deltaX = -(sizeX - 1 - data.posX);
+				deltaY = -data.posY + sizeY - 1;
+				break;
+			case 1:
+				deltaX = -(sizeY - 1 - data.posY);
+				deltaY = +data.posX;
+				break;
+			case 2:
+				deltaX = -data.posX;
+				deltaY = data.posY;
+				break;
+			case 3:
+				deltaX = -data.posY;
+				deltaY = -data.posX + sizeX - 1;
+				break;
+			}
+		}
+	}
+
+	// set position graphics item with taking into account the offset
+	item->setPos((zonePos.x + deltaX) * m_cellSize, (abs(int(zonePos.y + deltaY))) * m_cellSize);
 
 	// The size graphics item should be equal or proportional m_cellSize
 	item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize());
 
 	item->setData(ZoneName, QString(data.zoneName.c_str()));
-	nlinfo("render");
+
+	// for not full item zone
+	item->setZValue(0);
+
 	return item;
 }
 
@@ -133,7 +179,10 @@ QGraphicsItem *LandscapeScene::createItemEmptyZone(const ZonePosition &zonePos)
 
 	// The size graphics item should be equal or proportional m_cellSize
 	item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize());
-	nlinfo("render");
+
+	// for not full item zone
+	item->setZValue(1);
+
 	return item;
 }
 
@@ -153,7 +202,7 @@ void LandscapeScene::processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
 	{
 		for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
 		{
-			nlinfo(QString("%1 %2 %3").arg(i).arg(j).arg(zoneRegion.getName(i, j).c_str()).toStdString().c_str());
+			//nlinfo(QString("%1 %2 %3").arg(i).arg(j).arg(zoneRegion.getName(i, j).c_str()).toStdString().c_str());
 			std::string zoneName = zoneRegion.getName(i, j);
 			if (zoneName == STRING_UNUSED)
 			{
@@ -254,34 +303,34 @@ void LandscapeScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent)
 
 bool LandscapeScene::checkUnderZone(const int posX, const int posY)
 {
-	/*	QGraphicsItem *item = itemAt((posX * m_cellSize), abs(posY) * m_cellSize);
-		if (item != 0)
-		{
-			QString zoneName = item->data(ZoneName).toString();
-			return true;
-		}
-	*/	return false;
+	QGraphicsItem *item = itemAt((posX * m_cellSize), abs(posY) * m_cellSize);
+	if (item != 0)
+		return true;
+	return false;
 }
 
 void LandscapeScene::drawForeground(QPainter *painter, const QRectF &rect)
 {
 	QGraphicsScene::drawForeground(painter, rect);
-	painter->setPen(QPen(Qt::white, 0.5, Qt::SolidLine));
+	/*
+		// Render debug text (slow!)
+		painter->setPen(QPen(Qt::white, 0.5, Qt::SolidLine));
 
-	int left = int(floor(rect.left() / m_cellSize));
-	int right = int(floor(rect.right() / m_cellSize));
-	int top = int(floor(rect.top() / m_cellSize));
-	int bottom = int(floor(rect.bottom() / m_cellSize));
+		int left = int(floor(rect.left() / m_cellSize));
+		int right = int(floor(rect.right() / m_cellSize));
+		int top = int(floor(rect.top() / m_cellSize));
+		int bottom = int(floor(rect.bottom() / m_cellSize));
 
-	for (int i = left; i < right; ++i)
-	{
-		for (int j = top; j < bottom; ++j)
+		for (int i = left; i < right; ++i)
 		{
-			LigoData data;
-			m_zoneBuilder->currentZoneRegion()->ligoData(data, i, -j);
-			painter->drawText(i * m_cellSize + 10, j * m_cellSize + 10, QString("%1 %2 %3 %4").arg(i).arg(j).arg(data.posX).arg(data.posY));
+			for (int j = top; j < bottom; ++j)
+			{
+				LigoData data;
+				m_zoneBuilder->currentZoneRegion()->ligoData(data, i, -j);
+				painter->drawText(i * m_cellSize + 10, j * m_cellSize + 10, QString("%1 %2 %3 %4").arg(i).arg(j).arg(data.posX).arg(data.posY));
+			}
 		}
-	}
+	*/
 }
 
 } /* namespace LandscapeEditor */

From aedfcced67dd231afabddca71b5eeefc07a099b8 Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Sat, 2 Jul 2011 13:00:28 +0300
Subject: [PATCH 11/19] Fixed: #1301 Fixed incorrect work landscape plugin with
 other plugins which use opengl (object_viewer plugin).

---
 .../landscape_editor_window.cpp                | 18 ++++++++++++++----
 .../landscape_editor/landscape_editor_window.h |  5 +++++
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
index facf90264..abfdcbd35 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
@@ -34,14 +34,17 @@
 // Qt includes
 #include <QtCore/QSettings>
 #include <QtGui/QFileDialog>
-#include <QtOpenGL/QGLWidget>
 
 namespace LandscapeEditor
 {
 QString _lastDir;
 
 LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
-	: QMainWindow(parent)
+	: QMainWindow(parent),
+	  m_landscapeScene(0),
+	  m_zoneBuilder(0),
+	  m_undoStack(0),
+	  m_oglWidget(0)
 {
 	m_ui.setupUi(this);
 
@@ -55,8 +58,9 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
 
 	m_landscapeScene->setZoneBuilder(m_zoneBuilder);
 	m_ui.graphicsView->setScene(m_landscapeScene);
-	//m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer)));
-	m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers)));
+	//m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer));
+	m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers));
+	m_ui.graphicsView->setViewport(m_oglWidget);
 
 	createMenus();
 	createToolBars();
@@ -150,6 +154,12 @@ void LandscapeEditorWindow::openSnapshotDialog()
 	delete dialog;
 }
 
+void LandscapeEditorWindow::showEvent(QShowEvent *showEvent)
+{
+	QMainWindow::showEvent(showEvent);
+	m_oglWidget->makeCurrent();
+}
+
 void LandscapeEditorWindow::createMenus()
 {
 	Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager();
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
index ccfcf2778..ff9cfd273 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
@@ -23,6 +23,7 @@
 
 // Qt includes
 #include <QtGui/QUndoStack>
+#include <QtOpenGL/QGLWidget>
 
 namespace LandscapeEditor
 {
@@ -49,6 +50,9 @@ private Q_SLOTS:
 	void openProjectSettings();
 	void openSnapshotDialog();
 
+protected:
+	virtual void showEvent(QShowEvent *showEvent);
+
 private:
 	void createMenus();
 	void createToolBars();
@@ -58,6 +62,7 @@ private:
 	LandscapeScene *m_landscapeScene;
 	ZoneBuilder *m_zoneBuilder;
 	QUndoStack *m_undoStack;
+	QGLWidget *m_oglWidget;
 	Ui::LandscapeEditorWindow m_ui;
 }; /* class LandscapeEditorWindow */
 

From 0823243f10264ac8b98dbcc0892d0266ac0680cc Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Sun, 3 Jul 2011 17:12:31 +0300
Subject: [PATCH 12/19] Fixed: #1301 Fixed build landscape plugin under linux.

---
 code/nel/src/ligo/zone_bank.cpp                     | 13 +++++++------
 .../src/plugins/landscape_editor/builder_zone.cpp   |  2 +-
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/code/nel/src/ligo/zone_bank.cpp b/code/nel/src/ligo/zone_bank.cpp
index 5f03c4bb5..a79b98449 100644
--- a/code/nel/src/ligo/zone_bank.cpp
+++ b/code/nel/src/ligo/zone_bank.cpp
@@ -19,14 +19,15 @@
 
 #include "nel/ligo/zone_bank.h"
 
-#ifdef NL_OS_WINDOWS
-
 #include "nel/misc/debug.h"
 #include "nel/misc/file.h"
 #include "nel/misc/i_xml.h"
 #include "nel/misc/o_xml.h"
+
+#ifdef NL_OS_WINDOWS
 #define NOMINMAX
 #include <windows.h>
+#endif // NL_OS_WINDOWS
 
 using namespace std;
 using namespace NLMISC;
@@ -496,8 +497,9 @@ void CZoneBank::reset ()
 	_Selection.clear ();
 }
 
+#ifdef NL_OS_WINDOWS
 // ---------------------------------------------------------------------------
-bool CZoneBank::initFromPath(const string &sPathName, std::string &error)
+bool CZoneBank::initFromPath(const std::string &sPathName, std::string &error)
 {
 	char sDirBackup[512];
 	GetCurrentDirectory (512, sDirBackup);
@@ -520,6 +522,7 @@ bool CZoneBank::initFromPath(const string &sPathName, std::string &error)
 	SetCurrentDirectory (sDirBackup);
 	return true;
 }
+#endif // NL_OS_WINDOWS
 
 // ---------------------------------------------------------------------------
 bool CZoneBank::addElement (const std::string &elementName, std::string &error)
@@ -694,6 +697,4 @@ void CZoneBank::getSelection (std::vector<CZoneBankElement*> &SelectedElements)
 
 // ***************************************************************************
 
-} // namespace NLLIGO
-
-#endif // NL_OS_WINDOWS
+} // namespace NLLIGO
\ No newline at end of file
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
index 0e00d72be..21ab1118b 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
@@ -78,7 +78,7 @@ bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zon
 			m_pixmapMap.insert(zonePixmapName, pixmap);
 	}
 
-	QPixmap *pixmap = new QPixmap(zonePath + "_UNUSED_.png");
+	QPixmap *pixmap = new QPixmap(zonePath + "_unused_.png");
 	QPixmap *scaledPixmap = new QPixmap(pixmap->scaled(m_textureSize, m_textureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
 	delete pixmap;
 	m_pixmapMap.insert(QString(STRING_UNUSED), scaledPixmap);

From 54391eaebf6ce531e5c1e5faadebe67c4ab2e009 Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Mon, 4 Jul 2011 23:16:45 +0300
Subject: [PATCH 13/19] Changed: #1301 Added random and full cycle modes(for
 rotation and flip values too) adding zone on landscape.

---
 .../landscape_editor/list_zones_widget.cpp    | 67 ++++++++++++++++---
 .../landscape_editor/list_zones_widget.h      | 10 ++-
 .../landscape_editor/list_zones_widget.ui     | 10 ++-
 3 files changed, 74 insertions(+), 13 deletions(-)

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
index 7ce3f5421..d0bfe058c 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
@@ -38,6 +38,8 @@ namespace LandscapeEditor
 
 ListZonesWidget::ListZonesWidget(QWidget *parent)
 	: QWidget(parent),
+	  m_rotCycle(0),
+	  m_flipCycle(0),
 	  m_listZonesModel(0),
 	  m_zoneBuilder(0)
 {
@@ -101,24 +103,70 @@ void ListZonesWidget::updateUi()
 	m_listZonesModel->rebuildModel(m_zoneBuilder->pixmapDatabase());
 }
 
-QString ListZonesWidget::currentZoneName() const
+QString ListZonesWidget::currentZoneName()
 {
 	QString zoneName = "";
 	QModelIndex index = m_ui.listView->currentIndex();
 	if (index.isValid())
 		zoneName = index.data().toString();
-
+	if (m_ui.zoneSelectComboBox->currentIndex() == 1)
+	{
+		// Random value
+		if (m_listSelection.size() > 0)
+		{
+			uint32 randZone = uint32(NLMISC::frand(m_listSelection.size()));
+			NLMISC::clamp(randZone, (uint32)0, uint32(m_listSelection.size() - 1));
+			zoneName = m_listSelection[randZone];
+		}
+	}
+	else if (m_ui.zoneSelectComboBox->currentIndex() == 2)
+	{
+		// Full cycle
+		zoneName = m_listSelection[m_zoneNameCycle];
+		m_zoneNameCycle++;
+		m_zoneNameCycle = m_zoneNameCycle % m_listSelection.size();
+	}
 	return zoneName;
 }
 
-int ListZonesWidget::currentRot() const
+int ListZonesWidget::currentRot()
 {
-	return m_ui.rotComboBox->currentIndex();
+	int rot = m_ui.rotComboBox->currentIndex();
+	if (rot == 4)
+	{
+		// Random value
+		uint32 randRot = uint32(NLMISC::frand(4.0));
+		NLMISC::clamp(randRot, (uint32)0, (uint32)3);
+		rot = int(randRot);
+	}
+	else if (rot == 5)
+	{
+		// Full cycle
+		rot = m_rotCycle;
+		m_rotCycle++;
+		m_rotCycle = m_rotCycle % 4;
+	}
+	return rot;
 }
 
-int ListZonesWidget::currentFlip() const
+int ListZonesWidget::currentFlip()
 {
-	return m_ui.flipComboBox->currentIndex();
+	int flip = m_ui.flipComboBox->currentIndex();
+	if (flip == 2)
+	{
+		// Random value
+		uint32 randFlip = uint32(NLMISC::frand(2.0));
+		NLMISC::clamp (randFlip, (uint32)0, (uint32)1);
+		flip = int(randFlip);
+	}
+	else if (flip == 3)
+	{
+		// Full cycle
+		flip = m_flipCycle;
+		m_flipCycle++;
+		m_flipCycle = m_flipCycle % 2;
+	}
+	return flip;
 }
 
 bool ListZonesWidget::isNotPropogate() const
@@ -234,11 +282,12 @@ void ListZonesWidget::updateListZones()
 	std::vector<NLLIGO::CZoneBankElement *> currentSelection;
 	zoneBank.getSelection (currentSelection);
 
-	QStringList listSelection;
+	m_listSelection.clear();
+	m_zoneNameCycle = 0;
 	for (size_t i = 0; i < currentSelection.size(); ++i)
-		listSelection << currentSelection[i]->getName().c_str();
+		m_listSelection << currentSelection[i]->getName().c_str();
 
-	m_listZonesModel->setListZones(listSelection);
+	m_listZonesModel->setListZones(m_listSelection);
 }
 
 void ListZonesWidget::disableSignals(bool block)
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
index c35e7b0fa..4128f8cc2 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
@@ -45,9 +45,9 @@ public:
 
 	void updateUi();
 	void setZoneBuilder(ZoneBuilder *zoneBuilder);
-	QString currentZoneName() const;
-	int currentRot() const;
-	int currentFlip() const;
+	QString currentZoneName();
+	int currentRot();
+	int currentFlip();
 	bool isNotPropogate() const;
 	bool isForce() const;
 
@@ -62,6 +62,10 @@ private Q_SLOTS:
 private:
 	void disableSignals(bool block);
 
+	int m_rotCycle, m_flipCycle;
+	int m_zoneNameCycle;
+	QStringList m_listSelection;
+
 	ListZonesModel *m_listZonesModel;
 	ZoneBuilder *m_zoneBuilder;
 	Ui::ListZonesWidget m_ui;
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui
index 4d9f63129..ed9faf74e 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui
@@ -39,7 +39,12 @@
        <widget class="QComboBox" name="categoryValueComboBox_1"/>
       </item>
       <item row="0" column="3">
-       <widget class="QComboBox" name="comboBox_11">
+       <widget class="QComboBox" name="zoneSelectComboBox">
+        <item>
+         <property name="text">
+          <string>Select</string>
+         </property>
+        </item>
         <item>
          <property name="text">
           <string>Random</string>
@@ -297,6 +302,9 @@
      <property name="verticalScrollMode">
       <enum>QAbstractItemView::ScrollPerPixel</enum>
      </property>
+     <property name="spacing">
+      <number>1</number>
+     </property>
     </widget>
    </item>
   </layout>

From 423d6ae8b31e57e98dc972e3671a25e3034c875e Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Mon, 4 Jul 2011 23:19:58 +0300
Subject: [PATCH 14/19] Changed: #1301 Class PixmapDatabase was moved to a
 separate file.

---
 .../plugins/landscape_editor/CMakeLists.txt   |   1 -
 .../plugins/landscape_editor/builder_zone.cpp |  86 ------------
 .../plugins/landscape_editor/builder_zone.h   |  34 +----
 .../landscape_editor/pixmap_database.cpp      | 132 ++++++++++++++++++
 .../landscape_editor/pixmap_database.h        |  69 +++++++++
 5 files changed, 202 insertions(+), 120 deletions(-)
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp
 create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
index 8c4278c46..2f1d58c66 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt
@@ -14,7 +14,6 @@ SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR	landscape_editor_plugin.h
 					landscape_scene.h
 					list_zones_model.h
 					list_zones_widget.h
-					landscape_actions.h
 					landscape_view.h
 					project_settings_dialog.h
 					snapshot_dialog.h
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
index 21ab1118b..843259ddb 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
@@ -32,92 +32,6 @@
 namespace LandscapeEditor
 {
 
-PixmapDatabase::PixmapDatabase()
-	: m_textureSize(256)
-{
-}
-
-PixmapDatabase::~PixmapDatabase()
-{
-	reset();
-}
-
-bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zoneBank)
-{
-	QProgressDialog *progressDialog = new QProgressDialog();
-	progressDialog->show();
-
-	std::vector<std::string> listNames;
-	zoneBank.getCategoryValues ("zone", listNames);
-	progressDialog->setRange(0, listNames.size());
-	for (uint i = 0; i < listNames.size(); ++i)
-	{
-		QApplication::processEvents();
-		progressDialog->setValue(i);
-
-		NLLIGO::CZoneBankElement *zoneBankItem = zoneBank.getElementByZoneName (listNames[i]);
-
-		// Read the texture file
-		QString zonePixmapName(listNames[i].c_str());
-		uint8 sizeX = zoneBankItem->getSizeX();
-		uint8 sizeY = zoneBankItem->getSizeY();
-
-		QPixmap *pixmap = new QPixmap(zonePath + zonePixmapName + ".png");
-		if (pixmap->isNull())
-		{
-			// Generate filled pixmap
-		}
-		// All pixmaps must be have same size
-		if (pixmap->width() != sizeX * m_textureSize)
-		{
-			QPixmap *scaledPixmap = new QPixmap(pixmap->scaled(sizeX * m_textureSize, sizeY * m_textureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
-			delete pixmap;
-			m_pixmapMap.insert(zonePixmapName, scaledPixmap);
-		}
-		else
-			m_pixmapMap.insert(zonePixmapName, pixmap);
-	}
-
-	QPixmap *pixmap = new QPixmap(zonePath + "_unused_.png");
-	QPixmap *scaledPixmap = new QPixmap(pixmap->scaled(m_textureSize, m_textureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
-	delete pixmap;
-	m_pixmapMap.insert(QString(STRING_UNUSED), scaledPixmap);
-
-	delete progressDialog;
-	return true;
-}
-
-void PixmapDatabase::reset()
-{
-	QStringList listNames(m_pixmapMap.keys());
-	Q_FOREACH(QString name, listNames)
-	{
-		QPixmap *pixmap = m_pixmapMap.value(name);
-		delete pixmap;
-	}
-	m_pixmapMap.clear();
-}
-
-QStringList PixmapDatabase::listPixmaps() const
-{
-	return m_pixmapMap.keys();
-}
-
-QPixmap *PixmapDatabase::pixmap(const QString &zoneName) const
-{
-	QPixmap *result = 0;
-	if (!m_pixmapMap.contains(zoneName))
-		nlwarning("QPixmap %s not found", zoneName.toStdString().c_str());
-	else
-		result = m_pixmapMap.value(zoneName);
-	return result;
-}
-
-int PixmapDatabase::textureSize() const
-{
-	return m_textureSize;
-}
-
 ZoneBuilder::ZoneBuilder(ListZonesWidget *listZonesWidget, LandscapeScene *landscapeScene, QUndoStack *undoStack)
 	: m_currentZoneRegion(-1),
 	  m_pixmapDatabase(0),
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
index ecc47976f..da5c2901f 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
@@ -21,6 +21,7 @@
 // Project includes
 #include "builder_zone_region.h"
 #include "zone_region_editor.h"
+#include "pixmap_database.h"
 
 // NeL includes
 #include <nel/ligo/zone_bank.h>
@@ -67,39 +68,6 @@ struct ZonePosition
 	}
 };
 
-/**
-@class PixmapDatabase
-@brief PixmapDatabase contains the image database
-@details
-*/
-class PixmapDatabase
-{
-public:
-	PixmapDatabase();
-	~PixmapDatabase();
-
-	/// Load all images(png) from zonePath, list images gets from zoneBank
-	bool loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zoneBank);
-
-	/// Unload all images
-	void reset();
-
-	/// Get list names all loaded pixmaps
-	QStringList listPixmaps() const;
-
-	/// Get original pixmap
-	/// @return QPixmap* if the image is in the database ; otherwise returns 0.
-	QPixmap *pixmap(const QString &zoneName) const;
-
-	int textureSize() const;
-
-private:
-
-	int m_textureSize;
-	QMap<QString, QPixmap*> m_pixmapMap;
-};
-
-
 /**
 @class ZoneBuilder
 @brief ZoneBuilder contains all the shared data between the tools and the engine.
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp
new file mode 100644
index 000000000..f0e2859f6
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp
@@ -0,0 +1,132 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+// Project includes
+#include "pixmap_database.h"
+
+// NeL includes
+#include <nel/misc/debug.h>
+#include <nel/ligo/zone_region.h>
+
+// STL includes
+#include <vector>
+#include <string>
+
+// Qt includes
+#include <QtCore/QDir>
+#include <QtGui/QMessageBox>
+#include <QtGui/QApplication>
+#include <QtGui/QProgressDialog>
+
+namespace LandscapeEditor
+{
+
+PixmapDatabase::PixmapDatabase(int textureSize)
+	: m_textureSize(textureSize)
+{
+}
+
+PixmapDatabase::~PixmapDatabase()
+{
+	reset();
+}
+
+bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zoneBank, bool displayProgress)
+{
+	QProgressDialog *progressDialog;
+	std::vector<std::string> listNames;
+	zoneBank.getCategoryValues ("zone", listNames);
+	if (displayProgress)
+	{
+		progressDialog = new QProgressDialog();
+		progressDialog->show();
+		progressDialog->setRange(0, listNames.size());
+	}
+
+	for (uint i = 0; i < listNames.size(); ++i)
+	{
+		QApplication::processEvents();
+
+		if (displayProgress)
+			progressDialog->setValue(i);
+
+		NLLIGO::CZoneBankElement *zoneBankItem = zoneBank.getElementByZoneName (listNames[i]);
+
+		// Read the texture file
+		QString zonePixmapName(listNames[i].c_str());
+		uint8 sizeX = zoneBankItem->getSizeX();
+		uint8 sizeY = zoneBankItem->getSizeY();
+
+		QPixmap *pixmap = new QPixmap(zonePath + zonePixmapName + ".png");
+		if (pixmap->isNull())
+		{
+			// Generate filled pixmap
+		}
+		// All pixmaps must be have same size
+		if (pixmap->width() != sizeX * m_textureSize)
+		{
+			QPixmap *scaledPixmap = new QPixmap(pixmap->scaled(sizeX * m_textureSize, sizeY * m_textureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+			delete pixmap;
+			m_pixmapMap.insert(zonePixmapName, scaledPixmap);
+		}
+		else
+			m_pixmapMap.insert(zonePixmapName, pixmap);
+	}
+
+	QPixmap *pixmap = new QPixmap(zonePath + "_unused_.png");
+	QPixmap *scaledPixmap = new QPixmap(pixmap->scaled(m_textureSize, m_textureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+	delete pixmap;
+	m_pixmapMap.insert(QString(STRING_UNUSED), scaledPixmap);
+
+	if (displayProgress)
+		delete progressDialog;
+
+	return true;
+}
+
+void PixmapDatabase::reset()
+{
+	QStringList listNames(m_pixmapMap.keys());
+	Q_FOREACH(QString name, listNames)
+	{
+		QPixmap *pixmap = m_pixmapMap.value(name);
+		delete pixmap;
+	}
+	m_pixmapMap.clear();
+}
+
+QStringList PixmapDatabase::listPixmaps() const
+{
+	return m_pixmapMap.keys();
+}
+
+QPixmap *PixmapDatabase::pixmap(const QString &zoneName) const
+{
+	QPixmap *result = 0;
+	if (!m_pixmapMap.contains(zoneName))
+		nlwarning("QPixmap %s not found", zoneName.toStdString().c_str());
+	else
+		result = m_pixmapMap.value(zoneName);
+	return result;
+}
+
+int PixmapDatabase::textureSize() const
+{
+	return m_textureSize;
+}
+
+} /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h
new file mode 100644
index 000000000..fc90fe180
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h
@@ -0,0 +1,69 @@
+// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+// Copyright (C) 2011  Dzmitry Kamiahin <dnk-88@tut.by>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef PIXMAP_DATABASE_H
+#define PIXMAP_DATABASE_H
+
+// Project includes
+#include "landscape_editor_global.h"
+
+// NeL includes
+#include <nel/ligo/zone_bank.h>
+
+// Qt includes
+#include <QtCore/QString>
+#include <QtCore/QMap>
+#include <QtGui/QPixmap>
+
+namespace LandscapeEditor
+{
+
+/**
+@class PixmapDatabase
+@brief PixmapDatabase contains the image database
+@details
+*/
+class LANDSCAPE_EDITOR_EXPORT PixmapDatabase
+{
+public:
+	PixmapDatabase(int textureSize = 256);
+	~PixmapDatabase();
+
+	/// Load all images(png) from zonePath, list images gets from zoneBank
+	bool loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zoneBank, bool displayProgress = false);
+
+	/// Unload all images
+	void reset();
+
+	/// Get list names all loaded pixmaps
+	QStringList listPixmaps() const;
+
+	/// Get original pixmap
+	/// @return QPixmap* if the image is in the database ; otherwise returns 0.
+	QPixmap *pixmap(const QString &zoneName) const;
+
+	int textureSize() const;
+
+private:
+
+	int m_textureSize;
+	QMap<QString, QPixmap*> m_pixmapMap;
+};
+
+} /* namespace LandscapeEditor */
+
+#endif // PIXMAP_DATABASE_H

From 777c00f27064a5a4b1d5269fd9aadd75051c8544 Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Wed, 6 Jul 2011 03:32:02 +0300
Subject: [PATCH 15/19] Changed: #1301 Added flag "modified" in
 ZoneRegionObject.

---
 .../landscape_editor/zone_region_editor.cpp   | 14 ++++++++--
 .../landscape_editor/zone_region_editor.h     | 28 +++++++++++++++----
 2 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp
index 81e4b687c..399d39496 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp
@@ -196,12 +196,12 @@ void ZoneRegionObject::setLigoData(const LigoData &data, const sint32 x, const s
 	m_zoneRegion.setSharingCutEdges(x, y, 3, data.sharingCutEdges[3]);
 }
 
-NLLIGO::CZoneRegion &ZoneRegionObject::zoneRegion()
+NLLIGO::CZoneRegion &ZoneRegionObject::ligoZoneRegion()
 {
 	return m_zoneRegion;
 }
 
-void ZoneRegionObject::setZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
+void ZoneRegionObject::setLigoZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
 {
 	m_zoneRegion = zoneRegion;
 }
@@ -214,4 +214,14 @@ bool ZoneRegionObject::checkPos(const sint32 x, const sint32 y)
 			(y <= m_zoneRegion.getMaxY()));
 }
 
+bool ZoneRegionObject::isModified() const
+{
+	return m_modified;
+}
+
+void ZoneRegionObject::setModified(bool modified)
+{
+	m_modified = modified;
+}
+
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h
index 2d4f063aa..9081d7002 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h
@@ -32,6 +32,7 @@
 namespace LandscapeEditor
 {
 
+// Data
 struct LigoData
 {
 	uint8			posX;
@@ -47,33 +48,50 @@ struct LigoData
 	bool operator!= (const LigoData& other) const;
 };
 
+/**
+@class ZoneRegionObject
+@brief
+@details
+*/
 class ZoneRegionObject
 {
 public:
 	ZoneRegionObject();
 	~ZoneRegionObject();
 
-	// Load landscape data from file
+	/// Load landscape data from file
 	bool load(const std::string &fileName);
 
-	// Save landscape data to file
+	/// Save landscape data to file (before save, should set file name).
 	bool save();
 
+	/// Get ligo data
 	void ligoData(LigoData &data, const sint32 x, const sint32 y);
 
+	/// Set ligo data
 	void setLigoData(const LigoData &data, const sint32 x, const sint32 y);
 
+	/// Get file name
 	std::string fileName() const;
 
-	// Set file name
+	/// Set file name, use for saving data in file
 	void setFileName(const std::string &fileName);
 
-	NLLIGO::CZoneRegion &zoneRegion();
+	/// Accessor to LIGO CZoneRegion
+	NLLIGO::CZoneRegion &ligoZoneRegion();
 
-	void setZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
+	void setLigoZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
 
+	/// Check position, it belongs to the landscape
 	bool checkPos(const sint32 x, const sint32 y);
 
+	/// Helper flag to know if a ps has been modified
+	/// @{
+	bool isModified() const;
+
+	void setModified(bool modified);
+	/// @}
+
 private:
 
 	bool m_modified;

From eacb41e5b2aed1e1980ba64c1e0f35ac31fb2672 Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Wed, 6 Jul 2011 03:34:30 +0300
Subject: [PATCH 16/19] Fixed: #1301 Fixed "full cycle" flag with empty list
 and added comments in list_zones_widget.

---
 .../src/plugins/landscape_editor/list_zones_widget.cpp |  9 ++++++---
 .../src/plugins/landscape_editor/list_zones_widget.h   | 10 +++++++++-
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
index d0bfe058c..554b19ca3 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp
@@ -122,9 +122,12 @@ QString ListZonesWidget::currentZoneName()
 	else if (m_ui.zoneSelectComboBox->currentIndex() == 2)
 	{
 		// Full cycle
-		zoneName = m_listSelection[m_zoneNameCycle];
-		m_zoneNameCycle++;
-		m_zoneNameCycle = m_zoneNameCycle % m_listSelection.size();
+		if (m_listSelection.size() > 0)
+		{
+			zoneName = m_listSelection[m_zoneNameCycle];
+			m_zoneNameCycle++;
+			m_zoneNameCycle = m_zoneNameCycle % m_listSelection.size();
+		}
 	}
 	return zoneName;
 }
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
index 4128f8cc2..7298bbe3c 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h
@@ -44,14 +44,22 @@ public:
 	~ListZonesWidget();
 
 	void updateUi();
+
+	// Set zone builder, call this method before using this class
 	void setZoneBuilder(ZoneBuilder *zoneBuilder);
+
+	// Get current zone name which user selected from list.
 	QString currentZoneName();
+
+	// Get current rotation value which user selected (Rot 0-0deg, 1-90deg, 2-180deg, 3-270deg).
 	int currentRot();
+
+	// Get current flip value which user selected (Flip 0-false, 1-true).
 	int currentFlip();
+
 	bool isNotPropogate() const;
 	bool isForce() const;
 
-Q_SIGNALS:
 private Q_SLOTS:
 	void updateFilters_1(const QString &value);
 	void updateFilters_2(const QString &value);

From 712349f7f5356e195532479c7386ffbe941912b0 Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Wed, 6 Jul 2011 03:43:31 +0300
Subject: [PATCH 17/19] Changed: #1301 Added checking for the overlaps when
 adding a new landscape. Added blackout inactive landscapes. Operations adding
 and removing landscapes work correctly.

---
 .../plugins/landscape_editor/builder_zone.cpp | 165 +++++++++++++-----
 .../plugins/landscape_editor/builder_zone.h   |  29 ++-
 .../landscape_editor/builder_zone_region.cpp  |  40 ++---
 .../landscape_editor/builder_zone_region.h    |   2 +-
 .../landscape_editor/landscape_actions.cpp    |   8 +-
 .../landscape_editor_window.cpp               |  19 +-
 .../landscape_editor/landscape_scene.cpp      |  49 ++++--
 .../landscape_editor/landscape_scene.h        |  15 +-
 .../landscape_editor/landscape_view.cpp       |   2 +
 9 files changed, 232 insertions(+), 97 deletions(-)

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
index 843259ddb..265e380ca 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
@@ -32,13 +32,14 @@
 namespace LandscapeEditor
 {
 
-ZoneBuilder::ZoneBuilder(ListZonesWidget *listZonesWidget, LandscapeScene *landscapeScene, QUndoStack *undoStack)
+ZoneBuilder::ZoneBuilder(LandscapeScene *landscapeScene, ListZonesWidget *listZonesWidget, QUndoStack *undoStack)
 	: m_currentZoneRegion(-1),
 	  m_pixmapDatabase(0),
 	  m_listZonesWidget(listZonesWidget),
 	  m_landscapeScene(landscapeScene),
 	  m_undoStack(undoStack)
 {
+	nlassert(m_landscapeScene);
 	m_pixmapDatabase = new PixmapDatabase();
 	m_lastPathName = "";
 }
@@ -81,6 +82,9 @@ bool ZoneBuilder::init(const QString &pathName, bool makeAZone)
 
 void ZoneBuilder::actionLigoTile(const LigoData &data, const ZonePosition &zonePos)
 {
+	if (m_undoStack == 0)
+		return;
+
 	checkBeginMacro();
 	nlinfo(QString("%1 %2 %3 (%4 %5)").arg(data.zoneName.c_str()).arg(zonePos.x).arg(zonePos.y).arg(data.posX).arg(data.posY).toStdString().c_str());
 	m_zonePositionList.push_back(zonePos);
@@ -89,6 +93,9 @@ void ZoneBuilder::actionLigoTile(const LigoData &data, const ZonePosition &zoneP
 
 void ZoneBuilder::actionLigoMove(uint index, sint32 deltaX, sint32 deltaY)
 {
+	if (m_undoStack == 0)
+		return;
+
 	checkBeginMacro();
 	nlinfo("ligoMove");
 	//m_undoStack->push(new LigoMoveCommand(index, deltaX, deltaY, this));
@@ -96,6 +103,9 @@ void ZoneBuilder::actionLigoMove(uint index, sint32 deltaX, sint32 deltaY)
 
 void ZoneBuilder::actionLigoResize(uint index, sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY)
 {
+	if (m_undoStack == 0)
+		return;
+
 	checkBeginMacro();
 	nlinfo(QString("minX=%1 maxX=%2 minY=%3 maxY=%4").arg(newMinX).arg(newMaxX).arg(newMinY).arg(newMaxY).toStdString().c_str());
 	m_undoStack->push(new LigoResizeCommand(index, newMinX, newMaxX, newMinY, newMaxY, this));
@@ -103,16 +113,20 @@ void ZoneBuilder::actionLigoResize(uint index, sint32 newMinX, sint32 newMaxX, s
 
 void ZoneBuilder::addZone(sint32 posX, sint32 posY)
 {
-	if (m_builderZoneRegions.empty())
+	// Read-only mode
+	if ((m_listZonesWidget == 0) || (m_undoStack == 0))
 		return;
 
+	if (m_landscapeItems.empty())
+		return;
+
+	// Check zone name
 	std::string zoneName = m_listZonesWidget->currentZoneName().toStdString();
 	if (zoneName.empty())
 		return;
 
-	std::string error;
-	BuilderZoneRegion *builderZoneRegion = m_builderZoneRegions.at(m_currentZoneRegion);
-	builderZoneRegion->init(this, error);
+	BuilderZoneRegion *builderZoneRegion = m_landscapeItems.at(m_currentZoneRegion).builderZoneRegion;
+	builderZoneRegion->init(this);
 
 	uint8 rot = uint8(m_listZonesWidget->currentRot());
 	uint8 flip = uint8(m_listZonesWidget->currentFlip());
@@ -122,8 +136,6 @@ void ZoneBuilder::addZone(sint32 posX, sint32 posY)
 	m_titleAction = QString("Add zone %1,%2").arg(posX).arg(posY);
 	m_createdAction = false;
 	m_zonePositionList.clear();
-
-	nlinfo("---------");
 	if (m_listZonesWidget->isForce())
 	{
 		builderZoneRegion->addForce(posX, posY, rot, flip, zoneBankElement);
@@ -140,45 +152,95 @@ void ZoneBuilder::addZone(sint32 posX, sint32 posY)
 
 void ZoneBuilder::addTransition(const sint32 posX, const sint32 posY)
 {
+	if ((m_listZonesWidget == 0) || (m_undoStack == 0))
+		return;
 }
 
 void ZoneBuilder::delZone(const sint32 posX, const sint32 posY)
 {
-	if (m_builderZoneRegions.empty())
+	if ((m_listZonesWidget == 0) || (m_undoStack == 0))
+		return;
+
+	if (m_landscapeItems.empty())
 		return;
 
 	m_titleAction = QString("Del zone %1,%2").arg(posX).arg(posY);
 	m_createdAction = false;
 
-	BuilderZoneRegion *builderZoneRegion = m_builderZoneRegions.at(m_currentZoneRegion);
-	std::string error;
-	nlinfo("---------");
-	builderZoneRegion->init(this, error);
+	BuilderZoneRegion *builderZoneRegion = m_landscapeItems.at(m_currentZoneRegion).builderZoneRegion;
+
+	builderZoneRegion->init(this);
 	builderZoneRegion->del(posX, posY);
 	checkEndMacro();
 }
 
 int ZoneBuilder::createZoneRegion()
 {
-	ZoneRegionObject *newZoneRegion = new ZoneRegionObject();
-	m_zoneRegions.push_back(newZoneRegion);
-	if (m_currentZoneRegion == -1)
-		m_currentZoneRegion = m_zoneRegions.indexOf(newZoneRegion);
+	int newId = m_landscapeItems.size();
+	LandscapeItem landItem;
+	landItem.zoneRegionObject = new ZoneRegionObject();
+	landItem.builderZoneRegion = new BuilderZoneRegion(newId);
+	landItem.builderZoneRegion->init(this);
+	landItem.rectItem = 0;
 
 	newZone();
-	return m_zoneRegions.indexOf(newZoneRegion);
+	m_landscapeItems.push_back(landItem);
+	if (m_currentZoneRegion == -1)
+		setCurrentZoneRegion(newId);
+
+	return newId;
+}
+
+int ZoneBuilder::createZoneRegion(const QString &fileName)
+{
+	int newId = m_landscapeItems.size();
+	LandscapeItem landItem;
+	landItem.zoneRegionObject = new ZoneRegionObject();
+	landItem.zoneRegionObject->load(fileName.toStdString());
+
+	if (!checkOverlaps(landItem.zoneRegionObject->ligoZoneRegion()))
+	{
+		delete landItem.zoneRegionObject;
+		return -1;
+	}
+	landItem.builderZoneRegion = new BuilderZoneRegion(newId);
+	landItem.builderZoneRegion->init(this);
+
+	newZone();
+	m_landscapeItems.push_back(landItem);
+
+	m_landscapeScene->addZoneRegion(landItem.zoneRegionObject->ligoZoneRegion());
+	m_landscapeItems.at(newId).rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion());
+
+	if (m_currentZoneRegion == -1)
+		setCurrentZoneRegion(newId);
+
+	return newId;
 }
 
 void ZoneBuilder::deleteZoneRegion(int id)
 {
-	if ((0 <= id) && (id < m_zoneRegions.size()))
-		delete m_zoneRegions.takeAt(id);
+	if ((0 <= id) && (id < int(m_landscapeItems.size())))
+	{
+		m_landscapeScene->delZoneRegion(m_landscapeItems.at(id).zoneRegionObject->ligoZoneRegion());
+		delete m_landscapeItems.at(id).zoneRegionObject;
+		delete m_landscapeItems.at(id).builderZoneRegion;
+		delete m_landscapeItems.at(id).rectItem;
+		m_landscapeItems.erase(m_landscapeItems.begin() + id);
+		calcMask();
+	}
 }
 
 void ZoneBuilder::setCurrentZoneRegion(int id)
 {
-	if ((0 <= id) && (id < m_zoneRegions.size()))
+	if ((0 <= id) && (id < int(m_landscapeItems.size())))
+	{
+		if (currentIdZoneRegion() != -1)
+			m_landscapeItems.at(m_currentZoneRegion).rectItem = m_landscapeScene->createLayerBlackout(currentZoneRegion()->ligoZoneRegion());
 		m_currentZoneRegion = id;
+		delete m_landscapeItems.at(id).rectItem;
+		m_landscapeItems.at(id).rectItem = 0;
+	}
 }
 
 int ZoneBuilder::currentIdZoneRegion() const
@@ -188,27 +250,27 @@ int ZoneBuilder::currentIdZoneRegion() const
 
 ZoneRegionObject *ZoneBuilder::currentZoneRegion() const
 {
-	return m_zoneRegions.at(m_currentZoneRegion);
+	return m_landscapeItems.at(m_currentZoneRegion).zoneRegionObject;
 }
 
 int ZoneBuilder::countZoneRegion() const
 {
-	return m_zoneRegions.size();
+	return m_landscapeItems.size();
 }
 
 ZoneRegionObject *ZoneBuilder::zoneRegion(int id) const
 {
-	return m_zoneRegions.at(id);
+	return m_landscapeItems.at(id).zoneRegionObject;
 }
 
 void ZoneBuilder::ligoData(LigoData &data, const ZonePosition &zonePos)
 {
-	m_zoneRegions.at(zonePos.region)->ligoData(data, zonePos.x, zonePos.y);
+	m_landscapeItems.at(zonePos.region).zoneRegionObject->ligoData(data, zonePos.x, zonePos.y);
 }
 
 void ZoneBuilder::setLigoData(LigoData &data, const ZonePosition &zonePos)
 {
-	m_zoneRegions.at(zonePos.region)->setLigoData(data, zonePos.x, zonePos.y);
+	m_landscapeItems.at(zonePos.region).zoneRegionObject->setLigoData(data, zonePos.x, zonePos.y);
 }
 
 bool ZoneBuilder::initZoneBank (const QString &pathName)
@@ -243,16 +305,13 @@ QString ZoneBuilder::dataPath() const
 
 void ZoneBuilder::newZone()
 {
-	BuilderZoneRegion *builderZoneRegion = new BuilderZoneRegion(m_builderZoneRegions.size());
-	m_builderZoneRegions.push_back(builderZoneRegion);
-
 	// Select starting point for the moment 0,0
 	sint32 x = 0, y = 0;
 
 	// If there are some zone already present increase x until free
-	for (int i = 0; i < m_zoneRegions.size(); ++i)
+	for (size_t i = 0; i < m_landscapeItems.size(); ++i)
 	{
-		const NLLIGO::CZoneRegion &zoneRegion = m_zoneRegions.at(i)->zoneRegion();
+		const NLLIGO::CZoneRegion &zoneRegion = m_landscapeItems.at(i).zoneRegionObject->ligoZoneRegion();
 		const std::string &zoneName = zoneRegion.getName (x, y);
 		if ((zoneName != STRING_OUT_OF_BOUND) && (zoneName != STRING_UNUSED))
 		{
@@ -278,18 +337,17 @@ bool ZoneBuilder::getZoneMask(sint32 x, sint32 y)
 
 void ZoneBuilder::calcMask()
 {
-	sint32 i;
 	sint32 x, y;
 
 	m_minY = m_minX = 1000000;
 	m_maxY = m_maxX = -1000000;
 
-	if (m_builderZoneRegions.size() == 0)
+	if (m_landscapeItems.size() == 0)
 		return;
 
-	for (i = 0; i < (sint32)m_builderZoneRegions.size(); ++i)
+	for (size_t i = 0; i < m_landscapeItems.size(); ++i)
 	{
-		const NLLIGO::CZoneRegion &region = zoneRegion(i)->zoneRegion();
+		const NLLIGO::CZoneRegion &region = m_landscapeItems.at(i).zoneRegionObject->ligoZoneRegion();
 
 		if (m_minX > region.getMinX())
 			m_minX = region.getMinX();
@@ -308,10 +366,10 @@ void ZoneBuilder::calcMask()
 		{
 			m_zoneMask[x - m_minX + (y - m_minY) * stride] = true;
 
-			for (i = 0; i < (sint32)m_builderZoneRegions.size(); ++i)
-				if (i != m_currentZoneRegion)
+			for (size_t i = 0; i < m_landscapeItems.size(); ++i)
+				if (int(i) != m_currentZoneRegion)
 				{
-					const NLLIGO::CZoneRegion &region = zoneRegion(i)->zoneRegion();
+					const NLLIGO::CZoneRegion &region = zoneRegion(i)->ligoZoneRegion();
 
 					const std::string &rSZone = region.getName (x, y);
 					if ((rSZone != STRING_OUT_OF_BOUND) && (rSZone != STRING_UNUSED))
@@ -322,25 +380,24 @@ void ZoneBuilder::calcMask()
 		}
 }
 
-bool ZoneBuilder::getZoneAmongRegions (ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y)
+bool ZoneBuilder::getZoneAmongRegions(ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y)
 {
-	Q_FOREACH(ZoneRegionObject *zoneRegion, m_zoneRegions)
+	for (size_t i = 0; i < m_landscapeItems.size(); ++i)
 	{
-		const NLLIGO::CZoneRegion &region = zoneRegion->zoneRegion();
+		const NLLIGO::CZoneRegion &region = m_landscapeItems.at(i).zoneRegionObject->ligoZoneRegion();
 		if ((x < region.getMinX()) || (x > region.getMaxX()) ||
 				(y < region.getMinY()) || (y > region.getMaxY()))
 			continue;
 		if (region.getName(x, y) != STRING_UNUSED)
 		{
-			int index = m_zoneRegions.indexOf(zoneRegion);
-			builderZoneRegionFrom = m_builderZoneRegions.at(index);
-			zonePos = ZonePosition(x, y, index);
+			builderZoneRegionFrom = m_landscapeItems.at(i).builderZoneRegion;
+			zonePos = ZonePosition(x, y, i);
 			return true;
 		}
 	}
 
 	// The zone is not present in other region so it is an empty or oob zone of the current region
-	const NLLIGO::CZoneRegion &region = zoneRegion(builderZoneRegionFrom->getRegionId())->zoneRegion();
+	const NLLIGO::CZoneRegion &region = zoneRegion(builderZoneRegionFrom->getRegionId())->ligoZoneRegion();
 	if ((x < region.getMinX()) || (x > region.getMaxX()) ||
 			(y < region.getMinY()) || (y > region.getMaxY()))
 		return false; // Out Of Bound
@@ -372,4 +429,24 @@ void ZoneBuilder::checkEndMacro()
 	}
 }
 
+bool ZoneBuilder::checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion)
+{
+	for (size_t j = 0; j < m_landscapeItems.size(); ++j)
+	{
+		const NLLIGO::CZoneRegion &zoneRegion = m_landscapeItems.at(j).zoneRegionObject->ligoZoneRegion();
+		for (sint32 y = zoneRegion.getMinY(); y <= zoneRegion.getMaxY(); ++y)
+			for (sint32 x = zoneRegion.getMinX(); x <= zoneRegion.getMaxX(); ++x)
+			{
+				const std::string &refZoneName = zoneRegion.getName(x, y);
+				if (refZoneName != STRING_UNUSED)
+				{
+					const std::string &zoneName = newZoneRegion.getName(x, y);
+					if ((zoneName != STRING_UNUSED) && (zoneName != STRING_OUT_OF_BOUND))
+						return false;
+				}
+			}
+	}
+	return true;
+}
+
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
index da5c2901f..17d5a6f7e 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h
@@ -38,6 +38,7 @@
 #include <QtCore/QString>
 #include <QtGui/QPixmap>
 #include <QtGui/QUndoStack>
+#include <QtGui/QGraphicsRectItem>
 
 namespace LandscapeEditor
 {
@@ -77,7 +78,7 @@ PixmapDatabase contains the graphics for the zones
 class ZoneBuilder
 {
 public:
-	ZoneBuilder(ListZonesWidget *listZonesWidget, LandscapeScene *landscapeScene, QUndoStack *undoStack);
+	ZoneBuilder(LandscapeScene *landscapeScene, ListZonesWidget *listZonesWidget = 0, QUndoStack *undoStack = 0);
 	~ZoneBuilder();
 
 	/// Init zoneBank and init zone pixmap database
@@ -88,18 +89,24 @@ public:
 	bool getZoneMask (sint32 x, sint32 y);
 	bool getZoneAmongRegions(ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y);
 
-	// Ligo Actions
+	/// Ligo Actions
+	/// @{
 	void actionLigoTile(const LigoData &data, const ZonePosition &zonePos);
 	void actionLigoMove(uint index, sint32 deltaX, sint32 deltaY);
 	void actionLigoResize(uint index, sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY);
+	/// @}
 
-	// Zone Bricks
+	/// Zone Bricks
+	/// @{
 	void addZone(sint32 posX, sint32 posY);
 	void addTransition(const sint32 posX, const sint32 posY);
 	void delZone(const sint32 posX, const sint32 posY);
+	/// @}
 
-	// Zone Region
+	/// Zone Region
+	/// @{
 	int createZoneRegion();
+	int createZoneRegion(const QString &fileName);
 	void deleteZoneRegion(int id);
 	void setCurrentZoneRegion(int id);
 	int currentIdZoneRegion() const;
@@ -108,6 +115,7 @@ public:
 	ZoneRegionObject *zoneRegion(int id) const;
 	void ligoData(LigoData &data, const ZonePosition &zonePos);
 	void setLigoData(LigoData &data, const ZonePosition &zonePos);
+	/// @}
 
 	// Accessors
 	NLLIGO::CZoneBank &getZoneBank()
@@ -127,15 +135,22 @@ private:
 	void checkBeginMacro();
 	void checkEndMacro();
 
+	bool checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion);
+
+	struct LandscapeItem
+	{
+		BuilderZoneRegion *builderZoneRegion;
+		ZoneRegionObject *zoneRegionObject;
+		QGraphicsRectItem *rectItem;
+	};
+
 	sint32 m_minX, m_maxX, m_minY, m_maxY;
 	std::vector<bool> m_zoneMask;
 
 	QString m_lastPathName;
 
-	QList<ZoneRegionObject *> m_zoneRegions;
 	int m_currentZoneRegion;
-
-	std::vector<BuilderZoneRegion *> m_builderZoneRegions;
+	std::vector<LandscapeItem> m_landscapeItems;
 
 	bool m_createdAction;
 	QString m_titleAction;
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp
index 2a4fc204a..b294ce97b 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp
@@ -35,7 +35,7 @@ BuilderZoneRegion::BuilderZoneRegion(uint regionId)
 {
 }
 
-bool BuilderZoneRegion::init(ZoneBuilder *zoneBuilder, std::string &error)
+bool BuilderZoneRegion::init(ZoneBuilder *zoneBuilder)
 {
 	if (m_firstInit)
 		return true;
@@ -264,7 +264,7 @@ void BuilderZoneRegion::add(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::C
 
 void BuilderZoneRegion::invertCutEdge(sint32 x, sint32 y, uint8 cePos)
 {
-	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion();
 	if ((x < zoneRegion.getMinX ()) || (x > zoneRegion.getMaxX ()) ||
 			(y < zoneRegion.getMinY ()) || (y > zoneRegion.getMaxY ()))
 		return;
@@ -371,7 +371,7 @@ void BuilderZoneRegion::invertCutEdge(sint32 x, sint32 y, uint8 cePos)
 
 void BuilderZoneRegion::cycleTransition(sint32 x, sint32 y)
 {
-	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion();
 	if ((x < zoneRegion.getMinX ()) || (x > zoneRegion.getMaxX ()) ||
 			(y < zoneRegion.getMinY ()) || (y > zoneRegion.getMaxY ()))
 		return;
@@ -391,7 +391,7 @@ void BuilderZoneRegion::cycleTransition(sint32 x, sint32 y)
 
 bool BuilderZoneRegion::addNotPropagate (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement)
 {
-	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion();
 	sint32 sizeX = zoneBankElement->getSizeX(), sizeY = zoneBankElement->getSizeY();
 	sint32 i, j;
 	NLLIGO::SPiece sMask, sPosX, sPosY;
@@ -472,7 +472,7 @@ bool BuilderZoneRegion::addNotPropagate (sint32 x, sint32 y, uint8 rot, uint8 fl
 
 void BuilderZoneRegion::addForce (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement)
 {
-	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion();
 	sint32 sizeX = zoneBankElement->getSizeX(), sizeY = zoneBankElement->getSizeY();
 	sint32 i, j;
 	NLLIGO::SPiece sMask, sPosX, sPosY;
@@ -636,7 +636,7 @@ uint8 TransToEdge[72][4] =
 
 void BuilderZoneRegion::addTransition (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement)
 {
-	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion();
 	uint32 i;
 	// Check that we write in an already defined place
 	if ((x < zoneRegion.getMinX ()) || (x > zoneRegion.getMaxX ()) ||
@@ -806,7 +806,7 @@ void BuilderZoneRegion::addTransition (sint32 x, sint32 y, uint8 rot, uint8 flip
 
 void BuilderZoneRegion::addToUpdateAndCreate(BuilderZoneRegion* builderZoneRegion, sint32 sharePos, sint32 x, sint32 y, const std::string &newMat, void *pInt1, void *pInt2)
 {
-	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion();
 	ToUpdate *ptCreate = reinterpret_cast<ToUpdate *>(pInt1);
 	ToUpdate *ptUpdate = reinterpret_cast<ToUpdate *>(pInt2);
 	sint32 stride = (1 + zoneRegion.getMaxX() - zoneRegion.getMinX());
@@ -831,7 +831,7 @@ void BuilderZoneRegion::addToUpdateAndCreate(BuilderZoneRegion* builderZoneRegio
 void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SPiece &mask, const std::string &matName,
 										void *pInternal)
 {
-	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion();
 	ToUpdate tCreate; // Transition to create
 	ToUpdate *ptUpdate = reinterpret_cast<ToUpdate *>(pInternal); // Transition to update
 
@@ -984,7 +984,7 @@ void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SP
 	// For all transition to update choose the cut edge
 	for (m = 0; m < (sint32)tCreate.size(); ++m)
 	{
-		const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->zoneRegion();
+		const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->ligoZoneRegion();
 		x = tCreate.getX(m);
 		y = tCreate.getY(m);
 
@@ -1145,7 +1145,7 @@ void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SP
 	// Finally update all transition
 	for (m = 0; m < (sint32)tCreate.size(); ++m)
 	{
-		const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->zoneRegion();
+		const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->ligoZoneRegion();
 		x = tCreate.getX(m);
 		y = tCreate.getY(m);
 
@@ -1155,7 +1155,7 @@ void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SP
 	}
 	for (m = 0; m < (sint32)ptUpdate->size(); ++m)
 	{
-		const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->zoneRegion();
+		const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->ligoZoneRegion();
 		x = ptUpdate->getX(m);
 		y = ptUpdate->getY(m);
 		if ((x >= zoneRegion2.getMinX()) && (x <= zoneRegion2.getMaxX()) &&
@@ -1166,7 +1166,7 @@ void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SP
 	// Cross material
 	for (m = 0; m < (sint32)tCreate.size(); ++m)
 	{
-		const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->zoneRegion();
+		const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->ligoZoneRegion();
 		x = tCreate.getX(m);
 		y = tCreate.getY(m);
 
@@ -1363,7 +1363,7 @@ STrans TranConvTable[128] =
 
 void BuilderZoneRegion::updateTrans (sint32 x, sint32 y, NLLIGO::CZoneBankElement *zoneBankElement)
 {
-	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion();
 	if ((x < zoneRegion.getMinX()) || (x > zoneRegion.getMaxX()) ||
 			(y < zoneRegion.getMinY()) || (y > zoneRegion.getMaxY()))
 		return;
@@ -1564,7 +1564,7 @@ void BuilderZoneRegion::updateTrans (sint32 x, sint32 y, NLLIGO::CZoneBankElemen
 
 std::string BuilderZoneRegion::getNextMatInTree (const std::string &matA, const std::string &matB)
 {
-	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion();
 	uint32 i, posA = 10000, posB = 10000;
 
 	if (matA == matB)
@@ -1600,7 +1600,7 @@ struct SNode
 
 void BuilderZoneRegion::tryPath(uint32 posA, uint32 posB, std::vector<uint32> &path)
 {
-	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion();
 
 	// Build the adjascence matrix
 	std::vector<sint32> matAdj;
@@ -1662,7 +1662,7 @@ void BuilderZoneRegion::tryPath(uint32 posA, uint32 posB, std::vector<uint32> &p
 
 void BuilderZoneRegion::del(sint32 x, sint32 y, bool transition, void *pInternal)
 {
-	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion();
 	if (!m_zoneBuilder->getZoneMask(x, y))
 		return;
 
@@ -1783,7 +1783,7 @@ void BuilderZoneRegion::move (sint32 x, sint32 y)
 
 uint32 BuilderZoneRegion::countZones ()
 {
-	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion();
 	sint32 x, y;
 
 	uint32 counter = 0;
@@ -1799,7 +1799,7 @@ uint32 BuilderZoneRegion::countZones ()
 void BuilderZoneRegion::set(sint32 x, sint32 y, sint32 posX, sint32 posY,
 							const std::string &zoneName, bool transition)
 {
-	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion();
 
 	// Do we need to resize ?
 	if ((x < zoneRegion.getMinX()) || (x > zoneRegion.getMaxX()) ||
@@ -1988,7 +1988,7 @@ void BuilderZoneRegion::setFlip(sint32 x, sint32 y, uint8 flip)
 
 void BuilderZoneRegion::reduceMin ()
 {
-	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion();
 	sint32 i, j;
 
 	sint32 newMinX = zoneRegion.getMinX(), newMinY = zoneRegion.getMinY ();
@@ -2099,7 +2099,7 @@ uint BuilderZoneRegion::getRegionId() const
 
 void BuilderZoneRegion::resize (sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY)
 {
-	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion();
+	const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion();
 	if ((zoneRegion.getMinX ()!= newMinX) ||
 			(zoneRegion.getMaxX ()!= newMaxX) ||
 			(zoneRegion.getMinY ()!= newMinY) ||
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h
index 7322e47b6..63656d643 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h
@@ -43,7 +43,7 @@ public:
 	BuilderZoneRegion(uint regionId);
 
 	// New interface
-	bool init(ZoneBuilder *zoneBuilder, std::string &error);
+	bool init(ZoneBuilder *zoneBuilder);
 	void add(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
 	void invertCutEdge(sint32 x, sint32 y, uint8 cePos);
 	void cycleTransition(sint32 x, sint32 y);
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
index 8aea79933..4fcf36efe 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp
@@ -114,7 +114,6 @@ void UndoScanRegionCommand::undo()
 {
 	for (int i = 0; i < m_zonePositionList.size(); ++i)
 		m_scene->deleteItemZone(m_zonePositionList.at(i));
-	nlinfo("------");
 	for (int i = 0; i < m_zonePositionList.size(); ++i)
 	{
 		LigoData data;
@@ -152,7 +151,6 @@ void RedoScanRegionCommand::redo()
 {
 	for (int i = 0; i < m_zonePositionList.size(); ++i)
 		m_scene->deleteItemZone(m_zonePositionList.at(i));
-	nlinfo("------");
 	for (int i = 0; i < m_zonePositionList.size(); ++i)
 	{
 		LigoData data;
@@ -174,7 +172,7 @@ LigoResizeCommand::LigoResizeCommand(int index, sint32 newMinX, sint32 newMaxX,
 	m_newMaxY = newMaxY;
 
 	// Backup old region zone
-	m_oldZoneRegion = m_zoneBuilder->zoneRegion(m_index)->zoneRegion();
+	m_oldZoneRegion = m_zoneBuilder->zoneRegion(m_index)->ligoZoneRegion();
 }
 
 LigoResizeCommand::~LigoResizeCommand()
@@ -184,13 +182,13 @@ LigoResizeCommand::~LigoResizeCommand()
 void LigoResizeCommand::undo ()
 {
 	// Restore old region zone
-	m_zoneBuilder->zoneRegion(m_index)->setZoneRegion(m_oldZoneRegion);
+	m_zoneBuilder->zoneRegion(m_index)->setLigoZoneRegion(m_oldZoneRegion);
 }
 
 void LigoResizeCommand::redo ()
 {
 	// Get the zone region
-	NLLIGO::CZoneRegion &region = m_zoneBuilder->zoneRegion(m_index)->zoneRegion();
+	NLLIGO::CZoneRegion &region = m_zoneBuilder->zoneRegion(m_index)->ligoZoneRegion();
 
 	sint32 i, j;
 	std::vector<LigoData> newZones;
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
index abfdcbd35..f2e2773be 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
@@ -34,6 +34,7 @@
 // Qt includes
 #include <QtCore/QSettings>
 #include <QtGui/QFileDialog>
+#include <QtGui/QMessageBox>
 
 namespace LandscapeEditor
 {
@@ -51,7 +52,7 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
 	m_undoStack = new QUndoStack(this);
 	m_landscapeScene = new LandscapeScene(this);
 
-	m_zoneBuilder = new ZoneBuilder(m_ui.zoneListWidget, m_landscapeScene, m_undoStack);
+	m_zoneBuilder = new ZoneBuilder(m_landscapeScene, m_ui.zoneListWidget, m_undoStack);
 	m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", true);
 	m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder);
 	m_ui.zoneListWidget->updateUi();
@@ -96,12 +97,15 @@ void LandscapeEditorWindow::open()
 		_lastDir = QFileInfo(list.front()).absolutePath();
 		Q_FOREACH(QString fileName, fileNames)
 		{
-			int id = m_zoneBuilder->createZoneRegion();
+			int id = m_zoneBuilder->createZoneRegion(fileName);
+			if (id == -1)
+			{
+				QMessageBox::critical(this, "Landscape Editor", "Cannot add this zone because it overlaps existing ones");
+				continue;
+			}
 			ZoneRegionObject *zoneRegion = m_zoneBuilder->zoneRegion(id);
-			zoneRegion->load(fileName.toStdString());
-			m_landscapeScene->processZoneRegion(zoneRegion->zoneRegion());
-			m_ui.graphicsView->centerOn(zoneRegion->zoneRegion().getMinX() * m_landscapeScene->cellSize(),
-										abs(zoneRegion->zoneRegion().getMinY()) * m_landscapeScene->cellSize());
+			m_ui.graphicsView->centerOn(zoneRegion->ligoZoneRegion().getMinX() * m_landscapeScene->cellSize(),
+										abs(zoneRegion->ligoZoneRegion().getMinY()) * m_landscapeScene->cellSize());
 
 			m_zoneBuilder->setCurrentZoneRegion(id);
 		}
@@ -157,7 +161,8 @@ void LandscapeEditorWindow::openSnapshotDialog()
 void LandscapeEditorWindow::showEvent(QShowEvent *showEvent)
 {
 	QMainWindow::showEvent(showEvent);
-	m_oglWidget->makeCurrent();
+	if (m_oglWidget != 0)
+		m_oglWidget->makeCurrent();
 }
 
 void LandscapeEditorWindow::createMenus()
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
index 65316d9f7..82606f74a 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
@@ -17,6 +17,7 @@
 
 // Project includes
 #include "landscape_scene.h"
+#include "pixmap_database.h"
 
 // NeL includes
 #include <nel/misc/debug.h>
@@ -29,7 +30,10 @@
 namespace LandscapeEditor
 {
 
-static const int ZoneName = 0;
+static const int ZONE_NAME = 0;
+static const int LAYER_ZONES = 2;
+static const int LAYER_EMPTY_ZONES = 3;
+static const int LAYER_BLACKOUT = 4;
 
 LandscapeScene::LandscapeScene(QObject *parent)
 	: QGraphicsScene(parent),
@@ -78,19 +82,18 @@ QGraphicsItem *LandscapeScene::createItemZone(const LigoData &data, const ZonePo
 
 	if (data.flip == 0)
 	{
-		item = new QGraphicsPixmapItem(pixmap->transformed(matrix, Qt::SmoothTransformation), 0, this);
+		item = addPixmap(pixmap->transformed(matrix, Qt::SmoothTransformation));
 	}
 	else
 	{
 		// mirror image
 		QImage mirrorImage = pixmap->toImage();
 		QPixmap mirrorPixmap = QPixmap::fromImage(mirrorImage.mirrored(true, false));
-		item = new QGraphicsPixmapItem(mirrorPixmap.transformed(matrix, Qt::SmoothTransformation), 0, this);
+		item = addPixmap(mirrorPixmap.transformed(matrix, Qt::SmoothTransformation));
 	}
 	// Enable bilinear filtering
 	item->setTransformationMode(Qt::SmoothTransformation);
 
-	// Set position graphics item with offset for large piece
 	NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.zoneName);
 
 	sint32 deltaX = 0, deltaY = 0;
@@ -145,16 +148,16 @@ QGraphicsItem *LandscapeScene::createItemZone(const LigoData &data, const ZonePo
 		}
 	}
 
-	// set position graphics item with taking into account the offset
+	// Set position graphics item with offset for large piece
 	item->setPos((zonePos.x + deltaX) * m_cellSize, (abs(int(zonePos.y + deltaY))) * m_cellSize);
 
 	// The size graphics item should be equal or proportional m_cellSize
 	item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize());
 
-	item->setData(ZoneName, QString(data.zoneName.c_str()));
+	//item->setData(ZONE_NAME, QString(data.zoneName.c_str()));
 
 	// for not full item zone
-	item->setZValue(0);
+	item->setZValue(LAYER_ZONES);
 
 	return item;
 }
@@ -169,7 +172,7 @@ QGraphicsItem *LandscapeScene::createItemEmptyZone(const ZonePosition &zonePos)
 	if (pixmap == 0)
 		return 0;
 
-	QGraphicsPixmapItem *item = new QGraphicsPixmapItem(*pixmap, 0, this);
+	QGraphicsPixmapItem *item = addPixmap(*pixmap);
 
 	// Enable bilinear filtering
 	item->setTransformationMode(Qt::SmoothTransformation);
@@ -181,11 +184,23 @@ QGraphicsItem *LandscapeScene::createItemEmptyZone(const ZonePosition &zonePos)
 	item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize());
 
 	// for not full item zone
-	item->setZValue(1);
+	item->setZValue(LAYER_EMPTY_ZONES);
 
 	return item;
 }
 
+QGraphicsRectItem *LandscapeScene::createLayerBlackout(const NLLIGO::CZoneRegion &zoneRegion)
+{
+	QGraphicsRectItem *rectItem = addRect(zoneRegion.getMinX() * m_cellSize,
+										  abs(zoneRegion.getMaxY()) * m_cellSize,
+										  (abs(zoneRegion.getMaxX() - zoneRegion.getMinX()) + 1) * m_cellSize,
+										  (abs(zoneRegion.getMaxY() - zoneRegion.getMinY()) + 1) * m_cellSize,
+										  Qt::NoPen, QBrush(QColor(0, 0, 0, 50)));
+
+	rectItem->setZValue(LAYER_BLACKOUT);
+	return rectItem;
+}
+
 void LandscapeScene::deleteItemZone(const ZonePosition &zonePos)
 {
 	QGraphicsItem *item = itemAt(zonePos.x * m_cellSize, abs(zonePos.y) * m_cellSize);
@@ -196,12 +211,13 @@ void LandscapeScene::deleteItemZone(const ZonePosition &zonePos)
 	}
 }
 
-void LandscapeScene::processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
+void LandscapeScene::addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
 {
 	for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i)
 	{
 		for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
 		{
+
 			//nlinfo(QString("%1 %2 %3").arg(i).arg(j).arg(zoneRegion.getName(i, j).c_str()).toStdString().c_str());
 			std::string zoneName = zoneRegion.getName(i, j);
 			if (zoneName == STRING_UNUSED)
@@ -224,6 +240,17 @@ void LandscapeScene::processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
 	}
 }
 
+void LandscapeScene::delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
+{
+	for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i)
+	{
+		for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
+		{
+			deleteItemZone(ZonePosition(i, -j, -1));
+		}
+	}
+}
+
 void LandscapeScene::snapshot(const QString &fileName, int sizeSource)
 {
 	/*	if (m_zoneRegion == 0)
@@ -305,7 +332,9 @@ bool LandscapeScene::checkUnderZone(const int posX, const int posY)
 {
 	QGraphicsItem *item = itemAt((posX * m_cellSize), abs(posY) * m_cellSize);
 	if (item != 0)
+	{
 		return true;
+	}
 	return false;
 }
 
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
index 525971999..7e60febaf 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
@@ -21,6 +21,7 @@
 // Project includes
 #include "zone_region_editor.h"
 #include "builder_zone.h"
+#include "landscape_editor_global.h"
 
 // NeL includes
 #include <nel/ligo/zone_region.h>
@@ -32,7 +33,12 @@
 namespace LandscapeEditor
 {
 
-class LandscapeScene : public QGraphicsScene
+/**
+@class LandscapeScene
+@brief
+@details
+*/
+class LANDSCAPE_EDITOR_EXPORT LandscapeScene : public QGraphicsScene
 {
 	Q_OBJECT
 
@@ -45,15 +51,18 @@ public:
 
 	QGraphicsItem *createItemZone(const LigoData &data, const ZonePosition &zonePos);
 	QGraphicsItem *createItemEmptyZone(const ZonePosition &zonePos);
+	QGraphicsRectItem *createLayerBlackout(const NLLIGO::CZoneRegion &zoneRegion);
 	void deleteItemZone(const ZonePosition &zonePos);
-	void processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
+
+	void addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
+	void delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
 
 	void snapshot(const QString &fileName, int sizeSource);
 	void snapshot(const QString &fileName, int width, int height);
 
 protected:
 	virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
-	virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent);
+	virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
 	virtual void drawForeground(QPainter *painter, const QRectF &rect);
 
 private:
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
index e32f4ae6d..84bc4b47d 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp
@@ -41,6 +41,7 @@ LandscapeView::LandscapeView(QWidget *parent)
 	setBackgroundBrush(QBrush(Qt::lightGray));
 	//setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
 	//setRenderHints(QPainter::Antialiasing);
+	//setCacheMode(QGraphicsView::CacheBackground);
 	m_cellSize = 160;
 	m_numSteps = 0;
 	m_maxSteps = 20;
@@ -83,6 +84,7 @@ void LandscapeView::wheelEvent(QWheelEvent *event)
 		--m_numSteps;
 	}
 	scale(factor, factor);
+	QGraphicsView::wheelEvent(event);
 }
 
 void LandscapeView::mousePressEvent(QMouseEvent *event)

From 46b4ff3a6dad79a4da5eda46b53a55cc6f28c7f3 Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Wed, 6 Jul 2011 04:38:38 +0300
Subject: [PATCH 18/19] Changed: #1301 Completed snapshot dialog.

---
 .../landscape_editor_window.cpp               | 28 +++++++++-
 .../landscape_editor/landscape_scene.cpp      | 54 +++++--------------
 .../landscape_editor/landscape_scene.h        |  3 +-
 .../landscape_editor/shapshot_dialog.ui       | 40 +++++++++-----
 .../landscape_editor/snapshot_dialog.cpp      | 26 +++++++++
 .../landscape_editor/snapshot_dialog.h        |  6 +++
 6 files changed, 100 insertions(+), 57 deletions(-)

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
index f2e2773be..5f5fad552 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
@@ -152,7 +152,33 @@ void LandscapeEditorWindow::openSnapshotDialog()
 						   tr("Image file (*.png)"));
 
 		setCursor(Qt::WaitCursor);
-		m_landscapeScene->snapshot(fileName, 128);
+
+		NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->currentZoneRegion()->ligoZoneRegion();
+		sint32 regionMinX = zoneRegion.getMinX();
+		sint32 regionMaxX = zoneRegion.getMaxX();
+		sint32 regionMinY = zoneRegion.getMinY();
+		sint32 regionMaxY = zoneRegion.getMaxY();
+
+		int regionWidth = (regionMaxX - regionMinX + 1);
+		int regionHeight = (regionMaxY - regionMinY + 1);
+
+		int cellSize = m_landscapeScene->cellSize();
+		QRectF rect(regionMinX * cellSize, abs(regionMaxY) * cellSize, regionWidth * cellSize, regionHeight * cellSize);
+
+		if (dialog->isCustomSize())
+		{
+			int widthSnapshot = dialog->widthSnapshot();
+			int heightSnapshot = dialog->heightSnapshot();
+			if (dialog->isKeepRatio())
+				heightSnapshot = (widthSnapshot / regionWidth) * regionHeight;
+
+			m_landscapeScene->snapshot(fileName, widthSnapshot, heightSnapshot, rect);
+		}
+		else
+		{
+			m_landscapeScene->snapshot(fileName, regionWidth * dialog->resolutionZone(),
+									   regionHeight * dialog->resolutionZone(), rect);
+		}
 		setCursor(Qt::ArrowCursor);
 	}
 	delete dialog;
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
index 82606f74a..81a94fb1f 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp
@@ -218,7 +218,6 @@ void LandscapeScene::addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
 		for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
 		{
 
-			//nlinfo(QString("%1 %2 %3").arg(i).arg(j).arg(zoneRegion.getName(i, j).c_str()).toStdString().c_str());
 			std::string zoneName = zoneRegion.getName(i, j);
 			if (zoneName == STRING_UNUSED)
 			{
@@ -251,53 +250,26 @@ void LandscapeScene::delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
 	}
 }
 
-void LandscapeScene::snapshot(const QString &fileName, int sizeSource)
-{
-	/*	if (m_zoneRegion == 0)
-			return;
-
-		sint32 regionMinX = m_zoneRegion->getMinX();
-		sint32 regionMaxX = m_zoneRegion->getMaxX();
-		sint32 regionMinY = m_zoneRegion->getMinY();
-		sint32 regionMaxY = m_zoneRegion->getMaxY();
-
-		int regionWidth = (regionMaxX - regionMinX + 1);
-		int regionHeight = (regionMaxY - regionMinY + 1);
-
-		snapshot(fileName, regionWidth * sizeSource, regionHeight * sizeSource);
-		*/
-}
-
-void LandscapeScene::snapshot(const QString &fileName, int width, int height)
+void LandscapeScene::snapshot(const QString &fileName, int width, int height, const QRectF &landRect)
 {
 	if (m_zoneBuilder == 0)
 		return;
 
-	/*	if (m_zoneRegion == 0)
-			return;
+	// Create image
+	QImage image(landRect.width(), landRect.height(), QImage::Format_RGB888);
+	QPainter painter(&image);
+	painter.setRenderHint(QPainter::Antialiasing, true);
 
-		sint32 regionMinX = m_zoneRegion->getMinX();
-		sint32 regionMaxX = m_zoneRegion->getMaxX();
-		sint32 regionMinY = m_zoneRegion->getMinY();
-		sint32 regionMaxY = m_zoneRegion->getMaxY();
+	// Add white background
+	painter.setBrush(QBrush(Qt::white));
+	painter.setPen(Qt::NoPen);
+	painter.drawRect(0, 0, landRect.width(), landRect.height());
 
-		int regionWidth = (regionMaxX - regionMinX + 1);
-		int regionHeight = (regionMaxY - regionMinY + 1);
+	// Paint landscape
+	render(&painter, QRectF(0, 0, landRect.width(), landRect.height()), landRect);
 
-		QImage image(width, height, QImage::Format_RGB888);
-		QPainter painter(&image);
-		painter.setRenderHint(QPainter::Antialiasing, true);
-
-		// add white background
-		painter.setBrush(QBrush(Qt::white));
-		painter.setPen(Qt::NoPen);
-		painter.drawRect(0, 0, width, height);
-
-		render(&painter, QRectF(0, 0, width, height),
-			   QRectF(regionMinX * m_cellSize, abs(regionMaxY) * m_cellSize, regionWidth * m_cellSize, regionHeight * m_cellSize));
-
-		image.save(fileName);
-	*/
+	QImage scaledImage = image.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+	scaledImage.save(fileName);
 }
 
 void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
index 7e60febaf..34fe50e05 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h
@@ -57,8 +57,7 @@ public:
 	void addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
 	void delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
 
-	void snapshot(const QString &fileName, int sizeSource);
-	void snapshot(const QString &fileName, int width, int height);
+	void snapshot(const QString &fileName, int width, int height, const QRectF &landRect);
 
 protected:
 	virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui
index 792d9f7a4..1c25a2ace 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>286</width>
-    <height>182</height>
+    <width>230</width>
+    <height>187</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -15,19 +15,33 @@
   </property>
   <layout class="QGridLayout" name="gridLayout_2">
    <item row="0" column="0">
-    <widget class="QRadioButton" name="originalSizeRadioButton">
-     <property name="text">
-      <string>Original size</string>
-     </property>
-     <property name="checked">
-      <bool>true</bool>
-     </property>
-    </widget>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QRadioButton" name="originalSizeRadioButton">
+       <property name="text">
+        <string>Original size</string>
+       </property>
+       <property name="checked">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QSpinBox" name="resSpinBox">
+       <property name="maximum">
+        <number>1024</number>
+       </property>
+       <property name="value">
+        <number>128</number>
+       </property>
+      </widget>
+     </item>
+    </layout>
    </item>
    <item row="1" column="0">
     <widget class="QRadioButton" name="customSizeRadioButton">
      <property name="enabled">
-      <bool>false</bool>
+      <bool>true</bool>
      </property>
      <property name="text">
       <string>Custom size</string>
@@ -59,7 +73,7 @@
          <bool>false</bool>
         </property>
         <property name="text">
-         <string>TextLabel</string>
+         <string>Height:</string>
         </property>
         <property name="buddy">
          <cstring>heightSpinBox</cstring>
@@ -82,7 +96,7 @@
       <item row="0" column="0">
        <widget class="QLabel" name="label">
         <property name="text">
-         <string>TextLabel</string>
+         <string>Width:</string>
         </property>
         <property name="buddy">
          <cstring>widthSpinBox</cstring>
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp
index ff6ef1673..ab2579722 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp
@@ -36,10 +36,36 @@ SnapshotDialog::SnapshotDialog(QWidget *parent)
 	: QDialog(parent)
 {
 	m_ui.setupUi(this);
+	setFixedHeight(sizeHint().height());
 }
 
 SnapshotDialog::~SnapshotDialog()
 {
 }
 
+bool SnapshotDialog::isCustomSize() const
+{
+	return m_ui.customSizeRadioButton->isChecked();
+}
+
+bool SnapshotDialog::isKeepRatio() const
+{
+	return m_ui.keepRatioCheckBox->isChecked();
+}
+
+int SnapshotDialog::resolutionZone() const
+{
+	return m_ui.resSpinBox->value();
+}
+
+int SnapshotDialog::widthSnapshot() const
+{
+	return m_ui.widthSpinBox->value();
+}
+
+int SnapshotDialog::heightSnapshot() const
+{
+	return m_ui.heightSpinBox->value();
+}
+
 } /* namespace LandscapeEditor */
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h
index 906d59498..b66133a07 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h
@@ -34,6 +34,12 @@ public:
 	SnapshotDialog(QWidget *parent = 0);
 	~SnapshotDialog();
 
+	bool isCustomSize() const;
+	bool isKeepRatio() const;
+	int resolutionZone() const;
+	int widthSnapshot() const;
+	int heightSnapshot() const;
+
 private Q_SLOTS:
 
 

From 90464fa2f288bf6b567d934ac909b9e7bcf0a468 Mon Sep 17 00:00:00 2001
From: dnk-88 <devnull@localhost>
Date: Wed, 6 Jul 2011 18:52:10 +0300
Subject: [PATCH 19/19] Changed: #1301 Added dialog with a list of landscapes
 and operations (setActive, save, saveAs, delete).

---
 .../plugins/landscape_editor/builder_zone.cpp |  10 +-
 .../landscape_editor_window.cpp               | 191 ++++++++++++++++--
 .../landscape_editor_window.h                 |  11 +
 .../landscape_editor_window.ui                |  81 +++++++-
 4 files changed, 265 insertions(+), 28 deletions(-)

diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
index 265e380ca..9550b1f76 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp
@@ -222,10 +222,11 @@ void ZoneBuilder::deleteZoneRegion(int id)
 {
 	if ((0 <= id) && (id < int(m_landscapeItems.size())))
 	{
+		if (m_landscapeItems.at(id).rectItem != 0)
+			delete m_landscapeItems.at(id).rectItem;
 		m_landscapeScene->delZoneRegion(m_landscapeItems.at(id).zoneRegionObject->ligoZoneRegion());
 		delete m_landscapeItems.at(id).zoneRegionObject;
 		delete m_landscapeItems.at(id).builderZoneRegion;
-		delete m_landscapeItems.at(id).rectItem;
 		m_landscapeItems.erase(m_landscapeItems.begin() + id);
 		calcMask();
 	}
@@ -236,10 +237,13 @@ void ZoneBuilder::setCurrentZoneRegion(int id)
 	if ((0 <= id) && (id < int(m_landscapeItems.size())))
 	{
 		if (currentIdZoneRegion() != -1)
-			m_landscapeItems.at(m_currentZoneRegion).rectItem = m_landscapeScene->createLayerBlackout(currentZoneRegion()->ligoZoneRegion());
-		m_currentZoneRegion = id;
+		{
+			NLLIGO::CZoneRegion &ligoRegion = m_landscapeItems.at(m_currentZoneRegion).zoneRegionObject->ligoZoneRegion();
+			m_landscapeItems.at(m_currentZoneRegion).rectItem = m_landscapeScene->createLayerBlackout(ligoRegion);
+		}
 		delete m_landscapeItems.at(id).rectItem;
 		m_landscapeItems.at(id).rectItem = 0;
+		m_currentZoneRegion = id;
 	}
 }
 
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
index 5f5fad552..da949fea5 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp
@@ -33,15 +33,20 @@
 
 // Qt includes
 #include <QtCore/QSettings>
+#include <QtGui/QMenu>
 #include <QtGui/QFileDialog>
 #include <QtGui/QMessageBox>
 
 namespace LandscapeEditor
 {
+
+static const int LANDSCAPE_ID = 32;
+int NewLandCounter = 0;
 QString _lastDir;
 
 LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
 	: QMainWindow(parent),
+	  m_currentRow(-1),
 	  m_landscapeScene(0),
 	  m_zoneBuilder(0),
 	  m_undoStack(0),
@@ -53,7 +58,7 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
 	m_landscapeScene = new LandscapeScene(this);
 
 	m_zoneBuilder = new ZoneBuilder(m_landscapeScene, m_ui.zoneListWidget, m_undoStack);
-	m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", true);
+	m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", false);
 	m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder);
 	m_ui.zoneListWidget->updateUi();
 
@@ -63,6 +68,12 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
 	m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers));
 	m_ui.graphicsView->setViewport(m_oglWidget);
 
+	m_ui.newLandAction->setIcon(QIcon(Core::Constants::ICON_NEW));
+	m_ui.saveAction->setIcon(QIcon(Core::Constants::ICON_SAVE));
+	m_ui.saveLandAction->setIcon(QIcon(Core::Constants::ICON_SAVE));
+	m_ui.saveAsLandAction->setIcon(QIcon(Core::Constants::ICON_SAVE_AS));
+	m_ui.deleteLandAction->setEnabled(false);
+
 	createMenus();
 	createToolBars();
 	readSettings();
@@ -71,6 +82,16 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
 	connect(m_ui.projectSettingsAction, SIGNAL(triggered()), this, SLOT(openProjectSettings()));
 	connect(m_ui.snapshotAction, SIGNAL(triggered()), this, SLOT(openSnapshotDialog()));
 	connect(m_ui.enableGridAction, SIGNAL(toggled(bool)), m_ui.graphicsView, SLOT(setVisibleGrid(bool)));
+
+	connect(m_ui.newLandAction, SIGNAL(triggered()), this, SLOT(newLand()));
+	connect(m_ui.setActiveLandAction, SIGNAL(triggered()), this, SLOT(setActiveLand()));
+	connect(m_ui.saveLandAction, SIGNAL(triggered()), this, SLOT(saveSelectedLand()));
+	connect(m_ui.saveAsLandAction, SIGNAL(triggered()), this, SLOT(saveAsSelectedLand()));
+	connect(m_ui.deleteLandAction, SIGNAL(triggered()), this, SLOT(deleteSelectedLand()));
+
+	connect(m_ui.landscapesListWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customContextMenu()));
+	m_ui.landscapesListWidget->setContextMenuPolicy(Qt::CustomContextMenu);
+
 }
 
 LandscapeEditorWindow::~LandscapeEditorWindow()
@@ -97,17 +118,9 @@ void LandscapeEditorWindow::open()
 		_lastDir = QFileInfo(list.front()).absolutePath();
 		Q_FOREACH(QString fileName, fileNames)
 		{
-			int id = m_zoneBuilder->createZoneRegion(fileName);
-			if (id == -1)
-			{
-				QMessageBox::critical(this, "Landscape Editor", "Cannot add this zone because it overlaps existing ones");
-				continue;
-			}
-			ZoneRegionObject *zoneRegion = m_zoneBuilder->zoneRegion(id);
-			m_ui.graphicsView->centerOn(zoneRegion->ligoZoneRegion().getMinX() * m_landscapeScene->cellSize(),
-										abs(zoneRegion->ligoZoneRegion().getMinY()) * m_landscapeScene->cellSize());
-
-			m_zoneBuilder->setCurrentZoneRegion(id);
+			int row = createLandscape(fileName);
+			if (row != -1)
+				setActiveLandscape(row);
 		}
 	}
 	setCursor(Qt::ArrowCursor);
@@ -115,16 +128,7 @@ void LandscapeEditorWindow::open()
 
 void LandscapeEditorWindow::save()
 {
-	ZoneRegionObject *zoneRegion = m_zoneBuilder->currentZoneRegion();
-	if (zoneRegion->fileName().empty())
-	{
-		QString fileName = QFileDialog::getSaveFileName(this,
-						   tr("Save NeL Ligo land file"), _lastDir,
-						   tr("NeL Ligo land file (*.land)"));
-		if (!fileName.isEmpty())
-			zoneRegion->setFileName(fileName.toStdString());
-	}
-	zoneRegion->save();
+	saveLandscape(m_currentRow, true);
 }
 
 void LandscapeEditorWindow::openProjectSettings()
@@ -184,6 +188,133 @@ void LandscapeEditorWindow::openSnapshotDialog()
 	delete dialog;
 }
 
+void LandscapeEditorWindow::customContextMenu()
+{
+	if (m_ui.landscapesListWidget->currentRow() == -1)
+		return;
+	QMenu *popurMenu = new QMenu(this);
+	popurMenu->addAction(m_ui.setActiveLandAction);
+	popurMenu->addAction(m_ui.saveLandAction);
+	popurMenu->addAction(m_ui.saveAsLandAction);
+	popurMenu->addAction(m_ui.deleteLandAction);
+	popurMenu->exec(QCursor::pos());
+	delete popurMenu;
+}
+
+void LandscapeEditorWindow::newLand()
+{
+	createLandscape(QString());
+}
+
+void LandscapeEditorWindow::setActiveLand()
+{
+	setActiveLandscape(m_ui.landscapesListWidget->currentRow());
+}
+
+void LandscapeEditorWindow::saveSelectedLand()
+{
+	saveLandscape(m_ui.landscapesListWidget->currentRow(), true);
+}
+
+void LandscapeEditorWindow::saveAsSelectedLand()
+{
+	saveLandscape(m_ui.landscapesListWidget->currentRow(), false);
+}
+
+void LandscapeEditorWindow::deleteSelectedLand()
+{
+	int row = m_ui.landscapesListWidget->currentRow();
+	QListWidgetItem *item = m_ui.landscapesListWidget->item(row);
+	if (row == m_currentRow)
+	{
+		if (row == 0)
+			++row;
+		else
+			--row;
+		setActiveLandscape(row);
+	}
+	m_zoneBuilder->deleteZoneRegion(item->data(LANDSCAPE_ID).toInt());
+	m_ui.landscapesListWidget->removeItemWidget(item);
+	delete item;
+	if (m_ui.landscapesListWidget->count() == 1)
+		m_ui.deleteLandAction->setEnabled(false);
+}
+
+int LandscapeEditorWindow::createLandscape(const QString &fileName)
+{
+	int id;
+	if (fileName.isEmpty())
+		id = m_zoneBuilder->createZoneRegion();
+	else
+		id = m_zoneBuilder->createZoneRegion(fileName);
+
+	if (id == -1)
+	{
+		QMessageBox::critical(this, "Landscape Editor", "Cannot add this zone because it overlaps existing ones");
+		return -1;
+	}
+	ZoneRegionObject *zoneRegion = m_zoneBuilder->zoneRegion(id);
+	m_ui.graphicsView->centerOn(zoneRegion->ligoZoneRegion().getMinX() * m_landscapeScene->cellSize(),
+								abs(zoneRegion->ligoZoneRegion().getMinY()) * m_landscapeScene->cellSize());
+
+	QListWidgetItem *item;
+	if (fileName.isEmpty())
+		item = new QListWidgetItem(QString("NewLandscape%1").arg(NewLandCounter++), m_ui.landscapesListWidget);
+	else
+		item = new QListWidgetItem(fileName, m_ui.landscapesListWidget);
+
+	item->setData(LANDSCAPE_ID, id);
+	item->setFont(QFont("SansSerif", 9, QFont::Normal));
+
+	if (m_ui.landscapesListWidget->count() > 1)
+		m_ui.deleteLandAction->setEnabled(true);
+
+	return m_ui.landscapesListWidget->count() - 1;
+}
+
+void LandscapeEditorWindow::setActiveLandscape(int row)
+{
+	if ((0 <= row) && (row < m_ui.landscapesListWidget->count()))
+	{
+		if (m_currentRow != -1)
+		{
+			QListWidgetItem *item = m_ui.landscapesListWidget->item(m_currentRow);
+			item->setFont(QFont("SansSerif", 9, QFont::Normal));
+		}
+		QListWidgetItem *item = m_ui.landscapesListWidget->item(row);
+		item->setFont(QFont("SansSerif", 9, QFont::Bold));
+		m_zoneBuilder->setCurrentZoneRegion(item->data(LANDSCAPE_ID).toInt());
+		m_currentRow = row;
+	}
+}
+
+void LandscapeEditorWindow::saveLandscape(int row, bool force)
+{
+	if ((0 <= row) && (row < m_ui.landscapesListWidget->count()))
+	{
+		QListWidgetItem *item = m_ui.landscapesListWidget->item(row);
+		ZoneRegionObject *regionObject = m_zoneBuilder->zoneRegion(item->data(LANDSCAPE_ID).toInt());
+		if ((!force) || (regionObject->fileName().empty()))
+		{
+			QString fileName = QFileDialog::getSaveFileName(this,
+							   tr("Save NeL Ligo land file"), _lastDir,
+							   tr("NeL Ligo land file (*.land)"));
+			if (!fileName.isEmpty())
+			{
+				regionObject->setFileName(fileName.toStdString());
+				regionObject->save();
+				regionObject->setModified(false);
+				item->setText(fileName);
+			}
+		}
+		else
+		{
+			regionObject->save();
+			regionObject->setModified(false);
+		}
+	}
+}
+
 void LandscapeEditorWindow::showEvent(QShowEvent *showEvent)
 {
 	QMainWindow::showEvent(showEvent);
@@ -202,7 +333,23 @@ void LandscapeEditorWindow::createToolBars()
 	//QAction *action = menuManager->action(Core::Constants::NEW);
 	//m_ui.fileToolBar->addAction(action);
 	QAction *action = menuManager->action(Core::Constants::OPEN);
+	m_ui.fileToolBar->addAction(m_ui.newLandAction);
 	m_ui.fileToolBar->addAction(action);
+	m_ui.fileToolBar->addAction(m_ui.saveAction);
+
+	const char * const UNDO = "ObjectViewerQt.Undo";
+	const char * const REDO = "ObjectViewerQt.Redo";
+
+	//action = menuManager->action(Core::Constants::UNDO);
+	action = menuManager->action(UNDO);
+	if (action != 0)
+		m_ui.undoToolBar->addAction(action);
+
+	//action = menuManager->action(Core::Constants::REDO);
+	action = menuManager->action(REDO);
+	if (action != 0)
+		m_ui.undoToolBar->addAction(action);
+
 	//action = menuManager->action(Core::Constants::SAVE);
 	//m_ui.fileToolBar->addAction(action);
 	//action = menuManager->action(Core::Constants::SAVE_AS);
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
index ff9cfd273..f3421f120 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h
@@ -49,6 +49,12 @@ public Q_SLOTS:
 private Q_SLOTS:
 	void openProjectSettings();
 	void openSnapshotDialog();
+	void customContextMenu();
+	void newLand();
+	void setActiveLand();
+	void saveSelectedLand();
+	void saveAsSelectedLand();
+	void deleteSelectedLand();
 
 protected:
 	virtual void showEvent(QShowEvent *showEvent);
@@ -59,6 +65,11 @@ private:
 	void readSettings();
 	void writeSettings();
 
+	void setActiveLandscape(int row);
+	void saveLandscape(int row, bool force);
+	int createLandscape(const QString &fileName);
+
+	int m_currentRow;
 	LandscapeScene *m_landscapeScene;
 	ZoneBuilder *m_zoneBuilder;
 	QUndoStack *m_undoStack;
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
index 57eadda73..7d71acd49 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui
@@ -62,7 +62,7 @@
    </attribute>
    <widget class="LandscapeEditor::ListZonesWidget" name="zoneListWidget"/>
   </widget>
-  <widget class="QToolBar" name="landToolBar">
+  <widget class="QToolBar" name="undoToolBar">
    <property name="windowTitle">
     <string>toolBar_2</string>
    </property>
@@ -72,9 +72,40 @@
    <attribute name="toolBarBreak">
     <bool>false</bool>
    </attribute>
-   <addaction name="saveAction"/>
-   <addaction name="snapshotAction"/>
+  </widget>
+  <widget class="QDockWidget" name="landscapesDockWidget">
+   <property name="windowTitle">
+    <string>Landscapes</string>
+   </property>
+   <attribute name="dockWidgetArea">
+    <number>1</number>
+   </attribute>
+   <widget class="QWidget" name="dockWidgetContents">
+    <layout class="QGridLayout" name="gridLayout_2">
+     <property name="margin">
+      <number>3</number>
+     </property>
+     <property name="spacing">
+      <number>3</number>
+     </property>
+     <item row="0" column="0">
+      <widget class="QListWidget" name="landscapesListWidget"/>
+     </item>
+    </layout>
+   </widget>
+  </widget>
+  <widget class="QToolBar" name="zoneToolBar">
+   <property name="windowTitle">
+    <string>toolBar</string>
+   </property>
+   <attribute name="toolBarArea">
+    <enum>TopToolBarArea</enum>
+   </attribute>
+   <attribute name="toolBarBreak">
+    <bool>false</bool>
+   </attribute>
    <addaction name="projectSettingsAction"/>
+   <addaction name="snapshotAction"/>
    <addaction name="enableGridAction"/>
   </widget>
   <action name="projectSettingsAction">
@@ -113,6 +144,50 @@
     <string>Save</string>
    </property>
   </action>
+  <action name="setActiveLandAction">
+   <property name="icon">
+    <iconset resource="landscape_editor.qrc">
+     <normaloff>:/icons/ic_nel_zone.png</normaloff>:/icons/ic_nel_zone.png</iconset>
+   </property>
+   <property name="text">
+    <string>Set active</string>
+   </property>
+   <property name="toolTip">
+    <string>Set active selected landscape</string>
+   </property>
+  </action>
+  <action name="saveLandAction">
+   <property name="text">
+    <string>Save</string>
+   </property>
+   <property name="toolTip">
+    <string>Save selected landscape</string>
+   </property>
+  </action>
+  <action name="saveAsLandAction">
+   <property name="text">
+    <string>Save As landscape</string>
+   </property>
+   <property name="toolTip">
+    <string>Save as selected landscape</string>
+   </property>
+  </action>
+  <action name="deleteLandAction">
+   <property name="text">
+    <string>Delete</string>
+   </property>
+   <property name="toolTip">
+    <string>Delete selected landscape</string>
+   </property>
+  </action>
+  <action name="newLandAction">
+   <property name="text">
+    <string>New</string>
+   </property>
+   <property name="toolTip">
+    <string>Create new landscape</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>