Skip site navigation (1) Skip section navigation (2)

Peripheral Links

Header And Logo

PostgreSQL
| The world's most advanced open source database.

Site Navigation

Search for
  Advanced Search

Saving explain output graphically



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);
         }
     }


Home | Main Index | Thread Index

Privacy Policy | PostgreSQL Archives hosted by Command Prompt, Inc. | Designed by tinysofa
Copyright © 1996 – 2008 PostgreSQL Global Development Group