From 3bb0af0dc1c26489b723a268eedd722a6a06683f Mon Sep 17 00:00:00 2001
From: Guillaume Lelarge <guillaume@lelarge.info>
Date: Sun, 6 Feb 2011 11:59:39 +0100
Subject: [PATCH] Support for Foreign Data Wrapper object.

---
 pgadmin/dlg/dlgForeignDataWrapper.cpp            |  343 ++++++++++++++++++++++
 pgadmin/dlg/module.mk                            |    1 +
 pgadmin/frm/frmOptions.cpp                       |    1 +
 pgadmin/include/dlg/dlgForeignDataWrapper.h      |   51 ++++
 pgadmin/include/dlg/module.mk                    |    1 +
 pgadmin/include/images/foreigndatawrapper-sm.xpm |   57 ++++
 pgadmin/include/images/foreigndatawrapper.xpm    |   64 ++++
 pgadmin/include/images/foreigndatawrappers.xpm   |   65 ++++
 pgadmin/include/images/module.mk                 |    1 +
 pgadmin/include/precomp.h                        |    2 +
 pgadmin/include/schema/module.mk                 |    1 +
 pgadmin/include/schema/pgForeignDataWrapper.h    |   77 +++++
 pgadmin/include/utils/pgDefs.h                   |    1 +
 pgadmin/schema/module.mk                         |    1 +
 pgadmin/schema/pgDatabase.cpp                    |    5 +
 pgadmin/schema/pgForeignDataWrapper.cpp          |  169 +++++++++++
 pgadmin/ui/dlgForeignDataWrapper.xrc             |  255 ++++++++++++++++
 pgadmin/ui/module.mk                             |    1 +
 pgadmin/utils/sysSettings.cpp                    |    6 +
 19 files changed, 1102 insertions(+), 0 deletions(-)
 create mode 100644 pgadmin/dlg/dlgForeignDataWrapper.cpp
 create mode 100644 pgadmin/include/dlg/dlgForeignDataWrapper.h
 create mode 100644 pgadmin/include/images/foreigndatawrapper-sm.xpm
 create mode 100644 pgadmin/include/images/foreigndatawrapper.xpm
 create mode 100644 pgadmin/include/images/foreigndatawrappers.xpm
 create mode 100644 pgadmin/include/schema/pgForeignDataWrapper.h
 create mode 100644 pgadmin/schema/pgForeignDataWrapper.cpp
 create mode 100644 pgadmin/ui/dlgForeignDataWrapper.xrc

diff --git a/pgadmin/dlg/dlgForeignDataWrapper.cpp b/pgadmin/dlg/dlgForeignDataWrapper.cpp
new file mode 100644
index 0000000..3c368d2
--- /dev/null
+++ b/pgadmin/dlg/dlgForeignDataWrapper.cpp
@@ -0,0 +1,343 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+// RCS-ID:      $Id$
+// Copyright (C) 2002 - 2010, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// dlgForeignDataWrapper.cpp - PostgreSQL ForeignDataWrapper Property
+//
+//////////////////////////////////////////////////////////////////////////
+
+// wxWindows headers
+#include <wx/wx.h>
+
+// App headers
+#include "pgAdmin3.h"
+#include "utils/misc.h"
+#include "utils/pgDefs.h"
+
+#include "dlg/dlgForeignDataWrapper.h"
+#include "schema/pgForeignDataWrapper.h"
+
+
+// pointer to controls
+#define cbValidator     CTRL_COMBOBOX("cbValidator")
+#define lstOptions          CTRL_LISTVIEW("lstOptions")
+#define txtOption           CTRL_TEXT("txtOption")
+#define txtValue            CTRL_TEXT("txtValue")
+#define btnAdd              CTRL_BUTTON("wxID_ADD")
+#define btnRemove           CTRL_BUTTON("wxID_REMOVE")
+
+
+dlgProperty *pgForeignDataWrapperFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
+{
+	return new dlgForeignDataWrapper(this, frame, (pgForeignDataWrapper *)node);
+}
+
+
+BEGIN_EVENT_TABLE(dlgForeignDataWrapper, dlgSecurityProperty)
+	EVT_TEXT(XRCID("cbValidator"),                    dlgProperty::OnChange)
+	EVT_COMBOBOX(XRCID("cbValidator"),                dlgProperty::OnChange)
+	EVT_LIST_ITEM_SELECTED(XRCID("lstOptions"), dlgForeignDataWrapper::OnSelChangeOption)
+	EVT_TEXT(XRCID("txtOption"),                dlgForeignDataWrapper::OnChangeOptionName)
+	EVT_BUTTON(wxID_ADD,                        dlgForeignDataWrapper::OnAddOption)
+	EVT_BUTTON(wxID_REMOVE,                     dlgForeignDataWrapper::OnRemoveOption)
+END_EVENT_TABLE();
+
+
+dlgForeignDataWrapper::dlgForeignDataWrapper(pgaFactory *f, frmMain *frame, pgForeignDataWrapper *node)
+	: dlgSecurityProperty(f, frame, node, wxT("dlgForeignDataWrapper"), wxT("USAGE"), "U")
+{
+	fdw = node;
+}
+
+
+pgObject *dlgForeignDataWrapper::GetObject()
+{
+	return fdw;
+}
+
+
+int dlgForeignDataWrapper::Go(bool modal)
+{
+	// Fill owner combobox
+	AddGroups();
+	AddUsers(cbOwner);
+
+	// Fill validator combobox
+	cbValidator->Append(wxT(""));
+	pgSet *set = connection->ExecuteSet(
+	                 wxT("SELECT nspname, proname\n")
+	                 wxT("  FROM pg_proc p\n")
+	                 wxT("  JOIN pg_namespace nsp ON nsp.oid=pronamespace\n")
+	                 wxT(" WHERE proargtypes[0]=") + NumToStr(PGOID_TYPE_TEXT_ARRAY) +
+	                 wxT(" AND proargtypes[1]=") + NumToStr(PGOID_TYPE_OID));
+	if (set)
+	{
+		while (!set->Eof())
+		{
+			wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname"));
+			cbValidator->Append(procname);
+			set->MoveNext();
+		}
+		delete set;
+	}
+	cbValidator->SetSelection(0);
+
+	// Initialize options listview and buttons
+	lstOptions->AddColumn(_("Option"), 80);
+	lstOptions->AddColumn(_("Value"), 40);
+	txtOption->SetValue(wxT(""));
+	txtValue->SetValue(wxT(""));
+	btnAdd->Disable();
+	btnRemove->Disable();
+
+	if (fdw)
+	{
+		// edit mode
+		txtName->Disable();
+		wxString val = fdw->GetValidatorProc();
+		if (!val.IsEmpty())
+		{
+			for (int i = 0 ; i < cbValidator->GetCount() ; i++)
+			{
+				if (cbValidator->GetString(i) == val)
+					cbValidator->SetSelection(i);
+			}
+		}
+
+		wxString options = fdw->GetOptions();
+		wxString option, optionname, optionvalue;
+		while (options.Length() > 0)
+		{
+			option = options.BeforeFirst(',');
+			optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim();
+			optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim();
+			lstOptions->AppendItem(optionname, optionvalue);
+			options = options.AfterFirst(',');
+		}
+	}
+	else
+	{
+		// create mode
+	}
+
+	return dlgSecurityProperty::Go(modal);
+}
+
+
+pgObject *dlgForeignDataWrapper::CreateObject(pgCollection *collection)
+{
+	wxString name = txtName->GetValue();
+
+	pgObject *obj = foreignDataWrapperFactory.CreateObjects(collection, 0, wxT("\n   AND fdwname ILIKE ") + qtDbString(name));
+	return obj;
+}
+
+
+void dlgForeignDataWrapper::CheckChange()
+{
+	bool didChange = true;
+	wxString name = txtName->GetValue();
+	if (fdw)
+	{
+		didChange = name != fdw->GetName()
+		            || txtComment->GetValue() != fdw->GetComment()
+		            || cbOwner->GetValue() != fdw->GetOwner()
+		            || GetOptionsSql().Length() > 0;
+		EnableOK(didChange);
+	}
+	else
+	{
+
+		bool enable = true;
+
+		CheckValid(enable, !name.IsEmpty(), _("Please specify name."));
+		EnableOK(enable);
+	}
+}
+
+
+
+void dlgForeignDataWrapper::OnChangeOptionName(wxCommandEvent &ev)
+{
+	btnAdd->Enable(txtOption->GetValue().Length() > 0);
+}
+
+
+void dlgForeignDataWrapper::OnSelChangeOption(wxListEvent &ev)
+{
+	int row = lstOptions->GetSelection();
+	if (row >= 0)
+	{
+		txtOption->SetValue(lstOptions->GetText(row, 0));
+		txtValue->SetValue(lstOptions->GetText(row, 1));
+	}
+
+	btnRemove->Enable(row >= 0);
+}
+
+
+void dlgForeignDataWrapper::OnAddOption(wxCommandEvent &ev)
+{
+	bool found = false;
+
+	for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++)
+	{
+		if (lstOptions->GetText(pos).IsSameAs(txtOption->GetValue(), false))
+		{
+			lstOptions->SetItem(pos, 1, txtValue->GetValue());
+			found = true;
+			break;
+		}
+	}
+
+	if (!found)
+	{
+		lstOptions->AppendItem(txtOption->GetValue(), txtValue->GetValue());
+	}
+
+	txtOption->SetValue(wxT(""));
+	txtValue->SetValue(wxT(""));
+	btnAdd->Disable();
+
+	CheckChange();
+}
+
+
+void dlgForeignDataWrapper::OnRemoveOption(wxCommandEvent &ev)
+{
+	int sel = lstOptions->GetSelection();
+	lstOptions->DeleteItem(sel);
+
+	txtOption->SetValue(wxT(""));
+	txtValue->SetValue(wxT(""));
+	btnRemove->Disable();
+
+	CheckChange();
+}
+
+
+wxString dlgForeignDataWrapper::GetOptionsSql()
+{
+	wxString options = fdw->GetOptions();
+	wxString option, optionname, optionvalue, sqloptions;
+	bool found;
+	int pos;
+
+	while (options.Length() > 0)
+	{
+		option = options.BeforeFirst(',');
+		optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim();
+		optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim();
+
+		// check for options
+		found = false;
+		for (pos = 0 ; pos < lstOptions->GetItemCount() && !found; pos++)
+		{
+			found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0;
+			if (found) break;
+		}
+
+		if (found)
+		{
+			if (lstOptions->GetText(pos, 1).Cmp(optionvalue) != 0)
+			{
+				if (sqloptions.Length() > 0)
+					sqloptions += wxT(", ");
+				sqloptions += wxT("SET ") + optionname + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'");
+			}
+		}
+		else
+		{
+			if (sqloptions.Length() > 0)
+				sqloptions += wxT(", ");
+			sqloptions += wxT("DROP ") + optionname;
+		}
+
+		options = options.AfterFirst(',');
+	}
+
+	for (pos = 0 ; pos < lstOptions->GetItemCount() ; pos++)
+	{
+		options = fdw->GetOptions();
+		found = false;
+
+		while (options.Length() > 0 && !found)
+		{
+			option = options.BeforeFirst(',');
+			optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim();
+			found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0;
+			options = options.AfterFirst(',');
+		}
+
+		if (!found)
+		{
+			optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim();
+
+			if (sqloptions.Length() > 0)
+				sqloptions += wxT(", ");
+			sqloptions += wxT("ADD ") + lstOptions->GetText(pos, 0) + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'");
+		}
+	}
+
+	return sqloptions;
+}
+
+
+wxString dlgForeignDataWrapper::GetSql()
+{
+	wxString sql, name;
+	name = txtName->GetValue();
+
+	if (fdw)
+	{
+		// edit mode
+		if (cbValidator->GetValue() != fdw->GetValidatorProc())
+		{
+			sql = wxT("ALTER FOREIGN DATA WRAPPER ") + qtIdent(name)
+			      + wxT("\n   VALIDATOR ") + qtIdent(cbValidator->GetValue());
+		}
+
+		wxString sqloptions = GetOptionsSql();
+		if (sqloptions.Length() > 0)
+		{
+			sql += wxT("ALTER FOREIGN DATA WRAPPER ") + name
+			       + wxT(" OPTIONS (") + sqloptions + wxT(")");
+		}
+
+		AppendOwnerChange(sql, wxT("FOREIGN DATA WRAPPER ") + qtIdent(name));
+	}
+	else
+	{
+		// create mode
+		sql = wxT("CREATE FOREIGN DATA WRAPPER ") + qtIdent(name);
+		AppendIfFilled(sql, wxT("\n   VALIDATOR "), qtIdent(cbValidator->GetValue()));
+
+		// check for options
+		if (lstOptions->GetItemCount() > 0)
+		{
+			wxString options = wxEmptyString;
+			for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++)
+			{
+				if (options.Length() > 0)
+					options += wxT(", ");
+
+				options += lstOptions->GetText(pos, 0)
+				           + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("' ");
+			}
+			sql += wxT("\n  OPTIONS (") + options + wxT(")");
+		}
+
+		sql += wxT(";\n");
+		AppendOwnerNew(sql, wxT("FOREIGN DATA WRAPPER ") + qtIdent(name));
+	}
+
+	sql += GetGrant(wxT("U"), wxT("FOREIGN DATA WRAPPER ") + qtIdent(name));
+	AppendComment(sql, wxT("FOREIGN DATA WRAPPER ") + qtIdent(name), 0, fdw);
+
+	return sql;
+}
+
+
diff --git a/pgadmin/dlg/module.mk b/pgadmin/dlg/module.mk
index f5eda0b..d1001fc 100644
--- a/pgadmin/dlg/module.mk
+++ b/pgadmin/dlg/module.mk
@@ -22,6 +22,7 @@ pgadmin3_SOURCES += \
 	$(srcdir)/dlg/dlgDomain.cpp \
 	$(srcdir)/dlg/dlgEditGridOptions.cpp \
 	$(srcdir)/dlg/dlgFindReplace.cpp \
+	$(srcdir)/dlg/dlgForeignDataWrapper.cpp \
 	$(srcdir)/dlg/dlgForeignKey.cpp \
 	$(srcdir)/dlg/dlgFunction.cpp \
 	$(srcdir)/dlg/dlgGroup.cpp \
diff --git a/pgadmin/frm/frmOptions.cpp b/pgadmin/frm/frmOptions.cpp
index 2f45bf2..46447d4 100644
--- a/pgadmin/frm/frmOptions.cpp
+++ b/pgadmin/frm/frmOptions.cpp
@@ -327,6 +327,7 @@ frmOptions::frmOptions(frmMain *parent)
 	lstDisplay->Append(_("Resource Queues"));
 	lstDisplay->Append(_("Catalogs"));
 	lstDisplay->Append(_("Casts"));
+    lstDisplay->Append(_("Foreign Data Wrappers"));
 	lstDisplay->Append(_("Languages"));
 	lstDisplay->Append(_("Synonyms"));
 	lstDisplay->Append(_("Schemas"));
diff --git a/pgadmin/include/dlg/dlgForeignDataWrapper.h b/pgadmin/include/dlg/dlgForeignDataWrapper.h
new file mode 100644
index 0000000..34919c1
--- /dev/null
+++ b/pgadmin/include/dlg/dlgForeignDataWrapper.h
@@ -0,0 +1,51 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+// RCS-ID:      $Id$
+// Copyright (C) 2002 - 2010, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// dlgForeignDataWrapper.h - Foreign Data Wrapper property
+//
+//////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __DLG_FOREIGNDATAWRAPPERPROP
+#define __DLG_FOREIGNDATAWRAPPERPROP
+
+#include "dlg/dlgProperty.h"
+
+class pgForeignDataWrapper;
+
+class dlgForeignDataWrapper : public dlgSecurityProperty
+{
+public:
+	dlgForeignDataWrapper(pgaFactory *factory, frmMain *frame, pgForeignDataWrapper *db);
+	int Go(bool modal);
+
+	void CheckChange();
+	wxString GetSql();
+	pgObject *CreateObject(pgCollection *collection);
+	pgObject *GetObject();
+
+private:
+	pgForeignDataWrapper *fdw;
+
+	void OnChange(wxCommandEvent &ev);
+#ifdef __WXMAC__
+	void OnChangeSize(wxSizeEvent &ev);
+#endif
+
+	void OnSelChangeOption(wxListEvent &ev);
+	void OnChangeOptionName(wxCommandEvent &ev);
+	void OnAddOption(wxCommandEvent &ev);
+	void OnChangeOption(wxCommandEvent &ev);
+	void OnRemoveOption(wxCommandEvent &ev);
+
+	wxString GetOptionsSql();
+
+	DECLARE_EVENT_TABLE()
+};
+
+
+#endif
diff --git a/pgadmin/include/dlg/module.mk b/pgadmin/include/dlg/module.mk
index e21c45f..77ea2c3 100644
--- a/pgadmin/include/dlg/module.mk
+++ b/pgadmin/include/dlg/module.mk
@@ -22,6 +22,7 @@ pgadmin3_SOURCES += \
 	$(srcdir)/include/dlg/dlgDomain.h \
 	$(srcdir)/include/dlg/dlgEditGridOptions.h \
 	$(srcdir)/include/dlg/dlgFindReplace.h \
+	$(srcdir)/include/dlg/dlgForeignDataWrapper.h \
 	$(srcdir)/include/dlg/dlgForeignKey.h \
 	$(srcdir)/include/dlg/dlgFunction.h \
 	$(srcdir)/include/dlg/dlgGroup.h \
diff --git a/pgadmin/include/images/foreigndatawrapper-sm.xpm b/pgadmin/include/images/foreigndatawrapper-sm.xpm
new file mode 100644
index 0000000..c4866c6
--- /dev/null
+++ b/pgadmin/include/images/foreigndatawrapper-sm.xpm
@@ -0,0 +1,57 @@
+/* XPM */
+static const char * foreigndatawrapper_sm_xpm[] = {
+"16 16 38 1",
+" 	c None",
+".	c #EBD986",
+"+	c #E0C259",
+"@	c #D8B129",
+"#	c #F7EFD4",
+"$	c #D8B31F",
+"%	c #E3CD39",
+"&	c #EDE24F",
+"*	c #F4F25F",
+"=	c #F4EAC5",
+"-	c #DAB723",
+";	c #ECDE4B",
+">	c #F8F967",
+",	c #E6D069",
+"'	c #E8D643",
+")	c #F8FA69",
+"!	c #E8D180",
+"~	c #DAB632",
+"{	c #F4EE5F",
+"]	c #F9FA6B",
+"^	c #DAB638",
+"/	c #F4EF60",
+"(	c #FAFB6D",
+"_	c #E9D647",
+":	c #FBFB6F",
+"<	c #DBB825",
+"[	c #EEE053",
+"}	c #FCFC72",
+"|	c #D9B320",
+"1	c #E6CE3F",
+"2	c #F1E559",
+"3	c #FAF56C",
+"4	c #FDFC74",
+"5	c #D6AD1E",
+"6	c #D4AA16",
+"7	c #FEFD76",
+"8	c #E6CD76",
+"9	c #FFFD78",
+"                ",
+"                ",
+"     .+@@+ #    ",
+"    $%&**&%$=   ",
+"   -;>>>>>>;-   ",
+"  ,'))))))))'!  ",
+"  ~{]]]]]]]]{^  ",
+"  ^/((((((((/^  ",
+"  !_::::::::_!  ",
+"   <[}}}}}}[<   ",
+"   =|123344|    ",
+"      +56776    ",
+"        8696    ",
+"          68    ",
+"                ",
+"                "};
diff --git a/pgadmin/include/images/foreigndatawrapper.xpm b/pgadmin/include/images/foreigndatawrapper.xpm
new file mode 100644
index 0000000..7deffbd
--- /dev/null
+++ b/pgadmin/include/images/foreigndatawrapper.xpm
@@ -0,0 +1,64 @@
+/* XPM */
+static const char * foreigndatawrapper_xpm[] = {
+"16 16 45 1",
+" 	c None",
+".	c #E2C561",
+"+	c #DAB534",
+"@	c #D5AB1A",
+"#	c #EDDB9C",
+"$	c #D9B420",
+"%	c #E3CB38",
+"&	c #ECE04C",
+"*	c #F2EF5C",
+"=	c #F6F865",
+"-	c #F0E2B0",
+";	c #DFC32F",
+">	c #EFE552",
+",	c #F8F966",
+"'	c #DDBE2B",
+")	c #F2EB5A",
+"!	c #F8F968",
+"~	c #E5CB71",
+"{	c #EADB48",
+"]	c #F9FA69",
+"^	c #D9B432",
+"/	c #F5F061",
+"(	c #F9FA6B",
+"_	c #F5F162",
+":	c #FAFB6D",
+"<	c #ECDB4B",
+"[	c #FBFB6E",
+"}	c #DEBF2D",
+"|	c #F5ED60",
+"1	c #FCFB70",
+"2	c #EDDC9E",
+"3	c #E1C433",
+"4	c #F2E75B",
+"5	c #FCFC72",
+"6	c #D9B522",
+"7	c #E5CD3E",
+"8	c #F0E256",
+"9	c #F8F168",
+"0	c #FCFB73",
+"a	c #FDFC74",
+"b	c #D4AA16",
+"c	c #FEFD75",
+"d	c #E6CD76",
+"e	c #FEFD77",
+"f	c #FFFD78",
+"     .+@+.#     ",
+"   $%&*=*&%$-   ",
+"  ;>,,,,,,,>;   ",
+" ')!!!!!!!!!)'  ",
+"~{]]]]]]]]]]]{~ ",
+"^/(((((((((((/^ ",
+"^_:::::::::::_^ ",
+"~<[[[[[[[[[[[<~ ",
+" }|111111111|}  ",
+" 234555555553   ",
+"  -67890aaaab   ",
+"    #.+@bcccb   ",
+"        dbeeb   ",
+"         dbfb   ",
+"          dbd   ",
+"                "};
diff --git a/pgadmin/include/images/foreigndatawrappers.xpm b/pgadmin/include/images/foreigndatawrappers.xpm
new file mode 100644
index 0000000..42a902e
--- /dev/null
+++ b/pgadmin/include/images/foreigndatawrappers.xpm
@@ -0,0 +1,65 @@
+/* XPM */
+static const char * foreigndatawrappers_xpm[] = {
+"16 16 46 1",
+" 	c None",
+".	c #ECDA99",
+"+	c #E0C259",
+"@	c #D8B129",
+"#	c #D8B31F",
+"$	c #E3CD39",
+"%	c #EDE24F",
+"&	c #F4F25F",
+"*	c #F4EAC5",
+"=	c #DAB723",
+"-	c #ECDE4B",
+";	c #F8F967",
+">	c #F4F05E",
+",	c #E8D643",
+"'	c #DEC12D",
+")	c #D7B11D",
+"!	c #DBB925",
+"~	c #E8D180",
+"{	c #F8FA69",
+"]	c #EFE654",
+"^	c #DAB638",
+"/	c #F4EE5F",
+"(	c #F3ED5D",
+"_	c #F4EF60",
+":	c #E5CF3E",
+"<	c #E9D647",
+"[	c #DAB623",
+"}	c #DBB825",
+"|	c #D8B21F",
+"1	c #D6AE1B",
+"2	c #F9FA6B",
+"3	c #F4E9C4",
+"4	c #FAFB6D",
+"5	c #FBFB6F",
+"6	c #EEE053",
+"7	c #FCFC72",
+"8	c #D9B320",
+"9	c #E6CE3F",
+"0	c #F1E559",
+"a	c #FAF56C",
+"b	c #FDFC74",
+"c	c #D6AD1E",
+"d	c #D4AA16",
+"e	c #FEFD76",
+"f	c #E6CD76",
+"g	c #FFFD78",
+"   .+@@+.       ",
+"  #$%&&%$#*     ",
+" =-;>,'))!)     ",
+"~,{]#$%&&%$#    ",
+"^/(=-;>,'))!)   ",
+"^_:,{]#$%&&%$#  ",
+"~<[/(=-;;;;;;-= ",
+" }|_:,{{{{{{{{,~",
+"  1<[/22222222/^",
+"  3}|_44444444_^",
+"   *1<55555555<~",
+"     }67777776} ",
+"     *890aabb8  ",
+"        +cdeed  ",
+"          fdgd  ",
+"           fdf  "};
diff --git a/pgadmin/include/images/module.mk b/pgadmin/include/images/module.mk
index be7dd53..44472b4 100644
--- a/pgadmin/include/images/module.mk
+++ b/pgadmin/include/images/module.mk
@@ -107,6 +107,7 @@ pgadmin3_SOURCES += \
 	$(srcdir)/include/images/file_open.xpm \
 	$(srcdir)/include/images/file_save.xpm \
 	$(srcdir)/include/images/folder.xpm \
+	$(srcdir)/include/images/foreigndatawrapper.xpm \
 	$(srcdir)/include/images/foreignkey.xpm \
 	$(srcdir)/include/images/forward.xpm \
 	$(srcdir)/include/images/function.xpm \
diff --git a/pgadmin/include/precomp.h b/pgadmin/include/precomp.h
index e10eb92..c5bb2ee 100644
--- a/pgadmin/include/precomp.h
+++ b/pgadmin/include/precomp.h
@@ -78,6 +78,7 @@
 #include "dlg/dlgDomain.h"
 #include "dlg/dlgEditGridOptions.h"
 #include "dlg/dlgFindReplace.h"
+#include "dlg/dlgForeignDataWrapper.h"
 #include "dlg/dlgForeignKey.h"
 #include "dlg/dlgFunction.h"
 #include "dlg/dlgGroup.h"
@@ -169,6 +170,7 @@
 #include "schema/pgDatabase.h"
 #include "schema/pgDatatype.h"
 #include "schema/pgDomain.h"
+#include "schema/pgForeignDataWrapper.h"
 #include "schema/pgForeignKey.h"
 #include "schema/pgFunction.h"
 #include "schema/pgGroup.h"
diff --git a/pgadmin/include/schema/module.mk b/pgadmin/include/schema/module.mk
index d44d6a0..92970dc 100644
--- a/pgadmin/include/schema/module.mk
+++ b/pgadmin/include/schema/module.mk
@@ -26,6 +26,7 @@ pgadmin3_SOURCES += \
 	$(srcdir)/include/schema/pgDatabase.h \
 	$(srcdir)/include/schema/pgDatatype.h \
 	$(srcdir)/include/schema/pgDomain.h \
+	$(srcdir)/include/schema/pgForeignDataWrapper.h \
 	$(srcdir)/include/schema/pgForeignKey.h \
 	$(srcdir)/include/schema/pgFunction.h \
 	$(srcdir)/include/schema/pgGroup.h \
diff --git a/pgadmin/include/schema/pgForeignDataWrapper.h b/pgadmin/include/schema/pgForeignDataWrapper.h
new file mode 100644
index 0000000..543103f
--- /dev/null
+++ b/pgadmin/include/schema/pgForeignDataWrapper.h
@@ -0,0 +1,77 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+// RCS-ID:      $Id$
+// Copyright (C) 2002 - 2010, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// pgForeignDataWrapper.h PostgreSQL Foreign Data Wrapper
+//
+//////////////////////////////////////////////////////////////////////////
+
+#ifndef PGFOREIGNDATAWRAPPER_H
+#define PGFOREIGNDATAWRAPPER_H
+
+#include "pgDatabase.h"
+
+class pgCollection;
+class pgForeignDataWrapperFactory : public pgDatabaseObjFactory
+{
+public:
+	pgForeignDataWrapperFactory();
+	virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent);
+	virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString);
+};
+extern pgForeignDataWrapperFactory foreignDataWrapperFactory;
+
+class pgForeignDataWrapper : public pgDatabaseObject
+{
+public:
+	pgForeignDataWrapper(const wxString &newName = wxT(""));
+
+	void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0);
+	bool CanDropCascaded()
+	{
+		return true;
+	}
+
+	wxString GetValidatorProc() const
+	{
+		return validatorProc;
+	}
+	void iSetValidatorProc(const wxString &s)
+	{
+		validatorProc = s;
+	}
+	wxString GetOptions() const
+	{
+		return options;
+	}
+	wxString GetCreateOptions();
+	void iSetOptions(const wxString &s)
+	{
+		options = s;
+	}
+
+	bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded);
+	wxString GetSql(ctlTree *browser);
+	pgObject *Refresh(ctlTree *browser, const wxTreeItemId item);
+
+	bool HasStats()
+	{
+		return false;
+	}
+	bool HasDepends()
+	{
+		return true;
+	}
+	bool HasReferences()
+	{
+		return true;
+	}
+
+private:
+	wxString validatorProc, options;
+};
+
+#endif
diff --git a/pgadmin/include/utils/pgDefs.h b/pgadmin/include/utils/pgDefs.h
index 38d83d9..893bd03 100644
--- a/pgadmin/include/utils/pgDefs.h
+++ b/pgadmin/include/utils/pgDefs.h
@@ -36,6 +36,7 @@
 #define PGOID_TYPE_FLOAT8                   701L
 #define PGOID_TYPE_MONEY                    790L
 #define PGOID_TYPE_CHAR_ARRAY               1002L
+#define PGOID_TYPE_TEXT_ARRAY               1009L
 #define PGOID_TYPE_BPCHAR_ARRAY             1014L
 #define PGOID_TYPE_VARCHAR_ARRAY            1015L
 #define PGOID_TYPE_BPCHAR                   1042L
diff --git a/pgadmin/schema/module.mk b/pgadmin/schema/module.mk
index d193aec..ae6b506 100644
--- a/pgadmin/schema/module.mk
+++ b/pgadmin/schema/module.mk
@@ -28,6 +28,7 @@ pgadmin3_SOURCES += \
         $(subdir)/pgDatabase.cpp \
         $(subdir)/pgDatatype.cpp \
         $(subdir)/pgDomain.cpp \
+        $(subdir)/pgForeignDataWrapper.cpp \
         $(subdir)/pgForeignKey.cpp \
         $(subdir)/pgFunction.cpp \
         $(subdir)/pgGroup.cpp \
diff --git a/pgadmin/schema/pgDatabase.cpp b/pgadmin/schema/pgDatabase.cpp
index 3528aa9..6a7492d 100644
--- a/pgadmin/schema/pgDatabase.cpp
+++ b/pgadmin/schema/pgDatabase.cpp
@@ -19,6 +19,7 @@
 #include "frm/frmMain.h"
 #include "schema/edbSynonym.h"
 #include "schema/pgCast.h"
+#include "schema/pgForeignDataWrapper.h"
 #include "schema/pgLanguage.h"
 #include "schema/pgSchema.h"
 #include "slony/slCluster.h"
@@ -130,6 +131,8 @@ wxMenu *pgDatabase::GetNewMenu()
 	{
 		if (settings->GetDisplayOption(_("Casts")))
 			castFactory.AppendMenu(menu);
+        if (settings->GetDisplayOption(_("Foreign Data Wrappers")))
+            foreignDataWrapperFactory.AppendMenu(menu);
 		if (settings->GetDisplayOption(_("Languages")))
 			languageFactory.AppendMenu(menu);
 		if (settings->GetDisplayOption(_("Synonyms")) && GetConnection()->EdbMinimumVersion(8, 0))
@@ -559,6 +562,8 @@ void pgDatabase::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *pr
 				browser->AppendCollection(this, catalogFactory);
 			if (settings->GetDisplayOption(_("Casts")))
 				browser->AppendCollection(this, castFactory);
+			if (settings->GetDisplayOption(_("Foreign Data Wrappers")))
+				browser->AppendCollection(this, foreignDataWrapperFactory);
 			if (settings->GetDisplayOption(_("Languages")))
 				browser->AppendCollection(this, languageFactory);
 			if (settings->GetDisplayOption(_("Synonyms")) && connection()->EdbMinimumVersion(8, 0))
diff --git a/pgadmin/schema/pgForeignDataWrapper.cpp b/pgadmin/schema/pgForeignDataWrapper.cpp
new file mode 100644
index 0000000..26d4bda
--- /dev/null
+++ b/pgadmin/schema/pgForeignDataWrapper.cpp
@@ -0,0 +1,169 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+// RCS-ID:      $Id$
+// Copyright (C) 2002 - 2010, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// pgForeignDataWrapper.cpp - Foreign Data Wrapper class
+//
+//////////////////////////////////////////////////////////////////////////
+
+// wxWindows headers
+#include <wx/wx.h>
+
+// App headers
+#include "pgAdmin3.h"
+#include "utils/misc.h"
+#include "schema/pgForeignDataWrapper.h"
+
+
+pgForeignDataWrapper::pgForeignDataWrapper(const wxString &newName)
+	: pgDatabaseObject(foreignDataWrapperFactory, newName)
+{
+}
+
+bool pgForeignDataWrapper::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded)
+{
+	wxString sql = wxT("DROP FOREIGN DATA WRAPPER ") + GetQuotedFullIdentifier();
+	if (cascaded)
+		sql += wxT(" CASCADE");
+	return GetDatabase()->ExecuteVoid(sql);
+}
+
+
+wxString pgForeignDataWrapper::GetSql(ctlTree *browser)
+{
+	if (sql.IsNull())
+	{
+		sql = wxT("-- Foreign Data Wrapper: ") + GetQuotedFullIdentifier() + wxT("\n\n")
+		      + wxT("-- DROP FOREIGN DATA WRAPPER ") + GetQuotedFullIdentifier() + wxT(";")
+		      + wxT("\n\nCREATE ");
+		sql += wxT("FOREIGN DATA WRAPPER ") + GetName();
+
+		if (!GetValidatorProc().IsEmpty())
+			sql += wxT("\n  VALIDATOR ") + GetValidatorProc();
+
+		if (!GetOptions().IsEmpty())
+			sql += wxT("\n  OPTIONS (") + GetCreateOptions() + wxT(")");
+
+		sql += wxT(";\n")
+		       +  GetOwnerSql(8, 4, wxT("FOREIGN DATA WRAPPER ") + GetName())
+		       +  GetGrant(wxT("U"), wxT("FOREIGN DATA WRAPPER ") + GetQuotedFullIdentifier());
+	}
+	return sql;
+}
+
+
+void pgForeignDataWrapper::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane)
+{
+	if (properties)
+	{
+		CreateListColumns(properties);
+
+		properties->AppendItem(_("Name"), GetName());
+		properties->AppendItem(_("OID"), GetOid());
+		properties->AppendItem(_("Owner"), GetOwner());
+		properties->AppendItem(_("ACL"), GetAcl());
+		properties->AppendItem(_("Validator"), GetValidatorProc());
+		properties->AppendItem(_("Options"), GetOptions());
+		properties->AppendItem(_("Comment"), firstLineOnly(GetComment()));
+	}
+}
+
+
+
+pgObject *pgForeignDataWrapper::Refresh(ctlTree *browser, const wxTreeItemId item)
+{
+	pgObject *fdw = 0;
+	pgCollection *coll = browser->GetParentCollection(item);
+	if (coll)
+		fdw = foreignDataWrapperFactory.CreateObjects(coll, 0, wxT("\n   WHERE fdw.oid=") + GetOidStr());
+
+	return fdw;
+}
+
+
+
+pgObject *pgForeignDataWrapperFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction)
+{
+	wxString sql;
+	pgForeignDataWrapper *fdw = 0;
+
+	sql = wxT("SELECT fdw.oid, fdwname, fdwvalidator, fdwacl, vp.proname as fdwval, description, ")
+	      wxT("array_to_string(fdwoptions, ',') AS fdwoptions, ")
+	      wxT("pg_get_userbyid(fdwowner) as fdwowner\n");
+	sql += wxT("  FROM pg_foreign_data_wrapper fdw\n")
+	       wxT("  LEFT OUTER JOIN pg_proc vp on vp.oid=fdwvalidator\n")
+	       wxT("  LEFT OUTER JOIN pg_description des ON des.objoid=fdw.oid AND des.objsubid=0\n")
+	       + restriction + wxT("\n")
+	       wxT(" ORDER BY fdwname");
+	pgSet *fdws = collection->GetDatabase()->ExecuteSet(sql);
+
+	if (fdws)
+	{
+		while (!fdws->Eof())
+		{
+
+			fdw = new pgForeignDataWrapper(fdws->GetVal(wxT("fdwname")));
+			fdw->iSetDatabase(collection->GetDatabase());
+			fdw->iSetOid(fdws->GetOid(wxT("oid")));
+			fdw->iSetOwner(fdws->GetVal(wxT("fdwowner")));
+			fdw->iSetAcl(fdws->GetVal(wxT("fdwacl")));
+			fdw->iSetComment(fdws->GetVal(wxT("description")));
+			fdw->iSetValidatorProc(fdws->GetVal(wxT("fdwval")));
+			fdw->iSetOptions(fdws->GetVal(wxT("fdwoptions")));
+
+			if (browser)
+			{
+				browser->AppendObject(collection, fdw);
+
+				fdws->MoveNext();
+			}
+			else
+				break;
+		}
+
+		delete fdws;
+	}
+	return fdw;
+}
+
+
+wxString pgForeignDataWrapper::GetCreateOptions()
+{
+	wxString options_create = wxEmptyString;
+	wxString opt;
+	wxString val;
+
+	wxStringTokenizer tkz_options(options, wxT(","));
+	while (tkz_options.HasMoreTokens())
+	{
+		wxStringTokenizer tkz_option(tkz_options.GetNextToken(), wxT("="));
+		opt = tkz_option.GetNextToken();
+		val = tkz_option.GetNextToken();
+
+		if (!options_create.IsEmpty())
+			options_create += wxT(",");
+
+		options_create += opt + wxT(" '") + val + wxT("'");
+	}
+
+	return options_create;
+}
+
+
+///////////////////////////////////////////////////
+
+#include "images/foreigndatawrapper.xpm"
+#include "images/foreigndatawrapper-sm.xpm"
+#include "images/foreigndatawrappers.xpm"
+
+pgForeignDataWrapperFactory::pgForeignDataWrapperFactory()
+	: pgDatabaseObjFactory(__("Foreign Data Wrapper"), __("New Foreign Data Wrapper..."), __("Create a new Foreign Data Wrapper."), foreigndatawrapper_xpm, foreigndatawrapper_sm_xpm)
+{
+}
+
+
+pgForeignDataWrapperFactory foreignDataWrapperFactory;
+static pgaCollectionFactory cf(&foreignDataWrapperFactory, __("Foreign Data Wrappers"), foreigndatawrappers_xpm);
diff --git a/pgadmin/ui/dlgForeignDataWrapper.xrc b/pgadmin/ui/dlgForeignDataWrapper.xrc
new file mode 100644
index 0000000..190228f
--- /dev/null
+++ b/pgadmin/ui/dlgForeignDataWrapper.xrc
@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<resource>
+  <object class="wxDialog" name="dlgForeignDataWrapper">
+    <title></title>
+    <size>220,250d</size>
+    <style>wxDEFAULT_DIALOG_STYLE|wxCAPTION|wxSYSTEM_MENU|wxRESIZE_BORDER|wxRESIZE_BOX|wxTHICK_FRAME</style>
+    <object class="wxFlexGridSizer">
+      <cols>1</cols>
+      <growablecols>0</growablecols>
+      <growablerows>0</growablerows>
+      <object class="sizeritem">
+        <object class="wxNotebook" name="nbNotebook">
+          <size>216,225d</size>
+          <selected>0</selected>
+          <object class="notebookpage">
+            <label>Properties</label>
+            <object class="wxPanel" name="pnlProperties">
+              <object class="wxFlexGridSizer">
+                <cols>2</cols>
+                <rows>6</rows>
+                <vgap>5</vgap>
+                <hgap>5</hgap>
+                <growablerows>4</growablerows>
+                <growablecols>1</growablecols>
+                <object class="sizeritem">
+                  <object class="wxStaticText" name="stName">
+                    <label>Name</label>
+                  </object>
+                  <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxTextCtrl" name="txtName">
+                    <size>135,-1d</size>
+                  </object>
+                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxStaticText" name="stOID">
+                    <label>OID</label>
+                  </object>
+                  <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxTextCtrl" name="txtOID">
+                    <size>135,-1d</size>
+                  </object>
+                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxStaticText" name="stOwner">
+                    <label>Owner</label>
+                  </object>
+                  <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="ctlComboBox" name="cbOwner">
+                    <size>135,-1d</size>
+                    <content/>
+                    <style>wxCB_DROPDOWN</style>
+                  </object>
+                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxStaticText" name="stValidator">
+                    <label>Validator</label>
+                  </object>
+                  <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="ctlComboBox" name="cbValidator">
+                    <content/>
+                    <size>135,-1d</size>
+                    <style>wxCB_DROPDOWN</style>
+                  </object>
+                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxStaticText" name="stComment">
+                    <label>Comment</label>
+                  </object>
+                  <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxTextCtrl" name="txtComment">
+                    <size>135,-1d</size>
+                    <style>wxTE_MULTILINE</style>
+                  </object>
+                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxStaticText" name="stClusterSet">
+                    <label>Use replication</label>
+                  </object>
+                  <flag>wxALIGN_CENTRE_VERTICAL|wxALL</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxComboBox" name="cbClusterSet">
+                    <content/>
+                    <size>135,-1d</size>
+                    <style>wxCB_READONLY|wxCB_DROPDOWN</style>
+                  </object>
+                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL</flag>
+                  <border>4</border>
+                </object>
+              </object>
+            </object>
+          </object>
+          <object class="notebookpage">
+            <label>Options</label>
+            <object class="wxPanel" name="pnlOptions">
+              <object class="wxFlexGridSizer">
+                <cols>1</cols>
+                <rows>3</rows>
+                <growablerows>0</growablerows>
+                <growablecols>0</growablecols>
+                <object class="sizeritem">
+                  <object class="wxListCtrl" name="lstOptions">
+                    <pos>70,15d</pos>
+                    <style>wxLC_REPORT|wxLC_SINGLE_SEL</style>
+                  </object>
+                  <option>80</option>
+                  <flag>wxALL|wxEXPAND</flag>
+                  <border>5</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxFlexGridSizer">
+                    <cols>2</cols>
+                    <rows>2</rows>
+                    <vgap>5</vgap>
+                    <hgap>5</hgap>
+                    <growablecols>1</growablecols>
+                    <object class="sizeritem">
+                      <object class="wxStaticText" name="stOption">
+                        <label>Option</label>
+                      </object>
+                      <flag>wxALIGN_CENTRE_VERTICAL</flag>
+                    </object>
+                    <object class="sizeritem">
+                      <object class="wxTextCtrl" name="txtOption">
+                        <size>135,-1d</size>
+                      </object>
+                      <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                      <border>4</border>
+                      <flag>wxEXPAND|wxALIGN_CENTRE_VERTICAL</flag>
+                    </object>
+                    <object class="sizeritem">
+                      <object class="wxStaticText" name="stValue">
+                        <label>Value</label>
+                      </object>
+                      <flag>wxALIGN_CENTRE_VERTICAL</flag>
+                    </object>
+                    <object class="sizeritem">
+                      <object class="wxTextCtrl" name="txtValue">
+                        <size>135,-1d</size>
+                      </object>
+                      <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                      <border>4</border>
+                      <flag>wxEXPAND|wxALIGN_CENTRE_VERTICAL</flag>
+                    </object>
+                  </object>
+                  <flag>wxALL|wxEXPAND|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL</flag>
+                  <border>5</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxFlexGridSizer">
+                    <cols>2</cols>
+                    <rows>1</rows>
+                    <object class="sizeritem">
+                      <object class="wxButton" name="wxID_REMOVE">
+                        <label>Remove</label>
+                        <pos>13,58d</pos>
+                      </object>
+                      <flag>wxALL|wxALIGN_RIGHT</flag>
+                      <border>2</border>
+                    </object>
+                    <object class="sizeritem">
+                      <object class="wxButton" name="wxID_ADD">
+                        <label>Add/Change</label>
+                        <pos>13,78d</pos>
+                      </object>
+                      <flag>wxALL|wxALIGN_RIGHT</flag>
+                      <border>2</border>
+                    </object>
+                  </object>
+                  <flag>wxALIGN_RIGHT</flag>
+                </object>
+              </object>
+            </object>
+          </object>
+        </object>
+        <flag>wxALL|wxGROW|wxALIGN_CENTRE</flag>
+        <border>3</border>
+      </object>
+      <object class="spacer">
+        <size>2,2d</size>
+      </object>
+      <object class="sizeritem">
+        <object class="wxFlexGridSizer">
+          <cols>7</cols>
+          <growablecols>2</growablecols>
+          <object class="spacer">
+            <size>3,3d</size>
+          </object>
+          <object class="sizeritem">
+            <object class="wxButton" name="wxID_HELP">
+              <label>Help</label>
+            </object>
+          </object>
+          <object class="spacer">
+            <size>3,3d</size>
+          </object>
+          <object class="sizeritem">
+            <object class="wxButton" name="wxID_OK">
+              <label>&amp;OK</label>
+              <default>1</default>
+            </object>
+          </object>
+          <object class="spacer">
+            <size>3,3d</size>
+          </object>
+          <object class="sizeritem">
+            <object class="wxButton" name="wxID_CANCEL">
+              <label>&amp;Cancel</label>
+            </object>
+          </object>
+          <object class="spacer">
+            <size>3,3d</size>
+          </object>
+        </object>
+        <flag>wxTOP|wxLEFT|wxRIGHT|wxGROW</flag>
+      </object>
+      <object class="spacer">
+        <size>3,3d</size>
+      </object>
+      <object class="sizeritem">
+        <object class="wxStatusBar" name="unkStatusBar">
+          <style>wxST_SIZEGRIP</style>
+        </object>
+        <flag>wxGROW|wxALIGN_CENTRE</flag>
+        <border>3</border>
+      </object>
+    </object>
+  </object>
+</resource>
diff --git a/pgadmin/ui/module.mk b/pgadmin/ui/module.mk
index b6d77ec..9ff1b6d 100644
--- a/pgadmin/ui/module.mk
+++ b/pgadmin/ui/module.mk
@@ -26,6 +26,7 @@ TMP_ui += \
 	$(srcdir)/ui/dlgEditGridOptions.xrc \
 	$(srcdir)/ui/dlgExtTable.xrc \
 	$(srcdir)/ui/dlgFindReplace.xrc \
+	$(srcdir)/ui/dlgForeignDataWrapper.xrc \
 	$(srcdir)/ui/dlgForeignKey.xrc \
 	$(srcdir)/ui/dlgFunction.xrc \
 	$(srcdir)/ui/dlgGroup.xrc \
diff --git a/pgadmin/utils/sysSettings.cpp b/pgadmin/utils/sysSettings.cpp
index 2c16387..7153ca2 100644
--- a/pgadmin/utils/sysSettings.cpp
+++ b/pgadmin/utils/sysSettings.cpp
@@ -84,6 +84,11 @@ bool sysSettings::GetDisplayOption(const wxString &objtype, bool GetDefault)
 		engtype = wxT("Casts");
 		def = false;
 	}
+    else if (objtype == _("Foreign Data Wrappers")) 
+    {
+        engtype = wxT("Foreign Data Wrappers");
+        def = false;
+    }
 	else if (objtype == _("Languages"))
 	{
 		engtype = wxT("Languages");
@@ -173,6 +178,7 @@ void sysSettings::SetDisplayOption(const wxString &objtype, bool display)
 	else if (objtype == _("Resource Queues")) engtype = wxT("Resource Queues");
 	else if (objtype == _("Catalogs")) engtype = wxT("Catalogs");
 	else if (objtype == _("Casts")) engtype = wxT("Casts");
+    else if (objtype == _("Foreign Data Wrappers")) engtype = wxT("Foreign Data Wrappers");
 	else if (objtype == _("Languages")) engtype = wxT("Languages");
 	else if (objtype == _("Synonyms")) engtype = wxT("Synonyms");
 	else if (objtype == _("Schemas")) engtype = wxT("Schemas");
-- 
1.7.1

