Saving explain output graphically - Mailing list pgadmin-hackers

From Magnus Hagander
Subject Saving explain output graphically
Date
Msg-id 478BE3E6.8010500@hagander.net
Whole thread Raw
Responses Re: Saving explain output graphically
List pgadmin-hackers
There was some talk a while back about being able to save the explain
output graphically, and I've taken a stab at it. Attached patch appears
to be working for me, but I had a lot of trouble getting things to work
properly before I found the right track. Specifically, I got the wrong
size of the image all the time.

So if some people could test the patch with a bunch of different queries
and strange explain outputs, to see if you get proper size images out of
it, that would be great :-)

Thanks!


//Magnus
Index: ctl/explainCanvas.cpp
===================================================================
--- ctl/explainCanvas.cpp    (revision 6992)
+++ ctl/explainCanvas.cpp    (working copy)
@@ -163,6 +163,9 @@
     int h=(rootShape->totalShapes * yoffs + y0*2 + PIXPERUNIT - 1) / PIXPERUNIT;

     SetScrollbars(PIXPERUNIT, PIXPERUNIT, w, h);
+
+    graphWidth = maxLevel * xoffs + x0;
+    graphHeight = rootShape->totalShapes * yoffs + y0;
 }


@@ -182,7 +185,34 @@
     popup->Move(ClientToScreen(wxPoint(sx, sy)));
 }

+bool ExplainCanvas::CanSave()
+{
+    return (GetDiagram()->GetCount() > 0);
+}

+bool ExplainCanvas::SaveToFile(const wxString& filename)
+{
+    wxBitmap bmp(graphWidth, graphHeight);
+    wxMemoryDC *mem = new wxMemoryDC();
+
+    mem->SelectObject(bmp);
+    mem->Clear();
+
+    GetDiagram()->Redraw(*mem);
+
+    if (!bmp.SaveFile(filename, wxBITMAP_TYPE_PNG))
+    {
+        wxLogError(__("Could not write the file %s."), filename.c_str());
+        delete mem;
+        return false;
+    }
+
+    delete mem;
+
+    return true;
+}
+
+
 class ExplainText : public wxWindow
 {
 public:
Index: pgAdmin3.cpp
===================================================================
--- pgAdmin3.cpp    (revision 6992)
+++ pgAdmin3.cpp    (working copy)
@@ -183,6 +183,9 @@
     // Force logging off until we're ready
     wxLog *seLog=new wxLogStderr();
     wxLog::SetActiveTarget(seLog);
+
+    // Initialize image formats
+    ::wxInitAllImageHandlers();

     static const wxCmdLineEntryDesc cmdLineDesc[] =
     {
Index: include/ctl/explainCanvas.h
===================================================================
--- include/ctl/explainCanvas.h    (revision 6992)
+++ include/ctl/explainCanvas.h    (working copy)
@@ -33,11 +33,14 @@
     void ShowPopup(ExplainShape *s);
     void SetExplainString(const wxString &str);
     void Clear();
+    bool CanSave();
+    bool SaveToFile(const wxString &filename);

 private:

     ExplainShape *rootShape, *lastShape;
     ExplainPopup *popup;
+    int graphHeight, graphWidth;
 };


Index: include/frm/menu.h
===================================================================
--- include/frm/menu.h    (revision 6992)
+++ include/frm/menu.h    (working copy)
@@ -62,6 +62,7 @@
     MNU_ANALYZE,
     MNU_CLEARHISTORY,
     MNU_SAVEHISTORY,
+    MNU_SAVEEXPLAIN,
     MNU_CHECKALIVE,
     MNU_SELECTALL,

Index: include/frm/frmQuery.h
===================================================================
--- include/frm/frmQuery.h    (revision 6992)
+++ include/frm/frmQuery.h    (working copy)
@@ -105,6 +105,7 @@
     void OnSaveHistory(wxCommandEvent& event);
     void OnChangeConnection(wxCommandEvent &ev);
     void OnClearHistory(wxCommandEvent& event);
+    void OnSaveExplain(wxCommandEvent& event);
     void OnActivate(wxActivateEvent& event);
     void OnFocus(wxFocusEvent& event);
     void OnSelectAll(wxCommandEvent& event);
Index: frm/frmQuery.cpp
===================================================================
--- frm/frmQuery.cpp    (revision 6992)
+++ frm/frmQuery.cpp    (working copy)
@@ -92,6 +92,7 @@
     EVT_MENU(MNU_HELP,              frmQuery::OnHelp)
     EVT_MENU(MNU_CLEARHISTORY,      frmQuery::OnClearHistory)
     EVT_MENU(MNU_SAVEHISTORY,       frmQuery::OnSaveHistory)
+    EVT_MENU(MNU_SAVEEXPLAIN,       frmQuery::OnSaveExplain)
     EVT_MENU(MNU_SELECTALL,         frmQuery::OnSelectAll)
     EVT_MENU(MNU_QUICKREPORT,       frmQuery::OnQuickReport)
     EVT_MENU(MNU_AUTOINDENT,        frmQuery::OnAutoIndent)
@@ -195,6 +196,7 @@
     queryMenu->AppendSeparator();
     queryMenu->Append(MNU_SAVEHISTORY, _("Save history"), _("Save history of executed commands."));
     queryMenu->Append(MNU_CLEARHISTORY, _("Clear history"), _("Clear history window."));
+    queryMenu->Append(MNU_SAVEEXPLAIN, _("Save explain"), _("Save explain output image."));
     queryMenu->AppendSeparator();
     queryMenu->Append(MNU_CANCEL, _("&Cancel\tAlt-Break"), _("Cancel query"));
     menuBar->Append(queryMenu, _("&Query"));
@@ -856,7 +858,17 @@

 }

+void frmQuery::OnSaveExplain(wxCommandEvent& event)
+{
+    wxFileDialog *dlg = new wxFileDialog(this, _("Save explain"), lastDir, wxEmptyString,
+        _("Image files (*.png)|*.png|All files (*.*)|*.*)"), wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
+    if (dlg->ShowModal() == wxID_OK)
+    {
+        explainCanvas->SaveToFile(dlg->GetPath());
+    }
+}

+
 void frmQuery::OnSetFocus(wxFocusEvent& event)
 {
     sqlQuery->SetFocus();
@@ -1548,6 +1560,7 @@
         return;

     explainCanvas->SetExplainString(str);
+    setTools(false);
     outputPane->SetSelection(1);
     sqlQuery->SetFocus();
 }
@@ -1632,6 +1645,7 @@
     queryMenu->Enable(MNU_EXECFILE, !running);
     queryMenu->Enable(MNU_EXPLAIN, !running);
     queryMenu->Enable(MNU_CANCEL, running);
+    queryMenu->Enable(MNU_SAVEEXPLAIN, explainCanvas->CanSave());
     fileMenu->Enable(MNU_EXPORT, sqlResult->CanExport());
     fileMenu->Enable(MNU_QUICKREPORT, sqlResult->CanExport());
     fileMenu->Enable(MNU_RECENT, (recentFileMenu->GetMenuItemCount() > 0));
@@ -1653,12 +1667,12 @@

 void frmQuery::execQuery(const wxString &query, int resultToRetrieve, bool singleResult, const int queryOffset, bool
toFile,bool explain, bool verbose) 
 {
+    explainCanvas->Clear();
+
     setTools(true);
     queryMenu->Enable(MNU_SAVEHISTORY, true);
     queryMenu->Enable(MNU_CLEARHISTORY, true);

-    explainCanvas->Clear();
-
     // Clear markers and indicators
     sqlQuery->MarkerDeleteAll(0);
     sqlQuery->StartStyling(0, wxSTC_INDICS_MASK);
@@ -1933,6 +1947,7 @@
                 }
             }
             explainCanvas->SetExplainString(str);
+            setTools(false);
             outputPane->SetSelection(1);
         }
     }

pgadmin-hackers by date:

Previous
From: svn@pgadmin.org
Date:
Subject: SVN Commit by mha: r6998 - trunk/pgadmin3/pgadmin/schema
Next
From: "Dave Page"
Date:
Subject: Re: Saving explain output graphically