summaryrefslogtreecommitdiffstats
path: root/tools/designer
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>2011-03-22 10:27:47 +0100
committerFriedemann Kleint <Friedemann.Kleint@nokia.com>2011-03-22 10:27:47 +0100
commitaf617c319772a34115d0c4d802f25a807cb43065 (patch)
treeb6e326871c2ddbdc26d9dd1246d72847680830a6 /tools/designer
parent8a9dd3f463a312963dc420ee83ca75fd52e24463 (diff)
Designer: Avoid nested QDialog's in item widget content dialogs.
Refactor the AbstractItemEditor to be a QWidget instead of a dialog as it is used for the Rows/Columns of trees, tables as well, creating a hierarchy of nested QDialogs. The nested QDialogs cause some of the crashes observed with transparent styles using event filters accessing QWidget::window() in QEvent::Hide event filters. Task-number: QTBUG-18222
Diffstat (limited to 'tools/designer')
-rw-r--r--tools/designer/src/components/taskmenu/itemlisteditor.cpp29
-rw-r--r--tools/designer/src/components/taskmenu/itemlisteditor.h10
-rw-r--r--tools/designer/src/components/taskmenu/listwidgeteditor.h2
-rw-r--r--tools/designer/src/components/taskmenu/tablewidget_taskmenu.cpp2
-rw-r--r--tools/designer/src/components/taskmenu/tablewidgeteditor.cpp73
-rw-r--r--tools/designer/src/components/taskmenu/tablewidgeteditor.h18
-rw-r--r--tools/designer/src/components/taskmenu/treewidget_taskmenu.cpp2
-rw-r--r--tools/designer/src/components/taskmenu/treewidgeteditor.cpp63
-rw-r--r--tools/designer/src/components/taskmenu/treewidgeteditor.h18
9 files changed, 163 insertions, 54 deletions
diff --git a/tools/designer/src/components/taskmenu/itemlisteditor.cpp b/tools/designer/src/components/taskmenu/itemlisteditor.cpp
index 8d317f5adf..a04246de5b 100644
--- a/tools/designer/src/components/taskmenu/itemlisteditor.cpp
+++ b/tools/designer/src/components/taskmenu/itemlisteditor.cpp
@@ -80,7 +80,7 @@ private:
////////////////// Item editor ///////////////
AbstractItemEditor::AbstractItemEditor(QDesignerFormWindowInterface *form, QWidget *parent)
- : QDialog(parent),
+ : QWidget(parent),
m_iconCache(qobject_cast<FormWindowBase *>(form)->iconCache()),
m_updatingBrowser(false)
{
@@ -104,15 +104,6 @@ AbstractItemEditor::~AbstractItemEditor()
m_propertyBrowser->unsetFactoryForManager(m_propertyManager);
}
-void AbstractItemEditor::keyPressEvent(QKeyEvent *e)
-{
- // Avoid that embedded dialogs react to enter and escape keys.
- if (this == window())
- QDialog::keyPressEvent(e);
- else
- QWidget::keyPressEvent(e);
-}
-
static const char * const itemFlagNames[] = {
QT_TRANSLATE_NOOP("AbstractItemEditor", "Selectable"),
QT_TRANSLATE_NOOP("AbstractItemEditor", "Editable"),
@@ -304,7 +295,7 @@ ItemListEditor::ItemListEditor(QDesignerFormWindowInterface *form, QWidget *pare
injectPropertyBrowser(this, ui.widget);
connect(ui.showPropertiesButton, SIGNAL(clicked()),
this, SLOT(togglePropertyBrowser()));
- togglePropertyBrowser();
+ setPropertyBrowserVisible(false);
QIcon upIcon = createIconSet(QString::fromUtf8("up.png"));
QIcon downIcon = createIconSet(QString::fromUtf8("down.png"));
@@ -417,15 +408,13 @@ void ItemListEditor::on_listWidget_itemChanged(QListWidgetItem *item)
void ItemListEditor::togglePropertyBrowser()
{
- // Always hide in case parent widget is not visible -> on startup
- const bool isVisible =
- !this->isVisible() ? true : m_propertyBrowser->isVisible();
- if (isVisible)
- ui.showPropertiesButton->setText(tr("Properties &<<"));
- else
- ui.showPropertiesButton->setText(tr("Properties &>>"));
+ setPropertyBrowserVisible(!m_propertyBrowser->isVisible());
+}
- m_propertyBrowser->setVisible(!isVisible);
+void ItemListEditor::setPropertyBrowserVisible(bool v)
+{
+ ui.showPropertiesButton->setText(v ? tr("Properties &>>") : tr("Properties &<<"));
+ m_propertyBrowser->setVisible(v);
}
void ItemListEditor::setItemData(int role, const QVariant &v)
@@ -484,6 +473,6 @@ void ItemListEditor::updateEditor()
else
m_propertyBrowser->clear();
}
-}
+} // namespace qdesigner_internal
QT_END_NAMESPACE
diff --git a/tools/designer/src/components/taskmenu/itemlisteditor.h b/tools/designer/src/components/taskmenu/itemlisteditor.h
index 20596205c8..ffacad2934 100644
--- a/tools/designer/src/components/taskmenu/itemlisteditor.h
+++ b/tools/designer/src/components/taskmenu/itemlisteditor.h
@@ -53,6 +53,7 @@ class QtProperty;
class QtVariantProperty;
class QtTreePropertyBrowser;
class QSplitter;
+class QVBoxLayout;
namespace qdesigner_internal {
@@ -72,12 +73,12 @@ private:
bool reset;
};
-class AbstractItemEditor: public QDialog
+class AbstractItemEditor: public QWidget
{
Q_OBJECT
public:
- AbstractItemEditor(QDesignerFormWindowInterface *form, QWidget *parent);
+ explicit AbstractItemEditor(QDesignerFormWindowInterface *form, QWidget *parent);
~AbstractItemEditor();
DesignerIconCache *iconCache() const { return m_iconCache; }
@@ -95,7 +96,6 @@ private slots:
void cacheReloaded();
protected:
- void keyPressEvent(QKeyEvent *e);
void setupProperties(PropertyDefinition *propDefs);
void setupObject(QWidget *object);
void setupEditor(QWidget *object, PropertyDefinition *propDefs);
@@ -120,7 +120,7 @@ class ItemListEditor: public AbstractItemEditor
Q_OBJECT
public:
- ItemListEditor(QDesignerFormWindowInterface *form, QWidget *parent);
+ explicit ItemListEditor(QDesignerFormWindowInterface *form, QWidget *parent);
void setupEditor(QWidget *object, PropertyDefinition *propDefs);
QListWidget *listWidget() const { return ui.listWidget; }
@@ -150,6 +150,8 @@ protected:
virtual void setItemData(int role, const QVariant &v);
virtual QVariant getItemData(int role) const;
+private:
+ void setPropertyBrowserVisible(bool v);
void updateEditor();
Ui::ItemListEditor ui;
bool m_updating;
diff --git a/tools/designer/src/components/taskmenu/listwidgeteditor.h b/tools/designer/src/components/taskmenu/listwidgeteditor.h
index 7719451094..12d0591f29 100644
--- a/tools/designer/src/components/taskmenu/listwidgeteditor.h
+++ b/tools/designer/src/components/taskmenu/listwidgeteditor.h
@@ -45,7 +45,7 @@
#include "itemlisteditor.h"
#include <qdesigner_command_p.h>
-#include <QtGui/QDialog>
+#include <QtGui/QWidget>
QT_BEGIN_NAMESPACE
diff --git a/tools/designer/src/components/taskmenu/tablewidget_taskmenu.cpp b/tools/designer/src/components/taskmenu/tablewidget_taskmenu.cpp
index e3170bd9ee..e98714f623 100644
--- a/tools/designer/src/components/taskmenu/tablewidget_taskmenu.cpp
+++ b/tools/designer/src/components/taskmenu/tablewidget_taskmenu.cpp
@@ -94,7 +94,7 @@ void TableWidgetTaskMenu::editItems()
Q_ASSERT(m_tableWidget != 0);
- TableWidgetEditor dlg(m_formWindow, m_tableWidget->window());
+ TableWidgetEditorDialog dlg(m_formWindow, m_tableWidget->window());
TableWidgetContents oldCont = dlg.fillContentsFromTableWidget(m_tableWidget);
if (dlg.exec() == QDialog::Accepted) {
TableWidgetContents newCont = dlg.contents();
diff --git a/tools/designer/src/components/taskmenu/tablewidgeteditor.cpp b/tools/designer/src/components/taskmenu/tablewidgeteditor.cpp
index 4455ff161a..35f1a0e498 100644
--- a/tools/designer/src/components/taskmenu/tablewidgeteditor.cpp
+++ b/tools/designer/src/components/taskmenu/tablewidgeteditor.cpp
@@ -57,10 +57,10 @@
QT_BEGIN_NAMESPACE
-using namespace qdesigner_internal;
+namespace qdesigner_internal {
-TableWidgetEditor::TableWidgetEditor(QDesignerFormWindowInterface *form, QWidget *parent)
- : AbstractItemEditor(form, parent), m_updatingBrowser(false)
+TableWidgetEditor::TableWidgetEditor(QDesignerFormWindowInterface *form, QDialog *dialog)
+ : AbstractItemEditor(form, 0), m_updatingBrowser(false)
{
m_columnEditor = new ItemListEditor(form, this);
m_columnEditor->setObjectName(QLatin1String("columnEditor"));
@@ -68,12 +68,12 @@ TableWidgetEditor::TableWidgetEditor(QDesignerFormWindowInterface *form, QWidget
m_rowEditor = new ItemListEditor(form, this);
m_rowEditor->setObjectName(QLatin1String("rowEditor"));
m_rowEditor->setNewItemText(tr("New Row"));
- ui.setupUi(this);
+ ui.setupUi(dialog);
injectPropertyBrowser(ui.itemsTab, ui.widget);
connect(ui.showPropertiesButton, SIGNAL(clicked()),
this, SLOT(togglePropertyBrowser()));
- togglePropertyBrowser();
+ setPropertyBrowserVisible(false);
ui.tabWidget->insertTab(0, m_columnEditor, tr("&Columns"));
ui.tabWidget->insertTab(1, m_rowEditor, tr("&Rows"));
@@ -83,6 +83,36 @@ TableWidgetEditor::TableWidgetEditor(QDesignerFormWindowInterface *form, QWidget
ui.tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
connect(iconCache(), SIGNAL(reloaded()), this, SLOT(cacheReloaded()));
+
+ connect(ui.tableWidget, SIGNAL(currentCellChanged(int,int,int,int)),
+ this, SLOT(on_tableWidget_currentCellChanged(int,int,int,int)));
+ connect(ui.tableWidget, SIGNAL(itemChanged(QTableWidgetItem*)),
+ this, SLOT(on_tableWidget_itemChanged(QTableWidgetItem*)));
+ connect(m_columnEditor, SIGNAL(indexChanged(int)),
+ this, SLOT(on_columnEditor_indexChanged(int)));
+ connect(m_columnEditor, SIGNAL(itemChanged(int,int,QVariant)),
+ this, SLOT(on_columnEditor_itemChanged(int,int,QVariant)));
+ connect(m_columnEditor, SIGNAL(itemInserted(int)),
+ this, SLOT(on_columnEditor_itemInserted(int)));
+ connect(m_columnEditor, SIGNAL(itemDeleted(int)),
+ this, SLOT(on_columnEditor_itemDeleted(int)));
+ connect(m_columnEditor, SIGNAL(itemMovedUp(int)),
+ this, SLOT(on_columnEditor_itemMovedUp(int)));
+ connect(m_columnEditor, SIGNAL(itemMovedDown(int)),
+ this, SLOT(on_columnEditor_itemMovedDown(int)));
+
+ connect(m_rowEditor, SIGNAL(indexChanged(int)),
+ this, SLOT(on_rowEditor_indexChanged(int)));
+ connect(m_rowEditor, SIGNAL(itemChanged(int,int,QVariant)),
+ this, SLOT(on_rowEditor_itemChanged(int,int,QVariant)));
+ connect(m_rowEditor, SIGNAL(itemInserted(int)),
+ this, SLOT(on_rowEditor_itemInserted(int)));
+ connect(m_rowEditor, SIGNAL(itemDeleted(int)),
+ this, SLOT(on_rowEditor_itemDeleted(int)));
+ connect(m_rowEditor, SIGNAL(itemMovedUp(int)),
+ this, SLOT(on_rowEditor_itemMovedUp(int)));
+ connect(m_rowEditor, SIGNAL(itemMovedDown(int)),
+ this, SLOT(on_rowEditor_itemMovedDown(int)));
}
static AbstractItemEditor::PropertyDefinition tableHeaderPropList[] = {
@@ -207,16 +237,15 @@ void TableWidgetEditor::on_rowEditor_itemChanged(int idx, int role, const QVaria
ui.tableWidget->verticalHeaderItem(idx)->setData(role, v);
}
+void TableWidgetEditor::setPropertyBrowserVisible(bool v)
+{
+ ui.showPropertiesButton->setText(v ? tr("Properties &>>") : tr("Properties &<<"));
+ m_propertyBrowser->setVisible(v);
+}
+
void TableWidgetEditor::togglePropertyBrowser()
{
- // Always hide in case parent widget is not visible -> on startup
- const bool isVisible =
- !this->isVisible() ? true : m_propertyBrowser->isVisible();
- if (isVisible)
- ui.showPropertiesButton->setText(tr("Properties &<<"));
- else
- ui.showPropertiesButton->setText(tr("Properties &>>"));
- m_propertyBrowser->setVisible(!isVisible);
+ setPropertyBrowserVisible(!m_propertyBrowser->isVisible());
}
void TableWidgetEditor::updateEditor()
@@ -400,4 +429,22 @@ void TableWidgetEditor::cacheReloaded()
reloadIconResources(iconCache(), ui.tableWidget);
}
+TableWidgetEditorDialog::TableWidgetEditorDialog(QDesignerFormWindowInterface *form, QWidget *parent) :
+ QDialog(parent), m_editor(form, this)
+{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+}
+
+TableWidgetContents TableWidgetEditorDialog::fillContentsFromTableWidget(QTableWidget *tableWidget)
+{
+ return m_editor.fillContentsFromTableWidget(tableWidget);
+}
+
+TableWidgetContents TableWidgetEditorDialog::contents() const
+{
+ return m_editor.contents();
+}
+
+} // namespace qdesigner_internal
+
QT_END_NAMESPACE
diff --git a/tools/designer/src/components/taskmenu/tablewidgeteditor.h b/tools/designer/src/components/taskmenu/tablewidgeteditor.h
index cea2e2f9dc..1d5ad1f571 100644
--- a/tools/designer/src/components/taskmenu/tablewidgeteditor.h
+++ b/tools/designer/src/components/taskmenu/tablewidgeteditor.h
@@ -46,6 +46,8 @@
#include "listwidgeteditor.h"
+#include <QtGui/QDialog>
+
QT_BEGIN_NAMESPACE
class QTableWidget;
@@ -60,7 +62,7 @@ class TableWidgetEditor: public AbstractItemEditor
{
Q_OBJECT
public:
- TableWidgetEditor(QDesignerFormWindowInterface *form, QWidget *parent);
+ explicit TableWidgetEditor(QDesignerFormWindowInterface *form, QDialog *dialog);
TableWidgetContents fillContentsFromTableWidget(QTableWidget *tableWidget);
TableWidgetContents contents() const;
@@ -95,6 +97,7 @@ protected:
virtual QVariant getItemData(int role) const;
private:
+ void setPropertyBrowserVisible(bool v);
void updateEditor();
void moveColumnsLeft(int fromColumn, int toColumn);
void moveColumnsRight(int fromColumn, int toColumn);
@@ -107,6 +110,19 @@ private:
bool m_updatingBrowser;
};
+class TableWidgetEditorDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit TableWidgetEditorDialog(QDesignerFormWindowInterface *form, QWidget *parent);
+
+ TableWidgetContents fillContentsFromTableWidget(QTableWidget *tableWidget);
+ TableWidgetContents contents() const;
+
+private:
+ TableWidgetEditor m_editor;
+};
+
} // namespace qdesigner_internal
QT_END_NAMESPACE
diff --git a/tools/designer/src/components/taskmenu/treewidget_taskmenu.cpp b/tools/designer/src/components/taskmenu/treewidget_taskmenu.cpp
index 882c6569e6..96210dcdbe 100644
--- a/tools/designer/src/components/taskmenu/treewidget_taskmenu.cpp
+++ b/tools/designer/src/components/taskmenu/treewidget_taskmenu.cpp
@@ -93,7 +93,7 @@ void TreeWidgetTaskMenu::editItems()
Q_ASSERT(m_treeWidget != 0);
- TreeWidgetEditor dlg(m_formWindow, m_treeWidget->window());
+ TreeWidgetEditorDialog dlg(m_formWindow, m_treeWidget->window());
TreeWidgetContents oldCont = dlg.fillContentsFromTreeWidget(m_treeWidget);
if (dlg.exec() == QDialog::Accepted) {
TreeWidgetContents newCont = dlg.contents();
diff --git a/tools/designer/src/components/taskmenu/treewidgeteditor.cpp b/tools/designer/src/components/taskmenu/treewidgeteditor.cpp
index 50fc86aac6..f5f6035f21 100644
--- a/tools/designer/src/components/taskmenu/treewidgeteditor.cpp
+++ b/tools/designer/src/components/taskmenu/treewidgeteditor.cpp
@@ -60,18 +60,18 @@ QT_BEGIN_NAMESPACE
namespace qdesigner_internal {
-TreeWidgetEditor::TreeWidgetEditor(QDesignerFormWindowInterface *form, QWidget *parent)
- : AbstractItemEditor(form, parent), m_updatingBrowser(false)
+TreeWidgetEditor::TreeWidgetEditor(QDesignerFormWindowInterface *form, QDialog *dialog)
+ : AbstractItemEditor(form, 0), m_updatingBrowser(false)
{
m_columnEditor = new ItemListEditor(form, this);
m_columnEditor->setObjectName(QLatin1String("columnEditor"));
m_columnEditor->setNewItemText(tr("New Column"));
- ui.setupUi(this);
+ ui.setupUi(dialog);
injectPropertyBrowser(ui.itemsTab, ui.widget);
connect(ui.showPropertiesButton, SIGNAL(clicked()),
this, SLOT(togglePropertyBrowser()));
- togglePropertyBrowser();
+ setPropertyBrowserVisible(false);
ui.tabWidget->insertTab(0, m_columnEditor, tr("&Columns"));
ui.tabWidget->setCurrentIndex(0);
@@ -87,6 +87,30 @@ TreeWidgetEditor::TreeWidgetEditor(QDesignerFormWindowInterface *form, QWidget *
ui.treeWidget->header()->setMovable(false);
+ connect(ui.newItemButton, SIGNAL(clicked()), this, SLOT(on_newItemButton_clicked()));
+ connect(ui.newSubItemButton, SIGNAL(clicked()), this, SLOT(on_newSubItemButton_clicked()));
+ connect(ui.moveItemUpButton, SIGNAL(clicked()), this, SLOT(on_moveItemUpButton_clicked()));
+ connect(ui.moveItemDownButton, SIGNAL(clicked()), this, SLOT(on_moveItemDownButton_clicked()));
+ connect(ui.moveItemRightButton, SIGNAL(clicked()), this, SLOT(on_moveItemRightButton_clicked()));
+ connect(ui.moveItemLeftButton, SIGNAL(clicked()), this, SLOT(on_moveItemLeftButton_clicked()));
+ connect(ui.treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
+ this, SLOT(on_treeWidget_currentItemChanged()));
+ connect(ui.treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
+ this, SLOT(on_treeWidget_itemChanged(QTreeWidgetItem*,int)));
+
+ connect(m_columnEditor, SIGNAL(indexChanged(int)),
+ this, SLOT(on_columnEditor_indexChanged(int)));
+ connect(m_columnEditor, SIGNAL(itemChanged(int,int,QVariant)),
+ this, SLOT(on_columnEditor_itemChanged(int,int,QVariant)));
+ connect(m_columnEditor, SIGNAL(itemInserted(int)),
+ this, SLOT(on_columnEditor_itemInserted(int)));
+ connect(m_columnEditor, SIGNAL(itemDeleted(int)),
+ this, SLOT(on_columnEditor_itemDeleted(int)));
+ connect(m_columnEditor, SIGNAL(itemMovedUp(int)),
+ this, SLOT(on_columnEditor_itemMovedUp(int)));
+ connect(m_columnEditor, SIGNAL(itemMovedDown(int)),
+ this, SLOT(on_columnEditor_itemMovedDown(int)));
+
connect(iconCache(), SIGNAL(reloaded()), this, SLOT(cacheReloaded()));
}
@@ -386,15 +410,13 @@ void TreeWidgetEditor::on_moveItemRightButton_clicked()
void TreeWidgetEditor::togglePropertyBrowser()
{
- // Always hide in case parent widget is not visible -> on startup
- const bool isVisible =
- !this->isVisible() ? true : m_propertyBrowser->isVisible();
- if (isVisible)
- ui.showPropertiesButton->setText(tr("Properties &<<"));
- else
- ui.showPropertiesButton->setText(tr("Properties &>>"));
+ setPropertyBrowserVisible(!m_propertyBrowser->isVisible());
+}
- m_propertyBrowser->setVisible(!isVisible);
+void TreeWidgetEditor::setPropertyBrowserVisible(bool v)
+{
+ ui.showPropertiesButton->setText(v ? tr("Properties &>>") : tr("Properties &<<"));
+ m_propertyBrowser->setVisible(v);
}
void TreeWidgetEditor::on_treeWidget_currentItemChanged()
@@ -599,5 +621,22 @@ void TreeWidgetEditor::cacheReloaded()
reloadIconResources(iconCache(), ui.treeWidget);
}
+TreeWidgetEditorDialog::TreeWidgetEditorDialog(QDesignerFormWindowInterface *form, QWidget *parent) :
+ QDialog(parent), m_editor(form, this)
+{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+}
+
+TreeWidgetContents TreeWidgetEditorDialog::fillContentsFromTreeWidget(QTreeWidget *treeWidget)
+{
+ return m_editor.fillContentsFromTreeWidget(treeWidget);
}
+
+TreeWidgetContents TreeWidgetEditorDialog::contents() const
+{
+ return m_editor.contents();
+}
+
+} // namespace qdesigner_internal
+
QT_END_NAMESPACE
diff --git a/tools/designer/src/components/taskmenu/treewidgeteditor.h b/tools/designer/src/components/taskmenu/treewidgeteditor.h
index 461b20fbf9..f502bf3e4d 100644
--- a/tools/designer/src/components/taskmenu/treewidgeteditor.h
+++ b/tools/designer/src/components/taskmenu/treewidgeteditor.h
@@ -46,6 +46,8 @@
#include "listwidgeteditor.h"
+#include <QtGui/QDialog>
+
QT_BEGIN_NAMESPACE
class QTreeWidget;
@@ -60,7 +62,7 @@ class TreeWidgetEditor: public AbstractItemEditor
{
Q_OBJECT
public:
- TreeWidgetEditor(QDesignerFormWindowInterface *form, QWidget *parent);
+ explicit TreeWidgetEditor(QDesignerFormWindowInterface *form, QDialog *dialog);
TreeWidgetContents fillContentsFromTreeWidget(QTreeWidget *treeWidget);
TreeWidgetContents contents() const;
@@ -93,6 +95,7 @@ protected:
virtual QVariant getItemData(int role) const;
private:
+ void setPropertyBrowserVisible(bool v);
QtVariantProperty *setupPropertyGroup(const QString &title, PropertyDefinition *propDefs);
void updateEditor();
void moveColumnItems(const PropertyDefinition *propList, QTreeWidgetItem *item, int fromColumn, int toColumn, int step);
@@ -106,6 +109,19 @@ private:
bool m_updatingBrowser;
};
+class TreeWidgetEditorDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit TreeWidgetEditorDialog(QDesignerFormWindowInterface *form, QWidget *parent);
+
+ TreeWidgetContents fillContentsFromTreeWidget(QTreeWidget *treeWidget);
+ TreeWidgetContents contents() const;
+
+private:
+ TreeWidgetEditor m_editor;
+};
+
} // namespace qdesigner_internal
QT_END_NAMESPACE