Graphical query builder [Luis Ochoa - GSoC]
authordpage <dpage@a7884b65-44f6-0310-8a51-81a127f17b15>
Tue, 19 Aug 2008 15:32:25 +0000 (15:32 +0000)
committerdpage <dpage@a7884b65-44f6-0310-8a51-81a127f17b15>
Tue, 19 Aug 2008 15:32:25 +0000 (15:32 +0000)
git-svn-id: svn://svn.pgadmin.org/trunk/pgadmin3@7404 a7884b65-44f6-0310-8a51-81a127f17b15

64 files changed:
CHANGELOG
pgadmin/Makefile.am
pgadmin/frm/frmQuery.cpp
pgadmin/gqb/gqbArrayCollection.cpp [new file with mode: 0644]
pgadmin/gqb/gqbBrowser.cpp [new file with mode: 0644]
pgadmin/gqb/gqbCollection.cpp [new file with mode: 0644]
pgadmin/gqb/gqbColumn.cpp [new file with mode: 0644]
pgadmin/gqb/gqbController.cpp [new file with mode: 0644]
pgadmin/gqb/gqbDatabase.cpp [new file with mode: 0644]
pgadmin/gqb/gqbGraphSimple.cpp [new file with mode: 0644]
pgadmin/gqb/gqbGridOrderTable.cpp [new file with mode: 0644]
pgadmin/gqb/gqbGridProjTable.cpp [new file with mode: 0644]
pgadmin/gqb/gqbGridRestTable.cpp [new file with mode: 0644]
pgadmin/gqb/gqbModel.cpp [new file with mode: 0644]
pgadmin/gqb/gqbObject.cpp [new file with mode: 0644]
pgadmin/gqb/gqbObjectCollection.cpp [new file with mode: 0644]
pgadmin/gqb/gqbQueryObjs.cpp [new file with mode: 0644]
pgadmin/gqb/gqbSchema.cpp [new file with mode: 0644]
pgadmin/gqb/gqbTable.cpp [new file with mode: 0644]
pgadmin/gqb/gqbView.cpp [new file with mode: 0644]
pgadmin/gqb/gqbViewPanels.cpp [new file with mode: 0644]
pgadmin/gqb/module.mk [new file with mode: 0644]
pgadmin/include/frm/frmQuery.h
pgadmin/include/frm/menu.h
pgadmin/include/gqb/gqbArrayCollection.h [new file with mode: 0644]
pgadmin/include/gqb/gqbBrowser.h [new file with mode: 0644]
pgadmin/include/gqb/gqbCollection.h [new file with mode: 0644]
pgadmin/include/gqb/gqbCollectionBase.h [new file with mode: 0644]
pgadmin/include/gqb/gqbColumn.h [new file with mode: 0644]
pgadmin/include/gqb/gqbDatabase.h [new file with mode: 0644]
pgadmin/include/gqb/gqbEvents.h [new file with mode: 0644]
pgadmin/include/gqb/gqbGraphBehavior.h [new file with mode: 0644]
pgadmin/include/gqb/gqbGraphSimple.h [new file with mode: 0644]
pgadmin/include/gqb/gqbGridOrderTable.h [new file with mode: 0644]
pgadmin/include/gqb/gqbGridProjTable.h [new file with mode: 0644]
pgadmin/include/gqb/gqbGridRestTable.h [new file with mode: 0644]
pgadmin/include/gqb/gqbModel.h [new file with mode: 0644]
pgadmin/include/gqb/gqbObject.h [new file with mode: 0644]
pgadmin/include/gqb/gqbObjectCollection.h [new file with mode: 0644]
pgadmin/include/gqb/gqbQueryObjs.h [new file with mode: 0644]
pgadmin/include/gqb/gqbSchema.h [new file with mode: 0644]
pgadmin/include/gqb/gqbTable.h [new file with mode: 0644]
pgadmin/include/gqb/gqbViewController.h [new file with mode: 0644]
pgadmin/include/gqb/gqbViewPanels.h [new file with mode: 0644]
pgadmin/include/gqb/module.mk [new file with mode: 0644]
pgadmin/include/images/gqbAddRest.xpm [new file with mode: 0644]
pgadmin/include/images/gqbColNotSel.xpm [new file with mode: 0644]
pgadmin/include/images/gqbColSel.xpm [new file with mode: 0644]
pgadmin/include/images/gqbDown.xpm [new file with mode: 0644]
pgadmin/include/images/gqbDownBottom.xpm [new file with mode: 0644]
pgadmin/include/images/gqbJoin.xpm [new file with mode: 0644]
pgadmin/include/images/gqbJoinCursor.xpm [new file with mode: 0644]
pgadmin/include/images/gqbOrderAdd.xpm [new file with mode: 0644]
pgadmin/include/images/gqbOrderAddAll.xpm [new file with mode: 0644]
pgadmin/include/images/gqbOrderRemove.xpm [new file with mode: 0644]
pgadmin/include/images/gqbOrderRemoveAll.xpm [new file with mode: 0644]
pgadmin/include/images/gqbRemoveRest.xpm [new file with mode: 0644]
pgadmin/include/images/gqbUp.xpm [new file with mode: 0644]
pgadmin/include/images/gqbUpTop.xpm [new file with mode: 0644]
pgadmin/include/module.mk
pgadmin/include/precomp.h
pgadmin/pgAdmin3.vcproj
xtra/pgaevent/pgaevent.vcproj
xtra/pgagent/pgAgent.vcproj

index c3f4587976e7b4b2523bc2198a72d775566c5bea..afff2bae2bd2e792c33b9e416faf9322f3c45887 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -36,6 +36,7 @@ Changes
 \r
 Date       Dev Ver    Change details\r
 ---------- --- -----  --------------\r
+2008-08-19 DP  1.9.0  Graphical query builder [Luis Ochoa - GSoC]\r
 2008-08-11 GL  1.9.0  Support for FTS objects.\r
 2008-08-11 GL  1.9.0  Support for adding/removing inherited tables with 8.2+\r
                       servers.\r
index 97624f25c4140d9ad3463c3c53549d3e8e272160..f558c43b407fcf8f2abb395ea7146d0c1741bcec 100644 (file)
@@ -39,6 +39,7 @@ include $(srcdir)/frm/module.mk
 include $(srcdir)/include/module.mk
 include $(srcdir)/schema/module.mk
 include $(srcdir)/slony/module.mk
+include $(srcdir)/gqb/module.mk
 include $(srcdir)/ui/module.mk
 include $(srcdir)/utils/module.mk
 
index 7a3ca4078b2892e03f107c1efeb58caf60f74707..61d9e9a20c852e6a7afad200ffe37aa3b6060f57 100644 (file)
 
 // wxWindows headers
 #include <wx/wx.h>
-#include <wx/regex.h>
+#include <wx/busyinfo.h>
+#include <wx/clipbrd.h>
+#include <wx/dcbuffer.h>
 #include <wx/filename.h>
+#include <wx/regex.h>
+#include <wx/textctrl.h>
 #include <wx/timer.h>
-
-// wxAUI
 #include <wx/aui/aui.h>
 
 // App headers
 
 #include "ctl/ctlMenuToolbar.h"
 #include "ctl/ctlSQLResult.h"
-#include "schema/pgDatabase.h"
-#include "schema/pgTable.h"
-#include "schema/pgView.h"
 #include "dlg/dlgSelectConnection.h"
 #include "dlg/dlgAddFavourite.h"
 #include "dlg/dlgManageFavourites.h"
 #include "dlg/dlgManageMacros.h"
+#include "frm/frmReport.h"
+#include "gqb/gqbViewController.h"
+#include "gqb/gqbModel.h"
+#include "gqb/gqbViewPanels.h"
+#include "gqb/gqbEvents.h"
+#include "schema/pgDatabase.h"
+#include "schema/pgTable.h"
+#include "schema/pgView.h"
+#include "schema/pgServer.h"
 #include "utils/favourites.h"
 #include "utils/sysLogger.h"
 #include "utils/utffile.h"
-#include "frm/frmReport.h"
-
-#include <wx/clipbrd.h>
 
 // Icons
 #include "images/sql.xpm"
+
 // Bitmaps
 #include "images/file_new.xpm"
 #include "images/file_open.xpm"
 #include "images/query_explain.xpm"
 #include "images/query_cancel.xpm"
 #include "images/help.xpm"
-
+#include "images/gqbJoin.xpm"
 
 #define CTRLID_CONNECTION       4200
 #define CTRLID_DATABASELABEL    4201
 
 BEGIN_EVENT_TABLE(frmQuery, pgFrame)
-    EVT_ERASE_BACKGROUND(           frmQuery::OnEraseBackground)
-    EVT_SIZE(                       frmQuery::OnSize)
-    EVT_COMBOBOX(CTRLID_CONNECTION, frmQuery::OnChangeConnection)
-    EVT_CLOSE(                      frmQuery::OnClose)
-    EVT_SET_FOCUS(                  frmQuery::OnSetFocus)
-    EVT_MENU(MNU_NEW,               frmQuery::OnNew)
-    EVT_MENU(MNU_OPEN,              frmQuery::OnOpen)
-    EVT_MENU(MNU_SAVE,              frmQuery::OnSave)
-    EVT_MENU(MNU_SAVEAS,            frmQuery::OnSaveAs)
-    EVT_MENU(MNU_EXPORT,            frmQuery::OnExport)
-    EVT_MENU(MNU_EXIT,              frmQuery::OnExit)
-    EVT_MENU(MNU_CUT,               frmQuery::OnCut)
-    EVT_MENU(MNU_COPY,              frmQuery::OnCopy)
-    EVT_MENU(MNU_PASTE,             frmQuery::OnPaste)
-    EVT_MENU(MNU_CLEAR,             frmQuery::OnClear)
-    EVT_MENU(MNU_FIND,              frmQuery::OnSearchReplace)
-    EVT_MENU(MNU_UNDO,              frmQuery::OnUndo)
-    EVT_MENU(MNU_REDO,              frmQuery::OnRedo)
-    EVT_MENU(MNU_EXECUTE,           frmQuery::OnExecute)
-    EVT_MENU(MNU_EXECFILE,          frmQuery::OnExecFile)
-    EVT_MENU(MNU_EXPLAIN,           frmQuery::OnExplain)
-    EVT_MENU(MNU_CANCEL,            frmQuery::OnCancel)
-    EVT_MENU(MNU_CONTENTS,          frmQuery::OnContents)
-    EVT_MENU(MNU_HELP,              frmQuery::OnHelp)
-    EVT_MENU(MNU_CLEARHISTORY,      frmQuery::OnClearHistory)
-    EVT_MENU(MNU_SAVEHISTORY,       frmQuery::OnSaveHistory)
-    EVT_MENU(MNU_SELECTALL,         frmQuery::OnSelectAll)
-    EVT_MENU(MNU_QUICKREPORT,       frmQuery::OnQuickReport)
-    EVT_MENU(MNU_AUTOINDENT,        frmQuery::OnAutoIndent)
-    EVT_MENU(MNU_WORDWRAP,          frmQuery::OnWordWrap)
-    EVT_MENU(MNU_SHOWINDENTGUIDES,  frmQuery::OnShowIndentGuides)
-    EVT_MENU(MNU_SHOWWHITESPACE,    frmQuery::OnShowWhitespace)
-    EVT_MENU(MNU_SHOWLINEENDS,      frmQuery::OnShowLineEnds)
-    EVT_MENU(MNU_FAVOURITES_ADD,    frmQuery::OnAddFavourite)
-    EVT_MENU(MNU_FAVOURITES_MANAGE, frmQuery::OnManageFavourites)
-       EVT_MENU(MNU_MACROS_MANAGE,             frmQuery::OnMacroManage)
-    EVT_MENU(MNU_DATABASEBAR,       frmQuery::OnToggleDatabaseBar)
-    EVT_MENU(MNU_TOOLBAR,           frmQuery::OnToggleToolBar)
-    EVT_MENU(MNU_SCRATCHPAD,        frmQuery::OnToggleScratchPad)
-    EVT_MENU(MNU_OUTPUTPANE,        frmQuery::OnToggleOutputPane)
-    EVT_MENU(MNU_DEFAULTVIEW,       frmQuery::OnDefaultView)
-    EVT_MENU(MNU_LF,                frmQuery::OnSetEOLMode)
-    EVT_MENU(MNU_CRLF,              frmQuery::OnSetEOLMode)
-    EVT_MENU(MNU_CR,                frmQuery::OnSetEOLMode)
-    EVT_MENU_RANGE(MNU_FAVOURITES_MANAGE+1, MNU_FAVOURITES_MANAGE+999, frmQuery::OnSelectFavourite)
-    EVT_MENU_RANGE(MNU_MACROS_MANAGE+1, MNU_MACROS_MANAGE+99, frmQuery::OnMacroInvoke)
-    EVT_ACTIVATE(                   frmQuery::OnActivate)
-    EVT_STC_MODIFIED(CTL_SQLQUERY,  frmQuery::OnChangeStc)
-    EVT_STC_UPDATEUI(CTL_SQLQUERY,  frmQuery::OnPositionStc)
-    EVT_AUI_PANE_CLOSE(             frmQuery::OnAuiUpdate)
-
-    EVT_TIMER(wxID_ANY,             frmQuery::OnTimer)
-
-    // These fire when the queries complete
-    EVT_MENU(QUERY_COMPLETE,        frmQuery::OnQueryComplete)
+EVT_ERASE_BACKGROUND(           frmQuery::OnEraseBackground)
+EVT_SIZE(                       frmQuery::OnSize)
+EVT_COMBOBOX(CTRLID_CONNECTION, frmQuery::OnChangeConnection)
+EVT_CLOSE(                      frmQuery::OnClose)
+EVT_SET_FOCUS(                  frmQuery::OnSetFocus)
+EVT_MENU(MNU_NEW,               frmQuery::OnNew)
+EVT_MENU(MNU_OPEN,              frmQuery::OnOpen)
+EVT_MENU(MNU_SAVE,              frmQuery::OnSave)
+EVT_MENU(MNU_SAVEAS,            frmQuery::OnSaveAs)
+EVT_MENU(MNU_EXPORT,            frmQuery::OnExport)
+EVT_MENU(MNU_EXIT,              frmQuery::OnExit)
+EVT_MENU(MNU_CUT,               frmQuery::OnCut)
+EVT_MENU(MNU_COPY,              frmQuery::OnCopy)
+EVT_MENU(MNU_PASTE,             frmQuery::OnPaste)
+EVT_MENU(MNU_CLEAR,             frmQuery::OnClear)
+EVT_MENU(MNU_FIND,              frmQuery::OnSearchReplace)
+EVT_MENU(MNU_UNDO,              frmQuery::OnUndo)
+EVT_MENU(MNU_REDO,              frmQuery::OnRedo)
+EVT_MENU(MNU_EXECUTE,           frmQuery::OnExecute)
+EVT_MENU(MNU_EXECFILE,          frmQuery::OnExecFile)
+EVT_MENU(MNU_EXPLAIN,           frmQuery::OnExplain)
+EVT_MENU(MNU_CANCEL,            frmQuery::OnCancel)
+EVT_MENU(MNU_CONTENTS,          frmQuery::OnContents)
+EVT_MENU(MNU_HELP,              frmQuery::OnHelp)
+EVT_MENU(MNU_CLEARHISTORY,      frmQuery::OnClearHistory)
+EVT_MENU(MNU_SAVEHISTORY,       frmQuery::OnSaveHistory)
+EVT_MENU(MNU_SELECTALL,         frmQuery::OnSelectAll)
+EVT_MENU(MNU_QUICKREPORT,       frmQuery::OnQuickReport)
+EVT_MENU(MNU_AUTOINDENT,        frmQuery::OnAutoIndent)
+EVT_MENU(MNU_WORDWRAP,          frmQuery::OnWordWrap)
+EVT_MENU(MNU_SHOWINDENTGUIDES,  frmQuery::OnShowIndentGuides)
+EVT_MENU(MNU_SHOWWHITESPACE,    frmQuery::OnShowWhitespace)
+EVT_MENU(MNU_SHOWLINEENDS,      frmQuery::OnShowLineEnds)
+EVT_MENU(MNU_FAVOURITES_ADD,    frmQuery::OnAddFavourite)
+EVT_MENU(MNU_FAVOURITES_MANAGE, frmQuery::OnManageFavourites)
+EVT_MENU(MNU_MACROS_MANAGE,     frmQuery::OnMacroManage)
+EVT_MENU(MNU_DATABASEBAR,       frmQuery::OnToggleDatabaseBar)
+EVT_MENU(MNU_TOOLBAR,           frmQuery::OnToggleToolBar)
+EVT_MENU(MNU_SCRATCHPAD,        frmQuery::OnToggleScratchPad)
+EVT_MENU(MNU_OUTPUTPANE,        frmQuery::OnToggleOutputPane)
+EVT_MENU(MNU_DEFAULTVIEW,       frmQuery::OnDefaultView)
+EVT_MENU(MNU_LF,                frmQuery::OnSetEOLMode)
+EVT_MENU(MNU_CRLF,              frmQuery::OnSetEOLMode)
+EVT_MENU(MNU_CR,                frmQuery::OnSetEOLMode)
+EVT_MENU_RANGE(MNU_FAVOURITES_MANAGE+1, MNU_FAVOURITES_MANAGE+999, frmQuery::OnSelectFavourite)
+EVT_MENU_RANGE(MNU_MACROS_MANAGE+1, MNU_MACROS_MANAGE+99, frmQuery::OnMacroInvoke)
+EVT_ACTIVATE(                   frmQuery::OnActivate)
+EVT_STC_MODIFIED(CTL_SQLQUERY,  frmQuery::OnChangeStc)
+EVT_STC_UPDATEUI(CTL_SQLQUERY,  frmQuery::OnPositionStc)
+EVT_AUI_PANE_CLOSE(             frmQuery::OnAuiUpdate)
+EVT_TIMER(CTL_TIMERSIZES,       frmQuery::OnAdjustSizesTimer)
+EVT_TIMER(CTL_TIMERFRM,         frmQuery::OnTimer)
+// These fire when the queries complete
+EVT_MENU(QUERY_COMPLETE,        frmQuery::OnQueryComplete)
+EVT_NOTEBOOK_PAGE_CHANGED(CTL_NTBKCENTER, frmQuery::OnChangeNotebook)
+EVT_SPLITTER_SASH_POS_CHANGED(GQB_HORZ_SASH, frmQuery::onResizeHorizontally)
 END_EVENT_TABLE()
 
 frmQuery::frmQuery(frmMain *form, const wxString& _title, pgConn *_conn, const wxString& query, const wxString& file)
 : pgFrame(NULL, _title),
-  timer(this)
+timer(this,CTL_TIMERFRM)
 {
     mainForm=form;
     conn=_conn;
 
-       loading = true;
+    loading = true;
     closing = false;
 
     dlgName = wxT("frmQuery");
     recentKey = wxT("RecentFiles");
     RestorePosition(100, 100, 600, 500, 450, 300);
 
-    // notify wxAUI which frame to use
+       // notify wxAUI which frame to use
     manager.SetManagedWindow(this);
     manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG);
 
@@ -184,9 +191,10 @@ frmQuery::frmQuery(frmMain *form, const wxString& _title, pgConn *_conn, const w
     menuBar->Append(editMenu, _("&Edit"));
 
     queryMenu = new wxMenu();
-    queryMenu->Append(MNU_EXECUTE, _("&Execute\tF5"), _("Execute query"));
-    queryMenu->Append(MNU_EXECFILE, _("Execute to file"), _("Execute query, write result to file"));
+    queryMenu->Append(MNU_EXECUTE, _("&Execute\tF5"), _("Execute query / Generate SQL from Graphical Query Builder Model"));
+    queryMenu->Append(MNU_EXECFILE, _("Execute to file"), _("Execute query, write result to file / Generate SQL from Graphical Query Builder Model"));
     queryMenu->Append(MNU_EXPLAIN, _("E&xplain\tF7"), _("Explain query"));
+    
 
     wxMenu *eo=new wxMenu();
     eo->Append(MNU_VERBOSE, _("Verbose"), _("Explain verbose query"), wxITEM_CHECK);
@@ -207,14 +215,14 @@ frmQuery::frmQuery(frmMain *form, const wxString& _title, pgConn *_conn, const w
     UpdateFavouritesList();
     menuBar->Append(favouritesMenu, _("Fav&ourites"));
 
-       macrosMenu = new wxMenu();
-       macrosMenu->Append(MNU_MACROS_MANAGE, _("Manage macros..."), _("Edit and delete macros"));
-       macrosMenu->AppendSeparator();
-       macros = queryMacroFileProvider::LoadMacros(true);
-       UpdateMacrosList();
-       menuBar->Append(macrosMenu, _("&Macros"));
+    macrosMenu = new wxMenu();
+    macrosMenu->Append(MNU_MACROS_MANAGE, _("Manage macros..."), _("Edit and delete macros"));
+    macrosMenu->AppendSeparator();
+    macros = queryMacroFileProvider::LoadMacros(true);
+    UpdateMacrosList();
+    menuBar->Append(macrosMenu, _("&Macros"));
 
-    // View menu
+       // View menu
     viewMenu = new wxMenu();
     viewMenu->Append(MNU_DATABASEBAR, _("&Database bar\tCtrl-Alt-B"), _("Show or hide the database selection bar."), wxITEM_CHECK);
     viewMenu->Append(MNU_OUTPUTPANE, _("&Output pane\tCtrl-Alt-O"), _("Show or hide the output pane."), wxITEM_CHECK);
@@ -233,8 +241,8 @@ frmQuery::frmQuery(frmMain *form, const wxString& _title, pgConn *_conn, const w
     wxMenu *helpMenu=new wxMenu();
     helpMenu->Append(MNU_CONTENTS, _("&Help"),                 _("Open the helpfile."));
     helpMenu->Append(MNU_HELP, _("&SQL Help\tF1"),                _("Display help on SQL commands."));
-    menuBar->Append(helpMenu, _("&Help"));
 
+    menuBar->Append(helpMenu, _("&Help"));
 
     SetMenuBar(menuBar);
 
@@ -287,8 +295,8 @@ frmQuery::frmQuery(frmMain *form, const wxString& _title, pgConn *_conn, const w
     toolBar->AddTool(MNU_FIND, _("Find"), wxBitmap(edit_find_xpm), _("Find and replace text"), wxITEM_NORMAL);
     toolBar->AddSeparator();
 
-    toolBar->AddTool(MNU_EXECUTE, _("Execute"), wxBitmap(query_execute_xpm), _("Execute query"), wxITEM_NORMAL);
-    toolBar->AddTool(MNU_EXECFILE, _("Execute to file"), wxBitmap(query_execfile_xpm), _("Execute query, write result to file"), wxITEM_NORMAL);
+    toolBar->AddTool(MNU_EXECUTE, _("Execute"), wxBitmap(query_execute_xpm), _("Execute query / Generate SQL from Graphical Query Builder Model"), wxITEM_NORMAL);
+    toolBar->AddTool(MNU_EXECFILE, _("Execute to file"), wxBitmap(query_execfile_xpm), _("Execute query, write result to file / Generate SQL from Graphical Query Builder Model"), wxITEM_NORMAL);
     toolBar->AddTool(MNU_EXPLAIN, _("Explain"), wxBitmap(query_explain_xpm), _("Explain query"), wxITEM_NORMAL);
     toolBar->AddTool(MNU_CANCEL, _("Cancel"), wxBitmap(query_cancel_xpm), _("Cancel query"), wxITEM_NORMAL);
     toolBar->AddSeparator();
@@ -296,25 +304,43 @@ frmQuery::frmQuery(frmMain *form, const wxString& _title, pgConn *_conn, const w
     toolBar->AddTool(MNU_HELP, _("Help"), wxBitmap(help_xpm), _("Display help on SQL commands."), wxITEM_NORMAL);
     toolBar->Realize();
 
-    // Add the database selection bar
+       // Add the database selection bar
     cbConnection = new ctlComboBoxFix(this, CTRLID_CONNECTION, wxDefaultPosition, wxSize(-1, -1), wxCB_READONLY|wxCB_DROPDOWN);
     cbConnection->Append(conn->GetName(), (void*)conn);
     cbConnection->Append(_("<new connection>"), (void*)0);
 
-    // Query box
-    sqlQuery = new ctlSQLBox(this, CTL_SQLQUERY, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSIMPLE_BORDER | wxTE_RICH2);
+       //Create SQL editor notebook
+    sqlNotebook = new wxNotebook(this, CTL_NTBKCENTER, wxDefaultPosition, wxDefaultSize);
+
+       // Query box
+    sqlQuery = new ctlSQLBox(sqlNotebook, CTL_SQLQUERY, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSIMPLE_BORDER | wxTE_RICH2);
     sqlQuery->SetDatabase(conn);
     sqlQuery->SetMarginWidth(1, 16);
     SetEOLModeDisplay(sqlQuery->GetEOLMode());
 
-    // Results pane
-    outputPane = new wxNotebook(this, -1, wxDefaultPosition, wxSize(500, 300));
+       // Results pane
+       // TODO change number 9999 by a correct one & should use static event instead?
+    outputPane = new wxNotebook(this, 9999, wxDefaultPosition, wxSize(500, 300));
     sqlResult = new ctlSQLResult(outputPane, conn, CTL_SQLRESULT, wxDefaultPosition, wxDefaultSize);
     explainCanvas = new ExplainCanvas(outputPane);
     msgResult = new wxTextCtrl(outputPane, CTL_MSGRESULT, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_DONTWRAP);
     msgResult->SetFont(settings->GetSQLFont());
     msgHistory = new wxTextCtrl(outputPane, CTL_MSGHISTORY, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_DONTWRAP);
     msgHistory->SetFont(settings->GetSQLFont());
+
+       // Graphical Canvas
+       // initialize values
+    model=new gqbModel();
+    controller = new gqbController(model,sqlNotebook, outputPane, wxSize(1280,800));
+    firstTime=true;                               // Inform to GQB that the tree of table haven't filled.
+       firstGeneration=true;                         // Allow to ask if a query can be overwrite by a new one generate with GQB
+    adjustSizesTimer=NULL;                        // Timer used to avoid a bug when close outputPane
+
+       // Setup SQL editor notebook NBP_SQLEDTR
+    sqlNotebook->AddPage(sqlQuery, _("SQL Editor"));
+    sqlNotebook->AddPage(controller->getViewContainer(), _("Graphical Query Builder"));
+    sqlNotebook->SetSelection(0);
+
     outputPane->AddPage(sqlResult, _("Data Output"));
     outputPane->AddPage(explainCanvas, _("Explain"));
     outputPane->AddPage(msgResult, _("Messages"));
@@ -325,40 +351,36 @@ frmQuery::frmQuery(frmMain *form, const wxString& _title, pgConn *_conn, const w
     msgResult->Connect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus));
     msgHistory->Connect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus));
 
-    // Finally, the scratchpad
+       // Now, the scratchpad
     scratchPad = new wxTextCtrl(this, -1, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxHSCROLL);
 
-    // Kickstart wxAUI
+       // Kickstart wxAUI
     manager.AddPane(toolBar, wxAuiPaneInfo().Name(wxT("toolBar")).Caption(_("Tool bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false));
     manager.AddPane(cbConnection, wxAuiPaneInfo().Name(wxT("databaseBar")).Caption(_("Database bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false));
-    manager.AddPane(sqlQuery, wxAuiPaneInfo().Name(wxT("sqlQuery")).Caption(_("SQL query")).Center().CaptionVisible(false).CloseButton(false).MinSize(wxSize(200,100)).BestSize(wxSize(350,200)));
     manager.AddPane(outputPane, wxAuiPaneInfo().Name(wxT("outputPane")).Caption(_("Output pane")).Bottom().MinSize(wxSize(200,100)).BestSize(wxSize(550,300)));
     manager.AddPane(scratchPad, wxAuiPaneInfo().Name(wxT("scratchPad")).Caption(_("Scratch pad")).Right().MinSize(wxSize(100,100)).BestSize(wxSize(250,200)));
+    manager.AddPane(sqlNotebook, wxAuiPaneInfo().Name(wxT("sqlQuery")).Caption(_("SQL query")).Center().CaptionVisible(false).CloseButton(false).MinSize(wxSize(200,100)).BestSize(wxSize(350,200)));
 
-    // Now load the layout
-    wxString perspective;
-    settings->Read(wxT("frmQuery/Perspective-") + VerFromRev(FRMQUERY_PERPSECTIVE_VER), &perspective, FRMQUERY_DEFAULT_PERSPECTIVE);
-    manager.LoadPerspective(perspective, true);
-
-    // and reset the captions for the current language
+       // and reset the captions for the current language
     manager.GetPane(wxT("toolBar")).Caption(_("Tool bar"));
     manager.GetPane(wxT("databaseBar")).Caption(_("Database bar"));
     manager.GetPane(wxT("sqlQuery")).Caption(_("SQL query"));
     manager.GetPane(wxT("outputPane")).Caption(_("Output pane"));
     manager.GetPane(wxT("scratchPad")).Caption(_("Scratch pad"));
 
-    // Sync the View menu options
+
+       // Sync the View menu options
     viewMenu->Check(MNU_DATABASEBAR, manager.GetPane(wxT("databaseBar")).IsShown());
     viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown());
     viewMenu->Check(MNU_OUTPUTPANE, manager.GetPane(wxT("outputPane")).IsShown());
     viewMenu->Check(MNU_SCRATCHPAD, manager.GetPane(wxT("scratchPad")).IsShown());
 
-    // tell the manager to "commit" all the changes just made
+       // tell the manager to "commit" all the changes just made
     manager.Update();
 
     bool bVal;
 
-    // Auto indent
+       // Auto indent
     settings->Read(wxT("frmQuery/AutoIndent"), &bVal, true);
     editMenu->Check(MNU_AUTOINDENT, bVal);
     if (bVal)
@@ -366,7 +388,7 @@ frmQuery::frmQuery(frmMain *form, const wxString& _title, pgConn *_conn, const w
     else
         sqlQuery->SetAutoIndent(false);
 
-    // Word wrap
+       // Word wrap
     settings->Read(wxT("frmQuery/WordWrap"), &bVal, false);
     viewMenu->Check(MNU_WORDWRAP, bVal);
     if (bVal)
@@ -374,23 +396,23 @@ frmQuery::frmQuery(frmMain *form, const wxString& _title, pgConn *_conn, const w
     else
         sqlQuery->SetWrapMode(wxSTC_WRAP_NONE);
 
-    // Indent Guides
+       // Indent Guides
     settings->Read(wxT("frmQuery/ShowIndentGuides"), &bVal, false);
     viewMenu->Check(MNU_SHOWINDENTGUIDES, bVal);
     if (bVal)
         sqlQuery->SetIndentationGuides(true);
     else
-        sqlQuery->SetIndentationGuides(false); 
+        sqlQuery->SetIndentationGuides(false);
 
-    // Whitespace
+       // Whitespace
     settings->Read(wxT("frmQuery/ShowWhitespace"), &bVal, false);
     viewMenu->Check(MNU_SHOWWHITESPACE, bVal);
     if (bVal)
         sqlQuery->SetViewWhiteSpace(wxSTC_WS_VISIBLEALWAYS);
     else
-        sqlQuery->SetViewWhiteSpace(wxSTC_WS_INVISIBLE); 
+        sqlQuery->SetViewWhiteSpace(wxSTC_WS_INVISIBLE);
 
-    // Line ends
+       // Line ends
     settings->Read(wxT("frmQuery/ShowLineEnds"), &bVal, false);
     viewMenu->Check(MNU_SHOWLINEENDS, bVal);
     if (bVal)
@@ -404,7 +426,7 @@ frmQuery::frmQuery(frmMain *form, const wxString& _title, pgConn *_conn, const w
         lastFilename=fn.GetFullName();
         lastDir = fn.GetPath();
         lastPath = fn.GetFullPath();
-        OpenLastFile();    
+        OpenLastFile();
     }
     else
         sqlQuery->SetText(query);
@@ -422,6 +444,11 @@ frmQuery::frmQuery(frmMain *form, const wxString& _title, pgConn *_conn, const w
 
     msgResult->SetMaxLength(0L);
     msgHistory->SetMaxLength(0L);
+
+       // TODO 666 : This should be replaced with a message when activating GQB not at startup
+    wxString msg=wxT("Loading Database metadata info for Graphical Query Builder");
+    wxBusyInfo waiting(msg, this);
+
 }
 
 
@@ -432,6 +459,22 @@ frmQuery::~frmQuery()
     msgResult->Disconnect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus));
     msgHistory->Disconnect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus));
 
+    if(sqlNotebook)
+    {
+        delete sqlNotebook;
+        controller->nullView();                   //to avoid bug on *nix when deleting controller
+    }
+    if(controller)
+        delete controller;
+    if(model)
+        delete model;
+    if(adjustSizesTimer)
+        delete adjustSizesTimer;
+
+       // Commented out in the original GQB patch - why?
+    // if(tablesBrowser)
+    //     delete tablesBrowser;
+
     if (mainForm)
         mainForm->RemoveFrame(this);
 
@@ -441,7 +484,7 @@ frmQuery::~frmQuery()
     settings->SetExplainAnalyze(queryMenu->IsChecked(MNU_ANALYZE));
     settings->SetExplainVerbose(queryMenu->IsChecked(MNU_VERBOSE));
 
-    sqlResult->Abort(); // to make sure conn is unused
+    sqlResult->Abort();                           // to make sure conn is unused
 
     while (cbConnection->GetCount() > 1)
     {
@@ -453,22 +496,26 @@ frmQuery::~frmQuery()
         delete favourites;
 }
 
+
 void frmQuery::OnExit(wxCommandEvent& event)
 {
     closing = true;
     Close();
 }
 
+
 void frmQuery::OnEraseBackground(wxEraseEvent& event)
 {
     event.Skip();
 }
 
+
 void frmQuery::OnSize(wxSizeEvent& event)
 {
     event.Skip();
 }
 
+
 void frmQuery::OnToggleScratchPad(wxCommandEvent& event)
 {
     if (viewMenu->IsChecked(MNU_SCRATCHPAD))
@@ -478,6 +525,7 @@ void frmQuery::OnToggleScratchPad(wxCommandEvent& event)
     manager.Update();
 }
 
+
 void frmQuery::OnToggleDatabaseBar(wxCommandEvent& event)
 {
     if (viewMenu->IsChecked(MNU_DATABASEBAR))
@@ -487,6 +535,7 @@ void frmQuery::OnToggleDatabaseBar(wxCommandEvent& event)
     manager.Update();
 }
 
+
 void frmQuery::OnToggleToolBar(wxCommandEvent& event)
 {
     if (viewMenu->IsChecked(MNU_TOOLBAR))
@@ -496,15 +545,22 @@ void frmQuery::OnToggleToolBar(wxCommandEvent& event)
     manager.Update();
 }
 
+
 void frmQuery::OnToggleOutputPane(wxCommandEvent& event)
 {
     if (viewMenu->IsChecked(MNU_OUTPUTPANE))
+    {
         manager.GetPane(wxT("outputPane")).Show(true);
+    }
     else
+    {
         manager.GetPane(wxT("outputPane")).Show(false);
+    }
     manager.Update();
+    adjustGQBSizes();
 }
 
+
 void frmQuery::OnAuiUpdate(wxAuiManagerEvent& event)
 {
     if(event.pane->name == wxT("databaseBar"))
@@ -518,6 +574,9 @@ void frmQuery::OnAuiUpdate(wxAuiManagerEvent& event)
     else if(event.pane->name == wxT("outputPane"))
     {
         viewMenu->Check(MNU_OUTPUTPANE, false);
+        if(!adjustSizesTimer)
+            adjustSizesTimer = new wxTimer(this,CTL_TIMERSIZES);
+        adjustSizesTimer->Start(500);
     }
     else if(event.pane->name == wxT("scratchPad"))
     {
@@ -526,11 +585,12 @@ void frmQuery::OnAuiUpdate(wxAuiManagerEvent& event)
     event.Skip();
 }
 
+
 void frmQuery::OnDefaultView(wxCommandEvent& event)
 {
     manager.LoadPerspective(FRMQUERY_DEFAULT_PERSPECTIVE, true);
 
-    // Reset the captions for the current language
+       // Reset the captions for the current language
     manager.GetPane(wxT("toolBar")).Caption(_("Tool bar"));
     manager.GetPane(wxT("databaseBar")).Caption(_("Database bar"));
     manager.GetPane(wxT("sqlQuery")).Caption(_("SQL query"));
@@ -539,67 +599,72 @@ void frmQuery::OnDefaultView(wxCommandEvent& event)
 
     manager.Update();
 
-    // Sync the View menu options
+       // Sync the View menu options
     viewMenu->Check(MNU_DATABASEBAR, manager.GetPane(wxT("databaseBar")).IsShown());
     viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown());
     viewMenu->Check(MNU_OUTPUTPANE, manager.GetPane(wxT("outputPane")).IsShown());
     viewMenu->Check(MNU_SCRATCHPAD, manager.GetPane(wxT("scratchPad")).IsShown());
 }
 
+
 void frmQuery::OnAutoIndent(wxCommandEvent &event)
 {
     editMenu->Check(MNU_AUTOINDENT, event.IsChecked());
 
     settings->Write(wxT("frmQuery/AutoIndent"), editMenu->IsChecked(MNU_AUTOINDENT));
-    
+
     if (editMenu->IsChecked(MNU_AUTOINDENT))
         sqlQuery->SetAutoIndent(true);
     else
         sqlQuery->SetAutoIndent(false);
 }
 
+
 void frmQuery::OnWordWrap(wxCommandEvent &event)
 {
     viewMenu->Check(MNU_WORDWRAP, event.IsChecked());
 
     settings->Write(wxT("frmQuery/WordWrap"), viewMenu->IsChecked(MNU_WORDWRAP));
-    
+
     if (viewMenu->IsChecked(MNU_WORDWRAP))
         sqlQuery->SetWrapMode(wxSTC_WRAP_WORD);
     else
         sqlQuery->SetWrapMode(wxSTC_WRAP_NONE);
 }
 
+
 void frmQuery::OnShowIndentGuides(wxCommandEvent& event)
 {
     viewMenu->Check(MNU_SHOWINDENTGUIDES, event.IsChecked());
 
     settings->Write(wxT("frmQuery/ShowIndentGuides"), viewMenu->IsChecked(MNU_SHOWINDENTGUIDES));
-    
+
     if (viewMenu->IsChecked(MNU_SHOWINDENTGUIDES))
         sqlQuery->SetIndentationGuides(true);
     else
         sqlQuery->SetIndentationGuides(false);
 }
 
+
 void frmQuery::OnShowWhitespace(wxCommandEvent& event)
 {
     viewMenu->Check(MNU_SHOWWHITESPACE, event.IsChecked());
 
     settings->Write(wxT("frmQuery/ShowWhitespace"), viewMenu->IsChecked(MNU_SHOWWHITESPACE));
-    
+
     if (viewMenu->IsChecked(MNU_SHOWWHITESPACE))
         sqlQuery->SetViewWhiteSpace(wxSTC_WS_VISIBLEALWAYS);
     else
         sqlQuery->SetViewWhiteSpace(wxSTC_WS_INVISIBLE);
 }
 
+
 void frmQuery::OnShowLineEnds(wxCommandEvent& event)
 {
     viewMenu->Check(MNU_SHOWLINEENDS, event.IsChecked());
 
     settings->Write(wxT("frmQuery/ShowLineEnds"), viewMenu->IsChecked(MNU_SHOWLINEENDS));
-    
+
     if (viewMenu->IsChecked(MNU_SHOWLINEENDS))
         sqlQuery->SetViewEOL(1);
     else
@@ -629,7 +694,7 @@ void frmQuery::Go()
 
     Show(true);
     sqlQuery->SetFocus();
-       loading = false;
+    loading = false;
 }
 
 
@@ -640,7 +705,6 @@ typedef struct __sqltokenhelp
     int type;
 } SqlTokenHelp;
 
-
 SqlTokenHelp sqlTokenHelp[] =
 {
     { wxT("ABORT"), 0, 0},
@@ -670,12 +734,12 @@ SqlTokenHelp sqlTokenHelp[] =
     { wxT("MOVE"), 0, 0},
     { wxT("NOTIFY"), 0, 0},
     { wxT("END"), 0, 0},
-//    { wxT("PREPARE"), 0, 0},  handled individually
+       // { wxT("PREPARE"), 0, 0},  handled individually
     { wxT("REINDEX"), 0, 0},
     { wxT("RELEASE"), wxT("pg/sql-release-savepoint"), 0},
     { wxT("RESET"), 0, 0},
     { wxT("REVOKE"), 0, 0},
-//    { wxT("ROLLBACK"), 0, 0}, handled individually
+       // { wxT("ROLLBACK"), 0, 0}, handled individually
     { wxT("SAVEPOINT"), 0, 0},
     { wxT("SELECT"), 0, 0},
     { wxT("SET"), 0, 0},
@@ -710,7 +774,6 @@ SqlTokenHelp sqlTokenHelp[] =
     { 0, 0 }
 };
 
-
 void frmQuery::OnContents(wxCommandEvent& event)
 {
     DisplayHelp(wxT("query"), HELP_PGADMIN);
@@ -719,14 +782,14 @@ void frmQuery::OnContents(wxCommandEvent& event)
 
 void frmQuery::OnChangeConnection(wxCommandEvent &ev)
 {
-    // On Solaris, this event seems to get fired when the form closes(!!)
+       // On Solaris, this event seems to get fired when the form closes(!!)
     if(!IsVisible() && !loading)
-        return; 
+        return;
 
     unsigned int sel=cbConnection->GetCurrentSelection();
     if (sel == cbConnection->GetCount()-1)
     {
-        // new Connection
+               // new Connection
         dlgSelectConnection dlg(this, mainForm);
         int rc=dlg.Go(conn, cbConnection);
         if (rc == wxID_OK)
@@ -760,6 +823,15 @@ void frmQuery::OnChangeConnection(wxCommandEvent &ev)
         sqlResult->SetConnection(conn);
         title = wxT("Query - ") + cbConnection->GetValue();
         setExtendedTitle();
+
+               //Refresh GQB Tree if used
+        if(conn && !firstTime)
+        {
+            wxString msg = wxT("Retrieving tables from database ")+conn->GetDbname();
+            wxBusyInfo waiting(msg, this);
+            controller->getTablesBrowser()->refreshTables(conn);
+            controller->getView()->Refresh();
+        }
     }
 }
 
@@ -843,7 +915,7 @@ void frmQuery::OnHelp(wxCommandEvent& event)
 
 void frmQuery::OnSaveHistory(wxCommandEvent& event)
 {
-    wxFileDialog *dlg=new wxFileDialog(this, _("Save history"), lastDir, wxEmptyString, 
+    wxFileDialog *dlg=new wxFileDialog(this, _("Save history"), lastDir, wxEmptyString,
         _("Log files (*.log)|*.log|All files (*.*)|*.*"), wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
     if (dlg->ShowModal() == wxID_OK)
     {
@@ -856,6 +928,29 @@ void frmQuery::OnSaveHistory(wxCommandEvent& event)
 
 }
 
+void frmQuery::OnChangeNotebook(wxNotebookEvent& event)
+{
+    if(sqlNotebook)
+       {
+        if (sqlNotebook->GetPageCount()>=2)
+               {
+            if(firstTime)        //Things that should be done on first click on GQB
+            {
+                               // Size, and pause to allow the window to draw
+                               adjustGQBSizes();
+                               wxTheApp->Yield(true);
+
+                               // Database related Stuffs.
+                               // Create a server object and connect it.
+                               wxString msg= wxT("Retrieving tables from database ") + conn->GetDbname();
+                               wxBusyInfo waiting(msg, this);
+                               controller->getTablesBrowser()->refreshTables(conn);
+                               firstTime=false;
+                       }
+               }
+    }
+}
+
 
 void frmQuery::OnSetFocus(wxFocusEvent& event)
 {
@@ -927,12 +1022,14 @@ void frmQuery::OnCopy(wxCommandEvent& ev)
         msgHistory->Copy();
     else if (wnd == scratchPad)
         scratchPad->Copy();
-    else 
+    else
     {
         wxWindow *obj = wnd;
 
-        while (obj != NULL) {
-            if (obj == sqlResult) {
+        while (obj != NULL)
+        {
+            if (obj == sqlResult)
+            {
                 sqlResult->Copy();
                 break;
             }
@@ -942,14 +1039,16 @@ void frmQuery::OnCopy(wxCommandEvent& ev)
     updateMenu();
 }
 
+
 void frmQuery::OnPaste(wxCommandEvent& ev)
 {
     if (currentControl() == sqlQuery)
-      sqlQuery->Paste();
+        sqlQuery->Paste();
     else if (currentControl() == scratchPad)
-      scratchPad->Paste();
+        scratchPad->Paste();
 }
 
+
 void frmQuery::OnClear(wxCommandEvent& ev)
 {
     wxWindow *wnd=currentControl();
@@ -964,6 +1063,7 @@ void frmQuery::OnClear(wxCommandEvent& ev)
         scratchPad->Clear();
 }
 
+
 void frmQuery::OnSelectAll(wxCommandEvent& ev)
 {
     wxWindow *wnd=currentControl();
@@ -982,21 +1082,25 @@ void frmQuery::OnSelectAll(wxCommandEvent& ev)
         sqlResult->SelectAll();
 }
 
+
 void frmQuery::OnSearchReplace(wxCommandEvent& ev)
 {
-      sqlQuery->OnSearchReplace(ev);
+    sqlQuery->OnSearchReplace(ev);
 }
 
+
 void frmQuery::OnUndo(wxCommandEvent& ev)
 {
     sqlQuery->Undo();
 }
 
+
 void frmQuery::OnRedo(wxCommandEvent& ev)
 {
     sqlQuery->Redo();
 }
 
+
 void frmQuery::setExtendedTitle()
 {
     wxString chgStr;
@@ -1029,7 +1133,6 @@ void frmQuery::updateMenu(wxObject *obj)
     if (closing)
         return;
 
-
     if (!obj || obj == sqlQuery)
     {
         canUndo=sqlQuery->CanUndo();
@@ -1047,7 +1150,6 @@ void frmQuery::updateMenu(wxObject *obj)
         canClear = true;
     }
 
-
     toolBar->EnableTool(MNU_UNDO, canUndo);
     editMenu->Enable(MNU_UNDO, canUndo);
 
@@ -1069,6 +1171,7 @@ void frmQuery::updateMenu(wxObject *obj)
     favouritesMenu->Enable(MNU_FAVOURITES_ADD, canAddFavourite);
 }
 
+
 void frmQuery::UpdateFavouritesList()
 {
     while (favouritesMenu->GetMenuItemCount() > 3)
@@ -1079,46 +1182,50 @@ void frmQuery::UpdateFavouritesList()
     favourites->AppendAllToMenu(favouritesMenu, MNU_FAVOURITES_MANAGE+1);
 }
 
+
 void frmQuery::UpdateMacrosList()
 {
-       while (macrosMenu->GetMenuItemCount() > 2)
-       {
-               macrosMenu->Destroy(macrosMenu->GetMenuItems()[2]);
-       }
+    while (macrosMenu->GetMenuItemCount() > 2)
+    {
+        macrosMenu->Destroy(macrosMenu->GetMenuItems()[2]);
+    }
 
-       macros->AppendAllToMenu(macrosMenu, MNU_MACROS_MANAGE+1);
+    macros->AppendAllToMenu(macrosMenu, MNU_MACROS_MANAGE+1);
 }
 
+
 void frmQuery::OnAddFavourite(wxCommandEvent &event)
 {
     if (sqlQuery->GetText().Trim().IsEmpty())
         return;
     if (dlgAddFavourite(this,favourites).AddFavourite(sqlQuery->GetText()))
     {
-        /* Added a favourite, so save */
+               // Added a favourite, so save
         queryFavouriteFileProvider::SaveFavourites(favourites);
         UpdateFavouritesList();
     }
 }
 
+
 void frmQuery::OnManageFavourites(wxCommandEvent &event)
 {
     int r = dlgManageFavourites(this,favourites).ManageFavourites();
     if (r == 1)
     {
-        /* Changed something, so save */
+               // Changed something, so save
         queryFavouriteFileProvider::SaveFavourites(favourites);
         UpdateFavouritesList();
     }
     else if (r == -1)
     {
-        /* Changed something requiring rollback */
+               // Changed something requiring rollback
         delete favourites;
         favourites = queryFavouriteFileProvider::LoadFavourites(true);
         UpdateFavouritesList();
     }
 }
 
+
 void frmQuery::OnSelectFavourite(wxCommandEvent &event)
 {
     queryFavouriteItem *fav;
@@ -1137,25 +1244,25 @@ void frmQuery::OnSelectFavourite(wxCommandEvent &event)
         else
         {
             if (sqlQuery->GetText().Last() != '\n')
-                sqlQuery->AddText(wxT("\n")); // Add a newline after the last query
+                sqlQuery->AddText(wxT("\n"));     // Add a newline after the last query
         }
     }
     sqlQuery->AddText(fav->GetContents());
 }
 
+
 bool frmQuery::CheckChanged(bool canVeto)
 {
     if (changed && settings->GetAskSaveConfirmation())
     {
         wxString fn;
         if (!lastPath.IsNull())
-                       fn = wxString::Format(_("The text in file %s has changed.\nDo you want to save changes?"), lastPath.c_str());
-               else
-                       fn = _("The text has changed.\nDo you want to save changes?");
-        wxMessageDialog msg(this, fn, _("Query"), 
-                    wxYES_NO|wxICON_EXCLAMATION|
-                    (canVeto ? wxCANCEL : 0));
+            fn = wxString::Format(_("The text in file %s has changed.\nDo you want to save changes?"), lastPath.c_str());
+        else
+            fn = _("The text has changed.\nDo you want to save changes?");
+        wxMessageDialog msg(this, fn, _("Query"),
+            wxYES_NO|wxICON_EXCLAMATION|
+            (canVeto ? wxCANCEL : 0));
 
         wxCommandEvent noEvent;
         switch (msg.ShowModal())
@@ -1182,8 +1289,8 @@ void frmQuery::OnClose(wxCloseEvent& event)
     {
         if (event.CanVeto())
         {
-            wxMessageDialog msg(this, _("A query is running. Do you wish to cancel it?"), _("Query"), 
-                        wxYES_NO|wxNO_DEFAULT|wxICON_EXCLAMATION);
+            wxMessageDialog msg(this, _("A query is running. Do you wish to cancel it?"), _("Query"),
+                wxYES_NO|wxNO_DEFAULT|wxICON_EXCLAMATION);
 
             if (msg.ShowModal() == wxID_NO)
             {
@@ -1226,6 +1333,7 @@ void frmQuery::OnChangeStc(wxStyledTextEvent& event)
     updateMenu();
 }
 
+
 void frmQuery::OnPositionStc(wxStyledTextEvent& event)
 {
     wxString pos;
@@ -1247,14 +1355,15 @@ void frmQuery::OpenLastFile()
     {
         sqlQuery->SetText(str);
         sqlQuery->Colourise(0, str.Length());
-        wxSafeYield();  // needed to process sqlQuery modify event
+        wxSafeYield();                            // needed to process sqlQuery modify event
         changed = false;
         setExtendedTitle();
         SetLineEndingStyle();
         UpdateRecentFiles();
     }
 }
-        
+
+
 void frmQuery::OnNew(wxCommandEvent& event)
 {
     frmQuery *fq = new frmQuery(mainForm, wxEmptyString, conn->Duplicate(), wxEmptyString);
@@ -1263,12 +1372,13 @@ void frmQuery::OnNew(wxCommandEvent& event)
     fq->Go();
 }
 
+
 void frmQuery::OnOpen(wxCommandEvent& event)
 {
     if (CheckChanged(true))
         return;
 
-    wxFileDialog dlg(this, _("Open query file"), lastDir, wxT(""), 
+    wxFileDialog dlg(this, _("Open query file"), lastDir, wxT(""),
         _("Query files (*.sql)|*.sql|All files (*.*)|*.*"), wxFD_OPEN);
     if (dlg.ShowModal() == wxID_OK)
     {
@@ -1279,6 +1389,7 @@ void frmQuery::OnOpen(wxCommandEvent& event)
     }
 }
 
+
 void frmQuery::OnSave(wxCommandEvent& event)
 {
     bool modeUnicode = settings->GetUnicodeFile();
@@ -1291,7 +1402,7 @@ void frmQuery::OnSave(wxCommandEvent& event)
 
     wxUtfFile file(lastPath, wxFile::write, modeUnicode ? wxFONTENCODING_UTF8:wxFONTENCODING_DEFAULT);
     if (file.IsOpened())
-     {
+    {
         if ((file.Write(sqlQuery->GetText()) == 0) && (!modeUnicode))
             wxMessageBox(_("Query text incomplete.\nQuery contained characters that could not be converted to the local charset.\nPlease correct the data or try using UTF8 instead."));
         file.Close();
@@ -1305,10 +1416,11 @@ void frmQuery::OnSave(wxCommandEvent& event)
     }
 }
 
+
 // Set the line ending style based on the current document.
 void frmQuery::SetLineEndingStyle()
 {
-    // Detect the file mode
+       // Detect the file mode
     wxRegEx *reLF = new wxRegEx(wxT("[^\r]\n"), wxRE_NEWLINE);
     wxRegEx *reCRLF = new wxRegEx(wxT("\r\n"), wxRE_NEWLINE);
     wxRegEx *reCR = new wxRegEx(wxT("\r[^\n]"), wxRE_NEWLINE);
@@ -1338,7 +1450,7 @@ void frmQuery::SetLineEndingStyle()
             mode = wxSTC_EOL_CR;
     }
 
-    // Now set the status text, menu options, and the mode
+       // Now set the status text, menu options, and the mode
     sqlQuery->SetEOLMode(mode);
     switch(mode)
     {
@@ -1367,6 +1479,7 @@ void frmQuery::SetLineEndingStyle()
     delete reLF;
 }
 
+
 // Get the line ending style
 int frmQuery::GetLineEndingStyle()
 {
@@ -1376,27 +1489,29 @@ int frmQuery::GetLineEndingStyle()
         return wxSTC_EOL_CRLF;
     else if (lineEndMenu->IsChecked(MNU_CR))
         return wxSTC_EOL_CR;
-    else 
+    else
         return sqlQuery->GetEOLMode();
 }
 
+
 // User-set the current EOL mode for the form
 void frmQuery::OnSetEOLMode(wxCommandEvent& event)
 {
     int mode = GetLineEndingStyle();
     sqlQuery->ConvertEOLs(mode);
-       sqlQuery->SetEOLMode(mode);
-       settings->SetLineEndingType(mode);
+    sqlQuery->SetEOLMode(mode);
+    settings->SetLineEndingType(mode);
 
     SetEOLModeDisplay(mode);
 
     if (!changed)
     {
         changed=true;
-        setExtendedTitle();  
+        setExtendedTitle();
     }
 }
 
+
 // Display the EOL mode settings on the form
 void frmQuery::SetEOLModeDisplay(int mode)
 {
@@ -1423,9 +1538,10 @@ void frmQuery::SetEOLModeDisplay(int mode)
     }
 }
 
+
 void frmQuery::OnSaveAs(wxCommandEvent& event)
 {
-    wxFileDialog *dlg=new wxFileDialog(this, _("Save query file as"), lastDir, lastFilename, 
+    wxFileDialog *dlg=new wxFileDialog(this, _("Save query file as"), lastDir, lastFilename,
         _("Query files (*.sql)|*.sql|All files (*.*)|*.*"), wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
     if (dlg->ShowModal() == wxID_OK)
     {
@@ -1434,16 +1550,16 @@ void frmQuery::OnSaveAs(wxCommandEvent& event)
         lastPath = dlg->GetPath();
         switch (dlg->GetFilterIndex())
         {
-            case 0: 
+            case 0:
 #ifdef __WXMAC__
-        if (!lastPath.Contains(wxT(".")))
-            lastPath += wxT(".sql");
+                if (!lastPath.Contains(wxT(".")))
+                    lastPath += wxT(".sql");
 #endif
                 break;
             case 1:
 #ifdef __WXMAC__
                 if (!lastPath.Contains(wxT(".")))
-                        lastPath += wxT(".sql");
+                    lastPath += wxT(".sql");
 #endif
                 break;
             default:
@@ -1471,6 +1587,7 @@ void frmQuery::OnSaveAs(wxCommandEvent& event)
     delete dlg;
 }
 
+
 void frmQuery::OnQuickReport(wxCommandEvent& event)
 {
     wxDateTime now = wxDateTime::Now();
@@ -1534,15 +1651,15 @@ void frmQuery::OnExplain(wxCommandEvent& event)
         sql += wxT("ANALYZE ");
     if (verbose)
         sql += wxT("VERBOSE ");
-    
+
     int offset=sql.Length();
 
     sql += query;
 
     if (analyze)
     {
-        // Bizarre bug fix - if we append a rollback directly after -- it'll crash!!
-        // Add a \n first.
+               // Bizarre bug fix - if we append a rollback directly after -- it'll crash!!
+               // Add a \n first.
         sql += wxT("\n;\nROLLBACK;");
     }
 
@@ -1552,41 +1669,116 @@ void frmQuery::OnExplain(wxCommandEvent& event)
 
 void frmQuery::OnExecute(wxCommandEvent& event)
 {
-    wxString query=sqlQuery->GetSelectedText();
-    if (query.IsNull())
-        query = sqlQuery->GetText();
+       // Execute Generation of SQL sentence from GQB
+       bool canGenerate=false;
+       if(sqlNotebook->GetSelection()==1)
+       {
+               if(firstGeneration)  // First time generate sentence without asking for overwriting
+               {
+                       changed=false;
+                       firstGeneration=false;
+               }
 
-    if (query.IsNull())
-        return;
-    execQuery(query);
-    sqlQuery->SetFocus();
+               if(changed) //Next time ask for permisson only if have changed
+               {
+                   wxString fn = _("The generated SQL query has changed.\nDo you want to update it?");
+            wxMessageDialog msg(this, fn, _("Query"), wxYES_NO|wxICON_EXCLAMATION);
+                   if(msg.ShowModal() == wxID_YES && changed)
+                   {
+                       canGenerate=true;
+                   }
+               }
+               else
+               {
+                   canGenerate=true;
+               }
+
+               if(canGenerate)
+               {
+                   sqlQuery->ClearAll();
+                   sqlQuery->AddText(controller->generateSQL());
+                   sqlQuery->AddText(wxT("\n"));
+               sqlNotebook->SetSelection(0);
+                   changed=false;
+               }
+       }
+       // Execute SQL sentences created by user
+       else
+       {
+               wxString query=sqlQuery->GetSelectedText();
+               if (query.IsNull())
+                       query = sqlQuery->GetText();
+
+               if (query.IsNull())
+                       return;
+
+               execQuery(query);
+               sqlQuery->SetFocus();
+       }
 }
 
 
 void frmQuery::OnExecFile(wxCommandEvent &event)
 {
-    wxString query=sqlQuery->GetSelectedText();
-    if (query.IsNull())
-        query = sqlQuery->GetText();
+    bool canGenerate=false;
+       if(sqlNotebook->GetSelection()==1)
+       {
+           if(firstGeneration)  // First time generate sentence without asking for overwriting
+               {
+                       changed=false;
+                       firstGeneration=false;
+               }
 
-    if (query.IsNull())
-        return;
-    execQuery(query, 0, false, 0, true);
-    sqlQuery->SetFocus();
+               if(changed) //Next time ask for permisson only if have changed
+               {
+                   wxString fn = _("The generated SQL query has changed.\nDo you want to update it?");
+            wxMessageDialog msg(this, fn, _("Query"), wxYES_NO|wxICON_EXCLAMATION);
+                   if(msg.ShowModal() == wxID_YES && changed)
+                   {
+                       canGenerate=true;
+                   }
+               }
+               else
+               {
+                   canGenerate=true;
+               }
+
+               if(canGenerate)
+               {
+                   sqlQuery->ClearAll();
+                   sqlQuery->AddText(controller->generateSQL());
+                   sqlQuery->AddText(wxT("\n"));
+               sqlNotebook->SetSelection(0);
+                   changed=false;
+               }
+       }
+       else
+       {
+        wxString query=sqlQuery->GetSelectedText();
+        if (query.IsNull())
+            query = sqlQuery->GetText();
+
+        if (query.IsNull())
+            return;
+
+        execQuery(query, 0, false, 0, true);
+        sqlQuery->SetFocus();
+       }
 }
 
+
 void frmQuery::OnMacroManage(wxCommandEvent &event)
 {
-       int r = dlgManageMacros(this,mainForm,macros).ManageMacros();
+    int r = dlgManageMacros(this,mainForm,macros).ManageMacros();
     if (r == 1)
     {
-        /* Changed something, so save */
+               // Changed something, so save
         queryMacroFileProvider::SaveMacros(macros);
         UpdateMacrosList();
     }
     else if (r == -1)
     {
-        /* Changed something requiring rollback */
+               // Changed something requiring rollback
         delete macros;
         macros = queryMacroFileProvider::LoadMacros(true);
         UpdateMacrosList();
@@ -1594,6 +1786,7 @@ void frmQuery::OnMacroManage(wxCommandEvent &event)
 
 }
 
+
 void frmQuery::OnMacroInvoke(wxCommandEvent &event)
 {
     queryMacroItem *mac;
@@ -1602,24 +1795,25 @@ void frmQuery::OnMacroInvoke(wxCommandEvent &event)
     if (!mac)
         return;
 
-       wxString query = mac->GetQuery();
-       if (query.IsEmpty())
-               return; // do not execute empty query
+    wxString query = mac->GetQuery();
+    if (query.IsEmpty())
+        return;                        // do not execute empty query
 
-       if (query.Find(wxT("$SELECTION$")) != wxNOT_FOUND)
-       {
-               wxString selection = sqlQuery->GetSelectedText();
-               if (selection.IsEmpty())
-               {
-                       wxMessageBox(_("This macro includes a text substitution. Please select some text in the SQL pane and re-run the macro."), _("Execute macro"), wxICON_EXCLAMATION);
-                       return;
-               }
-               query.Replace(wxT("$SELECTION$"), selection);
-       }
+    if (query.Find(wxT("$SELECTION$")) != wxNOT_FOUND)
+    {
+        wxString selection = sqlQuery->GetSelectedText();
+        if (selection.IsEmpty())
+        {
+            wxMessageBox(_("This macro includes a text substitution. Please select some text in the SQL pane and re-run the macro."), _("Execute macro"), wxICON_EXCLAMATION);
+            return;
+        }
+        query.Replace(wxT("$SELECTION$"), selection);
+    }
     execQuery(query);
     sqlQuery->SetFocus();
 }
 
+
 void frmQuery::setTools(const bool running)
 {
     toolBar->EnableTool(MNU_EXECUTE, !running);
@@ -1649,6 +1843,7 @@ void frmQuery::showMessage(const wxString& msg, const wxString &msgShort)
     SetStatusText(str, STATUSPOS_MSGS);
 }
 
+
 void frmQuery::execQuery(const wxString &query, int resultToRetrieve, bool singleResult, const int queryOffset, bool toFile, bool explain, bool verbose)
 {
     setTools(true);
@@ -1657,7 +1852,7 @@ void frmQuery::execQuery(const wxString &query, int resultToRetrieve, bool singl
 
     explainCanvas->Clear();
 
-    // Clear markers and indicators
+       // Clear markers and indicators
     sqlQuery->MarkerDeleteAll(0);
     sqlQuery->StartStyling(0, wxSTC_INDICS_MASK);
     sqlQuery->SetStyling(sqlQuery->GetText().Length(), 0);
@@ -1674,9 +1869,9 @@ void frmQuery::execQuery(const wxString &query, int resultToRetrieve, bool singl
     qi->explain = explain;
     qi->verbose = verbose;
 
-    // We must do this lot before the query starts, otherwise
-    // it might not happen once the main thread gets busy with
-    // other stuff.
+       // We must do this lot before the query starts, otherwise
+       // it might not happen once the main thread gets busy with
+       // other stuff.
     SetStatusText(wxT(""), STATUSPOS_SECS);
     SetStatusText(_("Query is running."), STATUSPOS_MSGS);
     SetStatusText(wxT(""), STATUSPOS_ROWS);
@@ -1693,13 +1888,14 @@ void frmQuery::execQuery(const wxString &query, int resultToRetrieve, bool singl
 
     if (sqlResult->Execute(query, resultToRetrieve, this, QUERY_COMPLETE, qi) >= 0)
     {
-        // Return and wait for the result
+               // Return and wait for the result
         return;
     }
 
     completeQuery(false, false, false);
 }
 
+
 // When the query completes, it raises an event which we process here.
 void frmQuery::OnQueryComplete(wxCommandEvent &ev)
 {
@@ -1739,13 +1935,13 @@ void frmQuery::OnQueryComplete(wxCommandEvent &ev)
             else if (insertedCount == 1 && insertedOid)
             {
                 showMessage(wxString::Format(_("Query returned successfully: one row with OID %d inserted, %s ms execution time."),
-                    insertedOid, elapsedQuery.ToString().c_str()), 
+                    insertedOid, elapsedQuery.ToString().c_str()),
                     wxString::Format(_("One Row with OID %d inserted."), insertedOid));
             }
             else
             {
                 showMessage(wxString::Format(_("Query returned successfully: %d rows affected, %s ms execution time."),
-                    insertedCount, elapsedQuery.ToString().c_str()), 
+                    insertedCount, elapsedQuery.ToString().c_str()),
                     wxString::Format(_("%d rows affected."), insertedCount));
             }
         }
@@ -1757,7 +1953,7 @@ void frmQuery::OnQueryComplete(wxCommandEvent &ev)
 
             long errPos;
             err.statement_pos.ToLong(&errPos);
-            
+
             showMessage(wxString::Format(wxT("********** %s **********\n"), _("Error")));
             showMessage(errMsg);
 
@@ -1767,17 +1963,17 @@ void frmQuery::OnQueryComplete(wxCommandEvent &ev)
                 if (selStart == selEnd)
                     selStart=0;
 
-                errPos -= qi->queryOffset;  // do not count EXPLAIN or similar
+                errPos -= qi->queryOffset;        // do not count EXPLAIN or similar
 
-                // Set an indicator on the error word (break on any kind of bracket, a space or full stop)
+                               // Set an indicator on the error word (break on any kind of bracket, a space or full stop)
                 int sPos = errPos + selStart - 1, wEnd = 1;
                 sqlQuery->StartStyling(sPos, wxSTC_INDICS_MASK);
-                while(sqlQuery->GetCharAt(sPos + wEnd) != ' ' && 
-                      sqlQuery->GetCharAt(sPos + wEnd) != '(' && 
-                      sqlQuery->GetCharAt(sPos + wEnd) != '{' && 
-                      sqlQuery->GetCharAt(sPos + wEnd) != '[' && 
-                      sqlQuery->GetCharAt(sPos + wEnd) != '.' &&
-                      (unsigned int)(sPos + wEnd) < sqlQuery->GetText().Length())
+                while(sqlQuery->GetCharAt(sPos + wEnd) != ' ' &&
+                    sqlQuery->GetCharAt(sPos + wEnd) != '(' &&
+                    sqlQuery->GetCharAt(sPos + wEnd) != '{' &&
+                    sqlQuery->GetCharAt(sPos + wEnd) != '[' &&
+                    sqlQuery->GetCharAt(sPos + wEnd) != '.' &&
+                    (unsigned int)(sPos + wEnd) < sqlQuery->GetText().Length())
                     wEnd++;
                 sqlQuery->SetStyling(wEnd, wxSTC_INDIC0_MASK);
 
@@ -1839,8 +2035,6 @@ void frmQuery::OnQueryComplete(wxCommandEvent &ev)
 
                 sqlResult->DisplayData();
 
-
-
                 SetStatusText(elapsedQuery.ToString() + wxT(" ms"), STATUSPOS_SECS);
 
                 str= _("Total query runtime: ") + elapsedQuery.ToString() + wxT(" ms.\n") ;
@@ -1856,10 +2050,11 @@ void frmQuery::OnQueryComplete(wxCommandEvent &ev)
     completeQuery(done, qi->explain, qi->verbose);
 }
 
+
 // Complete the processing of a query
 void frmQuery::completeQuery(bool done, bool explain, bool verbose)
 {
-    // Display async notifications
+       // Display async notifications
     pgNotification *notify;
     int notifies = 0;
     notify = conn->GetNotification();
@@ -1893,7 +2088,7 @@ void frmQuery::completeQuery(bool done, bool explain, bool verbose)
     msgHistory->AppendText(wxT("\n"));
     msgHistory->ShowPosition(0);
 
-    // If the transaction aborted for some reason, issue a rollback to cleanup.
+       // If the transaction aborted for some reason, issue a rollback to cleanup.
     if (conn->GetTxStatus() == PGCONN_TXSTATUS_INERROR)
         conn->ExecuteVoid(wxT("ROLLBACK;"));
 
@@ -1910,7 +2105,7 @@ void frmQuery::completeQuery(bool done, bool explain, bool verbose)
         manager.Update();
     }
 
-    // If this was an EXPLAIN query, process the results
+       // If this was an EXPLAIN query, process the results
     if (done && explain)
     {
         if (!verbose)
@@ -1919,7 +2114,7 @@ void frmQuery::completeQuery(bool done, bool explain, bool verbose)
             wxString str;
             if (sqlResult->NumRows() == 1)
             {
-                // Avoid shared storage issues with strings
+                               // Avoid shared storage issues with strings
                 str.Append(sqlResult->OnGetItemText(0, 0).c_str());
             }
             else
@@ -1939,6 +2134,7 @@ void frmQuery::completeQuery(bool done, bool explain, bool verbose)
     sqlQuery->SetFocus();
 }
 
+
 void frmQuery::OnTimer(wxTimerEvent & event)
 {
     elapsedQuery=wxGetLocalTimeMillis() - startTimeQuery;
@@ -1951,7 +2147,7 @@ void frmQuery::OnTimer(wxTimerEvent & event)
         msgHistory->AppendText(str + wxT("\n"));
     }
 
-    // Increase the granularity for longer running queries
+       // Increase the granularity for longer running queries
     if (elapsedQuery > 200 && timer.GetInterval() == 10 && timer.IsRunning())
     {
         timer.Stop();
@@ -1959,8 +2155,52 @@ void frmQuery::OnTimer(wxTimerEvent & event)
     }
 }
 
-///////////////////////////////////////////////////////
+// Adjust sizes of GQB components, Located here because need to 
+// avoid some issues when implementing inside controller/view Classes
+void frmQuery::adjustGQBSizes()
+{
+       // Get Size (only height) from main Tab with GQB and SQL Editor and adjust the width 
+       // to desiree, then set [Sash of tablesBrowser | GQB_Canvas]
+    manager.Update();
+    sqlNotebook->Refresh();
+    wxSize s = sqlNotebook->GetSize();
+    s.SetWidth(200);
+    s.SetHeight(s.GetHeight()-180);            //re-adjust weight eliminating Horz Sash Position
+    controller->getTablesBrowser()->SetSize(s);
+    controller->setSashVertPosition(controller->getTablesBrowser()->GetSize().GetWidth());
+
+       // Now Adjust Sash Horizontal
+    s = sqlNotebook->GetSize();
+    controller->setSashHorizPosition(s.GetHeight()-150);
+
+       // Adjust GQB grids internal columns sizes
+    controller->calcGridColsSizes();
+}
+
+
+// Adjust sizes of GQB components after vertical sash adjustment, 
+// Located here because need to avoid some issues when implementing 
+// inside controller/view Classes
+void frmQuery::onResizeHorizontally(wxSplitterEvent& event)
+{
+    int y = event.GetSashPosition();
+       wxSize s = controller->getTablesBrowser()->GetSize();
+    s.SetHeight(y);               // re-adjust weight eliminating Horz Sash Position
+    controller->getTablesBrowser()->SetSize(s);
+}
+
+
 
+// This function adjust the GQB Components after an event on the wxAui 
+// event, it's a workaround because need event finish to work properly
+void frmQuery::OnAdjustSizesTimer(wxTimerEvent & event)
+{
+    adjustGQBSizes();
+    adjustSizesTimer->Stop();
+}
+
+
+///////////////////////////////////////////////////////
 
 wxWindow *queryToolBaseFactory::StartDialogSql(frmMain *form, pgObject *obj, const wxString &sql)
 {
@@ -1981,6 +2221,7 @@ bool queryToolBaseFactory::CheckEnable(pgObject *obj)
     return obj && obj->GetDatabase() && obj->GetDatabase()->GetConnected();
 }
 
+
 bool queryToolDataFactory::CheckEnable(pgObject *obj)
 {
     return queryToolBaseFactory::CheckEnable(obj) && !obj->IsCollection() &&
@@ -1988,7 +2229,6 @@ bool queryToolDataFactory::CheckEnable(pgObject *obj)
 }
 
 
-
 queryToolFactory::queryToolFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolBaseFactory(list)
 {
     mnu->Append(id, _("&Query tool\tCtrl-E"), _("Execute arbitrary SQL queries."));
@@ -1999,7 +2239,7 @@ queryToolFactory::queryToolFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuTo
 wxWindow *queryToolFactory::StartDialog(frmMain *form, pgObject *obj)
 {
     wxString qry;
-    if (settings->GetStickySql()) 
+    if (settings->GetStickySql())
         qry = obj->GetSql(form->GetBrowser());
     return StartDialogSql(form, obj, qry);
 }
@@ -2018,6 +2258,7 @@ wxWindow *queryToolSqlFactory::StartDialog(frmMain *form, pgObject *obj)
     return StartDialogSql(form, obj, obj->GetSql(form->GetBrowser()));
 }
 
+
 bool queryToolSqlFactory::CheckEnable(pgObject *obj)
 {
     return queryToolBaseFactory::CheckEnable(obj) && obj->CanCreate() && !obj->IsCollection();
@@ -2045,11 +2286,13 @@ wxWindow *queryToolSelectFactory::StartDialog(frmMain *form, pgObject *obj)
     return 0;
 }
 
+
 queryToolDeleteFactory::queryToolDeleteFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolDataFactory(list)
 {
     mnu->Append(id, _("DELETE script"), _("Start query tool with DELETE script."));
 }
 
+
 bool queryToolDeleteFactory::CheckEnable(pgObject *obj)
 {
     if (!queryToolDataFactory::CheckEnable(obj))
@@ -2059,6 +2302,7 @@ bool queryToolDeleteFactory::CheckEnable(pgObject *obj)
     return false;
 }
 
+
 wxWindow *queryToolDeleteFactory::StartDialog(frmMain *form, pgObject *obj)
 {
     if (obj->IsCreatedBy(tableFactory))
@@ -2091,6 +2335,7 @@ wxWindow *queryToolUpdateFactory::StartDialog(frmMain *form, pgObject *obj)
     return 0;
 }
 
+
 bool queryToolUpdateFactory::CheckEnable(pgObject *obj)
 {
     if (!queryToolDataFactory::CheckEnable(obj))
@@ -2103,7 +2348,6 @@ bool queryToolUpdateFactory::CheckEnable(pgObject *obj)
 }
 
 
-
 queryToolInsertFactory::queryToolInsertFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolDataFactory(list)
 {
     mnu->Append(id, _("INSERT script"), _("Start query tool with INSERT script."));
diff --git a/pgadmin/gqb/gqbArrayCollection.cpp b/pgadmin/gqb/gqbArrayCollection.cpp
new file mode 100644 (file)
index 0000000..afb37cb
--- /dev/null
@@ -0,0 +1,190 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbArrayCollection.cpp - Implementation of Collection Using Arrays\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+\r
+// App headers\r
+#include "gqb/gqbArrayCollection.h"\r
+#include "gqb/gqbObject.h"\r
+\r
+// Destructor\r
+gqbArrayCollection::~gqbArrayCollection()\r
+{\r
+    WX_CLEAR_ARRAY(gqbArray);\r
+}\r
+\r
+\r
+// Add item to array\r
+void gqbArrayCollection::addItem(gqbObject *item)\r
+{\r
+    gqbArray.Add(item);\r
+}\r
+\r
+\r
+// Remove item from array but don't delete it.\r
+void gqbArrayCollection::removeItem(gqbObject *item)\r
+{\r
+    gqbArray.Remove(item);\r
+}\r
+\r
+\r
+// Create an iterator for the objects inside the array\r
+gqbIteratorBase* gqbArrayCollection::createIterator()\r
+{\r
+    return (new gqbArrayIterator(&gqbArray));\r
+}\r
+\r
+// Create a Down to iterator for the objects inside the array\r
+gqbIteratorBase* gqbArrayCollection::createDownIterator()\r
+{\r
+    return (new gqbArrayDownIterator(&gqbArray));\r
+}\r
+\r
+// Return the number of elements inside the array\r
+int gqbArrayCollection::count()\r
+{\r
+    return gqbArray.Count();\r
+}\r
+\r
+\r
+// Return true if an element pointer is found inside array\r
+bool gqbArrayCollection::existsObject(gqbObject *item)\r
+{\r
+    gqbObject *found=NULL;\r
+    int size=gqbArray.GetCount();\r
+    for(int i=0;i<size;i++)\r
+    {\r
+        if (gqbArray.Item(i)==item)\r
+        {\r
+            found=gqbArray.Item(i);\r
+            break;\r
+        }\r
+    }\r
+    if(found)\r
+        return true;\r
+    else\r
+        return false;\r
+}\r
+\r
+\r
+// Delete all elements inside array\r
+void gqbArrayCollection::deleteAll()\r
+{\r
+    WX_CLEAR_ARRAY(gqbArray);\r
+}\r
+\r
+\r
+// Removes all elements inside array without deleting\r
+void gqbArrayCollection::removeAll()\r
+{\r
+    gqbArray.Empty();\r
+}\r
+\r
+// Get Item at certain position at Collection \r
+gqbObject* gqbArrayCollection::getItemAt(int index)\r
+{\r
+    if(!gqbArray.IsEmpty())\r
+        return gqbArray.Item(index);\r
+    else\r
+        return NULL;\r
+}\r
+\r
+\r
+int gqbArrayCollection::getIndex(gqbObject *item)\r
+{\r
+    return gqbArray.Index(item);\r
+}\r
+\r
+\r
+// Insert item into the array before the index\r
+void gqbArrayCollection:: insertAtIndex(gqbObject *item, int index)\r
+{\r
+    gqbArray.Insert(item,index);\r
+}\r
+\r
+\r
+//\r
+// gqbArrayIterator - Manages iterator for the array collection concrete class, from first to last element\r
+//\r
+\r
+// Constructor\r
+gqbArrayIterator::gqbArrayIterator(gqbObjsArray *gqbPtrsArray)\r
+{\r
+    position=0;\r
+    internalArray=gqbPtrsArray;\r
+}\r
+\r
+\r
+// Get next item in the array for the iterator\r
+gqbObject* gqbArrayIterator::Next()\r
+{\r
+    gqbObject *obj = internalArray->Item(position);\r
+    position++;\r
+    return obj;\r
+}\r
+\r
+\r
+// Return true if the array has more elements to return\r
+bool gqbArrayIterator::HasNext()\r
+{\r
+    int size=internalArray->GetCount();\r
+    if( (size>0) && (position<=(size-1)) )\r
+        return true;\r
+    else\r
+        return false;\r
+}\r
+\r
+\r
+void gqbArrayIterator::ResetIterator()\r
+{\r
+    position=0;\r
+}\r
+\r
+\r
+//\r
+// gqbArrayDownIterator - Manages iterator for the array collection concrete class from last to first element\r
+//\r
+\r
+// Constructor\r
+gqbArrayDownIterator::gqbArrayDownIterator(gqbObjsArray *gqbPtrsArray)\r
+{\r
+    internalArray=gqbPtrsArray;\r
+       position=internalArray->GetCount()-1;\r
+}\r
+\r
+\r
+// Get next item in the array for the iterator\r
+gqbObject* gqbArrayDownIterator::Next()\r
+{\r
+    gqbObject *obj = internalArray->Item(position);\r
+    position--;\r
+    return obj;\r
+}\r
+\r
+\r
+// Return true if the array has more elements to return\r
+bool gqbArrayDownIterator::HasNext()\r
+{\r
+    int size=internalArray->GetCount();\r
+    if( (size>0) && (position<=(size-1) && position>=0) )\r
+        return true;\r
+    else\r
+        return false;\r
+}\r
+\r
+\r
+void gqbArrayDownIterator::ResetIterator()\r
+{\r
+    position=internalArray->GetCount()-1;\r
+}\r
diff --git a/pgadmin/gqb/gqbBrowser.cpp b/pgadmin/gqb/gqbBrowser.cpp
new file mode 100644 (file)
index 0000000..e126858
--- /dev/null
@@ -0,0 +1,124 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbBrowser.cpp - Tables Tree of GQB.\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+#include <wx/regex.h>\r
+#include <wx/imaglist.h>\r
+\r
+// App headers\r
+#include "gqb/gqbBrowser.h"\r
+#include "gqb/gqbEvents.h"\r
+#include "gqb/gqbSchema.h"\r
+#include "gqb/gqbDatabase.h"\r
+#include "gqb/gqbViewController.h"\r
+\r
+// Images\r
+#include "images/table-sm.xpm"\r
+#include "images/view-sm.xpm"\r
+#include "images/namespace-sm.xpm"\r
+#include "images/namespaces.xpm"\r
+#include "images/database-sm.xpm"\r
+#include "images/catalog-sm.xpm"\r
+#include "images/catalogs.xpm"\r
+#include "images/catalogobject-sm.xpm"\r
+\r
+BEGIN_EVENT_TABLE(gqbBrowser, wxTreeCtrl)\r
+EVT_TREE_ITEM_ACTIVATED(GQB_BROWSER, gqbBrowser::OnItemActivated)\r
+EVT_TREE_BEGIN_DRAG(GQB_BROWSER, gqbBrowser::OnBeginDrag)\r
+END_EVENT_TABLE()\r
+\r
+gqbBrowser::gqbBrowser(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, gqbController *_controller)\r
+: wxTreeCtrl(parent, id, pos, size, style)\r
+{\r
+    controller=_controller;\r
+    rootNode=NULL;\r
+\r
+       // Create normal images list of browser\r
+    imageList = new wxImageList(16, 16);\r
+    imageList->Add(wxIcon(database_sm_xpm));\r
+    imageList->Add(wxIcon(namespace_sm_xpm));\r
+    imageList->Add(wxIcon(table_sm_xpm));\r
+    imageList->Add(wxIcon(namespaces_xpm));\r
+    imageList->Add(wxIcon(catalogs_xpm));\r
+    imageList->Add(wxIcon(catalog_sm_xpm));\r
+    imageList->Add(wxIcon(catalogobject_sm_xpm));\r
+       imageList->Add(wxIcon(view_sm_xpm));\r
+    this->AssignImageList(imageList);\r
+}\r
+\r
+\r
+// Destructor\r
+gqbBrowser::~gqbBrowser()\r
+{\r
+    this->DeleteAllItems();            // This remove and delete data inside tree's node\r
+}\r
+\r
+\r
+// Create root node\r
+wxTreeItemId& gqbBrowser::createRoot(wxString &Name)\r
+{\r
+    rootNode=this->AddRoot(Name,0,0);\r
+    catalogsNode=this->AppendItem(rootNode,wxT("Catalogs"),4,4,NULL);\r
+    schemasNode=this->AppendItem(rootNode,wxT("Schemas"),3,3,NULL);\r
+    return rootNode;\r
+}\r
+\r
+\r
+// Event activated when user double click on a item of tree\r
+void gqbBrowser::OnItemActivated(wxTreeEvent& event)\r
+{\r
+    wxTreeItemId itemId = event.GetItem();\r
+    gqbObject *object = (gqbObject *) GetItemData(itemId);\r
+    if(object!=NULL && object->getType()==_gqbTable)\r
+    {\r
+        gqbTable *item = (gqbTable *)  object;\r
+        controller->addTableToModel(item,wxPoint(10,10));\r
+        controller->getView()->Refresh();\r
+    }\r
+}\r
+\r
+\r
+void gqbBrowser::refreshTables(pgConn *connection)\r
+{\r
+    controller->emptyModel();\r
+    this->DeleteAllItems();                       // GQB-TODO: same as destructor\r
+    wxString a = wxString(wxT("Database Name Here"));\r
+    gqbDatabase *Data = new gqbDatabase(a,_gqbDatabase);\r
+    Data->createObjects(this,connection);\r
+    this->Expand(rootNode);\r
+}\r
+\r
+\r
+void gqbBrowser::OnBeginDrag(wxTreeEvent& event)\r
+{\r
+    wxTreeItemId itemId = event.GetItem();\r
+\r
+       // Simplest solution, simulate DnD but actually don't do it\r
+    gqbObject *object = (gqbObject *) GetItemData(itemId);\r
+    if(object!=NULL && object->getType()==_gqbTable)\r
+    {\r
+        gqbTable *item = (gqbTable *) object;\r
+        wxString tableName=item->getName();\r
+        wxTextDataObject textData(tableName);\r
+        wxDropSource dragSource(this);\r
+        dragSource.SetData(textData);\r
+        wxDragResult result = dragSource.DoDragDrop(wxDrag_CopyOnly);\r
+        if(result==wxDragCopy)\r
+        {\r
+            controller->getView()->CalcUnscrolledPosition(xx,yy,&xx,&yy);\r
+            controller->addTableToModel(item,wxPoint(xx,yy));\r
+            controller->getView()->Refresh();\r
+        }\r
+    }\r
+}\r
diff --git a/pgadmin/gqb/gqbCollection.cpp b/pgadmin/gqb/gqbCollection.cpp
new file mode 100644 (file)
index 0000000..7ccdb5b
--- /dev/null
@@ -0,0 +1,98 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbCollection.cpp - Generic implementation of a Collection used by GQB.\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+// App headers\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+\r
+// App headers\r
+#include "gqb/gqbCollection.h"\r
+#include "gqb/gqbObject.h"\r
+\r
+gqbCollection::gqbCollection(gqbCollectionBase *collectionBase)\r
+{\r
+    collection=collectionBase;\r
+}\r
+\r
+\r
+gqbCollection::~gqbCollection()\r
+{\r
+    if(collection)\r
+        delete collection;\r
+}\r
+\r
+\r
+void gqbCollection::addItem(gqbObject *item)\r
+{\r
+    collection->addItem(item);\r
+}\r
+\r
+\r
+void gqbCollection::removeItem(gqbObject *item)\r
+{\r
+    collection->removeItem(item);\r
+}\r
+\r
+\r
+gqbIteratorBase* gqbCollection::createIterator()\r
+{\r
+    return collection->createIterator();\r
+}\r
+\r
+gqbIteratorBase* gqbCollection::createDownIterator()\r
+{\r
+    return collection->createDownIterator();\r
+}\r
+\r
+\r
+int gqbCollection::count()\r
+{\r
+    return collection->count();\r
+}\r
+\r
+\r
+bool gqbCollection::existsObject(gqbObject *item)\r
+{\r
+    return collection->existsObject(item);\r
+}\r
+\r
+\r
+gqbObject* gqbCollection::getItemAt(int index)\r
+{\r
+    return collection->getItemAt(index);\r
+}\r
+\r
+\r
+// Remove all items from collection without deleting each one.\r
+void gqbCollection::removeAll()\r
+{\r
+    collection->removeAll();\r
+}\r
+\r
+\r
+void gqbCollection::deleteAll()\r
+{\r
+    collection->deleteAll();\r
+}\r
+\r
+\r
+int gqbCollection::getIndex(gqbObject *item)\r
+{\r
+    return collection->getIndex(item);\r
+}\r
+\r
+\r
+void gqbCollection::insertAtIndex(gqbObject *item, int index)\r
+{\r
+    collection->insertAtIndex(item,index);\r
+}\r
diff --git a/pgadmin/gqb/gqbColumn.cpp b/pgadmin/gqb/gqbColumn.cpp
new file mode 100644 (file)
index 0000000..b196f10
--- /dev/null
@@ -0,0 +1,31 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbColumn.cpp - Column Object for GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+// App headers\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+\r
+// App headers\r
+#include "gqb/gqbColumn.h"\r
+#include "gqb/gqbObject.h"\r
+#include "gqb/gqbSchema.h"\r
+#include "gqb/gqbTable.h"\r
+#include "gqb/gqbArrayCollection.h"\r
+\r
+gqbColumn::gqbColumn(gqbObject *parent, wxString name, type_gqbObject type=_gqbColumn):\r
+gqbObject(name, type)\r
+{\r
+    this->setType(_gqbColumn);\r
+    this->setName(name);\r
+    this->setOwner(parent);\r
+}\r
diff --git a/pgadmin/gqb/gqbController.cpp b/pgadmin/gqb/gqbController.cpp
new file mode 100644 (file)
index 0000000..a9502fa
--- /dev/null
@@ -0,0 +1,595 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbController.cpp - Controller part of MVC Software Pattern used by GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+#include <wx/grid.h>\r
+#include <wx/dnd.h>\r
+#include <wx/dataobj.h>\r
+\r
+// App headers\r
+#include "frm/frmQuery.h"\r
+#include "gqb/gqbViewController.h"\r
+#include "gqb/gqbModel.h"\r
+#include "gqb/gqbSchema.h"\r
+#include "gqb/gqbQueryObjs.h"\r
+#include "gqb/gqbBrowser.h"\r
+#include "gqb/gqbEvents.h"\r
+#include "gqb/gqbViewPanels.h"\r
+\r
+gqbController::gqbController(gqbModel *_model, wxWindow *gqbParent, wxNotebook *gridParent, wxSize size=wxSize(800,1280)):\r
+wxObject()\r
+{\r
+    pparent = gqbParent;\r
+    model=_model;\r
+    wxSize tablesBrowserSize = wxSize(200,800);   //Initial Size\r
+\r
+    // Initialize Main Splitter\r
+    gqbMainContainer = new wxSplitterWindow(gqbParent,GQB_HORZ_SASH,wxDefaultPosition,wxDefaultSize,wxSP_3D);\r
+    tabs = new wxNotebook(gqbMainContainer, CTL_NTBKCENTER, wxDefaultPosition, wxDefaultSize);\r
+\r
+    // Initialize view container with tables browser\r
+    // GQB-TODO: change 976 with a enum value of events.h\r
+    gqbContainer = new gqbSplitter(gqbMainContainer,976,wxDefaultPosition,wxDefaultSize,wxSP_3D);\r
+\r
+    // Initialize view canvas and tables tree\r
+    browserPanel = new wxPanel(gqbContainer, wxID_ANY,wxDefaultPosition,tablesBrowserSize);\r
+    tablesBrowser = new gqbBrowser(browserPanel, GQB_BROWSER, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxSIMPLE_BORDER,this);\r
+    view=new gqbView(gqbContainer, gridParent, size, this, model);\r
+\r
+    // Set Drag Target\r
+    view->SetDropTarget(new DnDText(tablesBrowser));\r
+\r
+    // Set Scroll Bar & split\r
+    view->SetScrollbars( 10, 10, 127, 80 );\r
+    gqbContainer->SplitVertically(browserPanel,view);\r
+\r
+    tabs->AddPage(view->getColsGridPanel(), _("Columns"));\r
+    tabs->AddPage(view->getCriteriaPanel(), _("Criteria"));\r
+    tabs->AddPage(view->getOrderPanel(), _("Ordering"));\r
+    gqbMainContainer->SplitHorizontally(gqbContainer,tabs);\r
+\r
+    // Fix Sash resize bug\r
+    gqbContainer->setTablesBrowser(tablesBrowser);\r
+    gqbContainer->setBrowserPanel(browserPanel);\r
+}\r
+\r
+\r
+// Destructor\r
+gqbController::~gqbController()\r
+{\r
+    if(view)\r
+    {\r
+        delete view;\r
+        view=NULL;\r
+    }\r
+}\r
+\r
+\r
+// Add a table to the model\r
+void gqbController::addTableToModel(gqbTable *table, wxPoint p)\r
+{\r
+    gqbQueryObject *added = model->addTable(table,p);\r
+    view->newTableAdded(added);\r
+}\r
+\r
+\r
+// Remove a table from the model\r
+void gqbController::removeTableFromModel(gqbQueryObject *mtable, gqbGridProjTable *gridTable=NULL, gqbGridOrderTable *orderLTable=NULL, gqbGridOrderTable *orderRTable=NULL)\r
+{\r
+    model->deleteTable(mtable);\r
+    gridTable->removeAllRows(mtable);             // GQB-TODO: move this functions to model??\r
+    orderLTable->emptyTableData(mtable);\r
+    orderRTable->emptyTableData(mtable);\r
+}\r
+\r
+\r
+// Add (Select to be use in projection) a column for table in a model\r
+void gqbController::processColumnInModel(gqbQueryObject *table, gqbColumn *column,  gqbGridProjTable *gridTable=NULL)\r
+{\r
+    if(!table->existsColumn(column))\r
+    {\r
+        table->addColumn(column);\r
+        if(gridTable)\r
+        {\r
+            gridTable->AppendItem(0,table);\r
+            gridTable->AppendItem(1,column);\r
+            gridTable->AppendItem(2,NULL);\r
+        }\r
+    }\r
+    else\r
+    {\r
+        // Removes but don't delete because we needed the column at table [this is just a pointer to it]\r
+        table->removeColumn(column);\r
+        if(gridTable)\r
+        {\r
+            gridTable->removeRow(table,column);\r
+        }\r
+    }\r
+}\r
+\r
+\r
+// Get selected item at position pt, marks item as selected and if there is a previous selected then unselect it\r
+gqbObject* gqbController::getModelSelected(wxPoint &pt, gqbQueryObject *lastSelected, gqbQueryJoin *lastJoinSelected, bool mark)\r
+{\r
+    gqbQueryObject *sel=NULL;\r
+    gqbQueryJoin *jSel=NULL;\r
+    gqbIteratorBase *iterator=model->createDownQueryIterator();\r
+    bool found=false;\r
+\r
+    while(!found && iterator->HasNext())\r
+    {\r
+        // Try to find if click over a table\r
+        sel=(gqbQueryObject *)iterator->Next();\r
+        if( ((pt.x - sel->position.x > 0 )&&(sel->position.x + sel->getWidth() > pt.x)) && ((pt.y - sel->position.y > 0)&&(sel->position.y + sel->getHeight() > pt.y)) )\r
+        {    \r
+                       // GQB-TODO: this function should be move to the view to allow to \r
+                       // recalculate it if the graphBehavior changes\r
+            if(mark)\r
+                sel->setSelected(true);\r
+\r
+            jSel=NULL;\r
+            found=true;\r
+            break;\r
+        }\r
+\r
+        // Try to find if user click over a Join\r
+        if(sel->getHaveJoins())\r
+        {\r
+            gqbIteratorBase *joinsIterator = sel->createJoinsIterator();\r
+            while(joinsIterator->HasNext())\r
+            {\r
+                // GQB-TODO: don't pass anchor because join it's passed as parameter yet.\r
+                jSel = (gqbQueryJoin *) joinsIterator->Next();\r
+                wxPoint o = jSel->getSourceAnchor();\r
+                wxPoint d = jSel->getDestAnchor();\r
+\r
+                if(view->clickOnJoin(jSel,pt,o,d))\r
+                {\r
+                    if(mark)\r
+                        jSel->setSelected(true);\r
+                    found=true;\r
+                    sel=NULL;\r
+                    break;\r
+                }\r
+\r
+            }\r
+            delete joinsIterator;\r
+        }\r
+    }\r
+\r
+    delete iterator;\r
+\r
+    if(found)\r
+    {\r
+        if(mark)\r
+        {\r
+            if(lastSelected && lastSelected!=sel) // Unselect previous table selected if exists\r
+                lastSelected->setSelected(false);\r
+                                                  // Unselect previous join selected if exists\r
+            if(lastJoinSelected && lastJoinSelected!=jSel)\r
+                lastJoinSelected->setSelected(false);\r
+        }\r
+        if(sel)\r
+            return sel;\r
+        else if(jSel)\r
+            return jSel;\r
+    }\r
+\r
+    return NULL;\r
+}\r
+\r
+\r
+// Unselect any previously selected item in the model\r
+void gqbController::unsetModelSelected(bool queryTable=true)\r
+{\r
+    gqbQueryObject *sel=NULL;\r
+    gqbQueryJoin *jSel=NULL;\r
+\r
+    if(queryTable)                                // QueryTable\r
+    {\r
+        gqbIteratorBase *iterator=model->createQueryIterator();\r
+        while(iterator->HasNext())\r
+        {\r
+            sel=(gqbQueryObject *)iterator->Next();\r
+            if(sel->getSelected())\r
+            {\r
+                sel->setSelected(false);\r
+            }\r
+        }\r
+        delete iterator;\r
+    }\r
+\r
+    if(!queryTable)                               // QueryJoin\r
+    {\r
+        gqbIteratorBase *iterator=model->createQueryIterator();\r
+        gqbQueryObject *sel=NULL;\r
+        while(iterator->HasNext())\r
+        {\r
+            sel=(gqbQueryObject *)iterator->Next();\r
+            if(sel->getHaveJoins())\r
+            {\r
+                gqbIteratorBase *joinsIterator = sel->createJoinsIterator();\r
+                while(joinsIterator->HasNext())\r
+                {\r
+                    // GQB-TODO: don't pass anchor because join it's passed as parameter yet.\r
+                    jSel = (gqbQueryJoin *) joinsIterator->Next();\r
+                    if(jSel->getSelected())\r
+                    {\r
+                        jSel->setSelected(false);\r
+                    }\r
+                }\r
+\r
+                delete joinsIterator;\r
+            }\r
+        }\r
+        delete iterator;\r
+    }\r
+}\r
+\r
+\r
+// GQB-TODO: Create a less complex & simpler generation function\r
+// Generate the SQL Sentence from the model\r
+wxString gqbController::generateSQL()\r
+{\r
+    wxString sentence=wxT("");\r
+    if(model->tablesCount()>0)\r
+    {\r
+        sentence+=wxT("SELECT \n");\r
+\r
+               // Add selected columns for Query\r
+        gqbQueryObject *sel=NULL;\r
+        gqbIteratorBase *iteratorRestrictions=NULL;\r
+        gqbIteratorBase *iteratorModel=NULL;\r
+        gqbIteratorBase *iteratorJoins=NULL;\r
+\r
+        // Projection Part [Select x,x,x...]\r
+        gqbObjsArray *cols=model->getOrderedColumns();\r
+        gqbObjsArray *tables=model->getColumnsParents();\r
+        wxArrayString *alias=model->getColumnsAlias();\r
+\r
+        int i,size=cols->GetCount();\r
+\r
+        for(i=0;i<size;i++)\r
+        {\r
+            if(alias->Item(i).length()>0)\r
+                       {\r
+                               if(((gqbQueryObject*)tables->Item(i))->getAlias().length()>0)\r
+                               {\r
+                           sentence += wxT("  ") +\r
+                                                       qtIdent(((gqbQueryObject*)tables->Item(i))->getAlias()) +\r
+                                                           wxT(".") +\r
+                                                           qtIdent(((gqbColumn*)cols->Item(i))->getName()) +\r
+                                                           wxT(" AS ") + \r
+                                                           qtIdent(alias->Item(i)) +\r
+                                                           wxT(", \n");\r
+                               }\r
+                               else\r
+                               {\r
+                           sentence += wxT("  ") +\r
+                                                       qtIdent(((gqbQueryObject*)tables->Item(i))->getName()) + \r
+                                                               wxT(".") +\r
+                                                               qtIdent(((gqbColumn*)cols->Item(i))->getName()) +\r
+                                                               wxT(" AS ") + \r
+                                                               qtIdent(alias->Item(i)) +\r
+                                                               wxT(", \n");\r
+                               }\r
+                       }\r
+            else\r
+                       {\r
+                if(((gqbQueryObject*)tables->Item(i))->getAlias().length()>0)\r
+                               {\r
+                                   sentence += wxT("  ") +\r
+                                                       qtIdent(((gqbQueryObject*)tables->Item(i))->getAlias()) + \r
+                                                               wxT(".") +\r
+                                                               qtIdent(((gqbColumn*)cols->Item(i))->getName()) + \r
+                                                               wxT(", \n");\r
+                               }\r
+                               else\r
+                               {\r
+                                   sentence += wxT("  ") +\r
+                                                       qtIdent(((gqbQueryObject*)tables->Item(i))->getName()) +\r
+                                                               wxT(".") +\r
+                                                               qtIdent(((gqbColumn*)cols->Item(i))->getName()) +\r
+                                                               wxT(", \n");\r
+                               }\r
+                       }\r
+        }\r
+\r
+        if(!size)\r
+            sentence+=wxT("  * \n");\r
+        else\r
+        {\r
+            // remove last ", "\r
+            sentence.Truncate(sentence.Length()-3);\r
+            sentence+=wxT("\n");\r
+        }\r
+\r
+        sentence+=wxT("FROM \n");\r
+\r
+        iteratorModel=model->createQueryIterator();\r
+        while(iteratorModel->HasNext())\r
+        {\r
+            sel=(gqbQueryObject *)iteratorModel->Next();\r
+            gqbSchema *schema = (gqbSchema *)&sel->parent->getOwner();\r
+            if(sel->getAlias().length()>0)\r
+            {\r
+                sentence += wxT("  ") +\r
+                                               qtIdent(schema->getName()) +\r
+                                                       wxT(".") +\r
+                                                       qtIdent(sel->getName()) +\r
+                                                       wxT(" ") + \r
+                                                       qtIdent(sel->getAlias()) +\r
+                                                       wxT(", \n");\r
+            }\r
+            else\r
+            {\r
+                sentence += wxT("  ") +\r
+                                               qtIdent(schema->getName()) +\r
+                                                       wxT(".") +\r
+                                                       qtIdent(sel->getName()) + \r
+                                                       wxT(", \n");\r
+            }\r
+\r
+        }\r
+        sentence.Truncate(sentence.Length()-3);   // remove last ", "\r
+\r
+        // WHERE PART\r
+        // [Joins]\r
+        bool first=true, truncAnd=false;\r
+        gqbQueryJoin *tmp;\r
+        iteratorModel->ResetIterator();\r
+        while(iteratorModel->HasNext())\r
+        {\r
+            sel=(gqbQueryObject *)iteratorModel->Next();\r
+            if(sel->getHaveJoins())\r
+            {\r
+                truncAnd=true;\r
+                iteratorJoins=sel->createJoinsIterator();\r
+                while(iteratorJoins->HasNext())\r
+                {\r
+                    if(first)\r
+                    {\r
+                        first=false;\r
+                        sentence+= wxT("\nWHERE \n");\r
+                    }\r
+                    tmp = (gqbQueryJoin *)iteratorJoins->Next();\r
+\r
+                    if(tmp->getSourceQTable()->getAlias().length()>0)\r
+                        sentence+= wxT("  ") + \r
+                                                          qtIdent(tmp->getSourceQTable()->getAlias()) + \r
+                                                                  wxT(".") +\r
+                                                                  qtIdent(tmp->getSourceCol());\r
+                    else\r
+                        sentence+= wxT("  ") + \r
+                                                          qtIdent(tmp->getSourceQTable()->getName()) + \r
+                                                                  wxT(".") +\r
+                                                                  qtIdent(tmp->getSourceCol());\r
+\r
+                    switch(tmp->getKindofJoin())\r
+                    {\r
+                        case _equally:\r
+                            sentence+= wxT(" = ");\r
+                            break;\r
+                        case _greater:\r
+                            sentence+= wxT(" > ");\r
+                            break;\r
+                        case _lesser:\r
+                            sentence+= wxT(" < ");\r
+                            break;\r
+                        case _equgreater:\r
+                            sentence+= wxT(" >= ");\r
+                            break;\r
+                        case _equlesser:\r
+                            sentence+= wxT(" <= ");\r
+                            break;\r
+\r
+                    }\r
+\r
+                    if(tmp->getDestQTable()->getAlias().length()>0)\r
+                        sentence += qtIdent(tmp->getDestQTable()->getAlias()) + \r
+                                                           wxT(".") +\r
+                                                                       qtIdent(tmp->getDestCol()) + \r
+                                                                       wxT(" AND\n");\r
+                    else\r
+                        sentence += qtIdent(tmp->getDestQTable()->getName()) + \r
+                                                           wxT(".") +\r
+                                                                       qtIdent(tmp->getDestCol()) +\r
+                                                                       wxT(" AND\n");\r
+                }\r
+                delete iteratorJoins;\r
+            }\r
+        }\r
+        delete iteratorModel;\r
+\r
+        gqbRestrictions *restrictions=model->getRestrictions();\r
+\r
+        // Remove last " AND " from joins if there isn't restrictions, only left white space\r
+               if(truncAnd && (restrictions->restrictionsCount()<=0))\r
+                sentence.Truncate(sentence.Length()-6);\r
+\r
+        // Never found a join\r
+        if (!truncAnd && (restrictions->restrictionsCount()>0))\r
+            sentence+= wxT("\nWHERE \n");\r
+\r
+        //GQB-TODO: VALIDATE RESTRICTIONS\r
+        iteratorRestrictions=restrictions->createRestrictionsIterator();\r
+        gqbQueryRestriction *r;\r
+\r
+        while(iteratorRestrictions->HasNext())\r
+        {\r
+            r=(gqbQueryRestriction *)iteratorRestrictions->Next();\r
+            sentence += wxT("  ") +\r
+                                       r->getLeft() +\r
+                                               wxT(" ") +\r
+                                               r->getRestriction() +\r
+                                               wxT(" ") +\r
+                                               r->getValue_s() +\r
+                                               wxT(" ") + \r
+                                               r->getConnector() +\r
+                                               wxT(" \n");\r
+        }\r
+        delete iteratorRestrictions;\r
+\r
+        if(restrictions->restrictionsCount()>0)\r
+        {\r
+            if(r->getConnector().Contains(wxT("AND")))\r
+            {\r
+                sentence.Truncate(sentence.Length()-6);\r
+            }\r
+            else\r
+            {\r
+                sentence.Truncate(sentence.Length()-5);\r
+            }\r
+        }\r
+        // ORDER BY PART\r
+        gqbObjsArray* orderByColumns=model->getOrdByColumns();\r
+        gqbObjsArray* orderByParents=model->getOrdByParents();\r
+        charArray* typeOfOrder=model->getOrdByKind();\r
+\r
+        size=orderByColumns->GetCount();\r
+        if(size>0)\r
+        {\r
+            sentence+=wxT("\nORDER BY\n");\r
+        }\r
+        wxString typeOrder=wxT("");\r
+        for(i=0;i<size;i++)\r
+        {\r
+            switch(typeOfOrder->Item(i))\r
+            {\r
+                case 'A':\r
+                    typeOrder=wxT(" ASC");\r
+                    break;\r
+                case 'D':\r
+                    typeOrder=wxT(" DESC");\r
+                    break;\r
+            };\r
+            if(((gqbQueryObject*)orderByParents->Item(i))->getAlias().length()>0)\r
+                sentence += wxT("  ") +\r
+                                           qtIdent(((gqbQueryObject*)orderByParents->Item(i))->getAlias()) +\r
+                                                       wxT(".") +\r
+                                                       qtIdent(((gqbColumn*)orderByColumns->Item(i))->getName()) + \r
+                                                       typeOrder + \r
+                                                       wxT(", \n");\r
+            else\r
+                sentence += wxT("  ") +\r
+                                           qtIdent(((gqbQueryObject*)orderByParents->Item(i))->getName()) +\r
+                                                       wxT(".") +\r
+                                                       qtIdent(((gqbColumn*)orderByColumns->Item(i))->getName()) +\r
+                                                       typeOrder + \r
+                                                       wxT(", \n");\r
+        }\r
+\r
+        if(size>0)\r
+            sentence.Truncate(sentence.Length()-3);\r
+\r
+        sentence+=wxT(";");\r
+    }                                             // Close Tables Count > 0 on model\r
+    return sentence;\r
+}\r
+\r
+\r
+gqbQueryRestriction* gqbController::addRestriction()\r
+{\r
+    return model->addRestriction();\r
+}\r
+\r
+\r
+gqbQueryJoin* gqbController::addJoin(gqbQueryObject *sTable, gqbColumn *sColumn, gqbQueryObject *dTable, gqbColumn *dColumn, type_Join kind)\r
+{\r
+    return sTable->addJoin(sTable,dTable,sColumn,dColumn,kind);\r
+}\r
+\r
+\r
+void gqbController::removeJoin(gqbQueryJoin *join)\r
+{\r
+    join->getSourceQTable()->removeJoin(join,true);\r
+}\r
+\r
+\r
+void gqbController::setPointerMode(pointerMode pm)\r
+{\r
+    view->setPointerMode(pm);\r
+}\r
+\r
+\r
+void gqbController::emptyModel()\r
+{\r
+    view->emptyPanelsData();\r
+    model->emptyAll();\r
+}\r
+\r
+\r
+void gqbController::calcGridColsSizes()\r
+{\r
+    // Recalculate best internals sizes for all columns inside grids.\r
+    ((gqbGridPanel *)view->getColsGridPanel())->SetGridColsSize();\r
+    ((gqbCriteriaPanel *)view->getCriteriaPanel())->SetGridColsSize();\r
+    ((gqbOrderPanel *)view->getOrderPanel())->SetGridColsSize();\r
+}\r
+\r
+\r
+void gqbController::setSashVertPosition(int pos)\r
+{\r
+    gqbContainer->UpdateSize();\r
+    gqbContainer->SetSashPosition(pos,true);\r
+    gqbContainer->SetMinimumPaneSize(pos);\r
+    gqbContainer->UpdateSize();\r
+}\r
+\r
+int gqbController::getSashHorizPosition(){\r
+       return gqbMainContainer->GetSashPosition();\r
+}\r
+\r
+\r
+void gqbController::setSashHorizPosition(int pos)\r
+{\r
+    gqbMainContainer->UpdateSize();\r
+    gqbMainContainer->SetSashPosition(pos,true);\r
+\r
+  if(pos>=150 && pos<=200)\r
+  {\r
+         gqbMainContainer->SetMinimumPaneSize(pos);\r
+  }\r
+  else\r
+  {\r
+      gqbMainContainer->SetMinimumPaneSize(150);       \r
+  }\r
+  gqbMainContainer->UpdateSize();\r
+}\r
+\r
+\r
+//\r
+// Utility Class to avoid a bug when the event sash resize is called [onVerticalSashResize]\r
+//\r
+\r
+// GQB-TODO: fix 976 for real one value here and above\r
+\r
+BEGIN_EVENT_TABLE(gqbSplitter, wxSplitterWindow)\r
+EVT_SPLITTER_SASH_POS_CHANGED(976, gqbSplitter::onVerticalSashResize)\r
+END_EVENT_TABLE()\r
+\r
+gqbSplitter::gqbSplitter(wxWindow* parent, wxWindowID id, const wxPoint& point, const wxSize& size, long style)\r
+:wxSplitterWindow(parent,id,point,size,style)\r
+{\r
+}\r
+\r
+\r
+void gqbSplitter::onVerticalSashResize(wxSplitterEvent& event)\r
+{\r
+    wxSize s = tablesBrowser->GetSize();\r
+    s.SetWidth(event.GetSashPosition());\r
+    browserPanel->SetSize(s);\r
+    tablesBrowser->SetSize(s);\r
+    // GQB-TODO: Set a minimun value\r
+}\r
diff --git a/pgadmin/gqb/gqbDatabase.cpp b/pgadmin/gqb/gqbDatabase.cpp
new file mode 100644 (file)
index 0000000..cd3507e
--- /dev/null
@@ -0,0 +1,169 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbDatabase.cpp - Database object for GQB.\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+// App headers\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+#include <wx/regex.h>\r
+\r
+// App headers\r
+#include "gqb/gqbDatabase.h"\r
+#include "gqb/gqbObject.h"\r
+#include "gqb/gqbSchema.h"\r
+#include "schema/pgSchema.h"\r
+\r
+gqbDatabase::gqbDatabase(wxString name, type_gqbObject type=_gqbDatabase):\r
+gqbObject(name,type)\r
+{\r
+    this->setType(_gqbDatabase);\r
+    this->setName(name);\r
+    this->setOwner(NULL);\r
+    conn=NULL;\r
+}\r
+\r
+\r
+void gqbDatabase::createObjects(gqbBrowser *_tablesBrowser,  pgConn *_conn)\r
+{\r
+\r
+    wxString rootNodeString = wxString(_conn->GetDbname());\r
+    // Create Root Node\r
+    _tablesBrowser->createRoot(rootNodeString);\r
+\r
+    // FillBrowser\r
+    createSchemas(_conn,_tablesBrowser,_tablesBrowser->getCatalogRootNode(),GQB_CATALOG,5);\r
+    createSchemas(_conn,_tablesBrowser,_tablesBrowser->getTablesRootNode(),GQB_OTHER,1);\r
+}\r
+\r
+\r
+// Use database connection to create all objects inside tree\r
+void gqbDatabase::createSchemas(pgConn *conn,  gqbBrowser *tablesBrowser, wxTreeItemId parentNode,typeSchema MetaType, int indexImage)\r
+{\r
+\r
+    // Search Schemas and insert it\r
+    wxString restr =  wxT(" WHERE ");\r
+\r
+    if (MetaType != GQB_CATALOG)\r
+    {\r
+        restr += wxT("NOT ");\r
+    }\r
+    restr += wxT("((nspname = 'pg_catalog' and (SELECT count(*) FROM pg_class WHERE relname = 'pg_class' AND relnamespace = nsp.oid) > 0) OR\n");\r
+    restr += wxT("(nspname = 'pgagent' and (SELECT count(*) FROM pg_class WHERE relname = 'pga_job' AND relnamespace = nsp.oid) > 0) OR\n");\r
+    restr += wxT("(nspname = 'information_schema' and (SELECT count(*) FROM pg_class WHERE relname = 'tables' AND relnamespace = nsp.oid) > 0) OR\n");\r
+    restr += wxT("(nspname LIKE '_%' and (SELECT count(*) FROM pg_proc WHERE proname='slonyversion' AND pronamespace = nsp.oid) > 0) OR\n");\r
+    restr += wxT("(nspname = 'dbo' and (SELECT count(*) FROM pg_class WHERE relname = 'systables' AND relnamespace = nsp.oid) > 0) OR\n");\r
+    restr += wxT("(nspname = 'sys' and (SELECT count(*) FROM pg_class WHERE relname = 'all_tables' AND relnamespace = nsp.oid) > 0)) AND nspname!='information_schema'\n");\r
+\r
+    if (conn->EdbMinimumVersion(8, 2))\r
+        restr += wxT("  AND nsp.nspparent = 0\n");\r
+\r
+    wxString sql;\r
+\r
+    if (MetaType == GQB_CATALOG)\r
+    {\r
+        sql = wxT("SELECT 2 AS nsptyp,\n")\r
+            wxT("       nsp.nspname, nsp.oid, pg_get_userbyid(nspowner) AS namespaceowner, nspacl, description,")\r
+            wxT("       FALSE as cancreate\n")\r
+            wxT("  FROM pg_namespace nsp\n")\r
+            wxT("  LEFT OUTER JOIN pg_description des ON des.objoid=nsp.oid\n")\r
+            + restr +\r
+            wxT(" ORDER BY 1, nspname");\r
+    }\r
+    else\r
+    {\r
+        if (conn->BackendMinimumVersion(8, 1))\r
+        {\r
+            sql = wxT("SELECT CASE WHEN nspname LIKE E'pg\\\\_temp\\\\_%' THEN 1\n")\r
+                wxT("            WHEN (nspname LIKE E'pg\\\\_%') THEN 0\n");\r
+        }\r
+        else\r
+        {\r
+            sql = wxT("SELECT CASE WHEN nspname LIKE 'pg\\\\_temp\\\\_%' THEN 1\n")\r
+                wxT("            WHEN (nspname LIKE 'pg\\\\_%') THEN 0\n");\r
+        }\r
+        sql += wxT("            ELSE 3 END AS nsptyp,\n")\r
+            wxT("       nsp.nspname, nsp.oid, pg_get_userbyid(nspowner) AS namespaceowner, nspacl, description,")\r
+            wxT("       has_schema_privilege(nsp.oid, 'CREATE') as cancreate\n")\r
+            wxT("  FROM pg_namespace nsp\n")\r
+            wxT("  LEFT OUTER JOIN pg_description des ON des.objoid=nsp.oid\n")\r
+            + restr +\r
+            wxT(" ORDER BY 1, nspname");\r
+    }\r
+\r
+    pgSet *schemas = conn->ExecuteSet(sql);\r
+    wxTreeItemId parent;\r
+\r
+    if (schemas)\r
+    {\r
+        while (!schemas->Eof())\r
+        {\r
+            wxString name=schemas->GetVal(wxT("nspname"));\r
+            long nsptyp=schemas->GetLong(wxT("nsptyp"));\r
+\r
+            wxStringTokenizer tokens(settings->GetSystemSchemas(), wxT(","));\r
+            while (tokens.HasMoreTokens())\r
+            {\r
+                wxRegEx regex(tokens.GetNextToken());\r
+                if (regex.Matches(name))\r
+                {\r
+                    nsptyp = SCHEMATYP_USERSYS;\r
+                    break;\r
+                }\r
+            }\r
+\r
+            if (nsptyp <= SCHEMATYP_USERSYS && MetaType != GQB_CATALOG && !settings->GetShowSystemObjects())\r
+            {\r
+                schemas->MoveNext();\r
+                continue;\r
+            }\r
+\r
+            if (MetaType == PGM_CATALOG)\r
+            {\r
+\r
+                // Create Schema Object\r
+                wxString tmpname = wxString(name);\r
+                gqbSchema *schema = new gqbSchema(this, tmpname, _gqbSchema);\r
+                parent=tablesBrowser->AppendItem(parentNode, name , indexImage, indexImage,schema);\r
+                schema->createObjects(tablesBrowser, conn, schemas->GetOid(wxT("oid")), parent, 5, 5);\r
+                schemas->MoveNext();\r
+            }\r
+            else\r
+            {\r
+\r
+                // Create Schema Object\r
+                wxString tmpname= wxString(name);\r
+                gqbSchema *schema = new gqbSchema(this, tmpname, _gqbSchema);\r
+                parent=tablesBrowser->AppendItem(parentNode, name , indexImage, indexImage,schema);\r
+                int tableImage=-1, viewImage=-1;\r
+\r
+                //GQB-TODO: temporary fix replace this with a better one option\r
+                if(schema->getName().Contains(wxT("pg_catalog")))\r
+                               {\r
+                    tableImage=6;\r
+                                       viewImage=6;\r
+                               }\r
+                else\r
+                               {\r
+                    tableImage=2;\r
+                                       viewImage=7;\r
+                               }\r
+\r
+                //Create tables inside this schema.\r
+                schema->createObjects(tablesBrowser, conn, schemas->GetOid(wxT("oid")), parent, tableImage, viewImage);\r
+\r
+                schemas->MoveNext();\r
+            }\r
+        }\r
+\r
+        delete schemas;\r
+    }\r
+}\r
diff --git a/pgadmin/gqb/gqbGraphSimple.cpp b/pgadmin/gqb/gqbGraphSimple.cpp
new file mode 100644 (file)
index 0000000..00217b6
--- /dev/null
@@ -0,0 +1,486 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbGraphsimple.cpp - A simple Implementation of the Graphic Interface for GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+// App headers\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+#include <wx/dcbuffer.h>\r
+\r
+// App headers\r
+#include "utils/sysSettings.h"\r
+#include "gqb/gqbGraphSimple.h"\r
+#include "gqb/gqbQueryObjs.h"\r
+// GQB Images\r
+#include "images/gqbColNotSel.xpm"\r
+#include "images/gqbColSel.xpm"\r
+\r
+gqbGraphSimple::gqbGraphSimple()\r
+{\r
+    normalFont = settings->GetSystemFont();\r
+    TableTitleFont = settings->GetSystemFont();\r
+    TableTitleFont.SetWeight(wxFONTWEIGHT_BOLD);\r
+    BackgroundLayer1 = wxBrush(wxColour(112, 112, 112),wxSOLID);\r
+    BackgroundLayer2 = wxBrush (wxColour(208, 208, 208),wxSOLID);\r
+    BackgroundTitle = wxBrush (wxColour(245, 245, 245),wxSOLID);\r
+    minTableWidth=80;\r
+    minTableHeight=54;\r
+    rowHeight=0;                                  //By default but this it's replaced by font metrics value\r
+    rowLeftMargin=14;\r
+    rowRightMargin=5;\r
+    rowTopMargin=1;\r
+    lineClickThreshold=7;\r
+    selectedPen=wxPen(wxColour(0,146,195),2,wxSOLID);\r
+    selectedBrush=wxBrush(wxColour(0,146,195),wxSOLID);\r
+    imgSelBoxEmpty = wxBitmap(gqbColNotSel_xpm);\r
+    imgSelBoxSelected = wxBitmap(gqbColSel_xpm);\r
+\r
+}\r
+\r
+\r
+// NOTES:(1) store values of width & height at queryTable.\r
+// (2)Need to set a font for the device context before get font metrics with GetTextExtent\r
+void gqbGraphSimple::drawTable(wxBufferedDC& bdc, wxPoint *origin, gqbQueryObject *queryTable)\r
+{\r
+    long  w=0,h=0,height=0,width=0,margin=5;\r
+\r
+    // Get Value for row Height\r
+    if(!rowHeight)\r
+    {\r
+        bdc.SetFont(TableTitleFont);\r
+        bdc.GetTextExtent(wxT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxtz"),&w,&h);\r
+        rowHeight=h;\r
+    }\r
+\r
+    // Get Title Metrics\r
+    bdc.SetFont(TableTitleFont);\r
+    height+= rowHeight + rowTopMargin;\r
+\r
+    // Calculate font metrics for table title with/without alias\r
+    if(queryTable->getAlias().length()>0)\r
+        bdc.GetTextExtent(queryTable->getName()+wxT(" (")+queryTable->getAlias()+wxT(")"),&w,&h);\r
+    else\r
+        bdc.GetTextExtent(queryTable->getName(),&w,&h);\r
+    width= rowLeftMargin + w + rowRightMargin;\r
+\r
+    // Get Columns Metrics\r
+    bdc.SetFont(normalFont);\r
+\r
+    // Don't use h value from font metrics to get consistency between columns vertical separation (height)\r
+    height+=rowHeight*queryTable->parent->countCols()+rowTopMargin*queryTable->parent->countCols();\r
+    gqbIteratorBase *iterator = queryTable->parent->createColumnsIterator();\r
+    while(iterator->HasNext())\r
+    {\r
+        gqbColumn *tmp= (gqbColumn *)iterator->Next();\r
+        bdc.GetTextExtent(tmp->getName(),&w,&h);\r
+        if((rowLeftMargin + w + rowRightMargin) > width)\r
+            width=rowLeftMargin + w + rowRightMargin;\r
+    }\r
+\r
+    //Don't delete iterator because will be use below;\r
+\r
+       // Set table Size in ObjectModel (Temporary Values for object representation,\r
+       // and for this reason the view can modified model without using the controller\r
+       // because this values are used by controller when use object's size in internal operations)\r
+    if( (height+2) < minTableHeight) // +2 from BackgroundLayers addition\r
+    {\r
+        queryTable->setHeight(minTableHeight);    \r
+        height=minTableHeight;\r
+    }\r
+    else\r
+        queryTable->setHeight(height+2);\r
+\r
+    if( (width+2) < minTableWidth)\r
+    {\r
+        queryTable->setWidth(minTableWidth);\r
+        width=minTableWidth;\r
+    }\r
+    else\r
+        queryTable->setWidth(width+2);\r
+\r
+    //Decorate Table\r
+    bdc.SetPen(*wxTRANSPARENT_PEN);\r
+\r
+    //draw second Layer\r
+    bdc.SetBrush(BackgroundLayer2);\r
+    bdc.DrawRectangle(wxRect(wxPoint(origin->x,origin->y), wxSize(width+2,height+2)));\r
+\r
+    //draw third Layer\r
+    bdc.SetBrush(BackgroundLayer1);\r
+    bdc.DrawRectangle(wxRect(wxPoint(origin->x,origin->y), wxSize(width+1,height+1)));\r
+\r
+    //draw real frame layer\r
+    bdc.SetBrush(*wxWHITE_BRUSH);\r
+    if(queryTable->getSelected())\r
+    {\r
+        bdc.SetPen(selectedPen);\r
+    }\r
+    else\r
+    {\r
+        bdc.SetPen(*wxBLACK_PEN);\r
+    }\r
+    bdc.DrawRectangle(wxRect(wxPoint(origin->x,origin->y), wxSize(width,height)));\r
+\r
+    //draw title layer\r
+    bdc.SetBrush(BackgroundTitle);\r
+    bdc.DrawRectangle(wxRect(wxPoint(origin->x,origin->y), wxSize(width,rowHeight+rowTopMargin)));\r
+    bdc.SetFont(TableTitleFont);\r
+    if(queryTable->getAlias().length()>0)\r
+        bdc.DrawText(queryTable->getName()+wxT(" (")+queryTable->getAlias()+wxT(")"),origin->x+margin,origin->y+rowTopMargin);\r
+    else\r
+        bdc.DrawText(queryTable->getName(),origin->x+margin,origin->y+rowTopMargin);\r
+    bdc.SetFont(normalFont);\r
+\r
+    // GQB-TODO: in a future reuse a little more the iterator creating it inside the Query or Table Object\r
+    // and only delete it when delete the query object.\r
+\r
+    // Draw Columns\r
+    height=rowHeight+rowTopMargin;\r
+    iterator->ResetIterator();\r
+    while(iterator->HasNext())\r
+    {\r
+        gqbColumn *tmp= (gqbColumn *)iterator->Next();\r
+        if(queryTable->existsColumn(tmp))\r
+        {\r
+            bdc.SetTextForeground(* wxRED);\r
+            bdc.SetFont(normalFont);\r
+            bdc.DrawBitmap(imgSelBoxSelected,origin->x+3,origin->y+height,true);\r
+        }\r
+        else\r
+        {\r
+            bdc.SetFont(normalFont);\r
+            bdc.DrawBitmap(imgSelBoxEmpty,origin->x+3,origin->y+height,true);\r
+        }\r
+        bdc.DrawText(tmp->getName(),origin->x+rowLeftMargin,origin->y+height);\r
+        bdc.SetTextForeground( *wxBLACK);\r
+        height+=rowHeight+rowTopMargin;\r
+    }\r
+    delete iterator;                              //now if delete because it's not needed anymore\r
+\r
+}\r
+\r
+\r
+// return a column when a user click on a checkbox [0->16] x point\r
+gqbColumn* gqbGraphSimple::getColumnAtPosition(wxPoint *clickPoint, gqbQueryObject *queryTable, int sensibility)\r
+{\r
+    int countCols=queryTable->parent->countCols(),colPos=-1;\r
+    if(countCols>0)                               //exists any column\r
+    {\r
+        colPos= (clickPoint->y-queryTable->position.y) /(rowHeight+rowTopMargin);\r
+    }\r
+\r
+    int x=clickPoint->x-queryTable->position.x;\r
+    if( (x>0 && x < sensibility) && colPos > 0)\r
+\r
+    // Because 0 is title\r
+        return queryTable->parent->getColumnAtIndex(colPos-1);\r
+    else\r
+        return NULL;\r
+}\r
+\r
+\r
+void gqbGraphSimple::drawTempJoinLine(wxBufferedDC& bdc, wxPoint &origin, wxPoint &end)\r
+{\r
+    wxPoint anchorsUsed = wxPoint(0,0);\r
+\r
+    if(origin.x<end.x)\r
+    {\r
+        anchorsUsed.x=1;\r
+        anchorsUsed.y=-1;\r
+    }\r
+    else\r
+    {\r
+        anchorsUsed.x=-1;\r
+        anchorsUsed.y=1;\r
+    }\r
+\r
+    drawJoin(bdc,origin,end,anchorsUsed,true,_equally);\r
+}\r
+\r
+\r
+void gqbGraphSimple::drawJoin(wxBufferedDC& bdc, wxPoint& origin, wxPoint& dest, wxPoint& anchorUsed, bool selected=false, type_Join joinKind=_equally)\r
+{\r
+    wxPoint origin2=origin;\r
+    wxPoint dest2=dest;\r
+\r
+    if(selected)\r
+    {\r
+        bdc.SetPen(selectedPen);\r
+        bdc.SetBrush(selectedBrush);\r
+    }\r
+    else\r
+    {\r
+        bdc.SetPen(*wxBLACK_PEN);\r
+        bdc.SetBrush(*wxBLACK_BRUSH);\r
+    }\r
+\r
+    // GQB-TODO: optimize this if possible, I know one other can be the same?\r
+\r
+    // getAnchorsUsed() [-1==left]   [1==right] x->origin y->destination\r
+    if(anchorUsed.x==1)\r
+    {\r
+        bdc.DrawRectangle(origin.x,origin.y-4,8,8);\r
+        origin2.x+=20;\r
+    }\r
+    else\r
+    {\r
+        bdc.DrawRectangle(origin.x-8,origin.y-4,8,8);\r
+        origin2.x-=20;\r
+    }\r
+\r
+    if(anchorUsed.y==1)\r
+    {\r
+        bdc.DrawRectangle(dest.x,dest.y-4,8,8);\r
+        dest2.x+=20;\r
+    }\r
+    else\r
+    {\r
+        bdc.DrawRectangle(dest.x-8,dest.y-4,8,8);\r
+        dest2.x-=20;\r
+    }\r
+\r
+    bdc.DrawLine(origin,origin2);\r
+    bdc.DrawLine(dest,dest2);\r
+    bdc.DrawLine(origin2,dest2);\r
+\r
+    // Draw type of join\r
+    switch(joinKind)\r
+    {\r
+        case _equally:\r
+            bdc.DrawText(wxT("="),findLineMiddle(origin2, dest2));\r
+            break;\r
+        case _lesser:\r
+            bdc.DrawText(wxT("<"),findLineMiddle(origin2, dest2));\r
+            break;\r
+        case _greater:\r
+            bdc.DrawText(wxT(">"),findLineMiddle(origin2, dest2));\r
+            break;\r
+        case _equlesser:\r
+            bdc.DrawText(wxT("<="),findLineMiddle(origin2, dest2));\r
+            break;\r
+        case _equgreater:\r
+            bdc.DrawText(wxT(">="),findLineMiddle(origin2, dest2));\r
+            break;\r
+    };\r
+}\r
+\r
+\r
+// Return true if pt click over a threshold of the join, false if not\r
+bool gqbGraphSimple::clickOnJoin(gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest)\r
+{\r
+\r
+    wxPoint origin2=origin;\r
+    wxPoint dest2=dest;\r
+\r
+    if(join->getAnchorsUsed().x==1)\r
+    {\r
+        origin2.x+=20;\r
+    }\r
+    else\r
+    {\r
+        origin2.x-=20;\r
+    }\r
+\r
+    if(join->getAnchorsUsed().y==1)\r
+    {\r
+        dest2.x+=20;\r
+    }\r
+    else\r
+    {\r
+        dest2.x-=20;\r
+    }\r
+\r
+    // Check origin anchor\r
+    bool value1=insideLine(pt,origin,origin2,lineClickThreshold);\r
+\r
+    // Check dest anchor\r
+    bool value2=insideLine(pt,dest,dest2,lineClickThreshold);\r
+\r
+    // Check line between both tables\r
+    bool value3=insideLine(pt,origin2,dest2,lineClickThreshold);\r
+\r
+    if(value1 || value2 || value3)\r
+        return true;\r
+    else\r
+        return false;\r
+}\r
+\r
+\r
+bool gqbGraphSimple::insideLine(wxPoint &pt, wxPoint &p1, wxPoint &p2, int threshold=7)\r
+{\r
+    bool value=false;\r
+    if(distanceToLine(pt,p1,p2)<threshold)\r
+    {\r
+        value=true;\r
+    }\r
+    return value;\r
+}\r
+\r
+\r
+wxPoint gqbGraphSimple::findLineMiddle(wxPoint p1, wxPoint p2)\r
+{\r
+    int middleX=-1, middleY=-1;\r
+\r
+    int dx =  p2.x - p1.x;\r
+    if(dx>0)                                      // p1 at left\r
+    {\r
+        middleX = dx/2 + p1.x;\r
+    }                                             // p1 at right\r
+    else\r
+    {\r
+        middleX = p1.x + dx/2;\r
+    }\r
+\r
+    int dy =  p2.y - p1.y;\r
+    if(dy>0)                                      // p1 is above\r
+    {\r
+        middleY = dy/2 + p1.y;\r
+    }                                             // p1 is below\r
+    else\r
+    {\r
+        middleY = p1.y + dy/2;\r
+    }\r
+\r
+    if(dy==0)\r
+        middleY=p1.y;\r
+    if(dx==0)\r
+        middleX=p1.x;\r
+\r
+    return wxPoint(middleX,middleY);\r
+}\r
+\r
+\r
+double gqbGraphSimple::distanceToLine(wxPoint pt, wxPoint p1, wxPoint p2)\r
+{\r
+    p2.x -= p1.x;\r
+    p2.y -= p1.y;\r
+\r
+    pt.x -= p1.x;\r
+    pt.y -= p1.y;\r
+\r
+    double dprod = pt.x * p2.x + pt.y * p2.y;\r
+    double pLenSq;\r
+\r
+    if(dprod <= 0.0)\r
+    {\r
+        pLenSq = 0.0;\r
+    }\r
+    else\r
+    {\r
+        pt.x = p2.x - pt.x;\r
+        pt.y = p2.y - pt.y;\r
+        dprod = pt.x * p2.x + pt.y * p2.y;\r
+        if(dprod <= 0.0)\r
+        {\r
+            pLenSq=0.0;\r
+        }\r
+        else\r
+        {\r
+            pLenSq= dprod*dprod / (p2.x*p2.x + p2.y*p2.y);\r
+        }\r
+    }\r
+\r
+    double lengthSq = pt.x * pt.x + pt.y * pt.y - pLenSq;\r
+\r
+    if(lengthSq<0)\r
+    {\r
+        lengthSq=0;\r
+    }\r
+\r
+    double length = sqrt(lengthSq);\r
+\r
+    return length;\r
+}\r
+\r
+\r
+// Set the anchors points [source, destination] for a join\r
+void gqbGraphSimple::calcAnchorPoint(gqbQueryJoin *join)\r
+{\r
+    int index,x,y;\r
+    wxPoint use;                                  // [-1==left]   [1==right] x->origin y->destination\r
+    int sx=join->getSourceQTable()->position.x;\r
+    int sy=join->getSourceQTable()->position.y;\r
+    int dx=join->getDestQTable()->position.x;\r
+    int dy=join->getDestQTable()->position.y;\r
+\r
+    // Source\r
+    index=join->getSourceQTable()->getColumnIndex(join->getSCol())+1;\r
+    if(sx<dx)\r
+    {\r
+        x=sx+join->getSourceQTable()->getWidth();\r
+        use.x=1;\r
+    }\r
+    else\r
+    {\r
+        x=sx;\r
+        use.x=-1;\r
+    }\r
+    y=sy+index*(rowHeight+rowTopMargin)+((rowHeight+rowTopMargin)/2);\r
+    join->setSourceAnchor(wxPoint(x,y));\r
+\r
+    // Destination\r
+    index=join->getDestQTable()->getColumnIndex(join->getDCol())+1;\r
+    if(dx<sx)\r
+    {\r
+        x=dx+join->getDestQTable()->getWidth();\r
+        use.y=1;\r
+    }\r
+    else\r
+    {\r
+        x=dx;\r
+        use.y=-1;\r
+    }\r
+    y=dy+index*(rowHeight+rowTopMargin)+((rowHeight+rowTopMargin)/2);\r
+    join->setDestAnchor(wxPoint(x,y));\r
+\r
+    join->setAnchorsUsed(use);\r
+}\r
+\r
+\r
+// Update position of Object in the query if move table & adjust all other items like joins (own & registered)\r
+void  gqbGraphSimple::UpdatePosObject(gqbQueryObject *queryTable, int x, int y, int cursorAdjustment)\r
+{\r
+    x-=cursorAdjustment;                          // Move Pointer to a better Position;\r
+    y-=rowHeight/2;\r
+    queryTable->position.x=x;                     // Update position of table\r
+    queryTable->position.y=y;\r
+\r
+    // Update position of anchor points of Joins that origin from this table\r
+    if(queryTable->getHaveJoins())\r
+    {\r
+        gqbIteratorBase *j=queryTable->createJoinsIterator();\r
+        while(j->HasNext())\r
+        {\r
+            gqbQueryJoin *tmp= (gqbQueryJoin *)j->Next();\r
+            calcAnchorPoint(tmp);\r
+        }\r
+        delete j;\r
+    }\r
+\r
+    // Update position of anchor points of Joins that come from others tables\r
+    if(queryTable->getHaveRegJoins())\r
+    {\r
+        gqbIteratorBase *r=queryTable->createRegJoinsIterator();\r
+        while(r->HasNext())\r
+        {\r
+            gqbQueryJoin *tmp= (gqbQueryJoin *)r->Next();\r
+            calcAnchorPoint(tmp);\r
+        }\r
+        delete r;\r
+    }\r
+}\r
+\r
+\r
+int gqbGraphSimple::getTitleRowHeight()\r
+{\r
+    return rowHeight;\r
+}\r
diff --git a/pgadmin/gqb/gqbGridOrderTable.cpp b/pgadmin/gqb/gqbGridOrderTable.cpp
new file mode 100644 (file)
index 0000000..cb93416
--- /dev/null
@@ -0,0 +1,293 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbGridOrderTable.cpp - Table implementation for Order By Panel Grid\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+// App headers\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+\r
+// App headers\r
+#include "gqb/gqbGridOrderTable.h"\r
+#include "gqb/gqbColumn.h"\r
+#include "gqb/gqbArrayCollection.h"\r
+#include "gqb/gqbModel.h"\r
+\r
+gqbGridOrderTable::gqbGridOrderTable(int numColumns, gqbObjsArray* cols, gqbObjsArray* parent, charArray* orderBy)\r
+{\r
+    numberColumns=numColumns;\r
+    columns=cols;\r
+    colsParents=parent;\r
+    kindOfOrder=orderBy;\r
+}\r
+\r
+\r
+gqbGridOrderTable::~gqbGridOrderTable()\r
+{\r
+}\r
+\r
+\r
+int gqbGridOrderTable::GetNumberRows()\r
+{\r
+    return (columns->GetCount());\r
+}\r
+\r
+\r
+int gqbGridOrderTable::GetNumberCols()\r
+{\r
+    return numberColumns;\r
+}\r
+\r
+\r
+bool gqbGridOrderTable::IsEmptyCell( int row, int col )\r
+{\r
+    int count=columns->GetCount();\r
+    if(row+1 <= count)\r
+        return false;\r
+    else\r
+        return true;\r
+}\r
+\r
+\r
+wxString gqbGridOrderTable::GetValue( int row, int col )\r
+{\r
+    if(col==0)\r
+    {\r
+        wxString col = wxT("");\r
+        if(((gqbQueryObject *)colsParents->Item(row))->getAlias().length()>0)\r
+        {\r
+            col+=((gqbQueryObject *)colsParents->Item(row))->getAlias()+wxT(".");\r
+        }\r
+        else\r
+        {\r
+            col+=((gqbQueryObject *)colsParents->Item(row))->getName()+wxT(".");\r
+        }\r
+        col+=((gqbColumn *)columns->Item(row))->getName();\r
+        return col;\r
+    }\r
+\r
+    if(numberColumns==2)\r
+    {\r
+        if(col==1)\r
+        {\r
+            wxString ord = wxT("");\r
+            if(kindOfOrder->Item(row)=='A')\r
+                ord+=wxT("ASC");\r
+            else\r
+                ord+=wxT("DESC");\r
+\r
+            return ord;\r
+        }\r
+    }\r
+    return wxT("");\r
+}\r
+\r
+\r
+wxString gqbGridOrderTable::GetColLabelValue(int col)\r
+{\r
+    switch(col)\r
+    {\r
+        case 0:\r
+            if(numberColumns==2)\r
+            {\r
+                return wxT("Column");\r
+            }\r
+            else\r
+            {\r
+                return wxT("Available Columns");\r
+            }\r
+            break;\r
+        case 1:\r
+            return wxT("Order");\r
+            break;\r
+    };\r
+    return wxT("");\r
+}\r
+\r
+\r
+void gqbGridOrderTable::SetValue( int row, int col, const wxString& value )\r
+{\r
+    if(col==1 && numberColumns==2)\r
+    {\r
+        if(value.Contains(wxT("ASC")))\r
+        {\r
+            kindOfOrder->Item(row)='A';\r
+        }\r
+        else\r
+        {\r
+            kindOfOrder->Item(row)='D';\r
+        }\r
+    }\r
+}\r
+\r
+\r
+void gqbGridOrderTable::AppendItem(gqbColumn *column, gqbQueryObject *parent, char kindOrder)\r
+{\r
+    columns->Add(column);\r
+    colsParents->Add(parent);\r
+    if(numberColumns==2)\r
+    {\r
+        kindOfOrder->Add(kindOrder);\r
+    }\r
+\r
+    if (GetView() )\r
+    {\r
+        wxGridTableMessage msg( this,\r
+            wxGRIDTABLE_NOTIFY_ROWS_INSERTED,\r
+            (columns->GetCount()-1),\r
+            1 );\r
+        GetView()->ProcessTableMessage( msg );\r
+    }\r
+}\r
+\r
+\r
+bool gqbGridOrderTable::removeFirstRow(gqbObject *itemTable)\r
+{\r
+    bool found=false;\r
+    int i,size=colsParents->GetCount();\r
+\r
+    for(i=0;i<size;i++)\r
+    {\r
+        if (colsParents->Item(i)==itemTable)\r
+        {\r
+            found=true;\r
+            break;\r
+        }\r
+    }\r
+\r
+    if(found)\r
+    {\r
+        columns->RemoveAt(i);\r
+        colsParents->RemoveAt(i);\r
+        if(numberColumns==2)\r
+        {\r
+            kindOfOrder->RemoveAt(i);\r
+        }\r
+        if ( GetView() )                          // Notify Grid about the change\r
+        {\r
+            wxGridTableMessage msg( this,\r
+                wxGRIDTABLE_NOTIFY_ROWS_DELETED,\r
+                i+1,\r
+                1 );\r
+            GetView()->ProcessTableMessage( msg );\r
+        }\r
+    }\r
+\r
+    return found;\r
+}\r
+\r
+\r
+void gqbGridOrderTable::emptyTableData(gqbQueryObject *object)\r
+{\r
+    // Because items positions on array changes when I delete one, I have to do the remove in this way\r
+    while(removeFirstRow(object));\r
+}\r
+\r
+\r
+void gqbGridOrderTable::removeRowAt(int i)\r
+{\r
+    columns->RemoveAt(i);\r
+    colsParents->RemoveAt(i);\r
+    if(numberColumns==2)\r
+    {\r
+        kindOfOrder->RemoveAt(i);\r
+    }\r
+    // Notify Grid about the change\r
+       if ( GetView() )                              \r
+    {\r
+        wxGridTableMessage msg( this,\r
+            wxGRIDTABLE_NOTIFY_ROWS_DELETED,\r
+            i+1,\r
+            1 );\r
+        GetView()->ProcessTableMessage( msg );\r
+    }\r
+}\r
+\r
+\r
+gqbObject* gqbGridOrderTable::getObjectAt(int pos, int col)\r
+{\r
+    gqbObject *value = NULL;\r
+    switch(col)\r
+    {\r
+        case 0:\r
+            value=columns->Item(pos);\r
+            break;\r
+        case 1:\r
+            value=colsParents->Item(pos);\r
+            break;\r
+    };\r
+    return value;\r
+}\r
+\r
+\r
+void gqbGridOrderTable::changesPositions(int sPos, int dPos)\r
+{\r
+\r
+    int size=columns->GetCount();\r
+    gqbObject *tmpTable=NULL, *tmpColumn=NULL;\r
+    char tmpKind = 'N';\r
+\r
+    if( (sPos>=0 && sPos < size) && (dPos>=0 && dPos < size) )\r
+    {\r
+        tmpTable=colsParents->Item(sPos);\r
+        tmpColumn=columns->Item(sPos);\r
+        tmpKind=kindOfOrder->Item(sPos);\r
+\r
+        colsParents->Item(sPos)=colsParents->Item(dPos);\r
+        columns->Item(sPos)=columns->Item(dPos);\r
+        kindOfOrder->Item(sPos)=kindOfOrder->Item(dPos);\r
+        colsParents->Item(dPos)=tmpTable;\r
+        columns->Item(dPos)=tmpColumn;\r
+        kindOfOrder->Item(dPos)=tmpKind;\r
+    }\r
+\r
+    wxGridTableMessage msg( this,\r
+        wxGRIDTABLE_REQUEST_VIEW_GET_VALUES,\r
+        sPos,\r
+        1 );\r
+    GetView()->ProcessTableMessage( msg );\r
+\r
+}\r
+\r
+\r
+// GQB-TODO: optimize this functions & related buttons events at gqbView because works but are a mess.\r
+// Change a single row or a range to one pos up or down (but no more than one position)\r
+void gqbGridOrderTable::changesRangeOnePos(int topPos, int bottomPos, int newTop)\r
+{\r
+    // Eliminate side effect of zero base array on calculations, but carefull newTop still it's zero based\r
+    topPos++;\r
+    bottomPos++;\r
+    int sizeRange=bottomPos-(topPos-1), size=GetNumberRows();\r
+    if(topPos>newTop)                             // Go Down\r
+    {\r
+        // Only if the movement don't create an overflow\r
+        if( (topPos > 1) && ((newTop+sizeRange) <  size)  )\r
+        {\r
+            for(int i=newTop ; i < (newTop+sizeRange) ; i++)\r
+            {\r
+                changesPositions(i,i+1);\r
+            }\r
+        }\r
+\r
+    }                                             // Go Up\r
+    else\r
+    {\r
+        // Only if the movement don't create an overflow\r
+        if( (bottomPos < size) && ((newTop+sizeRange) <=  size)  )\r
+        {\r
+                                                  // Go Up Down\r
+            for(int i=(newTop+sizeRange-1) ; i >= newTop  ; i--)\r
+            {\r
+                changesPositions(i-1,i);\r
+            }\r
+        }\r
+    }\r
+}\r
diff --git a/pgadmin/gqb/gqbGridProjTable.cpp b/pgadmin/gqb/gqbGridProjTable.cpp
new file mode 100644 (file)
index 0000000..72c6f93
--- /dev/null
@@ -0,0 +1,341 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbGridProjTable.cpp - Table implementation for Projection Panel Grid\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+// App headers\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+#include <wx/settings.h>\r
+#include <wx/utils.h>\r
+#include <wx/notebook.h>\r
+#include <wx/regex.h>\r
+\r
+// App headers\r
+#include "gqb/gqbGridProjTable.h"\r
+#include "gqb/gqbColumn.h"\r
+#include "gqb/gqbQueryObjs.h"\r
+\r
+gqbGridProjTable::gqbGridProjTable(gqbObjsArray *position, gqbObjsArray *parent, wxArrayString *alias):\r
+wxGridTableBase()\r
+{\r
+    colsPosition=position;\r
+    colsParents=parent;\r
+    columnsAlias=alias;\r
+    // GQB-TODO: replace above pointers array with local variable if possible or research what it's causing bug in destructor???\r
+}\r
+\r
+\r
+gqbGridProjTable::~gqbGridProjTable()\r
+{\r
+}\r
+\r
+\r
+int gqbGridProjTable::GetNumberRows()\r
+{\r
+    return (colsPosition->GetCount());\r
+}\r
+\r
+\r
+int gqbGridProjTable::GetNumberCols()\r
+{\r
+\r
+    return 3;\r
+}\r
+\r
+\r
+bool gqbGridProjTable::IsEmptyCell( int row, int col )\r
+{\r
+\r
+    int count=colsParents->GetCount();\r
+    if(row+1 <= count)\r
+        return false;\r
+    else\r
+        return true;\r
+}\r
+\r
+\r
+wxString gqbGridProjTable::GetValue( int row, int col )\r
+{\r
+    switch(col)\r
+    {\r
+        case 0:\r
+            if(((gqbQueryObject *)colsParents->Item(row))->getAlias().length()>0)\r
+            {\r
+                               return ((gqbQueryObject*)colsParents->Item(row))->getAlias();\r
+            }\r
+            else\r
+            {\r
+                return ((gqbQueryObject*)colsParents->Item(row))->getName();\r
+            }\r
+            break;\r
+        case 1:\r
+            return ((gqbColumn*)colsPosition->Item(row))->getName();\r
+            break;\r
+        case 2:\r
+            return columnsAlias->Item(row);\r
+            break;\r
+    };\r
+    return wxT("");\r
+}\r
+\r
+\r
+wxString gqbGridProjTable::GetColLabelValue( int col)\r
+{\r
+    switch(col)\r
+    {\r
+        case 0:\r
+            return wxT("Relation");\r
+            break;\r
+        case 1:\r
+            return wxT("Column");\r
+            break;\r
+        case 2:\r
+            return wxT("Alias");\r
+            break;\r
+    };\r
+    return wxT("");\r
+}\r
+\r
+\r
+void gqbGridProjTable::SetValue( int row, int col, const wxString& value )\r
+{\r
+    // Do nothing on values that cannot be edited on this model [Column & Relation Name]\r
+    switch(col)\r
+    {\r
+        case 2:\r
+            wxString tmp = value;\r
+            if (haveUpperCase(tmp))\r
+                columnsAlias->Item(row)=wxT("\"")+value+wxT("\"");\r
+            else\r
+                columnsAlias->Item(row)=value;\r
+            break;\r
+    };\r
+}\r
+\r
+\r
+bool gqbGridProjTable::haveUpperCase(wxString &str)\r
+{\r
+    bool result=false;\r
+    // if any uppercase character at string, then quoted.\r
+    wxRegEx *reUpper =  new wxRegEx(wxT("[a-z0-9]*[A-Z]"));\r
+    if(reUpper->Matches(str))\r
+    {\r
+        result=true;\r
+    }\r
+    delete reUpper;\r
+    return result;\r
+}\r
+\r
+\r
+void* gqbGridProjTable::GetValueAsCustom( int row, int col, const wxString& typeName )\r
+{\r
+    switch(col)\r
+    {\r
+        case 0:\r
+            return (void *)&colsParents->Item(row);\r
+            break;\r
+        case 1:\r
+            return (void *)&colsPosition->Item(row);\r
+            break;\r
+        case 2:\r
+            break;\r
+    };\r
+    return NULL;\r
+}\r
+\r
+\r
+void  gqbGridProjTable::SetValueAsCustom( int row, int col, const wxString& typeName, void* value )\r
+{\r
+    switch(col)\r
+    {\r
+        case 0:\r
+            colsParents->Add(((gqbQueryObject*)value));\r
+            break;\r
+        case 1:\r
+            colsPosition->Add(((gqbColumn*)value));\r
+    };\r
+}\r
+\r
+\r
+void gqbGridProjTable::AppendItem(int col, gqbObject *item)\r
+{\r
+    bool notify=false;\r
+    switch(col)\r
+    {\r
+        case 0:\r
+            colsParents->Add(item);\r
+            break;\r
+        case 1:\r
+            colsPosition->Add(item);\r
+            notify=true;\r
+            break;\r
+        case 2:\r
+            columnsAlias->Add(wxT(""));\r
+            break;\r
+    };\r
+\r
+    if (notify && GetView() )\r
+    {\r
+        wxGridTableMessage msg( this,\r
+            wxGRIDTABLE_NOTIFY_ROWS_INSERTED,\r
+            (colsParents->GetCount()-1),\r
+            1 );\r
+        GetView()->ProcessTableMessage( msg );\r
+    }\r
+\r
+}\r
+\r
+// Remove a column at the grid\r
+bool gqbGridProjTable::removeRow(gqbObject *itemTable, gqbObject *itemColumn)\r
+{\r
+    bool found=false;\r
+    int i,size=colsPosition->GetCount();\r
+\r
+    for(i=0;i<size;i++)\r
+    {\r
+        if (colsParents->Item(i)==itemTable && colsPosition->Item(i)==itemColumn)\r
+        {\r
+            found=true;\r
+            break;\r
+        }\r
+    }\r
+\r
+    if(found)\r
+    {\r
+        colsParents->RemoveAt(i);\r
+        colsPosition->RemoveAt(i);\r
+        columnsAlias->RemoveAt(i);\r
+\r
+        if ( GetView() )                          // Notify Grid about the change\r
+        {\r
+            wxGridTableMessage msg( this,\r
+                wxGRIDTABLE_NOTIFY_ROWS_DELETED,\r
+                i+1,\r
+                1 );\r
+            GetView()->ProcessTableMessage( msg );\r
+        }\r
+    }\r
+\r
+    return found;\r
+}\r
+\r
+\r
+void gqbGridProjTable::removeAllRows(gqbObject *itemTable)\r
+{\r
+\r
+    int size=colsParents->GetCount();\r
+    for(int i=(size-1);i>=0;i--)\r
+    {\r
+        if (colsParents->Item(i)==itemTable)\r
+        {\r
+            colsParents->RemoveAt(i);\r
+            colsPosition->RemoveAt(i);\r
+            columnsAlias->RemoveAt(i);\r
+\r
+            // Notify Grid about the change\r
+            if ( GetView() )\r
+            {\r
+                wxGridTableMessage msg( this,\r
+                    wxGRIDTABLE_NOTIFY_ROWS_DELETED,\r
+                    i+1,\r
+                    1 );\r
+                GetView()->ProcessTableMessage( msg );\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+\r
+void gqbGridProjTable::changesPositions(int sPos, int dPos)\r
+{\r
+\r
+    int size=colsPosition->GetCount();\r
+    gqbObject *tmpTable=NULL, *tmpColumn=NULL;\r
+    wxString tmpAlias = wxT("");\r
+\r
+    if( (sPos>=0 && sPos < size) && (dPos>=0 && dPos < size) )\r
+    {\r
+        tmpTable=colsParents->Item(sPos);\r
+        tmpColumn=colsPosition->Item(sPos);\r
+        tmpAlias=columnsAlias->Item(sPos);\r
+\r
+        colsParents->Item(sPos)=colsParents->Item(dPos);\r
+        colsPosition->Item(sPos)=colsPosition->Item(dPos);\r
+        columnsAlias->Item(sPos)=columnsAlias->Item(dPos);\r
+        colsParents->Item(dPos)=tmpTable;\r
+        colsPosition->Item(dPos)=tmpColumn;\r
+        columnsAlias->Item(dPos)=tmpAlias;\r
+    }\r
+\r
+    wxGridTableMessage msg( this,\r
+        wxGRIDTABLE_REQUEST_VIEW_GET_VALUES,\r
+        sPos,\r
+        1 );\r
+    GetView()->ProcessTableMessage( msg );\r
+\r
+}\r
+\r
+\r
+// GQB-TODO: optimize this functions & related buttons events at gqbView because works but are a mess.\r
+// Change a single row or a range to one pos up or down (but no more than one position)\r
+void gqbGridProjTable::changesRangeOnePos(int topPos, int bottomPos, int newTop)\r
+{\r
+    // Eliminate side effect of zero base array on calculations, but carefull newTop still it's zero based\r
+    topPos++;\r
+    bottomPos++;\r
+    int sizeRange=bottomPos-(topPos-1), size=GetNumberRows();\r
+    if(topPos>newTop)                             // Go Down\r
+    {\r
+    // Only if the movement don't create an overflow\r
+        if( (topPos > 1) && ((newTop+sizeRange) <  size)  )\r
+        {\r
+            for(int i=newTop ; i < (newTop+sizeRange) ; i++)\r
+            {\r
+                changesPositions(i,i+1);\r
+            }\r
+        }\r
+\r
+    }                                             // Go Up\r
+    else\r
+    {\r
+               // Only if the movement don't create an overflow\r
+        if( (bottomPos < size) && ((newTop+sizeRange) <=  size)  )\r
+        {\r
+            // Go Up Down\r
+            for(int i=(newTop+sizeRange-1) ; i >= newTop  ; i--)\r
+            {\r
+                changesPositions(i-1,i);\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+\r
+// Removes all items from gqbGridProjTable\r
+void gqbGridProjTable::emptyTableData()\r
+{\r
+\r
+    int count=colsPosition->GetCount();\r
+    colsPosition->Empty();\r
+    colsParents->Empty();\r
+    columnsAlias->Empty();\r
+\r
+       // Notify Grid about the change\r
+    if ( GetView() )\r
+    {\r
+        wxGridTableMessage msg( this,\r
+            wxGRIDTABLE_NOTIFY_ROWS_DELETED,\r
+            1,                                    \r
+            count);\r
+        GetView()->ProcessTableMessage( msg );\r
+    }\r
+}\r
diff --git a/pgadmin/gqb/gqbGridRestTable.cpp b/pgadmin/gqb/gqbGridRestTable.cpp
new file mode 100644 (file)
index 0000000..07ef579
--- /dev/null
@@ -0,0 +1,372 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbGridRestTable.cpp - Table implementation for Restrictions Panel Grid\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+// App headers\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+#include <wx/settings.h>\r
+#include <wx/utils.h>\r
+#include <wx/notebook.h>\r
+\r
+// App headers\r
+#include "gqb/gqbGridRestTable.h"\r
+#include "gqb/gqbColumn.h"\r
+#include "gqb/gqbQueryObjs.h"\r
+#include "gqb/gqbViewPanels.h"\r
+\r
+gqbGridRestTable::gqbGridRestTable(gqbRestrictions *_restrictions):\r
+wxGridTableBase()\r
+{\r
+    restrictions=_restrictions;\r
+}\r
+\r
+\r
+gqbGridRestTable::~gqbGridRestTable()\r
+{\r
+}\r
+\r
+\r
+int gqbGridRestTable::GetNumberRows()\r
+{\r
+    return (restrictions->restrictionsCount());\r
+}\r
+\r
+\r
+int gqbGridRestTable::GetNumberCols()\r
+{\r
+    return 4;\r
+}\r
+\r
+\r
+bool gqbGridRestTable::IsEmptyCell( int row, int col )\r
+{\r
+\r
+    int count=restrictions->restrictionsCount();\r
+    if(row+1 <= count)\r
+        return false;\r
+    else\r
+        return true;\r
+}\r
+\r
+\r
+wxString gqbGridRestTable::GetValue( int row, int col )\r
+{\r
+    switch(col)\r
+    {\r
+        case 0:\r
+            return ((gqbQueryRestriction*)restrictions->getRestrictionAt(row))->getLeft();\r
+            break;\r
+        case 1:\r
+            return ((gqbQueryRestriction*)restrictions->getRestrictionAt(row))->getRestriction();\r
+            break;\r
+        case 2:\r
+            return ((gqbQueryRestriction*)restrictions->getRestrictionAt(row))->getValue_s();\r
+            break;\r
+        case 3:\r
+            return ((gqbQueryRestriction*)restrictions->getRestrictionAt(row))->getConnector();\r
+            break;\r
+    };\r
+\r
+    return wxT("");\r
+}\r
+\r
+\r
+wxString gqbGridRestTable::GetColLabelValue( int col)\r
+{\r
+    switch(col)\r
+    {\r
+        case 0:\r
+            return wxT("Restricted Value");\r
+            break;\r
+        case 1:\r
+            return wxT("Restriction");\r
+            break;\r
+        case 2:\r
+            return wxT("Value");\r
+            break;\r
+        case 3:\r
+            return wxT("Connector");\r
+            break;\r
+    };\r
+    return wxT("");\r
+}\r
+\r
+\r
+void gqbGridRestTable::SetValue( int row, int col, const wxString& value )\r
+{\r
+    switch(col)\r
+    {\r
+        case 0:\r
+            ((gqbQueryRestriction*)restrictions->getRestrictionAt(row))->setLeft(value);\r
+            break;\r
+        case 1:\r
+            ((gqbQueryRestriction*)restrictions->getRestrictionAt(row))->setRestriction(value);\r
+            break;\r
+        case 2:\r
+            ((gqbQueryRestriction*)restrictions->getRestrictionAt(row))->setValue_s(value);\r
+            break;\r
+        case 3:\r
+            ((gqbQueryRestriction*)restrictions->getRestrictionAt(row))->setConnector(value);\r
+            break;\r
+    }\r
+}\r
+\r
+\r
+void gqbGridRestTable::AppendItem(gqbQueryRestriction *item)\r
+{\r
+    bool notify=true;\r
+\r
+    restrictions->addRestriction(item);\r
+\r
+    if (notify && GetView() )\r
+    {\r
+        wxGridTableMessage msg( this,\r
+            wxGRIDTABLE_NOTIFY_ROWS_INSERTED,\r
+            (restrictions->restrictionsCount()-1),\r
+            1 );\r
+        GetView()->ProcessTableMessage( msg );\r
+    }\r
+\r
+}\r
+\r
+\r
+bool gqbGridRestTable::DeleteRows(size_t pos = 0, size_t numRows = 1)\r
+{\r
+    if(pos>=0 && numRows==1)\r
+    {\r
+        gqbQueryRestriction *r=restrictions->getRestrictionAt(pos);\r
+        restrictions->removeRestriction(r);\r
+        \r
+               // Notify Grid about the change\r
+               if ( GetView() )\r
+        {\r
+            wxGridTableMessage msg( this,\r
+                wxGRIDTABLE_NOTIFY_ROWS_DELETED,\r
+                pos,\r
+                1 );\r
+            GetView()->ProcessTableMessage( msg );\r
+        }\r
+\r
+        delete r;\r
+        return true;\r
+    }\r
+    else\r
+        return false;\r
+}\r
+\r
+\r
+// Removes all items from gqbGridTable\r
+void gqbGridRestTable::emptyTableData()\r
+{\r
+\r
+    int count=restrictions->restrictionsCount();\r
+    restrictions->deleteAllRestrictions();\r
+\r
+    if ( GetView() )                              //Notify Grid about the change\r
+    {\r
+        wxGridTableMessage msg( this,\r
+            wxGRIDTABLE_NOTIFY_ROWS_DELETED,\r
+            1,\r
+            count);\r
+        GetView()->ProcessTableMessage( msg );\r
+    }\r
+}\r
+\r
+\r
+//\r
+// Cell rendering utilities classes\r
+//\r
+\r
+void wxGridCellComboBoxRenderer::Draw(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc,\r
+const wxRect& rectCell, int row, int col, bool isSelected)\r
+{\r
+    wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);\r
+\r
+    // first calculate button size\r
+    // don't draw outside the cell\r
+    int nButtonWidth = 17;\r
+    if (rectCell.height < 2) return;\r
+    wxRect rectButton;\r
+    rectButton.x = rectCell.x + rectCell.width - nButtonWidth;\r
+    rectButton.y = rectCell.y + 1;\r
+    int cell_rows, cell_cols;\r
+    attr.GetSize(&cell_rows, &cell_cols);\r
+    rectButton.width = nButtonWidth;\r
+    if (cell_rows == 1)\r
+        rectButton.height = rectCell.height-2;\r
+    else\r
+        rectButton.height = nButtonWidth;\r
+\r
+    SetTextColoursAndFont(grid, attr, dc, isSelected);\r
+    int hAlign, vAlign;\r
+    attr.GetAlignment(&hAlign, &vAlign);\r
+\r
+       // Leave room for button\r
+    wxRect rect = rectCell;\r
+    rect.SetWidth(rectCell.GetWidth() - rectButton.GetWidth()-2);\r
+    rect.Inflate(-1);\r
+    grid.DrawTextRectangle(dc, grid.GetCellValue(row, col), rect, hAlign, vAlign);\r
+\r
+       // Don't bother drawing if the cell is too small\r
+    if (rectButton.height < 4 || rectButton.width < 4) \r
+               return;\r
+\r
+       // Draw 3-d button\r
+    wxColour colourBackGround = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);\r
+    dc.SetBrush(wxBrush(colourBackGround, wxSOLID));\r
+    dc.SetPen(wxPen(colourBackGround, 1, wxSOLID));\r
+    dc.DrawRectangle(rectButton);\r
+    dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID));\r
+    dc.DrawLine(rectButton.GetLeft(), rectButton.GetBottom(),\r
+        rectButton.GetRight(), rectButton.GetBottom());\r
+    dc.DrawLine(rectButton.GetRight(), rectButton.GetBottom(),\r
+        rectButton.GetRight(), rectButton.GetTop()-1);\r
+    dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW),\r
+        1, wxSOLID));\r
+    dc.DrawLine(rectButton.GetLeft()+1, rectButton.GetBottom()-1,\r
+        rectButton.GetRight()-1, rectButton.GetBottom()-1);\r
+    dc.DrawLine(rectButton.GetRight()-1, rectButton.GetBottom()-1,\r
+        rectButton.GetRight()-1, rectButton.GetTop());\r
+    dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT),\r
+        1, wxSOLID));\r
+    dc.DrawLine(rectButton.GetRight()-2, rectButton.GetTop()+1,\r
+        rectButton.GetLeft()+1, rectButton.GetTop()+1);\r
+    dc.DrawLine(rectButton.GetLeft()+1, rectButton.GetTop()+1,\r
+        rectButton.GetLeft()+1, rectButton.GetBottom()-1);\r
+\r
+       // Draw little triangle\r
+    int nTriWidth = 7;\r
+    int nTriHeight = 4;\r
+    wxPoint point[3];\r
+    point[0] = wxPoint(rectButton.GetLeft() + (rectButton.GetWidth()-nTriWidth)/2,\r
+        rectButton.GetTop()+(rectButton.GetHeight()-nTriHeight)/2);\r
+    point[1] = wxPoint(point[0].x+nTriWidth-1, point[0].y);\r
+    point[2] = wxPoint(point[0].x+3, point[0].y+nTriHeight-1);\r
+    dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), wxSOLID));\r
+    dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID));\r
+    dc.DrawPolygon(3, point);\r
+    if (m_border == wxLAYOUT_TOP)\r
+    {\r
+        dc.SetPen(wxPen(*wxBLACK, 1, wxDOT));\r
+        dc.DrawLine(rectCell.GetRight(), rectCell.GetTop(),\r
+            rectCell.GetLeft(), rectCell.GetTop());\r
+    }\r
+}\r
+\r
+\r
+void wxGridCellButtonRenderer::Draw(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc,\r
+const wxRect& rectCell, int row, int col, bool isSelected)\r
+{\r
+    wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);\r
+\r
+       // First calculate button size\r
+       // don't draw outside the cell\r
+    int nButtonWidth = 17;\r
+    if (rectCell.height < 2) return;\r
+    wxRect rectButton;\r
+    rectButton.x = rectCell.x + rectCell.width - nButtonWidth;\r
+    rectButton.y = rectCell.y + 1;\r
+    int cell_rows, cell_cols;\r
+    attr.GetSize(&cell_rows, &cell_cols);\r
+    rectButton.width = nButtonWidth;\r
+    if (cell_rows == 1)\r
+        rectButton.height = rectCell.height-2;\r
+    else\r
+        rectButton.height = nButtonWidth;\r
+\r
+    SetTextColoursAndFont(grid, attr, dc, isSelected);\r
+    int hAlign, vAlign;\r
+    attr.GetAlignment(&hAlign, &vAlign);\r
+\r
+       // Leave room for button\r
+    wxRect rect = rectCell;\r
+    rect.SetWidth(rectCell.GetWidth() - rectButton.GetWidth()-2);\r
+    rect.Inflate(-1);\r
+    grid.DrawTextRectangle(dc, grid.GetCellValue(row, col), rect, hAlign, vAlign);\r
+\r
+\r
+       // Don't bother drawing if the cell is too small draw 3-d button\r
+    if (rectButton.height < 4 || rectButton.width < 4) \r
+               return;\r
+\r
+    wxColour colourBackGround = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);\r
+    dc.SetBrush(wxBrush(colourBackGround, wxSOLID));\r
+    dc.SetPen(wxPen(colourBackGround, 1, wxSOLID));\r
+    dc.DrawRectangle(rectButton);\r
+    dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID));\r
+    dc.DrawLine(rectButton.GetLeft(), rectButton.GetBottom(),\r
+        rectButton.GetRight(), rectButton.GetBottom());\r
+    dc.DrawLine(rectButton.GetRight(), rectButton.GetBottom(),\r
+        rectButton.GetRight(), rectButton.GetTop()-1);\r
+    dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW),\r
+        1, wxSOLID));\r
+    dc.DrawLine(rectButton.GetLeft()+1, rectButton.GetBottom()-1,\r
+        rectButton.GetRight()-1, rectButton.GetBottom()-1);\r
+    dc.DrawLine(rectButton.GetRight()-1, rectButton.GetBottom()-1,\r
+        rectButton.GetRight()-1, rectButton.GetTop());\r
+    dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT),\r
+        1, wxSOLID));\r
+    dc.DrawLine(rectButton.GetRight()-2, rectButton.GetTop()+1,\r
+        rectButton.GetLeft()+1, rectButton.GetTop()+1);\r
+    dc.DrawLine(rectButton.GetLeft()+1, rectButton.GetTop()+1,\r
+        rectButton.GetLeft()+1, rectButton.GetBottom()-1);\r
+\r
+       // Draw little plus symbol\r
+    dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), wxSOLID));\r
+    dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID));\r
+    int nPlusWidth = 7;\r
+    int nPlusHeight = 7;\r
+    wxPoint point[4];\r
+    point[0] = wxPoint(rectButton.GetLeft() + (rectButton.GetWidth()-nPlusWidth)/2, rectButton.GetTop()+(rectButton.GetHeight()/2)-1);\r
+    point[1] = wxPoint(point[0].x+nPlusWidth, point[0].y);\r
+    point[2] = wxPoint(rectButton.GetLeft() + (rectButton.GetWidth())/2, rectButton.GetTop()+(rectButton.GetHeight()-nPlusHeight)/2);\r
+    point[3] = wxPoint(point[2].x,point[2].y+nPlusHeight);\r
+    dc.DrawLine(point[0],point[1]);\r
+    dc.DrawLine(point[2],point[3]);\r
+\r
+    if (m_border == wxLAYOUT_TOP)\r
+    {\r
+        dc.SetPen(wxPen(*wxBLACK, 1, wxDOT));\r
+        dc.DrawLine(rectCell.GetRight(), rectCell.GetTop(),\r
+            rectCell.GetLeft(), rectCell.GetTop());\r
+    }\r
+}\r
+\r
+\r
+//\r
+// Cell editing utilities classes\r
+//\r
+dxGridCellSizedChoiceEditor::dxGridCellSizedChoiceEditor(const wxArrayString& choices, bool allowOthers)\r
+:wxGridCellChoiceEditor(choices,allowOthers)\r
+{\r
+}\r
+\r
+\r
+dxGridCellSizedChoiceEditor::dxGridCellSizedChoiceEditor(size_t count, const wxString choices[], bool allowOthers)\r
+:wxGridCellChoiceEditor(count,choices, allowOthers)\r
+{\r
+}\r
+\r
+\r
+wxGridCellEditor *dxGridCellSizedChoiceEditor::Clone() const\r
+{\r
+    dxGridCellSizedChoiceEditor *editor = new\r
+        dxGridCellSizedChoiceEditor();\r
+    return editor;\r
+}\r
+\r
+\r
+void dxGridCellSizedChoiceEditor::Show(bool show, wxGridCellAttr *attr)\r
+{\r
+    wxGridCellEditor::Show(show, attr);\r
+}\r
diff --git a/pgadmin/gqb/gqbModel.cpp b/pgadmin/gqb/gqbModel.cpp
new file mode 100644 (file)
index 0000000..a0552a2
--- /dev/null
@@ -0,0 +1,112 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbModel.cpp - Model of MVC Pattern for GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+\r
+// App headers\r
+#include "gqb/gqbModel.h"\r
+#include "gqb/gqbQueryObjs.h"\r
+\r
+gqbModel::gqbModel():\r
+wxObject()\r
+{\r
+// here store all queryObjects\r
+// GQB-TODO: allow different names for each model\r
+    queryCollection = new gqbQueryObjs();\r
+    restrictions = new gqbRestrictions();\r
+    columnsAlias = new  wxArrayString();\r
+}\r
+\r
+\r
+// GQB-TODO: check this destructor is not complete\r
+gqbModel::~gqbModel()\r
+{\r
+    if(queryCollection)\r
+        delete queryCollection;\r
+\r
+    // Don't owns objects only remove then in both\r
+    colsPosition.Empty();\r
+    colsParents.Empty();\r
+    if(columnsAlias)\r
+        delete columnsAlias;\r
+\r
+    //GQB-TODO: delete restrictions\r
+}\r
+\r
+\r
+gqbQueryObject* gqbModel::addTable(gqbTable *table, wxPoint p)\r
+{\r
+    // Get a table but introduce a QueryObject\r
+    gqbQueryObject *tmp = new gqbQueryObject(table);\r
+    tmp->position=p;\r
+\r
+    // Now use insert the new object in the collection of the model\r
+    queryCollection->addTable(tmp);\r
+\r
+    // Columns of added table should be possible to use on Order By Clause\r
+    gqbIteratorBase *iterator = tmp->parent->createColumnsIterator();\r
+    while(iterator->HasNext())\r
+    {\r
+        gqbColumn *col= (gqbColumn *)iterator->Next();\r
+        AvailableColumns.Add(col);\r
+        ColumnAvailParent.Add(tmp);\r
+    }\r
+    delete iterator;\r
+\r
+    return tmp;\r
+}\r
+\r
+\r
+gqbIteratorBase*  gqbModel::createQueryIterator()\r
+{\r
+    return queryCollection->createQueryIterator();\r
+}\r
+\r
+gqbIteratorBase*  gqbModel::createDownQueryIterator()\r
+{\r
+    return queryCollection->createDownQueryIterator();\r
+}\r
+\r
+void gqbModel::deleteTable(gqbQueryObject *modelTable)\r
+{\r
+    if(modelTable)\r
+    {\r
+        queryCollection->removeTable(modelTable);\r
+        delete modelTable;\r
+        modelTable=NULL;\r
+    }\r
+}\r
+\r
+\r
+int gqbModel::tablesCount()\r
+{\r
+    return queryCollection->tablesCount();\r
+}\r
+\r
+\r
+void gqbModel::emptyAll()\r
+{\r
+    colsPosition.Empty();\r
+    colsParents.Empty();\r
+    queryCollection->removeAllQueryObjs();\r
+\r
+}\r
+\r
+\r
+gqbQueryRestriction* gqbModel::addRestriction()\r
+{\r
+    gqbQueryRestriction *r = new gqbQueryRestriction();\r
+    restrictions->addRestriction(r);\r
+    return r;\r
+}\r
diff --git a/pgadmin/gqb/gqbObject.cpp b/pgadmin/gqb/gqbObject.cpp
new file mode 100644 (file)
index 0000000..84430c4
--- /dev/null
@@ -0,0 +1,66 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbObject.cpp - Main basic object used by GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+// App headers\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+\r
+// App headers\r
+#include "gqb/gqbObject.h"\r
+\r
+gqbObject::gqbObject(wxString name, type_gqbObject type)\r
+{\r
+    this->Type=type;\r
+    this->Name=name;\r
+}\r
+\r
+\r
+gqbObject::~gqbObject()\r
+{\r
+}\r
+\r
+\r
+void gqbObject::setName(wxString name)\r
+{\r
+    this->Name=name;\r
+}\r
+\r
+\r
+const wxString& gqbObject::getName()\r
+{\r
+    return Name;\r
+}\r
+\r
+\r
+void gqbObject::setOwner(wxTreeItemData *owner)\r
+{\r
+    this->Owner=owner;\r
+}\r
+\r
+\r
+const wxTreeItemData& gqbObject::getOwner()\r
+{\r
+    return (*Owner);\r
+}\r
+\r
+\r
+void gqbObject::setType(type_gqbObject tname)\r
+{\r
+    this->Type=tname;\r
+}\r
+\r
+\r
+const type_gqbObject gqbObject::getType()\r
+{\r
+    return this->Type;\r
+}\r
diff --git a/pgadmin/gqb/gqbObjectCollection.cpp b/pgadmin/gqb/gqbObjectCollection.cpp
new file mode 100644 (file)
index 0000000..f5bd670
--- /dev/null
@@ -0,0 +1,113 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbObjectCollection.cpp - A Collection of simple GQB objects\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+// App headers\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+\r
+// App headers\r
+#include "gqb/gqbObject.h"\r
+#include "gqb/gqbObjectCollection.h"\r
+#include "gqb/gqbCollection.h"\r
+#include "gqb/gqbArrayCollection.h"\r
+\r
+gqbObjectCollection::gqbObjectCollection(wxString name, type_gqbObject type):\r
+gqbObject(name, type)\r
+{\r
+       // Create the concrete implementation of the Collection, right now only one implementation not need parameter\r
+    implementation = new gqbArrayCollection();\r
+\r
+       // Create the collection using the concrete implementation\r
+       // use the array implementation of the collection\r
+    objectsCollection =  new gqbCollection(implementation);\r
+    this->setOwner(NULL);\r
+}\r
+\r
+\r
+gqbObjectCollection::~gqbObjectCollection()\r
+{\r
+    if(objectsCollection)  // Implementation is deleted when delete the collection & shouldn't be deleted again\r
+        delete objectsCollection;\r
+}\r
+\r
+\r
+void gqbObjectCollection::addObject(gqbObject *object)\r
+{\r
+    objectsCollection->addItem(object);\r
+}\r
+\r
+\r
+void gqbObjectCollection::removeObject(gqbObject *object)\r
+{\r
+    objectsCollection->removeItem(object);\r
+}\r
+\r
+\r
+gqbIteratorBase* gqbObjectCollection::createIterator()\r
+{\r
+    return objectsCollection->createIterator();\r
+}\r
+\r
+gqbIteratorBase* gqbObjectCollection::createDownIterator()\r
+{\r
+    return objectsCollection->createDownIterator();\r
+}\r
+\r
+int gqbObjectCollection::countObjects()\r
+{\r
+    return objectsCollection->count();\r
+}\r
+\r
+\r
+gqbObject* gqbObjectCollection::getObjectAtIndex(int index)\r
+{\r
+    return objectsCollection->getItemAt(index);\r
+}\r
+\r
+\r
+bool gqbObjectCollection::existsObject(gqbObject *object)\r
+{\r
+    return objectsCollection->existsObject(object);\r
+}\r
+\r
+\r
+// Remove all objects from collection without deleting each one.\r
+void gqbObjectCollection::removeAll()\r
+{\r
+    objectsCollection->removeAll();\r
+}\r
+\r
+\r
+int gqbObjectCollection::indexObject(gqbObject *object)\r
+{\r
+    return  objectsCollection->getIndex(object);\r
+}\r
+\r
+\r
+void gqbObjectCollection::insertObjectAt(gqbObject *object, int index)\r
+{\r
+    objectsCollection->insertAtIndex(object, index);\r
+}\r
+\r
+\r
+int gqbObjectCollection::getCount()\r
+{\r
+    return objectsCollection->count();\r
+}\r
+\r
+\r
+// Remove & delete all objects\r
+void gqbObjectCollection::deleteAll()\r
+{\r
+    objectsCollection->deleteAll();\r
+}\r
diff --git a/pgadmin/gqb/gqbQueryObjs.cpp b/pgadmin/gqb/gqbQueryObjs.cpp
new file mode 100644 (file)
index 0000000..5c7808f
--- /dev/null
@@ -0,0 +1,523 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbQueryObjs.cpp - All objects used by a model of a query in the MVC Pattern model.\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+#include <wx/textctrl.h>\r
+#include <wx/regex.h>\r
+\r
+// App headers\r
+#include "gqb/gqbTable.h"\r
+#include "gqb/gqbColumn.h"\r
+#include "gqb/gqbQueryObjs.h"\r
+#include "gqb/gqbObjectCollection.h"\r
+#include "gqb/gqbViewPanels.h"\r
+\r
+//\r
+// Collections of Tables inside a Query, data structured used for query storage & later generation of SQL sentence\r
+//\r
+\r
+gqbQueryObjs::gqbQueryObjs():\r
+gqbObjectCollection(wxT(""),_gqbQuery)\r
+{\r
+    this->setOwner(NULL);\r
+}\r
+\r
+\r
+void gqbQueryObjs::addTable(gqbQueryObject *mtable)\r
+{\r
+    this->addObject(mtable);\r
+}\r
+\r
+\r
+void gqbQueryObjs::removeTable(gqbQueryObject *mtable)\r
+{\r
+    this->removeObject(mtable);\r
+}\r
+\r
+\r
+gqbIteratorBase*  gqbQueryObjs::createQueryIterator()\r
+{\r
+    return this->createIterator();\r
+}\r
+\r
+gqbIteratorBase*  gqbQueryObjs::createDownQueryIterator()\r
+{\r
+    return this->createDownIterator();\r
+}\r
+\r
+\r
+int gqbQueryObjs::tablesCount()\r
+{\r
+    return this->countObjects();\r
+}\r
+\r
+\r
+void gqbQueryObjs::removeAllQueryObjs()\r
+{\r
+    this->removeAll();\r
+}\r
+\r
+\r
+//\r
+// An Object inside a query (A table object in the query), not equal to gqbTable\r
+// Reason: Sometimes a table can be used twice or more times in a query with different columns selected\r
+//         Because this we can not use directly the base table object\r
+\r
+gqbQueryObject::gqbQueryObject(gqbTable *table)\r
+:gqbObjectCollection(table->getName(),_gqbQueryObj)\r
+{\r
+    selected=false;\r
+    parent=table;\r
+\r
+       //GQB-TODO: Calculate a good initial position\r
+    position.x=20;\r
+    position.y=20;\r
+    haveJoins=false;\r
+    haveRegisteredJoins=false;\r
+    registeredCollection=NULL;\r
+    joinsCollection=NULL;\r
+}\r
+\r
+\r
+// Destructor must empty collection to don't allow deleting of column items from tree\r
+// because this collection doesn't owns it, and then shouldn't destroy it.\r
+gqbQueryObject::~gqbQueryObject()\r
+{\r
+    this->removeAll();\r
+\r
+    // Remove item registered at this Query Object\r
+    gqbQueryJoin *tmp;\r
+    if(registeredCollection)\r
+    {\r
+        gqbIteratorBase *r=createRegJoinsIterator();\r
+        while(r->HasNext())\r
+        {\r
+            tmp= (gqbQueryJoin *)r->Next();\r
+            this->unregisterJoin(tmp,true);       // remove and unregister every join in every query object \r
+                                                             // which have registered at this query object\r
+\r
+            // On each iteration the structure of iterator change because \r
+                       // modified his own collection & should be reset\r
+            r->ResetIterator();\r
+        }\r
+        delete r;\r
+    }\r
+\r
+    if(joinsCollection)\r
+    {\r
+        gqbIteratorBase *j=createJoinsIterator();\r
+        while(j->HasNext())\r
+        {\r
+            tmp= (gqbQueryJoin *)j->Next();\r
+            this->removeJoin(tmp,true);           // removes & unregister Join which have like origin this \r
+                                                             // query object\r
+            // On each iteration the structure of iterator change because \r
+                       // modified his own collection & should be reset\r
+            j->ResetIterator();\r
+        }\r
+        delete j;\r
+\r
+    }\r
+\r
+    // removeJoin & unregisterJoin delete the collections where there aren't any items inside.\r
+}\r
+\r
+\r
+void gqbQueryObject::setSelected(bool value)\r
+{\r
+    this->selected=value;\r
+}\r
+\r
+\r
+bool gqbQueryObject::getSelected()\r
+{\r
+    return this->selected;\r
+}\r
+\r
+\r
+void gqbQueryObject::setWidth(int value)\r
+{\r
+    width=value;\r
+}\r
+\r
+\r
+int gqbQueryObject::getWidth()\r
+{\r
+    return width;\r
+}\r
+\r
+\r
+void gqbQueryObject::setHeight(int value)\r
+{\r
+    height=value;\r
+}\r
+\r
+\r
+int gqbQueryObject::getHeight()\r
+{\r
+    return height;\r
+}\r
+\r
+\r
+void gqbQueryObject::addColumn(gqbColumn *column)\r
+{\r
+    this->addObject(column);\r
+}\r
+\r
+\r
+void gqbQueryObject::removeColumn(gqbColumn *column)\r
+{\r
+    this->removeObject(column);\r
+}\r
+\r
+\r
+bool gqbQueryObject::existsColumn(gqbColumn *column)\r
+{\r
+    return this->existsObject(column);\r
+}\r
+\r
+\r
+gqbIteratorBase* gqbQueryObject::createQueryTableIterator()\r
+{\r
+    return this->createIterator();\r
+}\r
+\r
+\r
+gqbIteratorBase* gqbQueryObject::createJoinsIterator()\r
+{\r
+    return joinsCollection->createIterator();\r
+}\r
+\r
+\r
+gqbIteratorBase* gqbQueryObject::createRegJoinsIterator()\r
+{\r
+    return registeredCollection->createIterator();\r
+}\r
+\r
+\r
+// Create a Join from this table [owner] column to other table [observable] column\r
+gqbQueryJoin* gqbQueryObject::addJoin(gqbQueryObject *owner, gqbQueryObject *observable, gqbColumn *source, gqbColumn *destination, type_Join kind)\r
+{\r
+    if(!haveJoins)\r
+    {\r
+        implementationj = new gqbArrayCollection();\r
+        joinsCollection =  new gqbCollection(implementationj);\r
+        haveJoins=true;\r
+    }\r
+\r
+    gqbQueryJoin *join = new gqbQueryJoin(owner,observable,source,destination,kind);\r
+    joinsCollection->addItem(join);\r
+    observable->registerJoin(join);\r
+    return join;\r
+}\r
+\r
+\r
+// Remove the join from this query object [source table]\r
+void gqbQueryObject::removeJoin(gqbQueryJoin *join, bool unRegister = false)\r
+{\r
+    // Notify to observable that the join this object owns will be removed & then remove the join\r
+    if(unRegister)\r
+        join->getDestQTable()->unregisterJoin(join,false);\r
+    joinsCollection->removeItem(join);\r
+    if(join)\r
+        delete join;                              // Join can be only delete Here by his owner\r
+\r
+    if(joinsCollection->count()<=0)\r
+    {\r
+        delete joinsCollection;                   // implementation it's delete too inside collection.\r
+        haveJoins=false;\r
+        joinsCollection=NULL;\r
+    }\r
+}\r
+\r
+\r
+// Register a Join created from other table [source] to this table [destination]\r
+void gqbQueryObject::registerJoin(gqbQueryJoin *join)\r
+{\r
+    if(!haveRegisteredJoins)\r
+    {\r
+        implementationr = new gqbArrayCollection();\r
+        registeredCollection =  new gqbCollection(implementationr);\r
+        haveRegisteredJoins=true;\r
+    }\r
+    registeredCollection->addItem(join);\r
+}\r
+\r
+\r
+// Unregister a Join create from other table [source] to this table [destination] delete the join if need it..\r
+void gqbQueryObject::unregisterJoin(gqbQueryJoin *join, bool removeIt = false)\r
+{\r
+    // Notify to source/owner object of join about join removing & then remove\r
+    registeredCollection->removeItem(join);\r
+    if(removeIt)\r
+        join->getSourceQTable()->removeJoin(join,false);\r
+    if(registeredCollection->count()<=0)\r
+    {\r
+        delete registeredCollection;              //implementation it's delete too inside collection.\r
+        haveRegisteredJoins=false;\r
+        registeredCollection=NULL;\r
+    }\r
+}\r
+\r
+\r
+int gqbQueryObject::getColumnIndex(gqbColumn *column)\r
+{\r
+    return parent->indexColumn(column);\r
+}\r
+\r
+\r
+bool gqbQueryObject::getHaveJoins()\r
+{\r
+    return haveJoins;\r
+}\r
+\r
+\r
+bool gqbQueryObject::getHaveRegJoins()\r
+{\r
+    return haveRegisteredJoins;\r
+}\r
+\r
+\r
+wxString gqbQueryObject::getAlias()\r
+{\r
+    if (haveUpperCase(alias))\r
+    {\r
+        return wxT("\"")+alias+wxT("\"");\r
+    }\r
+    return alias;\r
+};\r
+\r
+bool gqbQueryObject::haveUpperCase(wxString &str)\r
+{\r
+    bool result=false;\r
+    \r
+       // if any uppercase character at string, then quoted.\r
+    wxRegEx *reUpper =  new wxRegEx(wxT("[a-z0-9]*[A-Z]"));\r
+    if(reUpper->Matches(str))\r
+    {\r
+        result=true;\r
+    }\r
+    delete reUpper;\r
+    return result;\r
+}\r
+\r
+\r
+// GQB-TODO if last join it's delete I MUST delete implementation & collection & put haveJoins in false;\r
+// Same for registered joins\r
+\r
+//\r
+//  A Join inside a query Object like Table or view [Stored at source, registered at destination]\r
+//  I need to store the owner, destination because columns it's share between multiple joins\r
+gqbQueryJoin::gqbQueryJoin(gqbQueryObject *_owner, gqbQueryObject *_destination, gqbColumn *sourceCol, gqbColumn *destCol, type_Join joinKind):\r
+gqbObject(wxT(""),_gqbJoin)\r
+{\r
+    kindofJoin=joinKind;\r
+    sCol=sourceCol;\r
+    dCol=destCol;\r
+    owner=_owner;\r
+    selected=false;\r
+    destination=_destination;\r
+}\r
+\r
+\r
+void gqbQueryJoin::setKindofJoin(type_Join kind)\r
+{\r
+    kindofJoin=kind;\r
+}\r
+\r
+\r
+type_Join gqbQueryJoin::getKindofJoin()\r
+{\r
+    return kindofJoin;\r
+}\r
+\r
+\r
+// Return the object where the join is stored\r
+gqbQueryObject* gqbQueryJoin::getSourceQTable()\r
+{\r
+    return owner;\r
+}\r
+\r
+\r
+// Return the object where the join point to.\r
+gqbQueryObject* gqbQueryJoin::getDestQTable()\r
+{\r
+    return destination;\r
+}\r
+\r
+\r
+// Return the gqbObject of Destination Column\r
+gqbColumn* gqbQueryJoin::getDCol()\r
+{\r
+    return dCol;\r
+}\r
+\r
+\r
+// Return the gqbObject of Source Column\r
+gqbColumn* gqbQueryJoin::getSCol()\r
+{\r
+    return sCol;\r
+}\r
+\r
+\r
+const wxString& gqbQueryJoin::getSourceTable()\r
+{\r
+    gqbTable *s=(gqbTable*)&sCol->getOwner();\r
+    return s->getName();\r
+}\r
+\r
+\r
+const wxString& gqbQueryJoin::getDestTable()\r
+{\r
+    gqbTable *d=(gqbTable*)&dCol->getOwner();\r
+    return d->getName();\r
+}\r
+\r
+\r
+const wxString& gqbQueryJoin::getSourceCol()\r
+{\r
+    return sCol->getName();\r
+}\r
+\r
+\r
+const wxString& gqbQueryJoin::getDestCol()\r
+{\r
+    return dCol->getName();\r
+}\r
+\r
+\r
+void gqbQueryJoin::setSourceAnchor(wxPoint pt)\r
+{\r
+    sAnchor=pt;\r
+}\r
+\r
+\r
+void gqbQueryJoin::setDestAnchor(wxPoint pt)\r
+{\r
+    dAnchor=pt;\r
+}\r
+\r
+\r
+wxPoint& gqbQueryJoin::getSourceAnchor()\r
+{\r
+    return sAnchor;\r
+}\r
+\r
+\r
+wxPoint& gqbQueryJoin::getDestAnchor()\r
+{\r
+    return dAnchor;\r
+}\r
+\r
+\r
+void gqbQueryJoin::setSelected(bool value)\r
+{\r
+    this->selected=value;\r
+}\r
+\r
+\r
+bool gqbQueryJoin::getSelected()\r
+{\r
+    return this->selected;\r
+}\r
+\r
+\r
+void gqbQueryJoin::setAnchorsUsed(wxPoint pt)\r
+{\r
+    anchorsUsed=pt;\r
+}\r
+\r
+\r
+wxPoint& gqbQueryJoin::getAnchorsUsed()\r
+{\r
+    return anchorsUsed;\r
+}\r
+\r
+\r
+//\r
+// A query restriction\r
+//\r
+\r
+enum\r
+{\r
+    QRButton=9000,\r
+    QRValue,\r
+    QRConnector,\r
+    QRtype\r
+};\r
+\r
+gqbQueryRestriction::gqbQueryRestriction():\r
+gqbObject(wxT(""),_gqbRestriction)\r
+{\r
+    leftPart=wxT("");\r
+    value_s=wxT("");\r
+    connector=wxT("AND");\r
+    restriction=wxT("=");\r
+}\r
+\r
+\r
+gqbRestrictions::gqbRestrictions():\r
+gqbObjectCollection(wxT(""),_gqbRestriction)\r
+{\r
+    this->setOwner(NULL);\r
+}\r
+\r
+\r
+gqbRestrictions::~gqbRestrictions()\r
+{\r
+    this->removeAll();\r
+}\r
+\r
+\r
+void gqbRestrictions::addRestriction(gqbQueryRestriction *r)\r
+{\r
+    this->addObject(r);\r
+}\r
+\r
+\r
+void gqbRestrictions::addRestrictionAt(gqbQueryRestriction *r, int index)\r
+{\r
+    this->insertObjectAt(r, index);\r
+}\r
+\r
+\r
+// Remove but don't delete restriction\r
+void gqbRestrictions::removeRestriction(gqbQueryRestriction *r)\r
+{\r
+    this->removeObject(r);\r
+}\r
+\r
+\r
+void gqbRestrictions::deleteAllRestrictions()\r
+{\r
+    this->deleteAll();\r
+}\r
+\r
+\r
+gqbIteratorBase* gqbRestrictions::createRestrictionsIterator()\r
+{\r
+    return this->createIterator();\r
+}\r
+\r
+\r
+int gqbRestrictions::restrictionsCount()\r
+{\r
+    return this->getCount();\r
+}\r
+\r
+\r
+gqbQueryRestriction* gqbRestrictions::getRestrictionAt(int index)\r
+{\r
+    return (gqbQueryRestriction*)this->getObjectAtIndex(index);\r
+}\r
diff --git a/pgadmin/gqb/gqbSchema.cpp b/pgadmin/gqb/gqbSchema.cpp
new file mode 100644 (file)
index 0000000..fafb9b6
--- /dev/null
@@ -0,0 +1,136 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbSchema.cpp - Schema object for GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+// App headers\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+\r
+// App headers\r
+#include "gqb/gqbSchema.h"\r
+#include "gqb/gqbObject.h"\r
+#include "gqb/gqbTable.h"\r
+#include "gqb/gqbBrowser.h"\r
+\r
+gqbSchema::gqbSchema(gqbObject *parent, wxString name, type_gqbObject type=_gqbSchema):\r
+gqbObject(name,type)\r
+{\r
+    this->setType(_gqbSchema);\r
+    this->setName(name);\r
+    this->setOwner(parent);\r
+}\r
+\r
+\r
+// GQB-TODO: don't declare OID inside gqbBrowsear instead use the pgadmin one\r
+void gqbSchema::createObjects(gqbBrowser *_tablesBrowser,  pgConn *_conn, OID oidVal, wxTreeItemId parentNode, int _tableImage, int _viewImage)\r
+{\r
+    createTables(_conn, _tablesBrowser, parentNode, oidVal, _tableImage, _viewImage);\r
+}\r
+\r
+\r
+wxString gqbSchema::NumToStr(OID value)\r
+{\r
+    wxString result;\r
+    result.Printf(wxT("%lu"), (long)value);\r
+    return result;\r
+}\r
+\r
+\r
+void gqbSchema::createTables(pgConn *conn, gqbBrowser *tablesBrowser, wxTreeItemId parentNode, OID oidVal, int tableImage, int viewImage)\r
+{\r
+       \r
+    wxString query;\r
+    wxString restriction=wxT("");\r
+       \r
+       // First Add Tables;\r
+    if (conn->BackendMinimumVersion(8, 0))\r
+    {\r
+        query= wxT("SELECT rel.oid, relname, rel.reltablespace AS spcoid, spcname, pg_get_userbyid(relowner) AS relowner, relacl, relhasoids, ")\r
+            wxT("relhassubclass, reltuples, description, conname, conkey,\n")\r
+            wxT("       EXISTS(select 1 FROM pg_trigger\n")\r
+            wxT("                       JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger'\n")\r
+            wxT("                       JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion'\n")\r
+            wxT("                     WHERE tgrelid=rel.oid) AS isrepl\n");\r
+        if (conn->BackendMinimumVersion(8, 2))\r
+            query += wxT(", substring(array_to_string(reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor \n");\r
+        query += wxT("  FROM pg_class rel\n")\r
+            wxT("  LEFT OUTER JOIN pg_tablespace ta on ta.oid=rel.reltablespace\n")\r
+            wxT("  LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0)\n")\r
+            wxT("  LEFT OUTER JOIN pg_constraint c ON c.conrelid=rel.oid AND c.contype='p'\n")\r
+            wxT(" WHERE relkind IN ('r','s','t') AND relnamespace = ") + NumToStr(oidVal) + wxT("\n")\r
+            + restriction +\r
+            wxT(" ORDER BY relname");\r
+    }\r
+    else\r
+    {\r
+        query= wxT("SELECT rel.oid, relname, pg_get_userbyid(relowner) AS relowner, relacl, relhasoids, ")\r
+            wxT("relhassubclass, reltuples, description, conname, conkey,\n")\r
+            wxT("       EXISTS(select 1 FROM pg_trigger\n")\r
+            wxT("                       JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger'\n")\r
+            wxT("                       JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion'\n")\r
+            wxT("                     WHERE tgrelid=rel.oid) AS isrepl\n")\r
+            wxT("  FROM pg_class rel\n")\r
+            wxT("  LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0)\n")\r
+            wxT("  LEFT OUTER JOIN pg_constraint c ON c.conrelid=rel.oid AND c.contype='p'\n")\r
+            wxT(" WHERE relkind IN ('r','s','t') AND relnamespace = ") + NumToStr(oidVal)  + wxT("\n")\r
+            + restriction +\r
+            wxT(" ORDER BY relname");\r
+    }\r
+\r
+    pgSet *tables = conn->ExecuteSet(query);\r
+    wxTreeItemId parent;\r
+\r
+    if (tables)\r
+    {\r
+        while (!tables->Eof())\r
+        {\r
+            wxString tmpname = wxString(tables->GetVal(wxT("relname")));\r
+            gqbTable *table = new gqbTable(this,tmpname,_gqbTable);\r
+            parent=tablesBrowser->AppendItem(parentNode, tables->GetVal(wxT("relname")) , tableImage, tableImage, table);\r
+\r
+                       // Create columns inside this table.\r
+            table->createObjects(tablesBrowser, conn, tables->GetOid(wxT("oid")), parent);\r
+\r
+            tables->MoveNext();\r
+        }\r
+\r
+        delete tables;\r
+    }\r
+\r
+       // Later Add Views;\r
+       query=wxT("SELECT c.oid, c.xmin, c.relname, pg_get_userbyid(c.relowner) AS viewowner, c.relacl, description")\r
+        wxT("  FROM pg_class c\n")\r
+        wxT("  LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid and des.objsubid=0)\n")\r
+        wxT(" WHERE ((c.relhasrules AND (EXISTS (\n")\r
+        wxT("           SELECT r.rulename FROM pg_rewrite r\n")\r
+        wxT("            WHERE ((r.ev_class = c.oid)\n")\r
+        wxT("              AND (bpchar(r.ev_type) = '1'::bpchar)) ))) OR (c.relkind = 'v'::char))\n")\r
+        wxT("   AND relnamespace = ") + NumToStr(oidVal) + wxT("\n")\r
+        + restriction\r
+        + wxT(" ORDER BY relname");\r
+\r
+    pgSet *views = conn->ExecuteSet(query);\r
+         if (views)\r
+    {\r
+        while (!views->Eof())\r
+        {\r
+            wxString tmpname = wxString(views->GetVal(wxT("relname")));\r
+            gqbTable *table = new gqbTable(this,tmpname,_gqbTable);\r
+            parent=tablesBrowser->AppendItem(parentNode, views->GetVal(wxT("relname")) , viewImage, viewImage, table);\r
+\r
+                       // Create columns inside this view.\r
+            table->createObjects(tablesBrowser,conn,views->GetOid(wxT("oid")),parent);\r
+\r
+            views->MoveNext();\r
+                       }\r
+         }\r
+}\r
diff --git a/pgadmin/gqb/gqbTable.cpp b/pgadmin/gqb/gqbTable.cpp
new file mode 100644 (file)
index 0000000..4fffb56
--- /dev/null
@@ -0,0 +1,134 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbTable.cpp - Table object for GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+// App headers\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+\r
+// App headers\r
+#include "gqb/gqbObject.h"\r
+#include "gqb/gqbTable.h"\r
+#include "gqb/gqbColumn.h"\r
+#include "gqb/gqbArrayCollection.h"\r
+\r
+gqbTable::gqbTable(gqbObject *parent, wxString name, type_gqbObject type=_gqbTable):\r
+gqbObjectCollection(name,type)\r
+{\r
+    this->setType(_gqbTable);\r
+    this->setName(name);\r
+    this->setOwner(parent);\r
+}\r
+\r
+\r
+gqbIteratorBase* gqbTable::createColumnsIterator()\r
+{\r
+    return createIterator();\r
+}\r
+\r
+\r
+void gqbTable::addColumn(gqbColumn *column)\r
+{\r
+    this->addObject(column);\r
+}\r
+\r
+\r
+void gqbTable::createObjects(gqbBrowser *_tablesBrowser,  pgConn *_conn, OID oidVal,  wxTreeItemId parentNode)\r
+{\r
+    createColumns(_conn, _tablesBrowser, parentNode, oidVal);\r
+}\r
+\r
+\r
+wxString gqbTable::NumToStr(OID value)\r
+{\r
+    wxString result;\r
+    result.Printf(wxT("%lu"), (long)value);\r
+    return result;\r
+}\r
+\r
+\r
+void gqbTable::createColumns(pgConn *conn, gqbBrowser *tablesBrowser, wxTreeItemId parentNode,  OID oidVal)\r
+{\r
+\r
+    wxString systemRestriction;\r
+    if (!settings->GetShowSystemObjects())\r
+        systemRestriction = wxT("\n   AND attnum > 0");\r
+\r
+    wxString sql=\r
+        wxT("SELECT att.*, def.*, pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS defval, CASE WHEN attndims > 0 THEN 1 ELSE 0 END AS isarray, format_type(ty.oid,NULL) AS typname, tn.nspname as typnspname, et.typname as elemtypname,\n")\r
+        wxT("  cl.relname, na.nspname, att.attstattarget, description, cs.relname AS sername, ns.nspname AS serschema,\n")\r
+        wxT("  (SELECT count(1) FROM pg_type t2 WHERE t2.typname=ty.typname) > 1 AS isdup, indkey");\r
+\r
+    if (conn->BackendMinimumVersion(7, 4))\r
+        sql +=\r
+            wxT(",\n")\r
+            wxT("  EXISTS(SELECT 1 FROM  pg_constraint WHERE conrelid=att.attrelid AND contype='f'")\r
+            wxT(" AND att.attnum=ANY(conkey)) As isfk");\r
+\r
+    sql += wxT("\n")\r
+        wxT("  FROM pg_attribute att\n")\r
+        wxT("  JOIN pg_type ty ON ty.oid=atttypid\n")\r
+        wxT("  JOIN pg_namespace tn ON tn.oid=ty.typnamespace\n")\r
+        wxT("  JOIN pg_class cl ON cl.oid=attrelid\n")\r
+        wxT("  JOIN pg_namespace na ON na.oid=cl.relnamespace\n")\r
+        wxT("  LEFT OUTER JOIN pg_type et ON et.oid=ty.typelem\n")\r
+        wxT("  LEFT OUTER JOIN pg_attrdef def ON adrelid=attrelid AND adnum=attnum\n")\r
+        wxT("  LEFT OUTER JOIN pg_description des ON des.objoid=attrelid AND des.objsubid=attnum\n")\r
+        wxT("  LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON objid=cs.oid AND cs.relkind='S') ON refobjid=attrelid AND refobjsubid=attnum\n")\r
+        wxT("  LEFT OUTER JOIN pg_namespace ns ON ns.oid=cs.relnamespace\n")\r
+        wxT("  LEFT OUTER JOIN pg_index pi ON pi.indrelid=attrelid AND indisprimary\n")\r
+        wxT(" WHERE attrelid = ")\r
+        + NumToStr(oidVal)\r
+        + systemRestriction + wxT("\n")\r
+        wxT("   AND attisdropped IS FALSE\n")\r
+        wxT(" ORDER BY attnum");\r
+\r
+    pgSet *columns= conn->ExecuteSet(sql);\r
+    if (columns)\r
+    {\r
+        while (!columns->Eof())\r
+        {\r
+            if (tablesBrowser)\r
+            {\r
+                //Disable, Column SHOULDN'T be added to tree only use for debug purposes tablesBrowser->AppendItem(parentNode, columns->GetVal(wxT("attname")) , -1, -1);\r
+                wxString tmpname = wxString(columns->GetVal(wxT("attname")));\r
+                gqbColumn *column = new gqbColumn(this,tmpname,_gqbColumn);\r
+                this->addColumn(column);\r
+                columns->MoveNext();\r
+            }\r
+            else\r
+                break;\r
+        }\r
+\r
+        delete columns;\r
+    }\r
+}\r
+\r
+\r
+//work as a synonym for function\r
+int gqbTable::countCols()\r
+{\r
+    return this->countObjects();\r
+}\r
+\r
+\r
+//work as a synonym for function & return correct type\r
+gqbColumn* gqbTable::getColumnAtIndex(int index)\r
+{\r
+    return (gqbColumn *)this->getObjectAtIndex(index);\r
+}\r
+\r
+\r
+int gqbTable::indexColumn(gqbColumn *col)\r
+{\r
+    return this->indexObject(col);\r
+}\r
diff --git a/pgadmin/gqb/gqbView.cpp b/pgadmin/gqb/gqbView.cpp
new file mode 100644 (file)
index 0000000..bdd6d1a
--- /dev/null
@@ -0,0 +1,656 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbView.cpp - View implementation for MVC Pattern of GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+// 1. READ MODEL STATE FROM gqbModel TO CREATE THE GRAPHIC REPRESENTATION OF THE QUERY\r
+// 2. USE THE CONTROLLER TO CHANGE THE MODEL WITH THE USER INPUT\r
+\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+#include <wx/dcbuffer.h>\r
+#include <wx/generic/gridctrl.h>\r
+#include <wx/notebook.h>\r
+#include <wx/choicdlg.h>\r
+\r
+// App headers\r
+#include "gqb/gqbModel.h"\r
+#include "gqb/gqbEvents.h"\r
+#include "gqb/gqbViewController.h"\r
+#include "gqb/gqbQueryObjs.h"\r
+#include "gqb/gqbGraphSimple.h"\r
+#include "gqb/gqbViewPanels.h"\r
+#include "gqb/gqbObject.h"\r
+#include "gqb/gqbObjectCollection.h"\r
+\r
+// Image\r
+#include "images/gqbJoinCursor.xpm"\r
+\r
+BEGIN_EVENT_TABLE(gqbView, wxScrolledWindow)\r
+EVT_PAINT(gqbView::onPaint)\r
+EVT_MOTION(gqbView::onMotion)\r
+EVT_LEFT_DOWN(gqbView::onMotion)\r
+EVT_RIGHT_DOWN(gqbView::onRightClick)\r
+EVT_LEFT_UP(gqbView::onMotion)\r
+EVT_LEFT_DCLICK(gqbView::onDoubleClick)\r
+EVT_ERASE_BACKGROUND(gqbView::onEraseBackGround)  //This erase flicker create by wxStaticText when erasing background but this is not needed\r
+EVT_KEY_DOWN(gqbView::OnKeyDown)\r
+EVT_MENU(GQB_RMJ_DELETE,gqbView::OnMenuJoinDelete)\r
+EVT_MENU(GQB_RMJ_SETTYPE,gqbView::OnMenuJoinSetType)\r
+EVT_MENU(GQB_RMT_DELETE,gqbView::OnMenuTableDelete)\r
+EVT_MENU(GQB_RMT_SETALIAS,gqbView::OnMenuTableSetAlias)\r
+END_EVENT_TABLE()\r
+\r
+gqbView::gqbView(wxWindow *gqbParent, wxNotebook *gridParent, wxSize size, gqbController *controller, gqbModel *model)\r
+: wxScrolledWindow(gqbParent, wxID_ANY, wxPoint(201,0), size,\r
+wxHSCROLL | wxVSCROLL | wxBORDER | wxRETAINED)\r
+{\r
+    this->controller=controller;\r
+    this->model=model;\r
+    pressed=-1;\r
+    selected=-1;\r
+    changeTOpressed=false;\r
+    canvasSize=size;\r
+    collectionSelected=NULL;\r
+    joinSelected=NULL;\r
+    joinSource=NULL;\r
+    joinDest=NULL;\r
+    joinSCol=NULL;\r
+    joinDCol=NULL;\r
+    refreshRate=3;\r
+    iterator=NULL;\r
+    mode=pt_normal;\r
+    joinCursorImage = wxBitmap(gqbJoinCursor_xpm).ConvertToImage();\r
+    joinCursor= wxCursor(joinCursorImage);\r
+    m_rightJoins=NULL;\r
+    m_rightTables=NULL;\r
+    jTempSelected=NULL;\r
+    cTempSelected=NULL;\r
+\r
+    // Assing kind of join Options\r
+    joinTypeChoices.Add(wxString(wxT(" = ")));\r
+    joinTypeChoices.Add(wxString(wxT(" > ")));\r
+    joinTypeChoices.Add(wxString(wxT(" < ")));\r
+    joinTypeChoices.Add(wxString(wxT(" >= ")));\r
+    joinTypeChoices.Add(wxString(wxT(" <= ")));\r
+\r
+    // Assign default graphic behavior [skin of forms inside model]\r
+    this->graphBehavior = new gqbGraphSimple();\r
+\r
+    // Create Projection Panel\r
+    // GQB-TODO: move model to grid panel constructor\r
+    this->gridTable = new gqbGridProjTable(this->model->getOrderedColumns(),this->model->getColumnsParents(),this->model->getColumnsAlias());\r
+    this->projectionPanel = new gqbGridPanel(controller->getTabs(),-1,gridTable);\r
+\r
+    // Create Restrictions Panel\r
+    this->restrictionsGridTable = new gqbGridRestTable(model->getRestrictions());\r
+    this->criteriaPanel = new gqbCriteriaPanel(controller->getTabs(),model,restrictionsGridTable);\r
+\r
+    // Create Order by Panel\r
+    this->orderByLGridTable = new gqbGridOrderTable(1,model->getOrdByAvailColumns(),model->getOrdByAvailParents(),NULL);\r
+    this->orderByRGridTable = new gqbGridOrderTable(2,model->getOrdByColumns(), model->getOrdByParents(),model->getOrdByKind());\r
+    this->orderPanel = new gqbOrderPanel(controller->getTabs(), orderByLGridTable, orderByRGridTable);\r
+}\r
+\r
+\r
+gqbView::~gqbView()\r
+{\r
+    if(graphBehavior)\r
+        delete graphBehavior;\r
+    if(iterator)\r
+        delete iterator;\r
+\r
+    if(m_rightTables)\r
+        delete m_rightTables;\r
+\r
+    if(m_rightJoins)\r
+        delete m_rightJoins;\r
+}\r
+\r
+\r
+// Overwrite and disable onEraseBackground Event to avoid Flicker\r
+void gqbView::onEraseBackGround(wxEraseEvent& event)\r
+{\r
+}\r
+\r
+\r
+// Detect when should be drawn the canvas with the model information\r
+void gqbView::onPaint(wxPaintEvent& event)\r
+{\r
+    wxPaintDC dcc(this);                          // Prepare Context for Buffered Draw\r
+    wxBufferedDC dc(&dcc, canvasSize);\r
+    drawAll(dc);                                  // Call Function to draw all\r
+}\r
+\r
+\r
+// GQB-TODO: remove all possible modification to model from here to controller.\r
+void gqbView::onRightClick(wxMouseEvent& event)\r
+{\r
+// GQB-TODO: Validate Alias\r
+    gqbObject *anySelected=NULL;\r
+    wxPoint pdc=event.GetPosition();\r
+    pdc.x=event.GetPosition().x;\r
+    pdc.y=event.GetPosition().y;\r
+    this->CalcUnscrolledPosition(pdc.x,pdc.y,&pdc.x,&pdc.y);\r
+    anySelected=controller->getModelSelected(pdc,cTempSelected, jTempSelected, false);\r
+    if(anySelected)\r
+    {\r
+        if(anySelected->getType()==_gqbQueryObj)\r
+        {\r
+            if(!m_rightTables)\r
+            {\r
+                m_rightTables = new wxMenu;\r
+                m_rightTables->Append(GQB_RMT_SETALIAS, wxT("&Set Alias for table"));\r
+                m_rightTables->Append(GQB_RMT_DELETE, wxT("&Delete Table"));\r
+            }\r
+            cTempSelected=(gqbQueryObject *) (gqbObjectCollection *) anySelected;\r
+            jTempSelected=NULL;\r
+            PopupMenu(m_rightTables, event.GetPosition());\r
+        }\r
+\r
+        if(anySelected->getType()==_gqbJoin)\r
+        {\r
+            if(!m_rightJoins)\r
+            {\r
+                m_rightJoins = new wxMenu;\r
+                m_rightJoins->Append(GQB_RMJ_SETTYPE, wxT("&Set Join Type"));\r
+                m_rightJoins->Append(GQB_RMJ_DELETE, wxT("&Delete Join"));\r
+            }\r
+            cTempSelected=NULL;\r
+            jTempSelected=(gqbQueryJoin *) anySelected;;\r
+            PopupMenu(m_rightJoins, event.GetPosition());\r
+        }\r
+    }\r
+}\r
+\r
+\r
+void gqbView::OnMenuJoinDelete(wxCommandEvent& WXUNUSED(event))\r
+{\r
+    if(jTempSelected)\r
+    {\r
+        controller->removeJoin(jTempSelected);\r
+        jTempSelected=NULL;\r
+        this->Refresh();\r
+    }\r
+}\r
+\r
+\r
+void gqbView::OnMenuJoinSetType(wxCommandEvent& WXUNUSED(event))\r
+{\r
+// Because a bug that scrolled automatically the panel of the view if this dialog is called, then assign\r
+// as his parent the main container of the view, and void the bug\r
+    if(jTempSelected)\r
+    {\r
+        wxSingleChoiceDialog dialog(controller->getDialogParent(),\r
+            wxT("Select the kind of Join"),\r
+            wxT("Please select a type of Join for relation, e.g. = "),\r
+            joinTypeChoices,\r
+            NULL,\r
+            wxOK | wxCANCEL| wxCENTRE);\r
+        dialog.SetSelection(0);\r
+        if (dialog.ShowModal() == wxID_OK)\r
+        {\r
+            if(dialog.GetStringSelection().Contains(wxT(" = ")))\r
+            {\r
+                jTempSelected->setKindofJoin(_equally);\r
+            }\r
+            else if(dialog.GetStringSelection().Contains(wxT(" > ")))\r
+            {\r
+                jTempSelected->setKindofJoin(_greater);\r
+            }\r
+            else if(dialog.GetStringSelection().Contains(wxT(" < ")))\r
+            {\r
+                jTempSelected->setKindofJoin(_lesser);\r
+            }\r
+            else if(dialog.GetStringSelection().Contains(wxT(" >= ")))\r
+            {\r
+                jTempSelected->setKindofJoin(_equgreater);\r
+            }\r
+            else if(dialog.GetStringSelection().Contains(wxT(" <= ")))\r
+            {\r
+                jTempSelected->setKindofJoin(_equlesser);\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+\r
+void gqbView::OnMenuTableDelete(wxCommandEvent& WXUNUSED(event))\r
+{\r
+    if(cTempSelected)\r
+    {\r
+        controller->removeTableFromModel(cTempSelected, gridTable, orderByLGridTable, orderByRGridTable);\r
+        cTempSelected=NULL;\r
+        this->Refresh();\r
+    }\r
+}\r
+\r
+\r
+void gqbView::OnMenuTableSetAlias(wxCommandEvent& event)\r
+{\r
+    if(cTempSelected)\r
+    {\r
+// Because a bug that scrolled automatically the panel of the view if this dialog is called, then assign\r
+// as his parent the main container of the view, and void the bug\r
+        wxTextEntryDialog dialog(controller->getDialogParent(),\r
+            wxT("Enter an Alias for table ")+cTempSelected->getName()+wxT(" without white spaces"),\r
+            wxT("Please enter an Alias for table, e.g. for table Customers may be ctr"),\r
+            wxT(""),\r
+            wxOK | wxCANCEL| wxCENTRE);\r
+        if (dialog.ShowModal() == wxID_OK)\r
+            cTempSelected->setAlias(dialog.GetValue());\r
+        cTempSelected=NULL;\r
+        this->Refresh();\r
+    }\r
+}\r
+\r
+\r
+void gqbView::onDoubleClick(wxMouseEvent& event)\r
+{\r
+    // GQB-TODO: Validate Alias\r
+    gqbObject *anySelected=NULL;\r
+    wxPoint pdc=event.GetPosition();\r
+    pdc.x=event.GetPosition().x;\r
+    pdc.y=event.GetPosition().y;\r
+    this->CalcUnscrolledPosition(pdc.x,pdc.y,&pdc.x,&pdc.y);\r
+\r
+    anySelected=controller->getModelSelected(pdc,cTempSelected, jTempSelected, false);\r
+    if(anySelected)\r
+    {\r
+        if(anySelected->getType()==_gqbQueryObj)\r
+        {\r
+            gqbQueryObject *t = (gqbQueryObject *) (gqbObjectCollection *) anySelected;\r
+\r
+            // Because a bug that scrolled automatically the panel of the view if this dialog is called, then assign\r
+            // as his parent the main container of the view, and void the bug\r
+            wxTextEntryDialog dialog(controller->getDialogParent(),\r
+                wxT("Enter an Alias for table ")+t->getName()+wxT(" without white spaces"),\r
+                wxT("Please enter an Alias for table, e.g. for table Customers may be ctr"),\r
+                wxT(""),\r
+                wxOK | wxCANCEL| wxCENTRE);\r
+            if (dialog.ShowModal() == wxID_OK)\r
+                t->setAlias(dialog.GetValue());\r
+        }\r
+        else if(anySelected->getType()==_gqbJoin)\r
+        {\r
+            gqbQueryJoin *j = (gqbQueryJoin *) anySelected;\r
+            wxSingleChoiceDialog dialog(controller->getDialogParent(),\r
+                wxT("Select the kind of Join"),\r
+                wxT("Please select a type of Join for relation, e.g. = "),\r
+                joinTypeChoices,\r
+                NULL,\r
+                wxOK | wxCANCEL| wxCENTRE);\r
+            dialog.SetSelection(0);\r
+            if (dialog.ShowModal() == wxID_OK)\r
+            {\r
+                if(dialog.GetStringSelection().Contains(wxT(" = ")))\r
+                {\r
+                    j->setKindofJoin(_equally);\r
+                }\r
+                else if(dialog.GetStringSelection().Contains(wxT(" > ")))\r
+                {\r
+                    j->setKindofJoin(_greater);\r
+                }\r
+                else if(dialog.GetStringSelection().Contains(wxT(" < ")))\r
+                {\r
+                    j->setKindofJoin(_lesser);\r
+                }\r
+                else if(dialog.GetStringSelection().Contains(wxT(" >= ")))\r
+                {\r
+                    j->setKindofJoin(_equgreater);\r
+                }\r
+                else if(dialog.GetStringSelection().Contains(wxT(" <= ")))\r
+                {\r
+                    j->setKindofJoin(_equlesser);\r
+                }\r
+            }\r
+        }\r
+    }\r
+    this->Refresh();\r
+}\r
+\r
+\r
+// Manages user input [Mouse click, drag & drop] over the Canvas\r
+void gqbView::onMotion(wxMouseEvent& event)\r
+{\r
+    static int refresh=1;                         // refresh counter, everytime this values reaches \r
+                                                     // "refreshRate" value then Refresh while dragging\r
+    // Discover area where event ocurrs\r
+    pos.x=event.GetPosition().x;\r
+    pos.y=event.GetPosition().y;\r
+    this->CalcUnscrolledPosition(pos.x,pos.y,&pos.x,&pos.y);\r
+    gqbObject *anySelected=NULL;\r
+\r
+    // Button Down Event is triggered\r
+    if(event.ButtonDown()&& !changeTOpressed)\r
+    {\r
+        this->SetFocus();\r
+\r
+        // Which kind of button down was? join creation [click on any column at the \r
+               // right of checkbox and drag & drop] or table moving [click on title and drag & drop]\r
+        anySelected=controller->getModelSelected(pos,collectionSelected, joinSelected, false);\r
+        if(anySelected)\r
+        {\r
+            // Anything before just forget about it\r
+            changeTOpressed=false;\r
+            joinSource=NULL;\r
+            joinSCol=NULL;\r
+            joinDCol=NULL;\r
+            joinDest=NULL;\r
+            jpos.x=0;\r
+            jpos.y=0;\r
+\r
+            if(anySelected->getType()==_gqbQueryObj)\r
+            {\r
+                gqbQueryObject* t = (gqbQueryObject *) (gqbObjectCollection *) anySelected;\r
+\r
+                // If click on the title area AND don't click on the columns selection checkbox\r
+                if( (pos.y-t->position.y <= graphBehavior->getTitleRowHeight()))\r
+                    controller->setPointerMode(pt_normal);\r
+                else\r
+                if(pos.x - t->position.x <= 17)\r
+                    controller->setPointerMode(pt_normal);\r
+                else\r
+                    controller->setPointerMode(pt_join);\r
+            }\r
+        }\r
+        else\r
+        {\r
+            anySelected=false;\r
+            mode=pt_normal;\r
+        }\r
+\r
+        if(mode==pt_normal)                       // pointer is used to move tables & select/unselect columns\r
+        {\r
+            // getSelected Item [Mark it as selected if possible]\r
+            anySelected=controller->getModelSelected(pos,collectionSelected, joinSelected, true);\r
+            changeTOpressed=true;\r
+\r
+            // Do conversion of type object if any found\r
+            if(anySelected)\r
+            {\r
+                if(anySelected->getType()==_gqbQueryObj)\r
+                {\r
+                    collectionSelected = (gqbQueryObject *) (gqbObjectCollection *) anySelected;\r
+                    joinSelected = NULL;\r
+                }\r
+                else if(anySelected->getType()==_gqbJoin)\r
+                {\r
+                    joinSelected = (gqbQueryJoin *) anySelected;\r
+                    collectionSelected = NULL;\r
+                }\r
+            }\r
+            else\r
+            {\r
+                collectionSelected = NULL;\r
+                joinSelected = NULL;\r
+            }\r
+\r
+            if(!collectionSelected)               \r
+            {\r
+                               // none selected temp unselect all items\r
+                controller->unsetModelSelected(true);\r
+            }\r
+            else\r
+            {\r
+                gqbColumn *col=graphBehavior->getColumnAtPosition(&pos,collectionSelected);\r
+                if(col)\r
+                {   \r
+                                       // Add or remove column from model & observers (ex: Grid) (projection part of SQL sentence)\r
+                    controller->processColumnInModel(collectionSelected,col,gridTable);\r
+                }\r
+            }\r
+\r
+            if(!joinSelected)\r
+            {\r
+                controller->unsetModelSelected(false);\r
+            }\r
+\r
+        }   \r
+               // Pointer is used to add joins\r
+        else if(mode==pt_join)\r
+        {\r
+            anySelected=controller->getModelSelected(pos,collectionSelected, joinSelected, false);\r
+\r
+            // Even if I get an object check that it isn't a join\r
+            if( (anySelected) && anySelected->getType()==_gqbQueryObj)\r
+                joinSource = (gqbQueryObject *)(gqbObjectCollection *) anySelected;\r
+            else\r
+                joinSource = NULL;\r
+\r
+            if(!joinSource)               \r
+            {\r
+                               // creation of join starts\r
+                joinSCol=NULL;\r
+                joinDCol=NULL;\r
+                jpos.x=0;\r
+                jpos.y=0;\r
+            }\r
+            else\r
+            {\r
+                joinSCol=graphBehavior->getColumnAtPosition(&pos,joinSource,joinSource->getWidth());\r
+                jpos=pos;\r
+\r
+                // GQB-TODO then draw line between column & pointer\r
+            }\r
+        }\r
+\r
+        this->Refresh();\r
+    }\r
+\r
+    // Button Up Event is triggered\r
+    if(event.ButtonUp())\r
+    {\r
+               // Pointer is used to move tables & select/unselect columns\r
+               if(mode==pt_normal)\r
+        {\r
+            changeTOpressed=false;\r
+        }                                         \r
+        // Pointer is used to add joins\r
+               else if(mode==pt_join)\r
+        {\r
+            anySelected=controller->getModelSelected(pos,collectionSelected, joinSelected, false);\r
+\r
+            // Even if I get an object check that it isn't a join\r
+            if( (anySelected) && anySelected->getType()==_gqbQueryObj)\r
+            {\r
+                joinDest = (gqbQueryObject *)(gqbObjectCollection *) anySelected;\r
+                // Validate not self joins [in this version tables can be duplicated to create same effect]\r
+                if(joinDest==joinSource)\r
+                {\r
+                    joinDest=NULL;\r
+                }\r
+            }else\r
+            joinDest = NULL;\r
+\r
+                       // Creation of join starts\r
+            if(!joinDest)                         \r
+            {\r
+                joinSource=NULL;\r
+                joinSCol=NULL;\r
+                joinDCol=NULL;\r
+                joinDest=NULL;\r
+                jpos.x=0;\r
+                jpos.y=0;\r
+            }\r
+            else\r
+            {\r
+                joinDCol=graphBehavior->getColumnAtPosition(&pos,joinDest,joinDest->getWidth());\r
+                if(joinDCol)\r
+                {\r
+                    // GQB-TODO: Allow other type of joins\r
+                    gqbQueryJoin *qj=controller->addJoin(joinSource,joinSCol,joinDest,joinDCol,_equally);\r
+                    graphBehavior->calcAnchorPoint(qj);\r
+                }\r
+                // Let the temporary join line to be draw again [Don't destroy anything because all object where own by other objects this are just pointers]\r
+                joinSource=NULL;\r
+                joinSCol=NULL;\r
+                joinDest=NULL;\r
+                joinDCol=NULL;\r
+                jpos.x=0;\r
+                jpos.y=0;\r
+            }\r
+        }\r
+\r
+        controller->setPointerMode(pt_normal);    //when button is up, pointer mode should be only normal\r
+        this->Refresh();\r
+    }\r
+\r
+    // Mouse is Dragged while mouse button is down\r
+    if (event.Dragging()&&pressed)\r
+    {\r
+        if(mode==pt_normal)\r
+        {\r
+            if(collectionSelected)\r
+            {\r
+                // GQB-TODO: same as gqbGraphBehavior.h [find a way to not hard code the 17 default value]\r
+                if((pos.x > collectionSelected->position.x+17) || (pos.x < collectionSelected->position.x) )\r
+                {\r
+                    graphBehavior->UpdatePosObject(collectionSelected,pos.x,pos.y,40);\r
+                }\r
+\r
+                // Don't draw too much when dragging table around canvas [lower cpu use]\r
+                               if(refresh%refreshRate==0)\r
+                {\r
+                    this->Refresh();\r
+                    refresh=1;\r
+                }else\r
+                refresh++;\r
+\r
+            }\r
+        }\r
+        else if(mode==pt_join)\r
+        {\r
+            if(joinSource && !joinDest)\r
+            {\r
+                this->Refresh();\r
+            }\r
+\r
+        }\r
+    }\r
+}\r
+\r
+\r
+void gqbView::OnKeyDown(wxKeyEvent& event)\r
+{\r
+    if(event.GetKeyCode() == WXK_DELETE)\r
+    {\r
+        if(collectionSelected)\r
+        {\r
+            controller->removeTableFromModel(collectionSelected,gridTable,orderByLGridTable,orderByRGridTable);\r
+            collectionSelected=NULL;\r
+            this->Refresh();\r
+        }\r
+\r
+        if(joinSelected)\r
+        {\r
+            controller->removeJoin(joinSelected);\r
+            joinSelected=NULL;\r
+            this->Refresh();\r
+        }\r
+    }\r
+}\r
+\r
+\r
+void gqbView::drawAll(wxBufferedDC& bdc)\r
+{\r
+    bdc.Clear();\r
+    if(!iterator)\r
+        // Get an iterator for the objects (tables/views) in the model.\r
+        iterator = this->model->createQueryIterator();\r
+    else\r
+        iterator->ResetIterator();\r
+\r
+    // First Draw Tables\r
+    while(iterator->HasNext())\r
+    {\r
+        gqbQueryObject *tmp= (gqbQueryObject *)iterator->Next();\r
+        wxPoint pt = wxPoint(tmp->position);      // Use a copy because I don't want to store the modified \r
+                                                         // version of point after CalcScrolledPosition was called\r
+\r
+               // adjust coordinates\r
+        this->CalcScrolledPosition(pt.x,pt.y,&pt.x,&pt.y);\r
+        graphBehavior->drawTable(bdc,&pt,tmp);    // graph table\r
+    }\r
+\r
+    // Later Draw Joins over Tables\r
+    iterator->ResetIterator();\r
+    while(iterator->HasNext())\r
+    {\r
+        gqbQueryObject *tmp= (gqbQueryObject *)iterator->Next();\r
+\r
+        if(tmp->getHaveJoins())\r
+        {\r
+            gqbIteratorBase *joinsIterator = tmp->createJoinsIterator();\r
+            while(joinsIterator->HasNext())\r
+            {\r
+                gqbQueryJoin *join = (gqbQueryJoin *) joinsIterator->Next();\r
+                wxPoint o = join->getSourceAnchor();\r
+                wxPoint d = join->getDestAnchor();\r
+                // adjust coordinates origin\r
+                this->CalcScrolledPosition(o.x,o.y,&o.x,&o.y);\r
+                // adjust coordinates destination\r
+                this->CalcScrolledPosition(d.x,d.y,&d.x,&d.y);\r
+                graphBehavior->drawJoin(bdc,o,d,join->getAnchorsUsed(), join->getSelected(), join->getKindofJoin());\r
+            }\r
+            delete joinsIterator;\r
+        }\r
+\r
+    }\r
+\r
+    // This iterator is delete at destroyer for reuse purposes\r
+    if(joinSource)\r
+    {\r
+        // Draw temporary line while creating a join\r
+        wxPoint source=jpos;\r
+        wxPoint destination=pos;\r
+        this->CalcScrolledPosition(source.x,source.y,&source.x,&source.y);\r
+        this->CalcScrolledPosition(destination.x,destination.y,&destination.x,&destination.y);\r
+        graphBehavior->drawTempJoinLine(bdc,source,destination);\r
+    }\r
+}\r
+\r
+\r
+void gqbView::setPointerMode(pointerMode pm)\r
+{\r
+    mode=pm;\r
+    if(mode==pt_join)\r
+        this->SetCursor(joinCursor);\r
+    else\r
+        this->SetCursor(wxNullCursor);\r
+}\r
+\r
+\r
+bool gqbView::clickOnJoin (gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest)\r
+{\r
+    return graphBehavior->clickOnJoin(join,pt,origin,dest);\r
+}\r
+\r
+\r
+void gqbView::emptyPanelsData()\r
+{\r
+    gridTable->emptyTableData();\r
+}\r
+\r
+\r
+void gqbView::newTableAdded(gqbQueryObject *item)\r
+{\r
+    // Refresh Order By Panel's Left Grid\r
+    if (orderByLGridTable->GetView() )\r
+    {\r
+        wxGridTableMessage msg( orderByLGridTable,\r
+            wxGRIDTABLE_NOTIFY_ROWS_INSERTED,\r
+            orderByLGridTable->GetNumberRows()-1,\r
+            item->parent->countCols() );\r
+        orderByLGridTable->GetView()->ProcessTableMessage( msg );\r
+    }\r
+}\r
diff --git a/pgadmin/gqb/gqbViewPanels.cpp b/pgadmin/gqb/gqbViewPanels.cpp
new file mode 100644 (file)
index 0000000..36ecd91
--- /dev/null
@@ -0,0 +1,1256 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbViewPanels.cpp - All panels used by GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+// App headers\r
+#include "pgAdmin3.h"\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+#include <wx/minifram.h>\r
+#include <wx/generic/gridctrl.h>\r
+#include <wx/notebook.h>\r
+#include <wx/imaglist.h>\r
+#include <wx/listctrl.h>\r
+\r
+// App headers\r
+#include "gqb/gqbViewPanels.h"\r
+#include "gqb/gqbGridProjTable.h"\r
+#include "gqb/gqbGridRestTable.h"\r
+#include "gqb/gqbGridOrderTable.h"\r
+\r
+// Images\r
+#include "images/gqbUp.xpm"\r
+#include "images/gqbUpTop.xpm"\r
+#include "images/gqbDown.xpm"\r
+#include "images/gqbDownBottom.xpm"\r
+#include "images/gqbOrderAddAll.xpm"\r
+#include "images/gqbOrderRemoveAll.xpm"\r
+#include "images/gqbOrderRemove.xpm"\r
+#include "images/gqbOrderAdd.xpm"\r
+#include "images/gqbAddRest.xpm"\r
+#include "images/gqbRemoveRest.xpm"\r
+#include "images/tables.xpm"\r
+#include "images/table-sm.xpm"\r
+#include "images/column-sm.xpm"\r
+\r
+//\r
+//    View Columns Grid Panel Class.\r
+//\r
+\r
+BEGIN_EVENT_TABLE(gqbGridPanel, wxPanel)\r
+EVT_GRID_SELECT_CELL(gqbGridPanel::OnGridSelectCell)\r
+EVT_GRID_RANGE_SELECT(gqbGridPanel::OnGridRangeSelected)\r
+EVT_BUTTON(buttonUp_ID, gqbGridPanel::OnButtonUp)\r
+EVT_BUTTON(buttonUpTop_ID, gqbGridPanel::OnButtonUpTop)\r
+EVT_BUTTON(buttonDown_ID, gqbGridPanel::OnButtonDown)\r
+EVT_BUTTON(buttonDownBottom_ID, gqbGridPanel::OnButtonDownBottom)\r
+END_EVENT_TABLE()\r
+\r
+gqbGridPanel::gqbGridPanel(wxWindow* parent, wxWindowID id = wxID_ANY, gqbGridProjTable *gridModel=NULL):\r
+wxPanel(parent,-1)\r
+{\r
+    gModel=gridModel;\r
+    allowSelCells=true;\r
+    selTop=-1;\r
+    selBottom=-1;\r
+    upBitmap = wxBitmap(gqbUp_xpm);\r
+    upTopBitmap = wxBitmap(gqbUpTop_xpm);\r
+    downBitmap = wxBitmap(gqbDown_xpm);\r
+    downBottomBitmap = wxBitmap(gqbDownBottom_xpm);\r
+\r
+    buttonUp = new wxBitmapButton( this, buttonUp_ID,  upBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Column(s) Up") );\r
+    buttonUpTop  = new wxBitmapButton( this, buttonUpTop_ID,  upTopBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Column(s) Up") );\r
+    buttonDown = new wxBitmapButton( this, buttonDown_ID,  downBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Column(s) Up") );\r
+    buttonDownBottom = new wxBitmapButton( this, buttonDownBottom_ID,  downBottomBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Column(s) Up") );\r
+\r
+    this->colsGrid = new wxGrid(this, -1, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_BESTWRAP ,wxT(""));\r
+    colsGrid->SetTable(gModel,true,wxGrid::wxGridSelectCells);\r
+\r
+    // Adjust the default row height to be more compact\r
+    wxFont font = colsGrid->GetLabelFont();\r
+    int nWidth = 0;\r
+    int nHeight = 18;\r
+    colsGrid->GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font);\r
+    colsGrid->SetColLabelSize(nHeight+6);\r
+       colsGrid->SetRowLabelSize(35);\r
+#ifdef __WXGTK__\r
+    colsGrid->SetDefaultRowSize(nHeight+8, TRUE);\r
+#else\r
+    colsGrid->SetDefaultRowSize(nHeight+4, TRUE);\r
+#endif\r
+\r
+    wxBoxSizer *horizontalSizer = new wxBoxSizer( wxHORIZONTAL );\r
+    horizontalSizer->Add(colsGrid,\r
+        1,                                        // make vertically stretchable\r
+        wxEXPAND |                                // make horizontally stretchable\r
+        wxALL,                                    //   and make border all around\r
+        3 );                                      // set border width to 10\r
+\r
+    wxBoxSizer *buttonsSizer = new wxBoxSizer( wxVERTICAL );\r
+\r
+    buttonsSizer->Add(\r
+        this->buttonUpTop,\r
+        0,                                        // make horizontally unstretchable\r
+        wxALL,                                    // make border all around (implicit top alignment)\r
+        3 );                                      // set border width to 10\r
+\r
+    buttonsSizer->Add(\r
+        this->buttonUp,\r
+        0,                                        // make horizontally unstretchable\r
+        wxALL,                                    // make border all around (implicit top alignment)\r
+        3 );                                      // set border width to 10\r
+\r
+    buttonsSizer->Add(\r
+        this->buttonDown,\r
+        0,                                        // make horizontally unstretchable\r
+        wxALL,                                    // make border all around (implicit top alignment)\r
+        3 );                                      // set border width to 10\r
+\r
+    buttonsSizer->Add(\r
+        this->buttonDownBottom,\r
+        0,                                        // make horizontally unstretchable\r
+        wxALL,                                    // make border all around (implicit top alignment)\r
+        3 );                                      // set border width to 10\r
+\r
+    horizontalSizer->Add(\r
+        buttonsSizer,\r
+        0,                                        // make vertically unstretchable\r
+        wxALIGN_CENTER );                         // no border and centre horizontally\r
+\r
+    this->SetSizer(horizontalSizer);\r
+}\r
+\r
+\r
+gqbGridPanel::~gqbGridPanel()\r
+{\r
+    if (buttonUp)\r
+        delete buttonUp;\r
+    if(buttonDown)\r
+        delete buttonDown;\r
+    if(buttonUpTop)\r
+        delete buttonUpTop;\r
+    if(buttonDownBottom)\r
+        delete buttonDownBottom;\r
+}\r
+\r
+\r
+void gqbGridPanel::SetGridColsSize()\r
+{\r
+    // After sizers determine the width of Grid then calculate the % space for each column about 33% each one\r
+    int size=(colsGrid->GetSize().GetWidth() - colsGrid->GetRowLabelSize())*0.30;\r
+    colsGrid->SetColSize(0,size);\r
+    colsGrid->SetColSize(1,size);\r
+    colsGrid->SetColSize(2,size);\r
+}\r
+\r
+\r
+void gqbGridPanel::OnGridSelectCell( wxGridEvent& ev )\r
+{\r
+    if(allowSelCells)\r
+    {\r
+        if ( ev.Selecting() )\r
+        {\r
+            selTop=ev.GetRow();\r
+            selBottom=-1;\r
+        }\r
+        else\r
+        {\r
+            selTop=-1;\r
+            selBottom=-1;\r
+        }\r
+    }\r
+    ev.Skip();\r
+}\r
+\r
+\r
+void gqbGridPanel::OnGridRangeSelected( wxGridRangeSelectEvent& ev )\r
+{\r
+    if(allowSelCells)\r
+    {\r
+        if ( ev.Selecting() )\r
+        {\r
+            selTop=ev.GetTopRow();\r
+            selBottom=ev.GetBottomRow();\r
+        }\r
+        else\r
+        {\r
+            selTop=-1;\r
+            selBottom=-1;\r
+        }\r
+    }\r
+    ev.Skip();\r
+}\r
+\r
+\r
+void gqbGridPanel::OnButtonUp(wxCommandEvent&)\r
+{\r
+    // A single row is selected\r
+    allowSelCells=false;\r
+    if((selTop>=0 && selBottom==-1) || (selTop==selBottom))\r
+    {\r
+        gModel->changesPositions(selTop,selTop--);\r
+        if(selTop<0)\r
+        {\r
+            selTop=0;\r
+        }\r
+        colsGrid->SelectBlock(selTop,0,selTop,1,false);\r
+        colsGrid->SetGridCursor(selTop,0);\r
+        selBottom=-1;\r
+    }\r
+    else\r
+    {\r
+        // A range of rows is selected\r
+        if (selTop>=0 && selBottom>=0)\r
+        {\r
+            int newTop=selTop-1;\r
+            gModel->changesRangeOnePos(selTop,selBottom,newTop);\r
+            if(selTop > 0)                        // recalculate new selection area & avoid bad selection area\r
+            {\r
+                selTop--;\r
+                selBottom--;\r
+            }\r
+            colsGrid->SelectBlock(selTop,0,selBottom,1,false);\r
+            colsGrid->SetGridCursor(selTop,0);\r
+        }\r
+    }\r
+    allowSelCells=true;\r
+}\r
+\r
+\r
+void gqbGridPanel::OnButtonUpTop(wxCommandEvent&)\r
+{\r
+    allowSelCells=false;\r
+    \r
+       // A Single Row is selected\r
+    if((selTop>=0 && selBottom==-1) || (selTop==selBottom))\r
+    {\r
+        selBottom=selTop-1;\r
+        selTop=0;\r
+        gModel->changesRangeOnePos(selTop,selBottom,1);\r
+        colsGrid->SelectBlock(0,0,0,1,false);\r
+        colsGrid->SetGridCursor(0,0);\r
+\r
+        // Put variables in correct values now.\r
+        selTop=0;\r
+        selBottom=-1;\r
+    }   \r
+       // A range of rows is selected\r
+    else\r
+    {\r
+        int newTop=0;\r
+        if (selTop>=0 && selBottom>=0)\r
+        {\r
+            // Move all range only one pos the require times to get the top\r
+                       for(int i=selTop;i>0;i--)\r
+            {\r
+                newTop=selTop-1;\r
+                gModel->changesRangeOnePos(selTop,selBottom,newTop);\r
+\r
+                // Recalculate new selection area & avoid bad selection area\r
+                               if(selTop > 0)\r
+                {\r
+                    selTop--;\r
+                    selBottom--;\r
+                }\r
+                colsGrid->SelectBlock(selTop,0,selBottom,1,false);\r
+                colsGrid->SetGridCursor(selTop,0);\r
+            }\r
+        }\r
+    }\r
+    allowSelCells=true;\r
+}\r
+\r
+\r
+void gqbGridPanel::OnButtonDown(wxCommandEvent&)\r
+{\r
+\r
+    allowSelCells=false;\r
+\r
+    // A single row is selected\r
+    if((selTop>=0 && selBottom==-1) || (selTop==selBottom))\r
+    {\r
+        gModel->changesPositions(selTop,selTop++);\r
+\r
+        // Adjust selection when selected item it's last item.\r
+               if(selTop==gModel->GetNumberRows())\r
+        {\r
+            selTop--;\r
+        }\r
+        colsGrid->SelectBlock(selTop,0,selTop,1,false);\r
+        colsGrid->SetGridCursor(selTop,0);\r
+        selBottom=-1;\r
+    }       \r
+       // A range of rows is selected\r
+    else\r
+    {\r
+        if (selTop>=0 && selBottom>=0)\r
+        {\r
+            int newTop=selTop+1;\r
+            gModel->changesRangeOnePos(selTop,selBottom,newTop);\r
+\r
+            // Recalculate new selection area & avoid bad selection area\r
+            if(selBottom < gModel->GetNumberRows()-1)\r
+            {\r
+                selTop++;\r
+                selBottom++;\r
+            }\r
+            colsGrid->SelectBlock(selTop,0,selBottom,1,false);\r
+            colsGrid->SetGridCursor(selTop,0);\r
+        }\r
+    }\r
+    allowSelCells=true;\r
+}\r
+\r
+\r
+void gqbGridPanel::OnButtonDownBottom(wxCommandEvent&)\r
+{\r
+    allowSelCells=false;\r
+\r
+    // A Single Row is selected\r
+    if((selTop>=0 && selBottom==-1) || (selTop==selBottom))\r
+    {\r
+        selBottom=gModel->GetNumberRows()-1;\r
+        selTop=selTop+1;\r
+        int newBottom=gModel->GetNumberRows()-1;\r
+        gModel->changesRangeOnePos(selTop,selBottom,selTop-1);\r
+        colsGrid->SelectBlock(newBottom,0,newBottom,1,false);\r
+        colsGrid->SetGridCursor(newBottom,0);\r
+\r
+               // Put variables in correct values now.\r
+        selTop=newBottom;\r
+        selBottom=-1;\r
+    }  \r
+       // A range of rows is selected\r
+    else\r
+    {\r
+        int newTop=0, size=gModel->GetNumberRows();\r
+\r
+        if (selTop>=0 && selBottom>=0)\r
+        {\r
+            for(int i=selBottom;i<size;i++)\r
+            {\r
+                newTop=selTop+1;\r
+                gModel->changesRangeOnePos(selTop,selBottom,newTop);\r
+\r
+                // Recalculate new selection area & avoid bad selection area\r
+                if(selBottom < gModel->GetNumberRows()-1)\r
+                {\r
+                    selTop++;\r
+                    selBottom++;\r
+                }\r
+                colsGrid->SelectBlock(selTop,0,selBottom,1,false);\r
+                colsGrid->SetGridCursor(selTop,0);\r
+            }\r
+        }\r
+    }\r
+    allowSelCells=true;\r
+}\r
+\r
+\r
+//\r
+//    Tree with Columns & tables inside a query model\r
+//\r
+\r
+gqbColsTree::gqbColsTree(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)\r
+: wxTreeCtrl(parent, id, pos, size, style)\r
+{\r
+    wxImageList *imageList = new wxImageList(16, 16);\r
+    imageList->Add(wxIcon(tables_xpm));\r
+    imageList->Add(wxIcon(table_sm_xpm));\r
+    imageList->Add(wxIcon(column_sm_xpm));\r
+    this->AssignImageList(imageList);\r
+    wxString a=wxT("Select Column");\r
+    createRoot(a);\r
+    this->Expand(rootNode);\r
+}\r
+\r
+\r
+// Create root node\r
+wxTreeItemId& gqbColsTree::createRoot(wxString &Name)\r
+{\r
+    rootNode=this->AddRoot(Name,0,0);\r
+    return rootNode;\r
+}\r
+\r
+\r
+void gqbColsTree::refreshTree(gqbModel * model)\r
+{\r
+    // This remove and delete data inside tree's node\r
+       this->DeleteAllItems();                       \r
+    wxString a=wxT("Select Column");\r
+    createRoot(a);\r
+    this->Expand(rootNode);\r
+\r
+    wxTreeItemId parent;\r
+    gqbIteratorBase *iterator = model->createQueryIterator();\r
+    while(iterator->HasNext())\r
+    {\r
+        gqbQueryObject *tmpTable= (gqbQueryObject *)iterator->Next();\r
+        if(tmpTable->getAlias().length()>0)\r
+        {\r
+            parent=this->AppendItem(rootNode, tmpTable->getAlias() , 1, 1,NULL);\r
+        }\r
+        else\r
+        {\r
+            parent=this->AppendItem(rootNode, tmpTable->getName() , 1, 1,NULL);\r
+        }\r
+        gqbIteratorBase *colsIterator = tmpTable->parent->createColumnsIterator();\r
+        while(colsIterator->HasNext())\r
+        {\r
+            gqbColumn *tmpColumn= (gqbColumn *)colsIterator->Next();\r
+            this->AppendItem(parent, tmpColumn->getName() , 2, 2,NULL);\r
+        }\r
+        delete colsIterator;\r
+    }\r
+    delete iterator;\r
+\r
+    if(rootNode)\r
+        this->Expand(rootNode);\r
+}\r
+\r
+\r
+//\r
+//    Popup Window for gqbColsTree\r
+//\r
+\r
+gqbColsPopUp::gqbColsPopUp(wxWindow* parent, wxWindowID id, wxString title, wxPoint pos, const wxSize size):\r
+wxDialog(parent, id, title, pos, size, wxRESIZE_BORDER | wxCAPTION)\r
+{\r
+    this->SetSize(wxSize(243,165));\r
+       wxBoxSizer *hSizer = new wxBoxSizer(wxHORIZONTAL);\r
+       wxBoxSizer *vSizer = new wxBoxSizer(wxVERTICAL);\r
+\r
+    editTree = new wxTextCtrl(this, QR_TREE, wxT(""),wxPoint(5,5),wxSize(193,22));\r
+    editTree->AcceptsFocus();\r
+    editTree->SetFocus();\r
+    editTree->SetEditable(true);\r
+\r
+       hSizer->Add(editTree, 1, wxEXPAND | wxRIGHT, 3);\r
+\r
+    buttonTree= new wxButton(this, QR_TREE_OK, _("OK") ,wxPoint(199,5), wxDefaultSize, wxBU_EXACTFIT);\r
+    this->Connect(QR_TREE_OK, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &gqbColsPopUp::OnPopUpOKClick);\r
+\r
+       hSizer->Add(buttonTree);\r
+       vSizer->Add(hSizer, 0, wxEXPAND | wxALL, 3);\r
+\r
+    colsTree = new gqbColsTree(this, QR_TREE, wxPoint(5,31),  wxSize(224,104), wxTR_HAS_BUTTONS | wxSIMPLE_BORDER | wxTR_SINGLE);\r
+    this->Connect(QR_TREE, wxEVT_COMMAND_TREE_ITEM_ACTIVATED, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) &gqbColsPopUp::OnPopUpTreeDoubleClick);\r
+    this->Connect(QR_TREE, wxEVT_COMMAND_TREE_SEL_CHANGED, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) &gqbColsPopUp::OnPopUpTreeClick);\r
+\r
+       vSizer->Add(colsTree, 1, wxEXPAND | wxALL, 3);\r
+       SetSizer(vSizer);\r
+}\r
+\r
+\r
+void gqbColsPopUp::refreshTree(gqbModel *_model)\r
+{\r
+    model=_model;\r
+    if(colsTree && _model)\r
+    {\r
+        colsTree->refreshTree(model);\r
+    }\r
+\r
+}\r
+\r
+\r
+void  gqbColsPopUp::OnPopUpOKClick(wxCommandEvent& event)\r
+{\r
+    this->usedGrid->SetCellValue(_row,_col,this->getEditText());\r
+    this->MakeModal(false);\r
+    this->Hide();\r
+    this->GetParent()->Refresh();\r
+}\r
+\r
+\r
+void  gqbColsPopUp::OnPopUpTreeDoubleClick(wxTreeEvent& event)\r
+{\r
+    if(colsTree)\r
+    {\r
+        wxTreeItemId itemId = event.GetItem();\r
+        wxTreeItemId itemIdParent =  colsTree->GetItemParent(itemId);\r
+        if(!colsTree->ItemHasChildren(itemId) && (colsTree->GetRootItem()!=itemId))\r
+        {\r
+            this->usedGrid->SetCellValue(_row,_col,this->getEditText());\r
+            if(this->usedGrid->GetCellValue(_row,_col).length()<=0)\r
+            {\r
+                this->usedGrid->SetCellValue(_row,_col,wxT("Set Value"));\r
+            }\r
+            this->MakeModal(false);\r
+            this->Hide();\r
+            this->GetParent()->Refresh();\r
+        }\r
+    }\r
+}\r
+\r
+void  gqbColsPopUp::OnPopUpTreeClick(wxTreeEvent& event)\r
+{\r
+    if(colsTree)\r
+    {\r
+        wxTreeItemId itemId = event.GetItem();\r
+        wxTreeItemId itemIdParent =  colsTree->GetItemParent(itemId);\r
+\r
+        if(!colsTree->ItemHasChildren(itemId) && (colsTree->GetRootItem()!=itemId))\r
+        {\r
+            this->editTree->SetValue(qtIdent(colsTree->GetItemText(itemIdParent)) + wxT(".") + qtIdent(colsTree->GetItemText(itemId)));\r
+        }\r
+    }\r
+}\r
+\r
+\r
+void gqbColsPopUp::setEditText(wxString text)\r
+{\r
+    this->editTree->SetValue(text);\r
+}\r
+\r
+\r
+void gqbColsPopUp::focus()\r
+{\r
+    this->editTree->SetFocus();\r
+    this->editTree->SetSelection(-1,-1);\r
+}\r
+\r
+\r
+//\r
+//    View Selection Criteria Panel Class.\r
+//\r
+\r
+BEGIN_EVENT_TABLE(gqbCriteriaPanel, wxPanel)\r
+EVT_BUTTON(addButton_ID, gqbCriteriaPanel::OnButtonAdd)\r
+EVT_BUTTON(dropButton_ID, gqbCriteriaPanel::OnButtonDrop)\r
+END_EVENT_TABLE()\r
+\r
+gqbCriteriaPanel::gqbCriteriaPanel(wxWindow* parent, gqbModel *_model, gqbGridRestTable *gridModel):\r
+wxPanel(parent,-1)\r
+{\r
+    model=_model;\r
+    gModel=gridModel;\r
+    colsPopUp=NULL;\r
+\r
+    // GQB-TODO: add real ID not 321\r
+    // wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_DONTWRAP,wxT(""));\r
+    this->restrictionsGrid = new wxRestrictionGrid(this, 321);\r
+    restrictionsGrid->SetTable(gModel, true, wxGrid::wxGridSelectCells);\r
+    this->restrictionsGrid->SetSelectionMode(wxGrid::wxGridSelectRows);\r
+\r
+    this->Connect(321, wxEVT_GRID_CELL_LEFT_CLICK, (wxObjectEventFunction) (wxEventFunction) (wxGridEventFunction) &gqbCriteriaPanel::OnCellLeftClick);\r
+    // GQB-TODO: in a future implement OnMouseWheel\r
+\r
+    addBitmap= wxBitmap(gqbAddRest_xpm);\r
+    dropBitmap= wxBitmap(gqbRemoveRest_xpm);\r
+    buttonAdd= new wxBitmapButton( this, addButton_ID,  addBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add"));\r
+    buttonDrop= new wxBitmapButton( this, dropButton_ID,  dropBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove"));\r
+\r
+    wxBoxSizer *horizontalSizer = new wxBoxSizer( wxHORIZONTAL );\r
+    horizontalSizer->Add(restrictionsGrid,\r
+        1,                                        // make vertically stretchable\r
+        wxEXPAND |                                // make horizontally stretchable\r
+        wxALL,                                    //   and make border all around\r
+        3 );                                     // set border width to 10\r
+\r
+    wxBoxSizer *buttonsSizer = new wxBoxSizer( wxVERTICAL );\r
+\r
+    buttonsSizer->Add(\r
+        this->buttonAdd,\r
+        0,                                        // make horizontally unstretchable\r
+        wxALL,                                    // make border all around (implicit top alignment)\r
+        10 );                                     // set border width to 10\r
+\r
+    buttonsSizer->Add(\r
+        this->buttonDrop,\r
+        0,                                        // make horizontally unstretchable\r
+        wxALL,                                    // make border all around (implicit top alignment)\r
+        10 );                                     // set border width to 10\r
+\r
+    horizontalSizer->Add(\r
+        buttonsSizer,\r
+        0,                                        // make vertically unstretchable\r
+        wxALIGN_CENTER );                         // no border and centre horizontally\r
+\r
+    this->SetSizer(horizontalSizer);\r
+}\r
+\r
+\r
+void gqbCriteriaPanel::showColsPopUp(int row, int col, wxPoint pos)\r
+{\r
+    if(!colsPopUp)\r
+    {\r
+        colsPopUp = new gqbColsPopUp(this,-1,wxT("Set Value"),wxDefaultPosition,wxDefaultSize);\r
+    }\r
+\r
+    refreshTree(model);\r
+\r
+    // Set initial Value\r
+    colsPopUp->setEditText(restrictionsGrid->GetCellValue(row,col));\r
+\r
+    // Set Position for Pop Up Tree\r
+    // Position of wxNotebook\r
+       wxPoint p=this->GetParent()->GetPosition();\r
+    p.x+=pos.x;\r
+    p.y+=pos.y;\r
+    wxPoint p2=this->GetPosition();\r
+\r
+       // Position of panel inside wxNotebook\r
+    p.x+=p2.x;\r
+    p.y+=p2.y+40;\r
+    colsPopUp->SetPosition(p);\r
+    colsPopUp->Show();\r
+    colsPopUp->MakeModal(true);\r
+    colsPopUp->focus();\r
+    colsPopUp->setUsedCell(restrictionsGrid,row,col);\r
+}\r
+\r
+\r
+void gqbCriteriaPanel::refreshTree(gqbModel *_model)\r
+{\r
+    // GQB-TODO: Do this through controller...\r
+    model=_model;\r
+    if(colsPopUp && model)\r
+        colsPopUp->refreshTree(model);\r
+\r
+}\r
+\r
+\r
+void gqbCriteriaPanel::OnCellLeftClick(wxGridEvent& event)\r
+{\r
+    wxObject *object = event.GetEventObject();\r
+    wxRestrictionGrid *grid = wxDynamicCast( object, wxRestrictionGrid );\r
+\r
+    // Only show editor y case of column 1\r
+    if(event.GetCol()==1)\r
+    {\r
+        grid->ComboBoxEvent(event);\r
+    } else if(event.GetCol()==0 || event.GetCol()==2)\r
+    {\r
+        // Allow mini browser frame to be visible to user\r
+        wxRect cellSize=grid->CellToRect(event.GetRow(), event.GetCol());\r
+        wxPoint p =event.GetPosition();\r
+        restrictionsGrid->CalcUnscrolledPosition(p.x,p.y,&p.x,&p.y);\r
+\r
+        // Number 17 is button's width at cellRender function [nButtonWidth]\r
+        if((grid->GetRowLabelSize()+cellSize.GetRight())-(p.x) <= 17 )\r
+        {\r
+            p =event.GetPosition();\r
+            showColsPopUp(event.GetRow(), event.GetCol(),p);\r
+        }\r
+    }                                             //GQB-TODO 1,2 can be integrate with 3\r
+    else if(event.GetCol()==3)\r
+    {\r
+        // Change connector of the Restriction between AND/OR\r
+        wxRect cellSize=restrictionsGrid->CellToRect(event.GetRow(), event.GetCol());\r
+        wxPoint p =event.GetPosition();\r
+        restrictionsGrid->CalcUnscrolledPosition(p.x,p.y,&p.x,&p.y);\r
+\r
+        // Number 17 is button's width at cellRender function [nButtonWidth]\r
+        if((restrictionsGrid->GetRowLabelSize()+cellSize.GetRight())-(p.x) <= 17 )\r
+        {\r
+            p =event.GetPosition();\r
+            if( gModel->GetValue(event.GetRow(),3).Contains(wxT("AND")) )\r
+            {\r
+                gModel->SetValue(event.GetRow(),3,wxT("OR"));\r
+            }\r
+            else\r
+            {\r
+                gModel->SetValue(event.GetRow(),3,wxT("AND"));\r
+            }\r
+            restrictionsGrid->Refresh();\r
+        }\r
+    }\r
+    event.Skip();\r
+}\r
+\r
+\r
+void gqbCriteriaPanel::OnButtonAdd(wxCommandEvent&)\r
+{\r
+    // GQB-TODO: use controller one\r
+    gqbQueryRestriction *r = new gqbQueryRestriction();\r
+    gModel->AppendItem(r);\r
+    int row=model->getRestrictions()->restrictionsCount()-1;\r
+\r
+    wxString strChoices[16] = {wxT("="), wxT("!="),wxT("<"),wxT("<="),wxT(">"),wxT(">="),wxT("BETWEEN"),wxT("LIKE"),wxT("NOT LIKE"),wxT("ILIKE"),wxT("NOT ILIKE"),wxT("IN"),wxT("NOT IN"),wxT("NOT BETWEEN"),wxT("IS NULL"),wxT("IS NOT NULL")};\r
+    restrictionsGrid->SetCellRenderer(row, 1, new wxGridCellComboBoxRenderer);\r
+    restrictionsGrid->SetCellRenderer(row, 0, new wxGridCellButtonRenderer);\r
+    restrictionsGrid->SetCellEditor(row, 1, new dxGridCellSizedChoiceEditor(WXSIZEOF(strChoices),strChoices));\r
+    restrictionsGrid->SetCellRenderer(row, 2, new wxGridCellButtonRenderer);\r
+    restrictionsGrid->SetCellRenderer(row, 3, new wxGridCellButtonRenderer);\r
+    restrictionsGrid->SetReadOnly(row,3,true);\r
+}\r
+\r
+\r
+void gqbCriteriaPanel::OnButtonDrop(wxCommandEvent&)\r
+{\r
+    if(restrictionsGrid->GetGridCursorRow()>=0)\r
+        gModel->DeleteRows(restrictionsGrid->GetGridCursorRow(),1);\r
+    restrictionsGrid->Refresh();\r
+}\r
+\r
+\r
+void gqbCriteriaPanel::SetGridColsSize()\r
+{\r
+    // After sizers determine the width of Grid then calculate the % space for each column about 33% each one\r
+    int size=(restrictionsGrid->GetSize().GetWidth() - restrictionsGrid->GetRowLabelSize())*0.225;\r
+    restrictionsGrid->SetColSize(0,size);\r
+    restrictionsGrid->SetColSize(1,size);\r
+    restrictionsGrid->SetColSize(2,size);\r
+    restrictionsGrid->SetColSize(3,size);\r
+}\r
+\r
+\r
+//\r
+//  View Selection Criteria Panel Class's Grid.\r
+//\r
+wxRestrictionGrid::wxRestrictionGrid(wxWindow* parent, wxWindowID id):\r
+wxGrid(parent, id, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_BESTWRAP,wxT("")),\r
+m_selTemp(NULL)\r
+{\r
+    // Adjust the default row height to be more compact\r
+    wxFont font = GetLabelFont();\r
+    int nWidth = 0;\r
+    int nHeight = 18;\r
+    GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font);\r
+    SetColLabelSize(nHeight+6);\r
+       SetRowLabelSize(35);\r
+#ifdef __WXGTK__\r
+    SetDefaultRowSize(nHeight+8, TRUE);\r
+#else\r
+    SetDefaultRowSize(nHeight+4, TRUE);\r
+#endif\r
+}\r
+\r
+\r
+void wxRestrictionGrid::RevertSel()\r
+{\r
+    if (m_selTemp)\r
+    {\r
+        wxASSERT(m_selection == NULL);\r
+        m_selection = m_selTemp;\r
+        m_selTemp = NULL;\r
+    }\r
+}\r
+\r
+\r
+void wxRestrictionGrid::ComboBoxEvent(wxGridEvent& event)\r
+{\r
+\r
+    // This forces the cell to go into edit mode directly\r
+    this->m_waitForSlowClick = TRUE;\r
+    int row=event.GetRow();\r
+    int col=event.GetCol();\r
+\r
+    this->SetGridCursor(row,col);\r
+\r
+    // Store the click co-ordinates in the editor if possible\r
+    // if an editor has created a ClientData area, we presume it's\r
+    // a wxPoint and we store the click co-ordinates\r
+    wxGridCellEditor* pEditor  = this->GetCellEditor(event.GetRow(), event.GetCol());\r
+    wxPoint* pClickPoint = (wxPoint*)pEditor->GetClientData();\r
+    if (pClickPoint)\r
+    {\r
+        *pClickPoint = this->ClientToScreen(event.GetPosition());\r
+#ifndef __WINDOWS__\r
+        EnableCellEditControl(true);\r
+#endif\r
+    }\r
+\r
+    // hack to prevent selection from being lost when click combobox\r
+    if (event.GetCol() == 0 && this->IsInSelection(event.GetRow(), event.GetCol()))\r
+    {\r
+        this->m_selTemp = this->m_selection;\r
+        this->m_selection = NULL;\r
+    }\r
+    pEditor->DecRef();\r
+}\r
+\r
+\r
+//\r
+//\r
+//   Order by Panel\r
+//\r
+//\r
+\r
+BEGIN_EVENT_TABLE(gqbOrderPanel, wxPanel)\r
+EVT_BUTTON(bRem_ID, gqbOrderPanel::OnButtonRemove)\r
+EVT_BUTTON(bRemAll_ID, gqbOrderPanel::OnButtonRemoveAll)\r
+EVT_BUTTON(bAdd_ID, gqbOrderPanel::OnButtonAdd)\r
+EVT_BUTTON(bAddAll_ID, gqbOrderPanel::OnButtonAddAll)\r
+EVT_GRID_SELECT_CELL(gqbOrderPanel::OnGridSelectCell)\r
+EVT_GRID_RANGE_SELECT(gqbOrderPanel::OnGridRangeSelected)\r
+EVT_BUTTON(bUp_ID, gqbOrderPanel::OnButtonUp)\r
+EVT_BUTTON(bUpTop_ID, gqbOrderPanel::OnButtonUpTop)\r
+EVT_BUTTON(bDown_ID, gqbOrderPanel::OnButtonDown)\r
+EVT_BUTTON(bDownBottom_ID, gqbOrderPanel::OnButtonDownBottom)\r
+END_EVENT_TABLE()\r
+\r
+gqbOrderPanel::gqbOrderPanel(wxWindow* parent, gqbGridOrderTable* gridTableLeft, gqbGridOrderTable* gridTableRight):\r
+wxPanel(parent,-1)\r
+{\r
+\r
+    // GQB-TODO: change bitmap buttons\r
+    selLeft=-1;\r
+    selRightTop=-1;\r
+    selRightBottom=-1;\r
+    tableLeft=gridTableLeft;\r
+    tableRight=gridTableRight;\r
+    allowSelCells=true;\r
+\r
+    addBitmap = wxBitmap(gqbOrderAdd_xpm);\r
+    addAllBitmap = wxBitmap(gqbOrderAddAll_xpm);\r
+    removeBitmap = wxBitmap(gqbOrderRemove_xpm);\r
+    removeAllBitmap = wxBitmap(gqbOrderRemoveAll_xpm);\r
+\r
+    buttonAdd=new wxBitmapButton( this, bAdd_ID,  addBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add Column") );\r
+    buttonAddAll=new wxBitmapButton( this, bAddAll_ID,  addAllBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add All Columns") );\r
+    buttonRemove=new wxBitmapButton( this, bRem_ID,  removeBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove Column") );\r
+    buttonRemoveAll=new wxBitmapButton( this, bRemAll_ID,  removeAllBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove All Columns") );\r
+\r
+    upBitmap = wxBitmap(gqbUp_xpm);\r
+    upTopBitmap = wxBitmap(gqbUpTop_xpm);\r
+    downBitmap = wxBitmap(gqbDown_xpm);\r
+    downBottomBitmap = wxBitmap(gqbDownBottom_xpm);\r
+\r
+    buttonUp = new wxBitmapButton( this, bUp_ID,  upBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Column(s) Up") );\r
+    buttonDown  = new wxBitmapButton( this, bDown_ID,  downBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Column(s) Up") );\r
+    buttonUpTop = new wxBitmapButton( this, bUpTop_ID,  upTopBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Column(s) Up") );\r
+    buttonDownBottom = new wxBitmapButton( this, bDownBottom_ID,  downBottomBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Column(s) Up") );\r
+\r
+    availableColumns = new wxGrid(this, -1, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_BESTWRAP ,wxT("Available Columns"));\r
+       availableColumns->SetTable(gridTableLeft);\r
+    availableColumns->EnableEditing(false);\r
+\r
+       // Adjust the default row height to be more compact\r
+    wxFont font = availableColumns->GetLabelFont();\r
+    int nWidth = 0;\r
+    int nHeight = 18;\r
+    availableColumns->GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font);\r
+    availableColumns->SetColLabelSize(nHeight+6);\r
+       availableColumns->SetRowLabelSize(35);\r
+#ifdef __WXGTK__\r
+    availableColumns->SetDefaultRowSize(nHeight+8, TRUE);\r
+#else\r
+    availableColumns->SetDefaultRowSize(nHeight+4, TRUE);\r
+#endif\r
+\r
+\r
+    wxBoxSizer *horizontalSizer = new wxBoxSizer( wxHORIZONTAL );\r
+\r
+    horizontalSizer->Add(availableColumns,\r
+        1,                                        // make vertically stretchable\r
+        wxEXPAND |                                // make horizontally stretchable\r
+        wxALL,                                    //   and make border all around\r
+        3 );                                      // set border width to 10\r
+\r
+    wxBoxSizer *buttonsSizer1 = new wxBoxSizer( wxVERTICAL );\r
+\r
+    buttonsSizer1->Add(\r
+        this->buttonAdd,\r
+        0,                                        // make horizontally unstretchable\r
+        wxALL,                                    // make border all around (implicit top alignment)\r
+        3 );                                      // set border width to 10\r
+\r
+    buttonsSizer1->Add(\r
+        this->buttonAddAll,\r
+        0,                                        // make horizontally unstretchable\r
+        wxALL,                                    // make border all around (implicit top alignment)\r
+        3 );                                      // set border width to 10\r
+\r
+    buttonsSizer1->Add(\r
+        this->buttonRemove,\r
+        0,                                        // make horizontally unstretchable\r
+        wxALL,                                    // make border all around (implicit top alignment)\r
+        3 );                                      // set border width to 10\r
+\r
+    buttonsSizer1->Add(\r
+        this->buttonRemoveAll,\r
+        0,                                        // make horizontally unstretchable\r
+        wxALL,                                    // make border all around (implicit top alignment)\r
+        3 );                                      // set border width to 10\r
+\r
+    horizontalSizer->Add(\r
+        buttonsSizer1,\r
+        0,                                        // make vertically unstretchable\r
+        wxALIGN_CENTER );                         // no border and centre horizontally\r
+\r
+    // GQB-TODO: change 333 for a new and better one.\r
+    usedColumns = new wxGrid(this, 333, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_BESTWRAP ,wxT("Columns Order"));\r
+       usedColumns->SetTable(gridTableRight);\r
+    usedColumns->EnableEditing(false);\r
+\r
+    // Adjust the default row height to be more compact\r
+    font = usedColumns->GetLabelFont();\r
+    nWidth = 0;\r
+    nHeight = 18;\r
+    usedColumns->GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font);\r
+    usedColumns->SetColLabelSize(nHeight+6);\r
+    usedColumns->SetRowLabelSize(35);\r
+#ifdef __WXGTK__\r
+    usedColumns->SetDefaultRowSize(nHeight+8, TRUE);\r
+#else\r
+    usedColumns->SetDefaultRowSize(nHeight+4, TRUE);\r
+#endif\r
+\r
+       this->Connect(333, wxEVT_GRID_CELL_LEFT_CLICK, (wxObjectEventFunction) (wxEventFunction) (wxGridEventFunction) &gqbOrderPanel::OnCellLeftClick);\r
+\r
+    horizontalSizer->Add(usedColumns,\r
+        1,                                        // make vertically stretchable\r
+        wxEXPAND |                                // make horizontally stretchable\r
+        wxALL,                                    //   and make border all around\r
+        3 );                                      // set border width to 10\r
+\r
+    wxBoxSizer *buttonsSizer2 = new wxBoxSizer( wxVERTICAL );\r
+\r
+    buttonsSizer2->Add(\r
+        this->buttonUpTop,\r
+        0,                                        // make horizontally unstretchable\r
+        wxALL,                                    // make border all around (implicit top alignment)\r
+        3 );                                      // set border width to 10\r
+\r
+    buttonsSizer2->Add(\r
+        this->buttonUp,\r
+        0,                                        // make horizontally unstretchable\r
+        wxALL,                                    // make border all around (implicit top alignment)\r
+        3 );                                      // set border width to 10\r
+\r
+    buttonsSizer2->Add(\r
+        this->buttonDown,\r
+        0,                                        // make horizontally unstretchable\r
+        wxALL,                                    // make border all around (implicit top alignment)\r
+        3 );                                      // set border width to 10\r
+\r
+    buttonsSizer2->Add(\r
+        this->buttonDownBottom,\r
+        0,                                        // make horizontally unstretchable\r
+        wxALL,                                    // make border all around (implicit top alignment)\r
+        3 );                                      // set border width to 10\r
+\r
+    horizontalSizer->Add(\r
+        buttonsSizer2,\r
+        0,                                        // make vertically unstretchable\r
+        wxALIGN_CENTER );                         // no border and centre horizontally\r
+\r
+    this->SetSizer(horizontalSizer);\r
+}\r
+\r
+\r
+void gqbOrderPanel::OnButtonRemove(wxCommandEvent&)\r
+{\r
+    if(usedColumns->GetRows()>0)\r
+    {\r
+        if(selRightTop!=-1)\r
+        {\r
+            gqbColumn *col = (gqbColumn*) tableRight->getObjectAt(selRightTop,0);\r
+            gqbQueryObject *colParent = (gqbQueryObject *) tableRight->getObjectAt(selRightTop,1);\r
+            tableLeft->AppendItem(col,colParent,'N');\r
+            tableRight->removeRowAt(selRightTop);\r
+        }\r
+    }\r
+}\r
+\r
+\r
+void gqbOrderPanel::OnButtonRemoveAll(wxCommandEvent&)\r
+{\r
+    if(usedColumns->GetRows()>0)\r
+    {\r
+        for(int i=usedColumns->GetRows()-1;i>=0;i--)\r
+        {\r
+            gqbColumn *col = (gqbColumn*) tableRight->getObjectAt(i,0);\r
+            gqbQueryObject *colParent = (gqbQueryObject *) tableRight->getObjectAt(i,1);\r
+            tableLeft->AppendItem(col,colParent,'N');\r
+            tableRight->removeRowAt(i);\r
+        }\r
+    }\r
+}\r
+\r
+\r
+void gqbOrderPanel::OnButtonAdd(wxCommandEvent&)\r
+{\r
+    if(availableColumns->GetRows()>0)\r
+    {\r
+        if(selLeft!=-1)\r
+        {\r
+            gqbColumn *col = (gqbColumn*) tableLeft->getObjectAt(selLeft,0);\r
+            gqbQueryObject *colParent = (gqbQueryObject *) tableLeft->getObjectAt(selLeft,1);\r
+            tableRight->AppendItem(col,colParent,'A');\r
+            usedColumns->SetCellRenderer((usedColumns->GetRows()-1), 1, new wxGridCellButtonRenderer);\r
+            tableLeft->removeRowAt(selLeft);\r
+        }\r
+    }\r
+}\r
+\r
+\r
+void gqbOrderPanel::OnButtonAddAll(wxCommandEvent&)\r
+{\r
+    if(availableColumns->GetRows()>0)\r
+    {\r
+        for(int i=availableColumns->GetRows()-1;i>=0;i--)\r
+        {\r
+            gqbColumn *col = (gqbColumn*) tableLeft->getObjectAt(i,0);\r
+            gqbQueryObject *colParent = (gqbQueryObject *) tableLeft->getObjectAt(i,1);\r
+            tableRight->AppendItem(col,colParent,'A');\r
+            usedColumns->SetCellRenderer((usedColumns->GetRows()-1), 1, new wxGridCellButtonRenderer);\r
+            tableLeft->removeRowAt(i);\r
+        }\r
+    }\r
+}\r
+\r
+\r
+void gqbOrderPanel::OnGridSelectCell( wxGridEvent& ev )\r
+{\r
+    if(allowSelCells)\r
+    {\r
+        if ( ev.Selecting() )\r
+        {\r
+            wxObject *object = ev.GetEventObject();\r
+            wxGrid *grid = wxDynamicCast( object, wxGrid );\r
+            if(grid->GetCols()==1)                // Left Grid\r
+            {\r
+                selLeft=ev.GetRow();\r
+            }\r
+            else\r
+            {                                     // Right Grid\r
+                selRightTop=ev.GetRow();\r
+                selRightBottom=-1;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            selRightTop=-1;                       // GQB-TODO: this is correct??\r
+            selRightBottom=-1;\r
+            selLeft=-1;\r
+        }\r
+    }\r
+    ev.Skip();\r
+}\r
+\r
+\r
+void gqbOrderPanel::OnGridRangeSelected( wxGridRangeSelectEvent& ev )\r
+{\r
+    if(allowSelCells)\r
+    {\r
+        if ( ev.Selecting() )\r
+        {\r
+            selRightTop=ev.GetTopRow();\r
+            selRightBottom=ev.GetBottomRow();\r
+        }\r
+        else\r
+        {\r
+            selRightTop=-1;\r
+            selRightBottom=-1;\r
+        }\r
+    }\r
+    ev.Skip();\r
+}\r
+\r
+\r
+void gqbOrderPanel::OnButtonUp(wxCommandEvent&)\r
+{\r
+    // A single row is selected\r
+    allowSelCells=false;\r
+    if((selRightTop>=0 && selRightBottom==-1) || (selRightTop==selRightBottom))\r
+    {\r
+        tableRight->changesPositions(selRightTop,selRightTop--);\r
+        if(selRightTop<0)\r
+        {\r
+            selRightTop=0;\r
+        }\r
+        usedColumns->SelectBlock(selRightTop,0,selRightTop,1,false);\r
+        usedColumns->SetGridCursor(selRightTop,0);\r
+        selRightBottom=-1;\r
+    }\r
+    else\r
+    {\r
+               // A range of rows is selected\r
+        if (selRightTop>=0 && selRightBottom>=0)\r
+        {\r
+            int newTop=selRightTop-1;\r
+            tableRight->changesRangeOnePos(selRightTop,selRightBottom,newTop);\r
+            if(selRightTop > 0)                   // Recalculate new selection area & avoid bad selection area\r
+            {\r
+                selRightTop--;\r
+                selRightBottom--;\r
+            }\r
+            usedColumns->SelectBlock(selRightTop,0,selRightBottom,1,false);\r
+            usedColumns->SetGridCursor(selRightTop,0);\r
+        }\r
+    }\r
+    allowSelCells=true;\r
+}\r
+\r
+\r
+void gqbOrderPanel::OnButtonUpTop(wxCommandEvent&)\r
+{\r
+    allowSelCells=false;\r
+    \r
+       // A Single Row is selected\r
+    if((selRightTop>=0 && selRightBottom==-1) || (selRightTop==selRightBottom))\r
+    {\r
+        selRightBottom=selRightTop-1;\r
+        selRightTop=0;\r
+        tableRight->changesRangeOnePos(selRightTop,selRightBottom,1);\r
+        usedColumns->SelectBlock(0,0,0,1,false);\r
+        usedColumns->SetGridCursor(0,0);\r
+\r
+        // Put variables in correct values now.\r
+        selRightTop=0;\r
+        selRightBottom=-1;\r
+    }                                            \r
+       // A range of rows is selected\r
+    else\r
+    {\r
+        int newTop=0;\r
+        if (selRightTop>=0 && selRightBottom>=0)\r
+        {\r
+            // Move all range only one pos the require times to get the top\r
+                       for(int i=selRightTop;i>0;i--)\r
+            {\r
+                newTop=selRightTop-1;\r
+                tableRight->changesRangeOnePos(selRightTop,selRightBottom,newTop);\r
+\r
+                // Recalculate new selection area & avoid bad selection area\r
+                               if(selRightTop > 0)\r
+                {\r
+                    selRightTop--;\r
+                    selRightBottom--;\r
+                }\r
+                usedColumns->SelectBlock(selRightTop,0,selRightBottom,1,false);\r
+                usedColumns->SetGridCursor(selRightTop,0);\r
+            }\r
+        }\r
+    }\r
+    allowSelCells=true;\r
+}\r
+\r
+\r
+void gqbOrderPanel::OnButtonDown(wxCommandEvent&)\r
+{\r
+\r
+    allowSelCells=false;\r
+\r
+    // A single row is selected\r
+    if((selRightTop>=0 && selRightBottom==-1) || (selRightTop==selRightBottom))\r
+    {\r
+        tableRight->changesPositions(selRightTop,selRightTop++);\r
+\r
+        // Adjust selection when selected item it's last item.\r
+        if(selRightTop==tableRight->GetNumberRows())\r
+        {\r
+            selRightTop--;\r
+        }\r
+        usedColumns->SelectBlock(selRightTop,0,selRightTop,1,false);\r
+        usedColumns->SetGridCursor(selRightTop,0);\r
+        selRightBottom=-1;\r
+    }   \r
+       // A range of rows is selected\r
+    else\r
+    {\r
+        if (selRightTop>=0 && selRightBottom>=0)\r
+        {\r
+            int newTop=selRightTop+1;\r
+            tableRight->changesRangeOnePos(selRightTop,selRightBottom,newTop);\r
+\r
+                       // Recalculate new selection area & avoid bad selection area\r
+            if(selRightBottom < tableRight->GetNumberRows()-1)\r
+            {\r
+                selRightTop++;\r
+                selRightBottom++;\r
+            }\r
+            usedColumns->SelectBlock(selRightTop,0,selRightBottom,1,false);\r
+            usedColumns->SetGridCursor(selRightTop,0);\r
+        }\r
+    }\r
+    allowSelCells=true;\r
+}\r
+\r
+\r
+void gqbOrderPanel::OnButtonDownBottom(wxCommandEvent&)\r
+{\r
+    allowSelCells=false;\r
+\r
+    // A Single Row is selected\r
+    if((selRightTop>=0 && selRightBottom==-1) || (selRightTop==selRightBottom))\r
+    {\r
+        selRightBottom=tableRight->GetNumberRows()-1;\r
+        selRightTop=selRightTop+1;\r
+        int newBottom=tableRight->GetNumberRows()-1;\r
+        tableRight->changesRangeOnePos(selRightTop,selRightBottom,selRightTop-1);\r
+        usedColumns->SelectBlock(newBottom,0,newBottom,1,false);\r
+        usedColumns->SetGridCursor(newBottom,0);\r
+\r
+        // Put variables in correct values now.\r
+        selRightTop=newBottom;\r
+        selRightBottom=-1;\r
+    }\r
+       // A range of rows is selected\r
+    else\r
+    {\r
+        int newTop=0, size=tableRight->GetNumberRows();\r
+\r
+        if (selRightTop>=0 && selRightBottom>=0)\r
+        {\r
+            for(int i=selRightBottom;i<size;i++)\r
+            {\r
+                newTop=selRightTop+1;\r
+                tableRight->changesRangeOnePos(selRightTop,selRightBottom,newTop);\r
+       \r
+                               // Recalculate new selection area & avoid bad selection area\r
+                if(selRightBottom < tableRight->GetNumberRows()-1)\r
+                {\r
+                    selRightTop++;\r
+                    selRightBottom++;\r
+                }\r
+                usedColumns->SelectBlock(selRightTop,0,selRightBottom,1,false);\r
+                usedColumns->SetGridCursor(selRightTop,0);\r
+            }\r
+        }\r
+    }\r
+    allowSelCells=true;\r
+}\r
+\r
+\r
+void gqbOrderPanel::SetGridColsSize()\r
+{\r
+    // After sizers determine the width of Grid then calculate the % space for each column\r
+    int size=(availableColumns->GetSize().GetWidth() - availableColumns->GetRowLabelSize())*0.90;\r
+    availableColumns->SetColSize(0,size);\r
+\r
+    size=(usedColumns->GetSize().GetWidth() - usedColumns->GetRowLabelSize())*0.65;\r
+    int size2=(usedColumns->GetSize().GetWidth() - usedColumns->GetRowLabelSize())*0.25;\r
+    usedColumns->SetColSize(0,size);\r
+    usedColumns->SetColSize(1,size2);\r
+}\r
+\r
+\r
+void gqbOrderPanel::OnCellLeftClick(wxGridEvent& event)\r
+{\r
+\r
+    // Only show editor y case of column 1\r
+    if(event.GetCol()==1)\r
+    {\r
+        // Change kind of order of the columns between ASC and DESC\r
+        wxRect cellSize=usedColumns->CellToRect(event.GetRow(), event.GetCol());\r
+        wxPoint p =event.GetPosition();\r
+        usedColumns->CalcUnscrolledPosition(p.x,p.y,&p.x,&p.y);\r
+\r
+        // Number 17 is button's width at cellRender function [nButtonWidth]\r
+        if((usedColumns->GetRowLabelSize()+cellSize.GetRight())-(p.x) <= 17 )\r
+        {\r
+            p =event.GetPosition();\r
+            if( tableRight->GetValue(event.GetRow(),1).Contains(wxT("ASC")) )\r
+            {\r
+                tableRight->SetValue(event.GetRow(),1,wxT("DESC"));\r
+            }\r
+            else\r
+            {\r
+                tableRight->SetValue(event.GetRow(),1,wxT("ASC"));\r
+            }\r
+            usedColumns->Refresh();\r
+        }\r
+    }\r
+    event.Skip();\r
+}\r
diff --git a/pgadmin/gqb/module.mk b/pgadmin/gqb/module.mk
new file mode 100644 (file)
index 0000000..54c87b9
--- /dev/null
@@ -0,0 +1,35 @@
+#######################################################################\r
+#\r
+# pgAdmin III - PostgreSQL Tools\r
+# $Id: module.mk 7109 2008-03-03 20:04:34Z dpage $\r
+# Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+# This software is released under the Artistic Licence\r
+#\r
+# module.mk - pgadmin/gqb/ Makefile fragment\r
+#\r
+#######################################################################\r
+\r
+pgadmin3_SOURCES += \\r
+       $(srcdir)/gqb/gqbArrayCollection.cpp \\r
+       $(srcdir)/gqb/gqbBrowser.cpp \\r
+       $(srcdir)/gqb/gqbCollection.cpp \\r
+       $(srcdir)/gqb/gqbColumn.cpp \\r
+       $(srcdir)/gqb/gqbController.cpp \\r
+       $(srcdir)/gqb/gqbDatabase.cpp \\r
+       $(srcdir)/gqb/gqbGraphSimple.cpp \\r
+       $(srcdir)/gqb/gqbGridOrderTable.cpp \\r
+       $(srcdir)/gqb/gqbGridProjTable.cpp \\r
+       $(srcdir)/gqb/gqbGridRestTable.cpp \\r
+       $(srcdir)/gqb/gqbModel.cpp \\r
+       $(srcdir)/gqb/gqbObject.cpp \\r
+       $(srcdir)/gqb/gqbObjectCollection.cpp \\r
+       $(srcdir)/gqb/gqbQueryObjs.cpp \\r
+       $(srcdir)/gqb/gqbSchema.cpp \\r
+       $(srcdir)/gqb/gqbTable.cpp \\r
+       $(srcdir)/gqb/gqbViewPanels.cpp \\r
+       $(srcdir)/gqb/gqbView.cpp\r
+\r
+EXTRA_DIST += \\r
+    $(srcdir)/gqb/module.mk\r
+\r
+\r
index 3b26bc17a016e8f83f7636319ce04bff749d5ae0..7a8831b680c45104106795eb70ab007488b2199e 100644 (file)
 #define __FRM_QUERY_H
 
 #include "dlg/dlgClasses.h"
+#include "gqb/gqbViewController.h"
+#include "gqb/gqbModel.h"
 #include "utils/factory.h"
 #include "utils/favourites.h"
 #include "utils/macros.h"
 
 // wxAUI
 #include <wx/aui/aui.h>
+#include <wx/textctrl.h>
+#include <wx/dcbuffer.h>
 #include <wx/timer.h>
 
 #define FRMQUERY_PERPSECTIVE_VER wxT("$Rev$")
@@ -64,17 +68,28 @@ private:
     ctlComboBoxFix *cbConnection;
     wxTextCtrl *scratchPad;
 
-    // Query timing/status update
+       // Query timing/status update
     wxTimer timer;
     wxLongLong elapsedQuery, startTimeQuery;
 
-    // Our connection
+       //GQB related
+    void OnChangeNotebook(wxNotebookEvent& event);
+    void OnAdjustSizesTimer(wxTimerEvent & event);
+       void onResizeHorizontally(wxSplitterEvent& event);
+    void adjustGQBSizes();
+    wxNotebook *sqlNotebook;
+    gqbModel *model;
+    gqbController *controller;
+    bool firstTime,firstGeneration;
+    wxTimer *adjustSizesTimer;
+
+       // Our connection
     pgConn *conn;
 
        // These status flags are required to work round some wierdness on wxGTK,
        // particularly on Solaris.
     bool closing, loading;
-    
+
     void OnEraseBackground(wxEraseEvent& event);
     void OnSize(wxSizeEvent& event);
 
@@ -124,7 +139,7 @@ private:
     void OnAuiUpdate(wxAuiManagerEvent& event);
     void OnDefaultView(wxCommandEvent& event);
 
-       void OnTimer(wxTimerEvent & event);
+    void OnTimer(wxTimerEvent & event);
 
     bool CheckChanged(bool canVeto);
     void OpenLastFile();
@@ -139,20 +154,20 @@ private:
     void SetLineEndingStyle();
     int GetLineEndingStyle();
     void OnSetEOLMode(wxCommandEvent& event);
-       void SetEOLModeDisplay(int mode);
-       void OnMacroInvoke(wxCommandEvent& event);
-       void OnMacroManage(wxCommandEvent& event);
-       void UpdateMacrosList();
+    void SetEOLModeDisplay(int mode);
+    void OnMacroInvoke(wxCommandEvent& event);
+    void OnMacroManage(wxCommandEvent& event);
+    void UpdateMacrosList();
     wxWindow *currentControl();
     wxMenu *queryMenu;
     wxMenu *favouritesMenu;
-       wxMenu *macrosMenu;
+    wxMenu *macrosMenu;
     wxMenu *lineEndMenu;
     wxString title;
     wxString lastFilename, lastDir;
 
     queryFavouriteFolder *favourites;
-       queryMacroList *macros;
+    queryMacroList *macros;
 
     bool aborted;
     bool lastFileFormat;
@@ -160,8 +175,6 @@ private:
     DECLARE_EVENT_TABLE()
 };
 
-
-
 // Position of status line fields
 enum
 {
@@ -172,13 +185,16 @@ enum
     STATUSPOS_SECS
 };
 
-
 enum
 {
     CTL_SQLQUERY=331,
     CTL_SQLRESULT,
     CTL_MSGRESULT,
-    CTL_MSGHISTORY
+    CTL_MSGHISTORY,
+    CTL_NTBKCENTER,
+    CTL_COLSGRID,
+    CTL_TIMERSIZES,
+    CTL_TIMERFRM
 };
 
 ///////////////////////////////////////////////////////
@@ -200,8 +216,6 @@ public:
     bool CheckEnable(pgObject *obj);
 };
 
-
-
 class queryToolFactory : public queryToolBaseFactory
 {
 public:
@@ -209,7 +223,6 @@ public:
     wxWindow *StartDialog(frmMain *form, pgObject *obj);
 };
 
-    
 class queryToolSqlFactory : public queryToolBaseFactory
 {
 public:
@@ -218,9 +231,7 @@ public:
     bool CheckEnable(pgObject *obj);
 };
 
-
 class queryToolSelectFactory : public queryToolDataFactory
-
 {
 public:
     queryToolSelectFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar);
@@ -250,5 +261,4 @@ public:
     wxWindow *StartDialog(frmMain *form, pgObject *obj);
     bool CheckEnable(pgObject *obj);
 };
-
 #endif // __FRM_QUERY_H
index 193144a2ca0effb0c1f72736ccf7e5c374fc494c..59af06e7ee45d98858042d19696aa7e48f7a64ea 100644 (file)
@@ -108,7 +108,10 @@ enum
     QUERY_COMPLETE=MNU_MACROS_MANAGE+100,
 
     // This is a dummy menu item
-    MNU_DUMMY=QUERY_COMPLETE+1000
+    MNU_DUMMY=QUERY_COMPLETE+1000,
+
+       //Menu Test
+       MNU_GENERATESQL
 };
 
 #endif
diff --git a/pgadmin/include/gqb/gqbArrayCollection.h b/pgadmin/include/gqb/gqbArrayCollection.h
new file mode 100644 (file)
index 0000000..172d5d3
--- /dev/null
@@ -0,0 +1,63 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbArrayCollection.h - Implementation of Collection Using Arrays\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBARRAYCOLLECTION_H\r
+#define GQBARRAYCOLLECTION_H\r
+\r
+// App headers\r
+#include "gqb/gqbCollectionBase.h"\r
+\r
+WX_DEFINE_ARRAY_PTR(gqbObject *, gqbObjsArray);\r
+\r
+class gqbArrayIterator : public gqbIteratorBase\r
+{\r
+public:\r
+    gqbArrayIterator(gqbObjsArray *gqbPtrsArray);\r
+    gqbObject* Next();\r
+    bool HasNext();\r
+    void ResetIterator();\r
+private:\r
+    int position;\r
+    gqbObjsArray *internalArray;\r
+};\r
+\r
+class gqbArrayDownIterator : public gqbIteratorBase\r
+{\r
+public:\r
+    gqbArrayDownIterator(gqbObjsArray *gqbPtrsArray);\r
+    gqbObject* Next();\r
+    bool HasNext();\r
+    void ResetIterator();\r
+private:\r
+    int position;\r
+    gqbObjsArray *internalArray;\r
+};\r
+\r
+//Create Array Objects used as base for gqbCollections\r
+class gqbArrayCollection : public gqbCollectionBase\r
+{\r
+public:\r
+    ~gqbArrayCollection();\r
+    void addItem(gqbObject *item);\r
+    void removeItem(gqbObject *item);\r
+    gqbIteratorBase* createIterator();\r
+               gqbIteratorBase* createDownIterator();\r
+    gqbObject* getItemAt(int index);\r
+    int count();\r
+    bool existsObject(gqbObject *item);\r
+    int getIndex(gqbObject *item);\r
+    void insertAtIndex(gqbObject *item, int index);\r
+    void deleteAll();\r
+    void removeAll();\r
+private:\r
+    gqbObjsArray gqbArray;\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbBrowser.h b/pgadmin/include/gqb/gqbBrowser.h
new file mode 100644 (file)
index 0000000..37aa692
--- /dev/null
@@ -0,0 +1,47 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbBrowser.h - Tables Tree of GQB.\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBBROWSER_H\r
+#define GQBBROWSER_H\r
+\r
+typedef unsigned long OID;\r
+\r
+class gqbController;\r
+\r
+class gqbBrowser : public wxTreeCtrl\r
+{\r
+public:\r
+    gqbBrowser(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, gqbController *_controller);\r
+    ~gqbBrowser();\r
+    wxTreeItemId& createRoot(wxString &Name);\r
+    wxTreeItemId& getCatalogRootNode(){return catalogsNode;}\r
+    wxTreeItemId& getTablesRootNode(){return schemasNode;}\r
+    void refreshTables(pgConn *connection);\r
+    void setDnDPoint(int x, int y){xx=x; yy=y;};\r
+\r
+private:\r
+    enum typeSchema                                            // GQB-TODO: DELETE from here should be locate at gqbDatabase\r
+    {\r
+        GQB_CATALOG,\r
+        GQB_OTHER\r
+    };\r
+\r
+    wxTreeItemId rootNode,catalogsNode,schemasNode;\r
+    void OnItemActivated(wxTreeEvent& event);\r
+    void OnBeginDrag(wxTreeEvent& event);\r
+    wxString NumToStr(OID value);\r
+    gqbController *controller;                 //Allow access to controller functions like add table to model\r
+    wxImageList* imageList;\r
+    int xx,yy;\r
+\r
+    DECLARE_EVENT_TABLE()\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbCollection.h b/pgadmin/include/gqb/gqbCollection.h
new file mode 100644 (file)
index 0000000..0f93ae7
--- /dev/null
@@ -0,0 +1,38 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbCollection.h - Generic implementation of a Collection used by GQB.\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBCOLLECTION_H\r
+#define GQBCOLLECTION_H\r
+\r
+// App headers\r
+#include "gqb/gqbObject.h"\r
+#include "gqb/gqbCollectionBase.h"\r
+\r
+class gqbCollection : public wxObject\r
+{\r
+public:\r
+    gqbCollection(gqbCollectionBase *collectionBase);\r
+    virtual ~gqbCollection();\r
+    void addItem(gqbObject *item);\r
+    void removeItem(gqbObject *item);\r
+    void deleteAll();\r
+    void removeAll();\r
+    int count();\r
+    bool existsObject(gqbObject *item);\r
+    int getIndex(gqbObject *item);\r
+    gqbObject* getItemAt(int index);\r
+    void insertAtIndex(gqbObject *item, int index);\r
+    gqbIteratorBase* createIterator();\r
+               gqbIteratorBase* createDownIterator();\r
+private:\r
+    gqbCollectionBase *collection;\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbCollectionBase.h b/pgadmin/include/gqb/gqbCollectionBase.h
new file mode 100644 (file)
index 0000000..4521a33
--- /dev/null
@@ -0,0 +1,48 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbCollectionBase.h - A Collection Interface for GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBCOLLECTIONFACTORY_H\r
+#define GQBCOLLECTIONFACTORY_H\r
+\r
+// App headers\r
+#include "gqb/gqbObject.h"\r
+\r
+// This class it's like an interface (but with not all advantages of this at runtime)\r
+// If in a future I just don't want to use an array, simple implement this abstract class again\r
+// with the new data structure.\r
+\r
+class gqbIteratorBase : wxObject\r
+{\r
+public:\r
+    gqbIteratorBase() {};\r
+    virtual gqbObject* Next() = 0;\r
+    virtual bool HasNext() = 0;\r
+    virtual void ResetIterator() = 0;\r
+};\r
+// OR probably let to this class to\r
+class gqbCollectionBase : wxObject        // GQB-TODO: Change to the class because probably it's not adapted to the actual use of this class\r
+{\r
+public:\r
+    gqbCollectionBase() {};\r
+    virtual ~gqbCollectionBase() {};\r
+    virtual void addItem(gqbObject *item) = 0;\r
+    virtual void removeItem(gqbObject *item) = 0;\r
+    virtual gqbObject* getItemAt(int index) = 0;\r
+    virtual gqbIteratorBase* createIterator() = 0;\r
+       virtual gqbIteratorBase* createDownIterator() = 0;\r
+    virtual int count() = 0;\r
+    virtual bool existsObject(gqbObject *item) = 0;\r
+    virtual int getIndex(gqbObject *item) = 0;\r
+    virtual void insertAtIndex(gqbObject *item, int index) = 0;\r
+    virtual void deleteAll()=0;\r
+    virtual void removeAll()=0;           //remove all items from collection without deleting.\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbColumn.h b/pgadmin/include/gqb/gqbColumn.h
new file mode 100644 (file)
index 0000000..5d3ab93
--- /dev/null
@@ -0,0 +1,25 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbColumn.h - Column Object for GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBCOLUMN_H\r
+#define GQBCOLUMN_H\r
+\r
+// App headers\r
+#include "gqb/gqbObject.h"\r
+#include "gqb/gqbTable.h"\r
+\r
+// Create Array Objects used as base for gqbCollections\r
+class gqbColumn : public gqbObject\r
+{\r
+public:\r
+    gqbColumn(gqbObject *parent, wxString name, type_gqbObject type);\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbDatabase.h b/pgadmin/include/gqb/gqbDatabase.h
new file mode 100644 (file)
index 0000000..39c0e94
--- /dev/null
@@ -0,0 +1,35 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbDatabase.h - Database object for GQB.\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBDATABASE_H\r
+#define GQBDATABASE_H\r
+\r
+// App headers\r
+#include "gqb/gqbObject.h"\r
+#include "gqb/gqbSchema.h"\r
+#include "gqb/gqbBrowser.h"\r
+\r
+class gqbDatabase : public gqbObject\r
+{\r
+public:\r
+    gqbDatabase(wxString name, type_gqbObject type);\r
+    void createObjects(gqbBrowser *_tablesBrowser,  pgConn *_conn);\r
+\r
+private:\r
+    pgConn *conn;\r
+    enum typeSchema\r
+    {\r
+        GQB_CATALOG,\r
+        GQB_OTHER\r
+    };\r
+    void createSchemas(pgConn *conn,  gqbBrowser *tablesBrowser, wxTreeItemId parentNode,typeSchema MetaType, int indexImage);\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbEvents.h b/pgadmin/include/gqb/gqbEvents.h
new file mode 100644 (file)
index 0000000..3facc71
--- /dev/null
@@ -0,0 +1,29 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// Events.h - IDs for GQB Events\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBEVENTS_H\r
+#define GQBEVENTS_H\r
+\r
+enum gqb_Events\r
+{\r
+    GQB_COLSTREE = 1000,\r
+    GQB_BROWSER,\r
+       GQB_HORZ_SASH\r
+};\r
+\r
+enum gqb_rMenus\r
+{\r
+    GQB_RMJ_DELETE = 2000,\r
+    GQB_RMJ_SETTYPE,\r
+    GQB_RMT_DELETE,\r
+    GQB_RMT_SETALIAS\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbGraphBehavior.h b/pgadmin/include/gqb/gqbGraphBehavior.h
new file mode 100644 (file)
index 0000000..96cb334
--- /dev/null
@@ -0,0 +1,39 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbGraphsimple.h - A simple Graphic Interface for GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBGRAPHBEHAVIOR_H\r
+#define GQBGRAPHBEHAVIOR_H\r
+\r
+#include <wx/dcbuffer.h>\r
+\r
+// App headers\r
+#include "gqb/gqbQueryObjs.h"\r
+\r
+// Interface class for drawing of objects in canvas\r
+class gqbGraphBehavior : public wxObject\r
+{\r
+public:\r
+    // Important: The drawTable function always should store the width & height of the graphic\r
+    // representation of the table inside the gqbQueryObject for use of controller.\r
+    virtual void drawTable(wxBufferedDC& bdc, wxPoint *origin, gqbQueryObject *queryTable)=0;\r
+    virtual void drawTempJoinLine(wxBufferedDC& bdc, wxPoint &origin, wxPoint &end)=0;\r
+    virtual void drawJoin(wxBufferedDC& bdc, wxPoint& origin, wxPoint& dest, wxPoint& anchorUsed, bool selected, type_Join joinKind)=0;\r
+    virtual void calcAnchorPoint(gqbQueryJoin *join)=0;\r
+    virtual void UpdatePosObject(gqbQueryObject *queryTable, int x, int y, int cursorAdjustment)=0;\r
+    \r
+       // GQB-TODO find a way to not hard code the 17 default value\r
+    virtual gqbColumn* getColumnAtPosition(wxPoint *clickPoint, gqbQueryObject *queryTable, int sensibility=17)=0;\r
+    virtual bool clickOnJoin(gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest)=0;\r
+    virtual int getTitleRowHeight()=0;\r
+private:\r
+\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbGraphSimple.h b/pgadmin/include/gqb/gqbGraphSimple.h
new file mode 100644 (file)
index 0000000..2e06de4
--- /dev/null
@@ -0,0 +1,46 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbGraphsimple.h - A simple Implementation of the Graphic Interface for GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBGRAPHSIMPLE_H\r
+#define GQBGRAPHSIMPLE_H\r
+\r
+#include <wx/dcbuffer.h>\r
+\r
+// App headers\r
+#include "gqb/gqbQueryObjs.h"\r
+#include "gqb/gqbGraphBehavior.h"\r
+\r
+// Create Array Objects used as base for gqbCollections\r
+class gqbGraphSimple : public gqbGraphBehavior\r
+{\r
+public:\r
+    gqbGraphSimple();\r
+    void drawTable(wxBufferedDC& bdc, wxPoint *origin, gqbQueryObject *queryTable);\r
+    void drawTempJoinLine(wxBufferedDC& bdc, wxPoint &origin, wxPoint &end);\r
+    void calcAnchorPoint(gqbQueryJoin *join);\r
+    void drawJoin(wxBufferedDC& bdc, wxPoint& origin, wxPoint& dest, wxPoint& anchorUsed, bool selected, type_Join joinKind);\r
+    void UpdatePosObject(gqbQueryObject *queryTable, int x, int y, int cursorAdjustment);\r
+    gqbColumn* getColumnAtPosition(wxPoint *clickPoint, gqbQueryObject *queryTable, int sensibility=17);\r
+    bool clickOnJoin(gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest);\r
+    int getTitleRowHeight();\r
+\r
+private:\r
+    wxFont normalFont, TableTitleFont;\r
+    wxBrush BackgroundLayer1, BackgroundLayer2, BackgroundTitle, selectedBrush;\r
+    int minTableWidth, minTableHeight;\r
+    int rowHeight, rowLeftMargin, rowRightMargin, rowTopMargin, lineClickThreshold;\r
+    wxPen selectedPen;\r
+    wxBitmap imgSelBoxEmpty,imgSelBoxSelected;\r
+    bool insideLine(wxPoint &pt, wxPoint &p1, wxPoint &p2, int threshold);\r
+    double distanceToLine(wxPoint pt, wxPoint p1, wxPoint p2);\r
+    wxPoint findLineMiddle(wxPoint p1, wxPoint p2);\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbGridOrderTable.h b/pgadmin/include/gqb/gqbGridOrderTable.h
new file mode 100644 (file)
index 0000000..17a2faf
--- /dev/null
@@ -0,0 +1,52 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbGridOrderTable.h - Table implementation for Order By Panel Grid\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBGRIDORDERTABLE_H\r
+#define GQBGRIDORDERTABLE_H\r
+\r
+#include <wx/grid.h>\r
+\r
+// App headers\r
+#include "gqb/gqbArrayCollection.h"\r
+#include "gqb/gqbColumn.h"\r
+#include "gqb/gqbQueryObjs.h"\r
+#include "gqb/gqbModel.h"\r
+\r
+class gqbGridOrderTable : public wxGridTableBase\r
+{\r
+public:\r
+    gqbGridOrderTable(int numColumns, gqbObjsArray* cols, gqbObjsArray* parent, charArray* orderBy);\r
+    ~gqbGridOrderTable();\r
+    int GetNumberRows();\r
+    int GetNumberCols();\r
+    bool IsEmptyCell( int row, int col );\r
+    wxString GetValue( int row, int col );\r
+    wxString GetColLabelValue( int col);\r
+    void SetValue( int row, int col, const wxString& value );\r
+    void AppendItem(gqbColumn *column, gqbQueryObject *parent, char kindOrder);\r
+    void emptyTableData(gqbQueryObject *object);\r
+    gqbObject* getObjectAt(int pos, int col);\r
+    bool removeFirstRow(gqbObject *itemTable);\r
+    void removeRowAt(int i);\r
+    void changesRangeOnePos(int topPos, int bottomPos, int newTop);\r
+    void changesPositions(int sPos, int dPos);\r
+\r
+private:\r
+    int numberColumns;                                 // GQB-TODO: replace this with grid cols number function if possible\r
+    bool haveUpperCase(wxString &str);\r
+    gqbObjsArray *columns;                             // Here store position of the columns at Select projection clause \r
+                                                                               // [Select c1,c2,c3...,cn from...]\r
+    gqbObjsArray *colsParents;                 // Because above array only store a column object cannot be recovered \r
+                                                                               // the object that store it (gqbQueryObject) [remember can be use same \r
+                                                                               // table twice on a query].\r
+    charArray *kindOfOrder;                            // A [Asc] D [Desc]\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbGridProjTable.h b/pgadmin/include/gqb/gqbGridProjTable.h
new file mode 100644 (file)
index 0000000..ce68911
--- /dev/null
@@ -0,0 +1,56 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbGridProjTable.h - Table implementation for Projection Panel Grid\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBGRIDPROJTABLE_H\r
+#define GQBGRIDPROJTABLE_H\r
+\r
+#include <wx/grid.h>\r
+\r
+// App headers\r
+#include "gqb/gqbModel.h"\r
+#include "gqb/gqbArrayCollection.h"\r
+\r
+// GQB-TODO: don't use gqbObjsArray, use a new one in the model because violating MVC Pattern\r
+\r
+// GQB-TODO: this is not needed the one in gqbArrayCollections works her ?????\r
+// WX_DEFINE_ARRAY_PTR(gqbObject *, gqbObjsArray); this is not\r
+\r
+// Create the Data Model that will be used by wxGrid Component\r
+class gqbGridProjTable : public wxGridTableBase\r
+{\r
+public:\r
+    gqbGridProjTable(gqbObjsArray *position, gqbObjsArray *parent, wxArrayString *alias);\r
+    virtual ~gqbGridProjTable();\r
+    int GetNumberRows();\r
+    int GetNumberCols();\r
+    bool IsEmptyCell( int row, int col );\r
+    wxString GetValue( int row, int col );\r
+    void SetValue( int row, int col, const wxString& value );\r
+    void* GetValueAsCustom( int row, int col, const wxString& typeName );\r
+    void  SetValueAsCustom( int row, int col, const wxString& typeName, void* value );\r
+    wxString GetColLabelValue( int col);\r
+    bool removeRow(gqbObject *itemTable, gqbObject *itemColumn);\r
+    void removeAllRows(gqbObject *itemTable);\r
+    void changesPositions(int spos, int dpos);\r
+    void changesRangeOnePos(int topPos, int bottomPos, int newTop);\r
+    void AppendItem(int col, gqbObject *item);\r
+    void emptyTableData();\r
+\r
+private:\r
+    bool haveUpperCase(wxString &str);\r
+    gqbObjsArray *colsPosition;       // Here store position of the columns at Select projection clause \r
+                                         // [Select c1,c2,c3...,cn from...]\r
+    gqbObjsArray *colsParents;        // Because above array only store a column object cannot be recovered \r
+                                         // the object that store it (gqbQueryObject) [remember can be use \r
+                                         // same table twice on a query].\r
+    wxArrayString *columnsAlias;      // GQB-TODO: find a better solution than this\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbGridRestTable.h b/pgadmin/include/gqb/gqbGridRestTable.h
new file mode 100644 (file)
index 0000000..5398254
--- /dev/null
@@ -0,0 +1,95 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbGridRestTable.h - Table implementation for Restrictions Panel Grid\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBGRIDRESTTABLE_H\r
+#define GQBGRIDRESTTABLE_H\r
+\r
+#include <wx/grid.h>\r
+#include <wx/laywin.h>\r
+\r
+// App headers\r
+#include "gqb/gqbModel.h"\r
+#include "gqb/gqbArrayCollection.h"\r
+\r
+class gqbGridRestTable : public wxGridTableBase\r
+{\r
+public:\r
+    gqbGridRestTable(gqbRestrictions *_restrictions);\r
+    ~gqbGridRestTable();\r
+    int GetNumberRows();\r
+    int GetNumberCols();\r
+    bool IsEmptyCell( int row, int col );\r
+    wxString GetValue( int row, int col );\r
+    wxString GetColLabelValue( int col);\r
+    void SetValue( int row, int col, const wxString& value );\r
+    void AppendItem(gqbQueryRestriction *item);\r
+    void emptyTableData();\r
+    bool DeleteRows(size_t pos, size_t numRows);\r
+\r
+private:\r
+    gqbRestrictions *restrictions;\r
+};\r
+\r
+//\r
+// Cell rendering utilities classes\r
+//\r
+\r
+class wxGridCellComboBoxRenderer : public wxGridCellStringRenderer\r
+{\r
+public:\r
+    wxGridCellComboBoxRenderer(wxLayoutAlignment border = wxLAYOUT_NONE) :\r
+    m_border(border) {}\r
+    virtual void Draw(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, const wxRect& rect, int row, int col, bool isSelected);\r
+    virtual wxGridCellRenderer *Clone() const { return new wxGridCellComboBoxRenderer; }\r
+\r
+private:\r
+    wxLayoutAlignment m_border;\r
+};\r
+\r
+class wxGridCellButtonRenderer : public wxGridCellStringRenderer\r
+{\r
+public:\r
+    wxGridCellButtonRenderer(wxLayoutAlignment border = wxLAYOUT_NONE) :\r
+    m_border(border) {}\r
+    virtual void Draw(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, const wxRect& rect, int row, int col, bool isSelected);\r
+    virtual wxGridCellRenderer *Clone() const { return new wxGridCellComboBoxRenderer; }\r
+\r
+private:\r
+    wxLayoutAlignment m_border;\r
+};\r
+\r
+// Shows a wxGridCellChoiceEditor of cell's wide\r
+class dxGridCellSizedChoiceEditor : public wxGridCellChoiceEditor\r
+{\r
+public:\r
+    dxGridCellSizedChoiceEditor(const wxArrayString& choices, bool allowOthers = false);\r
+    dxGridCellSizedChoiceEditor(size_t count = 0, const wxString choices[] = NULL, bool allowOthers = false);\r
+\r
+    ~dxGridCellSizedChoiceEditor() {}\r
+\r
+    virtual wxGridCellEditor*  Clone() const;\r
+    virtual void Show(bool show, wxGridCellAttr *attr = (wxGridCellAttr *)NULL);\r
+\r
+protected:\r
+    int m_maxWide;\r
+\r
+    DECLARE_NO_COPY_CLASS(dxGridCellSizedChoiceEditor)\r
+\r
+};\r
+\r
+// GQB-TODO: don't use gqbObjsArray, use a new one in the model because violating MVC Pattern\r
+\r
+// GQB-TODO: this is not needed the one in gqbArrayCollections works her ?????\r
+// WX_DEFINE_ARRAY_PTR(gqbObject *, gqbObjsArray); this is not\r
+\r
+// Create the Data Model that will be used by wxGrid Component\r
+\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbModel.h b/pgadmin/include/gqb/gqbModel.h
new file mode 100644 (file)
index 0000000..cdd15ff
--- /dev/null
@@ -0,0 +1,76 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbModel.h - Model of MVC Pattern for GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBMODEL_H\r
+#define GQBMODEL_H\r
+\r
+// App headers\r
+#include "gqb/gqbQueryObjs.h"\r
+\r
+#define MAXRECTANGLES 10\r
+\r
+WX_DEFINE_ARRAY_CHAR(char, charArray);\r
+\r
+class gqbModel : public wxObject\r
+{\r
+public:\r
+    gqbModel();\r
+    ~gqbModel();\r
+    void emptyAll();\r
+\r
+       // Tables\r
+    gqbQueryObject* addTable(gqbTable *table, wxPoint p);\r
+    void deleteTable(gqbQueryObject *table);\r
+    gqbIteratorBase* createQueryIterator();\r
+       gqbIteratorBase* createDownQueryIterator();\r
+    int tablesCount();\r
+\r
+       // Projection Panel\r
+    gqbObjsArray* getOrderedColumns(){return &colsPosition;};\r
+    gqbObjsArray* getColumnsParents(){return &colsParents;};\r
+    wxArrayString* getColumnsAlias(){return columnsAlias;};\r
+\r
+       // Restrictions Panel\r
+    gqbQueryRestriction* addRestriction();    // GQB-TODO: delete if not use this function\r
+    gqbRestrictions* getRestrictions(){return restrictions;};\r
+\r
+       // Order By Panel\r
+    gqbObjsArray* getOrdByAvailColumns(){return &AvailableColumns;};\r
+    gqbObjsArray* getOrdByAvailParents(){return &ColumnAvailParent;};\r
+    gqbObjsArray* getOrdByColumns(){return &OrderedColumns;};\r
+    gqbObjsArray* getOrdByParents(){return &ColumnOrdParent;};\r
+    charArray* getOrdByKind(){return &orderBy;};\r
+private:\r
+       // query objects [tables] with joins inside\r
+    gqbQueryObjs *queryCollection;\r
+\r
+       // projection Panel\r
+    gqbObjsArray colsPosition;          // Here store position of the columns at Select projection clause \r
+                                                                               // [Select c1,c2,c3...,cn from...]\r
+    gqbObjsArray colsParents;                  // Because above array only store a column object cannot be recovered \r
+                                                                               // the object that store it (gqbQueryObject) [remember can be use same \r
+                                                                               // table twice on a query].\r
+    wxArrayString *columnsAlias;\r
+\r
+       // restrictions Panel\r
+    gqbRestrictions *restrictions;\r
+\r
+       // order by Panel\r
+    // For left grid [available columns to order clause]\r
+    gqbObjsArray AvailableColumns;\r
+    gqbObjsArray ColumnAvailParent;\r
+\r
+       // For right grid [used columns on order clause]\r
+    gqbObjsArray OrderedColumns;\r
+    gqbObjsArray ColumnOrdParent;\r
+    charArray orderBy;            // D or A\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbObject.h b/pgadmin/include/gqb/gqbObject.h
new file mode 100644 (file)
index 0000000..294e58f
--- /dev/null
@@ -0,0 +1,45 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbObject.h - Main basic object used by GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBOBJECT_H\r
+#define GQBOBJECT_H\r
+\r
+enum type_gqbObject\r
+{\r
+    _gqbDatabase,\r
+    _gqbSchema,\r
+    _gqbTable,\r
+    _gqbColumn,\r
+    _gqbQueryObj,\r
+    _gqbQuery,\r
+    _gqbJoin,\r
+    _gqbRestriction\r
+};\r
+\r
+// Create Array Objects used as base for gqbCollections\r
+class gqbObject : public wxTreeItemData\r
+{\r
+public:\r
+    gqbObject(wxString name, type_gqbObject type);\r
+    virtual ~gqbObject();\r
+    void setName(wxString name);\r
+    const wxString& getName();\r
+    void setOwner(wxTreeItemData *owner);\r
+    const wxTreeItemData& getOwner();\r
+    void setType(type_gqbObject name);\r
+    const type_gqbObject getType();\r
+\r
+private:\r
+    wxString Name;\r
+    wxTreeItemData *Owner;\r
+    type_gqbObject Type;\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbObjectCollection.h b/pgadmin/include/gqb/gqbObjectCollection.h
new file mode 100644 (file)
index 0000000..42ac3fd
--- /dev/null
@@ -0,0 +1,45 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbObjectCollection.h - A Collection of simple GQB objects\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBOBJECTCOLLECTION_H\r
+#define GQBOBJECTCOLLECTION_H\r
+\r
+// App headers\r
+#include "gqb/gqbObject.h"\r
+#include "gqb/gqbCollection.h"\r
+#include "gqb/gqbArrayCollection.h"\r
+\r
+// Create Collections of gqbObjects\r
+class gqbObjectCollection : public gqbObject\r
+{\r
+public:\r
+    gqbObjectCollection(wxString name, type_gqbObject type);\r
+    virtual ~gqbObjectCollection();\r
+\r
+protected:\r
+    void addObject(gqbObject *object);\r
+    void removeObject(gqbObject *object);\r
+    gqbIteratorBase* createIterator();\r
+    gqbIteratorBase* createDownIterator();\r
+       int countObjects();\r
+    gqbObject* getObjectAtIndex(int index);\r
+    bool existsObject(gqbObject *object);\r
+    int indexObject(gqbObject *object);\r
+    void insertObjectAt(gqbObject *object, int index);\r
+    int getCount();\r
+    void removeAll();             // Remove all objects from collection without deleting each one.\r
+    void deleteAll();             // Remove and Delete all objects from collection.\r
+\r
+private:\r
+    gqbCollection *objectsCollection;\r
+    gqbArrayCollection *implementation;       // GQB-TODO: DEBO Eliminar esto (que gqbArrayCollection este dentro de la clase) pero como?\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbQueryObjs.h b/pgadmin/include/gqb/gqbQueryObjs.h
new file mode 100644 (file)
index 0000000..56e9f8e
--- /dev/null
@@ -0,0 +1,166 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbQueryObjs.h - All objects used by a model of a query in the MVC Pattern model.\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBQUERYOBJS_H\r
+#define GQBQUERYOBJS_H\r
+\r
+// wxWindows headers\r
+#include <wx/wx.h>\r
+#include <wx/textctrl.h>\r
+\r
+// App headers\r
+#include "gqb/gqbTable.h"\r
+#include "gqb/gqbColumn.h"\r
+#include "gqb/gqbObjectCollection.h"\r
+\r
+#define MAXRECTANGLES 10\r
+\r
+class gqbQueryObject;\r
+class gqbQueryJoin;\r
+\r
+// GQB-TODO: Add all kinds of joins\r
+enum type_Join\r
+{\r
+    _equally,\r
+    _lesser,\r
+    _greater,\r
+    _equlesser,\r
+    _equgreater\r
+\r
+};\r
+\r
+// Collection of main Query Objects [Tables]\r
+class gqbQueryObjs : public gqbObjectCollection\r
+{\r
+public:\r
+    gqbQueryObjs();                                                            // No destructor, the base destructor destroy collection \r
+                                                                                               // the unique dynamic object in this class\r
+    void addTable(gqbQueryObject *mtable);             // Uses alias to only allow operations I want to do it.\r
+    void removeTable(gqbQueryObject *mtable);\r
+    gqbIteratorBase* createQueryIterator();\r
+    gqbIteratorBase* createDownQueryIterator();\r
+       int tablesCount();\r
+    void removeAllQueryObjs();\r
+};\r
+\r
+// Collection of main Table Objects [Columns] have joins too but in a new variable\r
+class gqbQueryObject : public gqbObjectCollection\r
+{\r
+public:\r
+    gqbQueryObject(gqbTable *table);\r
+    ~gqbQueryObject();\r
+    gqbTable *parent;\r
+    wxPoint position;\r
+    void setSelected(bool value);\r
+    bool getSelected();\r
+    void setWidth(int value);\r
+    int getWidth();\r
+    void setHeight(int value);\r
+    int getHeight();\r
+    void removeColumn(gqbColumn *column);              // Used only as synonym for gqbObjectCollection removeObject\r
+    void addColumn(gqbColumn *column);                 // Used only as synonym for gqbObjectCollection addObject\r
+    int getColumnIndex(gqbColumn *column);\r
+    bool existsColumn(gqbColumn *column);\r
+    gqbIteratorBase* createQueryTableIterator();\r
+    gqbIteratorBase* createJoinsIterator();\r
+    gqbIteratorBase* createRegJoinsIterator();\r
+    gqbQueryJoin* addJoin(gqbQueryObject *owner, gqbQueryObject *observable, gqbColumn *source, gqbColumn *destination, type_Join kind);\r
+    void removeJoin(gqbQueryJoin *join, bool unRegister);\r
+    void registerJoin(gqbQueryJoin *join);\r
+    void unregisterJoin(gqbQueryJoin *join, bool removeIt);\r
+    bool getHaveJoins();\r
+    bool getHaveRegJoins();\r
+    void setAlias(wxString name){alias=name;};\r
+    wxString getAlias();\r
+\r
+private:\r
+    bool haveUpperCase(wxString &str);\r
+    bool selected;\r
+    wxString alias;\r
+    int width;\r
+    int height;\r
+    bool haveJoins, haveRegisteredJoins;\r
+    gqbCollection *joinsCollection, *registeredCollection;\r
+    gqbArrayCollection *implementationj, *implementationr ;\r
+\r
+};\r
+\r
+// A Join Object\r
+class gqbQueryJoin : public gqbObject\r
+{\r
+public:\r
+    gqbQueryJoin(gqbQueryObject *_owner, gqbQueryObject *_destination, gqbColumn *sourceCol, gqbColumn *destCol, type_Join joinKind);\r
+    void setKindofJoin(type_Join join);\r
+    type_Join getKindofJoin();\r
+    gqbQueryObject* getSourceQTable();\r
+    gqbQueryObject* getDestQTable();\r
+    gqbColumn* getDCol();\r
+    gqbColumn* getSCol();\r
+    const wxString& getSourceTable();\r
+    const wxString& getDestTable();\r
+    const wxString& getSourceCol();\r
+    const wxString& getDestCol();\r
+    void setSourceAnchor(wxPoint pt);\r
+    void setDestAnchor(wxPoint pt);\r
+    wxPoint& getSourceAnchor();\r
+    wxPoint& getDestAnchor();\r
+    void setSelected(bool value);\r
+    bool getSelected();\r
+    void setAnchorsUsed(wxPoint pt);\r
+    wxPoint& getAnchorsUsed();\r
+\r
+private:\r
+    bool selected;\r
+    type_Join kindofJoin;\r
+    gqbColumn *sCol, *dCol;\r
+    gqbQueryObject *owner, *destination;\r
+    wxPoint sAnchor, dAnchor;         // The source/destination anchor points of the join (for same join)\r
+    wxPoint anchorsUsed;\r
+};\r
+\r
+// A Restriction Object\r
+class gqbQueryRestriction : public gqbObject\r
+{\r
+public:\r
+    gqbQueryRestriction();\r
+    wxString& getLeft(){return leftPart;};\r
+    wxString& getRestriction(){return restriction;};\r
+    wxString& getValue_s(){return value_s;};\r
+    wxString& getConnector(){return connector;};\r
+    void setLeft(const wxString& value){leftPart=value;};\r
+    void setRestriction(const wxString& value){restriction=value;};\r
+    void setValue_s(const wxString& value){value_s=value;};\r
+    void setConnector(const wxString& value){connector=value;};\r
+\r
+private:\r
+    wxString leftPart;\r
+    wxString restriction;\r
+    wxString value_s;\r
+    wxString connector;\r
+};\r
+\r
+// Collection of restrictions for a where clause\r
+class gqbRestrictions : public gqbObjectCollection\r
+{\r
+public:\r
+    gqbRestrictions();\r
+    ~gqbRestrictions();\r
+       \r
+    void addRestriction(gqbQueryRestriction *r);\r
+    void removeRestriction(gqbQueryRestriction *r);\r
+    void deleteAllRestrictions();\r
+    gqbIteratorBase* createRestrictionsIterator();\r
+    void addRestrictionAt(gqbQueryRestriction *r, int index);\r
+    int restrictionsCount();\r
+    gqbQueryRestriction* getRestrictionAt(int index);\r
+\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbSchema.h b/pgadmin/include/gqb/gqbSchema.h
new file mode 100644 (file)
index 0000000..85ee607
--- /dev/null
@@ -0,0 +1,30 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbSchema.h - Schema object for GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBSCHEMA_H\r
+#define GQBSCHEMA_H\r
+\r
+// App headers\r
+#include "gqb/gqbObject.h"\r
+#include "gqb/gqbTable.h"\r
+\r
+class gqbSchema : public gqbObject\r
+{\r
+public:\r
+    gqbSchema(gqbObject *parent, wxString name, type_gqbObject type);\r
+    void createObjects(gqbBrowser *_tablesBrowser,  pgConn *_conn, OID oidVal, wxTreeItemId parentNode, int _tableImage, int _viewImage);\r
+\r
+private:\r
+    pgConn *conn;\r
+    wxString NumToStr(OID value);\r
+    void createTables(pgConn *conn, gqbBrowser *tablesBrowser, wxTreeItemId parentNode, OID oidVal, int _tableImage, int _viewImage);\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbTable.h b/pgadmin/include/gqb/gqbTable.h
new file mode 100644 (file)
index 0000000..aba9791
--- /dev/null
@@ -0,0 +1,39 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbTable.h - Table object for GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBTABLE_H\r
+#define GQBTABLE_H\r
+\r
+// App headers\r
+#include "gqb/gqbObject.h"\r
+#include "gqb/gqbBrowser.h"\r
+#include "gqb/gqbObjectCollection.h"\r
+\r
+class gqbColumn;\r
+\r
+// Create Array Objects used as base for gqbCollections\r
+class gqbTable : public gqbObjectCollection\r
+{\r
+public:\r
+    gqbTable(gqbObject *parent, wxString name, type_gqbObject type);\r
+    void createObjects(gqbBrowser *_tablesBrowser,  pgConn *_conn, OID oidVal, wxTreeItemId parentNode);\r
+    gqbIteratorBase* createColumnsIterator();\r
+    int countCols();\r
+    gqbColumn* getColumnAtIndex(int index);\r
+    int indexColumn(gqbColumn *col);\r
+\r
+private:\r
+    wxString NumToStr(OID value);\r
+    void addColumn(gqbColumn *column);    // Used only as synonym for gqbObjectCollection addObject\r
+    void createColumns(pgConn *conn, gqbBrowser *tablesBrowser, wxTreeItemId parentNode,  OID oidVal);\r
+\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbViewController.h b/pgadmin/include/gqb/gqbViewController.h
new file mode 100644 (file)
index 0000000..fd504da
--- /dev/null
@@ -0,0 +1,167 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbViewController.h - View and Controller implementation for MVC Pattern of GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBCONTROLLER_H\r
+#define GQBCONTROLLER_H\r
+\r
+#include <wx/dcbuffer.h>\r
+#include <wx/notebook.h>\r
+#include <wx/splitter.h>\r
+#include <wx/dnd.h>\r
+#include <wx/dataobj.h>\r
+\r
+// App headers\r
+#include "gqb/gqbObject.h"\r
+#include "gqb/gqbModel.h"\r
+#include "gqb/gqbQueryObjs.h"\r
+#include "gqb/gqbGraphBehavior.h"\r
+#include "gqb/gqbColumn.h"\r
+#include "gqb/gqbGridProjTable.h"\r
+#include "gqb/gqbGridRestTable.h"\r
+#include "gqb/gqbGridOrderTable.h"\r
+#include "gqb/gqbBrowser.h"\r
+\r
+class gqbView;\r
+\r
+enum pointerMode\r
+{\r
+    pt_normal,\r
+    pt_join\r
+};\r
+\r
+// Utility Class to avoid a bug when the event sash resize is called\r
+class gqbSplitter: public wxSplitterWindow\r
+{\r
+public:\r
+    gqbSplitter(wxWindow* parent, wxWindowID id, const wxPoint& point, const wxSize& size, long style);\r
+    void setTablesBrowser(gqbBrowser *b){tablesBrowser=b;};\r
+    void setBrowserPanel(wxPanel *p){browserPanel=p;};\r
+\r
+private:\r
+    void onVerticalSashResize(wxSplitterEvent& event);\r
+    gqbBrowser *tablesBrowser;        // tables Browser Tree\r
+    wxPanel *browserPanel;            // Container of tables Browser Tree\r
+    DECLARE_EVENT_TABLE()\r
+};\r
+\r
+class gqbController: public wxObject\r
+{\r
+public:\r
+    gqbController(gqbModel *_model, wxWindow *gqbParent, wxNotebook *gridParent, wxSize size);\r
+    ~gqbController();\r
+    void addTableToModel(gqbTable *table, wxPoint p);\r
+    gqbQueryJoin* addJoin(gqbQueryObject *sTable, gqbColumn *sColumn, gqbQueryObject *dTable, gqbColumn *dColumn, type_Join kind);\r
+    void removeJoin(gqbQueryJoin *join);\r
+    void removeTableFromModel(gqbQueryObject *table, gqbGridProjTable *gridTable, gqbGridOrderTable *orderLTable, gqbGridOrderTable *orderRTable);\r
+    void unsetModelSelected(bool queryTable);\r
+    void processColumnInModel(gqbQueryObject *table, gqbColumn *column, gqbGridProjTable *gridTable);\r
+    void setPointerMode(pointerMode pm);      // Find selected table with their coordinates point\r
+    gqbView* getView(){return view;};\r
+    void nullView() {view=NULL;};\r
+    gqbObject* getModelSelected(wxPoint &pt, gqbQueryObject *lastSelected, gqbQueryJoin *lastJoinSelected, bool mark);\r
+    wxString generateSQL();\r
+    wxSplitterWindow* getViewContainer(){return gqbMainContainer;};\r
+    wxSplitterWindow* getDialogParent(){return (wxSplitterWindow*) gqbContainer;};\r
+    void setSashVertPosition(int pos);\r
+    void setSashHorizPosition(int pos);\r
+       int getSashHorizPosition();\r
+       gqbBrowser* getTablesBrowser(){return tablesBrowser;};\r
+    wxNotebook* getTabs(){return tabs;};\r
+    void emptyModel();\r
+    void calcGridColsSizes();\r
+    gqbQueryRestriction* addRestriction();\r
+\r
+protected:\r
+    gqbView *view;                                             // owned by caller application shouldn't be destroy by this class\r
+    wxWindow *pparent;                                 // GQB-TODO: deberia ser privada no se porque no funciona [la estoy usando?]\r
+    gqbModel *model;                                   // owned by caller application shouldn't be destroy by this class\r
+    wxNotebook *tabs;\r
+    gqbSplitter *gqbContainer;                 // container of canvas & tables browser.\r
+    wxSplitterWindow *gqbMainContainer;\r
+    gqbBrowser *tablesBrowser;                 // tables Browser Tree\r
+    wxPanel *browserPanel;                             // Container of tables Browser Tree\r
+};\r
+\r
+class gqbView: public wxScrolledWindow\r
+{\r
+public:\r
+    gqbView(wxWindow *gqbParent, wxNotebook *gridParent, wxSize size, gqbController *controller, gqbModel *model);\r
+    ~gqbView();\r
+    void drawAll(wxBufferedDC& bdc);\r
+    void setPointerMode(pointerMode pm);\r
+\r
+       // Events for wxScrolledWindow\r
+    void onPaint(wxPaintEvent& event);\r
+    void onMotion(wxMouseEvent& event);\r
+    void onDoubleClick(wxMouseEvent& event);\r
+    void onRightClick(wxMouseEvent& event);\r
+    void onErase(wxEraseEvent& event);\r
+    void onEraseBackGround(wxEraseEvent& event);\r
+    void OnKeyDown(wxKeyEvent& event);\r
+    wxPanel* getColsGridPanel(){ return (wxPanel*)projectionPanel; };\r
+    wxPanel* getCriteriaPanel(){ return (wxPanel*)criteriaPanel; };\r
+    wxPanel* getOrderPanel(){ return (wxPanel*)orderPanel; };\r
+    void newTableAdded(gqbQueryObject *item);\r
+    bool clickOnJoin (gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest);\r
+\r
+       // Functions for all gqb extra Panels (projection, criteria..)\r
+    void emptyPanelsData();\r
+\r
+private:\r
+    gqbController *controller;                                                                 // owned by caller application shouldn't be destroy \r
+                                                                                                                               // by this class\r
+    gqbModel *model;                                                                                   // owned by caller application shouldn't be destroy \r
+                                                                                                                               // by this class\r
+    gqbGraphBehavior *graphBehavior;                                                   // This points to the Graph behavior for objects, \r
+                                                                                                                               // if change the way objects were draw changes too.\r
+    gqbIteratorBase *iterator;                                                                 //include here for reuse of iterator, should be \r
+                                                                                                                               // delete when class destroy\r
+    wxPanel *projectionPanel, *criteriaPanel, *orderPanel;\r
+    gqbGridProjTable *gridTable;                                                               // Data model for the columns grid internals\r
+    gqbGridRestTable *restrictionsGridTable;                                   // Data model for restricions grid internals\r
+                          \r
+    gqbGridOrderTable *orderByLGridTable, *orderByRGridTable;  // Data model for order by grid internals\r
+    wxSize canvasSize;\r
+    bool changeTOpressed;\r
+    \r
+       // just a point to the selected item on the collection, shouldn't be destroy inside this class\r
+    gqbQueryObject *collectionSelected, *joinSource, *joinDest, *cTempSelected;\r
+    gqbQueryJoin *joinSelected, *jTempSelected;\r
+    gqbColumn *joinSCol, *joinDCol;\r
+    int pressed, selected, refreshRate;\r
+    wxPoint pos, jpos;            // Position of the last event of the mouse & the first event of a join event\r
+    pointerMode mode;             // pointer is used as normally or as in joins by example\r
+    wxImage joinCursorImage;\r
+    wxCursor joinCursor;\r
+    wxMenu *m_rightJoins, *m_rightTables;\r
+    void OnMenuJoinDelete(wxCommandEvent& event);\r
+    void OnMenuTableDelete(wxCommandEvent& event);\r
+    void OnMenuJoinSetType(wxCommandEvent& event);\r
+    void OnMenuTableSetAlias(wxCommandEvent& event);\r
+    wxArrayString joinTypeChoices;\r
+    DECLARE_EVENT_TABLE()\r
+};\r
+\r
+// A drop target that do nothing only accept text, if accept then tree add table to model\r
+class DnDText : public wxTextDropTarget\r
+{\r
+public:\r
+    DnDText(gqbBrowser *tablesBrowser) { tree=tablesBrowser;}\r
+    virtual bool OnDropText(wxCoord x, wxCoord y, const wxString& text)\r
+    {\r
+        tree->setDnDPoint(x,y);\r
+        return true;\r
+    }\r
+\r
+private:\r
+    gqbBrowser *tree;\r
+};\r
+#endif\r
diff --git a/pgadmin/include/gqb/gqbViewPanels.h b/pgadmin/include/gqb/gqbViewPanels.h
new file mode 100644 (file)
index 0000000..9f28cd1
--- /dev/null
@@ -0,0 +1,188 @@
+//////////////////////////////////////////////////////////////////////////\r
+//\r
+// pgAdmin III - PostgreSQL Tools\r
+// RCS-ID:      $Id: frmQuery.cpp 7381 2008-08-11 11:33:42Z dpage $\r
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+// This software is released under the Artistic Licence\r
+//\r
+// gqbViewPanels.h - All panels used by GQB\r
+//\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef GQBVIEWPANELS_H\r
+#define GQBVIEWPANELS_H\r
+\r
+#include <wx/minifram.h>\r
+\r
+// App headers\r
+#include "gqb/gqbGridProjTable.h"\r
+#include "gqb/gqbGridRestTable.h"\r
+#include "gqb/gqbGridOrderTable.h"\r
+\r
+enum gridColsButton\r
+{\r
+    buttonUp_ID,\r
+    buttonUpTop_ID,\r
+    buttonDown_ID,\r
+    buttonDownBottom_ID,\r
+    addButton_ID,\r
+    dropButton_ID\r
+};\r
+\r
+//\r
+//   Projection Panel\r
+//\r
+\r
+class gqbGridPanel: public wxPanel\r
+{\r
+public:\r
+    gqbGridPanel(wxWindow* parent, wxWindowID id, gqbGridProjTable *gridModel);\r
+    ~gqbGridPanel();\r
+    wxBitmapButton *buttonUp, *buttonDown, *buttonUpTop, *buttonDownBottom;\r
+    wxBitmap upBitmap, upTopBitmap, downBitmap, downBottomBitmap;\r
+    void SetGridColsSize();\r
+\r
+       // Events for wxGrid\r
+    void OnGridSelectCell( wxGridEvent& ev );\r
+    void OnGridRangeSelected( wxGridRangeSelectEvent& ev );\r
+    void OnButtonUp(wxCommandEvent&);\r
+    void OnButtonUpTop(wxCommandEvent&);\r
+    void OnButtonDown(wxCommandEvent&);\r
+    void OnButtonDownBottom(wxCommandEvent&);\r
+\r
+private:\r
+    bool allowSelCells;\r
+    int selTop,selBottom;         // Range Selection of wxGrid, -1 it's value not set.\r
+    wxGrid *colsGrid;             // Columns Grid used for order of columns in sentence & single row functions\r
+    gqbGridProjTable *gModel;\r
+    DECLARE_EVENT_TABLE()\r
+};\r
+\r
+//\r
+//   Panels reusable components\r
+//\r
+\r
+class gqbColsTree : public wxTreeCtrl\r
+{\r
+public:\r
+    gqbColsTree(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style);\r
+    wxTreeItemId& createRoot(wxString &Name);\r
+    wxTreeItemId& getRootNode(){return rootNode;}\r
+    void refreshTree(gqbModel *model);\r
+\r
+private:\r
+    wxTreeItemId rootNode;\r
+};\r
+\r
+enum\r
+{\r
+    QR_TREE_OK = 9100,\r
+    QR_TREE\r
+};\r
+\r
+class gqbColsPopUp: public wxDialog\r
+{\r
+public:\r
+    gqbColsPopUp(wxWindow* parent, wxWindowID id, wxString title, wxPoint pos, const wxSize size);\r
+    void refreshTree(gqbModel *_model);\r
+    void OnPopUpOKClick(wxCommandEvent& event);\r
+    void OnPopUpTreeClick(wxTreeEvent& event);\r
+    void OnPopUpTreeDoubleClick(wxTreeEvent& event);\r
+    void setEditText(wxString text);\r
+    wxString getEditText(){return editTree->GetValue();};\r
+    void setUsedCell(wxGrid* grid, int row, int col){usedGrid=grid; _row=row; _col=col;};\r
+    void focus();\r
+\r
+private:\r
+    int _row,_col;\r
+    wxGrid *usedGrid;\r
+    gqbColsTree *colsTree;\r
+    wxTextCtrl *editTree;\r
+    wxButton *buttonTree;\r
+    gqbModel *model;              // Not owned shouldn't be deleted at this class\r
+\r
+};\r
+\r
+//\r
+//   Criterias Panel\r
+//\r
+\r
+class wxRestrictionGrid: public wxGrid\r
+{\r
+public:\r
+    wxRestrictionGrid(wxWindow* parent, wxWindowID id);\r
+    void ComboBoxEvent(wxGridEvent& event);\r
+    void RevertSel();\r
+\r
+private:\r
+    wxGridSelection *m_selTemp;\r
+\r
+};\r
+\r
+class gqbCriteriaPanel: public wxPanel\r
+{\r
+public:\r
+    gqbCriteriaPanel(wxWindow* parent, gqbModel *_model, gqbGridRestTable *gridModel);\r
+    void OnCellLeftClick(wxGridEvent& ev);\r
+    void refreshTree(gqbModel *_model);\r
+    void OnButtonAdd(wxCommandEvent&);\r
+    void OnButtonDrop(wxCommandEvent&);\r
+    void SetGridColsSize();\r
+\r
+private:\r
+    wxBitmapButton *buttonAdd, *buttonDrop;\r
+    wxBitmap addBitmap, dropBitmap;\r
+    void showColsPopUp(int row, int col, wxPoint pos);\r
+    gqbGridRestTable *gModel;\r
+    wxGrid *restrictionsGrid;     // Columns Grid used for order of columns in sentence & single row functions\r
+    gqbModel *model;              // Not owned shouldn't be deleted at this class\r
+    gqbColsPopUp *colsPopUp;\r
+    DECLARE_EVENT_TABLE()\r
+\r
+};\r
+\r
+//\r
+// Order by Panel\r
+//\r
+\r
+enum orderButtons\r
+{\r
+    bRem_ID,\r
+    bRemAll_ID,\r
+    bAddAll_ID,\r
+    bAdd_ID,\r
+    bUp_ID,\r
+    bUpTop_ID,\r
+    bDown_ID,\r
+    bDownBottom_ID\r
+};\r
+\r
+class gqbOrderPanel: public wxPanel\r
+{\r
+public:\r
+    gqbOrderPanel(wxWindow* parent, gqbGridOrderTable* gridTableLeft, gqbGridOrderTable* gridTableRight);\r
+    void SetGridColsSize();\r
+\r
+private:\r
+    bool allowSelCells;\r
+    void OnButtonUp(wxCommandEvent&);\r
+    void OnButtonUpTop(wxCommandEvent&);\r
+    void OnButtonDown(wxCommandEvent&);\r
+    void OnButtonDownBottom(wxCommandEvent&);\r
+    void OnButtonRemove(wxCommandEvent&);\r
+    void OnButtonRemoveAll(wxCommandEvent&);\r
+    void OnButtonAdd(wxCommandEvent&);\r
+    void OnButtonAddAll(wxCommandEvent&);\r
+    void OnGridSelectCell( wxGridEvent& ev );\r
+    void OnGridRangeSelected( wxGridRangeSelectEvent& ev );\r
+    void OnCellLeftClick(wxGridEvent& ev);\r
+    int selLeft, selRightTop,selRightBottom;\r
+    gqbGridOrderTable *tableLeft, *tableRight;\r
+    wxGrid *availableColumns, *usedColumns;\r
+    wxBitmapButton *buttonAdd, *buttonAddAll, *buttonRemove, *buttonRemoveAll;\r
+    wxBitmap addBitmap, addAllBitmap, removeBitmap, removeAllBitmap;\r
+    wxBitmapButton *buttonUp, *buttonDown, *buttonUpTop, *buttonDownBottom;\r
+    wxBitmap upBitmap, upTopBitmap, downBitmap, downBottomBitmap;\r
+    DECLARE_EVENT_TABLE()\r
+};\r
+#endif
\ No newline at end of file
diff --git a/pgadmin/include/gqb/module.mk b/pgadmin/include/gqb/module.mk
new file mode 100644 (file)
index 0000000..d518ade
--- /dev/null
@@ -0,0 +1,36 @@
+#######################################################################\r
+#\r
+# pgAdmin III - PostgreSQL Tools\r
+# $Id: module.mk 6929 2008-01-01 23:54:26Z dpage $\r
+# Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
+# This software is released under the Artistic Licence\r
+#\r
+# module.mk - pgadmin/include/gqb/ Makefile fragment\r
+#\r
+#######################################################################\r
+\r
+pgadmin3_SOURCES += \\r
+    $(srcdir)/include/gqb/gqbArrayCollection.h \\r
+    $(srcdir)/include/gqb/gqbBrowser.h \\r
+    $(srcdir)/include/gqb/gqbCollection.h \\r
+    $(srcdir)/include/gqb/gqbCollectionBase.h \\r
+    $(srcdir)/include/gqb/gqbColumn.h \\r
+    $(srcdir)/include/gqb/gqbDatabase.h \\r
+    $(srcdir)/include/gqb/gqbEvents.h \\r
+    $(srcdir)/include/gqb/gqbGraphBehaviour.h \\r
+    $(srcdir)/include/gqb/gqbGraphSimple.h \\r
+    $(srcdir)/include/gqb/gqbGridOrderTable.h \\r
+    $(srcdir)/include/gqb/gqbGridProjTable.h \\r
+    $(srcdir)/include/gqb/gqbGridRestTable.h \\r
+    $(srcdir)/include/gqb/gqbModel.h \\r
+    $(srcdir)/include/gqb/gqbObject.h \\r
+    $(srcdir)/include/gqb/gqbObjectCollection.h \\r
+    $(srcdir)/include/gqb/gqbQueryObjs.h \\r
+    $(srcdir)/include/gqb/gqbSchema.h \\r
+    $(srcdir)/include/gqb/gqbTable.h \\r
+    $(srcdir)/include/gqb/gqbViewController.h \\r
+    $(srcdir)/include/gqb/gqbViewPanels.h\r
+\r
+EXTRA_DIST += \\r
+    $(srcdir)/include/gqb/module.mk\r
+\r
diff --git a/pgadmin/include/images/gqbAddRest.xpm b/pgadmin/include/images/gqbAddRest.xpm
new file mode 100644 (file)
index 0000000..4e56bc0
--- /dev/null
@@ -0,0 +1,74 @@
+/* XPM */\r
+const char * gqbAddRest_xpm[] = {\r
+"19 15 56 1",\r
+"      c None",\r
+".     c #9597B5",\r
+"+     c #787AB4",\r
+"@     c #7073B4",\r
+"#     c #B9BAD9",\r
+"$     c #8183BD",\r
+"%     c #F0F1F3",\r
+"&     c #F0E6FF",\r
+"*     c #E5D8FB",\r
+"=     c #DDD3F4",\r
+"-     c #D9CDF2",\r
+";     c #D3C9EC",\r
+">     c #D0C2EC",\r
+",     c #C9BCE7",\r
+"'     c #C5BCE1",\r
+")     c #EAE7F3",\r
+"!     c #7088B4",\r
+"~     c #D5BDFA",\r
+"{     c #CDB1F9",\r
+"]     c #C6AFEE",\r
+"^     c #C3A7F2",\r
+"/     c #B79CE8",\r
+"(     c #AD92E1",\r
+"_     c #A68BDB",\r
+":     c #9E83D5",\r
+"<     c #967CCE",\r
+"[     c #9075C9",\r
+"}     c #9983CC",\r
+"|     c #888AA8",\r
+"1     c #5A7AAA",\r
+"2     c #BBA7E3",\r
+"3     c #A7A8A9",\r
+"4     c #6F6F6F",\r
+"5     c #A4A6A9",\r
+"6     c #AB97D8",\r
+"7     c #8E73C8",\r
+"8     c #5FE6DB",\r
+"9     c #5BE2D7",\r
+"0     c #856BC2",\r
+"a     c #57DED3",\r
+"b     c #C3B5E1",\r
+"c     c #53DACF",\r
+"d     c #9DA2A7",\r
+"e     c #7D63BC",\r
+"f     c #4ED5CA",\r
+"g     c #49D0C5",\r
+"h     c #45CCC1",\r
+"i     c #40C7BC",\r
+"j     c #BBADDB",\r
+"k     c #6F55B0",\r
+"l     c #3CC3B8",\r
+"m     c #B6A8D7",\r
+"n     c #9AA0A6",\r
+"o     c #AFA2D2",\r
+"p     c #E4E4E4",\r
+"q     c #ABADD3",\r
+".+@@@@@@@@@@@@@@@# ",\r
+"$%&****=--;>>,';)$ ",\r
+"!$*~{]^//(_:<[}'$# ",\r
+" |$=~^//(_:<[}'$1  ",\r
+"  .$=]/(_:<[}'$!   ",\r
+"   .$-2_:<[}3445   ",\r
+"    1$;6<7<'4894   ",\r
+"     |$2706$49a4   ",\r
+"      @b03444ac444d",\r
+"      @be489acfghi4",\r
+"      @jk49acfghil4",\r
+"      @mk5444gh444n",\r
+"      @)oop@4hi4   ",\r
+"      q@@@@q4il4   ",\r
+"            d44n   "};\r
diff --git a/pgadmin/include/images/gqbColNotSel.xpm b/pgadmin/include/images/gqbColNotSel.xpm
new file mode 100644 (file)
index 0000000..13c24b1
--- /dev/null
@@ -0,0 +1,49 @@
+/* XPM */\r
+const char * gqbColNotSel_xpm[] = {\r
+"16 16 30 1",\r
+"      c None",\r
+".     c #9B9B9B",\r
+"+     c #555555",\r
+"@     c #FDFEFE",\r
+"#     c #FBFEFE",\r
+"$     c #F9FCFE",\r
+"%     c #F7FBFE",\r
+"&     c #F4FAFD",\r
+"*     c #F2FAFC",\r
+"=     c #FCFEFE",\r
+"-     c #FAFDFE",\r
+";     c #F7FBFD",\r
+">     c #F5FBFD",\r
+",     c #F3FAFC",\r
+"'     c #F0F9FC",\r
+")     c #F8FCFE",\r
+"!     c #F6FBFD",\r
+"~     c #F3FAFD",\r
+"{     c #F2F9FD",\r
+"]     c #EFF8FC",\r
+"^     c #F9FDFE",\r
+"/     c #F7FCFD",\r
+"(     c #F4FBFD",\r
+"_     c #EDF7FB",\r
+":     c #EEF8FC",\r
+"<     c #ECF7FB",\r
+"[     c #F6FCFD",\r
+"}     c #F2F9FC",\r
+"|     c #EDF8FB",\r
+"1     c #EAF7FB",\r
+"                ",\r
+"                ",\r
+"                ",\r
+"                ",\r
+".++++++.        ",\r
+"+@#$%&*+        ",\r
+"+=-;>,'+        ",\r
+"+-)!~{]+        ",\r
+"+^/(,'_+        ",\r
+"+)>~':<+        ",\r
+"+[&}]|1+        ",\r
+".++++++.        ",\r
+"                ",\r
+"                ",\r
+"                ",\r
+"                "};\r
diff --git a/pgadmin/include/images/gqbColSel.xpm b/pgadmin/include/images/gqbColSel.xpm
new file mode 100644 (file)
index 0000000..6c2ca4e
--- /dev/null
@@ -0,0 +1,63 @@
+/* XPM */\r
+const char * gqbColSel_xpm[] = {\r
+"16 16 44 1",\r
+"      c None",\r
+".     c #9B9B9B",\r
+"+     c #555555",\r
+"@     c #FDFEFE",\r
+"#     c #FBFEFE",\r
+"$     c #F9FCFE",\r
+"%     c #F7FBFE",\r
+"&     c #F1F6F9",\r
+"*     c #ECF6FA",\r
+"=     c #575757",\r
+"-     c #FCFEFE",\r
+";     c #FAFDFE",\r
+">     c #F7FBFD",\r
+",     c #F1F9FC",\r
+"'     c #DEB2B4",\r
+")     c #D8A6AC",\r
+"!     c #5E5B5C",\r
+"~     c #F9FBFC",\r
+"{     c #EDD1D3",\r
+"]     c #EDE7E9",\r
+"^     c #E2CCCD",\r
+"/     c #CD6163",\r
+"(     c #D19196",\r
+"_     c #605F60",\r
+":     c #F3E6E6",\r
+"<     c #D67072",\r
+"[     c #D68587",\r
+"}     c #D1787B",\r
+"|     c #CB7579",\r
+"1     c #D6D7DD",\r
+"2     c #6A7072",\r
+"3     c #F5F8F9",\r
+"4     c #DDA6A8",\r
+"5     c #CD4E50",\r
+"6     c #CA6265",\r
+"7     c #D6C3C9",\r
+"8     c #E2F1F7",\r
+"9     c #656A6C",\r
+"0     c #F2FAFC",\r
+"a     c #E9E6EB",\r
+"b     c #D2959A",\r
+"c     c #D5AFB4",\r
+"d     c #E6F1F5",\r
+"e     c #EAF7FB",\r
+"                ",\r
+"                ",\r
+"                ",\r
+"                ",\r
+".++++++.        ",\r
+"+@#$%&*=        ",\r
+"+-;>,')!        ",\r
+"+~{]^/(_        ",\r
+"+:<[}|12        ",\r
+"+3456789        ",\r
+"+0abcde+        ",\r
+".++++++.        ",\r
+"                ",\r
+"                ",\r
+"                ",\r
+"                "};\r
diff --git a/pgadmin/include/images/gqbDown.xpm b/pgadmin/include/images/gqbDown.xpm
new file mode 100644 (file)
index 0000000..134bf35
--- /dev/null
@@ -0,0 +1,49 @@
+/* XPM */\r
+const char * gqbDown_xpm[] = {\r
+"13 8 38 1",\r
+"      c None",\r
+".     c #8BB161",\r
+"+     c #5A9B13",\r
+"@     c #CEE0A7",\r
+"#     c #BAD381",\r
+"$     c #B2CE71",\r
+"%     c #B0CD6C",\r
+"&     c #AECB67",\r
+"*     c #ADCB62",\r
+"=     c #ABC95E",\r
+"-     c #AAC85A",\r
+";     c #A9C856",\r
+">     c #AFCC63",\r
+",     c #C5DA8D",\r
+"'     c #BAD485",\r
+")     c #9FC353",\r
+"!     c #97BD40",\r
+"~     c #95BB39",\r
+"{     c #92BA33",\r
+"]     c #90B82C",\r
+"^     c #8EB726",\r
+"/     c #94BB2F",\r
+"(     c #AFCC64",\r
+"_     c #BAD483",\r
+":     c #9FC251",\r
+"<     c #96BD3E",\r
+"[     c #94BB38",\r
+"}     c #92B931",\r
+"|     c #97BC38",\r
+"1     c #B1CD69",\r
+"2     c #BAD383",\r
+"3     c #9EC24F",\r
+"4     c #96BC3D",\r
+"5     c #9BBF43",\r
+"6     c #B4CF70",\r
+"7     c #A5C55A",\r
+"8     c #B6D178",\r
+"9     c #CCDFA3",\r
+".+++++++++++.",\r
+"+@#$%&*=-;>,+",\r
+".+')!~{]^/(+.",\r
+" .+_:<[}|1+. ",\r
+"  .+23456+.  ",\r
+"   .+#78+.   ",\r
+"    .+9+.    ",\r
+"     .+.     "};\r
diff --git a/pgadmin/include/images/gqbDownBottom.xpm b/pgadmin/include/images/gqbDownBottom.xpm
new file mode 100644 (file)
index 0000000..2569d06
--- /dev/null
@@ -0,0 +1,38 @@
+/* XPM */\r
+const char * gqbDownBottom_xpm[] = {\r
+"13 8 27 1",\r
+"      c None",\r
+".     c #8BB161",\r
+"+     c #5A9B13",\r
+"@     c #CEE0A7",\r
+"#     c #BAD381",\r
+"$     c #B2CE71",\r
+"%     c #B0CD6C",\r
+"&     c #ADCB62",\r
+"*     c #ABC95E",\r
+"=     c #A9C856",\r
+"-     c #AFCC63",\r
+";     c #C5DA8D",\r
+">     c #BAD485",\r
+",     c #9FC353",\r
+"'     c #97BD40",\r
+")     c #92BA33",\r
+"!     c #90B82C",\r
+"~     c #94BB2F",\r
+"{     c #AFCC64",\r
+"]     c #BAD483",\r
+"^     c #9FC251",\r
+"/     c #94BB38",\r
+"(     c #92B931",\r
+"_     c #B1CD69",\r
+":     c #A5C55A",\r
+"<     c #B6D178",\r
+"[     c #CCDFA3",\r
+" .+++++++++. ",\r
+" +@#$%&*=-;+ ",\r
+" .+>,')!~{+. ",\r
+"  .+]^/(_+.  ",\r
+"   .+#:<+.   ",\r
+"    .+[+.    ",\r
+"     .+.     ",\r
+" .+++++++++. "};\r
diff --git a/pgadmin/include/images/gqbJoin.xpm b/pgadmin/include/images/gqbJoin.xpm
new file mode 100644 (file)
index 0000000..a0ac2c0
--- /dev/null
@@ -0,0 +1,78 @@
+/* XPM */\r
+const char * gqbJoin_xpm[] = {\r
+"16 12 63 1",\r
+"      c None",\r
+".     c #9B9B9C",\r
+"+     c #808080",\r
+"@     c #C0C0C2",\r
+"#     c #949395",\r
+"$     c #F9F9F9",\r
+"%     c #DFDFE1",\r
+"&     c #A6A6A6",\r
+"*     c #767676",\r
+"=     c #DEDEE0",\r
+"-     c #DADADD",\r
+";     c #E2E2E2",\r
+">     c #A1A1A2",\r
+",     c #B2B2B4",\r
+"'     c #707071",\r
+")     c #767677",\r
+"!     c #757475",\r
+"~     c #D3D3D3",\r
+"{     c #929292",\r
+"]     c #F8F8F8",\r
+"^     c #DEDDE0",\r
+"/     c #7A7A7A",\r
+"(     c #858586",\r
+"_     c #A6A6A8",\r
+":     c #A1A1A3",\r
+"<     c #CCCBCF",\r
+"[     c #B2B1B4",\r
+"}     c #828282",\r
+"|     c #474747",\r
+"1     c #F6F6F6",\r
+"2     c #A0A0A0",\r
+"3     c #CDCDCD",\r
+"4     c #757576",\r
+"5     c #69696A",\r
+"6     c #9B9A9D",\r
+"7     c #D8D8DB",\r
+"8     c #C8C8CB",\r
+"9     c #555556",\r
+"0     c #F0F0F0",\r
+"a     c #DCDBDE",\r
+"b     c #7C7C7C",\r
+"c     c #ABABAB",\r
+"d     c #838284",\r
+"e     c #A8A7AA",\r
+"f     c #A5A5A8",\r
+"g     c #C6C6C9",\r
+"h     c #5C5C5E",\r
+"i     c #EDEDED",\r
+"j     c #DBDADD",\r
+"k     c #F7F7F7",\r
+"l     c #8C8C8E",\r
+"m     c #D0CFD3",\r
+"n     c #5D5D5F",\r
+"o     c #EAEAEA",\r
+"p     c #616062",\r
+"q     c #D4D4D7",\r
+"r     c #E8E8E8",\r
+"s     c #DAD9DC",\r
+"t     c #CBCBCD",\r
+"u     c #B7B7BA",\r
+"v     c #B7B7B9",\r
+"w     c #C8C8CA",\r
+"x     c #D4D3D6",\r
+"                ",\r
+"            .+@ ",\r
+"            #$% ",\r
+"          @&*$= ",\r
+" -;>   ,')!~{]^ ",\r
+" =$/(  _:<[}|1^ ",\r
+" =$234 56 7890a ",\r
+" =]bcdefg   hij ",\r
+" =k|lm      no- ",\r
+" =1pq       nrs ",\r
+" qtu        vwx ",\r
+"                "};\r
diff --git a/pgadmin/include/images/gqbJoinCursor.xpm b/pgadmin/include/images/gqbJoinCursor.xpm
new file mode 100644 (file)
index 0000000..0da473a
--- /dev/null
@@ -0,0 +1,38 @@
+/* XPM */\r
+const char * gqbJoinCursor_xpm[] = {\r
+"32 32 3 1",\r
+"      c None",\r
+".     c #000000",\r
+"+     c #FFFFFF",\r
+".                               ",\r
+"..                              ",\r
+".+.                             ",\r
+".++.                            ",\r
+".+++.                           ",\r
+".++++.                          ",\r
+".++....                         ",\r
+".+.                             ",\r
+"..                      ...     ",\r
+".                       .       ",\r
+"                        .       ",\r
+"                      ...       ",\r
+"      ...            .++.       ",\r
+"        .       ......++.       ",\r
+"        .       .    .++.       ",\r
+"        ...     .     ...       ",\r
+"        .++.    .       .       ",\r
+"        .++......       .       ",\r
+"        .++.            .       ",\r
+"        ...             .       ",\r
+"        .               .       ",\r
+"        .               .       ",\r
+"        .               .       ",\r
+"                                ",\r
+"                                ",\r
+"                                ",\r
+"                                ",\r
+"                                ",\r
+"                                ",\r
+"                                ",\r
+"                                ",\r
+"                                "};\r
diff --git a/pgadmin/include/images/gqbOrderAdd.xpm b/pgadmin/include/images/gqbOrderAdd.xpm
new file mode 100644 (file)
index 0000000..21ac094
--- /dev/null
@@ -0,0 +1,30 @@
+/* XPM */\r
+const char * gqbOrderAdd_xpm[] = {\r
+"13 9 18 1",\r
+"      c None",\r
+".     c #8BB161",\r
+"+     c #5A9B13",\r
+"@     c #CEE0A7",\r
+"#     c #BAD381",\r
+"$     c #BAD485",\r
+"%     c #B2CE71",\r
+"&     c #9FC353",\r
+"*     c #BAD483",\r
+"=     c #B0CD6C",\r
+"-     c #97BD40",\r
+";     c #9FC251",\r
+">     c #A9C856",\r
+",     c #94BB2F",\r
+"'     c #B1CD69",\r
+")     c #AFCC63",\r
+"!     c #AFCC64",\r
+"~     c #C5DA8D",\r
+"   .+.       ",\r
+"   +@+.      ",\r
+"   +#$+.     ",\r
+"   +%&*+.    ",\r
+"   +=-;#+.   ",\r
+"   +>,'+.    ",\r
+"   +)!+.     ",\r
+"   +~+.      ",\r
+"   .+.       "};\r
diff --git a/pgadmin/include/images/gqbOrderAddAll.xpm b/pgadmin/include/images/gqbOrderAddAll.xpm
new file mode 100644 (file)
index 0000000..eab1cb1
--- /dev/null
@@ -0,0 +1,30 @@
+/* XPM */\r
+const char * gqbOrderAddAll_xpm[] = {\r
+"13 9 18 1",\r
+"      c None",\r
+".     c #8BB161",\r
+"+     c #5A9B13",\r
+"@     c #CEE0A7",\r
+"#     c #BAD381",\r
+"$     c #BAD485",\r
+"%     c #B2CE71",\r
+"&     c #9FC353",\r
+"*     c #BAD483",\r
+"=     c #B0CD6C",\r
+"-     c #97BD40",\r
+";     c #9FC251",\r
+">     c #A9C856",\r
+",     c #94BB2F",\r
+"'     c #B1CD69",\r
+")     c #AFCC63",\r
+"!     c #AFCC64",\r
+"~     c #C5DA8D",\r
+".+.   .+.    ",\r
+"+@+.  +@+.   ",\r
+"+#$+. +#$+.  ",\r
+"+%&*+.+%&*+. ",\r
+"+=-;#++=-;#+.",\r
+"+>,'+.+>,'+. ",\r
+"+)!+. +)!+.  ",\r
+"+~+.  +~+.   ",\r
+".+.   .+.    "};\r
diff --git a/pgadmin/include/images/gqbOrderRemove.xpm b/pgadmin/include/images/gqbOrderRemove.xpm
new file mode 100644 (file)
index 0000000..f069bd9
--- /dev/null
@@ -0,0 +1,30 @@
+/* XPM */\r
+const char * gqbOrderRemove_xpm[] = {\r
+"13 9 18 1",\r
+"      c None",\r
+".     c #8BB161",\r
+"+     c #5A9B13",\r
+"@     c #CEE0A7",\r
+"#     c #BAD485",\r
+"$     c #BAD381",\r
+"%     c #BAD483",\r
+"&     c #9FC353",\r
+"*     c #B2CE71",\r
+"=     c #9FC251",\r
+"-     c #97BD40",\r
+";     c #B0CD6C",\r
+">     c #B1CD69",\r
+",     c #94BB2F",\r
+"'     c #A9C856",\r
+")     c #AFCC64",\r
+"!     c #AFCC63",\r
+"~     c #C5DA8D",\r
+"       .+.   ",\r
+"      .+@+   ",\r
+"     .+#$+   ",\r
+"    .+%&*+   ",\r
+"   .+$=-;+   ",\r
+"    .+>,'+   ",\r
+"     .+)!+   ",\r
+"      .+~+   ",\r
+"       .+.   "};\r
diff --git a/pgadmin/include/images/gqbOrderRemoveAll.xpm b/pgadmin/include/images/gqbOrderRemoveAll.xpm
new file mode 100644 (file)
index 0000000..1943be4
--- /dev/null
@@ -0,0 +1,30 @@
+/* XPM */\r
+const char * gqbOrderRemoveAll_xpm[] = {\r
+"13 9 18 1",\r
+"      c None",\r
+".     c #8BB161",\r
+"+     c #5A9B13",\r
+"@     c #CEE0A7",\r
+"#     c #BAD485",\r
+"$     c #BAD381",\r
+"%     c #BAD483",\r
+"&     c #9FC353",\r
+"*     c #B2CE71",\r
+"=     c #9FC251",\r
+"-     c #97BD40",\r
+";     c #B0CD6C",\r
+">     c #B1CD69",\r
+",     c #94BB2F",\r
+"'     c #A9C856",\r
+")     c #AFCC64",\r
+"!     c #AFCC63",\r
+"~     c #C5DA8D",\r
+"    .+.   .+.",\r
+"   .+@+  .+@+",\r
+"  .+#$+ .+#$+",\r
+" .+%&*+.+%&*+",\r
+".+$=-;++$=-;+",\r
+" .+>,'+.+>,'+",\r
+"  .+)!+ .+)!+",\r
+"   .+~+  .+~+",\r
+"    .+.   .+."};\r
diff --git a/pgadmin/include/images/gqbRemoveRest.xpm b/pgadmin/include/images/gqbRemoveRest.xpm
new file mode 100644 (file)
index 0000000..58d0410
--- /dev/null
@@ -0,0 +1,126 @@
+/* XPM */\r
+const char * gqbRemoveRest_xpm[] = {\r
+"19 15 108 2",\r
+"      c None",\r
+".     c #9597B5",\r
+"+     c #787AB4",\r
+"@     c #7073B4",\r
+"#     c #B9BAD9",\r
+"$     c #8183BD",\r
+"%     c #F0F1F3",\r
+"&     c #F0E6FF",\r
+"*     c #E5D8FB",\r
+"=     c #DDD3F4",\r
+"-     c #D9CDF2",\r
+";     c #D3C9EC",\r
+">     c #D0C2EC",\r
+",     c #C9BCE7",\r
+"'     c #C5BCE1",\r
+")     c #EAE7F3",\r
+"!     c #7088B4",\r
+"~     c #D5BDFA",\r
+"{     c #CDB1F9",\r
+"]     c #C6AFEE",\r
+"^     c #C3A7F2",\r
+"/     c #B79CE8",\r
+"(     c #AD92E1",\r
+"_     c #A68BDB",\r
+":     c #9E83D5",\r
+"<     c #967CCE",\r
+"[     c #9075C9",\r
+"}     c #9983CC",\r
+"|     c #888AA8",\r
+"1     c #5A7AAA",\r
+"2     c #BBA7E3",\r
+"3     c #AB97D8",\r
+"4     c #8E73C8",\r
+"5     c #CA8D9E",\r
+"6     c #C2191A",\r
+"7     c #A96776",\r
+"8     c #DE6C6C",\r
+"9     c #C92121",\r
+"0     c #DF7777",\r
+"a     c #856BC2",\r
+"b     c #AF4B61",\r
+"c     c #D93D3E",\r
+"d     c #C72425",\r
+"e     c #C52828",\r
+"f     c #DC2E2E",\r
+"g     c #D23B3B",\r
+"h     c #C3B5E1",\r
+"i     c #7D63BC",\r
+"j     c #B82A36",\r
+"k     c #D4363A",\r
+"l     c #FF8787",\r
+"m     c #E84141",\r
+"n     c #C02325",\r
+"o     c #BB272A",\r
+"p     c #DF3131",\r
+"q     c #F95A5B",\r
+"r     c #D72323",\r
+"s     c #6F55B0",\r
+"t     c #B6A8D7",\r
+"u     c #AE384A",\r
+"v     c #E14747",\r
+"w     c #FE7A7A",\r
+"x     c #DD393A",\r
+"y     c #DF3333",\r
+"z     c #FB5E5F",\r
+"A     c #DE2929",\r
+"B     c #D13535",\r
+"C     c #BBADDB",\r
+"D     c #AFA2D2",\r
+"E     c #8471A2",\r
+"F     c #C00B0C",\r
+"G     c #E03536",\r
+"H     c #F45D5D",\r
+"I     c #F25151",\r
+"J     c #DC2A2A",\r
+"K     c #CF3434",\r
+"L     c #8272A4",\r
+"M     c #BE0D0E",\r
+"N     c #DF2E2E",\r
+"O     c #F14646",\r
+"P     c #DB2222",\r
+"Q     c #D03535",\r
+"R     c #E4E4E4",\r
+"S     c #AC374C",\r
+"T     c #DE3839",\r
+"U     c #FC5C5C",\r
+"V     c #DC2929",\r
+"W     c #DB2223",\r
+"X     c #F53C3C",\r
+"Y     c #DB1717",\r
+"Z     c #D13333",\r
+"`     c #ABADD3",\r
+" .    c #B60506",\r
+"..    c #D5201F",\r
+"+.    c #FD5858",\r
+"@.    c #D91C1C",\r
+"#.    c #B92629",\r
+"$.    c #BE2C2F",\r
+"%.    c #DC1515",\r
+"&.    c #F02424",\r
+"*.    c #D20F0F",\r
+"=.    c #9E3435",\r
+"-.    c #C42D2D",\r
+";.    c #DA2020",\r
+">.    c #C42828",\r
+",.    c #C92B2C",\r
+"'.    c #D31010",\r
+").    c #D23A3A",\r
+". + @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ #   ",\r
+"$ % & * * * * = - - ; > > , ' ; ) $   ",\r
+"! $ * ~ { ] ^ / / ( _ : < [ } ' $ #   ",\r
+"  | $ = ~ ^ / / ( _ : < [ } ' $ 1     ",\r
+"    . $ = ] / ( _ : < [ } ' $ !       ",\r
+"      . $ - 2 _ : < [ } ' $ 1         ",\r
+"        1 $ ; 3 < 4 < 5 6 7     8 9 0 ",\r
+"          | $ 2 4 a 3 b c d     e f g ",\r
+"            @ h a i j k l m n o p q r ",\r
+"            @ h i s t u v w x y z A B ",\r
+"            @ C s s D E F G H I J K   ",\r
+"            @ t s s D L M N I O P Q   ",\r
+"            @ ) D D R S T U V W X Y Z ",\r
+"            ` @ @ @  ...+.@.#.$.%.&.*.",\r
+"                    =.-.;.>.    ,.'.)."};\r
diff --git a/pgadmin/include/images/gqbUp.xpm b/pgadmin/include/images/gqbUp.xpm
new file mode 100644 (file)
index 0000000..06f928b
--- /dev/null
@@ -0,0 +1,49 @@
+/* XPM */\r
+const char * gqbUp_xpm[] = {\r
+"13 8 38 1",\r
+"      c None",\r
+".     c #8BB161",\r
+"+     c #5A9B13",\r
+"@     c #CCDFA3",\r
+"#     c #BAD381",\r
+"$     c #A5C55A",\r
+"%     c #B6D178",\r
+"&     c #BAD383",\r
+"*     c #9EC24F",\r
+"=     c #96BC3D",\r
+"-     c #9BBF43",\r
+";     c #B4CF70",\r
+">     c #BAD483",\r
+",     c #9FC251",\r
+"'     c #96BD3E",\r
+")     c #94BB38",\r
+"!     c #92B931",\r
+"~     c #97BC38",\r
+"{     c #B1CD69",\r
+"]     c #BAD485",\r
+"^     c #9FC353",\r
+"/     c #97BD40",\r
+"(     c #95BB39",\r
+"_     c #92BA33",\r
+":     c #90B82C",\r
+"<     c #8EB726",\r
+"[     c #94BB2F",\r
+"}     c #AFCC64",\r
+"|     c #CEE0A7",\r
+"1     c #B2CE71",\r
+"2     c #B0CD6C",\r
+"3     c #AECB67",\r
+"4     c #ADCB62",\r
+"5     c #ABC95E",\r
+"6     c #AAC85A",\r
+"7     c #A9C856",\r
+"8     c #AFCC63",\r
+"9     c #C5DA8D",\r
+"     .+.     ",\r
+"    .+@+.    ",\r
+"   .+#$%+.   ",\r
+"  .+&*=-;+.  ",\r
+" .+>,')!~{+. ",\r
+".+]^/(_:<[}+.",\r
+"+|#123456789+",\r
+".+++++++++++."};\r
diff --git a/pgadmin/include/images/gqbUpTop.xpm b/pgadmin/include/images/gqbUpTop.xpm
new file mode 100644 (file)
index 0000000..f9e1bfb
--- /dev/null
@@ -0,0 +1,38 @@
+/* XPM */\r
+const char * gqbUpTop_xpm[] = {\r
+"13 8 27 1",\r
+"      c None",\r
+".     c #8BB161",\r
+"+     c #5A9B13",\r
+"@     c #CCDFA3",\r
+"#     c #BAD381",\r
+"$     c #A5C55A",\r
+"%     c #B6D178",\r
+"&     c #BAD483",\r
+"*     c #9FC251",\r
+"=     c #94BB38",\r
+"-     c #92B931",\r
+";     c #B1CD69",\r
+">     c #BAD485",\r
+",     c #9FC353",\r
+"'     c #97BD40",\r
+")     c #92BA33",\r
+"!     c #90B82C",\r
+"~     c #94BB2F",\r
+"{     c #AFCC64",\r
+"]     c #CEE0A7",\r
+"^     c #B2CE71",\r
+"/     c #B0CD6C",\r
+"(     c #ADCB62",\r
+"_     c #ABC95E",\r
+":     c #A9C856",\r
+"<     c #AFCC63",\r
+"[     c #C5DA8D",\r
+" .+++++++++. ",\r
+"     .+.     ",\r
+"    .+@+.    ",\r
+"   .+#$%+.   ",\r
+"  .+&*=-;+.  ",\r
+" .+>,')!~{+. ",\r
+" +]#^/(_:<[+ ",\r
+" .+++++++++. "};\r
index 8e38e1efa491922f6875fbb5c9d778d224680cd4..97e181450ceca9d53582180ff817de04a85e1c91 100644 (file)
@@ -30,5 +30,6 @@ include $(srcdir)/include/images/module.mk
 include $(srcdir)/include/parser/module.mk
 include $(srcdir)/include/schema/module.mk
 include $(srcdir)/include/slony/module.mk
+include $(srcdir)/include/gqb/module.mk
 include $(srcdir)/include/utils/module.mk
 
index b6e7fb99238d59d2fdc5dd6e32f7200e3595d41f..b168d9e4a4b6a8785b4593b23b896356c46afff6 100644 (file)
 #include "frm/frmStatus.h"\r
 #include "frm/menu.h"\r
 \r
+#include "gqb/gqbArrayCollection.h"\r
+#include "gqb/gqbBrowser.h"\r
+#include "gqb/gqbCollection.h"\r
+#include "gqb/gqbCollectionBase.h"\r
+#include "gqb/gqbColumn.h"\r
+#include "gqb/gqbDatabase.h"\r
+#include "gqb/gqbEvents.h"\r
+#include "gqb/gqbGraphBehavior.h"\r
+#include "gqb/gqbGraphSimple.h"\r
+#include "gqb/gqbGridOrderTable.h"\r
+#include "gqb/gqbGridProjTable.h"\r
+#include "gqb/gqbGridRestTable.h"\r
+#include "gqb/gqbModel.h"\r
+#include "gqb/gqbObject.h"\r
+#include "gqb/gqbObjectCollection.h"\r
+#include "gqb/gqbQueryObjs.h"\r
+#include "gqb/gqbSchema.h"\r
+#include "gqb/gqbTable.h"\r
+#include "gqb/gqbViewController.h"\r
+#include "gqb/gqbViewPanels.h"\r
+\r
 #include "schema/edbPackage.h"\r
 #include "schema/edbPackageFunction.h"\r
 #include "schema/edbPackageVariable.h"\r
index a7685dbf2e9d568557319ed62f82928ff714d28d..f68573d0615c0ab9f9c5900e917573c3c091fc15 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>\r
 <VisualStudioProject\r
        ProjectType="Visual C++"\r
-       Version="8.00"\r
+       Version="8,00"\r
        Name="pgAdmin3"\r
        ProjectGUID="{5C2D73BA-1F24-48F8-8233-85F5D672AA6A}"\r
        RootNamespace="pgAdmin3"\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               AdditionalDependencies="wxbase28ud.lib wxbase28ud_xml.lib wxbase28ud_net.lib wxmsw28ud_adv.lib wxmsw28ud_core.lib wxmsw28ud_html.lib wxmsw28ud_aui.lib wxregexud.lib wxpngd.lib wxzlibd.lib wxjpegd.lib wxtiffd.lib wxmsw28ud_stc.lib wxmsw28ud_ogl.lib wxmsw28ud_xrc.lib wxexpatd.lib libpq.lib libxml2.lib libxslt.lib iconv_a.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib"\r
+                               AdditionalDependencies="wxbase28ud.lib wxbase28ud_xml.lib wxbase28ud_net.lib wxmsw28ud_adv.lib wxmsw28ud_core.lib wxmsw28ud_html.lib wxmsw28ud_aui.lib wxregexud.lib wxpngd.lib wxzlibd.lib wxjpegd.lib wxtiffd.lib wxmsw28ud_stc.lib wxmsw28ud_ogl.lib wxmsw28ud_xrc.lib wxexpatd.lib libpq.lib libxml2.lib libxslt.lib iconv_a.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib oleaut32.lib ole32.lib shell32.lib odbc32.lib"\r
                                OutputFile=".\Debug/pgAdmin3.exe"\r
                                LinkIncremental="2"\r
                                SuppressStartupBanner="true"\r
                                GenerateMapFile="true"\r
                                MapFileName=".\Debug/pgAdmin3.map"\r
                                SubSystem="2"\r
+                               ResourceOnlyDLL="false"\r
                                TargetMachine="1"\r
                        />\r
                        <Tool\r
                                        >\r
                                </File>\r
                        </Filter>\r
+                       <Filter\r
+                               Name="gqb"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbArrayCollection.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbBrowser.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbCollection.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbCollectionBase.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbColumn.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbDatabase.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbEvents.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbGraphBehavior.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbGraphSimple.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbGridOrderTable.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbGridProjTable.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbGridRestTable.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbModel.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbObject.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbObjectCollection.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbQueryObjs.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbSchema.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbTable.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbViewController.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\include\gqb\gqbViewPanels.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
                </Filter>\r
                <Filter\r
                        Name="schema"\r
                                >\r
                        </File>\r
                </Filter>\r
+               <Filter\r
+                       Name="gqb"\r
+                       >\r
+                       <File\r
+                               RelativePath=".\gqb\gqbArrayCollection.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbBrowser.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbCollection.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbColumn.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbController.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbDatabase.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbGraphSimple.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbGridOrderTable.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbGridProjTable.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbGridRestTable.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbModel.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbObject.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbObjectCollection.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbQueryObjs.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbSchema.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbTable.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbView.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\gqb\gqbViewPanels.cpp"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
                <File\r
                        RelativePath="Makefile.am"\r
                        >\r
index d9147e1a58eeef80b71e8d15f78cde0b83a9771c..34d391dac1edae7883ffe77f209aaaa3fb7b2311 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>\r
 <VisualStudioProject\r
        ProjectType="Visual C++"\r
-       Version="8.00"\r
+       Version="8,00"\r
        Name="pgaevent"\r
        ProjectGUID="{71AF025C-C835-4501-89CF-A94EB3B14401}"\r
        RootNamespace="pgaevent"\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
+                               AdditionalDependencies="comctl32.lib rpcrt4.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib oleaut32.lib ole32.lib shell32.lib odbc32.lib"\r
                                OutputFile=".\Debug/pgaevent.dll"\r
                                LinkIncremental="2"\r
                                SuppressStartupBanner="true"\r
index 3e8ef6d967390d454b4bb486f3f646f4274a4390..8aedd22f7ea3f465e9966d92c72e9f11bc09fbb2 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>\r
 <VisualStudioProject\r
        ProjectType="Visual C++"\r
-       Version="8.00"\r
+       Version="8,00"\r
        Name="pgAgent"\r
        ProjectGUID="{7D082D30-F35A-42DA-A7E3-188EE6E67C7D}"\r
        RootNamespace="pgAgent"\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               AdditionalDependencies="libpq.lib wxbase28ud.lib wxbase28ud_xml.lib wxbase28ud_net.lib wxmsw28ud_adv.lib wxmsw28ud_core.lib wxregexud.lib wxzlibd.lib wxexpatd.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib"\r
+                               AdditionalDependencies="libpq.lib wxbase28ud.lib wxbase28ud_xml.lib wxbase28ud_net.lib wxmsw28ud_adv.lib wxmsw28ud_core.lib wxregexud.lib wxzlibd.lib wxexpatd.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib oleaut32.lib ole32.lib shell32.lib odbc32.lib"\r
                                OutputFile=".\Debug/pgAgent.exe"\r
                                LinkIncremental="2"\r
                                SuppressStartupBanner="true"\r