From 077de1ad7c287f4c15b2ebbf5b988264ae23cc89 Mon Sep 17 00:00:00 2001 From: lsv Date: Thu, 31 Jul 2025 16:14:09 +0500 Subject: [PATCH] Extended hints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit В результатах запроса, нажатием правой кнопки мыши можно вызвать окно подсказки, с возможностью выделения содержимого и его копирования (Rbutton). --- ctl/ctlListView.cpp | 23 +- ctl/ctlNavigatePanel.cpp | 11 +- ctl/ctlSQLBox.cpp | 57 +- ctl/ctlSQLGrid.cpp | 132 +- frm/frmStatus.cpp | 7820 +++++++++++++++--------------- include/ctl/ctlListView.h | 8 + include/ctl/ctlNavigatePanel.h | 1 + include/ctl/ctlSQLBox.h | 2 +- include/ctl/ctlSQLGrid.h | 10 +- include/frm/frmStatus.h | 14 +- include/log/Storage.h | 5 +- include/utils/FunctionPGHelper.h | 26 +- include/utils/PreviewHtml.h | 149 + include/utils/popuphelp.h | 217 +- pgAdmin3.vcxproj | 2 + utils/PreviewHtml.cpp | 250 + utils/log/Storage.cpp | 8 +- 17 files changed, 4789 insertions(+), 3946 deletions(-) create mode 100644 include/utils/PreviewHtml.h create mode 100644 utils/PreviewHtml.cpp diff --git a/ctl/ctlListView.cpp b/ctl/ctlListView.cpp index b9c6b09..27bdb4e 100644 --- a/ctl/ctlListView.cpp +++ b/ctl/ctlListView.cpp @@ -132,7 +132,14 @@ wxString ctlListView::GetText(long row, long col) item.SetColumn(col); item.SetMask(wxLIST_MASK_TEXT); GetItem(item); - return item.GetText(); + wxString v = item.GetText(); + if (storelongstring) { + int len = v.Length(); + if (len==200 && row >= 0 && col==0 && row < longstring.size()) { + return longstring[row]; + } + } + return v; }; @@ -151,7 +158,19 @@ void ctlListView::AddColumn(const wxString& text, int size, int format) long ctlListView::AppendItem(int icon, const wxString& val, const wxString& val2, const wxString& val3, const wxString& val4) { - long pos = InsertItem(GetItemCount(), val, icon); + long idx = GetItemCount(); + long pos; + if (storelongstring) { + if (val.Length() > 200) { + longstring.push_back(val); + pos = InsertItem(idx, val.Mid(0,200), icon); + } + else { + longstring.push_back(wxEmptyString); + pos = InsertItem(idx, val, icon); + } + } else + pos = InsertItem(idx, val, icon); if (!val2.IsEmpty()) SetItem(pos, 1, val2); if (!val3.IsEmpty()) diff --git a/ctl/ctlNavigatePanel.cpp b/ctl/ctlNavigatePanel.cpp index 2a103d2..4aed5db 100644 --- a/ctl/ctlNavigatePanel.cpp +++ b/ctl/ctlNavigatePanel.cpp @@ -261,6 +261,13 @@ wxMenu* ctlNavigatePanel::GetPopupMenu() { } return NULL; } +void ctlNavigatePanel::SetFindString(const wxString& findstr) { + logFindString = findstr; + items_find.clear(); + FindText(logFindString, FOCUSNEXT, false); + Refresh(); +} + bool ctlNavigatePanel::RunKeyCommand(wxKeyEvent& event,int numCmd) { //wxAcceleratorEntry::ParseAccel(const wxString & text, int* flagsOut, int* keyOut); wxJSONValue cmds = opt["commands"]; @@ -693,7 +700,7 @@ void ctlNavigatePanel::OnMouse(wxMouseEvent& evt) { wxString tt; if (i >= 0 && i < items_mark.size() && items_mark[i] > pos) i--; if (i >= 0 && i < items_mark.size() ) { - tt = ctrl->GetItemText(items_mark[i]); + tt = ctrl->GetText(items_mark[i]); this->SetToolTip(tt); } else @@ -983,7 +990,7 @@ int ctlNavigatePanel::FindText(wxString findtext, int position, bool directionUp // this item is selected - do whatever is needed with it //wxLogMessage("Item %ld is focused.", item); //long fpos = logList->FindItem(item, logFindString, true); - wxString s = ctrl->GetItemText(item); + wxString s = ctrl->GetText(item); item++; if (!(s.Find(logFindString) > -1)) { continue; diff --git a/ctl/ctlSQLBox.cpp b/ctl/ctlSQLBox.cpp index 1eaf84a..725d442 100644 --- a/ctl/ctlSQLBox.cpp +++ b/ctl/ctlSQLBox.cpp @@ -30,6 +30,7 @@ #include "utils/FormatterSQL.h" #include "utils/dlgTransformText.h" #include "utils/TableColsMap.h" +#include "wx/display.h" wxString ctlSQLBox::sqlKeywords; static const wxString s_leftBrace(_T("([{")); @@ -591,9 +592,40 @@ void ctlSQLBox::OnFuncHelp(wxCommandEvent& ev) { for (int i = tmp.Len()-1; i >=0; i--) key+=tmp[i]; } delete m_PopupHelp; - m_PopupHelp = new popuphelp(this->GetParent(), key.Lower(), fh); + wxSize rr(450, 370); + m_PopupHelp = new popuphelp(this->GetParent(), key.Lower(), fh,p,rr); + if (m_PopupHelp && m_PopupHelp->IsValid() && rr != m_PopupHelp->GetSizePopup()) { + // recreate with new size + rr = m_PopupHelp->GetSizePopup(); + delete m_PopupHelp; + m_PopupHelp = new popuphelp(this->GetParent(), key.Lower(), fh, p, rr); + + } if (m_PopupHelp && m_PopupHelp->IsValid()) { - m_PopupHelp->Position(p, wxSize(0, 17)); + //m_PopupHelp->UpdateWindowUI(true); + wxSize top_sz=m_PopupHelp->GetSizePopup(); + wxPoint posScreen; + wxSize sizeScreen; + const int displayNum = wxDisplay::GetFromPoint(p); + if (displayNum != wxNOT_FOUND) + { + const wxRect rectScreen = wxDisplay(displayNum).GetGeometry(); + posScreen = rectScreen.GetPosition(); + sizeScreen = rectScreen.GetSize(); + } + else // outside of any display? + { + // just use the primary one then + posScreen = wxPoint(0, 0); + sizeScreen = wxGetDisplaySize(); + } + wxSize top_new(top_sz); + wxPoint oldp(p); + if (p.x + top_new.x > sizeScreen.x) p.x = sizeScreen.x - top_new.x - 20; + if (p.y + top_new.y > sizeScreen.y) p.y = sizeScreen.y - top_new.y - 20; + if (oldp==p) p.x = p.x + 20; + m_PopupHelp->Move(p); + //m_PopupHelp->Position(p, wxSize(0, 17)); m_PopupHelp->Popup(); } @@ -1659,7 +1691,7 @@ void ctlSQLBox::OnMarginClick(wxStyledTextEvent &event) event.Skip(); } -wxString ctlSQLBox::TextToHtml(int start, int end) { +wxString ctlSQLBox::TextToHtml(int start, int end,bool isAddNewLine) { wxColor frColor[40]; wxString str; wxColour frc = settings->GetSQLBoxColourForeground(); @@ -1691,10 +1723,16 @@ wxString ctlSQLBox::TextToHtml(int start, int end) { wxString sz; sz.Printf("%d", fntSQLBox.GetPixelSize().GetHeight()); - str = wxT("
"); + //str = wxT("
"); + str = wxString::Format("
", fontName, sz, fontName); int k = 0; int l = 1; - while (startp < endp) { + wxString newline = "
"; + if (isAddNewLine) newline = L"\u2936
"; + //if (isAddNewLine) newline = L"⤶
"; + //if (isAddNewLine) newline = L"
\x0b78"; + int lenstr = selText.Length(); + while (k"); startp = startp + l; k++; continue; }; + if (c == '\n') { str += newline; startp = startp + l; k++; continue; }; if (c == 9) s = 5; if (c == 32) s = 1; if (s > 0) for (int tt = 0; tt < s; tt++) str += wxT(" "); - else str += selText[k]; + else str += c; startp = startp + l; k++; } str = str + wxT("
"); diff --git a/ctl/ctlSQLGrid.cpp b/ctl/ctlSQLGrid.cpp index fa44d86..204a208 100644 --- a/ctl/ctlSQLGrid.cpp +++ b/ctl/ctlSQLGrid.cpp @@ -22,12 +22,17 @@ #include #include "ctl/ctlSQLResult.h" #include "utils/misc.h" +#include "utils/FunctionPGHelper.h" +#include "utils/PreviewHtml.h" #define EXTRAEXTENT_HEIGHT 6 #define EXTRAEXTENT_WIDTH 6 +//DEFINE_EVENT_TYPE(myEVT_SHOW_POPUP) + BEGIN_EVENT_TABLE(ctlSQLGrid, wxGrid) EVT_MOUSEWHEEL(ctlSQLGrid::OnMouseWheel) +//EVT_CUSTOM(wxID_ANY, myEVT_SHOW_POPUP,ctlSQLGrid::OnShowPopup) EVT_GRID_COL_SIZE(ctlSQLGrid::OnGridColSize) EVT_GRID_LABEL_LEFT_CLICK(ctlSQLGrid::OnLabelClick) EVT_GRID_CELL_RIGHT_CLICK(ctlSQLGrid::OnCellRightClick) @@ -66,7 +71,7 @@ ctlSQLGrid::ctlSQLGrid(wxWindow* parent, wxWindowID id, const wxPoint& pos, cons event.Skip(); }); */ - + Bind(wxEVT_THREAD, &ctlSQLGrid::OnShowPopup, this); setresizedpi(); SetDefaultCellOverflow(false); //SetDefaultRenderer(new wxGridCellAutoWrapStringRenderer); @@ -859,15 +864,132 @@ void ctlSQLGrid::OnLabelDoubleClick(wxGridEvent& event) } } } +void ctlSQLGrid::OnMouseEvent(wxMouseEvent& event) +{ + if (event.RightDown()) { + wxGridEvent ev; + OnCellRightClick(ev); + return; + } + event.Skip(); +} +void ctlSQLGrid::OnShowPopup(wxThreadEvent& event) { + // wxMessageBox("omshowpopup "+event.GetString(), "msg"); + wxString s = event.GetString(); + wxPoint p = rpos; + wxPoint p1(rpos); + wxString bg; + wxColour bgColor = settings->GetSQLBoxColourBackground(); + if (settings->GetSQLBoxUseSystemBackground()) + { + bgColor = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + } + bg = bgColor.GetAsString(wxC2S_HTML_SYNTAX); + // parse context + wxRegEx r(L"(?im)(select|from|where|set|insert|into|delete)\\b", wxRE_NEWLINE); + int cnt = 0; + if (r.IsValid()) { + size_t start=0; + std::unordered_set unic; + while (r.Matches(s.Mid(start))) { + size_t start2 = 0, len2 = 0; + r.GetMatch(&start2, &len2, 1); + unic.insert(s.Mid(start + start2,len2)); + r.GetMatch(&start2, &len2, 0); + start = start + start2 + len2; + } + cnt = unic.size(); + } + if (cnt >= 2) { + wxString q = s; + wxString html; + ctlSQLBox* box = new ctlSQLBox((wxWindow*) winMain, CTL_SQLQUERY, wxDefaultPosition, wxSize(0, 0), wxTE_MULTILINE | wxTE_RICH2); + box->SetText(q); + int l = q.Length(); + box->Colourise(0, box->GetLength()); + //bg = box->SetSQLBoxColourBackground(false).GetAsString(wxC2S_CSS_SYNTAX); + html = box->TextToHtml(0, box->GetLength(),false); + delete box; + s = html; + s = "" + s + ""; + } + else { + //simple text + PreviewHtml v; + wxString tt=v.Preview(s,fmtpreview::AUTO); + s = tt; + } + delete m_Popup; + wxSize rr(350, 70); + FunctionPGHelper fh(s); + wxString key = "content"; + m_Popup = new popuphelp(this, key, &fh, p, rr); + if (m_Popup && m_Popup->IsValid() && rr != m_Popup->GetSizePopup()) { + // recreate with new size + rr = m_Popup->GetSizePopup(); + delete m_Popup; + m_Popup = new popuphelp((wxWindow*)winMain, key, &fh, p, rr); + } + if (m_Popup && m_Popup->IsValid()) { + //m_PopupHelp->UpdateWindowUI(true); + wxSize top_sz = m_Popup->GetSizePopup(); + wxPoint posScreen; + wxSize sizeScreen; + const int displayNum = wxDisplay::GetFromPoint(p); + if (displayNum != wxNOT_FOUND) + { + const wxRect rectScreen = wxDisplay(displayNum).GetGeometry(); + posScreen = rectScreen.GetPosition(); + sizeScreen = rectScreen.GetSize(); + } + else // outside of any display? + { + // just use the primary one then + posScreen = wxPoint(0, 0); + sizeScreen = wxGetDisplaySize(); + } + wxSize top_new(top_sz); + wxPoint oldp(p); + if (p.x + top_new.x > sizeScreen.x) p.x = sizeScreen.x - top_new.x - 20; + if (p.y + top_new.y > sizeScreen.y) p.y = sizeScreen.y - top_new.y - 20; + if (oldp == p) p.x = p.x + 20; + m_Popup->Move(p); + wxRect r = m_Popup->GetScreenRect(); + if (r.Contains(p1)) { + //wxMouseEvent mv(wxEVT_MOTION,); + //wxGetMousePosition(); + } + //m_PopupHelp->Position(p, wxSize(0, 17)); + m_Popup->Popup(); + //wxPopupTransientWindow + } + +} void ctlSQLGrid::OnCellRightClick(wxGridEvent& event) { int row = event.GetRow(); int col = event.GetCol(); - - //SetRowLabelValue(row-1,); - //HideRow(row); - event.Skip(); + wxPoint p; + if (row != -1 && col != -1) { + rrow = row; + rcol = col; + rpos = ClientToScreen(event.GetPosition()); + wxThreadEvent e(wxEVT_THREAD); + //e.SetString(s); + e.SetString(GetCellValue(row, col)); + //GetEventHandler()->AddPendingEvent(e); + wxPostEvent(this, e); + //event.Skip(); + return; + } + else + { + row = rrow; + col = rcol; + p = rpos; + } + wxString s = GetCellValue(row, col); } void ctlSQLGrid::OnLabelClick(wxGridEvent& event) { diff --git a/frm/frmStatus.cpp b/frm/frmStatus.cpp index db045fa..5bb5e60 100644 --- a/frm/frmStatus.cpp +++ b/frm/frmStatus.cpp @@ -52,4622 +52,4738 @@ #include "images/up.pngc" #include "images/server_status.pngc" #include +#include "utils/FunctionPGHelper.h" +#include "utils/PreviewHtml.h" #include "db/pgConn.h" +#ifdef __WXMSW__ +#include "wx/msw/wrapcctl.h" +#endif extern int s_pid_HIGHLIGH; #define CTRLID_DATABASE 4200 +//wxDEFINE_EVENT(EVENT_FIND_STR, wxCommandEvent); BEGIN_EVENT_TABLE(frmStatus, pgFrame) -EVT_MENU(MNU_EXIT, frmStatus::OnExit) + EVT_MENU(MNU_EXIT, frmStatus::OnExit) + EVT_MENU(MNU_COPY, frmStatus::OnCopy) + EVT_MENU(MNU_COPY_QUERY, frmStatus::OnCopyQuery) + EVT_MENU(MNU_HELP, frmStatus::OnHelp) + EVT_MENU(MNU_CONTENTS, frmStatus::OnContents) + EVT_MENU(MNU_STATUSPAGE, frmStatus::OnToggleStatusPane) + EVT_MENU(MNU_LOCKPAGE, frmStatus::OnToggleLockPane) + EVT_MENU(MNU_XACTPAGE, frmStatus::OnToggleXactPane) + EVT_MENU(MNU_LOGPAGE, frmStatus::OnToggleLogPane) + EVT_MENU(MNU_QUERYSTATEPAGE, frmStatus::OnToggleQuerystatePane) + EVT_MENU(MNU_WAITENABLE, frmStatus::OnToggleWaitEnable) + EVT_MENU(MNU_QUERYSTATEVERBOSE, frmStatus::OnEmptyAction) + EVT_MENU(MNU_QUERYSTATETIME, frmStatus::OnEmptyAction) + EVT_MENU(MNU_QUERYSTATEBUFFER, frmStatus::OnEmptyAction) + EVT_MENU(MNU_QUERYSTATETRIGGER, frmStatus::OnEmptyAction) -EVT_MENU(MNU_COPY, frmStatus::OnCopy) -EVT_MENU(MNU_COPY_QUERY, frmStatus::OnCopyQuery) -EVT_MENU(MNU_HELP, frmStatus::OnHelp) -EVT_MENU(MNU_CONTENTS, frmStatus::OnContents) -EVT_MENU(MNU_STATUSPAGE, frmStatus::OnToggleStatusPane) -EVT_MENU(MNU_LOCKPAGE, frmStatus::OnToggleLockPane) -EVT_MENU(MNU_XACTPAGE, frmStatus::OnToggleXactPane) -EVT_MENU(MNU_LOGPAGE, frmStatus::OnToggleLogPane) -EVT_MENU(MNU_QUERYSTATEPAGE, frmStatus::OnToggleQuerystatePane) -EVT_MENU(MNU_WAITENABLE, frmStatus::OnToggleWaitEnable) -EVT_MENU(MNU_QUERYSTATEVERBOSE, frmStatus::OnEmptyAction) -EVT_MENU(MNU_QUERYSTATETIME, frmStatus::OnEmptyAction) -EVT_MENU(MNU_QUERYSTATEBUFFER, frmStatus::OnEmptyAction) -EVT_MENU(MNU_QUERYSTATETRIGGER, frmStatus::OnEmptyAction) + EVT_MENU(MNU_TOOLBAR, frmStatus::OnToggleToolBar) + EVT_MENU(MNU_DEFAULTVIEW, frmStatus::OnDefaultView) + EVT_MENU(MNU_HIGHLIGHTSTATUS, frmStatus::OnHighlightStatus) -EVT_MENU(MNU_TOOLBAR, frmStatus::OnToggleToolBar) -EVT_MENU(MNU_DEFAULTVIEW, frmStatus::OnDefaultView) -EVT_MENU(MNU_HIGHLIGHTSTATUS, frmStatus::OnHighlightStatus) + EVT_AUI_PANE_CLOSE( frmStatus::OnPaneClose) + //EVT_AUI_PANE_ACTIVATED( frmStatus::OnPaneActivated) + EVT_COMBOBOX(CTL_RATECBO, frmStatus::OnRateChange) + EVT_MENU(MNU_REFRESH, frmStatus::OnRefresh) + EVT_MENU(MNU_CANCEL, frmStatus::OnCancelBtn) + EVT_MENU(MNU_TERMINATE, frmStatus::OnTerminateBtn) + EVT_MENU(MNU_COMMIT, frmStatus::OnCommit) + EVT_MENU(MNU_ROLLBACK, frmStatus::OnRollback) + EVT_MENU(MNU_CLEAR_FILTER_SERVER_STATUS, frmStatus::OnClearFilter) + EVT_MENU(CMD_EVENT_FIND_STR, frmStatus::OnCmdFindStrLog) + EVT_COMBOBOX(CTL_LOGCBO, frmStatus::OnLoadLogfile) + EVT_BUTTON(CTL_ROTATEBTN, frmStatus::OnRotateLogfile) -EVT_AUI_PANE_CLOSE(frmStatus::OnPaneClose) -//EVT_AUI_PANE_ACTIVATED( frmStatus::OnPaneActivated) -EVT_COMBOBOX(CTL_RATECBO, frmStatus::OnRateChange) -EVT_MENU(MNU_REFRESH, frmStatus::OnRefresh) -EVT_MENU(MNU_CANCEL, frmStatus::OnCancelBtn) -EVT_MENU(MNU_TERMINATE, frmStatus::OnTerminateBtn) -EVT_MENU(MNU_COMMIT, frmStatus::OnCommit) -EVT_MENU(MNU_ROLLBACK, frmStatus::OnRollback) -EVT_MENU(MNU_CLEAR_FILTER_SERVER_STATUS, frmStatus::OnClearFilter) -EVT_COMBOBOX(CTL_LOGCBO, frmStatus::OnLoadLogfile) -EVT_BUTTON(CTL_ROTATEBTN, frmStatus::OnRotateLogfile) + EVT_TIMER(TIMER_REFRESHUI_ID, frmStatus::OnRefreshUITimer) -EVT_TIMER(TIMER_REFRESHUI_ID, frmStatus::OnRefreshUITimer) + EVT_TIMER(TIMER_STATUS_ID, frmStatus::OnRefreshStatusTimer) + EVT_LIST_ITEM_SELECTED(CTL_STATUSLIST, frmStatus::OnSelStatusItem) + //EVT_LIST_ITEM_DESELECTED(CTL_STATUSLIST, frmStatus::OnSelStatusItem) + EVT_LIST_ITEM_RIGHT_CLICK(CTL_STATUSLIST, frmStatus::OnRightClickStatusItem) + EVT_LIST_COL_CLICK(CTL_STATUSLIST, frmStatus::OnSortStatusGrid) + EVT_LIST_COL_RIGHT_CLICK(CTL_STATUSLIST, frmStatus::OnRightClickStatusGrid) + EVT_LIST_COL_END_DRAG(CTL_STATUSLIST, frmStatus::OnChgColSizeStatusGrid) -EVT_TIMER(TIMER_STATUS_ID, frmStatus::OnRefreshStatusTimer) -EVT_LIST_ITEM_SELECTED(CTL_STATUSLIST, frmStatus::OnSelStatusItem) -//EVT_LIST_ITEM_DESELECTED(CTL_STATUSLIST, frmStatus::OnSelStatusItem) -EVT_LIST_ITEM_RIGHT_CLICK(CTL_STATUSLIST, frmStatus::OnRightClickStatusItem) -EVT_LIST_COL_CLICK(CTL_STATUSLIST, frmStatus::OnSortStatusGrid) -EVT_LIST_COL_RIGHT_CLICK(CTL_STATUSLIST, frmStatus::OnRightClickStatusGrid) -EVT_LIST_COL_END_DRAG(CTL_STATUSLIST, frmStatus::OnChgColSizeStatusGrid) + EVT_TIMER(TIMER_LOCKS_ID, frmStatus::OnRefreshLocksTimer) + EVT_LIST_ITEM_SELECTED(CTL_LOCKLIST, frmStatus::OnSelLockItem) + EVT_LIST_ITEM_DESELECTED(CTL_LOCKLIST, frmStatus::OnSelLockItem) + EVT_LIST_COL_CLICK(CTL_LOCKLIST, frmStatus::OnSortLockGrid) + EVT_LIST_COL_RIGHT_CLICK(CTL_LOCKLIST, frmStatus::OnRightClickLockGrid) + EVT_LIST_COL_END_DRAG(CTL_LOCKLIST, frmStatus::OnChgColSizeLockGrid) -EVT_TIMER(TIMER_LOCKS_ID, frmStatus::OnRefreshLocksTimer) -EVT_LIST_ITEM_SELECTED(CTL_LOCKLIST, frmStatus::OnSelLockItem) -EVT_LIST_ITEM_DESELECTED(CTL_LOCKLIST, frmStatus::OnSelLockItem) -EVT_LIST_COL_CLICK(CTL_LOCKLIST, frmStatus::OnSortLockGrid) -EVT_LIST_COL_RIGHT_CLICK(CTL_LOCKLIST, frmStatus::OnRightClickLockGrid) -EVT_LIST_COL_END_DRAG(CTL_LOCKLIST, frmStatus::OnChgColSizeLockGrid) + EVT_TIMER(TIMER_XACT_ID, frmStatus::OnRefreshXactTimer) + EVT_LIST_ITEM_SELECTED(CTL_XACTLIST, frmStatus::OnSelXactItem) + EVT_LIST_ITEM_DESELECTED(CTL_XACTLIST, frmStatus::OnSelXactItem) + EVT_LIST_COL_CLICK(CTL_XACTLIST, frmStatus::OnSortXactGrid) + EVT_LIST_COL_RIGHT_CLICK(CTL_XACTLIST, frmStatus::OnRightClickXactGrid) + EVT_LIST_COL_END_DRAG(CTL_XACTLIST, frmStatus::OnChgColSizeXactGrid) + EVT_TIMER(TIMER_LOG_ID, frmStatus::OnRefreshLogTimer) + EVT_LIST_ITEM_SELECTED(CTL_LOGLIST, frmStatus::OnSelLogItem) + EVT_LIST_ITEM_DESELECTED(CTL_LOGLIST, frmStatus::OnSelLogItem) + EVT_LIST_ITEM_RIGHT_CLICK(CTL_LOGLIST, frmStatus::OnRightClickLogGrid) + EVT_TIMER(TIMER_LOGHINT_ID, frmStatus::OnTimerHintLog) + EVT_TIMER(TIMER_QUERYSTATE_ID, frmStatus::OnRefreshQuerystateTimer) + EVT_LIST_COL_RIGHT_CLICK(CTL_QUERYSTATELIST, frmStatus::OnRightClickQuerystateGrid) + EVT_LIST_ITEM_SELECTED(CTL_QUERYSTATELIST, frmStatus::OnSelQuerystateItem) + EVT_LIST_ITEM_DESELECTED(CTL_QUERYSTATELIST, frmStatus::OnSelQuerystateItem) + EVT_LIST_COL_END_DRAG(CTL_QUERYSTATELIST, frmStatus::OnChgColSizeQuerystateGrid) + EVT_COMBOBOX(CTRLID_DATABASE, frmStatus::OnChangeDatabase) -EVT_TIMER(TIMER_XACT_ID, frmStatus::OnRefreshXactTimer) -EVT_LIST_ITEM_SELECTED(CTL_XACTLIST, frmStatus::OnSelXactItem) -EVT_LIST_ITEM_DESELECTED(CTL_XACTLIST, frmStatus::OnSelXactItem) -EVT_LIST_COL_CLICK(CTL_XACTLIST, frmStatus::OnSortXactGrid) -EVT_LIST_COL_RIGHT_CLICK(CTL_XACTLIST, frmStatus::OnRightClickXactGrid) -EVT_LIST_COL_END_DRAG(CTL_XACTLIST, frmStatus::OnChgColSizeXactGrid) -//EVT_KEY_UP(CTL_LOGLIST, frmStatus::OnLogKeyUp) - - - -EVT_TIMER(TIMER_LOG_ID, frmStatus::OnRefreshLogTimer) -EVT_LIST_ITEM_SELECTED(CTL_LOGLIST, frmStatus::OnSelLogItem) -EVT_LIST_ITEM_DESELECTED(CTL_LOGLIST, frmStatus::OnSelLogItem) -EVT_LIST_ITEM_RIGHT_CLICK(CTL_LOGLIST, frmStatus::OnRightClickLogGrid) - -EVT_TIMER(TIMER_QUERYSTATE_ID, frmStatus::OnRefreshQuerystateTimer) -EVT_LIST_COL_RIGHT_CLICK(CTL_QUERYSTATELIST, frmStatus::OnRightClickQuerystateGrid) -EVT_LIST_ITEM_SELECTED(CTL_QUERYSTATELIST, frmStatus::OnSelQuerystateItem) -EVT_LIST_ITEM_DESELECTED(CTL_QUERYSTATELIST, frmStatus::OnSelQuerystateItem) -EVT_LIST_COL_END_DRAG(CTL_QUERYSTATELIST, frmStatus::OnChgColSizeQuerystateGrid) -EVT_COMBOBOX(CTRLID_DATABASE, frmStatus::OnChangeDatabase) - -EVT_CLOSE(frmStatus::OnClose) + EVT_CLOSE( frmStatus::OnClose) END_EVENT_TABLE(); int frmStatus::cboToRate() { - int rate = 0; + int rate = 0; - if (cbRate->GetValue() == _("Don't refresh")) - rate = 0; - if (cbRate->GetValue() == _("1 second")) - rate = 1; - if (cbRate->GetValue() == _("5 seconds")) - rate = 5; - if (cbRate->GetValue() == _("10 seconds")) - rate = 10; - if (cbRate->GetValue() == _("30 seconds")) - rate = 30; - if (cbRate->GetValue() == _("1 minute")) - rate = 60; - if (cbRate->GetValue() == _("5 minutes")) - rate = 300; - if (cbRate->GetValue() == _("10 minutes")) - rate = 600; - if (cbRate->GetValue() == _("30 minutes")) - rate = 1800; - if (cbRate->GetValue() == _("1 hour")) - rate = 3600; + if (cbRate->GetValue() == _("Don't refresh")) + rate = 0; + if (cbRate->GetValue() == _("1 second")) + rate = 1; + if (cbRate->GetValue() == _("5 seconds")) + rate = 5; + if (cbRate->GetValue() == _("10 seconds")) + rate = 10; + if (cbRate->GetValue() == _("30 seconds")) + rate = 30; + if (cbRate->GetValue() == _("1 minute")) + rate = 60; + if (cbRate->GetValue() == _("5 minutes")) + rate = 300; + if (cbRate->GetValue() == _("10 minutes")) + rate = 600; + if (cbRate->GetValue() == _("30 minutes")) + rate = 1800; + if (cbRate->GetValue() == _("1 hour")) + rate = 3600; - return rate; + return rate; } wxString frmStatus::rateToCboString(int rate) { - wxString rateStr; + wxString rateStr; - if (rate == 0) - rateStr = _("Don't refresh"); - if (rate == 1) - rateStr = _("1 second"); - if (rate == 5) - rateStr = _("5 seconds"); - if (rate == 10) - rateStr = _("10 seconds"); - if (rate == 30) - rateStr = _("30 seconds"); - if (rate == 60) - rateStr = _("1 minute"); - if (rate == 300) - rateStr = _("5 minutes"); - if (rate == 600) - rateStr = _("10 minutes"); - if (rate == 1800) - rateStr = _("30 minutes"); - if (rate == 3600) - rateStr = _("1 hour"); + if (rate == 0) + rateStr = _("Don't refresh"); + if (rate == 1) + rateStr = _("1 second"); + if (rate == 5) + rateStr = _("5 seconds"); + if (rate == 10) + rateStr = _("10 seconds"); + if (rate == 30) + rateStr = _("30 seconds"); + if (rate == 60) + rateStr = _("1 minute"); + if (rate == 300) + rateStr = _("5 minutes"); + if (rate == 600) + rateStr = _("10 minutes"); + if (rate == 1800) + rateStr = _("30 minutes"); + if (rate == 3600) + rateStr = _("1 hour"); - return rateStr; + return rateStr; } bool frmStatus::getTextSqlbyQid(long long qid) { - bool rez = false; - if (wait_sample && wait_enable && (std || pro)) { - wxString q; - wxString view; - if (std) view = "pg_stat_statements"; - if (pro) view = "pgpro_stats_statements"; - q = wxString::Format("select distinct queryid,query from %s s ", view); - if (qid != 0) { - // where - q += wxString::Format("where s.queryid=%lld limit 1", qid); - } - wxCriticalSectionLocker lock(gs_critsect); - pgSet* dataSet1 = connection->ExecuteSet(q); - if (dataSet1) - { - while (!dataSet1->Eof()) - { - wxULongLong qid = dataSet1->GetLongLong("queryid"); - wxString query = dataSet1->GetVal("query"); - WS.AddQuery(qid.GetValue(), query); - rez = true; - dataSet1->MoveNext(); - } - delete dataSet1; - } + bool rez = false; + if (wait_sample && wait_enable && (std || pro)) { + wxString q; + wxString view; + if (std) view = "pg_stat_statements"; + if (pro) view = "pgpro_stats_statements"; + q=wxString::Format("select distinct queryid,query from %s s ",view); + if (qid != 0) { + // where + q+= wxString::Format("where s.queryid=%lld limit 1",qid); + } + wxCriticalSectionLocker lock(gs_critsect); + pgSet* dataSet1 = connection->ExecuteSet(q); + if (dataSet1) + { + while (!dataSet1->Eof()) + { + wxULongLong qid = dataSet1->GetLongLong("queryid"); + wxString query = dataSet1->GetVal("query"); + WS.AddQuery(qid.GetValue(), query); + rez = true; + dataSet1->MoveNext(); + } + delete dataSet1; + } - } - return rez; + } + return rez; } -frmStatus::frmStatus(frmMain* form, const wxString& _title, pgConn* conn) : pgFrame(NULL, _title) +frmStatus::frmStatus(frmMain *form, const wxString &_title, pgConn *conn) : pgFrame(NULL, _title) { - wxString initquery; - bool highlight = false; + wxString initquery; + bool highlight = false; - dlgName = wxT("frmStatus"); + dlgName = wxT("frmStatus"); - loaded = false; + loaded = false; - mainForm = form; - connection = conn; - locks_connection = conn; - logconn = NULL; - statusTimer = 0; - locksTimer = 0; - xactTimer = 0; - logTimer = 0; + mainForm = form; + connection = conn; + locks_connection = conn; + logconn = NULL; + statusTimer = 0; + locksTimer = 0; + xactTimer = 0; + logTimer = 0; - logHasTimestamp = false; - logFormatKnown = false; + logHasTimestamp = false; + logFormatKnown = false; - // Only superusers can set these parameters... - - if (connection->IsSuperuser()) - { - // Make the connection quiet on the logs - if (connection->BackendMinimumVersion(8, 0)) - initquery = wxT("SET log_statement='none';SET log_duration='off';SET log_min_duration_statement=-1;SET statement_timeout=10000;"); - else - initquery = wxT("SET log_statement='off';SET log_duration='off';SET log_min_duration_statement=-1;"); + // Only superusers can set these parameters... + + if (connection->IsSuperuser()) + { + // Make the connection quiet on the logs + if (connection->BackendMinimumVersion(8, 0)) + initquery = wxT("SET log_statement='none';SET log_duration='off';SET log_min_duration_statement=-1;SET statement_timeout=10000;"); + else + initquery = wxT("SET log_statement='off';SET log_duration='off';SET log_min_duration_statement=-1;"); #ifndef _DEBUG - initquery += wxT("set log_min_messages = FATAL;"); + initquery += wxT("set log_min_messages = FATAL;"); #endif // !_DEBUG - connection->ExecuteVoid(initquery, false); - } - //pg_is_in_recovery() - waitMenu = new wxMenu(); - waitMenu->Append(MNU_WAITENABLE, _("&Wait trace"), _("Enable the wait event."), wxITEM_CHECK); - waitMenu->Append(MNU_WAITSAVE, _("&Wait event save"), _("Enable the wait event save to file sample.dat."), wxITEM_CHECK); - settings->Read(wxT("frmStatus/WaitTraceEnable"), &wait_enable, false); - settings->Read(wxT("frmStatus/WaitSave"), &wait_save, false); - waitMenu->Check(MNU_WAITENABLE, wait_enable); - waitMenu->Check(MNU_WAITSAVE, wait_save); - //MNU_WAITSAVE - wxString q = "select pg_is_in_recovery() recovery, \ - (select setting from pg_settings s where name = 'pg_wait_sampling.history_size')::integer hsize, \ - (select setting from pg_settings s where name = 'pg_wait_sampling.history_period')::integer hperiod, \ - (select pg_table_is_visible(viewname::regclass) and has_table_privilege(viewname::regclass,'select') from pg_views where viewname = 'pg_wait_sampling_history') as wsh, \ - (select pg_table_is_visible(viewname::regclass) and has_table_privilege(viewname::regclass,'select') from pg_views v where viewname='pgpro_stats_statements') as pro, \ - (select pg_table_is_visible(viewname::regclass) and has_table_privilege(viewname::regclass,'select') from pg_views v where viewname='pg_stat_statements') as std, \ - has_function_privilege('pg_read_binary_file(text,bigint,bigint,boolean)','execute') isreadlog \ - "; + connection->ExecuteVoid(initquery, false); + } + //pg_is_in_recovery() + waitMenu = new wxMenu(); + waitMenu->Append(MNU_WAITENABLE, _("&Wait trace"), _("Enable the wait event."), wxITEM_CHECK); + waitMenu->Append(MNU_WAITSAVE, _("&Wait event save"), _("Enable the wait event save to file sample.dat."), wxITEM_CHECK); + settings->Read(wxT("frmStatus/WaitTraceEnable"), &wait_enable, false); + settings->Read(wxT("frmStatus/WaitSave"), &wait_save, false); + waitMenu->Check(MNU_WAITENABLE,wait_enable); + waitMenu->Check(MNU_WAITSAVE, wait_save); + //MNU_WAITSAVE + wxString q = "select pg_is_in_recovery() recovery, \ + (select setting from pg_settings s where name = 'pg_wait_sampling.history_size')::integer hsize, \ + (select setting from pg_settings s where name = 'pg_wait_sampling.history_period')::integer hperiod, \ + (select pg_table_is_visible(viewname::regclass) and has_table_privilege(viewname::regclass,'select') from pg_views where viewname = 'pg_wait_sampling_history') as wsh, \ + (select pg_table_is_visible(viewname::regclass) and has_table_privilege(viewname::regclass,'select') from pg_views v where viewname='pgpro_stats_statements') as pro, \ + (select pg_table_is_visible(viewname::regclass) and has_table_privilege(viewname::regclass,'select') from pg_views v where viewname='pg_stat_statements') as std, \ + has_function_privilege('pg_read_binary_file(text,bigint,bigint,boolean)','execute') isreadlog \ + "; - pgSet* dataSet1 = connection->ExecuteSet(q); - pro = false; - std = false; - wait_sample = false; - is_read_log = false; - if (dataSet1) - { - while (!dataSet1->Eof()) - { - wxString v = dataSet1->GetVal(wxT("recovery")); - pro = dataSet1->GetBool(wxT("pro")); - std = dataSet1->GetBool(wxT("std")); - is_read_log = dataSet1->GetBool(wxT("isreadlog")); - isrecovery = (v == wxT("t")); - track_commit_timestamp = connection->HasFeature(FEATURE_TRACK_COMMIT_TS); - long sz = dataSet1->GetLong(wxT("hsize")); - long p = dataSet1->GetLong(wxT("hperiod")); - if (!dataSet1->GetBool(wxT("wsh"))) p = 0; - if (sz > 1000000) { - wxLogWarning(_("Value parameter pg_wait_sampling.history_size = %ld greet 1000000 monitoring wait events disabled.\n"), - sz - ); - p = 0; - } - if (p > 0) { - wait_sample = true; - WS.SetConfig(p, sz, this); - } - dataSet1->MoveNext(); - } - delete dataSet1; - } - if (!wait_sample) { - waitMenu->Enable(MNU_WAITENABLE, false); - waitMenu->Enable(MNU_WAITSAVE, false); - } - if (wait_sample && wait_enable && (std || pro)) { - getTextSqlbyQid(0); - } + pgSet* dataSet1 = connection->ExecuteSet(q); + pro = false; + std = false; + wait_sample = false; + is_read_log = false; + if (dataSet1) + { + while (!dataSet1->Eof()) + { + wxString v = dataSet1->GetVal(wxT("recovery")); + pro= dataSet1->GetBool(wxT("pro")); + std = dataSet1->GetBool(wxT("std")); + is_read_log = dataSet1->GetBool(wxT("isreadlog")); + isrecovery = (v == wxT("t")); + track_commit_timestamp = connection->HasFeature(FEATURE_TRACK_COMMIT_TS); + long sz = dataSet1->GetLong(wxT("hsize")); + long p = dataSet1->GetLong(wxT("hperiod")); + if (!dataSet1->GetBool(wxT("wsh"))) p = 0; + if (sz > 1000000) { + wxLogWarning(_("Value parameter pg_wait_sampling.history_size = %ld greet 1000000 monitoring wait events disabled.\n"), + sz + ); + p = 0; + } + if (p > 0) { + wait_sample = true; + WS.SetConfig(p,sz,this); + } + dataSet1->MoveNext(); + } + delete dataSet1 ; + } + if (!wait_sample) { + waitMenu->Enable(MNU_WAITENABLE, false); + waitMenu->Enable(MNU_WAITSAVE, false); + } + if (wait_sample && wait_enable && (std || pro)) { + getTextSqlbyQid(0); + } - // Notify wxAUI which frame to use - manager.SetManagedWindow(this); - manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG | wxAUI_MGR_ALLOW_ACTIVE_PANE); + // Notify wxAUI which frame to use + manager.SetManagedWindow(this); + manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG | wxAUI_MGR_ALLOW_ACTIVE_PANE); - // Set different window's attributes - SetTitle(_title); - SetIcon(*server_status_png_ico); - RestorePosition(-1, -1, 700, 500, 700, 500); - SetMinSize(FromDIP(wxSize(700, 500))); - SetFont(settings->GetSystemFont()); + // Set different window's attributes + SetTitle(_title); + SetName(dlgName); + SetIcon(*server_status_png_ico); + RestorePosition(-1, -1, 700, 500, 700, 500); + SetMinSize(FromDIP(wxSize(700, 500))); + SetFont(settings->GetSystemFont()); - // Build menu bar - menuBar = new wxMenuBar(); + // Build menu bar + menuBar = new wxMenuBar(); - fileMenu = new wxMenu(); - fileMenu->Append(MNU_EXIT, _("E&xit\tCtrl-W"), _("Exit query window")); + fileMenu = new wxMenu(); + fileMenu->Append(MNU_EXIT, _("E&xit\tCtrl-W"), _("Exit query window")); - menuBar->Append(fileMenu, _("&File")); + menuBar->Append(fileMenu, _("&File")); - editMenu = new wxMenu(); - editMenu->Append(MNU_COPY, _("&Copy\tCtrl-C"), _("Copy selected text to clipboard"), wxITEM_NORMAL); + editMenu = new wxMenu(); + editMenu->Append(MNU_COPY, _("&Copy\tCtrl-C"), _("Copy selected text to clipboard"), wxITEM_NORMAL); - menuBar->Append(editMenu, _("&Edit")); + menuBar->Append(editMenu, _("&Edit")); - actionMenu = new wxMenu(); - actionMenu->Append(MNU_REFRESH, _("Refresh\tCtrl-R"), _("Refresh the selected panel"), wxITEM_NORMAL); - actionMenu->AppendSeparator(); - actionMenu->Append(MNU_COPY_QUERY, _("Copy to query tool\tCtrl-Shift-C"), _("Open the query tool with the selected query"), wxITEM_NORMAL); - actionMenu->Append(MNU_CANCEL, _("Cancel query\tDel"), _("Cancel the selected query"), wxITEM_NORMAL); - actionMenu->Append(MNU_TERMINATE, _("Terminate backend\tShift-Del"), _("Terminate the selected backend"), wxITEM_NORMAL); - actionMenu->AppendSeparator(); - actionMenu->Append(MNU_COMMIT, _("Commit prepared transaction"), _("Commit the selected prepared transaction"), wxITEM_NORMAL); - actionMenu->Append(MNU_ROLLBACK, _("Rollback prepared transaction"), _("Rollback the selected prepared transaction"), wxITEM_NORMAL); + actionMenu = new wxMenu(); + actionMenu->Append(MNU_REFRESH, _("Refresh\tCtrl-R"), _("Refresh the selected panel"), wxITEM_NORMAL); + actionMenu->AppendSeparator(); + actionMenu->Append(MNU_COPY_QUERY, _("Copy to query tool\tCtrl-Shift-C"), _("Open the query tool with the selected query"), wxITEM_NORMAL); + actionMenu->Append(MNU_CANCEL, _("Cancel query\tDel"), _("Cancel the selected query"), wxITEM_NORMAL); + actionMenu->Append(MNU_TERMINATE, _("Terminate backend\tShift-Del"), _("Terminate the selected backend"), wxITEM_NORMAL); + actionMenu->AppendSeparator(); + actionMenu->Append(MNU_COMMIT, _("Commit prepared transaction"), _("Commit the selected prepared transaction"), wxITEM_NORMAL); + actionMenu->Append(MNU_ROLLBACK, _("Rollback prepared transaction"), _("Rollback the selected prepared transaction"), wxITEM_NORMAL); - menuBar->Append(actionMenu, _("&Action")); + menuBar->Append(actionMenu, _("&Action")); - viewMenu = new wxMenu(); - viewMenu->Append(MNU_STATUSPAGE, _("&Activity\tCtrl-Alt-A"), _("Show or hide the activity tab."), wxITEM_CHECK); - viewMenu->Append(MNU_LOCKPAGE, _("&Locks\tCtrl-Alt-L"), _("Show or hide the locks tab."), wxITEM_CHECK); - viewMenu->Append(MNU_XACTPAGE, _("Prepared &Transactions\tCtrl-Alt-T"), _("Show or hide the prepared transactions tab."), wxITEM_CHECK); - viewMenu->Append(MNU_LOGPAGE, _("Log&file\tCtrl-Alt-F"), _("Show or hide the logfile tab."), wxITEM_CHECK); - viewMenu->AppendSeparator(); - viewMenu->Append(MNU_QUERYSTATEPAGE, _("&Query state\tCtrl-Alt-Q"), _("Show or hide the query state tab."), wxITEM_CHECK); - viewMenu->Append(MNU_QUERYSTATEVERBOSE, _("Append verbose"), _("Append verbose."), wxITEM_CHECK); - viewMenu->Append(MNU_QUERYSTATEBUFFER, _("Append use buffers"), _("Append use buffers."), wxITEM_CHECK); - viewMenu->Append(MNU_QUERYSTATETIME, _("Append real timing"), _("Append real timing."), wxITEM_CHECK); - viewMenu->Append(MNU_QUERYSTATETRIGGER, _("Append triggers"), _("Append triggers."), wxITEM_CHECK); + viewMenu = new wxMenu(); + viewMenu->Append(MNU_STATUSPAGE, _("&Activity\tCtrl-Alt-A"), _("Show or hide the activity tab."), wxITEM_CHECK); + viewMenu->Append(MNU_LOCKPAGE, _("&Locks\tCtrl-Alt-L"), _("Show or hide the locks tab."), wxITEM_CHECK); + viewMenu->Append(MNU_XACTPAGE, _("Prepared &Transactions\tCtrl-Alt-T"), _("Show or hide the prepared transactions tab."), wxITEM_CHECK); + viewMenu->Append(MNU_LOGPAGE, _("Log&file\tCtrl-Alt-F"), _("Show or hide the logfile tab."), wxITEM_CHECK); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_QUERYSTATEPAGE, _("&Query state\tCtrl-Alt-Q"), _("Show or hide the query state tab."), wxITEM_CHECK); + viewMenu->Append(MNU_QUERYSTATEVERBOSE, _("Append verbose"), _("Append verbose."), wxITEM_CHECK); + viewMenu->Append(MNU_QUERYSTATEBUFFER, _("Append use buffers"), _("Append use buffers."), wxITEM_CHECK); + viewMenu->Append(MNU_QUERYSTATETIME, _("Append real timing"), _("Append real timing."), wxITEM_CHECK); + viewMenu->Append(MNU_QUERYSTATETRIGGER, _("Append triggers"), _("Append triggers."), wxITEM_CHECK); - viewMenu->AppendSeparator(); - viewMenu->Append(MNU_TOOLBAR, _("Tool&bar\tCtrl-Alt-B"), _("Show or hide the toolbar."), wxITEM_CHECK); - viewMenu->Append(MNU_HIGHLIGHTSTATUS, _("Highlight items of the activity list"), _("Highlight or not the items of the activity list."), wxITEM_CHECK); - viewMenu->AppendSeparator(); - viewMenu->Append(MNU_DEFAULTVIEW, _("&Default view\tCtrl-Alt-V"), _("Restore the default view.")); - - menuBar->Append(waitMenu, _("&Wait")); - menuBar->Append(viewMenu, _("&View")); - - wxMenu* helpMenu = new wxMenu(); - helpMenu->Append(MNU_CONTENTS, _("&Help contents"), _("Open the helpfile.")); - helpMenu->Append(MNU_HELP, _("&Server status help"), _("Display help on this window.")); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_TOOLBAR, _("Tool&bar\tCtrl-Alt-B"), _("Show or hide the toolbar."), wxITEM_CHECK); + viewMenu->Append(MNU_HIGHLIGHTSTATUS, _("Highlight items of the activity list"), _("Highlight or not the items of the activity list."), wxITEM_CHECK); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_DEFAULTVIEW, _("&Default view\tCtrl-Alt-V"), _("Restore the default view.")); + + menuBar->Append(waitMenu, _("&Wait")); + menuBar->Append(viewMenu, _("&View")); + + wxMenu *helpMenu = new wxMenu(); + helpMenu->Append(MNU_CONTENTS, _("&Help contents"), _("Open the helpfile.")); + helpMenu->Append(MNU_HELP, _("&Server status help"), _("Display help on this window.")); #ifdef __WXMAC__ - menuFactories = new menuFactoryList(); - aboutFactory* af = new aboutFactory(menuFactories, helpMenu, 0); - wxApp::s_macAboutMenuItemId = af->GetId(); - menuFactories->RegisterMenu(this, wxCommandEventHandler(pgFrame::OnAction)); + menuFactories = new menuFactoryList(); + aboutFactory *af = new aboutFactory(menuFactories, helpMenu, 0); + wxApp::s_macAboutMenuItemId = af->GetId(); + menuFactories->RegisterMenu(this, wxCommandEventHandler(pgFrame::OnAction)); #endif - menuBar->Append(helpMenu, _("&Help")); + menuBar->Append(helpMenu, _("&Help")); - // Setup edit menu - editMenu->Enable(MNU_COPY, false); + // Setup edit menu + editMenu->Enable(MNU_COPY, false); - // Finish menu bar - SetMenuBar(menuBar); + // Finish menu bar + SetMenuBar(menuBar); - // Set statusBar - statusBar = CreateStatusBar(1); - SetStatusBarPane(-1); + // Set statusBar + statusBar = CreateStatusBar(1); + SetStatusBarPane(-1); - // Set up toolbar - toolBar = new ctlMenuToolbar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER); - toolBar->SetToolBitmapSize(FromDIP(wxSize(32, 32))); - toolBar->AddTool(MNU_REFRESH, wxEmptyString, GetBundleSVG(readdata_png_bmp, "refresh.svg", wxSize(16, 16)), _("Refresh"), wxITEM_NORMAL); - toolBar->AddSeparator(); - toolBar->AddTool(MNU_COPY, wxEmptyString, GetBundleSVG(clip_copy_png_bmp, "clip_copy.svg", wxSize(16, 16)), _("Copy selected text to clipboard"), wxITEM_NORMAL); - toolBar->AddTool(MNU_COPY_QUERY, wxEmptyString, GetBundleSVG(clip_copy_png_bmp, "clip_copy_sql.svg", wxSize(16, 16)), _("Open the query tool with the selected query"), wxITEM_NORMAL); - toolBar->AddSeparator(); - toolBar->AddTool(MNU_CANCEL, wxEmptyString, GetBundleSVG(query_cancel_png_bmp, "query_cancel.svg", wxSize(16, 16)), _("Cancel query"), wxITEM_NORMAL); - toolBar->AddTool(MNU_TERMINATE, wxEmptyString, GetBundleSVG(terminate_backend_png_bmp, "terminate_backend.svg", wxSize(16, 16)), _("Terminate backend"), wxITEM_NORMAL); - toolBar->AddTool(MNU_COMMIT, wxEmptyString, GetBundleSVG(storedata_png_bmp, "storedata.svg", wxSize(16, 16)), _("Commit transaction"), wxITEM_NORMAL); - toolBar->AddTool(MNU_ROLLBACK, wxEmptyString, GetBundleSVG(delete_png_bmp, "drop.svg", wxSize(16, 16)), _("Rollback transaction"), wxITEM_NORMAL); - toolBar->AddSeparator(); - toolBar->AddTool(MNU_CLEAR_FILTER_SERVER_STATUS, wxEmptyString, GetBundleSVG(sortfilterclear_png_bmp, "sortfilterclear.svg", wxSize(16, 16)), _("Clear filter"), wxITEM_NORMAL); - toolBar->AddSeparator(); + // Set up toolbar + toolBar = new ctlMenuToolbar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER); + toolBar->SetToolBitmapSize(FromDIP(wxSize(32, 32))); + toolBar->AddTool(MNU_REFRESH, wxEmptyString, GetBundleSVG(readdata_png_bmp, "refresh.svg", wxSize(16, 16)), _("Refresh"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_COPY, wxEmptyString, GetBundleSVG(clip_copy_png_bmp, "clip_copy.svg", wxSize(16, 16)), _("Copy selected text to clipboard"), wxITEM_NORMAL); + toolBar->AddTool(MNU_COPY_QUERY, wxEmptyString, GetBundleSVG(clip_copy_png_bmp, "clip_copy_sql.svg", wxSize(16, 16)), _("Open the query tool with the selected query"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_CANCEL, wxEmptyString, GetBundleSVG(query_cancel_png_bmp, "query_cancel.svg", wxSize(16, 16)), _("Cancel query"), wxITEM_NORMAL); + toolBar->AddTool(MNU_TERMINATE, wxEmptyString, GetBundleSVG(terminate_backend_png_bmp, "terminate_backend.svg", wxSize(16, 16)), _("Terminate backend"), wxITEM_NORMAL); + toolBar->AddTool(MNU_COMMIT, wxEmptyString, GetBundleSVG(storedata_png_bmp, "storedata.svg", wxSize(16, 16)), _("Commit transaction"), wxITEM_NORMAL); + toolBar->AddTool(MNU_ROLLBACK, wxEmptyString, GetBundleSVG(delete_png_bmp, "drop.svg", wxSize(16, 16)), _("Rollback transaction"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_CLEAR_FILTER_SERVER_STATUS, wxEmptyString, GetBundleSVG(sortfilterclear_png_bmp, "sortfilterclear.svg", wxSize(16, 16)), _("Clear filter"), wxITEM_NORMAL); + toolBar->AddSeparator(); + cbLogfiles = new wxComboBox(toolBar, CTL_LOGCBO, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, + wxCB_READONLY | wxCB_DROPDOWN); + toolBar->AddControl(cbLogfiles); + btnRotateLog = new wxButton(toolBar, CTL_ROTATEBTN, _("Rotate")); + toolBar->AddControl(btnRotateLog); + toolBar->AddSeparator(); + cbRate = new wxComboBox(toolBar, CTL_RATECBO, wxEmptyString, wxDefaultPosition, wxSize(-1, -1), wxArrayString(), wxCB_READONLY | wxCB_DROPDOWN); + toolBar->AddControl(cbRate); + toolBar->AddSeparator(); + cbDatabase = new ctlComboBoxFix(toolBar, CTRLID_DATABASE, wxDefaultPosition, wxSize(-1, -1), wxCB_READONLY | wxCB_DROPDOWN); + toolBar->AddControl(cbDatabase); + if (wait_sample && wait_enable) { + toolBar->AddSeparator(); + top_small = new wxTopActivity(toolBar, &WS, wxSize(100, 32)); + toolBar->AddControl(top_small); + } + else top_small = NULL; - cbLogfiles = new wxComboBox(toolBar, CTL_LOGCBO, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, - wxCB_READONLY | wxCB_DROPDOWN); - toolBar->AddControl(cbLogfiles); - btnRotateLog = new wxButton(toolBar, CTL_ROTATEBTN, _("Rotate")); - toolBar->AddControl(btnRotateLog); - toolBar->AddSeparator(); - cbRate = new wxComboBox(toolBar, CTL_RATECBO, wxEmptyString, wxDefaultPosition, wxSize(-1, -1), wxArrayString(), wxCB_READONLY | wxCB_DROPDOWN); - toolBar->AddControl(cbRate); - toolBar->AddSeparator(); - cbDatabase = new ctlComboBoxFix(toolBar, CTRLID_DATABASE, wxDefaultPosition, wxSize(-1, -1), wxCB_READONLY | wxCB_DROPDOWN); - toolBar->AddControl(cbDatabase); - if (wait_sample && wait_enable) { - toolBar->AddSeparator(); - top_small = new wxTopActivity(toolBar, &WS, wxSize(100, 32)); - toolBar->AddControl(top_small); - } - else top_small = NULL; + toolBar->Realize(); - toolBar->Realize(); + // Append items to cbo + cbRate->Append(_("Don't refresh")); + cbRate->Append(_("1 second")); + cbRate->Append(_("5 seconds")); + cbRate->Append(_("10 seconds")); + cbRate->Append(_("30 seconds")); + cbRate->Append(_("1 minute")); + cbRate->Append(_("5 minutes")); + cbRate->Append(_("10 minutes")); + cbRate->Append(_("30 minutes")); + cbRate->Append(_("1 hour")); - // Append items to cbo - cbRate->Append(_("Don't refresh")); - cbRate->Append(_("1 second")); - cbRate->Append(_("5 seconds")); - cbRate->Append(_("10 seconds")); - cbRate->Append(_("30 seconds")); - cbRate->Append(_("1 minute")); - cbRate->Append(_("5 minutes")); - cbRate->Append(_("10 minutes")); - cbRate->Append(_("30 minutes")); - cbRate->Append(_("1 hour")); + // Disable toolbar's items + toolBar->EnableTool(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + toolBar->EnableTool(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + toolBar->EnableTool(MNU_CLEAR_FILTER_SERVER_STATUS, false); + actionMenu->Enable(MNU_CANCEL, false); + actionMenu->Enable(MNU_TERMINATE, false); + actionMenu->Enable(MNU_COMMIT, false); + actionMenu->Enable(MNU_ROLLBACK, false); + cbLogfiles->Enable(false); + btnRotateLog->Enable(false); - // Disable toolbar's items - toolBar->EnableTool(MNU_CANCEL, false); - toolBar->EnableTool(MNU_TERMINATE, false); - toolBar->EnableTool(MNU_COMMIT, false); - toolBar->EnableTool(MNU_ROLLBACK, false); - toolBar->EnableTool(MNU_CLEAR_FILTER_SERVER_STATUS, false); - actionMenu->Enable(MNU_CANCEL, false); - actionMenu->Enable(MNU_TERMINATE, false); - actionMenu->Enable(MNU_COMMIT, false); - actionMenu->Enable(MNU_ROLLBACK, false); - cbLogfiles->Enable(false); - btnRotateLog->Enable(false); + // Add the database combobox + pgSet *dataSet3 = connection->ExecuteSet(wxT("SELECT datname FROM pg_database WHERE datallowconn ORDER BY datname")); + while (!dataSet3->Eof()) + { + cbDatabase->Append(dataSet3->GetVal(wxT("datname"))); + dataSet3->MoveNext(); + } + delete dataSet3; - // Add the database combobox - pgSet* dataSet3 = connection->ExecuteSet(wxT("SELECT datname FROM pg_database WHERE datallowconn ORDER BY datname")); - while (!dataSet3->Eof()) - { - cbDatabase->Append(dataSet3->GetVal(wxT("datname"))); - dataSet3->MoveNext(); - } - delete dataSet3; + // Image list for all listviews + listimages = new wxImageList(13, 8, true, 2); + listimages->Add(*down_png_ico); + listimages->Add(*up_png_ico); - // Image list for all listviews - listimages = new wxImageList(13, 8, true, 2); - listimages->Add(*down_png_ico); - listimages->Add(*up_png_ico); + // Create panel + AddStatusPane(); + AddLockPane(); + AddXactPane(); + AddQuerystatePane(); + AddLogPane(); + wxSize toolw = toolBar->GetBestSize(); - // Create panel - AddStatusPane(); - AddLockPane(); - AddXactPane(); - AddQuerystatePane(); - AddLogPane(); - wxSize toolw = toolBar->GetBestSize(); + manager.AddPane(toolBar, wxAuiPaneInfo().Name(wxT("toolBar")).Caption(_("Tool bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false)); - manager.AddPane(toolBar, wxAuiPaneInfo().Name(wxT("toolBar")).Caption(_("Tool bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false)); + // Now load the layout + wxString perspective; + settings->Read(wxT("frmStatus/Perspective-") + wxString(FRMSTATUS_PERSPECTIVE_VER), &perspective, FRMSTATUS_DEFAULT_PERSPECTIVE); + manager.LoadPerspective(perspective, true); + // Reset the captions for the current language + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + manager.GetPane(wxT("Activity")).Caption(_("Activity")); + manager.GetPane(wxT("Locks")).Caption(_("Locks")); + manager.GetPane(wxT("Transactions")).Caption(_("Prepared Transactions")); + manager.GetPane(wxT("Logfile")).Caption(_("Logfile")); + manager.GetPane(wxT("Querystate")).Caption(_("QueryState")); + manager.GetPane(wxT("toolBar")).BestSize(toolw); + //manager.GetPane(wxT("Activity")).GripperTop(true); + // Tell the manager to "commit" all the changes just made + manager.Update(); - // Now load the layout - wxString perspective; - settings->Read(wxT("frmStatus/Perspective-") + wxString(FRMSTATUS_PERSPECTIVE_VER), &perspective, FRMSTATUS_DEFAULT_PERSPECTIVE); - manager.LoadPerspective(perspective, true); - // Reset the captions for the current language - manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); - manager.GetPane(wxT("Activity")).Caption(_("Activity")); - manager.GetPane(wxT("Locks")).Caption(_("Locks")); - manager.GetPane(wxT("Transactions")).Caption(_("Prepared Transactions")); - manager.GetPane(wxT("Logfile")).Caption(_("Logfile")); - manager.GetPane(wxT("Querystate")).Caption(_("QueryState")); - manager.GetPane(wxT("toolBar")).BestSize(toolw); - //manager.GetPane(wxT("Activity")).GripperTop(true); - // Tell the manager to "commit" all the changes just made - manager.Update(); + // Sync the View menu options + viewMenu->Check(MNU_STATUSPAGE, manager.GetPane(wxT("Activity")).IsShown()); + viewMenu->Check(MNU_LOCKPAGE, manager.GetPane(wxT("Locks")).IsShown()); + viewMenu->Check(MNU_XACTPAGE, manager.GetPane(wxT("Transactions")).IsShown()); + viewMenu->Check(MNU_LOGPAGE, manager.GetPane(wxT("Logfile")).IsShown()); + pgSet *set = connection->ExecuteSet(wxT("SELECT 1 FROM pg_available_extensions WHERE installed_version is not null and name='pg_query_state'")); + bool queryenable = set->NumRows() == 1; + viewMenu->Enable(MNU_QUERYSTATEPAGE, queryenable); + if (!queryenable) { + viewMenu->Check(MNU_QUERYSTATEPAGE, false); + manager.GetPane(wxT("Querystate")).Hide(); + } + //viewMenu->Check(MNU_QUERYSTATEPAGE,set->NumRows() == 1); + delete set; - // Sync the View menu options - viewMenu->Check(MNU_STATUSPAGE, manager.GetPane(wxT("Activity")).IsShown()); - viewMenu->Check(MNU_LOCKPAGE, manager.GetPane(wxT("Locks")).IsShown()); - viewMenu->Check(MNU_XACTPAGE, manager.GetPane(wxT("Transactions")).IsShown()); - viewMenu->Check(MNU_LOGPAGE, manager.GetPane(wxT("Logfile")).IsShown()); - pgSet* set = connection->ExecuteSet(wxT("SELECT 1 FROM pg_available_extensions WHERE installed_version is not null and name='pg_query_state'")); - bool queryenable = set->NumRows() == 1; - viewMenu->Enable(MNU_QUERYSTATEPAGE, queryenable); - if (!queryenable) { - viewMenu->Check(MNU_QUERYSTATEPAGE, false); - manager.GetPane(wxT("Querystate")).Hide(); - } - //viewMenu->Check(MNU_QUERYSTATEPAGE,set->NumRows() == 1); - delete set; + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); + // + //if (!viewMenu->IsEnabled(MNU_QUERYSTATEPAGE)) { + // manager.GetPane(wxT("Querystate")).Hide(); + // } else manager.GetPane(wxT("Querystate")).Show(); - viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); - // - //if (!viewMenu->IsEnabled(MNU_QUERYSTATEPAGE)) { - // manager.GetPane(wxT("Querystate")).Hide(); - // } else manager.GetPane(wxT("Querystate")).Show(); + viewMenu->Check(MNU_QUERYSTATEPAGE,manager.GetPane(wxT("Querystate")).IsShown()); + // Read the highlight status checkbox + settings->Read(wxT("frmStatus/HighlightStatus"), &highlight, true); + viewMenu->Check(MNU_HIGHLIGHTSTATUS, highlight); + bool qu_status; + settings->Read(wxT("frmStatus/QuerystateVerboseStatus"), &qu_status, false); + viewMenu->Check(MNU_QUERYSTATEVERBOSE, qu_status); + settings->Read(wxT("frmStatus/QuerystateTimeStatus"), &qu_status, true); + viewMenu->Check(MNU_QUERYSTATETIME, qu_status); + settings->Read(wxT("frmStatus/QuerystateBufferStatus"), &qu_status, true); + viewMenu->Check(MNU_QUERYSTATEBUFFER, qu_status); + settings->Read(wxT("frmStatus/QuerystateTriggerStatus"), &qu_status, true); + viewMenu->Check(MNU_QUERYSTATETRIGGER, qu_status); - viewMenu->Check(MNU_QUERYSTATEPAGE, manager.GetPane(wxT("Querystate")).IsShown()); - // Read the highlight status checkbox - settings->Read(wxT("frmStatus/HighlightStatus"), &highlight, true); - viewMenu->Check(MNU_HIGHLIGHTSTATUS, highlight); - bool qu_status; - settings->Read(wxT("frmStatus/QuerystateVerboseStatus"), &qu_status, false); - viewMenu->Check(MNU_QUERYSTATEVERBOSE, qu_status); - settings->Read(wxT("frmStatus/QuerystateTimeStatus"), &qu_status, true); - viewMenu->Check(MNU_QUERYSTATETIME, qu_status); - settings->Read(wxT("frmStatus/QuerystateBufferStatus"), &qu_status, true); - viewMenu->Check(MNU_QUERYSTATEBUFFER, qu_status); - settings->Read(wxT("frmStatus/QuerystateTriggerStatus"), &qu_status, true); - viewMenu->Check(MNU_QUERYSTATETRIGGER, qu_status); + + // Get our PID + backend_pid = connection->GetBackendPID(); + // Create the refresh timer (quarter of a second) + // This is a horrible hack to get around the lack of a + // PANE_ACTIVATED event in wxAUI. + refreshUITimer = new wxTimer(this, TIMER_REFRESHUI_ID); + refreshUITimer->Start(250); - // Get our PID - backend_pid = connection->GetBackendPID(); + // The selected pane is the log pane by default + // so enable/disable the widgets according to this + wxListEvent nullevent; + OnSelLogItem(nullevent); - // Create the refresh timer (quarter of a second) - // This is a horrible hack to get around the lack of a - // PANE_ACTIVATED event in wxAUI. - refreshUITimer = new wxTimer(this, TIMER_REFRESHUI_ID); - refreshUITimer->Start(250); - - // The selected pane is the log pane by default - // so enable/disable the widgets according to this - wxListEvent nullevent; - OnSelLogItem(nullevent); - - // We're good now - loaded = true; + // We're good now + loaded = true; } frmStatus::~frmStatus() { - // Delete the refresh timer - delete refreshUITimer; - // If the status window wasn't launched in standalone mode... - if (mainForm) - mainForm->RemoveFrame(this); + // Delete the refresh timer + delete refreshUITimer; + // If the status window wasn't launched in standalone mode... + if (mainForm) + mainForm->RemoveFrame(this); - // Save the window's position - settings->Write(wxT("frmStatus/Perspective-") + wxString(FRMSTATUS_PERSPECTIVE_VER), manager.SavePerspective()); - manager.UnInit(); - SavePosition(); + // Save the window's position + settings->Write(wxT("frmStatus/Perspective-") + wxString(FRMSTATUS_PERSPECTIVE_VER), manager.SavePerspective()); + manager.UnInit(); + SavePosition(); - // Save the highlight status checkbox - settings->WriteBool(wxT("frmStatus/HighlightStatus"), viewMenu->IsChecked(MNU_HIGHLIGHTSTATUS)); - settings->WriteBool(wxT("frmStatus/QuerystateVerboseStatus"), viewMenu->IsChecked(MNU_QUERYSTATEVERBOSE)); - settings->WriteBool(wxT("frmStatus/QuerystateTimeStatus"), viewMenu->IsChecked(MNU_QUERYSTATETIME)); - settings->WriteBool(wxT("frmStatus/QuerystateBufferStatus"), viewMenu->IsChecked(MNU_QUERYSTATEBUFFER)); - settings->WriteBool(wxT("frmStatus/QuerystateTriggerStatus"), viewMenu->IsChecked(MNU_QUERYSTATETRIGGER)); - if (wait_sample) settings->WriteBool(wxT("frmStatus/WaitTraceEnable"), waitMenu->IsChecked(MNU_WAITENABLE)); - if (wait_sample) settings->WriteBool(wxT("frmStatus/WaitSave"), waitMenu->IsChecked(MNU_WAITSAVE)); - if (wait_sample && wait_enable && waitMenu->IsChecked(MNU_WAITSAVE)) WS.SaveFileSamples(); else { - // remove file - WS.RemoveFiles(); - } + // Save the highlight status checkbox + settings->WriteBool(wxT("frmStatus/HighlightStatus"), viewMenu->IsChecked(MNU_HIGHLIGHTSTATUS)); + settings->WriteBool(wxT("frmStatus/QuerystateVerboseStatus"), viewMenu->IsChecked(MNU_QUERYSTATEVERBOSE)); + settings->WriteBool(wxT("frmStatus/QuerystateTimeStatus"), viewMenu->IsChecked(MNU_QUERYSTATETIME)); + settings->WriteBool(wxT("frmStatus/QuerystateBufferStatus"), viewMenu->IsChecked(MNU_QUERYSTATEBUFFER)); + settings->WriteBool(wxT("frmStatus/QuerystateTriggerStatus"), viewMenu->IsChecked(MNU_QUERYSTATETRIGGER)); + if (wait_sample) settings->WriteBool(wxT("frmStatus/WaitTraceEnable"), waitMenu->IsChecked(MNU_WAITENABLE)); + if (wait_sample) settings->WriteBool(wxT("frmStatus/WaitSave"), waitMenu->IsChecked(MNU_WAITSAVE)); + if (wait_sample && wait_enable && waitMenu->IsChecked(MNU_WAITSAVE)) WS.SaveFileSamples(); else { + // remove file + WS.RemoveFiles(); + } - // For each current page, save the slider's position and delete the timer - settings->WriteInt(wxT("frmStatus/RefreshStatusRate"), statusRate); - delete statusTimer; - settings->WriteInt(wxT("frmStatus/RefreshLockRate"), locksRate); - delete locksTimer; - if (viewMenu->IsEnabled(MNU_XACTPAGE)) - { - settings->WriteInt(wxT("frmStatus/RefreshXactRate"), xactRate); - if (xactTimer) - { - delete xactTimer; - xactTimer = NULL; - } - } - if (viewMenu->IsEnabled(MNU_LOGPAGE)) - { - settings->WriteInt(wxT("frmStatus/RefreshLogRate"), logRate); - emptyLogfileCombo(); - if (logTimer) - { - delete logTimer; - logTimer = NULL; - } - } - if (viewMenu->IsEnabled(MNU_QUERYSTATEPAGE)) - { - settings->WriteInt(wxT("frmStatus/RefreshQuerystateRate"), querystateRate); - if (querystateTimer) - { - delete querystateTimer; - querystateTimer = NULL; - } - } + // For each current page, save the slider's position and delete the timer + settings->WriteInt(wxT("frmStatus/RefreshStatusRate"), statusRate); + delete statusTimer; + settings->WriteInt(wxT("frmStatus/RefreshLockRate"), locksRate); + delete locksTimer; + if (viewMenu->IsEnabled(MNU_XACTPAGE)) + { + settings->WriteInt(wxT("frmStatus/RefreshXactRate"), xactRate); + if (xactTimer) + { + delete xactTimer; + xactTimer = NULL; + } + } + if (viewMenu->IsEnabled(MNU_LOGPAGE)) + { + settings->WriteInt(wxT("frmStatus/RefreshLogRate"), logRate); + emptyLogfileCombo(); + if (logTimer) + { + delete logTimer; + logTimer = NULL; + } + } + if (viewMenu->IsEnabled(MNU_QUERYSTATEPAGE)) + { + settings->WriteInt(wxT("frmStatus/RefreshQuerystateRate"), querystateRate); + if (querystateTimer) + { + delete querystateTimer; + querystateTimer = NULL; + } + } - // If connection is still available, delete it - if (locks_connection && locks_connection != connection) - { - if (locks_connection->IsAlive()) - delete locks_connection; - } - if (connection) - { - if (connection->IsAlive()) - delete connection; - } - if (logThread) { - logThread->BreakRead(); - wxMilliSleep(50); - logThread->DoTerminate(); - //s_CloseLog.Wait(); - while (logThread != NULL) wxMilliSleep(50) ; - } - if (logconn) - { - if (logconn->IsAlive()) - delete logconn; - } + // If connection is still available, delete it + if (locks_connection && locks_connection != connection) + { + if (locks_connection->IsAlive()) + delete locks_connection; + } + if (connection) + { + if (connection->IsAlive()) + delete connection; + } + if (logThread) { + logThread->BreakRead(); + wxMilliSleep(50); + logThread->DoTerminate(); + //s_CloseLog.Wait(); + while (logThread != NULL) wxMilliSleep(50) ; + } + if (logconn) + { + if (logconn->IsAlive()) + delete logconn; + } } void frmStatus::Go() { - // Show the window - Show(true); + // Show the window + Show(true); - // Send RateChange event to launch each timer - wxScrollEvent nullScrollEvent; - if (viewMenu->IsChecked(MNU_STATUSPAGE)) - { - currentPane = PANE_STATUS; - cbRate->SetValue(rateToCboString(statusRate)); - OnRateChange(nullScrollEvent); - } - if (viewMenu->IsChecked(MNU_LOCKPAGE)) - { - currentPane = PANE_LOCKS; - cbRate->SetValue(rateToCboString(locksRate)); - OnRateChange(nullScrollEvent); - } - if (viewMenu->IsEnabled(MNU_XACTPAGE) && viewMenu->IsChecked(MNU_XACTPAGE)) - { - currentPane = PANE_XACT; - cbRate->SetValue(rateToCboString(xactRate)); - OnRateChange(nullScrollEvent); - } - if (viewMenu->IsEnabled(MNU_LOGPAGE) && viewMenu->IsChecked(MNU_LOGPAGE)) - { - currentPane = PANE_LOG; - cbRate->SetValue(rateToCboString(logRate)); - OnRateChange(nullScrollEvent); - } - if (viewMenu->IsEnabled(MNU_QUERYSTATEPAGE) && viewMenu->IsChecked(MNU_QUERYSTATEPAGE)) - { - currentPane = PANE_QUERYSTATE; - cbRate->SetValue(rateToCboString(querystateRate)); - OnRateChange(nullScrollEvent); - } + // Send RateChange event to launch each timer + wxScrollEvent nullScrollEvent; + if (viewMenu->IsChecked(MNU_STATUSPAGE)) + { + currentPane = PANE_STATUS; + cbRate->SetValue(rateToCboString(statusRate)); + OnRateChange(nullScrollEvent); + } + if (viewMenu->IsChecked(MNU_LOCKPAGE)) + { + currentPane = PANE_LOCKS; + cbRate->SetValue(rateToCboString(locksRate)); + OnRateChange(nullScrollEvent); + } + if (viewMenu->IsEnabled(MNU_XACTPAGE) && viewMenu->IsChecked(MNU_XACTPAGE)) + { + currentPane = PANE_XACT; + cbRate->SetValue(rateToCboString(xactRate)); + OnRateChange(nullScrollEvent); + } + if (viewMenu->IsEnabled(MNU_LOGPAGE) && viewMenu->IsChecked(MNU_LOGPAGE)) + { + currentPane = PANE_LOG; + cbRate->SetValue(rateToCboString(logRate)); + OnRateChange(nullScrollEvent); + } + if (viewMenu->IsEnabled(MNU_QUERYSTATEPAGE) && viewMenu->IsChecked(MNU_QUERYSTATEPAGE)) + { + currentPane = PANE_QUERYSTATE; + cbRate->SetValue(rateToCboString(querystateRate)); + OnRateChange(nullScrollEvent); + } - // Refresh all pages - wxCommandEvent nullEvent; - OnRefresh(nullEvent); + // Refresh all pages + wxCommandEvent nullEvent; + OnRefresh(nullEvent); } -void frmStatus::OnClose(wxCloseEvent& event) +void frmStatus::OnClose(wxCloseEvent &event) { - frm_exit = true; - if (logThread && logisread) { - logThread->BreakRead(); - event.Veto(); - } - else Destroy(); - //Destroy(); + frm_exit = true; + if (logThread && logisread) { + logThread->BreakRead(); + event.Veto(); + } else Destroy(); + //Destroy(); } -void frmStatus::OnExit(wxCommandEvent& event) +void frmStatus::OnExit(wxCommandEvent &event) { - wxCloseEvent e; - OnClose(e); - //Destroy(); + wxCloseEvent e; + OnClose(e); + //Destroy(); } -void frmStatus::OnChangeDatabase(wxCommandEvent& ev) +void frmStatus::OnChangeDatabase(wxCommandEvent &ev) { - wxString initquery; + wxString initquery; - if (locks_connection != connection) - { - delete locks_connection; - } + if (locks_connection != connection) + { + delete locks_connection; + } - locks_connection = new pgConn(connection->GetHostName(), connection->GetService(), connection->GetHostAddr(), cbDatabase->GetValue(), - connection->GetUser(), connection->GetPassword(), connection->GetPort(), connection->GetRole(), "", connection->GetSslMode(), - 0, connection->GetApplicationName(), connection->GetSSLCert(), connection->GetSSLKey(), connection->GetSSLRootCert(), connection->GetSSLCrl(), - connection->GetSSLCompression()); + locks_connection = new pgConn(connection->GetHostName(), connection->GetService(), connection->GetHostAddr(), cbDatabase->GetValue(), + connection->GetUser(), connection->GetPassword(), connection->GetPort(), connection->GetRole(),"", connection->GetSslMode(), + 0, connection->GetApplicationName(), connection->GetSSLCert(), connection->GetSSLKey(), connection->GetSSLRootCert(), connection->GetSSLCrl(), + connection->GetSSLCompression()); - pgUser* user = new pgUser(locks_connection->GetUser()); - if (user) - { - if (user->GetSuperuser()) - { - if (locks_connection->BackendMinimumVersion(8, 0)) - initquery = wxT("SET log_statement='none';SET log_duration='off';SET log_min_duration_statement=-1;"); - else - initquery = wxT("SET log_statement='off';SET log_duration='off';SET log_min_duration_statement=-1;"); - locks_connection->ExecuteVoid(initquery, false); - } - delete user; - } + pgUser *user = new pgUser(locks_connection->GetUser()); + if (user) + { + if (user->GetSuperuser()) + { + if (locks_connection->BackendMinimumVersion(8, 0)) + initquery = wxT("SET log_statement='none';SET log_duration='off';SET log_min_duration_statement=-1;"); + else + initquery = wxT("SET log_statement='off';SET log_duration='off';SET log_min_duration_statement=-1;"); + locks_connection->ExecuteVoid(initquery, false); + } + delete user; + } } void frmStatus::AddStatusPane() { - // Create panel - wxPanel* pnlActivity = new wxPanel(this); + // Create panel + wxPanel *pnlActivity = new wxPanel(this); - // Create flex grid - wxFlexGridSizer* grdActivity = new wxFlexGridSizer(1, 1, 5, 5); - grdActivity->AddGrowableCol(0); - grdActivity->AddGrowableRow(0); + // Create flex grid + wxFlexGridSizer *grdActivity = new wxFlexGridSizer(1, 1, 5, 5); + grdActivity->AddGrowableCol(0); + grdActivity->AddGrowableRow(0); - // Add the list control + // Add the list control #ifdef __WXMAC__ - // Switch to the generic list control. - // Disable sort on Mac. - wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); + // Switch to the generic list control. + // Disable sort on Mac. + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); #endif - wxListCtrl* lstStatus = new wxListCtrl(pnlActivity, CTL_STATUSLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); - // Now switch back + wxListCtrl *lstStatus = new wxListCtrl(pnlActivity, CTL_STATUSLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); + // Now switch back #ifdef __WXMAC__ - wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); #endif - grdActivity->Add(lstStatus, 0, wxGROW, 3); + grdActivity->Add(lstStatus, 0, wxGROW, 3); - // Add the panel to the notebook - manager.AddPane(pnlActivity, - wxAuiPaneInfo(). - Name(wxT("Activity")).Caption(_("Activity")). - CaptionVisible(true).CloseButton(true).MaximizeButton(true). - Dockable(true).Movable(true)); + // Add the panel to the notebook + manager.AddPane(pnlActivity, + wxAuiPaneInfo(). + Name(wxT("Activity")).Caption(_("Activity")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true). + Dockable(true).Movable(true)); - // Auto-sizing - pnlActivity->SetSizer(grdActivity); - grdActivity->Fit(pnlActivity); + // Auto-sizing + pnlActivity->SetSizer(grdActivity); + grdActivity->Fit(pnlActivity); - // Add each column to the list control - statusList = (ctlListView*)lstStatus; - statusList->AddColumn(_("PID"), 35); - if (connection->BackendMinimumVersion(8, 5)) - statusList->AddColumn(_("Application name"), 70); - statusList->AddColumn(_("Database"), 70); - statusList->AddColumn(_("User"), 70); - if (connection->BackendMinimumVersion(8, 1)) - { - statusList->AddColumn(_("Client"), 70); - statusList->AddColumn(_("Client start"), 80); - } - if (connection->BackendMinimumVersion(7, 4)) - statusList->AddColumn(_("Query start"), 50); - if (connection->BackendMinimumVersion(8, 3)) - statusList->AddColumn(_("TX start"), 50); - if (connection->BackendMinimumVersion(9, 2)) - { - statusList->AddColumn(_("State"), 35); - statusList->AddColumn(_("State change"), 35); - } - if (connection->BackendMinimumVersion(9, 4)) - { - statusList->AddColumn(_("Backend XID"), 35); - statusList->AddColumn(_("Backend XMin"), 35); - } - if (connection->BackendMinimumVersion(9, 6)) - { - statusList->AddColumn(_("W_Event_T"), 35); - statusList->AddColumn(_("W_Event"), 35); - } - statusList->AddColumn(_("Blocked by"), 35); - statusList->AddColumn(_("Query"), 500); + // Add each column to the list control + statusList = (ctlListView *)lstStatus; + statusList->AddColumn(_("PID"), 35); + if (connection->BackendMinimumVersion(8, 5)) + statusList->AddColumn(_("Application name"), 70); + statusList->AddColumn(_("Database"), 70); + statusList->AddColumn(_("User"), 70); + if (connection->BackendMinimumVersion(8, 1)) + { + statusList->AddColumn(_("Client"), 70); + statusList->AddColumn(_("Client start"), 80); + } + if (connection->BackendMinimumVersion(7, 4)) + statusList->AddColumn(_("Query start"), 50); + if (connection->BackendMinimumVersion(8, 3)) + statusList->AddColumn(_("TX start"), 50); + if (connection->BackendMinimumVersion(9, 2)) + { + statusList->AddColumn(_("State"), 35); + statusList->AddColumn(_("State change"), 35); + } + if (connection->BackendMinimumVersion(9, 4)) + { + statusList->AddColumn(_("Backend XID"), 35); + statusList->AddColumn(_("Backend XMin"), 35); + } + if (connection->BackendMinimumVersion(9, 6)) + { + statusList->AddColumn(_("W_Event_T"), 35); + statusList->AddColumn(_("W_Event"), 35); + } + statusList->AddColumn(_("Blocked by"), 35); + statusList->AddColumn(_("Query"), 500); - // Get through the list of columns to build the popup menu - // and reinitialize column's width if we find a saved width - statusPopupMenu = new wxMenu(); - wxListItem item; - item.SetMask(wxLIST_MASK_TEXT); - int savedwidth; - for (int col = 0; col < statusList->GetColumnCount(); col++) - { - // Get column - statusList->GetColumn(col, item); + // Get through the list of columns to build the popup menu + // and reinitialize column's width if we find a saved width + statusPopupMenu = new wxMenu(); + wxListItem item; + item.SetMask(wxLIST_MASK_TEXT); + int savedwidth; + for (int col = 0; col < statusList->GetColumnCount(); col++) + { + // Get column + statusList->GetColumn(col, item); - // Reinitialize column's width - settings->Read(wxT("frmStatus/StatusPane_") + item.GetText() + wxT("_Width"), &savedwidth, statusList->GetColumnWidth(col)); - if (savedwidth > 0) - statusList->SetColumnWidth(col, savedwidth); - else - statusList->SetColumnWidth(col, 0); - statusColWidth[col] = savedwidth; + // Reinitialize column's width + settings->Read(wxT("frmStatus/StatusPane_") + item.GetText() + wxT("_Width"), &savedwidth, statusList->GetColumnWidth(col)); + if (savedwidth > 0) + statusList->SetColumnWidth(col, savedwidth); + else + statusList->SetColumnWidth(col, 0); + statusColWidth[col] = savedwidth; - // Add new check item on the popup menu - statusPopupMenu->AppendCheckItem(1000 + col, item.GetText()); - statusPopupMenu->Check(1000 + col, statusList->GetColumnWidth(col) > 0); - this->Connect(1000 + col, wxEVT_COMMAND_MENU_SELECTED, - wxCommandEventHandler(frmStatus::OnStatusMenu)); - } + // Add new check item on the popup menu + statusPopupMenu->AppendCheckItem(1000 + col, item.GetText()); + statusPopupMenu->Check(1000 + col, statusList->GetColumnWidth(col) > 0); + this->Connect(1000 + col, wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler(frmStatus::OnStatusMenu)); + } - // Build image list - statusList->SetImageList(listimages, wxIMAGE_LIST_SMALL); + // Build image list + statusList->SetImageList(listimages, wxIMAGE_LIST_SMALL); - // Read statusRate configuration - settings->Read(wxT("frmStatus/RefreshStatusRate"), &statusRate, 10); + // Read statusRate configuration + settings->Read(wxT("frmStatus/RefreshStatusRate"), &statusRate, 10); - // Initialize sort order - statusSortColumn = 1; - statusSortOrder = wxT("ASC"); - // Create the timer - statusTimer = new wxTimer(this, TIMER_STATUS_ID); + // Initialize sort order + statusSortColumn = 1; + statusSortOrder = wxT("ASC"); + // Create the timer + statusTimer = new wxTimer(this, TIMER_STATUS_ID); } void frmStatus::AddLockPane() { - // Create panel - wxPanel* pnlLock = new wxPanel(this); + // Create panel + wxPanel *pnlLock = new wxPanel(this); - // Create flex grid - wxFlexGridSizer* grdLock = new wxFlexGridSizer(1, 1, 5, 5); - grdLock->AddGrowableCol(0); - grdLock->AddGrowableRow(0); + // Create flex grid + wxFlexGridSizer *grdLock = new wxFlexGridSizer(1, 1, 5, 5); + grdLock->AddGrowableCol(0); + grdLock->AddGrowableRow(0); - // Add the list control + // Add the list control #ifdef __WXMAC__ - // Switch to the generic list control. - // Disable sort on Mac. - wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); + // Switch to the generic list control. + // Disable sort on Mac. + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); #endif - wxListCtrl* lstLocks = new wxListCtrl(pnlLock, CTL_LOCKLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); - // Now switch back + wxListCtrl *lstLocks = new wxListCtrl(pnlLock, CTL_LOCKLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); + // Now switch back #ifdef __WXMAC__ - wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); #endif - grdLock->Add(lstLocks, 0, wxGROW, 3); + grdLock->Add(lstLocks, 0, wxGROW, 3); - // Add the panel to the notebook - manager.AddPane(pnlLock, - wxAuiPaneInfo(). - Name(wxT("Locks")).Caption(_("Locks")). - CaptionVisible(true).CloseButton(true).MaximizeButton(true). - Dockable(true).Movable(true)); + // Add the panel to the notebook + manager.AddPane(pnlLock, + wxAuiPaneInfo(). + Name(wxT("Locks")).Caption(_("Locks")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true). + Dockable(true).Movable(true)); - // Auto-sizing - pnlLock->SetSizer(grdLock); - grdLock->Fit(pnlLock); + // Auto-sizing + pnlLock->SetSizer(grdLock); + grdLock->Fit(pnlLock); - // Add each column to the list control - lockList = (ctlListView*)lstLocks; - lockList->AddColumn(wxT("PID"), 35); - lockList->AddColumn(_("Database"), 50); - lockList->AddColumn(_("Relation"), 50); - lockList->AddColumn(_("User"), 50); - if (locks_connection->BackendMinimumVersion(8, 3)) - lockList->AddColumn(_("XID"), 50); - lockList->AddColumn(_("TX"), 50); - lockList->AddColumn(_("Mode"), 50); - lockList->AddColumn(_("Granted"), 50); - if (locks_connection->BackendMinimumVersion(7, 4)) - lockList->AddColumn(_("Start"), 50); - lockList->AddColumn(_("Query"), 500); + // Add each column to the list control + lockList = (ctlListView *)lstLocks; + lockList->AddColumn(wxT("PID"), 35); + lockList->AddColumn(_("Database"), 50); + lockList->AddColumn(_("Relation"), 50); + lockList->AddColumn(_("User"), 50); + if (locks_connection->BackendMinimumVersion(8, 3)) + lockList->AddColumn(_("XID"), 50); + lockList->AddColumn(_("TX"), 50); + lockList->AddColumn(_("Mode"), 50); + lockList->AddColumn(_("Granted"), 50); + if (locks_connection->BackendMinimumVersion(7, 4)) + lockList->AddColumn(_("Start"), 50); + lockList->AddColumn(_("Query"), 500); - // Get through the list of columns to build the popup menu - lockPopupMenu = new wxMenu(); - wxListItem item; - item.SetMask(wxLIST_MASK_TEXT); - int savedwidth; - for (int col = 0; col < lockList->GetColumnCount(); col++) - { - // Get column - lockList->GetColumn(col, item); - int currwidth = lockList->GetColumnWidth(col); - // Reinitialize column's width - settings->Read(wxT("frmStatus/LockPane_") + item.GetText() + wxT("_Width"), &savedwidth, currwidth); - if (savedwidth > 0) - lockList->SetColumnWidth(col, savedwidth); - else - lockList->SetColumnWidth(col, 0); - lockColWidth[col] = savedwidth; + // Get through the list of columns to build the popup menu + lockPopupMenu = new wxMenu(); + wxListItem item; + item.SetMask(wxLIST_MASK_TEXT); + int savedwidth; + for (int col = 0; col < lockList->GetColumnCount(); col++) + { + // Get column + lockList->GetColumn(col, item); + int currwidth = lockList->GetColumnWidth(col); + // Reinitialize column's width + settings->Read(wxT("frmStatus/LockPane_") + item.GetText() + wxT("_Width"), &savedwidth, currwidth); + if (savedwidth > 0) + lockList->SetColumnWidth(col, savedwidth); + else + lockList->SetColumnWidth(col, 0); + lockColWidth[col] = savedwidth; - // Add new check item on the popup menu - lockPopupMenu->AppendCheckItem(2000 + col, item.GetText()); - lockPopupMenu->Check(2000 + col, lockList->GetColumnWidth(col) > 0); - this->Connect(2000 + col, wxEVT_COMMAND_MENU_SELECTED, - wxCommandEventHandler(frmStatus::OnLockMenu)); - } + // Add new check item on the popup menu + lockPopupMenu->AppendCheckItem(2000 + col, item.GetText()); + lockPopupMenu->Check(2000 + col, lockList->GetColumnWidth(col) > 0); + this->Connect(2000 + col, wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler(frmStatus::OnLockMenu)); + } - // Build image list - lockList->SetImageList(listimages, wxIMAGE_LIST_SMALL); + // Build image list + lockList->SetImageList(listimages, wxIMAGE_LIST_SMALL); - // Read locksRate configuration - settings->Read(wxT("frmStatus/RefreshLockRate"), &locksRate, 10); + // Read locksRate configuration + settings->Read(wxT("frmStatus/RefreshLockRate"), &locksRate, 10); - // Initialize sort order - lockSortColumn = 1; - lockSortOrder = wxT("ASC"); + // Initialize sort order + lockSortColumn = 1; + lockSortOrder = wxT("ASC"); - // Create the timer - locksTimer = new wxTimer(this, TIMER_LOCKS_ID); + // Create the timer + locksTimer = new wxTimer(this, TIMER_LOCKS_ID); } void frmStatus::AddXactPane() { - // Create panel - wxPanel* pnlXacts = new wxPanel(this); + // Create panel + wxPanel *pnlXacts = new wxPanel(this); - // Create flex grid - wxFlexGridSizer* grdXacts = new wxFlexGridSizer(1, 1, 5, 5); - grdXacts->AddGrowableCol(0); - grdXacts->AddGrowableRow(0); + // Create flex grid + wxFlexGridSizer *grdXacts = new wxFlexGridSizer(1, 1, 5, 5); + grdXacts->AddGrowableCol(0); + grdXacts->AddGrowableRow(0); - // Add the list control + // Add the list control #ifdef __WXMAC__ - // Switch to the generic list control. - // Disable sort on Mac. - wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); + // Switch to the generic list control. + // Disable sort on Mac. + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); #endif - wxListCtrl* lstXacts = new wxListCtrl(pnlXacts, CTL_XACTLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); - // Now switch back + wxListCtrl *lstXacts = new wxListCtrl(pnlXacts, CTL_XACTLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); + // Now switch back #ifdef __WXMAC__ - wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); #endif - grdXacts->Add(lstXacts, 0, wxGROW, 3); + grdXacts->Add(lstXacts, 0, wxGROW, 3); - // Add the panel to the notebook - manager.AddPane(pnlXacts, - wxAuiPaneInfo(). - Name(wxT("Transactions")).Caption(_("Transactions")). - CaptionVisible(true).CloseButton(true).MaximizeButton(true). - Dockable(true).Movable(true)); + // Add the panel to the notebook + manager.AddPane(pnlXacts, + wxAuiPaneInfo(). + Name(wxT("Transactions")).Caption(_("Transactions")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true). + Dockable(true).Movable(true)); - // Auto-sizing - pnlXacts->SetSizer(grdXacts); - grdXacts->Fit(pnlXacts); + // Auto-sizing + pnlXacts->SetSizer(grdXacts); + grdXacts->Fit(pnlXacts); - // Add the xact list - xactList = (ctlListView*)lstXacts; + // Add the xact list + xactList = (ctlListView *)lstXacts; - // We don't need this report if server release is less than 8.1 - // GPDB doesn't have external global transactions. - // Perhaps we should use this display to show our - // global xid to local xid mappings? - if (!connection->BackendMinimumVersion(8, 1) || connection->GetIsGreenplum()) - { - // manager.GetPane(wxT("Transactions")).Show(false); - lstXacts->InsertColumn(lstXacts->GetColumnCount(), _("Message"), wxLIST_FORMAT_LEFT, 800); - lstXacts->InsertItem(lstXacts->GetItemCount(), _("Prepared transactions not available on this server."), -1); - lstXacts->Enable(false); - xactTimer = NULL; + // We don't need this report if server release is less than 8.1 + // GPDB doesn't have external global transactions. + // Perhaps we should use this display to show our + // global xid to local xid mappings? + if (!connection->BackendMinimumVersion(8, 1) || connection->GetIsGreenplum()) + { + // manager.GetPane(wxT("Transactions")).Show(false); + lstXacts->InsertColumn(lstXacts->GetColumnCount(), _("Message"), wxLIST_FORMAT_LEFT, 800); + lstXacts->InsertItem(lstXacts->GetItemCount(), _("Prepared transactions not available on this server."), -1); + lstXacts->Enable(false); + xactTimer = NULL; - // We're done - return; - } + // We're done + return; + } - // Add each column to the list control - xactList->AddColumn(wxT("XID"), 50); - xactList->AddColumn(_("Global ID"), 200); - xactList->AddColumn(_("Time"), 100); - xactList->AddColumn(_("Owner"), 50); - xactList->AddColumn(_("Database"), 50); + // Add each column to the list control + xactList->AddColumn(wxT("XID"), 50); + xactList->AddColumn(_("Global ID"), 200); + xactList->AddColumn(_("Time"), 100); + xactList->AddColumn(_("Owner"), 50); + xactList->AddColumn(_("Database"), 50); - // Get through the list of columns to build the popup menu - xactPopupMenu = new wxMenu(); - wxListItem item; - item.SetMask(wxLIST_MASK_TEXT); - int savedwidth; - for (int col = 0; col < xactList->GetColumnCount(); col++) - { - // Get column - xactList->GetColumn(col, item); - int currwidth = xactList->GetColumnWidth(col); - // Reinitialize column's width - settings->Read(wxT("frmStatus/XactPane_") + item.GetText() + wxT("_Width"), &savedwidth, currwidth); - if (savedwidth > 0) - xactList->SetColumnWidth(col, savedwidth); - else - xactList->SetColumnWidth(col, 0); - xactColWidth[col] = savedwidth; + // Get through the list of columns to build the popup menu + xactPopupMenu = new wxMenu(); + wxListItem item; + item.SetMask(wxLIST_MASK_TEXT); + int savedwidth; + for (int col = 0; col < xactList->GetColumnCount(); col++) + { + // Get column + xactList->GetColumn(col, item); + int currwidth = xactList->GetColumnWidth(col); + // Reinitialize column's width + settings->Read(wxT("frmStatus/XactPane_") + item.GetText() + wxT("_Width"), &savedwidth, currwidth); + if (savedwidth > 0) + xactList->SetColumnWidth(col, savedwidth); + else + xactList->SetColumnWidth(col, 0); + xactColWidth[col] = savedwidth; - // Add new check item on the popup menu - xactPopupMenu->AppendCheckItem(3000 + col, item.GetText()); - xactPopupMenu->Check(3000 + col, xactList->GetColumnWidth(col) > 0); - this->Connect(3000 + col, wxEVT_COMMAND_MENU_SELECTED, - wxCommandEventHandler(frmStatus::OnXactMenu)); - } + // Add new check item on the popup menu + xactPopupMenu->AppendCheckItem(3000 + col, item.GetText()); + xactPopupMenu->Check(3000 + col, xactList->GetColumnWidth(col) > 0); + this->Connect(3000 + col, wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler(frmStatus::OnXactMenu)); + } - // Build image list - xactList->SetImageList(listimages, wxIMAGE_LIST_SMALL); + // Build image list + xactList->SetImageList(listimages, wxIMAGE_LIST_SMALL); - // Read xactRate configuration - settings->Read(wxT("frmStatus/RefreshXactRate"), &xactRate, 10); + // Read xactRate configuration + settings->Read(wxT("frmStatus/RefreshXactRate"), &xactRate, 10); - // Initialize sort order - xactSortColumn = 2; - xactSortOrder = wxT("ASC"); + // Initialize sort order + xactSortColumn = 2; + xactSortOrder = wxT("ASC"); - // Create the timer - xactTimer = new wxTimer(this, TIMER_XACT_ID); + // Create the timer + xactTimer = new wxTimer(this, TIMER_XACT_ID); } void frmStatus::AddQuerystatePane() { - // Create panel - wxPanel* pnlQuerystate = new wxPanel(this); + // Create panel + wxPanel *pnlQuerystate = new wxPanel(this); - // Create flex grid - wxFlexGridSizer* grdQuerystate = new wxFlexGridSizer(1, 1, 5, 5); - grdQuerystate->AddGrowableCol(0); - grdQuerystate->AddGrowableRow(0); + // Create flex grid + wxFlexGridSizer *grdQuerystate = new wxFlexGridSizer(1, 1, 5, 5); + grdQuerystate->AddGrowableCol(0); + grdQuerystate->AddGrowableRow(0); - // Add the list control + // Add the list control #ifdef __WXMAC__ - // Switch to the generic list control. - // Disable sort on Mac. - wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); + // Switch to the generic list control. + // Disable sort on Mac. + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); #endif - wxListCtrl* lstQuerystate = new wxListCtrl(pnlQuerystate, CTL_QUERYSTATELIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); - // Now switch back + wxListCtrl *lstQuerystate = new wxListCtrl(pnlQuerystate, CTL_QUERYSTATELIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); + // Now switch back #ifdef __WXMAC__ - wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); #endif - grdQuerystate->Add(lstQuerystate, 0, wxGROW, 3); + grdQuerystate->Add(lstQuerystate, 0, wxGROW, 3); - // Add the panel to the notebook - manager.AddPane(pnlQuerystate, - wxAuiPaneInfo().Center(). - Name(wxT("Querystate")).Caption(_("Query State")). - CaptionVisible(true).CloseButton(true).MaximizeButton(true). - Dockable(true).Movable(true)); + // Add the panel to the notebook + manager.AddPane(pnlQuerystate, + wxAuiPaneInfo().Center(). + Name(wxT("Querystate")).Caption(_("Query State")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true). + Dockable(true).Movable(true)); - // Auto-sizing - pnlQuerystate->SetSizer(grdQuerystate); - grdQuerystate->Fit(pnlQuerystate); + // Auto-sizing + pnlQuerystate->SetSizer(grdQuerystate); + grdQuerystate->Fit(pnlQuerystate); - // Add the xact list - querystateList = (ctlListView*)lstQuerystate; + // Add the xact list + querystateList = (ctlListView *)lstQuerystate; - // Add each column to the list control - querystateList->AddColumn(wxT("Pid"), 20); - querystateList->AddColumn(wxT("Fn"), 20); - querystateList->AddColumn(_("Query Text"), 200); - querystateList->AddColumn(_("Plan"), 300); - querystateList->AddColumn(wxT("Leader_pid"), 20); + // Add each column to the list control + querystateList->AddColumn(wxT("Pid"), 20); + querystateList->AddColumn(wxT("Fn"), 20); + querystateList->AddColumn(_("Query Text"), 200); + querystateList->AddColumn(_("Plan"), 300); + querystateList->AddColumn(wxT("Leader_pid"), 20); - // Get through the list of columns to build the popup menu - querystatePopupMenu = new wxMenu(); - wxListItem item; - item.SetMask(wxLIST_MASK_TEXT); - int savedwidth; - for (int col = 0; col < querystateList->GetColumnCount(); col++) - { - // Get column - querystateList->GetColumn(col, item); - wxString namec=item.GetText(); - int currwidth=querystateList->GetColumnWidth(col); - // Reinitialize column's width - settings->Read(wxT("frmStatus/QuerystatePane_") + namec + wxT("_Width"), &savedwidth, currwidth); - if (savedwidth > 0) - querystateList->SetColumnWidth(col, savedwidth); - else - querystateList->SetColumnWidth(col, 0); - querystateColWidth[col] = savedwidth; + // Get through the list of columns to build the popup menu + querystatePopupMenu = new wxMenu(); + wxListItem item; + item.SetMask(wxLIST_MASK_TEXT); + int savedwidth; + for (int col = 0; col < querystateList->GetColumnCount(); col++) + { + // Get column + querystateList->GetColumn(col, item); + wxString namec=item.GetText(); + int currwidth=querystateList->GetColumnWidth(col); + // Reinitialize column's width + settings->Read(wxT("frmStatus/QuerystatePane_") + namec + wxT("_Width"), &savedwidth, currwidth); + if (savedwidth > 0) + querystateList->SetColumnWidth(col, savedwidth); + else + querystateList->SetColumnWidth(col, 0); + querystateColWidth[col] = savedwidth; - // Add new check item on the popup menu - querystatePopupMenu->AppendCheckItem(4000 + col, item.GetText()); - querystatePopupMenu->Check(4000 + col, querystateList->GetColumnWidth(col) > 0); - this->Connect(4000 + col, wxEVT_COMMAND_MENU_SELECTED, - wxCommandEventHandler(frmStatus::OnQuerystateMenu)); - } + // Add new check item on the popup menu + querystatePopupMenu->AppendCheckItem(4000 + col, item.GetText()); + querystatePopupMenu->Check(4000 + col, querystateList->GetColumnWidth(col) > 0); + this->Connect(4000 + col, wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler(frmStatus::OnQuerystateMenu)); + } - // Build image list - querystateList->SetImageList(listimages, wxIMAGE_LIST_SMALL); + // Build image list + querystateList->SetImageList(listimages, wxIMAGE_LIST_SMALL); - // Read querystateRate configuration - settings->Read(wxT("frmStatus/RefreshQuerystateRate"), &querystateRate, 10); + // Read querystateRate configuration + settings->Read(wxT("frmStatus/RefreshQuerystateRate"), &querystateRate, 10); - // Initialize sort order - //QuerystateortColumn = 2; - //QuerystateortOrder = wxT("ASC"); + // Initialize sort order + //QuerystateortColumn = 2; + //QuerystateortOrder = wxT("ASC"); - // Create the timer - querystateTimer = new wxTimer(this, TIMER_QUERYSTATE_ID); - - pgSet* set = connection->ExecuteSet(wxT("SELECT 1 FROM pg_available_extensions WHERE installed_version is not null and name='pg_query_state'")); - if (set->NumRows() == 1) - viewMenu->Check(MNU_QUERYSTATEPAGE, true); - else - viewMenu->Check(MNU_QUERYSTATEPAGE, false); - delete set; + // Create the timer + querystateTimer = new wxTimer(this, TIMER_QUERYSTATE_ID); + + pgSet *set = connection->ExecuteSet(wxT("SELECT 1 FROM pg_available_extensions WHERE installed_version is not null and name='pg_query_state'")); + if (set->NumRows() == 1) + viewMenu->Check(MNU_QUERYSTATEPAGE,true); + else + viewMenu->Check(MNU_QUERYSTATEPAGE,false); + delete set; } void frmStatus::AddLogPane() { - int rc = -1; - wxString hint = HINT_INSTRUMENTATION; + int rc = -1; + wxString hint = HINT_INSTRUMENTATION; - // Create panel - wxPanel* pnlLog = new wxPanel(this); - //pnlLog->SetBackgroundColour(*wxRED); - // Create flex grid - wxFlexGridSizer* grdLog = new wxFlexGridSizer(1, 2, 2, 0); - //wxBoxSizer* grdLog = new wxBoxSizer(wxHORIZONTAL); - grdLog->AddGrowableCol(1); - grdLog->AddGrowableRow(0); + // Create panel + wxPanel *pnlLog = new wxPanel(this); + //pnlLog->SetBackgroundColour(*wxRED); + // Create flex grid + wxFlexGridSizer *grdLog = new wxFlexGridSizer(1, 2, 2, 0); + //wxBoxSizer* grdLog = new wxBoxSizer(wxHORIZONTAL); + grdLog->AddGrowableCol(1); + grdLog->AddGrowableRow(0); - // Add the list control + // Add the list control #ifdef __WXMAC__ - // Switch to the generic list control. - // Disable sort on Mac. - wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); -#endif - wxListCtrl* lstLog = new wxListCtrl(pnlLog, CTL_LOGLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); - // Add the log list - logList = (ctlListView*)lstLog; - nav = new ctlNavigatePanel(pnlLog, logList); - lstLog->Bind(wxEVT_KEY_UP, &frmStatus::OnLogKeyUp, this); - //lstLog->Bind(wxEVT_MENU, &ctlNavigatePanel::OnContextMenu, this); - Bind(wxEVT_THREAD, &frmStatus::OnAddLabelTextThread, this); - lstLog->Bind(wxEVT_MENU, &frmStatus::OnLogContextMenu, this); - //Connect(wxID_ANY, wxEVT_THREAD, wxThreadEventHandler(frmLog::OnAddLabelTextThread), NULL, this); - // Now switch back -#ifdef __WXMAC__ - wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); + // Switch to the generic list control. + // Disable sort on Mac. + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); #endif + //wxListCtrl *lstLog = new wxListCtrl(pnlLog, CTL_LOGLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); + logList = new ctlListView(pnlLog, CTL_LOGLIST, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER); + logList->SetToolTip(NULL); + // hide tooltip for windows +#ifdef __WXMSW__ + HWND hwndList = (HWND)logList->GetHandle(); + LPARAM style = ::SendMessage(hwndList, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0); + ::SendMessage(hwndList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, style & ~LVS_EX_LABELTIP); +#endif + // Add the log list + //logList = (ctlListView*)lstLog; + logList->SetModeStoreLongString(); + nav = new ctlNavigatePanel(pnlLog, logList); + logList->Bind(wxEVT_KEY_UP, &frmStatus::OnLogKeyUp, this); + //lstLog->Bind(wxEVT_MENU, &ctlNavigatePanel::OnContextMenu, this); + Bind(wxEVT_THREAD, &frmStatus::OnAddLabelTextThread, this); + logList->Bind(wxEVT_MENU, &frmStatus::OnLogContextMenu, this); + logList->Bind(wxEVT_MOTION, &frmStatus::OnMoveMouseLog, this); + //Connect(wxID_ANY, wxEVT_THREAD, wxThreadEventHandler(frmLog::OnAddLabelTextThread), NULL, this); + // Now switch back +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); +#endif + delayHitLog = new wxTimer(this, TIMER_LOGHINT_ID); + //Bind(wxEVT_TIMER, &frmStatus::OnTimerHintLog, this); + ///delayHitLog->Start(DELAYHITLOGPERIOD); - grdLog->Add(nav, 0, wxSHRINK, 3); - grdLog->Add(lstLog, 0, wxALL | wxEXPAND, 3); - // Add the panel to the notebook - manager.AddPane(pnlLog, - wxAuiPaneInfo().Center(). - Name(wxT("Logfile")).Caption(_("Logfile")). - CaptionVisible(true).CloseButton(true).MaximizeButton(true). - Dockable(true).Movable(true)); + grdLog->Add(nav, 0, wxSHRINK, 3); + grdLog->Add(logList, 0, wxALL | wxEXPAND, 3); + // Add the panel to the notebook + manager.AddPane(pnlLog, + wxAuiPaneInfo().Center(). + Name(wxT("Logfile")).Caption(_("Logfile")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true). + Dockable(true).Movable(true)); - // Auto-sizing - pnlLog->SetSizer(grdLog); - grdLog->Fit(pnlLog); + // Auto-sizing + pnlLog->SetSizer(grdLog); + grdLog->Fit(pnlLog); - logcol[0] = logList->GetBackgroundColour(); - logcol[1] = wxColour("#afafaf"); - // We don't need this report (but we need the pane) - // if server release is less than 8.0 or if server has no adminpack - if (!is_read_log) { - logList->InsertColumn(logList->GetColumnCount(), _("Message"), wxLIST_FORMAT_LEFT, 700); - logList->InsertItem(logList->GetItemCount(), _("Function pg_read_binary_file(text,bigint,bigint,boolean) permission denied."), -1); - logList->Enable(false); - logTimer = NULL; - // We're done - return; + logcol[0] = logList->GetBackgroundColour(); + logcol[1] = wxColour("#afafaf"); + // We don't need this report (but we need the pane) + // if server release is less than 8.0 or if server has no adminpack + if (!is_read_log) { + logList->InsertColumn(logList->GetColumnCount(), _("Message"), wxLIST_FORMAT_LEFT, 700); + logList->AppendItem(-1, _("Function pg_read_binary_file(text,bigint,bigint,boolean) permission denied.")); + logList->Enable(false); + logTimer = NULL; + // We're done + return; - } - if (!(connection->BackendMinimumVersion(8, 0) && - connection->HasFeature(FEATURE_FILEREAD))) - { - // if the server release is 9.1 or more and the server has no adminpack - if (connection->BackendMinimumVersion(9, 1)) - { - // Search the adminpack extension - pgSet* set = connection->ExecuteSet(wxT("SELECT 1 FROM pg_available_extensions WHERE name='adminpack'")); - if (set->NumRows() == 1) - hint = HINT_INSTRUMENTATION_91_WITH; - else - hint = HINT_INSTRUMENTATION_91_WITHOUT; - delete set; - } + } + if (!(connection->BackendMinimumVersion(8, 0) && + connection->HasFeature(FEATURE_FILEREAD))) + { + // if the server release is 9.1 or more and the server has no adminpack + if (connection->BackendMinimumVersion(9, 1)) + { + // Search the adminpack extension + pgSet *set = connection->ExecuteSet(wxT("SELECT 1 FROM pg_available_extensions WHERE name='adminpack'")); + if (set->NumRows() == 1) + hint = HINT_INSTRUMENTATION_91_WITH; + else + hint = HINT_INSTRUMENTATION_91_WITHOUT; + delete set; + } - if (connection->BackendMinimumVersion(8, 0)) - rc = frmHint::ShowHint(this, hint); + if (connection->BackendMinimumVersion(8, 0)) + rc = frmHint::ShowHint(this, hint); - if (rc == HINT_RC_FIX) - connection->ExecuteVoid(wxT("CREATE EXTENSION adminpack"), true); + if (rc == HINT_RC_FIX) + connection->ExecuteVoid(wxT("CREATE EXTENSION adminpack"), true); - if (!connection->HasFeature(FEATURE_FILEREAD, true)) - { - logList->InsertColumn(logList->GetColumnCount(), _("Message"), wxLIST_FORMAT_LEFT, wxLIST_AUTOSIZE_USEHEADER); - logList->InsertItem(logList->GetItemCount(), _("Logs are not available for this server."), -1); - logList->Enable(false); - logTimer = NULL; - // We're done - return; - } - } + if (!connection->HasFeature(FEATURE_FILEREAD, true)) + { + logList->InsertColumn(logList->GetColumnCount(), _("Message"), wxLIST_FORMAT_LEFT, wxLIST_AUTOSIZE_USEHEADER); + logList->AppendItem(-1,_("Logs are not available for this server.")); + logList->Enable(false); + logTimer = NULL; + // We're done + return; + } + } - // Add each column to the list control - logFormat = connection->ExecuteScalar(wxT("SHOW log_line_prefix")); - if (logFormat == wxT("unset")) - logFormat = wxEmptyString; - logFmtPos = logFormat.Find('%', true); + // Add each column to the list control + logFormat = connection->ExecuteScalar(wxT("SHOW log_line_prefix")); + if (logFormat == wxT("unset")) + logFormat = wxEmptyString; + logFmtPos = logFormat.Find('%', true); - if (logFmtPos < 0) - logFormatKnown = true; // log_line_prefix not specified. - else if (!logFmtPos && logFormat.Mid(logFmtPos, 2) == wxT("%t") && logFormat.Length() > 2) // Timestamp at end of log_line_prefix? - { - logFormatKnown = true; - logHasTimestamp = true; - } - else if (connection->GetIsGreenplum()) - { - // Always %m|%u|%d|%p|%I|%X|:- (timestamp w/ millisec) for 3.2.x - // Usually CSV formatted for 3.3 - logFormatKnown = true; - logHasTimestamp = true; - } + if (logFmtPos < 0) + logFormatKnown = true; // log_line_prefix not specified. + else if (!logFmtPos && logFormat.Mid(logFmtPos, 2) == wxT("%t") && logFormat.Length() > 2) // Timestamp at end of log_line_prefix? + { + logFormatKnown = true; + logHasTimestamp = true; + } + else if (connection->GetIsGreenplum()) + { + // Always %m|%u|%d|%p|%I|%X|:- (timestamp w/ millisec) for 3.2.x + // Usually CSV formatted for 3.3 + logFormatKnown = true; + logHasTimestamp = true; + } - if (connection->GetIsGreenplum() && connection->BackendMinimumVersion(8, 2, 13)) - { - // Be ready for GPDB CSV format log file - logList->AddColumn(_("Timestamp"), 120); // Room for millisecs - logList->AddColumn(_("Level"), 35); - logList->AddColumn(_("Log entry"), 400); - logList->AddColumn(_("Connection"), 45); - logList->AddColumn(_("Cmd number"), 48); - logList->AddColumn(_("Dbname"), 48); - logList->AddColumn(_("Segment"), 45); - } - else // Non-GPDB or non-CSV format log - { - if (logHasTimestamp) - logList->AddColumn(_("Timestamp"), 100); + if (connection->GetIsGreenplum() && connection->BackendMinimumVersion(8, 2, 13)) + { + // Be ready for GPDB CSV format log file + logList->AddColumn(_("Timestamp"), 120); // Room for millisecs + logList->AddColumn(_("Level"), 35); + logList->AddColumn(_("Log entry"), 400); + logList->AddColumn(_("Connection"), 45); + logList->AddColumn(_("Cmd number"), 48); + logList->AddColumn(_("Dbname"), 48); + logList->AddColumn(_("Segment"), 45); + } + else // Non-GPDB or non-CSV format log + { + if (logHasTimestamp) + logList->AddColumn(_("Timestamp"), 100); - if (logFormatKnown) - logList->AddColumn(_("Level"), 35); + if (logFormatKnown) + logList->AddColumn(_("Level"), 35); - logList->AddColumn(_("Log entry"), 800); - } + logList->AddColumn(_("Log entry"), 800); + } - if (!connection->HasFeature(FEATURE_ROTATELOG)) - btnRotateLog->Disable(); + if (!connection->HasFeature(FEATURE_ROTATELOG)) + btnRotateLog->Disable(); - // Re-initialize variables - logfileLength = 0; + // Re-initialize variables + logfileLength = 0; - // Read logRate configuration - settings->Read(wxT("frmStatus/RefreshLogRate"), &logRate, 10); + // Read logRate configuration + settings->Read(wxT("frmStatus/RefreshLogRate"), &logRate, 10); - // Create the timer - logTimer = new wxTimer(this, TIMER_LOG_ID); + // Create the timer + logTimer = new wxTimer(this, TIMER_LOG_ID); } -void frmStatus::OnCopy(wxCommandEvent& ev) +void frmStatus::OnCopy(wxCommandEvent &ev) { - ctlListView* list; - int row, col; - wxString text; + ctlListView *list; + int row, col; + wxString text; - switch (currentPane) - { - case PANE_STATUS: - list = statusList; - break; - case PANE_LOCKS: - list = lockList; - break; - case PANE_XACT: - list = xactList; - break; - case PANE_LOG: - list = logList; - break; - case PANE_QUERYSTATE: - list = querystateList; - break; - default: - // This shouldn't happen. - // If it does, it's no big deal, we just need to get out. - return; - break; - } - if (currentPane == PANE_QUERYSTATE) { - wxString s; - for (row = 0; row < list->GetItemCount(); row++) - { - s = list->GetText(row, 2); - if (s.Length() > 0) { - text.Append(wxT("SQL QUERY: ")).Append(s); -#ifdef __WXMSW__ - text.Append(wxT("\r\n")); -#else - text.Append(wxT("\n")); -#endif - } - text.Append(list->GetText(row, 3)); -#ifdef __WXMSW__ - text.Append(wxT("\r\n")); -#else - text.Append(wxT("\n")); -#endif - } - // list->GetText(row,3); - } - else - { - row = list->GetFirstSelected(); + switch(currentPane) + { + case PANE_STATUS: + list = statusList; + break; + case PANE_LOCKS: + list = lockList; + break; + case PANE_XACT: + list = xactList; + break; + case PANE_LOG: + list = logList; + break; + case PANE_QUERYSTATE: + list = querystateList; + break; + default: + // This shouldn't happen. + // If it does, it's no big deal, we just need to get out. + return; + break; + } + if (currentPane==PANE_QUERYSTATE) { + wxString s; + for (row = 0; row < list->GetItemCount(); row++) + { + s=list->GetText(row, 2); + if (s.Length()>0) { + text.Append(wxT("SQL QUERY: ")).Append(s); + #ifdef __WXMSW__ + text.Append(wxT("\r\n")); + #else + text.Append(wxT("\n")); + #endif + } + text.Append(list->GetText(row, 3)); + #ifdef __WXMSW__ + text.Append(wxT("\r\n")); + #else + text.Append(wxT("\n")); + #endif + } +// list->GetText(row,3); + } else + { + row = list->GetFirstSelected(); - while (row >= 0) - { - for (col = 0; col < list->GetColumnCount(); col++) - { - text.Append(list->GetText(row, col) + wxT("\t")); - } -#ifdef __WXMSW__ - text.Append(wxT("\r\n")); -#else - text.Append(wxT("\n")); -#endif - row = list->GetNextSelected(row); - } - } - if (text.Length() > 0 && wxTheClipboard->Open()) - { - wxTheClipboard->SetData(new wxTextDataObject(text)); - wxTheClipboard->Close(); - } + while (row >= 0) + { + for (col = 0; col < list->GetColumnCount(); col++) + { + text.Append(list->GetText(row, col) + wxT("\t")); + } + #ifdef __WXMSW__ + text.Append(wxT("\r\n")); + #else + text.Append(wxT("\n")); + #endif + row = list->GetNextSelected(row); + } + } + if (text.Length() > 0 && wxTheClipboard->Open()) + { + wxTheClipboard->SetData(new wxTextDataObject(text)); + wxTheClipboard->Close(); + } } -void frmStatus::OnCopyQuery(wxCommandEvent& ev) +void frmStatus::OnCopyQuery(wxCommandEvent &ev) { - ctlListView* list; - int row, col; - wxString text = wxT(""); - wxString dbname = wxT(""); - unsigned int maxlength; + ctlListView *list; + int row, col; + wxString text = wxT(""); + wxString dbname = wxT(""); + unsigned int maxlength; - // Only the status list shows the query - list = statusList; + // Only the status list shows the query + list = statusList; - // Get the database - row = list->GetFirstSelected(); - col = connection->BackendMinimumVersion(9, 0) ? 2 : 1; - dbname.Append(list->GetText(row, col)); + // Get the database + row = list->GetFirstSelected(); + col = connection->BackendMinimumVersion(9, 0) ? 2 : 1; + dbname.Append(list->GetText(row, col)); - // Get the actual query - row = list->GetFirstSelected(); - text.Append(queries.Item(row)); + // Get the actual query + row = list->GetFirstSelected(); + text.Append(queries.Item(row)); - // Check if we have a query whose length is maximum - maxlength = 1024; - if (connection->BackendMinimumVersion(8, 4)) - { - pgSet* set; - set = connection->ExecuteSet(wxT("SELECT setting FROM pg_settings\n") - wxT(" WHERE name='track_activity_query_size'")); - if (set) - { - maxlength = set->GetLong(0); - delete set; - } - } + // Check if we have a query whose length is maximum + maxlength = 1024; + if (connection->BackendMinimumVersion(8, 4)) + { + pgSet *set; + set = connection->ExecuteSet(wxT("SELECT setting FROM pg_settings\n") + wxT(" WHERE name='track_activity_query_size'")); + if (set) + { + maxlength = set->GetLong(0); + delete set; + } + } - if (text.Length() == maxlength) - { - wxLogError(_("The query you copied is at the maximum length.\nIt may have been truncated.")); - } + if (text.Length() == maxlength) + { + wxLogError(_("The query you copied is at the maximum length.\nIt may have been truncated.")); + } - // If we have some real query, launch the query tool - if (text.Length() > 0 && dbname.Length() > 0 - && text.Trim() != wxT("") && text.Trim() != wxT("")) - { - pgConn* conn = new pgConn(connection->GetHostName(), connection->GetService(), connection->GetHostAddr(), dbname, - connection->GetUser(), connection->GetPassword(), - connection->GetPort(), connection->GetRole(), "", connection->GetSslMode(), connection->GetDbOid(), - connection->GetApplicationName(), - connection->GetSSLCert(), connection->GetSSLKey(), connection->GetSSLRootCert(), connection->GetSSLCrl(), - connection->GetSSLCompression()); - if (conn) - { - frmQuery* fq = new frmQuery(mainForm, wxEmptyString, conn, text); - fq->Go(); - mainForm->AddFrame(fq); - } - } + // If we have some real query, launch the query tool + if (text.Length() > 0 && dbname.Length() > 0 + && text.Trim() != wxT("") && text.Trim() != wxT("")) + { + pgConn *conn = new pgConn(connection->GetHostName(), connection->GetService(), connection->GetHostAddr(), dbname, + connection->GetUser(), connection->GetPassword(), + connection->GetPort(), connection->GetRole(),"", connection->GetSslMode(), connection->GetDbOid(), + connection->GetApplicationName(), + connection->GetSSLCert(), connection->GetSSLKey(), connection->GetSSLRootCert(), connection->GetSSLCrl(), + connection->GetSSLCompression()); + if (conn) + { + frmQuery *fq = new frmQuery(mainForm, wxEmptyString, conn, text); + fq->Go(); + mainForm->AddFrame(fq); + } + } } void frmStatus::OnPaneActivated(wxAuiManagerEvent& evt) { - wxTimerEvent event; - OnRefreshUITimer(event); + wxTimerEvent event; + OnRefreshUITimer(event); } -void frmStatus::OnPaneClose(wxAuiManagerEvent& evt) +void frmStatus::OnPaneClose(wxAuiManagerEvent &evt) { - if (evt.pane->name == wxT("Activity")) - { - viewMenu->Check(MNU_STATUSPAGE, false); - statusTimer->Stop(); - } - if (evt.pane->name == wxT("Locks")) - { - viewMenu->Check(MNU_LOCKPAGE, false); - locksTimer->Stop(); - } - if (evt.pane->name == wxT("Transactions")) - { - viewMenu->Check(MNU_XACTPAGE, false); - if (xactTimer) - xactTimer->Stop(); - } - if (evt.pane->name == wxT("Logfile")) - { - viewMenu->Check(MNU_LOGPAGE, false); + if (evt.pane->name == wxT("Activity")) + { + viewMenu->Check(MNU_STATUSPAGE, false); + statusTimer->Stop(); + } + if (evt.pane->name == wxT("Locks")) + { + viewMenu->Check(MNU_LOCKPAGE, false); + locksTimer->Stop(); + } + if (evt.pane->name == wxT("Transactions")) + { + viewMenu->Check(MNU_XACTPAGE, false); + if (xactTimer) + xactTimer->Stop(); + } + if (evt.pane->name == wxT("Logfile")) + { + viewMenu->Check(MNU_LOGPAGE, false); - if (logThread) logThread->BreakRead(); - if (logTimer) - logTimer->Stop(); - } - if (evt.pane->name == wxT("Querystate")) - { - viewMenu->Check(MNU_QUERYSTATEPAGE, false); - if (querystateTimer) - querystateTimer->Stop(); - } + if (logThread) logThread->BreakRead(); + if (logTimer) + logTimer->Stop(); + } + if (evt.pane->name == wxT("Querystate")) + { + viewMenu->Check(MNU_QUERYSTATEPAGE, false); + if (querystateTimer) + querystateTimer->Stop(); + } } -void frmStatus::OnToggleStatusPane(wxCommandEvent& event) +void frmStatus::OnToggleStatusPane(wxCommandEvent &event) { - if (viewMenu->IsChecked(MNU_STATUSPAGE)) - { - manager.GetPane(wxT("Activity")).Show(true); - cbRate->SetValue(rateToCboString(statusRate)); - if (statusRate > 0) - statusTimer->Start(statusRate * 1000L); - } - else - { - manager.GetPane(wxT("Activity")).Show(false); - statusTimer->Stop(); - } + if (viewMenu->IsChecked(MNU_STATUSPAGE)) + { + manager.GetPane(wxT("Activity")).Show(true); + cbRate->SetValue(rateToCboString(statusRate)); + if (statusRate > 0) + statusTimer->Start(statusRate * 1000L); + } + else + { + manager.GetPane(wxT("Activity")).Show(false); + statusTimer->Stop(); + } - // Tell the manager to "commit" all the changes just made - manager.Update(); + // Tell the manager to "commit" all the changes just made + manager.Update(); } -void frmStatus::OnToggleLockPane(wxCommandEvent& event) +void frmStatus::OnToggleLockPane(wxCommandEvent &event) { - if (viewMenu->IsChecked(MNU_LOCKPAGE)) - { - manager.GetPane(wxT("Locks")).Show(true); - cbRate->SetValue(rateToCboString(locksRate)); - if (locksRate > 0) - locksTimer->Start(locksRate * 1000L); - } - else - { - manager.GetPane(wxT("Locks")).Show(false); - locksTimer->Stop(); - } + if (viewMenu->IsChecked(MNU_LOCKPAGE)) + { + manager.GetPane(wxT("Locks")).Show(true); + cbRate->SetValue(rateToCboString(locksRate)); + if (locksRate > 0) + locksTimer->Start(locksRate * 1000L); + } + else + { + manager.GetPane(wxT("Locks")).Show(false); + locksTimer->Stop(); + } - // Tell the manager to "commit" all the changes just made - manager.Update(); + // Tell the manager to "commit" all the changes just made + manager.Update(); } -void frmStatus::OnToggleXactPane(wxCommandEvent& event) +void frmStatus::OnToggleXactPane(wxCommandEvent &event) { - if (viewMenu->IsEnabled(MNU_XACTPAGE) && viewMenu->IsChecked(MNU_XACTPAGE)) - { - manager.GetPane(wxT("Transactions")).Show(true); - cbRate->SetValue(rateToCboString(xactRate)); - if (xactRate > 0 && xactTimer) - xactTimer->Start(xactRate * 1000L); - } - else - { - manager.GetPane(wxT("Transactions")).Show(false); - if (xactTimer) - xactTimer->Stop(); - } + if (viewMenu->IsEnabled(MNU_XACTPAGE) && viewMenu->IsChecked(MNU_XACTPAGE)) + { + manager.GetPane(wxT("Transactions")).Show(true); + cbRate->SetValue(rateToCboString(xactRate)); + if (xactRate > 0 && xactTimer) + xactTimer->Start(xactRate * 1000L); + } + else + { + manager.GetPane(wxT("Transactions")).Show(false); + if (xactTimer) + xactTimer->Stop(); + } - // Tell the manager to "commit" all the changes just made - manager.Update(); + // Tell the manager to "commit" all the changes just made + manager.Update(); } -void frmStatus::OnToggleLogPane(wxCommandEvent& event) +void frmStatus::OnToggleLogPane(wxCommandEvent &event) { - if (viewMenu->IsEnabled(MNU_LOGPAGE) && viewMenu->IsChecked(MNU_LOGPAGE)) - { - manager.GetPane(wxT("Logfile")).Show(true); - cbRate->SetValue(rateToCboString(logRate)); - if (logRate > 0 && logTimer) - logTimer->Start(logRate * 1000L); - wxTimerEvent e; - OnRefreshLogTimer(e); - } - else - { - manager.GetPane(wxT("Logfile")).Show(false); - if (logThread) logThread->BreakRead(); - if (logTimer) - logTimer->Stop(); - } + if (viewMenu->IsEnabled(MNU_LOGPAGE) && viewMenu->IsChecked(MNU_LOGPAGE)) + { + manager.GetPane(wxT("Logfile")).Show(true); + cbRate->SetValue(rateToCboString(logRate)); + if (logRate > 0 && logTimer) + logTimer->Start(logRate * 1000L); + wxTimerEvent e; + OnRefreshLogTimer(e); + } + else + { + manager.GetPane(wxT("Logfile")).Show(false); + if (logThread) logThread->BreakRead(); + if (logTimer) + logTimer->Stop(); + } - // Tell the manager to "commit" all the changes just made - manager.Update(); + // Tell the manager to "commit" all the changes just made + manager.Update(); } void frmStatus::OnToggleWaitEnable(wxCommandEvent& event) { } -void frmStatus::OnToggleQuerystatePane(wxCommandEvent& event) +void frmStatus::OnToggleQuerystatePane(wxCommandEvent &event) { - if (viewMenu->IsEnabled(MNU_QUERYSTATEPAGE) && viewMenu->IsChecked(MNU_QUERYSTATEPAGE)) - { - manager.GetPane(wxT("Querystate")).Show(true); - cbRate->SetValue(rateToCboString(querystateRate)); - if (querystateRate > 0 && querystateTimer) - querystateTimer->Start(querystateRate * 1000L); - } - else - { - manager.GetPane(wxT("Querystate")).Show(false); - if (querystateTimer) - querystateTimer->Stop(); - } + if (viewMenu->IsEnabled(MNU_QUERYSTATEPAGE) && viewMenu->IsChecked(MNU_QUERYSTATEPAGE)) + { + manager.GetPane(wxT("Querystate")).Show(true); + cbRate->SetValue(rateToCboString(querystateRate)); + if (querystateRate > 0 && querystateTimer) + querystateTimer->Start(querystateRate * 1000L); + } + else + { + manager.GetPane(wxT("Querystate")).Show(false); + if (querystateTimer) + querystateTimer->Stop(); + } - // Tell the manager to "commit" all the changes just made - manager.Update(); + // Tell the manager to "commit" all the changes just made + manager.Update(); } -void frmStatus::OnToggleToolBar(wxCommandEvent& event) +void frmStatus::OnToggleToolBar(wxCommandEvent &event) { - if (viewMenu->IsChecked(MNU_TOOLBAR)) - { - manager.GetPane(wxT("toolBar")).Show(true); - } - else - { - manager.GetPane(wxT("toolBar")).Show(false); - } + if (viewMenu->IsChecked(MNU_TOOLBAR)) + { + manager.GetPane(wxT("toolBar")).Show(true); + } + else + { + manager.GetPane(wxT("toolBar")).Show(false); + } - // Tell the manager to "commit" all the changes just made - manager.Update(); + // Tell the manager to "commit" all the changes just made + manager.Update(); } -void frmStatus::OnDefaultView(wxCommandEvent& event) +void frmStatus::OnDefaultView(wxCommandEvent &event) { - manager.LoadPerspective(FRMSTATUS_DEFAULT_PERSPECTIVE, true); + manager.LoadPerspective(FRMSTATUS_DEFAULT_PERSPECTIVE, true); - // Reset the captions for the current language - manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); - manager.GetPane(wxT("Activity")).Caption(_("Activity")); - manager.GetPane(wxT("Locks")).Caption(_("Locks")); - manager.GetPane(wxT("Transactions")).Caption(_("Prepared Transactions")); - manager.GetPane(wxT("Logfile")).Caption(_("Logfile")); - manager.GetPane(wxT("Querystate")).Caption(_("Query State")); + // Reset the captions for the current language + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + manager.GetPane(wxT("Activity")).Caption(_("Activity")); + manager.GetPane(wxT("Locks")).Caption(_("Locks")); + manager.GetPane(wxT("Transactions")).Caption(_("Prepared Transactions")); + manager.GetPane(wxT("Logfile")).Caption(_("Logfile")); + manager.GetPane(wxT("Querystate")).Caption(_("Query State")); - // tell the manager to "commit" all the changes just made - manager.Update(); + // tell the manager to "commit" all the changes just made + manager.Update(); - // Sync the View menu options - viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); - viewMenu->Check(MNU_STATUSPAGE, manager.GetPane(wxT("Activity")).IsShown()); - viewMenu->Check(MNU_LOCKPAGE, manager.GetPane(wxT("Locks")).IsShown()); - viewMenu->Check(MNU_XACTPAGE, manager.GetPane(wxT("Transactions")).IsShown()); - viewMenu->Check(MNU_LOGPAGE, manager.GetPane(wxT("Logfile")).IsShown()); - viewMenu->Check(MNU_QUERYSTATEPAGE, manager.GetPane(wxT("Querystate")).IsShown()); + // Sync the View menu options + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); + viewMenu->Check(MNU_STATUSPAGE, manager.GetPane(wxT("Activity")).IsShown()); + viewMenu->Check(MNU_LOCKPAGE, manager.GetPane(wxT("Locks")).IsShown()); + viewMenu->Check(MNU_XACTPAGE, manager.GetPane(wxT("Transactions")).IsShown()); + viewMenu->Check(MNU_LOGPAGE, manager.GetPane(wxT("Logfile")).IsShown()); + viewMenu->Check(MNU_QUERYSTATEPAGE, manager.GetPane(wxT("Querystate")).IsShown()); } -void frmStatus::OnHighlightStatus(wxCommandEvent& event) +void frmStatus::OnHighlightStatus(wxCommandEvent &event) { - wxTimerEvent evt; + wxTimerEvent evt; - OnRefreshStatusTimer(evt); + OnRefreshStatusTimer(evt); } -void frmStatus::OnEmptyAction(wxCommandEvent& event) +void frmStatus::OnEmptyAction(wxCommandEvent &event) { } -void frmStatus::OnHelp(wxCommandEvent& ev) +void frmStatus::OnHelp(wxCommandEvent &ev) { - DisplayHelp(wxT("status"), HELP_PGADMIN); + DisplayHelp(wxT("status"), HELP_PGADMIN); } -void frmStatus::OnContents(wxCommandEvent& ev) +void frmStatus::OnContents(wxCommandEvent &ev) { - DisplayHelp(wxT("index"), HELP_PGADMIN); + DisplayHelp(wxT("index"), HELP_PGADMIN); } -void frmStatus::OnRateChange(wxCommandEvent& event) +void frmStatus::OnRateChange(wxCommandEvent &event) { - wxTimer* timer; - int rate; + wxTimer *timer; + int rate; - switch (currentPane) - { - case PANE_STATUS: - timer = statusTimer; - rate = cboToRate(); - statusRate = rate; - break; - case PANE_LOCKS: - timer = locksTimer; - rate = cboToRate(); - locksRate = rate; - break; - case PANE_XACT: - timer = xactTimer; - rate = cboToRate(); - xactRate = rate; - break; - case PANE_LOG: - timer = logTimer; - rate = cboToRate(); - logRate = rate; - break; - case PANE_QUERYSTATE: - timer = querystateTimer; - rate = cboToRate(); - querystateRate = rate; - break; - default: - // This shouldn't happen. - // If it does, it's no big deal, we just need to get out. - return; - break; - } + switch(currentPane) + { + case PANE_STATUS: + timer = statusTimer; + rate = cboToRate(); + statusRate = rate; + break; + case PANE_LOCKS: + timer = locksTimer; + rate = cboToRate(); + locksRate = rate; + break; + case PANE_XACT: + timer = xactTimer; + rate = cboToRate(); + xactRate = rate; + break; + case PANE_LOG: + timer = logTimer; + rate = cboToRate(); + logRate = rate; + break; + case PANE_QUERYSTATE: + timer = querystateTimer; + rate = cboToRate(); + querystateRate = rate; + break; + default: + // This shouldn't happen. + // If it does, it's no big deal, we just need to get out. + return; + break; + } - if (timer) - { - timer->Stop(); - if (rate > 0) - timer->Start(rate * 1000L); - } - OnRefresh(event); + if (timer) + { + timer->Stop(); + if (rate > 0) + timer->Start(rate * 1000L); + } + OnRefresh(event); } -void frmStatus::OnRefreshUITimer(wxTimerEvent& event) +void frmStatus::OnRefreshUITimer(wxTimerEvent &event) { - wxListEvent evt; - refreshUITimer->Stop(); - if (frm_exit && !logisread) Destroy(); - for (unsigned int i = 0; i < manager.GetAllPanes().GetCount(); i++) - { - wxAuiPaneInfo& pane = manager.GetAllPanes()[i]; + wxListEvent evt; + refreshUITimer->Stop(); + if (frm_exit && !logisread) Destroy(); + for (unsigned int i = 0; i < manager.GetAllPanes().GetCount(); i++) + { + wxAuiPaneInfo &pane = manager.GetAllPanes()[i]; - if (pane.HasFlag(wxAuiPaneInfo::optionActive)) - { - if (pane.name == wxT("Activity") && currentPane != PANE_STATUS) - { - OnSelStatusItem(evt); - } - if (pane.name == wxT("Locks") && currentPane != PANE_LOCKS) - { - OnSelLockItem(evt); - } - if (pane.name == wxT("Transactions") && currentPane != PANE_XACT) - { - OnSelXactItem(evt); - } - if (pane.name == wxT("Logfile") && currentPane != PANE_LOG) - { - OnSelLogItem(evt); - } - if (pane.name == wxT("Querystate") && currentPane != PANE_QUERYSTATE) - { - OnSelQuerystateItem(evt); - } - } - } + if (pane.HasFlag(wxAuiPaneInfo::optionActive)) + { + if (pane.name == wxT("Activity") && currentPane != PANE_STATUS) + { + OnSelStatusItem(evt); + } + if (pane.name == wxT("Locks") && currentPane != PANE_LOCKS) + { + OnSelLockItem(evt); + } + if (pane.name == wxT("Transactions") && currentPane != PANE_XACT) + { + OnSelXactItem(evt); + } + if (pane.name == wxT("Logfile") && currentPane != PANE_LOG) + { + OnSelLogItem(evt); + } + if (pane.name == wxT("Querystate") && currentPane != PANE_QUERYSTATE) + { + OnSelQuerystateItem(evt); + } + } + } - refreshUITimer->Start(250); + refreshUITimer->Start(250); } -void frmStatus::OnRefreshStatusTimer(wxTimerEvent& event) +void frmStatus::OnRefreshStatusTimer(wxTimerEvent &event) { - long pid = 0; - wxString pidcol = connection->BackendMinimumVersion(9, 2) ? wxT("p.pid") : wxT("p.procpid"); - wxString querycol = connection->BackendMinimumVersion(9, 2) ? wxT("query") : wxT("current_query"); + long pid = 0; + wxString pidcol = connection->BackendMinimumVersion(9, 2) ? wxT("p.pid") : wxT("p.procpid"); + wxString querycol = connection->BackendMinimumVersion(9, 2) ? wxT("query") : wxT("current_query"); - if (!viewMenu->IsChecked(MNU_STATUSPAGE)) - return; + if (! viewMenu->IsChecked(MNU_STATUSPAGE)) + return; - checkConnection(); - if (!connection) - { - statusTimer->Stop(); - locksTimer->Stop(); - if (xactTimer) - xactTimer->Stop(); - if (logTimer) - logTimer->Stop(); - if (querystateTimer) - querystateTimer->Stop(); - return; - } + checkConnection(); + if (!connection) + { + statusTimer->Stop(); + locksTimer->Stop(); + if (xactTimer) + xactTimer->Stop(); + if (logTimer) + logTimer->Stop(); + if (querystateTimer) + querystateTimer->Stop(); + return; + } - wxCriticalSectionLocker lock(gs_critsect); + wxCriticalSectionLocker lock(gs_critsect); - long row = 0; - wxString q = wxT("SELECT "); - wait_enable = waitMenu->IsChecked(MNU_WAITENABLE); - // PID - q += pidcol + wxT(" AS pid, "); + long row = 0; + wxString q = wxT("SELECT "); + wait_enable = waitMenu->IsChecked(MNU_WAITENABLE); + // PID + q += pidcol + wxT(" AS pid, "); - // Application name (when available) - if (connection->BackendMinimumVersion(8, 5)) - q += wxT("application_name, "); - if (connection->BackendMinimumVersion(14, 0)) - q += wxT("query_id, "); + // Application name (when available) + if (connection->BackendMinimumVersion(8, 5)) + q += wxT("application_name, "); + if (connection->BackendMinimumVersion(14, 0)) + q += wxT("query_id, "); + + // Database, and user name + q += wxT("p.datname, usename,\n"); - // Database, and user name - q += wxT("p.datname, usename,\n"); + // Client connection method + if (connection->BackendMinimumVersion(8, 1)) + { + q += wxT("CASE WHEN client_port=-1 THEN 'local pipe' "); + if (connection->BackendMinimumVersion(9, 1)) + q += wxT("WHEN length(client_hostname)>0 THEN client_hostname||':'||client_port "); + q += wxT("ELSE textin(inet_out(client_addr))||':'||client_port END AS client,\n"); + } - // Client connection method - if (connection->BackendMinimumVersion(8, 1)) - { - q += wxT("CASE WHEN client_port=-1 THEN 'local pipe' "); - if (connection->BackendMinimumVersion(9, 1)) - q += wxT("WHEN length(client_hostname)>0 THEN client_hostname||':'||client_port "); - q += wxT("ELSE textin(inet_out(client_addr))||':'||client_port END AS client,\n"); - } + // Backend start timestamp + if (connection->BackendMinimumVersion(8, 1)) + q += wxT("date_trunc('second', backend_start) AS backend_start, "); - // Backend start timestamp - if (connection->BackendMinimumVersion(8, 1)) - q += wxT("date_trunc('second', backend_start) AS backend_start, "); + // Query start timestamp (when available) + if (connection->BackendMinimumVersion(9, 2)) + { + q += wxT("CASE WHEN state='active' THEN date_trunc('second', query_start)::text ELSE '' END "); + } + else if (connection->BackendMinimumVersion(7, 4)) + { + q += wxT("CASE WHEN ") + querycol + wxT("='' OR ") + querycol + wxT("='' THEN '' ") + wxT(" ELSE date_trunc('second', query_start)::text END "); + } + else + { + q += wxT("'' "); + } + q += wxT("AS query_start,\n"); - // Query start timestamp (when available) - if (connection->BackendMinimumVersion(9, 2)) - { - q += wxT("CASE WHEN state='active' THEN date_trunc('second', query_start)::text ELSE '' END "); - } - else if (connection->BackendMinimumVersion(7, 4)) - { - q += wxT("CASE WHEN ") + querycol + wxT("='' OR ") + querycol + wxT("='' THEN '' ") - wxT(" ELSE date_trunc('second', query_start)::text END "); - } - else - { - q += wxT("'' "); - } - q += wxT("AS query_start,\n"); + // Transaction start timestamp + if (connection->BackendMinimumVersion(8, 3)) + q += wxT("xact_start AS xact_start_full,date_trunc('second', xact_start) AS xact_start, "); - // Transaction start timestamp - if (connection->BackendMinimumVersion(8, 3)) - q += wxT("xact_start AS xact_start_full,date_trunc('second', xact_start) AS xact_start, "); + // State + if (connection->BackendMinimumVersion(9, 2)) + q += wxT("state, date_trunc('second', state_change) AS state_change, "); - // State - if (connection->BackendMinimumVersion(9, 2)) - q += wxT("state, date_trunc('second', state_change) AS state_change, "); + // Xmin and XID + if (connection->BackendMinimumVersion(9, 4)) + q += wxT("backend_xid::text, backend_xmin::text, "); - // Xmin and XID - if (connection->BackendMinimumVersion(9, 4)) - q += wxT("backend_xid::text, backend_xmin::text, "); + // Blocked by... + q += wxT("(SELECT min(l1.pid) FROM pg_locks l1 WHERE GRANTED AND (") + wxT("relation IN (SELECT relation FROM pg_locks l2 WHERE l2.pid=") + pidcol + wxT(" AND NOT granted)") + wxT(" OR ") + wxT("transactionid IN (SELECT transactionid FROM pg_locks l3 WHERE l3.pid=") + pidcol + wxT(" AND NOT granted)") + wxT(")) AS blockedby,\n"); - // Blocked by... - q += wxT("(SELECT min(l1.pid) FROM pg_locks l1 WHERE GRANTED AND (") - wxT("relation IN (SELECT relation FROM pg_locks l2 WHERE l2.pid=") + pidcol + wxT(" AND NOT granted)") - wxT(" OR ") - wxT("transactionid IN (SELECT transactionid FROM pg_locks l3 WHERE l3.pid=") + pidcol + wxT(" AND NOT granted)") - wxT(")) AS blockedby,\n"); + // Query + q += querycol + wxT(" AS query,\n"); - // Query - q += querycol + wxT(" AS query,\n"); + // Slow query? + if (connection->BackendMinimumVersion(9, 2)) + { + q += wxT("CASE WHEN query_start IS NULL OR state<>'active' THEN false ELSE query_start < now() - '10 seconds'::interval END "); + } + else if (connection->BackendMinimumVersion(7, 4)) + { + q += wxT("CASE WHEN query_start IS NULL OR ") + querycol + wxT(" LIKE '%' THEN false ELSE query_start < now() - '10 seconds'::interval END "); + } + else + { + q += wxT("false"); + } + q += wxT("AS slowquery\n"); + wxString progress13="(select format('%s %s',phase,pr) progress_info,pid from (\ + select case phase\ + when 'scanning heap' then\ + Round(100 * heap_blks_scanned / greatest(heap_blks_total, 1), 1) || '%'\ + else\ + Round(100 * heap_blks_vacuumed / greatest(heap_blks_total, 1), 1) || '%'\ + end pr\ + , phase, pid from pg_stat_progress_vacuum\ + union all\ + select \ + Round(100 * backup_streamed / greatest(backup_total, backup_streamed,1)) || '% (' || pg_size_pretty(backup_streamed) || ')'\ + pr\ + , phase, pid from pg_stat_progress_basebackup\ + union all\ + select case phase\ + when 'writing new heap' then\ + Round(100 * heap_tuples_written / greatest(heap_tuples_scanned, 1), 1) || '%'\ + else\ + pg_size_pretty(heap_tuples_scanned) || ' rows'\ + end pr\ + , phase, pid from pg_stat_progress_cluster\ + union all\ + select\ + round(100 * sample_blks_scanned / greatest(sample_blks_total, 1), 2) || '%' pr\ + , phase, pid from pg_stat_progress_analyze\ + union all\ + select Round(100 * blocks_done / greatest(blocks_total, 1), 1) || '%' pr\ + , phase, pid from pg_stat_progress_create_index\ + ) v) v\ + "; + bool iswalsend = false; + if (connection->BackendMinimumVersion(10, 0)) + { + if (connection->BackendMinimumVersion(13, 0)) + { + q += wxT(",backend_type,wait_event_type,wait_event,v.progress_info,case when backend_type='autovacuum launcher' then (select min(xmin::text::bigint) from pg_replication_slots) end av_replica\n"); + iswalsend = true; + if (wait_sample && wait_enable) { + q += ",transaction_timestamp() tt,hs.wait_sample,hs.maxts"; + } + } + else + q += wxT(",backend_type,wait_event_type,wait_event,v.heap_blks_total,v.heap_blks_vacuumed,v.heap_blks_scanned,v.phase\n"); - // Slow query? - if (connection->BackendMinimumVersion(9, 2)) - { - q += wxT("CASE WHEN query_start IS NULL OR state<>'active' THEN false ELSE query_start < now() - '10 seconds'::interval END "); - } - else if (connection->BackendMinimumVersion(7, 4)) - { - q += wxT("CASE WHEN query_start IS NULL OR ") + querycol + wxT(" LIKE '%' THEN false ELSE query_start < now() - '10 seconds'::interval END "); - } - else - { - q += wxT("false"); - } - q += wxT("AS slowquery\n"); - wxString progress13 = "(select format('%s %s',phase,pr) progress_info,pid from (\ - select case phase\ - when 'scanning heap' then\ - Round(100 * heap_blks_scanned / greatest(heap_blks_total, 1), 1) || '%'\ - else\ - Round(100 * heap_blks_vacuumed / greatest(heap_blks_total, 1), 1) || '%'\ - end pr\ - , phase, pid from pg_stat_progress_vacuum\ - union all\ - select \ - Round(100 * backup_streamed / greatest(backup_total, backup_streamed,1)) || '% (' || pg_size_pretty(backup_streamed) || ')'\ - pr\ - , phase, pid from pg_stat_progress_basebackup\ - union all\ - select case phase\ - when 'writing new heap' then\ - Round(100 * heap_tuples_written / greatest(heap_tuples_scanned, 1), 1) || '%'\ - else\ - pg_size_pretty(heap_tuples_scanned) || ' rows'\ - end pr\ - , phase, pid from pg_stat_progress_cluster\ - union all\ - select\ - round(100 * sample_blks_scanned / greatest(sample_blks_total, 1), 2) || '%' pr\ - , phase, pid from pg_stat_progress_analyze\ - union all\ - select Round(100 * blocks_done / greatest(blocks_total, 1), 1) || '%' pr\ - , phase, pid from pg_stat_progress_create_index\ - ) v) v\ - "; - bool iswalsend = false; - if (connection->BackendMinimumVersion(10, 0)) - { - if (connection->BackendMinimumVersion(13, 0)) - { - q += wxT(",backend_type,wait_event_type,wait_event,v.progress_info,case when backend_type='autovacuum launcher' then (select min(xmin::text::bigint) from pg_replication_slots) end av_replica\n"); - iswalsend = true; - if (wait_sample && wait_enable) { - q += ",transaction_timestamp() tt,hs.wait_sample,hs.maxts"; - } - } - else - q += wxT(",backend_type,wait_event_type,wait_event,v.heap_blks_total,v.heap_blks_vacuumed,v.heap_blks_scanned,v.phase\n"); - - if (!track_commit_timestamp) - q += wxT(",coalesce(sl.xmin,sl.catalog_xmin)::text xmin_slot,':'||slot_name||'['||sl.slot_type||']' slotinfo,'LagSent:'||pg_size_pretty(pg_wal_lsn_diff(pg_last_wal_receive_lsn(),coalesce(confirmed_flush_lsn,restart_lsn)))||' LagXmin: -1'||' s' xminlag,-1 xminslotdelta\n"); - else if (isrecovery) - q += wxT(",coalesce(sl.xmin,sl.catalog_xmin)::text xmin_slot,':'||slot_name||'['||sl.slot_type||']' slotinfo,'LagSent:'||pg_size_pretty(pg_wal_lsn_diff(pg_last_wal_receive_lsn(),coalesce(confirmed_flush_lsn,restart_lsn)))||' LagXmin: '||coalesce(extract(epoch from (pg_last_committed_xact()).timestamp - pg_xact_commit_timestamp(xmin))::int,0)||' s' xminlag,coalesce(extract(epoch from (pg_last_committed_xact()).timestamp - pg_xact_commit_timestamp(xmin))::int,0) xminslotdelta\n"); - else - q += wxT(",coalesce(sl.xmin,sl.catalog_xmin)::text xmin_slot,':'||slot_name||'['||sl.slot_type||']' slotinfo,'LagSent:'||pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(),coalesce(confirmed_flush_lsn,restart_lsn)))||' LagXmin: '||coalesce(extract(epoch from (pg_last_committed_xact()).timestamp - pg_xact_commit_timestamp(xmin))::int,0)||' s' xminlag,coalesce(extract(epoch from (pg_last_committed_xact()).timestamp - pg_xact_commit_timestamp(xmin))::int,0) xminslotdelta\n"); - if (connection->BackendMinimumVersion(13, 0)) - q += "FROM pg_stat_activity p LEFT JOIN " + progress13 + " ON p.pid=v.pid\n"; - else - q += wxT("FROM pg_stat_activity p LEFT JOIN pg_stat_progress_vacuum v ON p.pid=v.pid\n"); - q += wxT("LEFT JOIN pg_replication_slots sl ON p.pid=sl.active_pid\n"); - if (wait_sample && wait_enable) - { - q += " left join ( \ - select pid, string_agg(format('%s:%s', coalesce(event_type,'CPU') || ':' || coalesce(event,'CPU')||':'||queryid, cnt), ';') wait_sample, max(maxts) maxts from( \ - select pid,queryid, event_type, event, max(ts) maxts, count(*) cnt from pg_wait_sampling_history h \ - where h.event not in('ArchiverMain', 'WalWriterMain', 'CheckpointerMain', 'Extension', 'LogicalLauncherMain', 'CfsGcEnable', 'WalSenderMain' \ - , 'AutoVacuumMain', '-ClientRead', 'CheckpointWriteDelay', 'BgWriterMain', 'BgWriterHibernate') \ + if (!track_commit_timestamp) + q += wxT(",coalesce(sl.xmin,sl.catalog_xmin)::text xmin_slot,':'||slot_name||'['||sl.slot_type||']' slotinfo,'LagSent:'||pg_size_pretty(pg_wal_lsn_diff(pg_last_wal_receive_lsn(),coalesce(confirmed_flush_lsn,restart_lsn)))||' LagXmin: -1'||' s' xminlag,-1 xminslotdelta\n"); + else if (isrecovery) + q += wxT(",coalesce(sl.xmin,sl.catalog_xmin)::text xmin_slot,':'||slot_name||'['||sl.slot_type||']' slotinfo,'LagSent:'||pg_size_pretty(pg_wal_lsn_diff(pg_last_wal_receive_lsn(),coalesce(confirmed_flush_lsn,restart_lsn)))||' LagXmin: '||coalesce(extract(epoch from (pg_last_committed_xact()).timestamp - pg_xact_commit_timestamp(xmin))::int,0)||' s' xminlag,coalesce(extract(epoch from (pg_last_committed_xact()).timestamp - pg_xact_commit_timestamp(xmin))::int,0) xminslotdelta\n"); + else + q += wxT(",coalesce(sl.xmin,sl.catalog_xmin)::text xmin_slot,':'||slot_name||'['||sl.slot_type||']' slotinfo,'LagSent:'||pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(),coalesce(confirmed_flush_lsn,restart_lsn)))||' LagXmin: '||coalesce(extract(epoch from (pg_last_committed_xact()).timestamp - pg_xact_commit_timestamp(xmin))::int,0)||' s' xminlag,coalesce(extract(epoch from (pg_last_committed_xact()).timestamp - pg_xact_commit_timestamp(xmin))::int,0) xminslotdelta\n"); + if (connection->BackendMinimumVersion(13, 0)) + q += "FROM pg_stat_activity p LEFT JOIN "+progress13+" ON p.pid=v.pid\n"; + else + q += wxT("FROM pg_stat_activity p LEFT JOIN pg_stat_progress_vacuum v ON p.pid=v.pid\n"); + q += wxT("LEFT JOIN pg_replication_slots sl ON p.pid=sl.active_pid\n"); + if (wait_sample && wait_enable) + { + q += " left join ( \ + select pid, string_agg(format('%s:%s', coalesce(event_type,'CPU') || ':' || coalesce(event,'CPU')||':'||queryid, cnt), ';') wait_sample, max(maxts) maxts from( \ + select pid,queryid, event_type, event, max(ts) maxts, count(*) cnt from pg_wait_sampling_history h \ + where h.event not in('ArchiverMain', 'WalWriterMain', 'CheckpointerMain', 'Extension', 'LogicalLauncherMain', 'CfsGcEnable', 'WalSenderMain' \ + , 'AutoVacuumMain', '-ClientRead', 'CheckpointWriteDelay', 'BgWriterMain', 'BgWriterHibernate') \ or h.event is null\ - "; + "; - if (!first_tt.IsEmpty()) q += "and h.ts > '" + first_tt + "'"; + if (!first_tt.IsEmpty()) q += "and h.ts > '"+first_tt+"'"; - q += "group by pid, event_type, event,queryid \ - ) l group by pid) hs on p.pid = hs.pid\n"; - } - //backend_type - } - else - { - q += wxT("FROM pg_stat_activity p "); - } + q+="group by pid, event_type, event,queryid \ + ) l group by pid) hs on p.pid = hs.pid\n"; + } + + //backend_type + } else + { + q += wxT("FROM pg_stat_activity p "); + } - // And the rest of the query... + // And the rest of the query... + + q += wxT(" ORDER BY ") + NumToStr((long)statusSortColumn) + wxT(" ") + statusSortOrder; + wxString msgerror; + pgSet *dataSet1 = connection->ExecuteSet(q,false); + if (dataSet1) + { + msgerror = connection->GetLastError(); + statusBar->SetStatusText(_("Refreshing status list.")); + statusList->Freeze(); - q += wxT(" ORDER BY ") + NumToStr((long)statusSortColumn) + wxT(" ") + statusSortOrder; - wxString msgerror; - pgSet* dataSet1 = connection->ExecuteSet(q, false); - if (dataSet1) - { - msgerror = connection->GetLastError(); - statusBar->SetStatusText(_("Refreshing status list.")); - statusList->Freeze(); + // Clear the queries array content + queries.Clear(); + wxString blocked=wxT(""); + + wxArrayLong pids; + wxDateTime tt; + while (!dataSet1->Eof()) + { + pid = dataSet1->GetLong(wxT("pid")); + wxString slinfo=wxEmptyString; + wxString backend_xid; + wxDateTime start_transaction; + if (iswalsend) { + slinfo = dataSet1->GetVal(wxT("slotinfo")); + } + if (!tt.IsValid()&&wait_sample && wait_enable) { + tt = dataSet1->GetDateTime("tt"); + WS.BeginSeriosSample(tt.GetValue().GetValue()); + first_tt = dataSet1->GetVal("tt"); - // Clear the queries array content - queries.Clear(); - wxString blocked = wxT(""); + } + // Update the UI + if (pid != backend_pid) + { - wxArrayLong pids; - wxDateTime tt; - while (!dataSet1->Eof()) - { - pid = dataSet1->GetLong(wxT("pid")); - wxString slinfo = wxEmptyString; - wxString backend_xid; - wxDateTime start_transaction; - if (iswalsend) { - slinfo = dataSet1->GetVal(wxT("slotinfo")); - } - if (!tt.IsValid() && wait_sample && wait_enable) { - tt = dataSet1->GetDateTime("tt"); - WS.BeginSeriosSample(tt.GetValue().GetValue()); - first_tt = dataSet1->GetVal("tt"); + if (row >= statusList->GetItemCount()) + { + statusList->InsertItem(row, NumToStr(pid), -1); + row = statusList->GetItemCount() - 1; + } + else + { + statusList->SetItem(row, 0, NumToStr(pid),-1); + } - } - // Update the UI - if (pid != backend_pid) - { + wxString qry = dataSet1->GetVal(wxT("query")); + wxString app_name = dataSet1->GetVal(wxT("application_name")); + wxString backend_type; + if (connection->BackendMinimumVersion(13, 0)) { + backend_type = dataSet1->GetVal(wxT("backend_type")); + if (app_name.IsEmpty() && backend_type != "client backend") app_name = backend_type; + } + if (connection->BackendMinimumVersion(9, 6)) + { + if (connection->BackendMinimumVersion(13, 0)) { + wxString progress_info = dataSet1->GetVal(wxT("progress_info")); + if (!progress_info.IsEmpty()) app_name = progress_info; + } else + { + wxString heap_blks_total = dataSet1->GetVal(wxT("heap_blks_total")); + if (!heap_blks_total.IsEmpty()) { + wxString heap_blks_vacuumed = dataSet1->GetVal(wxT("heap_blks_vacuumed")); + wxString heap_blks_scanned = dataSet1->GetVal(wxT("heap_blks_scanned")); + wxString phase = dataSet1->GetVal(wxT("phase")); + double total; + double vac = 0; + double proc; + heap_blks_vacuumed.ToDouble(&vac); + if (!phase.CmpNoCase(wxT("scanning heap"))) { + heap_blks_scanned.ToDouble(&vac); + } + heap_blks_total.ToDouble(&total); + proc = vac * 100 / total; + wxString str; + str.Printf(wxT("%s %5.2f%%"), phase, proc); + app_name = str; + } + } + if (!slinfo.IsEmpty()) app_name += slinfo; + } + int colpos = 1; + if (connection->BackendMinimumVersion(8, 5)) + statusList->SetItem(row, colpos++, app_name); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("datname"))); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("usename"))); - if (row >= statusList->GetItemCount()) - { - statusList->InsertItem(row, NumToStr(pid), -1); - row = statusList->GetItemCount() - 1; - } - else - { - statusList->SetItem(row, 0, NumToStr(pid), -1); - } + if (connection->BackendMinimumVersion(8, 1)) + { + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("client"))); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("backend_start"))); + } + if (connection->BackendMinimumVersion(7, 4)) + { + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("query_start"))); + } - wxString qry = dataSet1->GetVal(wxT("query")); - wxString app_name = dataSet1->GetVal(wxT("application_name")); - wxString backend_type; - if (connection->BackendMinimumVersion(13, 0)) { - backend_type = dataSet1->GetVal(wxT("backend_type")); - if (app_name.IsEmpty() && backend_type != "client backend") app_name = backend_type; - } - if (connection->BackendMinimumVersion(9, 6)) - { - if (connection->BackendMinimumVersion(13, 0)) { - wxString progress_info = dataSet1->GetVal(wxT("progress_info")); - if (!progress_info.IsEmpty()) app_name = progress_info; - } - else - { - wxString heap_blks_total = dataSet1->GetVal(wxT("heap_blks_total")); - if (!heap_blks_total.IsEmpty()) { - wxString heap_blks_vacuumed = dataSet1->GetVal(wxT("heap_blks_vacuumed")); - wxString heap_blks_scanned = dataSet1->GetVal(wxT("heap_blks_scanned")); - wxString phase = dataSet1->GetVal(wxT("phase")); - double total; - double vac = 0; - double proc; - heap_blks_vacuumed.ToDouble(&vac); - if (!phase.CmpNoCase(wxT("scanning heap"))) { - heap_blks_scanned.ToDouble(&vac); - } - heap_blks_total.ToDouble(&total); - proc = vac * 100 / total; - wxString str; - str.Printf(wxT("%s %5.2f%%"), phase, proc); - app_name = str; - } - } - if (!slinfo.IsEmpty()) app_name += slinfo; - } - int colpos = 1; - if (connection->BackendMinimumVersion(8, 5)) - statusList->SetItem(row, colpos++, app_name); - statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("datname"))); - statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("usename"))); + if (connection->BackendMinimumVersion(8, 3)) { + start_transaction= dataSet1->GetDateTime("xact_start_full"); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("xact_start"))); + } - if (connection->BackendMinimumVersion(8, 1)) - { - statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("client"))); - statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("backend_start"))); - } - if (connection->BackendMinimumVersion(7, 4)) - { - statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("query_start"))); - } + if (connection->BackendMinimumVersion(9, 2)) + { + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("state"))); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("state_change"))); + } - if (connection->BackendMinimumVersion(8, 3)) { - start_transaction = dataSet1->GetDateTime("xact_start_full"); - statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("xact_start"))); - } + if (connection->BackendMinimumVersion(9, 4)) + { + backend_xid= dataSet1->GetVal(wxT("backend_xid")); + statusList->SetItem(row, colpos++, backend_xid); + if (!slinfo.IsEmpty()) statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("xmin_slot"))); + else + { + wxString av_replica; + if (iswalsend) av_replica= dataSet1->GetVal(wxT("av_replica")); + if (av_replica.IsEmpty()) + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("backend_xmin"))); + else + statusList->SetItem(row, colpos++, av_replica); + } + } + if (connection->BackendMinimumVersion(9, 6)) + { + wait_event_type_col=colpos; + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("wait_event_type"))); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("wait_event"))); + } + wxString blockedby = dataSet1->GetVal(wxT("blockedby")); + if (wait_sample && wait_enable) { + bool isClientReadTransaction = false; + //if ( spt.count>1 && ll!=0) isClientReadTransaction = true; + if (start_transaction.IsValid() + && start_transaction < tt + && !backend_xid.IsEmpty() + )isClientReadTransaction = true; - if (connection->BackendMinimumVersion(9, 2)) - { - statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("state"))); - statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("state_change"))); - } + WS.AddSample(pid, isClientReadTransaction, backend_type, dataSet1->GetVal("wait_sample")); + //wxULongLong qid = dataSet1->GetLongLong("query_id"); + //WS.AddQuery(qid.GetValue(), qry); + } + statusList->SetItem(row, colpos++, blockedby); + if (!slinfo.IsEmpty()) { + statusList->SetItem(row, colpos, dataSet1->GetVal(wxT("xminlag"))); + } + else + statusList->SetItem(row, colpos, qry); - if (connection->BackendMinimumVersion(9, 4)) - { - backend_xid = dataSet1->GetVal(wxT("backend_xid")); - statusList->SetItem(row, colpos++, backend_xid); - if (!slinfo.IsEmpty()) statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("xmin_slot"))); - else - { - wxString av_replica; - if (iswalsend) av_replica = dataSet1->GetVal(wxT("av_replica")); - if (av_replica.IsEmpty()) - statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("backend_xmin"))); - else - statusList->SetItem(row, colpos++, av_replica); - } - } - if (connection->BackendMinimumVersion(9, 6)) - { - wait_event_type_col = colpos; - statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("wait_event_type"))); - statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("wait_event"))); - } - wxString blockedby = dataSet1->GetVal(wxT("blockedby")); - if (wait_sample && wait_enable) { - bool isClientReadTransaction = false; - //if ( spt.count>1 && ll!=0) isClientReadTransaction = true; - if (start_transaction.IsValid() - && start_transaction < tt - && !backend_xid.IsEmpty() - )isClientReadTransaction = true; + // Colorize the new line + if (viewMenu->IsChecked(MNU_HIGHLIGHTSTATUS)) + { + statusList->SetItemBackgroundColour(row, + wxColour(settings->GetActiveProcessColour())); + if (qry == wxT("") || qry == wxT(" in transaction0")) + statusList->SetItemBackgroundColour(row, + wxColour(settings->GetIdleProcessColour())); + if (connection->BackendMinimumVersion(9, 2)) + { + if (dataSet1->GetVal(wxT("state")) != wxT("active")) + statusList->SetItemBackgroundColour(row, + wxColour(settings->GetIdleProcessColour())); + } - WS.AddSample(pid, isClientReadTransaction, backend_type, dataSet1->GetVal("wait_sample")); - //wxULongLong qid = dataSet1->GetLongLong("query_id"); - //WS.AddQuery(qid.GetValue(), qry); - } - statusList->SetItem(row, colpos++, blockedby); - if (!slinfo.IsEmpty()) { - statusList->SetItem(row, colpos, dataSet1->GetVal(wxT("xminlag"))); - } - else - statusList->SetItem(row, colpos, qry); + if (dataSet1->GetBool(wxT("slowquery"))) + statusList->SetItemBackgroundColour(row, + wxColour(settings->GetSlowProcessColour())); + if (dataSet1->GetVal(wxT("blockedby")).Length() > 0) { + statusList->SetItemBackgroundColour(row, + wxColour(settings->GetBlockedProcessColour())); + blocked += dataSet1->GetVal(wxT("blockedby")); + blocked += wxT(","); + } + if (!slinfo.IsEmpty()) { + // walsender + long xmindelta = dataSet1->GetLong(wxT("xminslotdelta")); + + if (xmindelta>=1800) + statusList->SetItemBackgroundColour(row,wxColour(wxT("#FF8028"))); // orange + else + statusList->SetItemBackgroundColour(row, wxColour(settings->GetIdleProcessColour())); // idle + } + if (app_name.StartsWith(wxT("pgp-s super"))||app_name.StartsWith(wxT("pgp-s manager"))) statusList->SetItemBackgroundColour(row, wxColour(settings->GetIdleProcessColour())); // idle - // Colorize the new line - if (viewMenu->IsChecked(MNU_HIGHLIGHTSTATUS)) - { - statusList->SetItemBackgroundColour(row, - wxColour(settings->GetActiveProcessColour())); - if (qry == wxT("") || qry == wxT(" in transaction0")) - statusList->SetItemBackgroundColour(row, - wxColour(settings->GetIdleProcessColour())); - if (connection->BackendMinimumVersion(9, 2)) - { - if (dataSet1->GetVal(wxT("state")) != wxT("active")) - statusList->SetItemBackgroundColour(row, - wxColour(settings->GetIdleProcessColour())); - } + } + else + statusList->SetItemBackgroundColour(row, *wxWHITE); - if (dataSet1->GetBool(wxT("slowquery"))) - statusList->SetItemBackgroundColour(row, - wxColour(settings->GetSlowProcessColour())); - if (dataSet1->GetVal(wxT("blockedby")).Length() > 0) { - statusList->SetItemBackgroundColour(row, - wxColour(settings->GetBlockedProcessColour())); - blocked += dataSet1->GetVal(wxT("blockedby")); - blocked += wxT(","); - } - if (!slinfo.IsEmpty()) { - // walsender - long xmindelta = dataSet1->GetLong(wxT("xminslotdelta")); + // filter apply + bool flt = false; + for (int i = 0; i < filterColumn.size(); i++) { + int col = filterColumn[i]; + wxListItem listitem; + listitem.SetMask(wxLIST_MASK_TEXT); + statusList->GetColumn(col, listitem); + wxString label = listitem.GetText(); + wxString tabval=statusList->GetItemText(row, col); + wxString fval = filterValue[i]; + if (label == _("Client")) { + tabval = tabval.BeforeLast(':'); + fval = fval.BeforeLast(':'); + } + if (tabval != fval) { + flt = true; + break; + } + } + if (!flt) { + // Add the query content to the queries array + queries.Add(qry); + pids.Add(pid); + if (pid == s_pid_HIGHLIGH) { + statusList->SetItemBackgroundColour(row, wxColour(wxT("#FF8028"))); + statusList->EnsureVisible(row); + } - if (xmindelta >= 1800) - statusList->SetItemBackgroundColour(row, wxColour(wxT("#FF8028"))); // orange - else - statusList->SetItemBackgroundColour(row, wxColour(settings->GetIdleProcessColour())); // idle - } - if (app_name.StartsWith(wxT("pgp-s super")) || app_name.StartsWith(wxT("pgp-s manager"))) statusList->SetItemBackgroundColour(row, wxColour(settings->GetIdleProcessColour())); // idle + row++; + } + } + dataSet1->MoveNext(); + } + delete dataSet1; + if (viewMenu->IsChecked(MNU_HIGHLIGHTSTATUS)) + { + wxString numstr; + wxString str; + numstr=blocked.BeforeFirst(',',&str); + while (!numstr.IsEmpty()) { + int number = wxAtoi(numstr); + for(long i = 0; i < pids.size(); i++) + { + if (pids[i]==number) { + statusList->SetItemBackgroundColour(i, + wxColour(settings->GetBlockedbyProcessColour())); - } - else - statusList->SetItemBackgroundColour(row, *wxWHITE); + } + } + blocked=str.Clone(); + numstr=blocked.BeforeFirst(',',&str); + } + } + if (tt.IsValid() && wait_sample && wait_enable) { + WS.EndSeriosSample(); + } + bool selverify=true; + long r = statusList->GetItemCount(); + long fuck_rows=0; + while ((row) < statusList->GetItemCount()) { + statusList->Select(row,false); + long item = -1; + item = statusList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED); + if (item>=row && row>0) statusList->Focus(row-1); + if (statusList->GetItemCount()>row) + { + #ifdef __WXGTK__ + //DeleteItem in GTK flicker problem + if (row+1 == r && filterColumn.size()>0) { + for(int cc=0;ccGetColumnCount();cc++) + statusList->SetItem(row, cc, " "); + fuck_rows=1; + break; + } else statusList->DeleteItem(row); + #else + statusList->DeleteItem(row); + #endif + } + } + r = statusList->GetItemCount()-fuck_rows; + wxString tit = _("Activity") + "(" + NumToStr(r) + ")"; + wxString old = manager.GetPane(wxT("Activity")).caption; + if (tit != old) { + manager.GetPane(wxT("Activity")).Caption(tit); + manager.Update(); + } + statusList->Thaw(); + if (wait_sample && wait_enable && top_small) top_small->Refresh(); + + wxListEvent ev; + //OnSelStatusItem(ev); + if (msgerror.length() > 0) { + statusBar->SetStatusText(msgerror); + } + else + { - // filter apply - bool flt = false; - for (int i = 0; i < filterColumn.size(); i++) { - int col = filterColumn[i]; - wxListItem listitem; - listitem.SetMask(wxLIST_MASK_TEXT); - statusList->GetColumn(col, listitem); - wxString label = listitem.GetText(); - wxString tabval = statusList->GetItemText(row, col); - wxString fval = filterValue[i]; - if (label == _("Client")) { - tabval = tabval.BeforeLast(':'); - fval = fval.BeforeLast(':'); - } - if (tabval != fval) { - flt = true; - break; - } - } - if (!flt) { - // Add the query content to the queries array - queries.Add(qry); - pids.Add(pid); - if (pid == s_pid_HIGHLIGH) { - statusList->SetItemBackgroundColour(row, wxColour(wxT("#FF8028"))); - statusList->EnsureVisible(row); - } - - row++; - } - } - dataSet1->MoveNext(); - } - delete dataSet1; - if (viewMenu->IsChecked(MNU_HIGHLIGHTSTATUS)) - { - wxString numstr; - wxString str; - numstr = blocked.BeforeFirst(',', &str); - while (!numstr.IsEmpty()) { - int number = wxAtoi(numstr); - for (long i = 0; i < pids.size(); i++) - { - if (pids[i] == number) { - statusList->SetItemBackgroundColour(i, - wxColour(settings->GetBlockedbyProcessColour())); - - } - } - blocked = str.Clone(); - numstr = blocked.BeforeFirst(',', &str); - } - } - if (tt.IsValid() && wait_sample && wait_enable) { - WS.EndSeriosSample(); - } - bool selverify = true; - long r = statusList->GetItemCount(); - long fuck_rows=0; - while ((row) < statusList->GetItemCount()) { - statusList->Select(row, false); - long item = -1; - item = statusList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED); - if (item>=row && row>0) statusList->Focus(row-1); - if (statusList->GetItemCount()>row) - { - #ifdef __WXGTK__ - //DeleteItem in GTK flicker problem - if (row+1 == r && filterColumn.size()>0) { - for(int cc=0;ccGetColumnCount();cc++) - statusList->SetItem(row, cc, " "); - fuck_rows=1; - break; - } else statusList->DeleteItem(row); - #else - statusList->DeleteItem(row); - #endif - } - } - r = statusList->GetItemCount()-fuck_rows; - wxString tit = _("Activity") + "(" + NumToStr(r) + ")"; - wxString old = manager.GetPane(wxT("Activity")).caption; - if (tit != old) { - manager.GetPane(wxT("Activity")).Caption(tit); - manager.Update(); - } - statusList->Thaw(); - if (wait_sample && wait_enable && top_small) top_small->Refresh(); - - wxListEvent ev; - //OnSelStatusItem(ev); - if (msgerror.length() > 0) { - statusBar->SetStatusText(msgerror); - } - else - { - - statusBar->SetStatusText(_("Done.")); - } - } - else - checkConnection(); + statusBar->SetStatusText(_("Done.")); + } + } + else + checkConnection(); } -void frmStatus::OnRefreshLocksTimer(wxTimerEvent& event) +void frmStatus::OnRefreshLocksTimer(wxTimerEvent &event) { - long pid = 0; + long pid = 0; - if (!viewMenu->IsChecked(MNU_LOCKPAGE)) - return; + if (! viewMenu->IsChecked(MNU_LOCKPAGE)) + return; - checkConnection(); - if (!locks_connection) - { - statusTimer->Stop(); - locksTimer->Stop(); - if (xactTimer) - xactTimer->Stop(); - if (logTimer) - logTimer->Stop(); - if (querystateTimer) - querystateTimer->Stop(); - return; - } + checkConnection(); + if (!locks_connection) + { + statusTimer->Stop(); + locksTimer->Stop(); + if (xactTimer) + xactTimer->Stop(); + if (logTimer) + logTimer->Stop(); + if (querystateTimer) + querystateTimer->Stop(); + return; + } - wxCriticalSectionLocker lock(gs_critsect); + wxCriticalSectionLocker lock(gs_critsect); - // There are no sort operator for xid before 8.3 - if (!connection->BackendMinimumVersion(8, 3) && lockSortColumn == 5) - { - wxLogError(_("You cannot sort by transaction id on your PostgreSQL release. You need at least 8.3.")); - lockSortColumn = 1; - } + // There are no sort operator for xid before 8.3 + if (!connection->BackendMinimumVersion(8, 3) && lockSortColumn == 5) + { + wxLogError(_("You cannot sort by transaction id on your PostgreSQL release. You need at least 8.3.")); + lockSortColumn = 1; + } - long row = 0; - wxString sql; - if (locks_connection->BackendMinimumVersion(8, 3)) - { - sql = wxT("SELECT pg_stat_get_backend_pid(svrid) AS pid, ") - wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ") - wxT("coalesce(pgc.relname, pgl.relation::text) AS class, ") - wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ") - wxT("pgl.virtualxid::text, pgl.virtualtransaction::text AS transaction, pgl.mode, pgl.granted, ") - wxT("date_trunc('second', pg_stat_get_backend_activity_start(svrid)) AS query_start, ") - wxT("pg_stat_get_backend_activity(svrid) AS query ") - wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ") - wxT("LEFT JOIN pg_class pgc ON pgl.relation=pgc.oid ") - wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ") - wxT("ORDER BY ") + NumToStr((long)lockSortColumn) + wxT(" ") + lockSortOrder; - } - else if (locks_connection->BackendMinimumVersion(7, 4)) - { - sql = wxT("SELECT pg_stat_get_backend_pid(svrid) AS pid, ") - wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ") - wxT("coalesce(pgc.relname, pgl.relation::text) AS class, ") - wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ") - wxT("pgl.transaction, pgl.mode, pgl.granted, ") - wxT("date_trunc('second', pg_stat_get_backend_activity_start(svrid)) AS query_start, ") - wxT("pg_stat_get_backend_activity(svrid) AS query ") - wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ") - wxT("LEFT JOIN pg_class pgc ON pgl.relation=pgc.oid ") - wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ") - wxT("ORDER BY ") + NumToStr((long)lockSortColumn) + wxT(" ") + lockSortOrder; - } - else - { - sql = wxT("SELECT pg_stat_get_backend_pid(svrid) AS pid, ") - wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ") - wxT("coalesce(pgc.relname, pgl.relation::text) AS class, ") - wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ") - wxT("pgl.transaction, pgl.mode, pgl.granted, ") - wxT("pg_stat_get_backend_activity(svrid) AS query ") - wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ") - wxT("LEFT JOIN pg_class pgc ON pgl.relation=pgc.oid ") - wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ") - wxT("ORDER BY ") + NumToStr((long)lockSortColumn) + wxT(" ") + lockSortOrder; - } + long row = 0; + wxString sql; + if (locks_connection->BackendMinimumVersion(8, 3)) + { + sql = wxT("SELECT pg_stat_get_backend_pid(svrid) AS pid, ") + wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ") + wxT("coalesce(pgc.relname, pgl.relation::text) AS class, ") + wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ") + wxT("pgl.virtualxid::text, pgl.virtualtransaction::text AS transaction, pgl.mode, pgl.granted, ") + wxT("date_trunc('second', pg_stat_get_backend_activity_start(svrid)) AS query_start, ") + wxT("pg_stat_get_backend_activity(svrid) AS query ") + wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ") + wxT("LEFT JOIN pg_class pgc ON pgl.relation=pgc.oid ") + wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ") + wxT("ORDER BY ") + NumToStr((long)lockSortColumn) + wxT(" ") + lockSortOrder; + } + else if (locks_connection->BackendMinimumVersion(7, 4)) + { + sql = wxT("SELECT pg_stat_get_backend_pid(svrid) AS pid, ") + wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ") + wxT("coalesce(pgc.relname, pgl.relation::text) AS class, ") + wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ") + wxT("pgl.transaction, pgl.mode, pgl.granted, ") + wxT("date_trunc('second', pg_stat_get_backend_activity_start(svrid)) AS query_start, ") + wxT("pg_stat_get_backend_activity(svrid) AS query ") + wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ") + wxT("LEFT JOIN pg_class pgc ON pgl.relation=pgc.oid ") + wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ") + wxT("ORDER BY ") + NumToStr((long)lockSortColumn) + wxT(" ") + lockSortOrder; + } + else + { + sql = wxT("SELECT pg_stat_get_backend_pid(svrid) AS pid, ") + wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ") + wxT("coalesce(pgc.relname, pgl.relation::text) AS class, ") + wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ") + wxT("pgl.transaction, pgl.mode, pgl.granted, ") + wxT("pg_stat_get_backend_activity(svrid) AS query ") + wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ") + wxT("LEFT JOIN pg_class pgc ON pgl.relation=pgc.oid ") + wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ") + wxT("ORDER BY ") + NumToStr((long)lockSortColumn) + wxT(" ") + lockSortOrder; + } - pgSet* dataSet2 = locks_connection->ExecuteSet(sql); - if (dataSet2) - { - statusBar->SetStatusText(_("Refreshing locks list.")); - lockList->Freeze(); + pgSet *dataSet2 = locks_connection->ExecuteSet(sql); + if (dataSet2) + { + statusBar->SetStatusText(_("Refreshing locks list.")); + lockList->Freeze(); - while (!dataSet2->Eof()) - { - pid = dataSet2->GetLong(wxT("pid")); + while (!dataSet2->Eof()) + { + pid = dataSet2->GetLong(wxT("pid")); - if (pid != backend_pid) - { - if (row >= lockList->GetItemCount()) - { - lockList->InsertItem(row, NumToStr(pid), -1); - row = lockList->GetItemCount() - 1; - } - else - { - lockList->SetItem(row, 0, NumToStr(pid)); - } + if (pid != backend_pid) + { + if (row >= lockList->GetItemCount()) + { + lockList->InsertItem(row, NumToStr(pid), -1); + row = lockList->GetItemCount() - 1; + } + else + { + lockList->SetItem(row, 0, NumToStr(pid)); + } - int colpos = 1; - lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("dbname"))); - lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("class"))); - lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("user"))); - if (locks_connection->BackendMinimumVersion(8, 3)) - lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("virtualxid"))); - lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("transaction"))); - lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("mode"))); + int colpos = 1; + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("dbname"))); + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("class"))); + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("user"))); + if (locks_connection->BackendMinimumVersion(8, 3)) + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("virtualxid"))); + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("transaction"))); + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("mode"))); - if (dataSet2->GetVal(wxT("granted")) == wxT("t")) - { - lockList->SetItem(row, colpos++, _("Yes")); - lockList->SetItemBackgroundColour(row, lockList->GetBackgroundColour()); - } - else { - lockList->SetItem(row, colpos++, _("No")); - lockList->SetItemBackgroundColour(row, wxColour(settings->GetBlockedProcessColour())); + if (dataSet2->GetVal(wxT("granted")) == wxT("t")) + { + lockList->SetItem(row, colpos++, _("Yes")); + lockList->SetItemBackgroundColour(row,lockList->GetBackgroundColour()); + } + else { + lockList->SetItem(row, colpos++, _("No")); + lockList->SetItemBackgroundColour(row, wxColour(settings->GetBlockedProcessColour())); + + } - } + wxString qry = dataSet2->GetVal(wxT("query")); - wxString qry = dataSet2->GetVal(wxT("query")); + if (locks_connection->BackendMinimumVersion(7, 4)) + { + if (qry.IsEmpty() || qry == wxT("")) + lockList->SetItem(row, colpos++, wxEmptyString); + else + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("query_start"))); + } + lockList->SetItem(row, colpos++, qry.Left(250)); - if (locks_connection->BackendMinimumVersion(7, 4)) - { - if (qry.IsEmpty() || qry == wxT("")) - lockList->SetItem(row, colpos++, wxEmptyString); - else - lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("query_start"))); - } - lockList->SetItem(row, colpos++, qry.Left(250)); + row++; + } + dataSet2->MoveNext(); + } - row++; - } - dataSet2->MoveNext(); - } + delete dataSet2; - delete dataSet2; + while (row < lockList->GetItemCount()) + lockList->DeleteItem(row); - while (row < lockList->GetItemCount()) - lockList->DeleteItem(row); - - lockList->Thaw(); - wxListEvent ev; - //OnSelLockItem(ev); - statusBar->SetStatusText(_("Done.")); - } - else - checkConnection(); + lockList->Thaw(); + wxListEvent ev; + //OnSelLockItem(ev); + statusBar->SetStatusText(_("Done.")); + } + else + checkConnection(); } -void frmStatus::OnRefreshXactTimer(wxTimerEvent& event) +void frmStatus::OnRefreshXactTimer(wxTimerEvent &event) { - if (!viewMenu->IsEnabled(MNU_XACTPAGE) || !viewMenu->IsChecked(MNU_XACTPAGE) || !xactTimer) - return; + if (! viewMenu->IsEnabled(MNU_XACTPAGE) || ! viewMenu->IsChecked(MNU_XACTPAGE) || !xactTimer) + return; - checkConnection(); - if (!connection) - { - statusTimer->Stop(); - locksTimer->Stop(); - xactTimer->Stop(); - querystateTimer->Stop(); - if (logTimer) - logTimer->Stop(); - return; - } + checkConnection(); + if (!connection) + { + statusTimer->Stop(); + locksTimer->Stop(); + xactTimer->Stop(); + querystateTimer->Stop(); + if (logTimer) + logTimer->Stop(); + return; + } - wxCriticalSectionLocker lock(gs_critsect); + wxCriticalSectionLocker lock(gs_critsect); - // There are no sort operator for xid before 8.3 - if (!connection->BackendMinimumVersion(8, 3) && xactSortColumn == 1) - { - wxLogError(_("You cannot sort by transaction id on your PostgreSQL release. You need at least 8.3.")); - xactSortColumn = 2; - } + // There are no sort operator for xid before 8.3 + if (!connection->BackendMinimumVersion(8, 3) && xactSortColumn == 1) + { + wxLogError(_("You cannot sort by transaction id on your PostgreSQL release. You need at least 8.3.")); + xactSortColumn = 2; + } - long row = 0; - wxString sql; - if (connection->BackendMinimumVersion(8, 3)) - sql = wxT("SELECT transaction::text, gid, prepared, owner, database ") - wxT("FROM pg_prepared_xacts ") - wxT("ORDER BY ") + NumToStr((long)xactSortColumn) + wxT(" ") + xactSortOrder; - else - sql = wxT("SELECT transaction, gid, prepared, owner, database ") - wxT("FROM pg_prepared_xacts ") - wxT("ORDER BY ") + NumToStr((long)xactSortColumn) + wxT(" ") + xactSortOrder; + long row = 0; + wxString sql; + if (connection->BackendMinimumVersion(8, 3)) + sql = wxT("SELECT transaction::text, gid, prepared, owner, database ") + wxT("FROM pg_prepared_xacts ") + wxT("ORDER BY ") + NumToStr((long)xactSortColumn) + wxT(" ") + xactSortOrder; + else + sql = wxT("SELECT transaction, gid, prepared, owner, database ") + wxT("FROM pg_prepared_xacts ") + wxT("ORDER BY ") + NumToStr((long)xactSortColumn) + wxT(" ") + xactSortOrder; - pgSet* dataSet3 = connection->ExecuteSet(sql); - if (dataSet3) - { - statusBar->SetStatusText(_("Refreshing transactions list.")); - xactList->Freeze(); + pgSet *dataSet3 = connection->ExecuteSet(sql); + if (dataSet3) + { + statusBar->SetStatusText(_("Refreshing transactions list.")); + xactList->Freeze(); - while (!dataSet3->Eof()) - { - long xid = dataSet3->GetLong(wxT("transaction")); + while (!dataSet3->Eof()) + { + long xid = dataSet3->GetLong(wxT("transaction")); - if (row >= xactList->GetItemCount()) - { - xactList->InsertItem(row, NumToStr(xid), -1); - row = xactList->GetItemCount() - 1; - } - else - { - xactList->SetItem(row, 0, NumToStr(xid)); - } + if (row >= xactList->GetItemCount()) + { + xactList->InsertItem(row, NumToStr(xid), -1); + row = xactList->GetItemCount() - 1; + } + else + { + xactList->SetItem(row, 0, NumToStr(xid)); + } - int colpos = 1; - xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("gid"))); - xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("prepared"))); - xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("owner"))); - xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("database"))); + int colpos = 1; + xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("gid"))); + xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("prepared"))); + xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("owner"))); + xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("database"))); - row++; - dataSet3->MoveNext(); - } - delete dataSet3; + row++; + dataSet3->MoveNext(); + } + delete dataSet3; - while (row < xactList->GetItemCount()) - xactList->DeleteItem(row); + while (row < xactList->GetItemCount()) + xactList->DeleteItem(row); - xactList->Thaw(); - wxListEvent ev; - //OnSelXactItem(ev); - statusBar->SetStatusText(_("Done.")); - } - else - checkConnection(); + xactList->Thaw(); + wxListEvent ev; + //OnSelXactItem(ev); + statusBar->SetStatusText(_("Done.")); + } + else + checkConnection(); } -long frmStatus::getlongvalue(wxString source, wxString match_str) { - long aa = 0; - wxRegEx foundstr(match_str); - if (foundstr.Matches(source)) { - wxString v = foundstr.GetMatch(source, 1); - v.ToLong(&aa); - } - return aa; +long frmStatus::getlongvalue(wxString source,wxString match_str) { + long aa=0; + wxRegEx foundstr(match_str); + if (foundstr.Matches(source)) { + wxString v=foundstr.GetMatch(source,1); + v.ToLong(&aa); + } + return aa; } + - -void frmStatus::OnRefreshQuerystateTimer(wxTimerEvent& event) +void frmStatus::OnRefreshQuerystateTimer(wxTimerEvent &event) { - if (!viewMenu->IsEnabled(MNU_QUERYSTATEPAGE) || !viewMenu->IsChecked(MNU_QUERYSTATEPAGE) || !querystateTimer) - return; + if (! viewMenu->IsEnabled(MNU_QUERYSTATEPAGE) || ! viewMenu->IsChecked(MNU_QUERYSTATEPAGE) || !querystateTimer) + return; - checkConnection(); - if (!connection) - { - statusTimer->Stop(); - locksTimer->Stop(); - xactTimer->Stop(); - if (querystateTimer) - querystateTimer->Stop(); - if (logTimer) - logTimer->Stop(); - return; - } - int row = statusList->GetFirstSelected(); - if (row < 0) - return; - wxString pid = statusList->GetText(row, 0); - wxString dbname = statusList->GetText(row, 2); // dbname - wxString wait_event_type = statusList->GetText(row, wait_event_type_col); - if (dbname.IsEmpty() || wait_event_type == wxT("Extension")) return; + checkConnection(); + if (!connection) + { + statusTimer->Stop(); + locksTimer->Stop(); + xactTimer->Stop(); + if (querystateTimer) + querystateTimer->Stop(); + if (logTimer) + logTimer->Stop(); + return; + } + int row = statusList->GetFirstSelected(); + if (row<0) + return; + wxString pid=statusList->GetText(row, 0); + wxString dbname=statusList->GetText(row, 2); // dbname + wxString wait_event_type= statusList->GetText(row, wait_event_type_col); + if (dbname.IsEmpty()||wait_event_type==wxT("Extension")) return; - wxString flags = wxT(""); - if (viewMenu->IsChecked(MNU_QUERYSTATEVERBOSE)) - flags += wxT(",true,false"); - else - flags += wxT(",false,false"); - if (viewMenu->IsChecked(MNU_QUERYSTATETIME)) - flags += wxT(",true"); - else - flags += wxT(",false"); - if (viewMenu->IsChecked(MNU_QUERYSTATEBUFFER)) - flags += wxT(",true"); - else - flags += wxT(",false"); - if (viewMenu->IsChecked(MNU_QUERYSTATETRIGGER)) - flags += wxT(",true"); - else - flags += wxT(",false"); + wxString flags=wxT(""); + if (viewMenu->IsChecked(MNU_QUERYSTATEVERBOSE)) + flags += wxT(",true,false"); + else + flags += wxT(",false,false"); + if (viewMenu->IsChecked(MNU_QUERYSTATETIME)) + flags += wxT(",true"); + else + flags += wxT(",false"); + if (viewMenu->IsChecked(MNU_QUERYSTATEBUFFER)) + flags += wxT(",true"); + else + flags += wxT(",false"); + if (viewMenu->IsChecked(MNU_QUERYSTATETRIGGER)) + flags += wxT(",true"); + else + flags += wxT(",false"); - flags += wxT(",'text'::text"); - wxCriticalSectionLocker lock(gs_critsect); + flags += wxT(",'text'::text"); + wxCriticalSectionLocker lock(gs_critsect); - row = 0; - wxString sql; - sql = wxT("select pid,frame_number,query_text,unnest(string_to_array(plan, E'\n')) pln,leader_pid from pg_query_state(") - + pid + flags + wxT(") s"); + row = 0; + wxString sql; + sql = wxT("select pid,frame_number,query_text,unnest(string_to_array(plan, E'\n')) pln,leader_pid from pg_query_state(") + +pid+flags+wxT(") s"); + + pgSet *dataSet3 = connection->ExecuteSet(sql,false); + if (dataSet3) + { + statusBar->SetStatusText(_("Refreshing query state list.")); + querystateList->Freeze(); + long prev_fn=100000000; + while (!dataSet3->Eof()&&dataSet3->NumCols()>0) + { + long pid = dataSet3->GetLong(wxT("pid")); - pgSet* dataSet3 = connection->ExecuteSet(sql, false); - if (dataSet3) - { - statusBar->SetStatusText(_("Refreshing query state list.")); - querystateList->Freeze(); - long prev_fn = 100000000; - while (!dataSet3->Eof() && dataSet3->NumCols() > 0) - { - long pid = dataSet3->GetLong(wxT("pid")); + if (row >= querystateList->GetItemCount()) + { + querystateList->InsertItem(row, NumToStr(pid), -1); + row = querystateList->GetItemCount() - 1; + } + else + { + querystateList->SetItem(row, 0, NumToStr(pid)); + } + + int colpos = 1; + long fn=dataSet3->GetLong(wxT("frame_number")); + querystateList->SetItem(row, colpos++, NumToStr(fn)); + querystateList->SetItem(row, colpos++, dataSet3->GetVal(wxT("query_text"))); + wxString p=dataSet3->GetVal(wxT("pln")); + querystateList->SetItem(row, colpos++, p); + querystateList->SetItem(row, colpos++, dataSet3->GetVal(wxT("leader_pid"))); + if (prev_fn==fn) { + querystateList->SetItem(row, 1, wxT("")); + querystateList->SetItem(row, 2, wxT("")); + } + wxColour wc; + if (p.Find(wxT("->"))<0) { + wc=*wxWHITE; + if (getlongvalue(p,wxT("Rows Removed by Join Filter: ([0-9]+)"))>1000000) { + wc=wxColour(201,83,2); + //querystateList->SetItemBackgroundColour(row, wxColour(201,83,2)); + } - if (row >= querystateList->GetItemCount()) - { - querystateList->InsertItem(row, NumToStr(pid), -1); - row = querystateList->GetItemCount() - 1; - } - else - { - querystateList->SetItem(row, 0, NumToStr(pid)); - } + querystateList->SetItemBackgroundColour(row, wc); + //querystateList->SetItemBackgroundColour(row, ); + } else + { + if (getlongvalue(p,wxT("actual rows=([0-9]+)"))>1000000) { + querystateList->SetItemBackgroundColour(row, wxColour(255,174,200)); // red + } else + querystateList->SetItemBackgroundColour(row, wxColour(224,255,224)); // gren + } - int colpos = 1; - long fn = dataSet3->GetLong(wxT("frame_number")); - querystateList->SetItem(row, colpos++, NumToStr(fn)); - querystateList->SetItem(row, colpos++, dataSet3->GetVal(wxT("query_text"))); - wxString p = dataSet3->GetVal(wxT("pln")); - querystateList->SetItem(row, colpos++, p); - querystateList->SetItem(row, colpos++, dataSet3->GetVal(wxT("leader_pid"))); - if (prev_fn == fn) { - querystateList->SetItem(row, 1, wxT("")); - querystateList->SetItem(row, 2, wxT("")); - } - wxColour wc; - if (p.Find(wxT("->")) < 0) { - wc = *wxWHITE; - if (getlongvalue(p, wxT("Rows Removed by Join Filter: ([0-9]+)")) > 1000000) { - wc = wxColour(201, 83, 2); - //querystateList->SetItemBackgroundColour(row, wxColour(201,83,2)); - } + row++; + prev_fn=fn; + dataSet3->MoveNext(); + } + delete dataSet3; - querystateList->SetItemBackgroundColour(row, wc); - //querystateList->SetItemBackgroundColour(row, ); - } - else - { - if (getlongvalue(p, wxT("actual rows=([0-9]+)")) > 1000000) { - querystateList->SetItemBackgroundColour(row, wxColour(255, 174, 200)); // red - } - else - querystateList->SetItemBackgroundColour(row, wxColour(224, 255, 224)); // gren - } + while (row < querystateList->GetItemCount()) + querystateList->DeleteItem(row); - row++; - prev_fn = fn; - dataSet3->MoveNext(); - } - delete dataSet3; - - while (row < querystateList->GetItemCount()) - querystateList->DeleteItem(row); - - querystateList->Thaw(); - wxListEvent ev; - //OnSelQuerystateItem(ev); - statusBar->SetStatusText(_("Done.")); - } - else - checkConnection(); + querystateList->Thaw(); + wxListEvent ev; + //OnSelQuerystateItem(ev); + statusBar->SetStatusText(_("Done.")); + } + else + checkConnection(); } -void frmStatus::OnRefreshLogTimer(wxTimerEvent& event) +void frmStatus::OnRefreshLogTimer(wxTimerEvent &event) { - if (logisread) return; - if (!viewMenu->IsEnabled(MNU_LOGPAGE) || !viewMenu->IsChecked(MNU_LOGPAGE) || !logTimer) - return; + if (logisread) return; + if (! viewMenu->IsEnabled(MNU_LOGPAGE) || ! viewMenu->IsChecked(MNU_LOGPAGE) || !logTimer) + return; - checkConnection(); - if (!connection) - { - statusTimer->Stop(); - locksTimer->Stop(); - if (xactTimer) - xactTimer->Stop(); - logTimer->Stop(); + checkConnection(); + if (!connection) + { + statusTimer->Stop(); + locksTimer->Stop(); + if (xactTimer) + xactTimer->Stop(); + logTimer->Stop(); - if (logThread) { - logThread->BreakRead(); - wxMilliSleep(50); - logThread->DoTerminate(); - wxMilliSleep(5); - //s_CloseLog.Wait(); - while (logThread != NULL) wxMilliSleep(5); - } - return; - } - if (!logThread) { - wxString applicationname = "pgAdmin III LogReader"; - logconn = new pgConn(connection->GetHostName(), connection->GetService(), connection->GetHostAddr(), connection->GetDbname(), - connection->GetUser(), connection->GetPassword(), connection->GetPort(), connection->GetRole(), "", connection->GetSslMode(), - 0, applicationname, connection->GetSSLCert(), connection->GetSSLKey(), connection->GetSSLRootCert(), connection->GetSSLCrl(), - connection->GetSSLCompression()); + if (logThread) { + logThread->BreakRead(); + wxMilliSleep(50); + logThread->DoTerminate(); + wxMilliSleep(5); + //s_CloseLog.Wait(); + while (logThread != NULL) wxMilliSleep(5); + } + return; + } + if (!logThread) { + wxString applicationname = "pgAdmin III LogReader"; + logconn = new pgConn(connection->GetHostName(), connection->GetService(), connection->GetHostAddr(), connection->GetDbname(), + connection->GetUser(), connection->GetPassword(), connection->GetPort(), connection->GetRole(), "", connection->GetSslMode(), + 0, applicationname, connection->GetSSLCert(), connection->GetSSLKey(), connection->GetSSLRootCert(), connection->GetSSLCrl(), + connection->GetSSLCompression()); + + if (!logconn->IsAlive()) { + wxString err=logconn->GetLastError(); + //wxMessageBox(err); + statusBar->SetStatusText(err); + delete logconn; + logconn = NULL; + return; + } + else + { + } + if (log_queue.IsOk()) log_queue.Clear(); - if (!logconn->IsAlive()) { - wxString err = logconn->GetLastError(); - //wxMessageBox(err); - statusBar->SetStatusText(err); - delete logconn; - logconn = NULL; - return; - } - else - { - } - if (log_queue.IsOk()) log_queue.Clear(); + logThread = new ReadLogThread(logconn, this,&log_queue); + if (logThread->Create() != wxTHREAD_NO_ERROR) + { + wxLogError(wxT("Can’t create log thread!")); + delete logThread; + logThread = NULL; + } else + logThread->Run(); + } + else + if (logThread) // The thread + { + // Recive lines + if (logThread->isBreak()) return; + wxString sstr; + long lastrow = logList->GetItemCount(); + bool remote = lastrow - 1 == logList->GetFocusedItem(); + long cnt = 0; + float pr = 0; + long timeout = logTimer->GetInterval(); + const wxMilliClock_t waitUntil = wxGetLocalTimeMillis() + timeout; + logisread = true; + if (!logList->IsFrozen()) logList->Freeze(); + while (logThread && log_queue.ReceiveTimeout(1, sstr) == wxMSGQUEUE_NO_ERROR) { + if (logThread->isBreak()) break; + addLogLine(sstr, true, true); + if (logThread->isBreak()) break; + if ((cnt++ % 1000) == 0) { + //pr = 100 * cnt / total; + wxString ll = wxString::Format("append rows %ld ...", cnt+ lastrow); + statusBar->SetStatusText(ll); + wxYield(); + if (frm_exit) { logisread = false; return; } + } + //if (logThread->isBreak()) return; + const wxMilliClock_t now = wxGetLocalTimeMillis(); + if (now >= waitUntil) break; - logThread = new ReadLogThread(logconn, this, &log_queue); - if (logThread->Create() != wxTHREAD_NO_ERROR) - { - wxLogError(wxT("Can’t create log thread!")); - delete logThread; - logThread = NULL; - } - else - logThread->Run(); - } - else - if (logThread) // The thread - { - // Recive lines - if (logThread->isBreak()) return; - wxString sstr; - long lastrow = logList->GetItemCount(); - bool remote = lastrow - 1 == logList->GetFocusedItem(); - long cnt = 0; - float pr = 0; - long timeout = logTimer->GetInterval(); - const wxMilliClock_t waitUntil = wxGetLocalTimeMillis() + timeout; - logisread = true; - if (!logList->IsFrozen()) logList->Freeze(); - while (logThread && log_queue.ReceiveTimeout(1, sstr) == wxMSGQUEUE_NO_ERROR) { - if (logThread->isBreak()) break; - addLogLine(sstr, true, true); - if (logThread->isBreak()) break; - if ((cnt++ % 1000) == 0) { - //pr = 100 * cnt / total; - wxString ll = wxString::Format("append rows %ld ...", cnt + lastrow); - statusBar->SetStatusText(ll); - wxYield(); - if (frm_exit) { logisread = false; return; } - } - //if (logThread->isBreak()) return; - const wxMilliClock_t now = wxGetLocalTimeMillis(); - if (now >= waitUntil) break; + }; + if (logList->IsFrozen()) + { + logList->Thaw(); + nav->Refresh(); + } + logisread = false; + if (logThread && logThread->isBreak()) { + return; + } + if (cnt > 0) { + cnt += lastrow; + //wxString ll = wxString::Format("append rows GUI %ld ...", cnt); + //statusBar->SetStatusText(ll); + addodd++; + if (remote) { + logList->Focus(logList->GetItemCount() - 1); + } + logList->Refresh(); + } + //statusBar->SetStatusText(s); + if (logThread && logThread->isReadyRows()) { + long read = logThread->GetReadByteFile(savedPartialLine); // result last read + logfileLength = read; + // Ready next lines + } + else { + return; /// not ready next lines + } + } + + + + wxCriticalSectionLocker lock(gs_critsect); + if (logList->IsFrozen()) logList->Thaw(); - }; - if (logList->IsFrozen()) - { - logList->Thaw(); - nav->Refresh(); - } - logisread = false; - if (logThread && logThread->isBreak()) { - return; - } - if (cnt > 0) { - cnt += lastrow; - //wxString ll = wxString::Format("append rows GUI %ld ...", cnt); - //statusBar->SetStatusText(ll); - addodd++; - if (remote) { - logList->Focus(logList->GetItemCount() - 1); - } - logList->Refresh(); - } - //statusBar->SetStatusText(s); - if (logThread && logThread->isReadyRows()) { - long read = logThread->GetReadByteFile(savedPartialLine); // result last read - logfileLength = read; - // Ready next lines - } - else { - return; /// not ready next lines - } - } + if (connection->GetLastResultError().sql_state == wxT("42501")) + { + // Don't have superuser privileges, so can't do anything with the log display + logTimer->Stop(); + cbLogfiles->Disable(); + btnRotateLog->Disable(); + manager.GetPane(wxT("Logfile")).Show(false); + manager.Update(); + return; + } + long newlen = 0; + if (logDirectory.IsEmpty()) + { + // freshly started + logDirectory = connection->ExecuteScalar(wxT("SHOW log_directory")); + if (connection->GetLastResultError().sql_state == wxT("42501")) + { + // Don't have superuser privileges, so can't do anything with the log display + logTimer->Stop(); + cbLogfiles->Disable(); + btnRotateLog->Disable(); + manager.GetPane(wxT("Logfile")).Show(false); + manager.Update(); + return; + } + if (fillLogfileCombo()) + { + savedPartialLine.Clear(); + cbLogfiles->SetSelection(0); + wxCommandEvent ev; + OnLoadLogfile(ev); + return; + } + else + { + //logDirectory = wxEmptyString; + return; + logDirectory = wxT("-"); + if (connection->BackendMinimumVersion(8, 3)) + logList->AppendItem(-1, wxString(_("logging_collector not enabled or log_filename misconfigured"))); + else + logList->AppendItem(-1, wxString(_("redirect_stderr not enabled or log_filename misconfigured"))); + cbLogfiles->Disable(); + btnRotateLog->Disable(); + } + } - wxCriticalSectionLocker lock(gs_critsect); - if (logList->IsFrozen()) logList->Thaw(); + if (logDirectory == wxT("-")) + return; - if (connection->GetLastResultError().sql_state == wxT("42501")) - { - // Don't have superuser privileges, so can't do anything with the log display - logTimer->Stop(); - cbLogfiles->Disable(); - btnRotateLog->Disable(); - manager.GetPane(wxT("Logfile")).Show(false); - manager.Update(); - return; - } + if (isCurrent && logfileName.Len()>0) + { + // check if the current logfile changed + + pgSet* set; + if ((connection->BackendMinimumVersion(10, 0))) + set = connection->ExecuteSet(wxT("select size len from pg_stat_file(") + connection->qtDbString(logfileName) + wxT(",true)"),false); + else + set = connection->ExecuteSet(wxT("SELECT pg_file_length(") + connection->qtDbString(logfileName) + wxT(") AS len")); + if (set ) + { + if (set->NumCols() == 0) { + // error server + // continue after + return; + } + if (set->NumCols()>0 && !set->IsNull(0)) newlen = set->GetLong(wxT("len")); + else { + logDirectory = ""; // reRead directory + logfileName = ""; + newlen = 0; + showCurrent = true; + } + delete set; + } + else + { + checkConnection(); + logDirectory = ""; // reRead directory + logfileName = ""; + return; + } + if (newlen > logfileLength) + { - long newlen = 0; + statusBar->SetStatusText(_("Refreshing log list.")); + addLogFile(logfileName, logfileTimestamp, newlen, logfileLength, false); + statusBar->SetStatusText(_("Wait...")); + // as long as there was new data, the logfile is probably the current + // one so we don't need to check for rotation + return; + } + } - if (logDirectory.IsEmpty()) - { - // freshly started - logDirectory = connection->ExecuteScalar(wxT("SHOW log_directory")); - if (connection->GetLastResultError().sql_state == wxT("42501")) - { - // Don't have superuser privileges, so can't do anything with the log display - logTimer->Stop(); - cbLogfiles->Disable(); - btnRotateLog->Disable(); - manager.GetPane(wxT("Logfile")).Show(false); - manager.Update(); - return; - } - if (fillLogfileCombo()) - { - savedPartialLine.Clear(); - cbLogfiles->SetSelection(0); - wxCommandEvent ev; - OnLoadLogfile(ev); - return; - } - else - { - //logDirectory = wxEmptyString; - return; - logDirectory = wxT("-"); - if (connection->BackendMinimumVersion(8, 3)) - logList->AppendItem(-1, wxString(_("logging_collector not enabled or log_filename misconfigured"))); - else - logList->AppendItem(-1, wxString(_("redirect_stderr not enabled or log_filename misconfigured"))); - cbLogfiles->Disable(); - btnRotateLog->Disable(); - } - } + // + wxString newDirectory = connection->ExecuteScalar(wxT("SHOW log_directory")); - if (logDirectory == wxT("-")) - return; + int newfiles = 0; + if (newDirectory != logDirectory) + cbLogfiles->Clear(); - if (isCurrent && logfileName.Len() > 0) - { - // check if the current logfile changed + newfiles = fillLogfileCombo(); - pgSet* set; - if ((connection->BackendMinimumVersion(10, 0))) - set = connection->ExecuteSet(wxT("select size len from pg_stat_file(") + connection->qtDbString(logfileName) + wxT(",true)"), false); - else - set = connection->ExecuteSet(wxT("SELECT pg_file_length(") + connection->qtDbString(logfileName) + wxT(") AS len")); - if (set) - { - if (set->NumCols() == 0) { - // error server - // continue after - return; - } - if (set->NumCols() > 0 && !set->IsNull(0)) newlen = set->GetLong(wxT("len")); - else { - logDirectory = ""; // reRead directory - logfileName = ""; - newlen = 0; - showCurrent = true; - } - delete set; - } - else - { - checkConnection(); - logDirectory = ""; // reRead directory - logfileName = ""; - return; - } - if (newlen > logfileLength) - { + if (newfiles) + { + if (!showCurrent) + isCurrent = false; - statusBar->SetStatusText(_("Refreshing log list.")); - addLogFile(logfileName, logfileTimestamp, newlen, logfileLength, false); - statusBar->SetStatusText(_("Wait...")); - // as long as there was new data, the logfile is probably the current - // one so we don't need to check for rotation - return; - } - } + if (isCurrent) + { + wxCommandEvent ev; + if (cbLogfiles->GetCount() > 0) { + cbLogfiles->SetSelection(0); + OnLoadLogfile(ev); + } + else { - // - wxString newDirectory = connection->ExecuteScalar(wxT("SHOW log_directory")); + int pos = cbLogfiles->GetCount() - newfiles; + bool skipFirst = true; - int newfiles = 0; - if (newDirectory != logDirectory) - cbLogfiles->Clear(); + while (newfiles--) + { + addLogLine(_("pgadmin:Logfile rotated."), false); + wxDateTime* ts = (wxDateTime*)cbLogfiles->wxItemContainer::GetClientData(pos++); + wxASSERT(ts != 0); + if (logThread) logThread->BreakRead(); + addLogFile(ts, skipFirst); + skipFirst = false; - newfiles = fillLogfileCombo(); - - if (newfiles) - { - if (!showCurrent) - isCurrent = false; - - if (isCurrent) - { - wxCommandEvent ev; - if (cbLogfiles->GetCount() > 0) { - cbLogfiles->SetSelection(0); - OnLoadLogfile(ev); - } - else { - - int pos = cbLogfiles->GetCount() - newfiles; - bool skipFirst = true; - - while (newfiles--) - { - addLogLine(_("pgadmin:Logfile rotated."), false); - wxDateTime* ts = (wxDateTime*)cbLogfiles->wxItemContainer::GetClientData(pos++); - wxASSERT(ts != 0); - if (logThread) logThread->BreakRead(); - addLogFile(ts, skipFirst); - skipFirst = false; - - pos++; - } - } - } - } + pos++; + } + } + } + } } -void frmStatus::OnRefresh(wxCommandEvent& event) +void frmStatus::OnRefresh(wxCommandEvent &event) { - wxTimerEvent evt; + wxTimerEvent evt; - OnRefreshStatusTimer(evt); - OnRefreshLocksTimer(evt); - OnRefreshXactTimer(evt); - OnRefreshLogTimer(evt); - OnRefreshQuerystateTimer(evt); + OnRefreshStatusTimer(evt); + OnRefreshLocksTimer(evt); + OnRefreshXactTimer(evt); + OnRefreshLogTimer(evt); + OnRefreshQuerystateTimer(evt); } void frmStatus::checkConnection() { - if (connection) { - if (!locks_connection->IsAlive()) - { - locks_connection = connection; - } - if (!connection->IsAlive()) - { - if (locks_connection == connection) locks_connection = 0; - delete connection; - connection = 0; - statusTimer->Stop(); - locksTimer->Stop(); - if (xactTimer) - xactTimer->Stop(); - if (logTimer) - logTimer->Stop(); - if (querystateTimer) - querystateTimer->Stop(); - actionMenu->Enable(MNU_REFRESH, false); - toolBar->EnableTool(MNU_REFRESH, false); - statusBar->SetStatusText(_("Connection broken.")); - SetTitle(_("Connection broken.")); - } - } + if (connection) { + if (!locks_connection->IsAlive()) + { + locks_connection = connection; + } + if (!connection->IsAlive()) + { + if (locks_connection==connection) locks_connection = 0; + delete connection; + connection = 0; + statusTimer->Stop(); + locksTimer->Stop(); + if (xactTimer) + xactTimer->Stop(); + if (logTimer) + logTimer->Stop(); + if (querystateTimer) + querystateTimer->Stop(); + actionMenu->Enable(MNU_REFRESH, false); + toolBar->EnableTool(MNU_REFRESH, false); + statusBar->SetStatusText(_("Connection broken.")); + SetTitle(_("Connection broken.")); + } + } } -void frmStatus::addLogFile(wxDateTime* dt, bool skipFirst) +void frmStatus::addLogFile(wxDateTime *dt, bool skipFirst) { - pgSet* set; - if (settings->GetASUTPstyle()) { - wxString sql = "select current_setting('log_directory')||'/'||name filename,modification filetime,size len\n" - " FROM pg_ls_logdir() where name ~ '.csv' and modification >= '" + DateToAnsiStr(*dt) + "'::timestamp order by modification-'" + DateToAnsiStr(*dt) + "'::timestamp limit 1"; - set = connection->ExecuteSet(sql); - } - else - set = connection->ExecuteSet( - wxT("SELECT modification filetime, name filename, size AS len ") - wxT(" FROM pg_ls_logdir()") - wxT(" WHERE modification = '") + DateToAnsiStr(*dt) + wxT("'::timestamp"), false); - if (set) - { - logfileName = set->GetVal(wxT("filename")); - logfileTimestamp = set->GetDateTime(wxT("filetime")); - long len = set->GetLong(wxT("len")); - //if (logThread) logThread->BreakRead(); - logfileLength = 0; - addLogFile(logfileName, logfileTimestamp, len, logfileLength, skipFirst); + pgSet* set; + if (settings->GetASUTPstyle()) { + wxString sql = "select current_setting('log_directory')||'/'||name filename,modification filetime,size len\n" + " FROM pg_ls_logdir() where name ~ '.csv' and modification >= '" + DateToAnsiStr(*dt) + "'::timestamp order by modification-'" + DateToAnsiStr(*dt) + "'::timestamp limit 1"; + set = connection->ExecuteSet(sql); + } else + set = connection->ExecuteSet( + wxT("SELECT modification filetime, name filename, size AS len ") + wxT(" FROM pg_ls_logdir()") + wxT(" WHERE modification = '") + DateToAnsiStr(*dt) + wxT("'::timestamp"),false); + if (set) + { + logfileName = set->GetVal(wxT("filename")); + logfileTimestamp = set->GetDateTime(wxT("filetime")); + long len = set->GetLong(wxT("len")); + //if (logThread) logThread->BreakRead(); + logfileLength = 0; + addLogFile(logfileName, logfileTimestamp, len, logfileLength, skipFirst); - delete set; - } + delete set; + } } -void frmStatus::addLogFile(const wxString& filename, const wxDateTime timestamp, long len, long& read, bool skipFirst) +void frmStatus::addLogFile(const wxString &filename, const wxDateTime timestamp, long len, long &read, bool skipFirst) { - wxString line; + wxString line; - if (skipFirst) - { - long maxServerLogSize = settings->GetMaxServerLogSize(); + if (skipFirst) + { + long maxServerLogSize = settings->GetMaxServerLogSize(); - if (!logfileLength && maxServerLogSize && logfileLength > maxServerLogSize) - { - long maxServerLogSize = settings->GetMaxServerLogSize(); - len = read - maxServerLogSize; - } - else - skipFirst = false; - } + if (!logfileLength && maxServerLogSize && logfileLength > maxServerLogSize) + { + long maxServerLogSize = settings->GetMaxServerLogSize(); + len = read - maxServerLogSize; + } + else + skipFirst = false; + } - // If GPDB 3.3 and later, log is normally in CSV format. Let's get a whole log line before calling addLogLine, - // so we can do things smarter. + // If GPDB 3.3 and later, log is normally in CSV format. Let's get a whole log line before calling addLogLine, + // so we can do things smarter. - // PostgreSQL can log in CSV format, as well as regular format. Normally, we'd only see - // the regular format logs here, because pg_logdir_ls only returns those. But if pg_logdir_ls is - // changed to return the csv format log files, we should handle it. + // PostgreSQL can log in CSV format, as well as regular format. Normally, we'd only see + // the regular format logs here, because pg_logdir_ls only returns those. But if pg_logdir_ls is + // changed to return the csv format log files, we should handle it. - bool csv_log_format = filename.Right(4) == wxT(".csv"); - - if (csv_log_format && savedPartialLine.length() > 0) - { - if (read == 0) // Starting at beginning of log file - savedPartialLine.clear(); - else - line = savedPartialLine; - } - if (logThread) { - if (logThread->isReadyRows()) { - logThread->SetParameters(filename, len, read, savedPartialLine); - logThread->GoReadRows(); - return; - } - } - wxString funcname = "pg_read_binary_file("; - //if (!settings->GetASUTPstyle()) funcname = "pg_file_read("; - wxString msg = _("Reading log from server..."); - while (len > read) - { + bool csv_log_format = filename.Right(4) == wxT(".csv"); + + if (csv_log_format && savedPartialLine.length() > 0) + { + if (read == 0) // Starting at beginning of log file + savedPartialLine.clear(); + else + line = savedPartialLine; + } + if (logThread) { + if (logThread->isReadyRows()) { + logThread->SetParameters(filename,len,read,savedPartialLine); + logThread->GoReadRows(); + return; + } + } + wxString funcname = "pg_read_binary_file("; + //if (!settings->GetASUTPstyle()) funcname = "pg_file_read("; + wxString msg = _("Reading log from server..."); + while (len > read) + { #define PG_READ_BUFFER 500000 - float pr = 100.0 * read / len; - statusBar->SetStatusText(wxString::Format("%s %.2f MB (%.1f %%)", msg, len / 1048576.0, pr)); - wxString readsql = wxString::Format("select %s%s,%s, %d)", funcname, connection->qtDbString(filename), NumToStr(read), PG_READ_BUFFER); - pgSet* set = connection->ExecuteSet(readsql); - if (!set) - { - connection->IsAlive(); - return; - } - wxSafeYield(); - char* raw1 = set->GetCharPtr(0); + float pr = 100.0 * read / len; + statusBar->SetStatusText(wxString::Format("%s %.2f MB (%.1f %%)", msg, len / 1048576.0, pr)); + wxString readsql = wxString::Format("select %s%s,%s, %d)", funcname, connection->qtDbString(filename), NumToStr(read), PG_READ_BUFFER); + pgSet *set = connection->ExecuteSet(readsql); + if (!set) + { + connection->IsAlive(); + return; + } + wxSafeYield(); + char *raw1 = set->GetCharPtr(0); - if (!raw1 || !*raw1) - { - delete set; - break; - } - char* raw; - unsigned char m[PG_READ_BUFFER + 1]; - if (settings->GetASUTPstyle()) { - - raw = (char*)&m[0]; - unsigned char c; - unsigned char* startChar; - int pos = 0; - raw1 = raw1 + 2; - int utf8charLen = 0; - while (*raw1 != 0) { - c = *raw1; - c = c - '0'; - if (c > 9) c = *raw1 - 'a' + 10; - raw1++; - m[pos] = c << 4; - c = *raw1 - '0'; - if (c > 9) c = *raw1 - 'a' + 10; - c = c | m[pos]; - m[pos] = c; - // check utf-8 char - if (utf8charLen == 0) { - startChar = &m[pos]; - if (c >> 7 == 0) - utf8charLen = 1; - else if (c >> 5 == 0x6) - utf8charLen = 2; - else if (c >> 4 == 0xE) - utf8charLen = 3; - else if (c >> 5 == 0x1E) - utf8charLen = 4; - else - utf8charLen = 0; - // bad utf8 format - } - pos++; - raw1++; - utf8charLen--; - } - // - if (utf8charLen != 0) { - //read = startChar - &m[0]; - // remove bad utf-8 char - *startChar = 0; - } - else - m[pos] = 0; - } - else { - raw = raw1; - } - read += strlen(raw); - - wxString str; - str = line + wxTextBuffer::Translate(wxString(raw, set->GetConversion()), wxTextFileType_Unix); - //if (wxString(wxString(raw, wxConvLibc).wx_str(), wxConvUTF8).Len() > 0) - // str = line + wxString(wxString(raw, wxConvLibc).wx_str(), wxConvUTF8); - //else { - // str = line + wxTextBuffer::Translate(wxString(raw, set->GetConversion()), wxTextFileType_Unix); - //} + if (!raw1 || !*raw1) + { + delete set; + break; + } + char* raw; + unsigned char m[PG_READ_BUFFER + 1]; + if (settings->GetASUTPstyle()) { + + raw =( char *) &m[0]; + unsigned char c; + unsigned char* startChar; + int pos = 0; + raw1 = raw1 + 2; + int utf8charLen = 0; + while (*raw1!=0) { + c = *raw1; + c = c - '0'; + if (c > 9) c = *raw1 - 'a' + 10; + raw1++; + m[pos] = c << 4; + c = *raw1 - '0'; + if (c > 9) c = *raw1 - 'a' + 10; + c = c | m[pos]; + m[pos] = c; + // check utf-8 char + if (utf8charLen == 0) { + startChar = &m[pos]; + if(c >> 7 == 0) + utf8charLen = 1; + else if (c >> 5 == 0x6) + utf8charLen = 2; + else if (c >> 4 == 0xE) + utf8charLen = 3; + else if (c >> 5 == 0x1E) + utf8charLen = 4; + else + utf8charLen=0; + // bad utf8 format + } + pos++; + raw1++; + utf8charLen--; + } + // + if (utf8charLen != 0) { + //read = startChar - &m[0]; + // remove bad utf-8 char + *startChar = 0; + } else + m[pos] = 0; + } else { + raw = raw1; + } + read += strlen(raw); + wxString str; + str = line + wxTextBuffer::Translate(wxString(raw, set->GetConversion()), wxTextFileType_Unix); + //if (wxString(wxString(raw, wxConvLibc).wx_str(), wxConvUTF8).Len() > 0) + // str = line + wxString(wxString(raw, wxConvLibc).wx_str(), wxConvUTF8); + //else { + // str = line + wxTextBuffer::Translate(wxString(raw, set->GetConversion()), wxTextFileType_Unix); + //} + #undef PG_READ_BUFFER - delete set; + delete set; - if (str.Len() == 0) - { - wxString msgstr = _("The server log contains entries in multiple encodings and cannot be displayed by pgAdmin."); - wxMessageBox(msgstr); - return; - } + if (str.Len() == 0) + { + wxString msgstr = _("The server log contains entries in multiple encodings and cannot be displayed by pgAdmin."); + wxMessageBox(msgstr); + return; + } - if (csv_log_format) - { - // This will work for any DB using CSV format logs + if (csv_log_format) + { + // This will work for any DB using CSV format logs - if (logHasTimestamp) - { - // Right now, csv format logs from GPDB and PostgreSQL always start with a timestamp, so we count on that. + if (logHasTimestamp) + { + // Right now, csv format logs from GPDB and PostgreSQL always start with a timestamp, so we count on that. - // And the only reason we need to do that is to make sure we are in sync. + // And the only reason we need to do that is to make sure we are in sync. - // Bad things happen if we start in the middle of a - // double-quoted string, as we would never find a correct line terminator! + // Bad things happen if we start in the middle of a + // double-quoted string, as we would never find a correct line terminator! - // In CSV logs, the first field must be a Timestamp, so must start with "2009" or "201" or "202" (at least for the next 20 years). - if (str.length() > 4 && str.Left(4) != wxT("2009") && str.Left(3) != wxT("201") && str.Left(3) != wxT("202")) - { - wxLogNotice(wxT("Log line does not start with timestamp: %s \n"), str.Mid(0, 100).c_str()); - // Something isn't right, as we are not at the beginning of a csv log record. - // We should never get here, but if we do, try to handle it in a smart way. - str = str.Mid(str.Find(wxT("\n20")) + 1); // Try to re-sync. - } - } + // In CSV logs, the first field must be a Timestamp, so must start with "2009" or "201" or "202" (at least for the next 20 years). + if (str.length() > 4 && str.Left(4) != wxT("2009") && str.Left(3) != wxT("201") && str.Left(3) != wxT("202")) + { + wxLogNotice(wxT("Log line does not start with timestamp: %s \n"), str.Mid(0, 100).c_str()); + // Something isn't right, as we are not at the beginning of a csv log record. + // We should never get here, but if we do, try to handle it in a smart way. + str = str.Mid(str.Find(wxT("\n20")) + 1); // Try to re-sync. + } + } - CSVLineTokenizer tk(str); + CSVLineTokenizer tk(str); - logList->Freeze(); + logList->Freeze(); - while (tk.HasMoreLines()) - { - line.Clear(); + while (tk.HasMoreLines()) + { + line.Clear(); - bool partial; - str = tk.GetNextLine(partial); - if (partial) - { - line = str; // Start of a log line, but not complete. Loop back, Read more data. - break; - } + bool partial; + str = tk.GetNextLine(partial); + if (partial) + { + line = str; // Start of a log line, but not complete. Loop back, Read more data. + break; + } - // Some extra debug checking, assuming csv logs line start with timestamps. - // Not really necessary, but it is good for debugging if something isn't right. - if (logHasTimestamp) - { - // The first field must be a Timestamp, so must start with "2009" or "201" or "202" (at least for the next 20 years). - // This is just an extra check to make sure we haven't gotten out of sync with the log. - if (str.length() > 5 && str.Left(4) != wxT("2009") && str.Left(3) != wxT("201") && str.Left(3) != wxT("202")) - { - // BUG: We are out of sync on the log - wxLogNotice(wxT("Log line does not start with timestamp: %s\n"), str.c_str()); - } - else if (str.length() < 20) - { - // BUG: We are out of sync on the log, or the log is garbled - wxLogNotice(wxT("Log line too short: %s\n"), str.c_str()); - } - } + // Some extra debug checking, assuming csv logs line start with timestamps. + // Not really necessary, but it is good for debugging if something isn't right. + if (logHasTimestamp) + { + // The first field must be a Timestamp, so must start with "2009" or "201" or "202" (at least for the next 20 years). + // This is just an extra check to make sure we haven't gotten out of sync with the log. + if (str.length() > 5 && str.Left(4) != wxT("2009") && str.Left(3) != wxT("201") && str.Left(3) != wxT("202")) + { + // BUG: We are out of sync on the log + wxLogNotice(wxT("Log line does not start with timestamp: %s\n"), str.c_str()); + } + else if (str.length() < 20) + { + // BUG: We are out of sync on the log, or the log is garbled + wxLogNotice(wxT("Log line too short: %s\n"), str.c_str()); + } + } - // Looks like we have a good complete CSV log record. - addLogLine(str.Trim(), true, true); - } + // Looks like we have a good complete CSV log record. + addLogLine(str.Trim(), true, true); + } - logList->Thaw(); - } - else - { - // Non-csv format log file + logList->Thaw(); + } + else + { + // Non-csv format log file - bool hasCr = (str.Right(1) == wxT("\n")); + bool hasCr = (str.Right(1) == wxT("\n")); - wxStringTokenizer tk(str, wxT("\n")); + wxStringTokenizer tk(str, wxT("\n")); - logList->Freeze(); + logList->Freeze(); - while (tk.HasMoreTokens()) - { - str = tk.GetNextToken(); - if (skipFirst) - { - // could be truncated - skipFirst = false; - continue; - } + while (tk.HasMoreTokens()) + { + str = tk.GetNextToken(); + if (skipFirst) + { + // could be truncated + skipFirst = false; + continue; + } - if (tk.HasMoreTokens() || hasCr) - addLogLine(str.Trim()); - else - line = str; - } + if (tk.HasMoreTokens() || hasCr) + addLogLine(str.Trim()); + else + line = str; + } - logList->Thaw(); - } - } + logList->Thaw(); + } + } - savedPartialLine.clear(); + savedPartialLine.clear(); - if (!line.IsEmpty()) - { - // We finished reading to the end of the log file, but still have some data left - if (csv_log_format) - { - savedPartialLine = line; // Save partial log line for next read of the data file. - line.Clear(); - } - else - addLogLine(line.Trim()); - } + if (!line.IsEmpty()) + { + // We finished reading to the end of the log file, but still have some data left + if (csv_log_format) + { + savedPartialLine = line; // Save partial log line for next read of the data file. + line.Clear(); + } + else + addLogLine(line.Trim()); + } } -void frmStatus::addLogLine(const wxString& str, bool formatted, bool csv_log_format) +void frmStatus::addLogLine(const wxString &str, bool formatted, bool csv_log_format) { - int row = logList->GetItemCount(); + int row = logList->GetItemCount(); - int idxTimeStampCol = -1, idxLevelCol = -1; - int idxLogEntryCol = 0; + int idxTimeStampCol = -1, idxLevelCol = -1; + int idxLogEntryCol = 0; - if (logFormatKnown) - { - // Known Format first will be level, then Log entry - // idxLevelCol : 0, idxLogEntryCol : 1, idxTimeStampCol : -1 - idxLevelCol++; - idxLogEntryCol++; - if (logHasTimestamp) - { - // idxLevelCol : 1, idxLogEntryCol : 2, idxTimeStampCol : 0 - idxTimeStampCol++; - idxLevelCol++; - idxLogEntryCol++; - } - } + if (logFormatKnown) + { + // Known Format first will be level, then Log entry + // idxLevelCol : 0, idxLogEntryCol : 1, idxTimeStampCol : -1 + idxLevelCol++; + idxLogEntryCol++; + if (logHasTimestamp) + { + // idxLevelCol : 1, idxLogEntryCol : 2, idxTimeStampCol : 0 + idxTimeStampCol++; + idxLevelCol++; + idxLogEntryCol++; + } + } - if (!logFormatKnown) { - logList->AppendItem(-1, str); - int colorindex = nav->TryMarkItem(row, str); - if (colorindex >= 0) - logList->SetItemBackgroundColour(row, nav->GetColorByIndex(colorindex)); - else - logList->SetItemBackgroundColour(row, logcol[addodd % 2]); - } - else if ((!csv_log_format) && str.Find(':') < 0) - { - // Must be a continuation of a previous line. - logList->InsertItem(row, wxEmptyString, -1); - logList->SetItem(row, idxLogEntryCol, str); - } - else if (!formatted) - { - // Not from a log, from pgAdmin itself. - if (logHasTimestamp) - { - logList->InsertItem(row, wxEmptyString, -1); - logList->SetItem(row, idxLevelCol, str.BeforeFirst(':')); - } - else - { - logList->InsertItem(row, str.BeforeFirst(':'), -1); - } - logList->SetItem(row, idxLogEntryCol, str.AfterFirst(':')); - } - else // formatted log - { - if (csv_log_format) - { - // Log is in CSV format (GPDB 3.3 and later, or Postgres if only csv log enabled) - // In this case, we are always supposed to have a complete log line in csv format in str when called. + if (!logFormatKnown) { + logList->AppendItem(-1, str); + int colorindex = nav->TryMarkItem(row, str); + if (colorindex>=0) + logList->SetItemBackgroundColour(row, nav->GetColorByIndex(colorindex)); + else + logList->SetItemBackgroundColour(row, logcol[addodd % 2]); + } + else if ((!csv_log_format) && str.Find(':') < 0) + { + // Must be a continuation of a previous line. + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, idxLogEntryCol, str); + } + else if (!formatted) + { + // Not from a log, from pgAdmin itself. + if (logHasTimestamp) + { + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, idxLevelCol, str.BeforeFirst(':')); + } + else + { + logList->InsertItem(row, str.BeforeFirst(':'), -1); + } + logList->SetItem(row, idxLogEntryCol, str.AfterFirst(':')); + } + else // formatted log + { + if (csv_log_format) + { + // Log is in CSV format (GPDB 3.3 and later, or Postgres if only csv log enabled) + // In this case, we are always supposed to have a complete log line in csv format in str when called. - if (logHasTimestamp && (str.Length() < 20 || (logHasTimestamp && (str[0] != wxT('2') || str[1] != wxT('0'))))) - { - // Log line too short or does not start with an expected timestamp... - // Must be a continuation of the previous line or garbage, - // or we are out of sync in our CSV handling. - // We shouldn't ever get here. - logList->InsertItem(row, wxEmptyString, -1); - logList->SetItem(row, 2, str); - } - else - { - CSVTokenizer tk(str); + if (logHasTimestamp && (str.Length() < 20 || (logHasTimestamp && (str[0] != wxT('2') || str[1] != wxT('0'))))) + { + // Log line too short or does not start with an expected timestamp... + // Must be a continuation of the previous line or garbage, + // or we are out of sync in our CSV handling. + // We shouldn't ever get here. + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, 2, str); + } + else + { + CSVTokenizer tk(str); - bool gpdb = connection->GetIsGreenplum(); + bool gpdb = connection->GetIsGreenplum(); - // Get the fields from the CSV log. - wxString logTime = tk.GetNextToken(); - wxString logUser = tk.GetNextToken(); - wxString logDatabase = tk.GetNextToken(); - wxString logPid = tk.GetNextToken(); + // Get the fields from the CSV log. + wxString logTime = tk.GetNextToken(); + wxString logUser = tk.GetNextToken(); + wxString logDatabase = tk.GetNextToken(); + wxString logPid = tk.GetNextToken(); - wxString logSession; - wxString logCmdcount; - wxString logSegment; + wxString logSession; + wxString logCmdcount; + wxString logSegment; - if (gpdb) - { - wxString logThread = tk.GetNextToken(); // GPDB specific - wxString logHost = tk.GetNextToken(); - wxString logPort = tk.GetNextToken(); // GPDB (Postgres puts port with Host) - wxString logSessiontime = tk.GetNextToken(); - wxString logTransaction = tk.GetNextToken(); - logSession = tk.GetNextToken(); - logCmdcount = tk.GetNextToken(); - logSegment = tk.GetNextToken(); - wxString logSlice = tk.GetNextToken(); - wxString logDistxact = tk.GetNextToken(); - wxString logLocalxact = tk.GetNextToken(); - wxString logSubxact = tk.GetNextToken(); - } - else - { - wxString logHost = tk.GetNextToken(); // Postgres puts port with Hostname - logSession = tk.GetNextToken(); - wxString logLineNumber = tk.GetNextToken(); - wxString logPsDisplay = tk.GetNextToken(); - wxString logSessiontime = tk.GetNextToken(); - wxString logVXid = tk.GetNextToken(); - wxString logTransaction = tk.GetNextToken(); - } + if (gpdb) + { + wxString logThread = tk.GetNextToken(); // GPDB specific + wxString logHost = tk.GetNextToken(); + wxString logPort = tk.GetNextToken(); // GPDB (Postgres puts port with Host) + wxString logSessiontime = tk.GetNextToken(); + wxString logTransaction = tk.GetNextToken(); + logSession = tk.GetNextToken(); + logCmdcount = tk.GetNextToken(); + logSegment = tk.GetNextToken(); + wxString logSlice = tk.GetNextToken(); + wxString logDistxact = tk.GetNextToken(); + wxString logLocalxact = tk.GetNextToken(); + wxString logSubxact = tk.GetNextToken(); + } + else + { + wxString logHost = tk.GetNextToken(); // Postgres puts port with Hostname + logSession = tk.GetNextToken(); + wxString logLineNumber = tk.GetNextToken(); + wxString logPsDisplay = tk.GetNextToken(); + wxString logSessiontime = tk.GetNextToken(); + wxString logVXid = tk.GetNextToken(); + wxString logTransaction = tk.GetNextToken(); + } - wxString logSeverity = tk.GetNextToken(); - wxString logState = tk.GetNextToken(); - wxString logMessage = tk.GetNextToken(); - wxString logDetail = tk.GetNextToken(); - wxString logHint = tk.GetNextToken(); - wxString logQuery = tk.GetNextToken(); - wxString logQuerypos = tk.GetNextToken(); - wxString logContext = tk.GetNextToken(); - wxString logDebug = tk.GetNextToken(); - wxString logCursorpos = tk.GetNextToken(); + wxString logSeverity = tk.GetNextToken(); + wxString logState = tk.GetNextToken(); + wxString logMessage = tk.GetNextToken(); + wxString logDetail = tk.GetNextToken(); + wxString logHint = tk.GetNextToken(); + wxString logQuery = tk.GetNextToken(); + wxString logQuerypos = tk.GetNextToken(); + wxString logContext = tk.GetNextToken(); + wxString logDebug = tk.GetNextToken(); + wxString logCursorpos = tk.GetNextToken(); - wxString logStack; - if (gpdb) - { - wxString logFunction = tk.GetNextToken(); // GPDB. Postgres puts func, file, and line together - wxString logFile = tk.GetNextToken(); - wxString logLine = tk.GetNextToken(); - logStack = tk.GetNextToken(); // GPDB only. - } - else - wxString logFuncFileLine = tk.GetNextToken(); + wxString logStack; + if (gpdb) + { + wxString logFunction = tk.GetNextToken(); // GPDB. Postgres puts func, file, and line together + wxString logFile = tk.GetNextToken(); + wxString logLine = tk.GetNextToken(); + logStack = tk.GetNextToken(); // GPDB only. + } + else + wxString logFuncFileLine = tk.GetNextToken(); - logList->InsertItem(row, logTime, -1); // Insert timestamp (with time zone) + logList->InsertItem(row, logTime, -1); // Insert timestamp (with time zone) - logList->SetItem(row, 1, logSeverity); + logList->SetItem(row, 1, logSeverity); - // Display the logMessage, breaking it into lines - wxStringTokenizer lm(logMessage, wxT("\n")); - logList->SetItem(row, 2, lm.GetNextToken()); + // Display the logMessage, breaking it into lines + wxStringTokenizer lm(logMessage, wxT("\n")); + logList->SetItem(row, 2, lm.GetNextToken()); - logList->SetItem(row, 3, logSession); - logList->SetItem(row, 4, logCmdcount); - logList->SetItem(row, 5, logDatabase); - if ((!gpdb) || (logSegment.length() > 0 && logSegment != wxT("seg-1"))) - { - logList->SetItem(row, 6, logSegment); - } - else - { - // If we are reading the masterDB log only, the logSegment won't - // have anything useful in it. Look in the logMessage, and see if the - // segment info exists in there. It will always be at the end. - if (logMessage.length() > 0 && logMessage[logMessage.length() - 1] == wxT(')')) - { - int segpos = -1; - segpos = logMessage.Find(wxT("(seg")); - if (segpos <= 0) - segpos = logMessage.Find(wxT("(mir")); - if (segpos > 0) - { - logSegment = logMessage.Mid(segpos + 1); - if (logSegment.Find(wxT(' ')) > 0) - logSegment = logSegment.Mid(0, logSegment.Find(wxT(' '))); - logList->SetItem(row, 6, logSegment); - } - } - } + logList->SetItem(row, 3, logSession); + logList->SetItem(row, 4, logCmdcount); + logList->SetItem(row, 5, logDatabase); + if ((!gpdb) || (logSegment.length() > 0 && logSegment != wxT("seg-1"))) + { + logList->SetItem(row, 6, logSegment); + } + else + { + // If we are reading the masterDB log only, the logSegment won't + // have anything useful in it. Look in the logMessage, and see if the + // segment info exists in there. It will always be at the end. + if (logMessage.length() > 0 && logMessage[logMessage.length() - 1] == wxT(')')) + { + int segpos = -1; + segpos = logMessage.Find(wxT("(seg")); + if (segpos <= 0) + segpos = logMessage.Find(wxT("(mir")); + if (segpos > 0) + { + logSegment = logMessage.Mid(segpos + 1); + if (logSegment.Find(wxT(' ')) > 0) + logSegment = logSegment.Mid(0, logSegment.Find(wxT(' '))); + logList->SetItem(row, 6, logSegment); + } + } + } - // The rest of the lines from the logMessage - while (lm.HasMoreTokens()) - { - int controw = logList->GetItemCount(); - logList->InsertItem(controw, wxEmptyString, -1); - logList->SetItem(controw, 2, lm.GetNextToken()); - } + // The rest of the lines from the logMessage + while (lm.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, lm.GetNextToken()); + } - // Add the detail - wxStringTokenizer ld(logDetail, wxT("\n")); - while (ld.HasMoreTokens()) - { - int controw = logList->GetItemCount(); - logList->InsertItem(controw, wxEmptyString, -1); - logList->SetItem(controw, 2, ld.GetNextToken()); - } + // Add the detail + wxStringTokenizer ld(logDetail, wxT("\n")); + while (ld.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, ld.GetNextToken()); + } - // And the hint - wxStringTokenizer lh(logHint, wxT("\n")); - while (lh.HasMoreTokens()) - { - int controw = logList->GetItemCount(); - logList->InsertItem(controw, wxEmptyString, -1); - logList->SetItem(controw, 2, lh.GetNextToken()); - } + // And the hint + wxStringTokenizer lh(logHint, wxT("\n")); + while (lh.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, lh.GetNextToken()); + } - if (logDebug.length() > 0) - { - wxString logState3 = logState.Mid(0, 3); - if (logState3 == wxT("426") || logState3 == wxT("22P") || logState3 == wxT("427") - || logState3 == wxT("42P") || logState3 == wxT("458") - || logMessage.Mid(0, 9) == wxT("duration:") || logSeverity == wxT("FATAL") || logSeverity == wxT("PANIC")) - { - // If not redundant, add the statement from the debug_string - wxStringTokenizer lh(logDebug, wxT("\n")); - if (lh.HasMoreTokens()) - { - int controw = logList->GetItemCount(); - logList->InsertItem(controw, wxEmptyString, -1); - logList->SetItem(controw, 2, wxT("statement: ") + lh.GetNextToken()); - } - while (lh.HasMoreTokens()) - { - int controw = logList->GetItemCount(); - logList->InsertItem(controw, wxEmptyString, -1); - logList->SetItem(controw, 2, lh.GetNextToken()); - } - } - } + if (logDebug.length() > 0) + { + wxString logState3 = logState.Mid(0, 3); + if (logState3 == wxT("426") || logState3 == wxT("22P") || logState3 == wxT("427") + || logState3 == wxT("42P") || logState3 == wxT("458") + || logMessage.Mid(0, 9) == wxT("duration:") || logSeverity == wxT("FATAL") || logSeverity == wxT("PANIC")) + { + // If not redundant, add the statement from the debug_string + wxStringTokenizer lh(logDebug, wxT("\n")); + if (lh.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, wxT("statement: ") + lh.GetNextToken()); + } + while (lh.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, lh.GetNextToken()); + } + } + } - if (gpdb) - if (logSeverity == wxT("PANIC") || - (logSeverity == wxT("FATAL") && logState != wxT("57P03") && logState != wxT("53300"))) - { - // If this is a severe error, add the stack trace. - wxStringTokenizer ls(logStack, wxT("\n")); - if (ls.HasMoreTokens()) - { - int controw = logList->GetItemCount(); - logList->InsertItem(controw, wxEmptyString, -1); - logList->SetItem(controw, 1, wxT("STACK")); - logList->SetItem(controw, 2, ls.GetNextToken()); - } - while (ls.HasMoreTokens()) - { - int controw = logList->GetItemCount(); - logList->InsertItem(controw, wxEmptyString, -1); - logList->SetItem(controw, 2, ls.GetNextToken()); - } - } - } - } - else if (connection->GetIsGreenplum()) - { - // Greenplum 3.2 and before. log_line_prefix = "%m|%u|%d|%p|%I|%X|:-" + if (gpdb) + if (logSeverity == wxT("PANIC") || + (logSeverity == wxT("FATAL") && logState != wxT("57P03") && logState != wxT("53300"))) + { + // If this is a severe error, add the stack trace. + wxStringTokenizer ls(logStack, wxT("\n")); + if (ls.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 1, wxT("STACK")); + logList->SetItem(controw, 2, ls.GetNextToken()); + } + while (ls.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, ls.GetNextToken()); + } + } + } + } + else if (connection->GetIsGreenplum()) + { + // Greenplum 3.2 and before. log_line_prefix = "%m|%u|%d|%p|%I|%X|:-" - wxString logSeverity; - // Skip prefix, get message. In GPDB, always follows ":-". - wxString rest = str.Mid(str.Find(wxT(":-")) + 1); - if (rest.Length() > 0 && rest[0] == wxT('-')) - rest = rest.Mid(1); + wxString logSeverity; + // Skip prefix, get message. In GPDB, always follows ":-". + wxString rest = str.Mid(str.Find(wxT(":-")) + 1) ; + if (rest.Length() > 0 && rest[0] == wxT('-')) + rest = rest.Mid(1); - // Separate loglevel from message + // Separate loglevel from message - if (rest.Length() > 1 && rest[0] != wxT(' ') && rest.Find(':') > 0) - { - logSeverity = rest.BeforeFirst(':'); - rest = rest.AfterFirst(':').Mid(2); - } + if (rest.Length() > 1 && rest[0] != wxT(' ') && rest.Find(':') > 0) + { + logSeverity = rest.BeforeFirst(':'); + rest = rest.AfterFirst(':').Mid(2); + } - wxString ts = str.BeforeFirst(logFormat.c_str()[logFmtPos + 2]); - if (ts.Length() < 20 || (logHasTimestamp && (ts.Left(2) != wxT("20") || str.Find(':') < 0))) - { - // No Timestamp? Must be a continuation of a previous line? - // Not sure if it is possible to get here. - logList->InsertItem(row, wxEmptyString, -1); - logList->SetItem(row, 2, rest); - } - else if (logSeverity.Length() > 1) - { - // Normal case: Start of a new log record. - logList->InsertItem(row, ts, -1); - logList->SetItem(row, 1, logSeverity); - logList->SetItem(row, 2, rest); - } - else - { - // Continuation of previous line - logList->InsertItem(row, wxEmptyString, -1); - logList->SetItem(row, 2, rest); - } - } - else - { - // All Non-csv-format non-GPDB PostgreSQL systems. + wxString ts = str.BeforeFirst(logFormat.c_str()[logFmtPos + 2]); + if (ts.Length() < 20 || (logHasTimestamp && (ts.Left(2) != wxT("20") || str.Find(':') < 0))) + { + // No Timestamp? Must be a continuation of a previous line? + // Not sure if it is possible to get here. + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, 2, rest); + } + else if (logSeverity.Length() > 1) + { + // Normal case: Start of a new log record. + logList->InsertItem(row, ts, -1); + logList->SetItem(row, 1, logSeverity); + logList->SetItem(row, 2, rest); + } + else + { + // Continuation of previous line + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, 2, rest); + } + } + else + { + // All Non-csv-format non-GPDB PostgreSQL systems. - wxString rest; + wxString rest; - if (logHasTimestamp) - { - if (formatted) - { - rest = str.Mid(logFmtPos + 22).AfterFirst(':'); - wxString ts = str.Mid(logFmtPos, str.Length() - rest.Length() - logFmtPos - 1); + if (logHasTimestamp) + { + if (formatted) + { + rest = str.Mid(logFmtPos + 22).AfterFirst(':'); + wxString ts = str.Mid(logFmtPos, str.Length() - rest.Length() - logFmtPos - 1); - int pos = ts.Find(logFormat.c_str()[logFmtPos + 2], true); - logList->InsertItem(row, ts.Left(pos), -1); - logList->SetItem(row, idxLevelCol, ts.Mid(pos + logFormat.Length() - logFmtPos - 2)); - logList->SetItem(row, idxLogEntryCol, rest.Mid(2)); - } - else - { - logList->InsertItem(row, wxEmptyString, -1); - logList->SetItem(row, idxLevelCol, str.BeforeFirst(':')); - logList->SetItem(row, idxLogEntryCol, str.AfterFirst(':').Mid(2)); - } - } - else - { - if (formatted) - rest = str.Mid(logFormat.Length()); - else - rest = str; + int pos = ts.Find(logFormat.c_str()[logFmtPos + 2], true); + logList->InsertItem(row, ts.Left(pos), -1); + logList->SetItem(row, idxLevelCol, ts.Mid(pos + logFormat.Length() - logFmtPos - 2)); + logList->SetItem(row, idxLogEntryCol, rest.Mid(2)); + } + else + { + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, idxLevelCol, str.BeforeFirst(':')); + logList->SetItem(row, idxLogEntryCol, str.AfterFirst(':').Mid(2)); + } + } + else + { + if (formatted) + rest = str.Mid(logFormat.Length()); + else + rest = str; - int pos = rest.Find(':'); + int pos = rest.Find(':'); - if (pos < 0) { - logList->InsertItem(row, rest, -1); - } - else - { - logList->InsertItem(row, rest.BeforeFirst(':'), -1); - logList->SetItem(row, idxLogEntryCol, rest.AfterFirst(':').Mid(2)); - } - } - } - } + if (pos < 0) { + logList->InsertItem(row, rest, -1); + } + else + { + logList->InsertItem(row, rest.BeforeFirst(':'), -1); + logList->SetItem(row, idxLogEntryCol, rest.AfterFirst(':').Mid(2)); + } + } + } + } } void frmStatus::OnLogKeyUp(wxKeyEvent& event) { - if (currentPane == PANE_LOG) { - if (nav->RunKeyCommand(event)) return; - } - event.Skip(); + if (currentPane == PANE_LOG) { + if (nav->RunKeyCommand(event)) return; + } + event.Skip(); } void frmStatus::emptyLogfileCombo() { - if (cbLogfiles->GetCount()) // first entry has no client data - cbLogfiles->Delete(0); + if (cbLogfiles->GetCount()) // first entry has no client data + cbLogfiles->Delete(0); - while (cbLogfiles->GetCount()) - { - wxDateTime* dt = (wxDateTime*)cbLogfiles->wxItemContainer::GetClientData(0); - if (dt) - delete dt; - cbLogfiles->Delete(0); - } + while (cbLogfiles->GetCount()) + { + wxDateTime *dt = (wxDateTime *)cbLogfiles->wxItemContainer::GetClientData(0); + if (dt) + delete dt; + cbLogfiles->Delete(0); + } } int frmStatus::fillLogfileCombo() { - int count = cbLogfiles->GetCount(); - if (!count) - cbLogfiles->Append(_("Current log")); - else - count--; - pgSet* set; - if (settings->GetASUTPstyle()) - set = connection->ExecuteSet( - wxT("select name filename,modification filetime\n") - wxT(" FROM pg_ls_logdir() where name ~ '.csv'\n") - wxT(" ORDER BY modification DESC"), false); + int count = cbLogfiles->GetCount(); + if (!count) + cbLogfiles->Append(_("Current log")); + else + count--; + pgSet* set; + if (settings->GetASUTPstyle()) + set = connection->ExecuteSet( + wxT("select name filename,modification filetime\n") + wxT(" FROM pg_ls_logdir() where name ~ '.csv'\n") + wxT(" ORDER BY modification DESC"),false); - else set = connection->ExecuteSet( - wxT("SELECT name filename,modification filetime\n") - wxT(" FROM pg_ls_logdir()\n") - wxT(" ORDER BY filetime DESC"), false); + else set = connection->ExecuteSet( + wxT("SELECT name filename,modification filetime\n") + wxT(" FROM pg_ls_logdir()\n") + wxT(" ORDER BY filetime DESC"),false); - if (set) - { - if (set->NumRows() <= count) - { - delete set; - return 0; - } + if (set) + { + if (set->NumRows() <= count) + { + delete set; + return 0; + } - set->Locate(count + 1); - count = 0; + set->Locate(count + 1); + count = 0; - while (!set->Eof()) - { - count++; - wxString fn = set->GetVal(wxT("filename")); - wxDateTime ts = set->GetDateTime(wxT("filetime")); + while (!set->Eof()) + { + count++; + wxString fn = set->GetVal(wxT("filename")); + wxDateTime ts = set->GetDateTime(wxT("filetime")); - cbLogfiles->Append(DateToAnsiStr(ts), (void*)new wxDateTime(ts)); + cbLogfiles->Append(DateToAnsiStr(ts), (void *)new wxDateTime(ts)); - set->MoveNext(); - } + set->MoveNext(); + } - delete set; - } - if (count > 0) { - unsigned int i; - int maxWidth(0), width; - for (i = 0; i < cbLogfiles->GetCount(); i++) - { - cbLogfiles->GetTextExtent(cbLogfiles->GetString(i), &width, NULL); - if (width > maxWidth) - maxWidth = width; - } + delete set; + } + if (count > 0) { + unsigned int i; + int maxWidth(0), width; + for (i = 0; i < cbLogfiles->GetCount(); i++) + { + cbLogfiles->GetTextExtent(cbLogfiles->GetString(i), &width, NULL); + if (width > maxWidth) + maxWidth = width; + } - //cbLogfiles->SetMinSize(wxSize(maxWidth + 2, -1)); - //int sz = wxSystemSettings::GetMetric(wxSYS_VSCROLL_X, cbLogfiles); - int sz = 24; - cbLogfiles->SetSize(wxSize(maxWidth + sz, -1)); - toolBar->Realize(); - - wxSize newszT = toolBar->GetBestSize(); - manager.GetPane(wxT("toolBar")).BestSize(newszT); - //manager.GetPane(wxT("toolBar")).MinSize(newszT); - manager.Update(); - } - return count; + //cbLogfiles->SetMinSize(wxSize(maxWidth + 2, -1)); + //int sz = wxSystemSettings::GetMetric(wxSYS_VSCROLL_X, cbLogfiles); + int sz = 24; + cbLogfiles->SetSize(wxSize(maxWidth + sz, -1)); + toolBar->Realize(); + + wxSize newszT = toolBar->GetBestSize(); + manager.GetPane(wxT("toolBar")).BestSize(newszT); + //manager.GetPane(wxT("toolBar")).MinSize(newszT); + manager.Update(); + } + return count; } -void frmStatus::OnLoadLogfile(wxCommandEvent& event) +void frmStatus::OnLoadLogfile(wxCommandEvent &event) { - int pos = cbLogfiles->GetCurrentSelection(); - if (pos >= 0) - { - showCurrent = (pos == 0); - isCurrent = showCurrent || (pos == 1); + int pos = cbLogfiles->GetCurrentSelection(); + if (pos >= 0) + { + showCurrent = (pos == 0); + isCurrent = showCurrent || (pos == 1); - wxDateTime* ts = (wxDateTime*)cbLogfiles->wxItemContainer::GetClientData(showCurrent ? 1 : pos); - wxASSERT(ts != 0); + wxDateTime *ts = (wxDateTime *)cbLogfiles->wxItemContainer::GetClientData(showCurrent ? 1 : pos); + wxASSERT(ts != 0); - if (ts != NULL && (!logfileTimestamp.IsValid() || *ts != logfileTimestamp)) - { - if (logThread) logThread->BreakRead(); + if (ts != NULL && (!logfileTimestamp.IsValid() || *ts != logfileTimestamp)) + { + if (logThread) logThread->BreakRead(); - logList->DeleteAllItems(); - nav->ClearMark(); - //bgColor = wxColour("#afafaf"); - //bgColor = logList->GetBackgroundColour(); - addodd = 0; - addLogFile(ts, true); - nav->Refresh(); - } - } + logList->DeleteAllItems(); + nav->ClearMark(); + //bgColor = wxColour("#afafaf"); + //bgColor = logList->GetBackgroundColour(); + addodd = 0; + addLogFile(ts, true); + nav->Refresh(); + } + } } ReadLogThread::~ReadLogThread() { - //s_CloseLog.Post(); - ((frmStatus *) theParent)->logThread = NULL; + //s_CloseLog.Post(); + ((frmStatus *) theParent)->logThread = NULL; } void ReadLogThread::BreakRead() { - if (!isReadyRows()) { - m_break = true; - while (!isReadyRows()) { - wxMilliSleep(20); - } - } - log_queue->Clear(); + if (!isReadyRows()) { + m_break = true; + while (!isReadyRows()) { + wxMilliSleep(20); + } + } + log_queue->Clear(); } void ReadLogThread::DoTerminate() { - m_exit = true; - if (isReadyRows()) { - s_goReadLog.Post(); - } - return; + m_exit = true; + if (isReadyRows()) { + s_goReadLog.Post(); + } + return; } void* ReadLogThread::Entry() { - int size_rows = 0; - while (!m_exit) - { - { - wxMutexLocker lock(s_mutexDBLogReading); - //s_mutexDBLogReading.Lock(); - //rows.clear(); - getFilename(); - } - if (m_exit) break; - s_goReadLog.Wait(); - } - return NULL; + int size_rows = 0; + while (!m_exit) + { + { + wxMutexLocker lock(s_mutexDBLogReading); + //s_mutexDBLogReading.Lock(); + //rows.clear(); + getFilename(); + } + if (m_exit) break; + s_goReadLog.Wait(); + } + return NULL; } void ReadLogThread::getFilename() { - pgSet* set; - if (logfileName.length() == 0) return; - if (m_exit || m_break) return; - if (!conn->IsAlive()) { - wxDateTime n = wxDateTime::Now(); - if (!nextrun.IsValid() || nextrun < n) { - if (!conn->Reconnect(false)) - { - wxTimeSpan sp(0, 2); - nextrun = wxDateTime::Now() + sp; - } - } - return; - } - readLogFile(logfileName, len, logfileLength, savedPartialLine); - - //if (namepage.IsEmpty()) namepage = "not connect"; - //if (m_notebook->GetPageText(0) != namepage) m_notebook->SetPageText(0, namepage); + pgSet* set; + if (logfileName.length() == 0) return; + if (m_exit || m_break) return; + if (!conn->IsAlive()) { + wxDateTime n = wxDateTime::Now(); + if (!nextrun.IsValid() || nextrun < n) { + if (!conn->Reconnect(false)) + { + wxTimeSpan sp(0, 2); + nextrun = wxDateTime::Now() + sp; + } + } + return; + } + readLogFile(logfileName, len, logfileLength, savedPartialLine); + + //if (namepage.IsEmpty()) namepage = "not connect"; + //if (m_notebook->GetPageText(0) != namepage) m_notebook->SetPageText(0, namepage); } void ReadLogThread::readLogFile(wxString logfileName, long& lenfile, long& logfileLength, wxString& savedPartialLine) { - wxString line; + wxString line; - // If GPDB 3.3 and later, log is normally in CSV format. Let's get a whole log line before calling addLogLine, - // so we can do things smarter. + // If GPDB 3.3 and later, log is normally in CSV format. Let's get a whole log line before calling addLogLine, + // so we can do things smarter. - // PostgreSQL can log in CSV format, as well as regular format. Normally, we'd only see - // the regular format logs here, because pg_logdir_ls only returns those. But if pg_logdir_ls is - // changed to return the csv format log files, we should handle it. + // PostgreSQL can log in CSV format, as well as regular format. Normally, we'd only see + // the regular format logs here, because pg_logdir_ls only returns those. But if pg_logdir_ls is + // changed to return the csv format log files, we should handle it. - bool csv_log_format = logfileName.Right(4) == wxT(".csv"); - if (csv_log_format && savedPartialLine.length() > 0) - { - if (logfileLength == 0) // Starting at beginning of log file - savedPartialLine.clear(); - line = savedPartialLine; - } - wxString funcname = "pg_read_binary_file("; - int countLine = 0; - long logf = logfileLength; - while (lenfile > logfileLength) - { - //statusBar->SetStatusText(_("Reading log from server...")); - if (m_exit) return; + bool csv_log_format = logfileName.Right(4) == wxT(".csv"); + if (csv_log_format && savedPartialLine.length() > 0) + { + if (logfileLength == 0) // Starting at beginning of log file + savedPartialLine.clear(); + line = savedPartialLine; + } + wxString funcname = "pg_read_binary_file("; + int countLine = 0; + long logf = logfileLength; + while (lenfile > logfileLength) + { + //statusBar->SetStatusText(_("Reading log from server...")); + if (m_exit) return; #define PG_READ_BUFFER 500000 - wxString readsql = wxString::Format("select %s%s,%s, %d,true)", funcname, conn->qtDbString(logfileName), NumToStr(logfileLength), PG_READ_BUFFER); - pgSet* set = conn->ExecuteSet(readsql, false); - if (!set) - { - conn->IsAlive(); - return; - } - if (set->NumRows() == 0 || set->NumCols() == 0 || set->GetVal(0).IsNull()) { - delete set; - break; - } - char* raw1 = set->GetCharPtr(0); - if (!raw1 || !*raw1) - { - delete set; - break; - } - char* rawbuff; - char m[PG_READ_BUFFER + 1]; - if (true) { + wxString readsql = wxString::Format("select %s%s,%s, %d,true)", funcname, conn->qtDbString(logfileName), NumToStr(logfileLength), PG_READ_BUFFER); + pgSet* set = conn->ExecuteSet(readsql,false); + if (!set) + { + conn->IsAlive(); + return; + } + if (set->NumRows() == 0 || set->NumCols() ==0 || set->GetVal(0).IsNull()) { + delete set; + break; + } + char* raw1 = set->GetCharPtr(0); + if (!raw1 || !*raw1) + { + delete set; + break; + } + char* rawbuff; + char m[PG_READ_BUFFER + 1]; + if (true) { - rawbuff = &m[0]; - unsigned char c; - unsigned char* startChar; - unsigned char* startLine = (unsigned char*)&m[0]; - int pos = 0; - raw1 = raw1 + 2; // bytea data \x01cf23 .... - int utf8charLen = 0; - unsigned int unichar = 0; - unsigned int unicharcurrent = 0; - int shift; - while (*raw1 != 0) { - if (m_exit) return; - if (m_break) { - log_queue->Clear(); - return; - } - c = *raw1; - c = c - '0'; - if (c > 9) c = *raw1 - 'a' + 10; - raw1++; - m[pos] = c << 4; - c = *raw1 - '0'; - if (c > 9) c = *raw1 - 'a' + 10; - c = c | m[pos]; // hex string -> byte - m[pos] = c; - // check utf-8 char - if (utf8charLen == 0) { - startChar = (unsigned char*)&m[pos]; + rawbuff = &m[0]; + unsigned char c; + unsigned char* startChar; + unsigned char* startLine= (unsigned char*)&m[0]; + int pos = 0; + raw1 = raw1 + 2; // bytea data \x01cf23 .... + int utf8charLen = 0; + unsigned int unichar = 0; + unsigned int unicharcurrent = 0; + int shift; + while (*raw1 != 0) { + if (m_exit) return; + if (m_break) { + log_queue->Clear(); + return; + } + c = *raw1; + c = c - '0'; + if (c > 9) c = *raw1 - 'a' + 10; + raw1++; + m[pos] = c << 4; + c = *raw1 - '0'; + if (c > 9) c = *raw1 - 'a' + 10; + c = c | m[pos]; // hex string -> byte + m[pos] = c; + // check utf-8 char + if (utf8charLen == 0) { + startChar = (unsigned char*) &m[pos]; - if (c >> 7 == 0) - utf8charLen = 1; - else if (c >> 5 == 0x6) - utf8charLen = 2; - else if (c >> 4 == 0xE) - utf8charLen = 3; - else if (c >> 5 == 0x1E) - utf8charLen = 4; - else - utf8charLen = 0; - // bad utf8 format - shift = 0; - unichar = c; - } - unicharcurrent = c << shift; - shift += 8; - unichar = unichar | unicharcurrent; - pos++; - raw1++; - utf8charLen--; - if (utf8charLen == 0) { - // utf-8 char complite - if (unichar == '\"' && csv_log_format) - inquote = !inquote; - //wxString linebuff(startChar, lencsvstr); - if (unichar == '\n' && !inquote) { - // end line - size_t lencsvstr = (unsigned char*)&m[pos] - startLine; - wxString linebuff(startLine, set->GetConversion(), lencsvstr); // include '\n' - if (line.length() > 0) { - linebuff = line + linebuff; - line.clear(); - } - startLine = (unsigned char*)&m[pos]; - //rows.push_back(linebuff.Trim()); - log_queue->Post(linebuff.Trim()); - countLine++; - } + if (c >> 7 == 0) + utf8charLen = 1; + else if (c >> 5 == 0x6) + utf8charLen = 2; + else if (c >> 4 == 0xE) + utf8charLen = 3; + else if (c >> 5 == 0x1E) + utf8charLen = 4; + else + utf8charLen = 0; + // bad utf8 format + shift = 0; + unichar = c; + } + unicharcurrent = c << shift; + shift += 8; + unichar = unichar | unicharcurrent; + pos++; + raw1++; + utf8charLen--; + if (utf8charLen == 0) { + // utf-8 char complite + if (unichar == '\"' && csv_log_format) + inquote = !inquote; + //wxString linebuff(startChar, lencsvstr); + if (unichar == '\n' && !inquote) { + // end line + size_t lencsvstr = (unsigned char*)&m[pos] - startLine; + wxString linebuff(startLine, set->GetConversion(),lencsvstr); // include '\n' + if (line.length() > 0) { + linebuff = line + linebuff; + line.clear(); + } + startLine = (unsigned char*)&m[pos]; + //rows.push_back(linebuff.Trim()); + log_queue->Post(linebuff.Trim()); + countLine++; + } - } - } - // - m[pos] = 0; - if (utf8charLen != 0) { - //read = startChar - &m[0]; - // remove bad utf-8 char - *startChar = 0; - pos = startChar - (unsigned char*)&m[0]; - // start position bad utf-8 char - } - else - m[pos] = 0; - if (startLine != (unsigned char*)&m[pos]) { - // partial line - size_t lencsvstr = (unsigned char*)&m[pos] - startLine; - wxString linebuff(startLine, lencsvstr); // include '\n' - if (line.length() > 0) { - linebuff = line + linebuff; - line.clear(); - } - line = linebuff; - } - } - else { - rawbuff = raw1; - } - int l = strlen(rawbuff); - logfileLength += l; - //status->SetLabelText(wxString::Format("%s Load bytes %ld", host, logfileLength)); - - wxString str; - //str = line + wxTextBuffer::Translate(wxString(rawbuff, set->GetConversion()), wxTextFileType_Unix); - sendText(wxString::Format("@Load log line %d ...", countLine)); + } + } + // + m[pos] = 0; + if (utf8charLen != 0) { + //read = startChar - &m[0]; + // remove bad utf-8 char + *startChar = 0; + pos = startChar- (unsigned char*)&m[0]; + // start position bad utf-8 char + } else + m[pos] = 0; + if (startLine != (unsigned char*)&m[pos]) { + // partial line + size_t lencsvstr = (unsigned char*)&m[pos] - startLine; + wxString linebuff(startLine, lencsvstr); // include '\n' + if (line.length() > 0) { + linebuff = line + linebuff; + line.clear(); + } + line = linebuff; + } + } + else { + rawbuff = raw1; + } + int l = strlen(rawbuff); + logfileLength += l; + //status->SetLabelText(wxString::Format("%s Load bytes %ld", host, logfileLength)); + + wxString str; + //str = line + wxTextBuffer::Translate(wxString(rawbuff, set->GetConversion()), wxTextFileType_Unix); + sendText(wxString::Format("@Load log line %d ...", countLine)); #undef PG_READ_BUFFER - delete set; + delete set; - if (countLine == 0) - { - wxString msgstr = "@ The server log contains entries in multiple encodings and cannot be displayed by pgAdmin."; - //wxMessageBox(msgstr); - sendText(msgstr); - return; - } + if (countLine == 0) + { + wxString msgstr = "@ The server log contains entries in multiple encodings and cannot be displayed by pgAdmin."; + //wxMessageBox(msgstr); + sendText(msgstr); + return; + } - } + } - savedPartialLine.clear(); + savedPartialLine.clear(); - if (!line.IsEmpty()) - { - // We finished reading to the end of the log file, but still have some data left - if (csv_log_format) - { - savedPartialLine = line; // Save partial log line for next read of the data file. - line.Clear(); - } - else - //my_view->AddRow(line.Trim()); - log_queue->Post(line.Trim()); - //rows.push_back(line.Trim()); + if (!line.IsEmpty()) + { + // We finished reading to the end of the log file, but still have some data left + if (csv_log_format) + { + savedPartialLine = line; // Save partial log line for next read of the data file. + line.Clear(); + } + else + //my_view->AddRow(line.Trim()); + log_queue->Post(line.Trim()); + //rows.push_back(line.Trim()); - } - if (logf == 0) sendText(wxString::Format("Done %d", countLine)); + } + if (logf==0) sendText(wxString::Format("Done %d", countLine)); } void frmStatus::OnAddLabelTextThread(wxThreadEvent& event) { - wxString s = event.GetString(); - if (s[0] == '@') { - s = s.substr(1); - statusBar->SetStatusText(s); - return; - } - { - wxTimerEvent event; - OnRefreshLogTimer(event); - } - + wxString s = event.GetString(); + if (s[0] == '@') { + s = s.substr(1); + statusBar->SetStatusText(s); + return; + } + { + wxTimerEvent event; + OnRefreshLogTimer(event); + } + } /////////////////////////////// -void frmStatus::OnRotateLogfile(wxCommandEvent& event) +void frmStatus::OnRotateLogfile(wxCommandEvent &event) { - if (wxMessageBox(_("Are you sure the logfile should be rotated?"), _("Logfile rotation"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxYES) - connection->ExecuteVoid(wxT("select pg_logfile_rotate()")); + if (wxMessageBox(_("Are you sure the logfile should be rotated?"), _("Logfile rotation"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxYES) + connection->ExecuteVoid(wxT("select pg_logfile_rotate()")); } -void frmStatus::OnCancelBtn(wxCommandEvent& event) +void frmStatus::OnCancelBtn(wxCommandEvent &event) { - switch (currentPane) - { - case PANE_STATUS: - OnStatusCancelBtn(event); - break; - case PANE_LOCKS: - OnLocksCancelBtn(event); - break; - default: - // This shouldn't happen. If it does, it's no big deal - break; - } + switch(currentPane) + { + case PANE_STATUS: + OnStatusCancelBtn(event); + break; + case PANE_LOCKS: + OnLocksCancelBtn(event); + break; + default: + // This shouldn't happen. If it does, it's no big deal + break; + } } -void frmStatus::OnStatusCancelBtn(wxCommandEvent& event) +void frmStatus::OnStatusCancelBtn(wxCommandEvent &event) { - long item = statusList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (item < 0) - return; + long item = statusList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; - if (wxMessageBox(_("Are you sure you wish to cancel the selected query(s)?"), _("Cancel query?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) - return; + if (wxMessageBox(_("Are you sure you wish to cancel the selected query(s)?"), _("Cancel query?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; - while (item >= 0) - { - wxString pid = statusList->GetItemText(item); - wxString sql = wxT("SELECT pg_cancel_backend(") + pid + wxT(");"); - connection->ExecuteScalar(sql); + while (item >= 0) + { + wxString pid = statusList->GetItemText(item); + wxString sql = wxT("SELECT pg_cancel_backend(") + pid + wxT(");"); + connection->ExecuteScalar(sql); - item = statusList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - } + item = statusList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } - wxMessageBox(_("A cancel signal was sent to the selected server process(es)."), _("Cancel query"), wxOK | wxICON_INFORMATION); - OnRefresh(event); - wxListEvent ev; - OnSelStatusItem(ev); + wxMessageBox(_("A cancel signal was sent to the selected server process(es)."), _("Cancel query"), wxOK | wxICON_INFORMATION); + OnRefresh(event); + wxListEvent ev; + OnSelStatusItem(ev); } -void frmStatus::OnLocksCancelBtn(wxCommandEvent& event) +void frmStatus::OnLocksCancelBtn(wxCommandEvent &event) { - long item = lockList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (item < 0) - return; + long item = lockList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; - if (wxMessageBox(_("Are you sure you wish to cancel the selected query(s)?"), _("Cancel query?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) - return; + if (wxMessageBox(_("Are you sure you wish to cancel the selected query(s)?"), _("Cancel query?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; - while (item >= 0) - { - wxString pid = lockList->GetItemText(item); - wxString sql = wxT("SELECT pg_cancel_backend(") + pid + wxT(");"); - connection->ExecuteScalar(sql); + while (item >= 0) + { + wxString pid = lockList->GetItemText(item); + wxString sql = wxT("SELECT pg_cancel_backend(") + pid + wxT(");"); + connection->ExecuteScalar(sql); - item = lockList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - } + item = lockList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } - wxMessageBox(_("A cancel signal was sent to the selected server process(es)."), _("Cancel query"), wxOK | wxICON_INFORMATION); - OnRefresh(event); - wxListEvent ev; - OnSelLockItem(ev); + wxMessageBox(_("A cancel signal was sent to the selected server process(es)."), _("Cancel query"), wxOK | wxICON_INFORMATION); + OnRefresh(event); + wxListEvent ev; + OnSelLockItem(ev); } -void frmStatus::OnTerminateBtn(wxCommandEvent& event) +void frmStatus::OnTerminateBtn(wxCommandEvent &event) { - switch (currentPane) - { - case PANE_STATUS: - OnStatusTerminateBtn(event); - break; - case PANE_LOCKS: - OnLocksTerminateBtn(event); - break; - default: - // This shouldn't happen. If it does, it's no big deal - break; - } + switch(currentPane) + { + case PANE_STATUS: + OnStatusTerminateBtn(event); + break; + case PANE_LOCKS: + OnLocksTerminateBtn(event); + break; + default: + // This shouldn't happen. If it does, it's no big deal + break; + } } -void frmStatus::OnStatusTerminateBtn(wxCommandEvent& event) +void frmStatus::OnStatusTerminateBtn(wxCommandEvent &event) { - long item = statusList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (item < 0) - return; + long item = statusList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; - if (wxMessageBox(_("Are you sure you wish to terminate the selected server process(es)?"), _("Terminate process?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) - return; + if (wxMessageBox(_("Are you sure you wish to terminate the selected server process(es)?"), _("Terminate process?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; - while (item >= 0) - { - wxString pid = statusList->GetItemText(item); - wxString sql = wxT("SELECT pg_terminate_backend(") + pid + wxT(");"); - connection->ExecuteScalar(sql); + while (item >= 0) + { + wxString pid = statusList->GetItemText(item); + wxString sql = wxT("SELECT pg_terminate_backend(") + pid + wxT(");"); + connection->ExecuteScalar(sql); - item = statusList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - } + item = statusList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } - wxMessageBox(_("A terminate signal was sent to the selected server process(es)."), _("Terminate process"), wxOK | wxICON_INFORMATION); - OnRefresh(event); - wxListEvent ev; - OnSelStatusItem(ev); + wxMessageBox(_("A terminate signal was sent to the selected server process(es)."), _("Terminate process"), wxOK | wxICON_INFORMATION); + OnRefresh(event); + wxListEvent ev; + OnSelStatusItem(ev); } -void frmStatus::OnLocksTerminateBtn(wxCommandEvent& event) +void frmStatus::OnLocksTerminateBtn(wxCommandEvent &event) { - long item = lockList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (item < 0) - return; + long item = lockList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; - if (wxMessageBox(_("Are you sure you wish to terminate the selected server process(es)?"), _("Terminate process?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) - return; + if (wxMessageBox(_("Are you sure you wish to terminate the selected server process(es)?"), _("Terminate process?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; - while (item >= 0) - { - wxString pid = lockList->GetItemText(item); - wxString sql = wxT("SELECT pg_terminate_backend(") + pid + wxT(");"); - connection->ExecuteScalar(sql); + while (item >= 0) + { + wxString pid = lockList->GetItemText(item); + wxString sql = wxT("SELECT pg_terminate_backend(") + pid + wxT(");"); + connection->ExecuteScalar(sql); - item = lockList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - } + item = lockList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } - wxMessageBox(_("A terminate signal was sent to the selected server process(es)."), _("Terminate process"), wxOK | wxICON_INFORMATION); - OnRefresh(event); - wxListEvent ev; - OnSelLockItem(ev); + wxMessageBox(_("A terminate signal was sent to the selected server process(es)."), _("Terminate process"), wxOK | wxICON_INFORMATION); + OnRefresh(event); + wxListEvent ev; + OnSelLockItem(ev); } -void frmStatus::OnStatusMenu(wxCommandEvent& event) +void frmStatus::OnStatusMenu(wxCommandEvent &event) { - wxListItem column; - column.SetMask(wxLIST_MASK_TEXT); + wxListItem column; + column.SetMask(wxLIST_MASK_TEXT); - for (unsigned int i = 0; i < statusPopupMenu->GetMenuItemCount(); i++) - { - // Save column's width in a variable so that we can restore the old width - // if we make this column "invisible" - int currwidth= statusList->GetColumnWidth(i); - if (statusList->GetColumnWidth(i) > 0) - statusColWidth[i] = statusList->GetColumnWidth(i); + for (unsigned int i = 0; i < statusPopupMenu->GetMenuItemCount(); i++) + { + // Save column's width in a variable so that we can restore the old width + // if we make this column "invisible" + int currwidth= statusList->GetColumnWidth(i); + if (statusList->GetColumnWidth(i) > 0) + statusColWidth[i] = statusList->GetColumnWidth(i); - wxMenuItem* menu = statusPopupMenu->FindItemByPosition(i); - if (menu && menu->IsChecked()) - statusList->SetColumnWidth(i, statusColWidth[i]); - else if (statusList->GetColumnWidth(i) > 0) - statusList->SetColumnWidth(i, 0); + wxMenuItem *menu = statusPopupMenu->FindItemByPosition(i); + if (menu && menu->IsChecked()) + statusList->SetColumnWidth(i, statusColWidth[i]); + else if (statusList->GetColumnWidth(i) > 0) + statusList->SetColumnWidth(i, 0); - // Save current width to restore it at next launch - statusList->GetColumn(i, column); - if (currwidth > 0) - settings->WriteInt(wxT("frmStatus/StatusPane_") + column.GetText() + wxT("_Width"), - statusColWidth[i]); - else - settings->WriteInt(wxT("frmStatus/StatusPane_") + column.GetText() + wxT("_Width"), - -statusColWidth[i]); - } + // Save current width to restore it at next launch + statusList->GetColumn(i, column); + if (currwidth > 0) + settings->WriteInt(wxT("frmStatus/StatusPane_") + column.GetText() + wxT("_Width"), + statusColWidth[i]); + else + settings->WriteInt(wxT("frmStatus/StatusPane_") + column.GetText() + wxT("_Width"), + -statusColWidth[i]); + } } -void frmStatus::OnLockMenu(wxCommandEvent& event) +void frmStatus::OnLockMenu(wxCommandEvent &event) { - wxListItem column; - column.SetMask(wxLIST_MASK_TEXT); + wxListItem column; + column.SetMask(wxLIST_MASK_TEXT); - for (unsigned int i = 0; i < lockPopupMenu->GetMenuItemCount(); i++) - { - // Save column's width in a variable so that we can restore the old width - // if we make this column "invisible" - int currwidth = lockList->GetColumnWidth(i); - if (lockList->GetColumnWidth(i) > 0) - lockColWidth[i] = lockList->GetColumnWidth(i); + for (unsigned int i = 0; i < lockPopupMenu->GetMenuItemCount(); i++) + { + // Save column's width in a variable so that we can restore the old width + // if we make this column "invisible" + int currwidth = lockList->GetColumnWidth(i); + if (lockList->GetColumnWidth(i) > 0) + lockColWidth[i] = lockList->GetColumnWidth(i); - wxMenuItem* menu = lockPopupMenu->FindItemByPosition(i); - if (menu && menu->IsChecked()) - lockList->SetColumnWidth(i, lockColWidth[i]); - else if (lockList->GetColumnWidth(i) > 0) - lockList->SetColumnWidth(i, 0); + wxMenuItem *menu = lockPopupMenu->FindItemByPosition(i); + if (menu && menu->IsChecked()) + lockList->SetColumnWidth(i, lockColWidth[i]); + else if (lockList->GetColumnWidth(i) > 0) + lockList->SetColumnWidth(i, 0); - // Save current width to restore it at next launch - lockList->GetColumn(i, column); - if (currwidth > 0) - settings->WriteInt(wxT("frmStatus/LockPane_") + column.GetText() + wxT("_Width"), - lockColWidth[i]); - else - settings->WriteInt(wxT("frmStatus/LockPane_") + column.GetText() + wxT("_Width"), - -lockColWidth[i]); - } + // Save current width to restore it at next launch + lockList->GetColumn(i, column); + if (currwidth > 0) + settings->WriteInt(wxT("frmStatus/LockPane_") + column.GetText() + wxT("_Width"), + lockColWidth[i]); + else + settings->WriteInt(wxT("frmStatus/LockPane_") + column.GetText() + wxT("_Width"), + -lockColWidth[i]); + } } -void frmStatus::OnXactMenu(wxCommandEvent& event) +void frmStatus::OnXactMenu(wxCommandEvent &event) { - wxListItem column; - column.SetMask(wxLIST_MASK_TEXT); + wxListItem column; + column.SetMask(wxLIST_MASK_TEXT); - for (unsigned int i = 0; i < xactPopupMenu->GetMenuItemCount(); i++) - { - // Save column's width in a variable so that we can restore the old width - // if we make this column "invisible" - int currwidth = xactList->GetColumnWidth(i); - if (xactList->GetColumnWidth(i) > 0) - xactColWidth[i] = xactList->GetColumnWidth(i); + for (unsigned int i = 0; i < xactPopupMenu->GetMenuItemCount(); i++) + { + // Save column's width in a variable so that we can restore the old width + // if we make this column "invisible" + int currwidth = xactList->GetColumnWidth(i); + if (xactList->GetColumnWidth(i) > 0) + xactColWidth[i] = xactList->GetColumnWidth(i); - wxMenuItem* menu = xactPopupMenu->FindItemByPosition(i); - if (menu && menu->IsChecked()) - xactList->SetColumnWidth(i, xactColWidth[i]); - else if (xactList->GetColumnWidth(i) > 0) - xactList->SetColumnWidth(i, 0); + wxMenuItem *menu = xactPopupMenu->FindItemByPosition(i); + if (menu && menu->IsChecked()) + xactList->SetColumnWidth(i, xactColWidth[i]); + else if (xactList->GetColumnWidth(i) > 0) + xactList->SetColumnWidth(i, 0); - // Save current width to restore it at next launch - xactList->GetColumn(i, column); - if (currwidth > 0) - settings->WriteInt(wxT("frmStatus/XactPane_") + column.GetText() + wxT("_Width"), - xactColWidth[i]); - else - settings->WriteInt(wxT("frmStatus/XactPane_") + column.GetText() + wxT("_Width"), - -xactColWidth[i]); - } + // Save current width to restore it at next launch + xactList->GetColumn(i, column); + if (currwidth > 0) + settings->WriteInt(wxT("frmStatus/XactPane_") + column.GetText() + wxT("_Width"), + xactColWidth[i]); + else + settings->WriteInt(wxT("frmStatus/XactPane_") + column.GetText() + wxT("_Width"), + -xactColWidth[i]); + } } -void frmStatus::OnQuerystateMenu(wxCommandEvent& event) +void frmStatus::OnQuerystateMenu(wxCommandEvent &event) { - wxListItem column; - column.SetMask(wxLIST_MASK_TEXT); + wxListItem column; + column.SetMask(wxLIST_MASK_TEXT); - for (unsigned int i = 0; i < querystatePopupMenu->GetMenuItemCount(); i++) - { - // Save column's width in a variable so that we can restore the old width - // if we make this column "invisible" - int currwidth=querystateList->GetColumnWidth(i); - if (querystateList->GetColumnWidth(i) > 0) - querystateColWidth[i] = querystateList->GetColumnWidth(i); + for (unsigned int i = 0; i < querystatePopupMenu->GetMenuItemCount(); i++) + { + // Save column's width in a variable so that we can restore the old width + // if we make this column "invisible" + int currwidth=querystateList->GetColumnWidth(i); + if (querystateList->GetColumnWidth(i) > 0) + querystateColWidth[i] = querystateList->GetColumnWidth(i); - wxMenuItem* menu = querystatePopupMenu->FindItemByPosition(i); - if (menu && menu->IsChecked()) - querystateList->SetColumnWidth(i, querystateColWidth[i]); - else if (querystateList->GetColumnWidth(i) > 0) - querystateList->SetColumnWidth(i, 0); + wxMenuItem *menu = querystatePopupMenu->FindItemByPosition(i); + if (menu && menu->IsChecked()) + querystateList->SetColumnWidth(i, querystateColWidth[i]); + else if (querystateList->GetColumnWidth(i) > 0) + querystateList->SetColumnWidth(i, 0); - // Save current width to restore it at next launch - querystateList->GetColumn(i, column); - if (currwidth > 0) - settings->WriteInt(wxT("frmStatus/QuerystatePane_") + column.GetText() + wxT("_Width"), - querystateColWidth[i]); - else - settings->WriteInt(wxT("frmStatus/QuerystatePane_") + column.GetText() + wxT("_Width"), - -querystateColWidth[i]); - } + // Save current width to restore it at next launch + querystateList->GetColumn(i, column); + if (currwidth > 0) + settings->WriteInt(wxT("frmStatus/QuerystatePane_") + column.GetText() + wxT("_Width"), + querystateColWidth[i]); + else + settings->WriteInt(wxT("frmStatus/QuerystatePane_") + column.GetText() + wxT("_Width"), + -querystateColWidth[i]); + } } -void frmStatus::OnCommit(wxCommandEvent& event) +void frmStatus::OnCommit(wxCommandEvent &event) { - long item = xactList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (item < 0) - return; + long item = xactList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; - if (wxMessageBox(_("Are you sure you wish to commit the selected prepared transactions?"), _("Commit transaction?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) - return; + if (wxMessageBox(_("Are you sure you wish to commit the selected prepared transactions?"), _("Commit transaction?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; - while (item >= 0) - { - wxString xid = xactList->GetText(item, 1); - wxString sql = wxT("COMMIT PREPARED ") + connection->qtDbString(xid); + while (item >= 0) + { + wxString xid = xactList->GetText(item, 1); + wxString sql = wxT("COMMIT PREPARED ") + connection->qtDbString(xid); - // We must execute this in the database in which the prepared transaction originated. - if (connection->GetDbname() != xactList->GetText(item, 4)) - { - pgConn* tmpConn = new pgConn(connection->GetHost(), - connection->GetService(), - connection->GetHostAddr(), - xactList->GetText(item, 4), - connection->GetUser(), - connection->GetPassword(), - connection->GetPort(), - connection->GetRole(), - "", - connection->GetSslMode(), - 0, - connection->GetApplicationName(), - connection->GetSSLCert(), - connection->GetSSLKey(), - connection->GetSSLRootCert(), - connection->GetSSLCrl(), - connection->GetSSLCompression()); - if (tmpConn) - { - if (tmpConn->GetStatus() != PGCONN_OK) - { - wxMessageBox(wxT("Connection failed: ") + tmpConn->GetLastError()); - return; - } - tmpConn->ExecuteScalar(sql); + // We must execute this in the database in which the prepared transaction originated. + if (connection->GetDbname() != xactList->GetText(item, 4)) + { + pgConn *tmpConn = new pgConn(connection->GetHost(), + connection->GetService(), + connection->GetHostAddr(), + xactList->GetText(item, 4), + connection->GetUser(), + connection->GetPassword(), + connection->GetPort(), + connection->GetRole(), + "", + connection->GetSslMode(), + 0, + connection->GetApplicationName(), + connection->GetSSLCert(), + connection->GetSSLKey(), + connection->GetSSLRootCert(), + connection->GetSSLCrl(), + connection->GetSSLCompression()); + if (tmpConn) + { + if (tmpConn->GetStatus() != PGCONN_OK) + { + wxMessageBox(wxT("Connection failed: ") + tmpConn->GetLastError()); + return ; + } + tmpConn->ExecuteScalar(sql); - tmpConn->Close(); - delete tmpConn; - } - } - else - connection->ExecuteScalar(sql); + tmpConn->Close(); + delete tmpConn; + } + } + else + connection->ExecuteScalar(sql); - item = xactList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - } + item = xactList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } - OnRefresh(event); - wxListEvent ev; - OnSelXactItem(ev); + OnRefresh(event); + wxListEvent ev; + OnSelXactItem(ev); } -void frmStatus::OnRollback(wxCommandEvent& event) +void frmStatus::OnRollback(wxCommandEvent &event) { - long item = xactList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (item < 0) - return; + long item = xactList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; - if (wxMessageBox(_("Are you sure you wish to rollback the selected prepared transactions?"), _("Rollback transaction?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) - return; + if (wxMessageBox(_("Are you sure you wish to rollback the selected prepared transactions?"), _("Rollback transaction?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; - while (item >= 0) - { - wxString xid = xactList->GetText(item, 1); - wxString sql = wxT("ROLLBACK PREPARED ") + connection->qtDbString(xid); + while (item >= 0) + { + wxString xid = xactList->GetText(item, 1); + wxString sql = wxT("ROLLBACK PREPARED ") + connection->qtDbString(xid); - // We must execute this in the database in which the prepared transaction originated. - if (connection->GetDbname() != xactList->GetText(item, 4)) - { - pgConn* tmpConn = new pgConn(connection->GetHost(), - connection->GetService(), - connection->GetHostAddr(), - xactList->GetText(item, 4), - connection->GetUser(), - connection->GetPassword(), - connection->GetPort(), - connection->GetRole(), - "", - connection->GetSslMode(), - 0, - connection->GetApplicationName(), - connection->GetSSLCert(), - connection->GetSSLKey(), - connection->GetSSLRootCert(), - connection->GetSSLCrl(), - connection->GetSSLCompression()); - if (tmpConn) - { - if (tmpConn->GetStatus() != PGCONN_OK) - { - wxMessageBox(wxT("Connection failed: ") + tmpConn->GetLastError()); - return; - } - tmpConn->ExecuteScalar(sql); + // We must execute this in the database in which the prepared transaction originated. + if (connection->GetDbname() != xactList->GetText(item, 4)) + { + pgConn *tmpConn = new pgConn(connection->GetHost(), + connection->GetService(), + connection->GetHostAddr(), + xactList->GetText(item, 4), + connection->GetUser(), + connection->GetPassword(), + connection->GetPort(), + connection->GetRole(), + "", + connection->GetSslMode(), + 0, + connection->GetApplicationName(), + connection->GetSSLCert(), + connection->GetSSLKey(), + connection->GetSSLRootCert(), + connection->GetSSLCrl(), + connection->GetSSLCompression()); + if (tmpConn) + { + if (tmpConn->GetStatus() != PGCONN_OK) + { + wxMessageBox(wxT("Connection failed: ") + tmpConn->GetLastError()); + return ; + } + tmpConn->ExecuteScalar(sql); - tmpConn->Close(); - delete tmpConn; - } - } - else - connection->ExecuteScalar(sql); + tmpConn->Close(); + delete tmpConn; + } + } + else + connection->ExecuteScalar(sql); - item = xactList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - } + item = xactList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } - OnRefresh(event); - wxListEvent ev; - OnSelXactItem(ev); + OnRefresh(event); + wxListEvent ev; + OnSelXactItem(ev); } -void frmStatus::OnSelStatusItem(wxListEvent& event) +void frmStatus::OnSelStatusItem(wxListEvent &event) { #ifdef __WXGTK__1 - manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, true); - manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.Update(); + manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, true); + manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.Update(); #endif - currentPane = PANE_STATUS; - cbRate->SetValue(rateToCboString(statusRate)); - statusList->SetFocus(); - ActivatePane("Activity"); - if (connection && connection->BackendMinimumVersion(8, 0)) - { - if (statusList->GetSelectedItemCount() > 0) - { - toolBar->EnableTool(MNU_CANCEL, true); - actionMenu->Enable(MNU_CANCEL, true); - if (connection->HasFeature(FEATURE_TERMINATE_BACKEND)) - { - toolBar->EnableTool(MNU_TERMINATE, true); - actionMenu->Enable(MNU_TERMINATE, true); - } - } - else - { - toolBar->EnableTool(MNU_CANCEL, false); - actionMenu->Enable(MNU_CANCEL, false); - toolBar->EnableTool(MNU_TERMINATE, false); - actionMenu->Enable(MNU_TERMINATE, false); - } - } - toolBar->EnableTool(MNU_COMMIT, false); - actionMenu->Enable(MNU_COMMIT, false); - toolBar->EnableTool(MNU_ROLLBACK, false); - actionMenu->Enable(MNU_ROLLBACK, false); - cbLogfiles->Enable(false); - btnRotateLog->Enable(false); + currentPane = PANE_STATUS; + cbRate->SetValue(rateToCboString(statusRate)); + statusList->SetFocus(); + ActivatePane("Activity"); + if (connection && connection->BackendMinimumVersion(8, 0)) + { + if(statusList->GetSelectedItemCount() > 0) + { + toolBar->EnableTool(MNU_CANCEL, true); + actionMenu->Enable(MNU_CANCEL, true); + if (connection->HasFeature(FEATURE_TERMINATE_BACKEND)) + { + toolBar->EnableTool(MNU_TERMINATE, true); + actionMenu->Enable(MNU_TERMINATE, true); + } + } + else + { + toolBar->EnableTool(MNU_CANCEL, false); + actionMenu->Enable(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + actionMenu->Enable(MNU_TERMINATE, false); + } + } + toolBar->EnableTool(MNU_COMMIT, false); + actionMenu->Enable(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_ROLLBACK, false); + cbLogfiles->Enable(false); + btnRotateLog->Enable(false); - editMenu->Enable(MNU_COPY, statusList->GetFirstSelected() >= 0); - actionMenu->Enable(MNU_COPY_QUERY, statusList->GetFirstSelected() >= 0); - toolBar->EnableTool(MNU_COPY_QUERY, statusList->GetFirstSelected() >= 0); + editMenu->Enable(MNU_COPY, statusList->GetFirstSelected() >= 0); + actionMenu->Enable(MNU_COPY_QUERY, statusList->GetFirstSelected() >= 0); + toolBar->EnableTool(MNU_COPY_QUERY, statusList->GetFirstSelected() >= 0); - //OnRefresh(event); - wxTimerEvent evt; - OnRefreshStatusTimer(evt); - OnRefreshLocksTimer(evt); - OnRefreshXactTimer(evt); - OnRefreshQuerystateTimer(evt); + //OnRefresh(event); + wxTimerEvent evt; + OnRefreshStatusTimer(evt); + OnRefreshLocksTimer(evt); + OnRefreshXactTimer(evt); + OnRefreshQuerystateTimer(evt); } -void frmStatus::OnSelLockItem(wxListEvent& event) +void frmStatus::OnSelLockItem(wxListEvent &event) { #ifdef __WXGTK__1 - manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, true); - manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.Update(); + manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, true); + manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.Update(); #endif - currentPane = PANE_LOCKS; - lockList->SetFocus(); - ActivatePane("Locks"); - cbRate->SetValue(rateToCboString(locksRate)); - if (connection && connection->BackendMinimumVersion(8, 0)) - { - if (lockList->GetSelectedItemCount() > 0) - { - toolBar->EnableTool(MNU_CANCEL, true); - actionMenu->Enable(MNU_CANCEL, true); - if (connection->HasFeature(FEATURE_TERMINATE_BACKEND)) - { - toolBar->EnableTool(MNU_TERMINATE, true); - actionMenu->Enable(MNU_TERMINATE, true); - } - } - else - { - toolBar->EnableTool(MNU_CANCEL, false); - actionMenu->Enable(MNU_CANCEL, false); - toolBar->EnableTool(MNU_TERMINATE, false); - actionMenu->Enable(MNU_TERMINATE, false); - } - } - toolBar->EnableTool(MNU_COMMIT, false); - actionMenu->Enable(MNU_COMMIT, false); - toolBar->EnableTool(MNU_ROLLBACK, false); - actionMenu->Enable(MNU_ROLLBACK, false); - cbLogfiles->Enable(false); - btnRotateLog->Enable(false); + currentPane = PANE_LOCKS; + lockList->SetFocus(); + ActivatePane("Locks"); + cbRate->SetValue(rateToCboString(locksRate)); + if (connection && connection->BackendMinimumVersion(8, 0)) + { + if(lockList->GetSelectedItemCount() > 0) + { + toolBar->EnableTool(MNU_CANCEL, true); + actionMenu->Enable(MNU_CANCEL, true); + if (connection->HasFeature(FEATURE_TERMINATE_BACKEND)) + { + toolBar->EnableTool(MNU_TERMINATE, true); + actionMenu->Enable(MNU_TERMINATE, true); + } + } + else + { + toolBar->EnableTool(MNU_CANCEL, false); + actionMenu->Enable(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + actionMenu->Enable(MNU_TERMINATE, false); + } + } + toolBar->EnableTool(MNU_COMMIT, false); + actionMenu->Enable(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_ROLLBACK, false); + cbLogfiles->Enable(false); + btnRotateLog->Enable(false); - editMenu->Enable(MNU_COPY, lockList->GetFirstSelected() >= 0); - actionMenu->Enable(MNU_COPY_QUERY, false); - toolBar->EnableTool(MNU_COPY_QUERY, false); + editMenu->Enable(MNU_COPY, lockList->GetFirstSelected() >= 0); + actionMenu->Enable(MNU_COPY_QUERY, false); + toolBar->EnableTool(MNU_COPY_QUERY, false); } -void frmStatus::OnSelXactItem(wxListEvent& event) +void frmStatus::OnSelXactItem(wxListEvent &event) { #ifdef __WXGTK__1 - manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, true); - manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.Update(); + manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, true); + manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.Update(); #endif - currentPane = PANE_XACT; - xactList->SetFocus(); - ActivatePane("Transactions"); - cbRate->SetValue(rateToCboString(xactRate)); - if (xactList->GetSelectedItemCount() > 0) - { - toolBar->EnableTool(MNU_COMMIT, true); - actionMenu->Enable(MNU_COMMIT, true); - toolBar->EnableTool(MNU_ROLLBACK, true); - actionMenu->Enable(MNU_ROLLBACK, true); - } - else - { - toolBar->EnableTool(MNU_COMMIT, false); - actionMenu->Enable(MNU_COMMIT, false); - toolBar->EnableTool(MNU_ROLLBACK, false); - actionMenu->Enable(MNU_ROLLBACK, false); - } - toolBar->EnableTool(MNU_CANCEL, false); - actionMenu->Enable(MNU_CANCEL, false); - toolBar->EnableTool(MNU_TERMINATE, false); - actionMenu->Enable(MNU_TERMINATE, false); - cbLogfiles->Enable(false); - btnRotateLog->Enable(false); + currentPane = PANE_XACT; + xactList->SetFocus(); + ActivatePane("Transactions"); + cbRate->SetValue(rateToCboString(xactRate)); + if(xactList->GetSelectedItemCount() > 0) + { + toolBar->EnableTool(MNU_COMMIT, true); + actionMenu->Enable(MNU_COMMIT, true); + toolBar->EnableTool(MNU_ROLLBACK, true); + actionMenu->Enable(MNU_ROLLBACK, true); + } + else + { + toolBar->EnableTool(MNU_COMMIT, false); + actionMenu->Enable(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_ROLLBACK, false); + } + toolBar->EnableTool(MNU_CANCEL, false); + actionMenu->Enable(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + actionMenu->Enable(MNU_TERMINATE, false); + cbLogfiles->Enable(false); + btnRotateLog->Enable(false); - editMenu->Enable(MNU_COPY, xactList->GetFirstSelected() >= 0); - actionMenu->Enable(MNU_COPY_QUERY, false); - toolBar->EnableTool(MNU_COPY_QUERY, false); + editMenu->Enable(MNU_COPY, xactList->GetFirstSelected() >= 0); + actionMenu->Enable(MNU_COPY_QUERY, false); + toolBar->EnableTool(MNU_COPY_QUERY, false); } -void frmStatus::OnSelQuerystateItem(wxListEvent& event) +void frmStatus::OnSelQuerystateItem(wxListEvent &event) { #ifdef __WXGTK__1 - manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, true); - manager.Update(); + manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, true); + manager.Update(); #endif - currentPane = PANE_QUERYSTATE; - querystateList->SetFocus(); - ActivatePane("Querystate"); - cbRate->SetValue(rateToCboString(querystateRate)); - { - toolBar->EnableTool(MNU_COMMIT, false); - actionMenu->Enable(MNU_COMMIT, false); - toolBar->EnableTool(MNU_ROLLBACK, false); - actionMenu->Enable(MNU_ROLLBACK, false); - } - toolBar->EnableTool(MNU_CANCEL, false); - actionMenu->Enable(MNU_CANCEL, false); - toolBar->EnableTool(MNU_TERMINATE, false); - actionMenu->Enable(MNU_TERMINATE, false); - cbLogfiles->Enable(false); - btnRotateLog->Enable(false); + currentPane = PANE_QUERYSTATE; + querystateList->SetFocus(); + ActivatePane("Querystate"); + cbRate->SetValue(rateToCboString(querystateRate)); + { + toolBar->EnableTool(MNU_COMMIT, false); + actionMenu->Enable(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_ROLLBACK, false); + } + toolBar->EnableTool(MNU_CANCEL, false); + actionMenu->Enable(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + actionMenu->Enable(MNU_TERMINATE, false); + cbLogfiles->Enable(false); + btnRotateLog->Enable(false); - editMenu->Enable(MNU_COPY, querystateList->GetFirstSelected() >= 0); - actionMenu->Enable(MNU_COPY_QUERY, false); - toolBar->EnableTool(MNU_COPY_QUERY, false); + editMenu->Enable(MNU_COPY, querystateList->GetFirstSelected() >= 0); + actionMenu->Enable(MNU_COPY_QUERY, false); + toolBar->EnableTool(MNU_COPY_QUERY, false); } void frmStatus::ActivatePane(wxString name) { - if (!manager.GetPane(name).HasFlag(wxAuiPaneInfo::optionActive)) { - //manager.GetPane("Logfile").HasFlag(wxAuiPaneInfo::optionActive); - int i, pane_count; - wxAuiPaneInfo* active_paneinfo = NULL; - for (unsigned int i = 0; i < manager.GetAllPanes().GetCount(); i++) - { - wxAuiPaneInfo& pane = manager.GetAllPanes()[i]; - pane.state &= ~wxAuiPaneInfo::optionActive; - if (pane.name == name) - { - pane.state |= wxAuiPaneInfo::optionActive; - active_paneinfo = &pane; - } - } - if (active_paneinfo) manager.Update(); - } + if (!manager.GetPane(name).HasFlag(wxAuiPaneInfo::optionActive)) { + //manager.GetPane("Logfile").HasFlag(wxAuiPaneInfo::optionActive); + int i, pane_count; + wxAuiPaneInfo* active_paneinfo = NULL; + for (unsigned int i = 0; i < manager.GetAllPanes().GetCount(); i++) + { + wxAuiPaneInfo& pane = manager.GetAllPanes()[i]; + pane.state &= ~wxAuiPaneInfo::optionActive; + if (pane.name == name) + { + pane.state |= wxAuiPaneInfo::optionActive; + active_paneinfo = &pane; + } + } + if (active_paneinfo) manager.Update(); + } } -void frmStatus::OnSelLogItem(wxListEvent& event) +void frmStatus::OnSelLogItem(wxListEvent &event) { #ifdef __WXGTK__1 - manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, true); - manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, false); - manager.Update(); + manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, true); + manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.Update(); #endif - currentPane = PANE_LOG; - cbRate->SetValue(rateToCboString(logRate)); - logList->SetFocus(); - ActivatePane("Logfile"); - // if there's no log, don't enable items - if (logDirectory != wxT("-")) - { - cbLogfiles->Enable(true); - btnRotateLog->Enable(true); - toolBar->EnableTool(MNU_CANCEL, false); - toolBar->EnableTool(MNU_TERMINATE, false); - toolBar->EnableTool(MNU_COMMIT, false); - toolBar->EnableTool(MNU_ROLLBACK, false); - actionMenu->Enable(MNU_CANCEL, false); - actionMenu->Enable(MNU_TERMINATE, false); - actionMenu->Enable(MNU_COMMIT, false); - actionMenu->Enable(MNU_ROLLBACK, false); - } + currentPane = PANE_LOG; + cbRate->SetValue(rateToCboString(logRate)); + logList->SetFocus(); + ActivatePane("Logfile"); + // if there's no log, don't enable items + if (logDirectory != wxT("-")) + { + cbLogfiles->Enable(true); + btnRotateLog->Enable(true); + toolBar->EnableTool(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + toolBar->EnableTool(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_CANCEL, false); + actionMenu->Enable(MNU_TERMINATE, false); + actionMenu->Enable(MNU_COMMIT, false); + actionMenu->Enable(MNU_ROLLBACK, false); + } - editMenu->Enable(MNU_COPY, logList->GetFirstSelected() >= 0); - actionMenu->Enable(MNU_COPY_QUERY, false); - toolBar->EnableTool(MNU_COPY_QUERY, false); - event.Skip(); + editMenu->Enable(MNU_COPY, logList->GetFirstSelected() >= 0); + actionMenu->Enable(MNU_COPY_QUERY, false); + toolBar->EnableTool(MNU_COPY_QUERY, false); + event.Skip(); } -void frmStatus::SetColumnImage(ctlListView* list, int col, int image) +void frmStatus::SetColumnImage(ctlListView *list, int col, int image) { - wxListItem item; - item.SetMask(wxLIST_MASK_IMAGE); - item.SetImage(image); - list->SetColumn(col, item); + wxListItem item; + item.SetMask(wxLIST_MASK_IMAGE); + item.SetImage(image); + list->SetColumn(col, item); } void frmStatus::OnRightClickStatusItem(wxListEvent& event) { - int row = event.GetIndex(); - //wxString txt = event.GetText(); - if ((row < 0) || (row >= statusList->GetItemCount())) return; - wxRect r; - //statusList->GetItemRect(row, r); - wxString ss = wxEmptyString; - int col = -1; - for (int cc = 0; cc < statusList->GetColumnCount(); cc++) { - statusList->GetSubItemRect(row, cc, r, wxLIST_RECT_BOUNDS); - if (r.Contains(event.GetPoint())) { - ss = wxString::Format("\rBounding rect of item %d column %d is (%d, %d)-(%d, %d)", row, cc, r.x, r.y, r.x + r.width, r.y + r.height); - col = cc; - break; - } - } - if (col == -1) return; - wxString val = statusList->GetItemText(row, col); - wxString txt = wxString::Format("gettext=%s\r index=%d\r column=%d", val.c_str(), row, col); - txt = txt + ss; - - wxListItem listitem; - listitem.SetMask(wxLIST_MASK_TEXT); - statusList->GetColumn(col, listitem); - wxString label = listitem.GetText() + " = " + val; - //wxMessageBox(txt, "test", wxICON_WARNING | wxOK); - wxString hint = label; - if (filterColumn.size() > 0) hint = toolBar->GetToolShortHelp(MNU_CLEAR_FILTER_SERVER_STATUS) + "\n" + label; - filterColumn.Add(col); - filterValue.Add(val); - toolBar->SetToolShortHelp(MNU_CLEAR_FILTER_SERVER_STATUS, hint); - toolBar->EnableTool(MNU_CLEAR_FILTER_SERVER_STATUS, true); - wxTimerEvent evt; - OnRefreshStatusTimer(evt); + int row = event.GetIndex(); + //wxString txt = event.GetText(); + if ((row<0) || (row>=statusList->GetItemCount())) return; + wxRect r; + //statusList->GetItemRect(row, r); + wxString ss = wxEmptyString; + int col = -1; + for (int cc = 0; cc < statusList->GetColumnCount();cc++) { + statusList->GetSubItemRect(row, cc, r, wxLIST_RECT_BOUNDS); + if (r.Contains(event.GetPoint())) { + ss = wxString::Format("\rBounding rect of item %d column %d is (%d, %d)-(%d, %d)", row,cc, r.x, r.y, r.x + r.width, r.y + r.height); + col = cc; + break; + } + } + if (col == -1) return; + wxString val=statusList->GetItemText(row, col); + wxString txt = wxString::Format("gettext=%s\r index=%d\r column=%d", val.c_str(), row, col); + txt = txt + ss; + + wxListItem listitem; + listitem.SetMask(wxLIST_MASK_TEXT); + statusList->GetColumn(col, listitem); + wxString label = listitem.GetText()+" = "+val; + //wxMessageBox(txt, "test", wxICON_WARNING | wxOK); + wxString hint=label; + if (filterColumn.size() > 0) hint = toolBar->GetToolShortHelp(MNU_CLEAR_FILTER_SERVER_STATUS)+"\n"+label; + filterColumn.Add(col); + filterValue.Add(val); + toolBar->SetToolShortHelp(MNU_CLEAR_FILTER_SERVER_STATUS, hint); + toolBar->EnableTool(MNU_CLEAR_FILTER_SERVER_STATUS, true); + wxTimerEvent evt; + OnRefreshStatusTimer(evt); } void frmStatus::OnClearFilter(wxCommandEvent& event) { - toolBar->EnableTool(MNU_CLEAR_FILTER_SERVER_STATUS, false); - toolBar->SetToolShortHelp(MNU_CLEAR_FILTER_SERVER_STATUS, "Clear filter"); - filterColumn.Clear(); - filterValue.Clear(); - wxTimerEvent evt; - OnRefreshStatusTimer(evt); + toolBar->EnableTool(MNU_CLEAR_FILTER_SERVER_STATUS, false); + toolBar->SetToolShortHelp(MNU_CLEAR_FILTER_SERVER_STATUS, "Clear filter"); + filterColumn.Clear(); + filterValue.Clear(); + wxTimerEvent evt; + OnRefreshStatusTimer(evt); } -void frmStatus::OnSortStatusGrid(wxListEvent& event) +void frmStatus::OnSortStatusGrid(wxListEvent &event) { - // Get the information for the SQL ORDER BY - if (event.GetColumn() < 0) return; - if (statusSortColumn == event.GetColumn() + 1) - { - if (statusSortOrder == wxT("ASC")) - statusSortOrder = wxT("DESC"); - else - statusSortOrder = wxT("ASC"); - } - else - { - statusSortColumn = event.GetColumn() + 1; - statusSortOrder = wxT("ASC"); - } + // Get the information for the SQL ORDER BY + if (event.GetColumn()<0) return; + if (statusSortColumn == event.GetColumn() + 1) + { + if (statusSortOrder == wxT("ASC")) + statusSortOrder = wxT("DESC"); + else + statusSortOrder = wxT("ASC"); + } + else + { + statusSortColumn = event.GetColumn() + 1; + statusSortOrder = wxT("ASC"); + } - // Re-initialize all columns' image - for (int i = 0; i < statusList->GetColumnCount(); i++) - { - SetColumnImage(statusList, i, -1); - } + // Re-initialize all columns' image + for (int i = 0; i < statusList->GetColumnCount(); i++) + { + SetColumnImage(statusList, i, -1); + } - // Set the up/down image - if (statusSortOrder == wxT("ASC")) - SetColumnImage(statusList, statusSortColumn - 1, 0); - else - SetColumnImage(statusList, statusSortColumn - 1, 1); + // Set the up/down image + if (statusSortOrder == wxT("ASC")) + SetColumnImage(statusList, statusSortColumn - 1, 0); + else + SetColumnImage(statusList, statusSortColumn - 1, 1); - // Refresh grid - wxTimerEvent evt; - OnRefreshStatusTimer(evt); + // Refresh grid + wxTimerEvent evt; + OnRefreshStatusTimer(evt); } -void frmStatus::OnSortLockGrid(wxListEvent& event) +void frmStatus::OnSortLockGrid(wxListEvent &event) { - // Get the information for the SQL ORDER BY - if (lockSortColumn == event.GetColumn() + 1) - { - if (lockSortOrder == wxT("ASC")) - lockSortOrder = wxT("DESC"); - else - lockSortOrder = wxT("ASC"); - } - else - { - lockSortColumn = event.GetColumn() + 1; - lockSortOrder = wxT("ASC"); - } + // Get the information for the SQL ORDER BY + if (lockSortColumn == event.GetColumn() + 1) + { + if (lockSortOrder == wxT("ASC")) + lockSortOrder = wxT("DESC"); + else + lockSortOrder = wxT("ASC"); + } + else + { + lockSortColumn = event.GetColumn() + 1; + lockSortOrder = wxT("ASC"); + } - // There are no sort operator for xid before 8.3 - if (!connection->BackendMinimumVersion(8, 3) && lockSortColumn == 5) - { - wxLogError(_("You cannot sort by transaction id on your PostgreSQL release. You need at least 8.3.")); - lockSortColumn = 1; - } + // There are no sort operator for xid before 8.3 + if (!connection->BackendMinimumVersion(8, 3) && lockSortColumn == 5) + { + wxLogError(_("You cannot sort by transaction id on your PostgreSQL release. You need at least 8.3.")); + lockSortColumn = 1; + } - // Re-initialize all columns' image - for (int i = 0; i < lockList->GetColumnCount(); i++) - { - SetColumnImage(lockList, i, -1); - } + // Re-initialize all columns' image + for (int i = 0; i < lockList->GetColumnCount(); i++) + { + SetColumnImage(lockList, i, -1); + } - // Set the up/down image - if (lockSortOrder == wxT("ASC")) - SetColumnImage(lockList, lockSortColumn - 1, 0); - else - SetColumnImage(lockList, lockSortColumn - 1, 1); + // Set the up/down image + if (lockSortOrder == wxT("ASC")) + SetColumnImage(lockList, lockSortColumn - 1, 0); + else + SetColumnImage(lockList, lockSortColumn - 1, 1); - // Refresh grid - wxTimerEvent evt; - OnRefreshLocksTimer(evt); + // Refresh grid + wxTimerEvent evt; + OnRefreshLocksTimer(evt); } -void frmStatus::OnSortXactGrid(wxListEvent& event) +void frmStatus::OnSortXactGrid(wxListEvent &event) { - // Get the information for the SQL ORDER BY - if (xactSortColumn == event.GetColumn() + 1) - { - if (xactSortOrder == wxT("ASC")) - xactSortOrder = wxT("DESC"); - else - xactSortOrder = wxT("ASC"); - } - else - { - xactSortColumn = event.GetColumn() + 1; - xactSortOrder = wxT("ASC"); - } + // Get the information for the SQL ORDER BY + if (xactSortColumn == event.GetColumn() + 1) + { + if (xactSortOrder == wxT("ASC")) + xactSortOrder = wxT("DESC"); + else + xactSortOrder = wxT("ASC"); + } + else + { + xactSortColumn = event.GetColumn() + 1; + xactSortOrder = wxT("ASC"); + } - // There are no sort operator for xid before 8.3 - if (!connection->BackendMinimumVersion(8, 3) && xactSortColumn == 1) - { - wxLogError(_("You cannot sort by transaction id on your PostgreSQL release. You need at least 8.3.")); - xactSortColumn = 2; - } + // There are no sort operator for xid before 8.3 + if (!connection->BackendMinimumVersion(8, 3) && xactSortColumn == 1) + { + wxLogError(_("You cannot sort by transaction id on your PostgreSQL release. You need at least 8.3.")); + xactSortColumn = 2; + } - // Re-initialize all columns' image - for (int i = 0; i < xactList->GetColumnCount(); i++) - { - SetColumnImage(xactList, i, -1); - } + // Re-initialize all columns' image + for (int i = 0; i < xactList->GetColumnCount(); i++) + { + SetColumnImage(xactList, i, -1); + } - // Set the up/down image - if (xactSortOrder == wxT("ASC")) - SetColumnImage(xactList, xactSortColumn - 1, 0); - else - SetColumnImage(xactList, xactSortColumn - 1, 1); + // Set the up/down image + if (xactSortOrder == wxT("ASC")) + SetColumnImage(xactList, xactSortColumn - 1, 0); + else + SetColumnImage(xactList, xactSortColumn - 1, 1); - // Refresh grid - wxTimerEvent evt; - OnRefreshXactTimer(evt); + // Refresh grid + wxTimerEvent evt; + OnRefreshXactTimer(evt); } -void frmStatus::OnRightClickStatusGrid(wxListEvent& event) +void frmStatus::OnRightClickStatusGrid(wxListEvent &event) { - statusList->PopupMenu(statusPopupMenu, event.GetPoint()); + statusList->PopupMenu(statusPopupMenu, event.GetPoint()); } -void frmStatus::OnRightClickLockGrid(wxListEvent& event) +void frmStatus::OnRightClickLockGrid(wxListEvent &event) { - lockList->PopupMenu(lockPopupMenu, event.GetPoint()); + lockList->PopupMenu(lockPopupMenu, event.GetPoint()); } -void frmStatus::OnRightClickXactGrid(wxListEvent& event) +void frmStatus::OnRightClickXactGrid(wxListEvent &event) { - xactList->PopupMenu(xactPopupMenu, event.GetPoint()); + xactList->PopupMenu(xactPopupMenu, event.GetPoint()); } -void frmStatus::OnRightClickQuerystateGrid(wxListEvent& event) +void frmStatus::OnRightClickQuerystateGrid(wxListEvent &event) { - querystateList->PopupMenu(querystatePopupMenu, event.GetPoint()); + querystateList->PopupMenu(querystatePopupMenu, event.GetPoint()); } void frmStatus::OnLogContextMenu(wxCommandEvent& event) { - nav->OnContextMenu(event); + nav->OnContextMenu(event); +} +int count = 0; +void frmStatus::OnTimerHintLog(wxTimerEvent& event) +{ + delayHitLog->Stop(); + wxPoint pm = logList->GetScreenPosition(); + wxRect rc = logList->GetSize(); + wxPoint m = wxGetMousePosition(); + rc.x = pm.x; + rc.y = pm.y; + count++; + //statusBar->SetStatusText(wxString::Format(" TIMER COUNT %d x:%d,y:%d",count, m.x, m.y)); + if (!rc.Contains(m)) { + } + else { + wxPoint curr = logList->ScreenToClient(m); + if (lastmouse == m && lastlogitem != -1 && lastlogitemShow != lastlogitem) { + { + wxString s; + if (m_Popup != NULL) { + delete m_Popup; + m_Popup = NULL; + } + else { + } + s = logList->GetText(lastlogitem); + lastlogitemShow = lastlogitem; + lastlogitem = -1; + wxSize rr(350, 25); + // + wxString key = "content"; + int x, y; + wxPoint p = m; + p.x = p.x + 5; + p.y = p.y + 5; + PreviewHtml v; + wxString tt = v.Preview(s, fmtpreview::CSV); + s = tt; + FunctionPGHelper fh(s); + fh.SetTimerClose(1500); + //m_Popup = new popuphelp((wxWindow*)winMain, key, &fh, p, rr); + m_Popup = new popuphelp(this, key, &fh, p, rr); + if (m_Popup && m_Popup->IsValid() && rr != m_Popup->GetSizePopup()) { + // recreate with new size + rr = m_Popup->GetSizePopup(); + delete m_Popup; + m_Popup = new popuphelp(this, key, &fh, p, rr); + } + if (m_Popup && m_Popup->IsValid()) { + //m_PopupHelp->UpdateWindowUI(true); + wxSize top_sz = m_Popup->GetSizePopup(); + wxPoint posScreen; + wxSize sizeScreen; + const int displayNum = wxDisplay::GetFromPoint(p); + if (displayNum != wxNOT_FOUND) + { + const wxRect rectScreen = wxDisplay(displayNum).GetGeometry(); + posScreen = rectScreen.GetPosition(); + sizeScreen = rectScreen.GetSize(); + } + else // outside of any display? + { + // just use the primary one then + posScreen = wxPoint(0, 0); + sizeScreen = wxGetDisplaySize(); + } + wxSize top_new(top_sz); + wxPoint oldp(p); + if (p.x + top_new.x > sizeScreen.x) p.x = sizeScreen.x - top_new.x - 20; + if (p.y + top_new.y > sizeScreen.y) p.y = sizeScreen.y - top_new.y - 20; + if (oldp == p) p.x = p.x + 20; + m_Popup->Move(p); + wxRect r = m_Popup->GetScreenRect(); + //m_PopupHelp->Position(p, wxSize(0, 17)); + m_Popup->Popup(); + //wxPopupTransientWindow + + } + + } + } + } +} +void frmStatus::OnCmdFindStrLog(wxCommandEvent& event) { + wxString s = event.GetString(); + //statusBar->SetStatusText(wxString::Format(" FIND CMD: %s",s)); + nav->SetFindString(s); +} +void frmStatus::OnMoveMouseLog(wxMouseEvent& event) +{ +// wxMenu* logListPopupMenu; +// logListPopupMenu = nav->GetPopupMenu(); + wxPoint mp = event.GetPosition(); + lastmouse = wxGetMousePosition(); + int flags = wxLIST_HITTEST_ONITEMLABEL; + long item=logList->HitTest(mp,flags); + //logList->PopupMenu(logListPopupMenu, event.GetPoint()); + // statusBar->SetStatusText(wxString::Format("x:%d,y:%d",lastmouse.x,lastmouse.y)); + wxString s; + + if (lastlogitem != -1 || lastlogitem != item) { +#define DELAYHITLOGPERIOD 1000 + delayHitLog->Stop(); + delayHitLog->StartOnce(DELAYHITLOGPERIOD); + } + else + delayHitLog->Stop(); + lastlogitem = item; + event.Skip(); + return; } void frmStatus::OnRightClickLogGrid(wxListEvent& event) { - wxMenu* logListPopupMenu; - logListPopupMenu = nav->GetPopupMenu(); - logList->PopupMenu(logListPopupMenu, event.GetPoint()); + delayHitLog->Stop(); + wxMenu* logListPopupMenu; + logListPopupMenu = nav->GetPopupMenu(); + logList->PopupMenu(logListPopupMenu, event.GetPoint()); } -void frmStatus::OnChgColSizeStatusGrid(wxListEvent& event) +void frmStatus::OnChgColSizeStatusGrid(wxListEvent &event) { - wxCommandEvent ev; - OnStatusMenu(ev); + wxCommandEvent ev; + OnStatusMenu(ev); } -void frmStatus::OnChgColSizeLockGrid(wxListEvent& event) +void frmStatus::OnChgColSizeLockGrid(wxListEvent &event) { - wxCommandEvent ev; - OnLockMenu(ev); + wxCommandEvent ev; + OnLockMenu(ev); } -void frmStatus::OnChgColSizeXactGrid(wxListEvent& event) +void frmStatus::OnChgColSizeXactGrid(wxListEvent &event) { - wxCommandEvent ev; - OnXactMenu(ev); + wxCommandEvent ev; + OnXactMenu(ev); } -void frmStatus::OnChgColSizeQuerystateGrid(wxListEvent& event) +void frmStatus::OnChgColSizeQuerystateGrid(wxListEvent &event) { - wxCommandEvent ev; - OnQuerystateMenu(ev); + wxCommandEvent ev; + OnQuerystateMenu(ev); } -serverStatusFactory::serverStatusFactory(menuFactoryList* list, wxMenu* mnu, ctlMenuToolbar* toolbar) : actionFactory(list) +serverStatusFactory::serverStatusFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) { - mnu->Append(id, _("&Server Status\tCtrl-S"), _("Displays the current database status.")); + mnu->Append(id, _("&Server Status\tCtrl-S"), _("Displays the current database status.")); } -wxWindow* serverStatusFactory::StartDialog(frmMain* form, pgObject* obj) +wxWindow *serverStatusFactory::StartDialog(frmMain *form, pgObject *obj) { - pgServer* server = obj->GetServer(); - wxString applicationname = appearanceFactory->GetLongAppName() + wxT(" - Server Status"); + pgServer *server = obj->GetServer(); + wxString applicationname = appearanceFactory->GetLongAppName() + wxT(" - Server Status"); - pgConn* conn = server->CreateConn(wxEmptyString, 0, applicationname); - if (conn) - { - wxString txt = server->GetDescription() - + wxT(" (") + server->GetName() + wxT(":") + NumToStr((long)server->GetPort()) + wxT(")"); + pgConn *conn = server->CreateConn(wxEmptyString, 0, applicationname); + if (conn) + { + wxString txt = server->GetDescription() + + wxT(" (") + server->GetName() + wxT(":") + NumToStr((long)server->GetPort()) + wxT(")"); - frmStatus* status = new frmStatus(form, txt, conn); - status->Go(); - return status; - } - return 0; + frmStatus *status = new frmStatus(form, txt, conn); + status->Go(); + return status; + } + return 0; } -bool serverStatusFactory::CheckEnable(pgObject* obj) +bool serverStatusFactory::CheckEnable(pgObject *obj) { - return obj && obj->GetServer() != 0; + return obj && obj->GetServer() != 0; } diff --git a/include/ctl/ctlListView.h b/include/ctl/ctlListView.h index 872e7b8..d887abd 100644 --- a/include/ctl/ctlListView.h +++ b/include/ctl/ctlListView.h @@ -25,11 +25,19 @@ private: void OnSortGrid(wxListEvent& event); bool nosort; // если кто то пользуется SetItemData то не будем сортировать такие ctlListView int order, prev_col; + // будем сохранять длинные строки 0 колонки в этом массиве + bool storelongstring = false; + std::vector longstring; public: bool SetItemData(long item, long data) { nosort = true; return wxListView::SetItemData(item, data); } + void SetModeStoreLongString() { storelongstring = true; } + bool DeleteAllItems() { + longstring.clear(); + return wxListView::DeleteAllItems(); + } ctlListView(wxWindow* p, int id, wxPoint pos, wxSize siz, long attr = 0); long GetSelection(); wxString GetText(long row, long col = 0); diff --git a/include/ctl/ctlNavigatePanel.h b/include/ctl/ctlNavigatePanel.h index 7426b3f..9792f88 100644 --- a/include/ctl/ctlNavigatePanel.h +++ b/include/ctl/ctlNavigatePanel.h @@ -68,6 +68,7 @@ public: int GetIndexColor(const wxColour &color) const; void ClearMark(); void RowVisibleCenter(long row); + void SetFindString(const wxString &findstr); int GetCountMark(); wxMenu* GetPopupMenu(); bool RunKeyCommand(wxKeyEvent& event,int numCmd=-1); diff --git a/include/ctl/ctlSQLBox.h b/include/ctl/ctlSQLBox.h index 58dfb84..ff1ca06 100644 --- a/include/ctl/ctlSQLBox.h +++ b/include/ctl/ctlSQLBox.h @@ -53,7 +53,7 @@ public: void Create(wxWindow *parent, wxWindowID id = -1, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = 0); void HighlightBrace(int lb, int rb); void SetDatabase(pgConn *db); - wxString TextToHtml(int start, int end); + wxString TextToHtml(int start, int end, bool isAddNewLine=false); void Copy(); void OnKeyDown(wxKeyEvent &event); void OnAutoComplete(wxCommandEvent &event); diff --git a/include/ctl/ctlSQLGrid.h b/include/ctl/ctlSQLGrid.h index f2251d4..f4900e0 100644 --- a/include/ctl/ctlSQLGrid.h +++ b/include/ctl/ctlSQLGrid.h @@ -15,6 +15,8 @@ // wxWindows headers #include #include +#include "utils/popuphelp.h" + class GroupRows; class ctlSQLGrid : public wxGrid @@ -52,6 +54,8 @@ public: void OnGridSelectCell(wxGridEvent& evt); void OnLabelClick(wxGridEvent& event); void OnCellRightClick(wxGridEvent& event); + void OnMouseEvent(wxMouseEvent& event); + void OnShowPopup(wxThreadEvent& event); bool FullArrayCollapseRowsPlan(bool clear); void AutoSizeColumn(int col, bool setAsMin = false, bool doLimit = true); void AutoSizeColumns(bool setAsMin); @@ -83,7 +87,11 @@ private: // Max size for each column wxArrayInt colMaxSizes; bool isSort; - + // viewr + popuphelp* m_Popup = NULL; + int rcol, rrow; + wxPoint rpos; + //FunctionPGHelper fh; }; class GroupRows diff --git a/include/frm/frmStatus.h b/include/frm/frmStatus.h index 18541ca..5787a1f 100644 --- a/include/frm/frmStatus.h +++ b/include/frm/frmStatus.h @@ -63,12 +63,14 @@ enum MNU_QUERYSTATETRIGGER, MNU_WAITENABLE, MNU_WAITSAVE, + CMD_EVENT_FIND_STR, TIMER_REFRESHUI_ID, TIMER_STATUS_ID, TIMER_LOCKS_ID, TIMER_XACT_ID, TIMER_LOG_ID, - TIMER_QUERYSTATE_ID + TIMER_QUERYSTATE_ID, + TIMER_LOGHINT_ID }; @@ -80,9 +82,6 @@ enum PANE_LOG, PANE_QUERYSTATE }; - - -// // This number MUST be incremented if changing any of the default perspectives // #define FRMSTATUS_PERSPECTIVE_VER wxT("8275") @@ -241,6 +240,7 @@ private: wxTimer *refreshUITimer; wxTimer *statusTimer, *locksTimer, *xactTimer, *logTimer, *querystateTimer; + wxTimer *delayHitLog; int statusRate, locksRate, xactRate, logRate, querystateRate; ctlListView *statusList; @@ -261,6 +261,9 @@ private: wxArrayString filterValue; int statusColWidth[12], lockColWidth[10], xactColWidth[5], querystateColWidth[5]; + popuphelp* m_Popup = NULL; + long lastlogitem = -1, lastlogitemShow=-1; + wxPoint lastmouse; int cboToRate(); wxString rateToCboString(int rate); @@ -288,6 +291,8 @@ private: void OnToggleWaitEnable(wxCommandEvent& event); void OnEmptyAction(wxCommandEvent &event); void OnLogContextMenu(wxCommandEvent& event); + void OnMoveMouseLog(wxMouseEvent& event); + void OnTimerHintLog(wxTimerEvent& event); void OnToggleToolBar(wxCommandEvent &event); void OnDefaultView(wxCommandEvent &event); @@ -348,6 +353,7 @@ private: void OnLogKeyUp(wxKeyEvent& event); void OnAddLabelTextThread(wxThreadEvent& event); void ActivatePane(wxString name); + void OnCmdFindStrLog(wxCommandEvent& event); void OnChangeDatabase(wxCommandEvent &ev); diff --git a/include/log/Storage.h b/include/log/Storage.h index 78ce475..d1be288 100644 --- a/include/log/Storage.h +++ b/include/log/Storage.h @@ -155,10 +155,11 @@ public: int getCountGroup(int row); int GetTotalCountGroup(int rowfilter); wxArrayString GetAllFields(int row, bool isfilter); + // use for parse csv log file + static Line getLineParse(const wxString& str, bool csv = false, const wxString& host=wxEmptyString); + static wxString get_field(Line& l, MyConst::colField col); private: bool checkFilter(Line& l); - Line getLineParse(const wxString& str, bool csv = false); - wxString get_field(Line& l, MyConst::colField col); LineFilter getLineFilter(wxString strflt,wxString fn); void getLineToCache(int row, bool filter = true); bool CompareFilterLine(int row, bool filter); diff --git a/include/utils/FunctionPGHelper.h b/include/utils/FunctionPGHelper.h index 0f81d05..b42f73a 100644 --- a/include/utils/FunctionPGHelper.h +++ b/include/utils/FunctionPGHelper.h @@ -9,12 +9,27 @@ #include #include -extern sysSettings *settings; +extern sysSettings* settings; class FunctionPGHelper { public: FunctionPGHelper() {}; + /// + /// Создать только переданный в конструкторе html текст с именем "content" + /// + /// + FunctionPGHelper(const wxString& content) { + body.clear(); + Add("content", content); + isload = true; + }; + int Size() { + return body.size(); + } + void SetTimerClose(int ms) { m_interval = ms; } + int GetTimerClose() { return m_interval; } + void Add(const wxString& key, const wxString& v) { body.emplace(key, v); } wxString getHelpString(wxString fnd, bool isPart = true) { if (!isValid()) return wxEmptyString; auto search = body.find(fnd); @@ -46,9 +61,9 @@ public: wxString getSqlCommandHelp(wxString fnd) { wxUniChar sep = wxFileName::GetPathSeparator(); fnd.Replace(" ", ""); - wxString f = wxFindFirstFile(path + sep+"sql-"+fnd+"*.html"); - wxString last,txt; - + wxString f = wxFindFirstFile(path + sep + "sql-" + fnd + "*.html"); + wxString last, txt; + int c = 0; while (!f.empty()) { @@ -61,7 +76,7 @@ public: if (last.empty()) { return wxEmptyString; } - else if (c==1) { + else if (c == 1) { return getHelpFile(last); } else { @@ -100,6 +115,7 @@ public: } private: bool isload = false; + int m_interval = -1; wxString path; std::map body; void loadfile() { diff --git a/include/utils/PreviewHtml.h b/include/utils/PreviewHtml.h new file mode 100644 index 0000000..99c2aab --- /dev/null +++ b/include/utils/PreviewHtml.h @@ -0,0 +1,149 @@ +#pragma once +#include + +#define PREVIEW_SEP 1 +#define PREVIEW_DIGITS 2 +#define PREVIEW_WORD 4 +#define PREVIEW_SPACE 8 +#define PREVIEW_ENDFIELD 16 +#define PREVIEW_ENDROW 32 +#define PREVIEW_QUOTE 64 +#define CHKFLAG(val,par) ((val & par)>0) +enum class fmtpreview { + AUTO, AUTOVACCUM,CSV +}; + +struct Element { + wxString src; + wxString html; + int flags = 0; + +} ; +static wxString titles_log[] = { + L"log_time", +L"user_name", +L"database_name", +L"process_id", +L"connection_from", +L"session_id", +L"session_line_num", +L"command_tag", +L"session_start_time", +L"virtual_transaction_id", +L"transaction_id", +L"error_severity", +L"sql_state_code", +L"message", +L"detail", +L"hint", +L"internal_query", +L"internal_query_pos", +L"context", +L"query", +L"query_pos", +L"location", +L"application_name", +L"backend_type", +L"leader_pid", +L"query_id" +}; + +class PreviewHtml +{ +public: + //void SetColors(); + PreviewHtml() { InitColor(); }; + wxString Preview(const wxString& txt, fmtpreview type); +private: + void InitColor(); + bool saveTokenIfNotEmpty(wxString& savestr, int flag) { + if (savestr.Length() > 0) { + wxString tmp = savestr; + tmp=escapeHtml(tmp,true); + tmp.Replace(" ", " "); + if (CHKFLAG(flag, PREVIEW_ENDROW)) tmp = "
"; + if (CHKFLAG(flag, PREVIEW_DIGITS)) { + int l = savestr.Length(); + if (l > 4 && !savestr.Contains('.')) { + int dl = 3; + wxString fmt; + std::vector dd; + bool smalll = true; + while (l > 0) { + l = l - dl; + if (l < 0) { + dl = dl + l; + l = 0; + } + wxString d3 = savestr.Mid(l, dl); + if (smalll) + dd.push_back("" + d3 + ""); + else + dd.push_back(d3); + smalll = !smalll; + } + for (auto i = dd.rbegin(); i != dd.rend(); i++) + { + fmt += *i; + } + tmp = fmt; + } + wxString t = wxString::Format("%s", numcolor, tmp); + tmp = t; + + } + if (CHKFLAG(flag, PREVIEW_QUOTE)) { + wxString t = wxString::Format("%s",quotecolor,tmp); + tmp = t; + } + tokens.push_back({savestr,tmp,flag}); + savestr = ""; + return true; + } + return false; + } + int FindElement(int start_pos, int flag_find, wxString& value_find, int is_what_find) { + int p = start_pos; + int rez = -1; + while (p < tokens.size()) { + Element t = tokens[p]; + bool f1 = is_what_find & 1; + bool f2 = is_what_find & 2; + bool r1 = false; + bool r2 = false; + if (f1 && CHKFLAG(t.flags, flag_find)) { + r1 = true; + } + if (f2 && t.src==value_find ) { + r2 = true; + } + if ((is_what_find == 3 && r1 && r2) + || (is_what_find == 2 && r2) + || (is_what_find == 1 && r1) + ) { + rez = p; + break; + } + p++; + } + return rez; + } + wxString generateHtml() { + wxString s; + for (size_t i = 0; i < tokens.size(); i++) { + Element t = tokens[i]; + s += t.html; + } + // s = "" + s + ""; +// s=wxString::Format("%s", bgcolor,fgcolor,fname,fsize, s); + + + return s; + } + std::vector tokens; + // colors + wxString bgcolor, numcolor, fgcolor, quotecolor; + wxString fname; + int fsize; +}; + diff --git a/include/utils/popuphelp.h b/include/utils/popuphelp.h index 52c6055..1c98c9f 100644 --- a/include/utils/popuphelp.h +++ b/include/utils/popuphelp.h @@ -8,27 +8,58 @@ #include #include #include +#include "wx/display.h" class popuphelp : - public wxPopupTransientWindow + public wxPopupTransientWindow { public: - //popuphelp(wxWindow* parent); - bool ProcessLeftDown(wxMouseEvent& event) - { - return false; - } - bool IsValid() { - return isvalid; - } - popuphelp(wxWindow* parent,wxString keyword, FunctionPGHelper *hhelper) : wxPopupTransientWindow(parent) { - SetSize(450,370); - this->hhelper = hhelper; - SetBackgroundColour(*wxBLACK); - htmlWindow = new wxHtmlWindow(this, -1, wxDefaultPosition,GetSize()); - htmlWindow->SetRelatedStatusBar(0); - //htmlWindow->SetPage("

TEST

Set Page Works"); - wxString txt = hhelper->getHelpString(keyword); + ~popuphelp() { + delete closeTimer; + } + //popuphelp(wxWindow* parent); + bool ProcessLeftDown(wxMouseEvent& event) + { + return false; + } + bool IsValid() { + return isvalid; + } + void SetSizePopup(const wxSize& sz) { + SetSize(sz); + Layout(); + Fit(); + sizew = sz; + } + wxSize GetSizePopup() { return sizew; } + popuphelp(wxWindow* parent,wxString keyword, FunctionPGHelper *hhelper,wxPoint &posit,wxSize &newSz) : wxPopupTransientWindow(parent) { + wxSize top_sz(newSz); + sizew = top_sz; + //SetSize(top_sz); + this->hhelper = hhelper; + SetBackgroundColour(*wxBLACK); + extern sysSettings* settings; + wxFont fnt = settings->GetSQLFont(); + int size = fnt.GetPointSize(); + SetFont(fnt); + htmlWindow = new wxHtmlWindow(this, -1, wxDefaultPosition, sizew); + + wxFont font(size, wxFontFamily::wxFONTFAMILY_MODERN, wxFontStyle::wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); + wxString fixf = font.GetFaceName(); + wxString scalf = fnt.GetFaceName(); + int f_sizes[7]; + f_sizes[0] = int(size -4); + f_sizes[1] = int(size -2); + f_sizes[2] = size; + f_sizes[3] = int(size +1); + f_sizes[4] = int(size +3); + f_sizes[5] = int(size +5); + f_sizes[6] = int(size +7); + htmlWindow->SetFonts(scalf, fixf, f_sizes); + + htmlWindow->SetRelatedStatusBar(0); + //htmlWindow->SetPage("

TEST

Set Page Works"); + wxString txt = hhelper->getHelpString(keyword); if (txt.IsEmpty()) { txt = hhelper->getSqlCommandHelp(keyword); @@ -38,47 +69,80 @@ public: } } SetPage(txt); - //wxSize sz= htmlWindow->GetSize(); - //sz = htmlWindow->GetBestSize(); - //htmlWindow->SetHTMLBackgroundImage(wxBitmapBundle::FromSVGFile("data/bg.svg", wxSize(65, 45))); - wxBoxSizer* topsizer; - topsizer = new wxBoxSizer(wxVERTICAL); + //htmlWindow->SetSize(htmlWindow->GetInternalRepresentation()->GetWidth(), htmlWindow->GetInternalRepresentation()->GetHeight()); + //wxSize sz= htmlWindow->GetSize(); + //sz = htmlWindow->GetBestSize(); + //htmlWindow->SetHTMLBackgroundImage(wxBitmapBundle::FromSVGFile("data/bg.svg", wxSize(65, 45))); + wxBoxSizer* topsizer; + topsizer = new wxBoxSizer(wxVERTICAL); - //htmlWindow->SetInitialSize(wxSize(htmlWindow->GetInternalRepresentation()->GetWidth(), htmlWindow->GetInternalRepresentation()->GetHeight())); + //htmlWindow->SetInitialSize(wxSize(htmlWindow->GetInternalRepresentation()->GetWidth(), htmlWindow->GetInternalRepresentation()->GetHeight())); - //SetSize(wxSize(300,150)); - topsizer->Add(htmlWindow, 1, wxALL, 1); + //SetSize(wxSize(300,150)); + topsizer->Add(htmlWindow, 1, wxALL, 1); - //wxButton* bu1 = new wxButton(this, wxID_OK, _("OK")); - //bu1->SetDefault(); + //wxButton* bu1 = new wxButton(this, wxID_OK, _("OK")); + //bu1->SetDefault(); - //topsizer->Add(bu1, 0, wxALL | wxALIGN_RIGHT, 15); + //topsizer->Add(bu1, 0, wxALL | wxALIGN_RIGHT, 15); - SetSizer(topsizer); - topsizer->Fit(this); + SetSizer(topsizer); + topsizer->Fit(this); + int xx, yy; + htmlWindow->GetVirtualSize(&xx, &yy); + //wxSize sz = GetSize(); + wxPoint posScreen; + wxSize sizeScreen; + const int displayNum = wxDisplay::GetFromPoint(posit); + if (displayNum != wxNOT_FOUND) + { + const wxRect rectScreen = wxDisplay(displayNum).GetGeometry(); + posScreen = rectScreen.GetPosition(); + sizeScreen = rectScreen.GetSize(); + } + else // outside of any display? + { + // just use the primary one then + posScreen = wxPoint(0, 0); + sizeScreen = wxGetDisplaySize(); + } + wxSize top_new(top_sz); - //this->Bind(wxEVT_HTML_CELL_CLICKED, [&](wxHtmlCellEvent& event) { - // wxHtmlCell* c = event.GetCell(); - // - // wxString ctext=c->ConvertToText(NULL); - // ctext=htmlWindow->SelectionToText(); - // wxString s = wxString::Format("cell = %s",ctext.c_str()); - // wxMessageBox(s, "cell", wxOK | wxICON_INFORMATION); + if (xx > sizeScreen.x) xx = sizeScreen.x - 120; + if (yy > sizeScreen.y) yy = sizeScreen.y - 120; - // }); - this->Bind(wxEVT_HTML_LINK_CLICKED, [&](wxHtmlLinkEvent& event) { - wxHtmlLinkInfo i = event.GetLinkInfo(); - wxString name = i.GetHref(); - wxString body=this->hhelper->getHelpString(name); + + if (xx > top_sz.x || yy > top_sz.y) { + int dx = 0; + if (htmlWindow->IsScrollbarShown(wxHORIZONTAL)) dx=htmlWindow->GetScrollThumb(wxHORIZONTAL); + SetSizePopup(wxSize(xx+dx, yy+5)); + } + + //this->Bind(wxEVT_HTML_CELL_CLICKED, [&](wxHtmlCellEvent& event) { + // wxHtmlCell* c = event.GetCell(); + // + // wxString ctext=c->ConvertToText(NULL); + // ctext=htmlWindow->SelectionToText(); + // wxString s = wxString::Format("cell = %s",ctext.c_str()); + // wxMessageBox(s, "cell", wxOK | wxICON_INFORMATION); + + // }); + this->Bind(wxEVT_HTML_LINK_CLICKED, [&](wxHtmlLinkEvent& event) { + wxHtmlLinkInfo i = event.GetLinkInfo(); + wxString name = i.GetHref(); + wxString body=this->hhelper->getHelpString(name); if (body.IsEmpty()) { body = this->hhelper->getHelpFile(name); } - SetPage(body); - //ctext=htmlWindow->SelectionToText(); - //wxString s = wxString::Format("cell = %s",ctext.c_str()); - }); + SetPage(body); + //ctext=htmlWindow->SelectionToText(); + //wxString s = wxString::Format("cell = %s",ctext.c_str()); + }); htmlWindow->Bind(wxEVT_RIGHT_UP, [&](wxMouseEvent& event) { wxString name; + wxLongLong e = wxGetLocalTimeMillis(); + if (e - startTimeWin < 150) + return; //wxString body = this->hhelper->getHelpString(name); wxString ctext = htmlWindow->SelectionToText(); if (!ctext.IsEmpty()) { @@ -88,6 +152,17 @@ public: { } + wxString wname = GetParent()->GetName(); + if (wname == "frmStatus") { + //CMD_EVENT_FIND_STR + wxCommandEvent event(wxEVT_MENU, 281); + event.SetEventObject(this); + // Give it some contents + event.SetString(ctext); + // Do send it + GetParent()->ProcessWindowEvent(event); + } + //statusBar->SetStatusText(wxString::Format(" TIMER COUNT %d x:%d,y:%d", count, m.x, m.y)); Hide(); return; } @@ -95,21 +170,43 @@ public: //ctext=htmlWindow->SelectionToText(); //wxString s = wxString::Format("cell = %s",ctext.c_str()); }); - - } + startTimeWin = wxGetLocalTimeMillis(); + int inter = hhelper->GetTimerClose(); + if (inter != -1) { + closeTimer = new wxTimer(this); + Bind(wxEVT_TIMER, [&](wxTimerEvent& event) { + closeTimer->Stop(); + wxPoint pm = this->GetScreenPosition(); + wxRect rc = this->GetSize(); + wxPoint m = wxGetMousePosition(); + rc.x = pm.x; + rc.y = pm.y; + if (!rc.Contains(m)) { + Hide(); + return; + } + }); + closeTimer->StartOnce(inter); + } + } private: - bool isvalid = true; - wxHtmlWindow* htmlWindow; - FunctionPGHelper* hhelper; + bool isvalid = true; + wxHtmlWindow* htmlWindow; + wxLongLong startTimeWin; + wxSize sizew; + FunctionPGHelper* hhelper; std::vector hist; - void SetPage(wxString innerbody,bool gethistory=false) { + void SetPage(wxString innerbody,bool gethistory=false) { wxString h; int p = innerbody.Find(""); - if (p > -1) { - innerbody.Replace("", "", false); - h = "" + innerbody + ""; - } else - h = "" + innerbody + ""; + if (innerbody.Find("")>=0) h = innerbody; + else + if (p > -1) { + innerbody.Replace("", "", false); + h = "" + innerbody + ""; + } + else + h = "" + innerbody + ""; if (gethistory) { if (hist.size() < 2) { @@ -122,7 +219,9 @@ private: else { hist.push_back(h); } - htmlWindow->SetPage(h); - } + htmlWindow->SetPage(h); + } +private: + wxTimer *closeTimer=NULL; }; #endif diff --git a/pgAdmin3.vcxproj b/pgAdmin3.vcxproj index c630053..bed00c7 100644 --- a/pgAdmin3.vcxproj +++ b/pgAdmin3.vcxproj @@ -1062,6 +1062,7 @@ + @@ -1613,6 +1614,7 @@ + diff --git a/utils/PreviewHtml.cpp b/utils/PreviewHtml.cpp new file mode 100644 index 0000000..c16796e --- /dev/null +++ b/utils/PreviewHtml.cpp @@ -0,0 +1,250 @@ +#include "pgAdmin3.h" +#include "utils/PreviewHtml.h" +#include "utils/json/jsonval.h" +#include "utils/csvfiles.h" +#include "log/Storage.h" + +void PreviewHtml::InitColor() { + wxJSONValue def(wxJSONType::wxJSONTYPE_OBJECT); + def.SetType(wxJSONType::wxJSONTYPE_NULL); + wxJSONValue opt(wxJSONType::wxJSONTYPE_OBJECT); + opt.SetType(wxJSONType::wxJSONTYPE_NULL); + extern sysSettings* settings; + settings->ReadJsonObect("PreviewOptions", opt, def); + + // settings->WriteJsonFile(); + if (!opt.IsNull()) { + bgcolor = opt["bgcolor"].AsString(); + fgcolor = opt["fgcolor"].AsString(); + numcolor = opt["numcolor"].AsString(); + quotecolor = opt["quotecolor"].AsString(); + //fname = opt["fontname"].AsString(); + //fsize=opt["fontsize"].AsInt(); + + } + else { + wxColour frColor = settings->GetSQLBoxColourForeground(); + if (settings->GetSQLBoxUseSystemForeground()) + { + frColor = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); + } + fgcolor=frColor.GetAsString(wxC2S_HTML_SYNTAX); + opt["fgcolor"] = fgcolor; + bgcolor = "#FFFFE0"; + //4 + numcolor = settings->GetSQLBoxColour(4); + wxColour cc(numcolor); + if (cc.IsOk()) numcolor = cc.GetAsString(wxC2S_HTML_SYNTAX); + //6 + quotecolor = settings->GetSQLBoxColour(6); + wxColour ccc(quotecolor); + if (ccc.IsOk()) quotecolor = ccc.GetAsString(wxC2S_HTML_SYNTAX); + // wxFont fnt = settings->GetSQLFont(); + // fname = fnt.GetFaceName(); + // fsize = fnt.GetPointSize(); + //fnt.SetPointSize(fsize); + + opt["fgcolor"] = fgcolor; + opt["bgcolor"] = bgcolor; + opt["numcolor"] = numcolor; + opt["quotecolor"] = quotecolor; + // opt["fontname"] = fname; + // opt["fontsize"]=fsize; + settings->WriteJsonObect("PreviewOptions", opt); + } +} +wxString PreviewHtml::Preview(const wxString& txt, fmtpreview type) { + fmtpreview fmt = type; + wxString fieldSep=","; + wxString rowSep = "\n"; + bool iscsv = false; + if (txt.StartsWith("automatic vacuum")&& fmt == fmtpreview::AUTO) fmt = fmtpreview::AUTOVACCUM; + if (txt.StartsWith("automatic analyze") && fmt == fmtpreview::AUTO) fmt = fmtpreview::AUTOVACCUM; + +// + + if (fmt == fmtpreview::AUTOVACCUM) { + fieldSep = ","; + rowSep = "\n"; + } + else if (fmt == fmtpreview::CSV) { + iscsv = true; + } + else if (fmt == fmtpreview::AUTO) { + //CSVTokenizer tk(txt); + //int nfield = 0; + //while (tk.HasMoreTokens()) { + // wxString field = tk.GetNextToken(); + // nfield++; + //} + //if (nfield>1) iscsv = true; + } + // prepare csv + std::vector strlist; + wxString tmpstr = txt; + if (iscsv) { + CSVTokenizer tk(txt); + tmpstr = ""; + int nfield = 0; + while (tk.HasMoreTokens()) { + wxString field = tk.GetNextToken(); + + if (!field.IsEmpty()) { + if (!tmpstr.IsEmpty()) tmpstr += '\n'; // All not empty field as list rows + tmpstr += field; + } + strlist.push_back(field); + nfield++; + } + if (nfield == 26) { + // log db csv format 14,15,16,17 version + Line l=Storage::getLineParse(txt, true, ""); + strlist[15] = Storage::get_field(l, MyConst::colField::logHint); // bind value + strlist[13] = Storage::get_field(l, MyConst::colField::logMessage); // bind value + } + + } + if (strlist.size() == 0) strlist.push_back(tmpstr); + wxString html; + int nf = 0; + for (int nf = 0; nf < strlist.size();nf++) { + + tmpstr = strlist[nf]; + int pos = 0; + int len = tmpstr.Length(); + if (len == 0) continue; + wxUniChar c; + wxString currWord; + wxString currDigits; + wxString currSep; + int flag = 0; + tokens.clear(); + bool quote = false; + wxUniChar prevchar; + int startstr = -1; + while (pos < len) { + c = tmpstr[pos++]; + bool isquote = c == '"'; + if (quote) { + if (prevchar == c && isquote) { + // repeat quote + prevchar = '\0'; + continue; + } + if (prevchar == '"' && !isquote) { + // end quote string + wxString tmp = tmpstr.Mid(startstr, pos - startstr - 1); + saveTokenIfNotEmpty(tmp, PREVIEW_QUOTE); + quote = false; + } + else { + prevchar = c; + continue; + } + } + if (quote == false && isquote) { + saveTokenIfNotEmpty(currWord, PREVIEW_WORD); + saveTokenIfNotEmpty(currDigits, PREVIEW_DIGITS); + saveTokenIfNotEmpty(currSep, PREVIEW_SEP); + quote = true; + prevchar = '\0'; + startstr = pos - 1; + continue; + } + if (fieldSep.Length() > 0 && fieldSep[0] == c) { + //flag |= PREVIEW_ENDFIELD; + saveTokenIfNotEmpty(currWord, PREVIEW_WORD); + saveTokenIfNotEmpty(currDigits, PREVIEW_DIGITS); + saveTokenIfNotEmpty(currSep, PREVIEW_SEP); + currSep = c; + saveTokenIfNotEmpty(currSep, PREVIEW_ENDFIELD); + continue; + } + else if (rowSep.Length() > 0 && rowSep[0] == c) { + //flag |= PREVIEW_ENDROW; + saveTokenIfNotEmpty(currWord, PREVIEW_WORD); + saveTokenIfNotEmpty(currDigits, PREVIEW_DIGITS); + saveTokenIfNotEmpty(currSep, PREVIEW_SEP); + currSep = c; + saveTokenIfNotEmpty(currSep, PREVIEW_ENDROW); + continue; + } + + if ((c >= '0' && c <= '9') || (currDigits.Length() > 0 && c == '.')) { + if (currWord.Length() == 0) { // diget not after word + saveTokenIfNotEmpty(currSep, PREVIEW_SEP); + currDigits += c; + continue; + } + } + if (c == '-' || c == '+' || c == '.' || c == ',' || + c == ':' || c == '~' || + c == '@' || c == '*' || c == '/' || + c == '=' || c == '!' || c == '#' || + c == '&' || c == '%' || c == '^' || + c == '|' || c == '`' || c == '?' || + c == '>' || c == '<' + || c == ';' || c == '_' || c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}' + || c == ' ' + ) + { + saveTokenIfNotEmpty(currWord, PREVIEW_WORD); + saveTokenIfNotEmpty(currDigits, PREVIEW_DIGITS); + currSep += c; + continue; + } + saveTokenIfNotEmpty(currSep, PREVIEW_SEP); + if (currDigits.Length() > 0) { + currWord = currDigits + currWord; + currDigits = ""; + } + currWord += c; + } + // last element + if (quote) { + wxString tmp = tmpstr.Mid(startstr); + saveTokenIfNotEmpty(tmp, PREVIEW_QUOTE); + } + saveTokenIfNotEmpty(currWord, PREVIEW_WORD); + saveTokenIfNotEmpty(currDigits, PREVIEW_DIGITS); + saveTokenIfNotEmpty(currSep, PREVIEW_SEP); + + + // Additonal styled + wxString findstr = ""; + int p = 0; + while (p >= 0) { + int fp = FindElement(p, PREVIEW_ENDFIELD | PREVIEW_ENDROW, findstr, 1); + if (fp > 0) { + int pp = fp; + while (pp > 0 && pp > p) { + pp--; + Element t2 = tokens[pp]; + if (CHKFLAG(t2.flags, PREVIEW_SEP) && t2.src.StartsWith(":")) { + // Right bound title + if (pp - p > 0) { + tokens[p].html = "" + tokens[p].html; + tokens[pp - 1].html = tokens[pp - 1].html + ""; + } + } + } + fp++; // next field + p = fp; + } + else break; + } + + if (strlist.size() > 1) { + // csv log + wxString tit="field"+wxString::Format("%d",nf+1); + if (strlist.size() == 26) tit = titles_log[nf]; + tit = "" + tit + ""; + html=html+tit+"" + generateHtml() + ""; + + } else + html+= generateHtml(); // tokens -> html + } + if (strlist.size() > 1) html = "" + html + "
"; + wxString ttt = wxString::Format("%s", bgcolor, fgcolor, html); + return ttt; +} \ No newline at end of file diff --git a/utils/log/Storage.cpp b/utils/log/Storage.cpp index 0429d13..863831c 100644 --- a/utils/log/Storage.cpp +++ b/utils/log/Storage.cpp @@ -560,7 +560,7 @@ wxString replace_bind_parameters(const wxString& values_param, const wxString& t replacecount = c; return str; } -Line Storage::getLineParse(const wxString& str, bool csv) { +Line Storage::getLineParse(const wxString& str, bool csv,const wxString &host) { Line st; if (csv) { CSVTokenizer tk(str); @@ -575,7 +575,7 @@ Line Storage::getLineParse(const wxString& str, bool csv) { st.loguser = { static_cast(t.Len()),static_cast(logUser.Len()) }; t += logUser; wxString logDatabase = tk.GetNextToken(); - if (logDatabase.IsEmpty()) logDatabase = GetHost(); + if (logDatabase.IsEmpty()) logDatabase = host; st.logdb = { static_cast(t.Len()),static_cast(logDatabase.Len()) }; t += logDatabase; @@ -659,7 +659,7 @@ Line Storage::getLineParse(const wxString& str, bool csv) { wxString logType = tk.GetNextToken(); st.logbtype = { static_cast(t.Len()),static_cast(logType.Len()) }; t += logType; - logCursorpos = GetHost(); + logCursorpos = host; st.logSERVER = { static_cast(t.Len()),static_cast(logCursorpos.Len()) }; t += logCursorpos; //fields.Add(logType); @@ -785,7 +785,7 @@ bool Storage::checkFilter(Line& l) { return false; } bool Storage::AddLineTextCSV(const wxString& strcsv) { - Line st = getLineParse(strcsv, true); + Line st = getLineParse(strcsv, true,GetHost()); if (checkFilter(st)) { rowsignore++;