Index: ctl/ctlSQLResult.cpp
===================================================================
--- ctl/ctlSQLResult.cpp	(revision 4990)
+++ ctl/ctlSQLResult.cpp	(working copy)
@@ -11,6 +11,7 @@
 
 // wxWindows headers
 #include <wx/wx.h>
+#include <wx/clipbrd.h>
 
 #include "pgConn.h"
 #include "ctl/ctlSQLResult.h"
@@ -20,10 +21,12 @@
 
 
 ctlSQLResult::ctlSQLResult(wxWindow *parent, pgConn *_conn, wxWindowID id, const wxPoint& pos, const wxSize& size)
-: wxListView(parent, id, pos, size, wxLC_REPORT | wxSUNKEN_BORDER)
+: wxGrid(parent, id, pos, size, wxWANTS_CHARS|wxVSCROLL|wxHSCROLL)
 {
     conn=_conn;
     thread=0;
+    CreateGrid(0, 0);
+    EnableEditing(false);
 }
 
 
@@ -40,12 +43,6 @@
 }
 
 
-void ctlSQLResult::SelectAll()
-{
-	for (int i = 0; i < GetItemCount(); i++)
-		Select(i);
-}
-
 bool ctlSQLResult::Export()
 {
     if (rowsRetrieved>0 || (thread && thread->DataSet()->NumRows() > 0))
@@ -66,23 +63,46 @@
 
 wxString ctlSQLResult::GetExportLine(int row)
 {
-    if (GetColumnCount() <= 1)
+    return GetExportLine(row, 0, GetNumberCols() - 1);
+}
+
+wxString ctlSQLResult::GetExportLine(int row, int col1, int col2)
+{
+    wxArrayInt cols;
+    wxString str;
+    int i;
+
+    if (col2 < col1)
+        return str;
+
+    cols.Alloc(col2 - col1 + 1);
+    for (i = col1; i <= col2; i++) {
+        cols.Add(i);
+    }
+
+    return GetExportLine(row, cols);
+}
+
+
+wxString ctlSQLResult::GetExportLine(int row, wxArrayInt cols)
+{
+    if (GetNumberCols() <= 1)
         return GetItemText(row);
 
     wxString str;
-    int col;
-    for (col=1 ; col < GetColumnCount() ; col++)
+    unsigned int col;
+    for (col=0 ; col < cols.Count() ; col++)
     {
-        if (col > 1)
+        if (col > 0)
             str.Append(settings->GetCopyColSeparator());
 
-        wxString text=GetItemText(row, col);
+        wxString text = GetCellValue(row, cols[col]);
 
 		bool needQuote  = false;
 		if (settings->GetCopyQuoting() == 1)
 		{
 			/* Quote strings only */
-			switch (colTypClasses.Item(col))
+			switch (colTypClasses.Item(cols[col]))
 			{
 			case PGTYPCLASS_NUMERIC:
 			case PGTYPCLASS_BOOL:
@@ -112,18 +132,20 @@
 
     colSizes.Empty();
     colHeaders.Empty();
-    int i;
-    wxListItem item;
-    item.SetMask(wxLIST_MASK_TEXT|wxLIST_MASK_WIDTH);
+    int i, num;
 
-    for (i=0 ; i < GetColumnCount() ; i++)
+    for (i=0 ; i < GetNumberCols() ; i++)
     {
-        GetColumn(i, item);
-        colHeaders.Add(item.GetText());
-        colSizes.Add(item.GetWidth());
+        colHeaders.Add(GetColLabelValue(i));
+        colSizes.Add(GetColSize(i));
     }
 
-    ClearAll();
+    num = GetNumberRows();
+    if (num)
+        DeleteRows(0, num);
+    num = GetNumberCols();
+    if (num)
+        DeleteCols(0, num);
 
     rowsRetrieved=0;
     colNames.Empty();
@@ -165,22 +187,17 @@
 
     if (!rowsRetrieved)
     {
-        int w, h;
-        if (colSizes.GetCount() == 1)
-            w = colSizes.Item(0);
-        else
-            GetSize(&w, &h);
-
         colNames.Add(thread->DataSet()->ColName(0));
         colTypes.Add(wxT(""));
         colTypClasses.Add(0L);
 
 
-        InsertColumn(0, thread->DataSet()->ColName(0), wxLIST_FORMAT_LEFT, w);
+        SetColLabelValue(0, thread->DataSet()->ColName(0));
+        SetColLabelAlignment(wxALIGN_LEFT, wxALIGN_TOP);
 
         while (!thread->DataSet()->Eof())
         {
-            InsertItem(rowsRetrieved, thread->DataSet()->GetVal(0));
+            SetCellValue(rowsRetrieved, 0, thread->DataSet()->GetVal(0));
             rowsRetrieved++;
             thread->DataSet()->MoveNext();
         }
@@ -207,8 +224,8 @@
         colTypClasses.Add(0L);
 
         Freeze();
-        InsertColumn(0, _("Row"), wxLIST_FORMAT_RIGHT, 30);
-        colNames.Add(wxT("Row"));
+        AppendCols(nCols);
+        SetColLabelAlignment(wxALIGN_CENTER, wxALIGN_TOP);
 
         size_t hdrIndex=0;
 
@@ -220,7 +237,7 @@
             colTypes.Add(colType);
             colTypClasses.Add(thread->DataSet()->ColTypClass(col));
 
-            wxString colHeader=colName +wxT(" (")+ colType +wxT(")");
+            wxString colHeader = colName + wxT(" (") + colType + wxT(")");
 
             int w;
             if (hdrIndex < colHeaders.GetCount() && colHeaders.Item(hdrIndex) == colHeader)
@@ -236,7 +253,8 @@
                     w=-1;
             }
 
-            InsertColumn(col+1, colHeader, wxLIST_FORMAT_LEFT, w);
+            SetColLabelValue(col, colHeader);
+            SetColSize(col, w);
         }
         Thaw();
     }
@@ -246,7 +264,7 @@
 
     while (chunk-- && !thread->DataSet()->Eof())
     {
-        InsertItem(rowsRetrieved, NumToStr(rowsRetrieved+1L));
+        AppendRows(1);
 
         for (col=0 ; col < nCols ; col++)
         {
@@ -256,7 +274,7 @@
                 if ((int)value.Length() > maxColSize)
                     value = value.Left(maxColSize) + wxT(" (..)");
             }
-            SetItem(rowsRetrieved, col+1, value);
+            SetCellValue(rowsRetrieved, col, value);
         }
         
         thread->DataSet()->MoveNext();
@@ -272,14 +290,9 @@
 wxString ctlSQLResult::GetItemText(int row, int col)
 {
     if (col < 0)
-        return wxListCtrl::GetItemText(row);
-
-    wxListItem item;
-    item.m_mask=wxLIST_MASK_TEXT;
-    item.m_itemId=row;
-    item.m_col=col;
-    GetItem(item);
-    return item.GetText();
+        return GetExportLine(row);
+    else
+        return GetCellValue(row, col);
 }
 
 
@@ -334,3 +347,70 @@
 }
 
 
+void ctlSQLResult::Copy()
+{
+    wxString str;
+    int copied = 0;
+    size_t i;
+
+    if (GetSelectedRows().GetCount()) {
+        wxArrayInt rows = GetSelectedRows();
+
+        for (i=0 ; i < rows.GetCount() ; i++)
+        {
+            str.Append(GetExportLine(rows.Item(i)));
+    
+            if (rows.GetCount() > 1)
+                str.Append(END_OF_LINE);
+        }
+
+        copied = rows.GetCount();
+    }
+    else if (GetSelectedCols().GetCount()) {
+        wxArrayInt cols = GetSelectedCols();
+        size_t numRows = GetNumberRows();
+
+        for (i=0 ; i < numRows ; i++)
+        {
+            str.Append(GetExportLine(i, cols));
+    
+            if (numRows > 1)
+                str.Append(END_OF_LINE);
+        }
+
+        copied = numRows;
+    }
+    else if (GetSelectionBlockTopLeft().GetCount() > 0 &&
+        GetSelectionBlockBottomRight().GetCount() > 0) {
+        unsigned int x1, x2, y1, y2;
+
+        x1 = GetSelectionBlockTopLeft()[0].GetCol();
+        x2 = GetSelectionBlockBottomRight()[0].GetCol();
+        y1 = GetSelectionBlockTopLeft()[0].GetRow();
+        y2 = GetSelectionBlockBottomRight()[0].GetRow();
+
+        for (i = y1; i <= y2; i++) {
+            str.Append(GetExportLine(i, x1, x2));
+
+            if (y2 > y1)
+                str.Append(END_OF_LINE);
+        }
+
+        copied = y2 - y1 + 1;
+    }
+    else {
+        int row, col;
+
+        row = GetGridCursorRow();
+        col = GetGridCursorCol();
+
+        str.Append(GetExportLine(row, col, col));
+        copied = 1;
+    }
+
+    if (copied && wxTheClipboard->Open())
+    {
+        wxTheClipboard->SetData(new wxTextDataObject(str));
+        wxTheClipboard->Close();
+    }
+}
Index: frm/frmExport.cpp
===================================================================
--- frm/frmExport.cpp	(revision 4990)
+++ frm/frmExport.cpp	(working copy)
@@ -156,8 +156,8 @@
     }
     else
     {
-        colCount = data->GetColumnCount();
-        rowCount = data->GetItemCount();
+        colCount = data->GetNumberCols();
+        rowCount = data->GetNumberRows();
         if (colCount > 1) // first col contains row count
             startCol=1;
     }
Index: frm/frmQuery.cpp
===================================================================
--- frm/frmQuery.cpp	(revision 4990)
+++ frm/frmQuery.cpp	(working copy)
@@ -590,27 +590,16 @@
         msgResult->Copy();
     else if (wnd == msgHistory)
         msgHistory->Copy();
-    else if (wnd == sqlResult && sqlResult->GetSelectedItemCount() > 0)
-    {
-        wxString str;
-        int row=-1;
-        while (true)
-        {
-            row = sqlResult->GetNextItem(row, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
-            if (row < 0)
+    else {
+        wxWindow *obj = wnd;
+
+        while (obj != NULL) {
+            if (obj == sqlResult) {
+                sqlResult->Copy();
                 break;
-            
-            str.Append(sqlResult->GetExportLine(row));
-            if (sqlResult->GetSelectedItemCount() > 1)
-                str.Append(END_OF_LINE);
+            }
+            obj = obj->GetParent();
         }
-
-        if (wxTheClipboard->Open())
-        {
-            wxTheClipboard->SetData(new wxTextDataObject(str));
-            wxTheClipboard->Close();
-        }
-
     }
     updateMenu();
 }
Index: include/ctl/ctlSQLResult.h
===================================================================
--- include/ctl/ctlSQLResult.h	(revision 4990)
+++ include/ctl/ctlSQLResult.h	(working copy)
@@ -13,7 +13,7 @@
 #define CTLSQLRESULT_H
 
 // wxWindows headers
-#include <wx/listctrl.h>
+#include <wx/grid.h>
 #include <wx/thread.h>
 
 #include "pgSet.h"
@@ -24,7 +24,7 @@
 
 #define CTLSQL_RUNNING 100  // must be greater than ExecStatusType PGRES_xxx values
 
-class ctlSQLResult : public wxListView 
+class ctlSQLResult : public wxGrid
 {
 public:
     ctlSQLResult(wxWindow *parent, pgConn *conn, wxWindowID id, const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize);
@@ -41,13 +41,14 @@
     int RetrieveOne();
     int Abort();
 
-	void SelectAll();
-
     bool Export();
     bool CanExport() { return rowsRetrieved>0 && colNames.GetCount() > 0; }
 
     wxString GetItemText(int row, int col=-1);
     wxString GetExportLine(int row);
+    wxString GetExportLine(int row, wxArrayInt cols);
+    wxString GetExportLine(int row, int col1, int col2);
+    void Copy();
 
     int RunStatus();
     wxString GetMessagesAndClear();
