Thread: Improved copying from Edit Data Grid - rough patch

Improved copying from Edit Data Grid - rough patch

From
"Edward Di Geronimo Jr."
Date:
Hello,

I want to get involved in helping polish the pgAdmin interface. As a
first step, I've modified the copy for the Edit Data grid to have much
more flexiblity in copying data from the grid. The present code only
allows copying entire rows. With my changes, you can now copy rows,
columns, or the highlighted range.

The attached patch is very rough. The most notable rough spot is it
creates two new overloaded versions of sqlTable::GetExportLine which
duplicate a lot of code from the original. These can definitely be
consolidated, however, I wasn't sure what the preferred style would be
for it.

The next thing I would like to after finishing this is modify the query
windows to display the results in a grid instead of a list. The ability
to copy arbitrary sections of the results would be a huge help in my
daily work. I figured this could would most likely be reusable for that
goal.

Feedback would be appreciated.

Ed
Index: src/frm/frmEditGrid.cpp
===================================================================
--- src/frm/frmEditGrid.cpp    (revision 4983)
+++ src/frm/frmEditGrid.cpp    (working copy)
@@ -323,6 +323,7 @@
 }


+#if 0
 void frmEditGrid::OnCopy(wxCommandEvent &ev)
 {
     wxArrayInt rows=sqlGrid->GetSelectedRows();
@@ -345,8 +346,70 @@
     }
     SetStatusText(wxString::Format(_("%d rows copied to clipboard."), rows.GetCount()));
 }
+#endif

+void frmEditGrid::OnCopy(wxCommandEvent &ev)
+{
+    wxString str;
+    int copied = 0;
+    size_t i;

+    if (sqlGrid->GetSelectedRows().GetCount()) {
+        wxArrayInt rows=sqlGrid->GetSelectedRows();
+
+        for (i=0 ; i < rows.GetCount() ; i++)
+        {
+            str.Append(sqlGrid->GetTable()->GetExportLine(rows.Item(i)));
+
+            if (rows.GetCount() > 1)
+                str.Append(END_OF_LINE);
+        }
+
+        copied = rows.GetCount();
+    }
+    else if (sqlGrid->GetSelectedCols().GetCount()) {
+        wxArrayInt cols=sqlGrid->GetSelectedCols();
+        size_t numRows = sqlGrid->GetNumberRows();
+
+        for (i=0 ; i < numRows ; i++)
+        {
+            str.Append(sqlGrid->GetTable()->GetExportLine(i, cols));
+
+            if (numRows > 1)
+                str.Append(END_OF_LINE);
+        }
+
+        copied = numRows;
+    }
+    else if (sqlGrid->GetSelectionBlockTopLeft().GetCount() > 0 &&
+        sqlGrid->GetSelectionBlockBottomRight().GetCount() > 0) {
+        int x1, x2, y1, y2;
+
+        x1 = sqlGrid->GetSelectionBlockTopLeft()[0].GetCol();
+        x2 = sqlGrid->GetSelectionBlockBottomRight()[0].GetCol();
+        y1 = sqlGrid->GetSelectionBlockTopLeft()[0].GetRow();
+        y2 = sqlGrid->GetSelectionBlockBottomRight()[0].GetRow();
+
+        for (i = y1; i <= y2; i++) {
+            str.Append(sqlGrid->GetTable()->GetExportLine(i, x1, x2));
+
+            if (y2 > y1)
+                str.Append(END_OF_LINE);
+        }
+
+        copied = y2 - y1 + 1;
+    }
+
+    if (copied && wxTheClipboard->Open())
+    {
+        wxTheClipboard->SetData(new wxTextDataObject(str));
+        wxTheClipboard->Close();
+    }
+
+    SetStatusText(wxString::Format(_("%d rows copied to clipboard."), copied));
+}
+
+
 void frmEditGrid::OnHelp(wxCommandEvent &ev)
 {
     DisplayHelp(this, wxT("editgrid"), viewdata_xpm);
@@ -1439,6 +1502,79 @@
 }


+wxString sqlTable::GetExportLine(int row, int col1, int col2)
+{
+    wxString str;
+    cacheLine *line = GetLine(row);
+    int maxCol = (col2 < nCols - 1) ? col2 : (nCols - 1);
+    if (line)
+    {
+        int col;
+        for (col=col1 ; col <= maxCol ; col++)
+        {
+            if (col > col1)
+                str.Append(settings->GetExportColSeparator());
+            bool needQuote = settings->GetExportQuoting() > 1;
+
+            // find out if string
+            switch (columns[col].type)
+            {
+                case PGTYPCLASS_NUMERIC:
+                case PGTYPCLASS_BOOL:
+                    break;
+                default:
+                    needQuote=true;
+                    break;
+            }
+            if (needQuote)
+                str.Append(settings->GetExportQuoteChar());
+
+            str.Append(line->cols[col]);
+
+            if (needQuote)
+                str.Append(settings->GetExportQuoteChar());
+        }
+    }
+    return str;
+}
+
+
+wxString sqlTable::GetExportLine(int row, wxArrayInt cols)
+{
+    wxString str;
+    cacheLine *line = GetLine(row);
+    if (line)
+    {
+        int col;
+        for (col=0 ; col < cols.Count() ; col++)
+        {
+            if (col > 0)
+                str.Append(settings->GetExportColSeparator());
+            bool needQuote = settings->GetExportQuoting() > 1;
+
+            // find out if string
+            switch (columns[cols[col]].type)
+            {
+                case PGTYPCLASS_NUMERIC:
+                case PGTYPCLASS_BOOL:
+                    break;
+                default:
+                    needQuote=true;
+                    break;
+            }
+            if (needQuote)
+                str.Append(settings->GetExportQuoteChar());
+
+            str.Append(line->cols[cols[col]]);
+
+            if (needQuote)
+                str.Append(settings->GetExportQuoteChar());
+        }
+    }
+    return str;
+}
+
+
 wxString sqlTable::GetColLabelValue(int col)
 {
     wxString label=columns[col].name + wxT("\n");
Index: src/include/frmEditGrid.h
===================================================================
--- src/include/frmEditGrid.h    (revision 4983)
+++ src/include/frmEditGrid.h    (working copy)
@@ -113,6 +113,8 @@
     bool DeleteRows(size_t pos, size_t rows);
     int  LastRow() { return lastRow; }
     wxString GetExportLine(int row);
+    wxString GetExportLine(int row, int col1, int col2);
+    wxString sqlTable::GetExportLine(int row, wxArrayInt cols);

     bool CheckInCache(int row);


Re: Improved copying from Edit Data Grid - rough patch

From
"Magnus Hagander"
Date:
Note: I'm far from an authority in this group :-) I keep getting my own
patches bumpbed. But since it comes in contact with some of the changes
I've made lately, I'll fire off a couple of comments anyway.

(Nope, haven't looked at the actual code)


> I want to get involved in helping polish the pgAdmin
> interface. As a first step, I've modified the copy for the
> Edit Data grid to have much more flexiblity in copying data
> from the grid. The present code only allows copying entire
> rows. With my changes, you can now copy rows, columns, or the
> highlighted range.

It think the quoting used when copy here should be the one from Copy
Quoting and not Export Quoting. I actually had it on my list to do that.
While you're working in taht code anyway, maybe do that while at it?

Does this also fix the complete weirdness that you can have *both* a row
*and* a cell in a different row selected at the same time? That keeps
throwing me off all the time.

And yes, this sounds like a great feature :-)


> The next thing I would like to after finishing this is modify
> the query windows to display the results in a grid instead of
> a list. The ability to copy arbitrary sections of the results
> would be a huge help in my daily work. I figured this could
> would most likely be reusable for that goal.

Sounds like a good idea. Assuming there are no other problems with the
grid (I don't really know enough about wx to comment on that part).

//Magnus

Re: Improved copying from Edit Data Grid - rough

From
"Edward Di Geronimo Jr."
Date:
Magnus Hagander wrote:

>It think the quoting used when copy here should be the one from Copy
>Quoting and not Export Quoting. I actually had it on my list to do that.
>While you're working in taht code anyway, maybe do that while at it?
>
>
Ok, I went back and did that as well. While in the process, I noticed
that the setting to quote only strings also resulted in numbers being
quoted. I redid the logic to fix that.

>Does this also fix the complete weirdness that you can have *both* a row
>*and* a cell in a different row selected at the same time? That keeps
>throwing me off all the time.
>
>
I didn't change the selection behavior at all, only the copy behavior.

This version of the patch cleans up the code from my last patch. I
changed the 3 overloaded versions of GetExportLine so that only 1
version does the real work. The other two versions simply modify the
input and call the real version.

One other addition in this version - if you hit copy without any cells
highlighted, it will copy the cell the cursor is in.

Ed
Index: frm/frmEditGrid.cpp
===================================================================
--- frm/frmEditGrid.cpp    (revision 4983)
+++ frm/frmEditGrid.cpp    (working copy)
@@ -325,11 +325,13 @@

 void frmEditGrid::OnCopy(wxCommandEvent &ev)
 {
-    wxArrayInt rows=sqlGrid->GetSelectedRows();
+    wxString str;
+    int copied = 0;
     size_t i;
-    if (rows.GetCount())
-    {
-        wxString str;
+
+    if (sqlGrid->GetSelectedRows().GetCount()) {
+        wxArrayInt rows=sqlGrid->GetSelectedRows();
+
         for (i=0 ; i < rows.GetCount() ; i++)
         {
             str.Append(sqlGrid->GetTable()->GetExportLine(rows.Item(i)));
@@ -337,13 +339,61 @@
             if (rows.GetCount() > 1)
                 str.Append(END_OF_LINE);
         }
-        if (wxTheClipboard->Open())
+
+        copied = rows.GetCount();
+    }
+    else if (sqlGrid->GetSelectedCols().GetCount()) {
+        wxArrayInt cols=sqlGrid->GetSelectedCols();
+        size_t numRows = sqlGrid->GetNumberRows();
+
+        for (i=0 ; i < numRows ; i++)
         {
-            wxTheClipboard->SetData(new wxTextDataObject(str));
-            wxTheClipboard->Close();
+            str.Append(sqlGrid->GetTable()->GetExportLine(i, cols));
+
+            if (numRows > 1)
+                str.Append(END_OF_LINE);
         }
+
+        copied = numRows;
     }
-    SetStatusText(wxString::Format(_("%d rows copied to clipboard."), rows.GetCount()));
+    else if (sqlGrid->GetSelectionBlockTopLeft().GetCount() > 0 &&
+        sqlGrid->GetSelectionBlockBottomRight().GetCount() > 0) {
+        int x1, x2, y1, y2;
+
+        x1 = sqlGrid->GetSelectionBlockTopLeft()[0].GetCol();
+        x2 = sqlGrid->GetSelectionBlockBottomRight()[0].GetCol();
+        y1 = sqlGrid->GetSelectionBlockTopLeft()[0].GetRow();
+        y2 = sqlGrid->GetSelectionBlockBottomRight()[0].GetRow();
+
+        for (i = y1; i <= y2; i++) {
+            str.Append(sqlGrid->GetTable()->GetExportLine(i, x1, x2));
+
+            if (y2 > y1)
+                str.Append(END_OF_LINE);
+        }
+
+        copied = y2 - y1 + 1;
+    }
+    else {
+        int row, col;
+
+        row = sqlGrid->GetGridCursorRow();
+        col = sqlGrid->GetGridCursorCol();
+
+        str.Append(sqlGrid->GetTable()->GetExportLine(row, col, col));
+        copied = 1;
+    }
+
+    if (copied && wxTheClipboard->Open())
+    {
+        wxTheClipboard->SetData(new wxTextDataObject(str));
+        wxTheClipboard->Close();
+    }
+    else {
+        copied = 0;
+    }
+
+    SetStatusText(wxString::Format(_("%d rows copied to clipboard."), copied));
 }


@@ -1405,31 +1455,55 @@

 wxString sqlTable::GetExportLine(int row)
 {
+    return GetExportLine(row, 0, nCols - 1);
+}
+
+wxString sqlTable::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 sqlTable::GetExportLine(int row, wxArrayInt cols)
+{
+    wxString str;
     cacheLine *line = GetLine(row);
     if (line)
     {
         int col;
-        for (col=0 ; col < nCols ; col++)
+        for (col=0 ; col < cols.Count() ; col++)
         {
-            if (col)
+            if (col > 0)
                 str.Append(settings->GetExportColSeparator());
-            bool needQuote = settings->GetExportQuoting() > 1;

-            // find out if string
-            switch (columns[col].type)
-            {
-                case PGTYPCLASS_NUMERIC:
-                case PGTYPCLASS_BOOL:
-                    break;
-                default:
-                    needQuote=true;
-                    break;
+            bool needQuote  = false;
+
+            if (settings->GetCopyQuoting() == 1)
+            {
+                /* Quote strings only */
+                needQuote = !columns[cols[col]].numeric;
+            }
+            else if (settings->GetCopyQuoting() == 2) {
+                /* Quote everything */
+                needQuote = true;
             }
+
             if (needQuote)
                 str.Append(settings->GetExportQuoteChar());

-            str.Append(line->cols[col]);
+            str.Append(line->cols[cols[col]]);

             if (needQuote)
                 str.Append(settings->GetExportQuoteChar());
Index: include/frmEditGrid.h
===================================================================
--- include/frmEditGrid.h    (revision 4983)
+++ include/frmEditGrid.h    (working copy)
@@ -113,6 +113,8 @@
     bool DeleteRows(size_t pos, size_t rows);
     int  LastRow() { return lastRow; }
     wxString GetExportLine(int row);
+    wxString GetExportLine(int row, int col1, int col2);
+    wxString sqlTable::GetExportLine(int row, wxArrayInt cols);

     bool CheckInCache(int row);