From 4db8267ae602ff8814902fda5d008bdba28ee8cb Mon Sep 17 00:00:00 2001 From: lsv Date: Fri, 22 Oct 2021 18:06:26 +0500 Subject: [PATCH] Add new feature frmLog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Для окна состояние выполняется: set log_min_messages = FATAL Для Log view добавлена: подержка быстрой навигации: Shift+KeyUP,KeyDOWN переход на запись с тем же sql_state, Alt+KeyUP,KeyDOWN - переход на запись с другим sql_state Добавлена колонка Server - сервер с которого получен лог. --- .gitignore | 1 + ctl/ctlSQLGrid.cpp | 2 + frm/frmLog.cpp | 9 ++-- frm/frmStatus.cpp | 4 ++ include/ctl/ctlSQLGrid.h | 90 ++++++++++++++++++++++------------ include/log/MyDataViewCtrl.h | 1 + include/log/Storage.h | 2 + include/log/StorageModel.h | 1 + utils/log/MyDataViewCtrl.cpp | 93 +++++++++++++++++++++++++++++++++++- utils/log/Storage.cpp | 6 +++ utils/log/StorageModel.cpp | 31 ++++++++---- 11 files changed, 196 insertions(+), 44 deletions(-) diff --git a/.gitignore b/.gitignore index f12386e..6347211 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ Release/* *.7z *.bsc *.pdb +include/svnversion.h diff --git a/ctl/ctlSQLGrid.cpp b/ctl/ctlSQLGrid.cpp index a61da43..b4aa6e6 100644 --- a/ctl/ctlSQLGrid.cpp +++ b/ctl/ctlSQLGrid.cpp @@ -849,6 +849,8 @@ wxSize ctlSQLGrid::GetBestSize(int row, int col) { wxClientDC dc(GetGridWindow()); size = renderer->GetBestSize(*this, *attr, dc, row, col); + int h = renderer->GetBestHeight(*this, *attr, dc, row, col, size.GetWidth()); + size.SetHeight(h); renderer->DecRef(); } diff --git a/frm/frmLog.cpp b/frm/frmLog.cpp index 6b802bc..495bf86 100644 --- a/frm/frmLog.cpp +++ b/frm/frmLog.cpp @@ -130,8 +130,12 @@ void frmLog::getFilename() { wxString namepage; for (size_t i = 0;i< conArray.GetCount(); i++) { + if (!namepage.IsEmpty()) namepage += ","; - if (!conArray[i].conn->IsAlive()) continue; + if (!conArray[i].conn->IsAlive()) { + namepage += "-"+conArray[i].conn->GetDbname(); + continue; + } set = conArray[i].conn->ExecuteSet( wxT("select current_setting('log_directory')||'/'||name filename,modification filetime,size len\n") wxT(" FROM pg_ls_logdir() where name ~ '.csv' ORDER BY modification DESC")); @@ -140,7 +144,6 @@ void frmLog::getFilename() { //logfileTimestamp = set->GetDateTime(wxT("filetime")); len[i] = set->GetLong(wxT("len")); - if (!namepage.IsEmpty()) namepage += ","; namepage += conArray[i].conn->GetDbname(); m_storage_model->getStorage()->SetHost(conArray[i].conn->GetHostName()); @@ -417,7 +420,7 @@ frmLog::frmLog(frmMain *form, const wxString &_title, pgServer *srv) : pgFrame(N wxDefaultSize, wxDV_VARIABLE_LINE_HEIGHT | wxDV_HORIZ_RULES | wxDV_VERT_RULES); my_view->GetMainWindow()->Bind(wxEVT_MOTION, &MyDataViewCtrl::OnMouseMove, my_view); my_view->GetMainWindow()->Bind(wxEVT_KEY_DOWN, &MyDataViewCtrl::OnKEY_DOWN, my_view); - my_view->GetMainWindow()->Bind(wxEVT_KEY_UP, &MyDataViewCtrl::OnKEY_DOWN, my_view); + my_view->GetMainWindow()->Bind(wxEVT_KEY_UP, &MyDataViewCtrl::OnKEY_UP, my_view); my_view->Bind(wxEVT_DATAVIEW_COLUMN_HEADER_CLICK, &MyDataViewCtrl::OnEVT_DATAVIEW_COLUMN_HEADER_CLICK, my_view); my_view->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, &MyDataViewCtrl::OnEVT_DATAVIEW_SELECTION_CHANGED, my_view); my_view->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, &MyDataViewCtrl::OnContextMenu, my_view); diff --git a/frm/frmStatus.cpp b/frm/frmStatus.cpp index 1631379..7812d5a 100644 --- a/frm/frmStatus.cpp +++ b/frm/frmStatus.cpp @@ -220,6 +220,10 @@ frmStatus::frmStatus(frmMain *form, const wxString &_title, pgConn *conn) : pgFr 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;"); +#ifndef _DEBUG + initquery += wxT("set log_min_messages = FATAL;"); +#endif // !_DEBUG + connection->ExecuteVoid(initquery, false); } //pg_is_in_recovery() diff --git a/include/ctl/ctlSQLGrid.h b/include/ctl/ctlSQLGrid.h index 7419c48..218d4e0 100644 --- a/include/ctl/ctlSQLGrid.h +++ b/include/ctl/ctlSQLGrid.h @@ -186,7 +186,8 @@ private: wxArrayInt rowsGroup, end; wxArrayDouble run; }; - +//#define TEST_wxGridCellAutoWrapStringRenderer +#ifndef TEST_wxGridCellAutoWrapStringRenderer class CursorCellRenderer : public wxGridCellStringRenderer { public: @@ -197,46 +198,75 @@ class CursorCellRenderer : public wxGridCellStringRenderer attr.GetAlignment(&hAlign, &vAlign); ////////////////////////////////////////////////////////////////////////////// //CursorCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected); // - dc.SetBackgroundMode( wxSOLID ); - wxString text=grid.GetCellValue(row, col); - // grey out fields if the grid is disabled - if ( grid.IsEnabled() ) - { - if ( isSelected ) - { - wxColour clr; - if ( wxWindow::FindFocus() == grid.GetGridWindow() ) - clr = grid.GetSelectionBackground(); - else - clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW); + dc.SetBackgroundMode( wxSOLID ); + wxString text=grid.GetCellValue(row, col); + // grey out fields if the grid is disabled + if ( grid.IsEnabled() ) + { + if ( isSelected ) + { + wxColour clr; + if ( wxWindow::FindFocus() == grid.GetGridWindow() ) + clr = grid.GetSelectionBackground(); + else + clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW); - dc.SetBrush( wxBrush(clr, wxSOLID) ); - } - else - { - wxColor color; - color.Set(239, 228, 176); - if (text.Find(wxT('\n'))!=wxNOT_FOUND ) - dc.SetBrush( wxBrush(color, wxSOLID) ); + dc.SetBrush( wxBrush(clr, wxSOLID) ); + } + else + { + wxColor color; + color.Set(239, 228, 176); + if (text.Find(wxT('\n'))!=wxNOT_FOUND ) + dc.SetBrush( wxBrush(color, wxSOLID) ); + else + dc.SetBrush( wxBrush(attr.GetBackgroundColour(), wxSOLID) ); + } + } else - dc.SetBrush( wxBrush(attr.GetBackgroundColour(), wxSOLID) ); - } - } - else - { - dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE), wxSOLID)); - } + { + dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE), wxSOLID)); + } - dc.SetPen( *wxTRANSPARENT_PEN ); - dc.DrawRectangle(rect); + dc.SetPen( *wxTRANSPARENT_PEN ); + dc.DrawRectangle(rect); ////////////////////////////////////////////////////////////////////////////// SetTextColoursAndFont(grid, attr, dc, isSelected); grid.DrawTextRectangle(dc, text, rect, hAlign, vAlign); } +#else +class CursorCellRenderer : public wxGridCellAutoWrapStringRenderer +{ +public: + virtual void Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rectCell, + int row, int col, + bool isSelected) { + bool f = false; + wxString text = grid.GetCellValue(row, col); + wxColor prev; + if (!isSelected) { + wxColor color; + color.Set(239, 228, 176); + if (text.Find(wxT('\n')) != wxNOT_FOUND) + { + //dc.SetBrush(wxBrush(color, wxSOLID)); + prev = attr.GetBackgroundColour(); + attr.SetBackgroundColour(color); + f = true; + } + + } + wxGridCellAutoWrapStringRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); + if (f) attr.SetBackgroundColour(prev); + } +#endif }; #endif diff --git a/include/log/MyDataViewCtrl.h b/include/log/MyDataViewCtrl.h index 0575985..773b7a7 100644 --- a/include/log/MyDataViewCtrl.h +++ b/include/log/MyDataViewCtrl.h @@ -30,6 +30,7 @@ public: void AddRow(wxString csvtext); void OnMouseMove(wxMouseEvent& event); void OnKEY_DOWN(wxKeyEvent& event); + void OnKEY_UP(wxKeyEvent& event); #ifdef MYTEST void OnTimer(wxTimerEvent& event); #endif diff --git a/include/log/Storage.h b/include/log/Storage.h index f4761ec..af11ab8 100644 --- a/include/log/Storage.h +++ b/include/log/Storage.h @@ -26,6 +26,7 @@ namespace MyConst { logHint, logappname, logbtype, + logSERVER, Col_Max }; enum iconIndex { @@ -67,6 +68,7 @@ struct Line { ps logHint = { 0,0 }; ps logappname = { 0,0 }; ps logbtype = { 0,0 }; + ps logSERVER = { 0,0 }; wxString text; }; struct LineFilter { diff --git a/include/log/StorageModel.h b/include/log/StorageModel.h index a0c54e1..e9ad1b5 100644 --- a/include/log/StorageModel.h +++ b/include/log/StorageModel.h @@ -23,6 +23,7 @@ public: Col_Hint, Col_Detail, Col_Message, + Col_Server, Col_Max }; diff --git a/utils/log/MyDataViewCtrl.cpp b/utils/log/MyDataViewCtrl.cpp index 1abc194..d4b6346 100644 --- a/utils/log/MyDataViewCtrl.cpp +++ b/utils/log/MyDataViewCtrl.cpp @@ -132,8 +132,15 @@ void MyDataViewCtrl::ViewGroup(bool view) { void MyDataViewCtrl::AddRow(wxString csvtext) { StorageModel* m = dynamic_cast(GetModel()); wxDataViewItem select; - if (HasSelection()) select = GetSelection(); - + if (HasSelection()) { + //select = GetSelection(); + if (GetSelectedItemsCount() == 1) { + wxDataViewItemArray sel; + GetSelections(sel); + if (sel.size()>0) select = sel[0]; + } + + } if (m->Prepend(csvtext)) { if (!select.IsOk()) return; @@ -396,11 +403,93 @@ void MyDataViewCtrl::OnEVT_DATAVIEW_COLUMN_HEADER_CLICK(wxDataViewEvent& event) event.Skip(true); } +void MyDataViewCtrl::OnKEY_UP(wxKeyEvent& event) { + // goto next state code + int go = 0; + if (event.GetKeyCode() == WXK_DOWN) { + go = 1; + } + if (event.GetKeyCode() == WXK_UP) { + go = -1; + } + bool reverse = false; + int currrow = -1; + wxDataViewItem item; + //find next state != current state + if ((event.GetModifiers() & wxMOD_ALT) == wxMOD_ALT) { + reverse = true; + item = this->GetCurrentItem(); + } + //find next state == current state + if ((event.GetModifiers() & wxMOD_SHIFT) == wxMOD_SHIFT) { + item = this->GetCurrentItem(); + } + if (item.IsOk() && (go != 0)) { + + + StorageModel* m = dynamic_cast(GetModel()); + Storage* sta = m->getStorage(); + wxVariant v, t; + + int r = m->GetRow(item); + if (r != -1) { + m->GetValueByRow(v, r, 0); + } + else return; + int cnt = m->GetRowCount(); + wxDataViewIconText ic; + ic << v; + wxString str = ic.GetText(); + + for (;;) { + r = r + go; + if (r < 0 || r >= cnt) break; + m->GetValueByRow(t, r, 0); + ic << t; + bool rez = ic.GetText() == str; + if (reverse) rez = !rez; + if (rez) + { + item = m->GetItem(r); + this->SetCurrentItem(item); + EnsureVisible(item); + break; + } + } + event.Skip(true); + return; + } + +} void MyDataViewCtrl::OnKEY_DOWN(wxKeyEvent& event) { if ((event.GetModifiers() & wxMOD_CONTROL) == wxMOD_CONTROL) { modctrl = true; } else modctrl = false; + int go = 0; + if (event.GetKeyCode() == WXK_DOWN) { + go = 1; + } + if (event.GetKeyCode() == WXK_UP) { + go = -1; + } + bool reverse = false; + int currrow = -1; + wxDataViewItem item; + //find next state != current state + if ((event.GetModifiers() & wxMOD_ALT) == wxMOD_ALT) { + reverse = true; + item = this->GetCurrentItem(); + } + //find next state == current state + if ((event.GetModifiers() & wxMOD_SHIFT) == wxMOD_SHIFT) { + item = this->GetCurrentItem(); + } + if (item.IsOk() && (go != 0)) { + event.Skip(false); + return; + } + event.Skip(true); } diff --git a/utils/log/Storage.cpp b/utils/log/Storage.cpp index bcac9e4..e6f64dd 100644 --- a/utils/log/Storage.cpp +++ b/utils/log/Storage.cpp @@ -341,6 +341,9 @@ wxString Storage::get_field(Line& l, MyConst::colField col) { case MyConst::colField::logbtype: return l.text.substr(l.logbtype.s, l.logbtype.l); break; + case MyConst::colField::logSERVER: + return l.text.substr(l.logSERVER.s, l.logSERVER.l); + break; default: break; } @@ -434,6 +437,9 @@ 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(); + st.logSERVER = { static_cast(t.Len()),static_cast(logCursorpos.Len()) }; + t += logCursorpos; //fields.Add(logType); //st.logType = { t.Len(),logType.Len() }; //t += logType; diff --git a/utils/log/StorageModel.cpp b/utils/log/StorageModel.cpp index 0e67259..897542f 100644 --- a/utils/log/StorageModel.cpp +++ b/utils/log/StorageModel.cpp @@ -268,7 +268,7 @@ void StorageModel::BuildColumns(MyDataViewCtrl* ctrl) { new MyCustomRendererText(wxDATAVIEW_CELL_EDITABLE, StorageModel::Col_LogTime), StorageModel::Col_LogTime, wxCOL_WIDTH_AUTOSIZE, - wxALIGN_LEFT, + wxALIGN_NOT, wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE )); colmap[StorageModel::Col_LogTime] = MyConst::colField::logtime; @@ -278,7 +278,7 @@ void StorageModel::BuildColumns(MyDataViewCtrl* ctrl) { new MyCustomRendererText(wxDATAVIEW_CELL_EDITABLE, StorageModel::Col_User), StorageModel::Col_User, wxCOL_WIDTH_AUTOSIZE, - wxALIGN_LEFT, + wxALIGN_NOT, wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE )); colmap[StorageModel::Col_User] = MyConst::colField::loguser; @@ -287,7 +287,7 @@ void StorageModel::BuildColumns(MyDataViewCtrl* ctrl) { new MyCustomRendererText(wxDATAVIEW_CELL_EDITABLE, StorageModel::Col_Db), StorageModel::Col_Db, 30, - wxALIGN_LEFT, + wxALIGN_NOT, wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE )); colmap[StorageModel::Col_Db] = MyConst::colField::logdb; @@ -296,7 +296,7 @@ void StorageModel::BuildColumns(MyDataViewCtrl* ctrl) { new MyCustomRendererText(wxDATAVIEW_CELL_EDITABLE, StorageModel::Col_PID), StorageModel::Col_PID, 60, - wxALIGN_LEFT, + wxALIGN_NOT, wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE )); colmap[StorageModel::Col_PID] = MyConst::colField::logpid; @@ -305,7 +305,7 @@ void StorageModel::BuildColumns(MyDataViewCtrl* ctrl) { new MyCustomRendererText(wxDATAVIEW_CELL_EDITABLE, StorageModel::Col_Host), StorageModel::Col_Host, 90, - wxALIGN_LEFT, + wxALIGN_NOT, wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE )); colmap[StorageModel::Col_Host] = MyConst::colField::loghost; @@ -314,7 +314,7 @@ void StorageModel::BuildColumns(MyDataViewCtrl* ctrl) { new MyCustomRendererText(wxDATAVIEW_CELL_EDITABLE, StorageModel::Col_App), StorageModel::Col_App, 100, - wxALIGN_LEFT, + wxALIGN_NOT, wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE )); colmap[StorageModel::Col_App] = MyConst::colField::logappname; @@ -323,7 +323,7 @@ void StorageModel::BuildColumns(MyDataViewCtrl* ctrl) { new MyCustomRendererText(wxDATAVIEW_CELL_EDITABLE, StorageModel::Col_Hint), StorageModel::Col_Hint, 90, - wxALIGN_LEFT, + wxALIGN_NOT, wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE )); colmap[StorageModel::Col_Hint] = MyConst::colField::logHint; @@ -332,7 +332,7 @@ void StorageModel::BuildColumns(MyDataViewCtrl* ctrl) { new MyCustomRendererText(wxDATAVIEW_CELL_EDITABLE, StorageModel::Col_Detail), StorageModel::Col_Detail, 60, - wxALIGN_LEFT, + wxALIGN_NOT, wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE )); colmap[StorageModel::Col_Detail] = MyConst::colField::logDetail; @@ -342,10 +342,19 @@ void StorageModel::BuildColumns(MyDataViewCtrl* ctrl) { new MyCustomRendererText(wxDATAVIEW_CELL_EDITABLE, StorageModel::Col_Message), StorageModel::Col_Message, wxCOL_WIDTH_AUTOSIZE, - wxALIGN_LEFT, + wxALIGN_NOT, wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE )); colmap[StorageModel::Col_Message] = MyConst::colField::logMessage; + ctrl->AppendColumn( + new wxDataViewColumn("Server", + new MyCustomRendererText(wxDATAVIEW_CELL_EDITABLE, StorageModel::Col_Server), + StorageModel::Col_Server, + wxCOL_WIDTH_AUTOSIZE, + wxALIGN_NOT, + wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE + )); + colmap[StorageModel::Col_Server] = MyConst::colField::logSERVER; } @@ -368,6 +377,7 @@ StorageModel::StorageModel(MyDataViewCtrl* view) : bool StorageModel::setFilter(int col, wxString val, int flags, MyDataViewCtrl* view) { bool r = store->SetFilter(colmap[col], val, flags); + m_view->UnselectAll(); Reset(store->getCountFilter()); if (col != -1) { wxDataViewColumn* vc = view->GetColumn(col); @@ -382,6 +392,7 @@ int StorageModel::testFilter(int col, int position = 0) { } void StorageModel::ApplyFilter() { store->ApplyFilter(); + m_view->UnselectAll(); Reset(store->getCountFilter()); } @@ -406,6 +417,8 @@ bool StorageModel::Prepend(const wxString& text) IncCountFreq(StorageModel::Col_Hint, store->GetFieldStorage(row, MyConst::colField::logHint, false)); val = store->GetFieldStorage(row, MyConst::colField::logSqlstate, false); IncCountFreq(StorageModel::Col_ToggleIconText, val); + val = store->GetFieldStorage(row, MyConst::colField::logSERVER, false); + IncCountFreq(StorageModel::Col_Server, val); if (store->ApplyFilter(row)) {