mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 14:15:49 -06:00
643 lines
18 KiB
C++
643 lines
18 KiB
C++
#include "pgAdmin3.h"
|
|
|
|
#include "log/MyDataViewCtrl.h"
|
|
#include "log/StorageModel.h"
|
|
#include "wx/headerctrl.h"
|
|
#include "wx/itemattr.h"
|
|
#include "wx/dataview.h"
|
|
//#include <map>
|
|
#include <set>
|
|
|
|
|
|
BEGIN_EVENT_TABLE(MyDataViewCtrl, wxDataViewCtrl)
|
|
EVT_MOTION(MyDataViewCtrl::OnMouseMove)
|
|
|
|
END_EVENT_TABLE()
|
|
|
|
#ifdef MYTEST
|
|
#include <wx/textfile.h>
|
|
void MyDataViewCtrl::OnTimer(wxTimerEvent& event) {
|
|
// wxLogMessage("OnTimer called.");
|
|
if (linenumber == -1) {
|
|
wxTextFile tfile;
|
|
wxString str;
|
|
tfile.Open("logAdd.csv");
|
|
|
|
// read the first line
|
|
str = tfile.GetFirstLine() + "\n";
|
|
|
|
// read all lines one by one
|
|
// until the end of the file
|
|
while (!tfile.Eof())
|
|
{
|
|
str += tfile.GetNextLine() + "\n";
|
|
}
|
|
tfile.Close();
|
|
CSVLineTokenizer tk(str);
|
|
wxString line;
|
|
while (tk.HasMoreLines())
|
|
{
|
|
line.Clear();
|
|
|
|
bool partial;
|
|
line = tk.GetNextLine(partial);
|
|
if (partial)
|
|
{
|
|
break;
|
|
}
|
|
//Prepend(line);
|
|
logadd.Add(line);
|
|
|
|
}
|
|
linenumber = 0;
|
|
}
|
|
if (logadd.GetCount() > linenumber) {
|
|
StorageModel* m = dynamic_cast<StorageModel*>(GetModel());
|
|
//m->Prepend(logadd[linenumber++]);
|
|
AddRow(logadd[linenumber++]);
|
|
wxString l = wxString::Format("rows %d", m->GetCount());
|
|
st->SetLabelText(l);
|
|
if (m->getGroupFilter()) Refresh();
|
|
}
|
|
}
|
|
#endif
|
|
void MyDataViewCtrl::setSettingString(wxString setstr) {
|
|
wxString s;
|
|
wxStringTokenizer tokenizer(setstr, ";");
|
|
|
|
for (int i = 0; i < GetColumnCount(); i++) {
|
|
if (!tokenizer.HasMoreTokens()) break;
|
|
wxString token = tokenizer.GetNextToken();
|
|
wxDataViewColumn* vc = GetColumn(i);
|
|
int w;
|
|
w = wxAtoi(token);
|
|
vc->SetWidth(w);
|
|
}
|
|
return;
|
|
}
|
|
|
|
wxString MyDataViewCtrl::getSettingString() {
|
|
wxString s;
|
|
for (int i = 0; i < GetColumnCount(); i++) {
|
|
wxDataViewColumn* vc = GetColumn(i);
|
|
int width = vc->GetWidth();
|
|
if (!s.IsEmpty()) s = s + ";";
|
|
s = s + wxString::Format("%d", width);
|
|
}
|
|
//s = s + wxString::Format(";%d", modeGroup);
|
|
return s;
|
|
}
|
|
void MyDataViewCtrl::setGroupMode(bool mode) {
|
|
StorageModel* m = dynamic_cast<StorageModel*>(GetModel());
|
|
m->setGroupFilter(mode);
|
|
wxItemAttr attr;
|
|
if (m->getGroupFilter())
|
|
{
|
|
//attr.SetTextColour(*wxRED);
|
|
//attr.GetFont().Underlined();
|
|
attr.SetFont(attr.GetFont().Underlined());
|
|
//attr.GetFont().
|
|
//wxFontStyle s=attr.GetFont().GetStyle();
|
|
//attr.SetFont(attr.GetFont().Strikethrough());
|
|
}
|
|
//else: leave it as default to disable custom header attributes
|
|
wxString l = wxString::Format("rows %d", m->GetRowCount());
|
|
st->SetLabelText(l);
|
|
|
|
if (!SetHeaderAttr(attr)) {
|
|
//wxLogMessage("Sorry, header attributes not supported on this platform");
|
|
}
|
|
|
|
|
|
}
|
|
void MyDataViewCtrl::ViewGroup(bool view) {
|
|
StorageModel* m = dynamic_cast<StorageModel*>(GetModel());
|
|
Storage* sta = m->getStorage();
|
|
if (view) {
|
|
selectRowGroup = GetSelection();
|
|
if (!selectRowGroup.IsOk()) return;
|
|
int rowselectGroup = m->GetRow(selectRowGroup);
|
|
sta->setDetailGroupRow(rowselectGroup);
|
|
|
|
}
|
|
else sta->setDetailGroupRow(-1);
|
|
m->ApplyFilter();
|
|
if (!view) {
|
|
SetCurrentItem(selectRowGroup);
|
|
EnsureVisible(selectRowGroup);
|
|
}
|
|
wxString l = wxString::Format("rows %d", m->GetRowCount());
|
|
st->SetLabelText(l);
|
|
|
|
|
|
}
|
|
void MyDataViewCtrl::AddRow(wxString csvtext) {
|
|
StorageModel* m = dynamic_cast<StorageModel*>(GetModel());
|
|
wxDataViewItem select;
|
|
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;
|
|
int rowselect = m->GetRow(select);
|
|
// add visible row
|
|
int rowlast = m->GetRowCount() - 1;
|
|
if ((rowlast - 1) == rowselect) {
|
|
//m->GetItem();
|
|
select = m->GetItem(rowlast);
|
|
SetCurrentItem(select);
|
|
EnsureVisible(select);
|
|
ScrollPages(1);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
void MyDataViewCtrl::OnEVT_DATAVIEW_SELECTION_CHANGED(wxDataViewEvent& event) {
|
|
StorageModel* m = dynamic_cast<StorageModel*>(GetModel());
|
|
int r = m->GetRow(event.GetItem());
|
|
if (m->getGroupFilter() && r != -1) {
|
|
Storage* sta = m->getStorage();
|
|
sta->ClearCount(r);
|
|
int a=sta->GetTotalCountGroup(r);
|
|
|
|
wxString l = wxString::Format("Total rows in group %d", a);
|
|
st->SetLabelText(l);
|
|
|
|
//EnsureVisible(event.GetItem());
|
|
}
|
|
|
|
//wxLogMessage("wxEVT_DATAVIEW_SELECTION_CHANGED, First selected Item row: %d", r);
|
|
|
|
}
|
|
void MyDataViewCtrl::ClearAllFilter(bool no_apply) {
|
|
int colt = 0;
|
|
int col = 0;
|
|
bool all = false;
|
|
bool clear = false;
|
|
wxArrayInt fCol;
|
|
StorageModel* m = dynamic_cast<StorageModel*>(GetModel());
|
|
for (int j = 0; j < GetColumnCount(); j++) {
|
|
col = j;
|
|
clear = false;
|
|
colt = 0;
|
|
while (colt != -1) {
|
|
colt = m->testFilter(col, colt);
|
|
if (colt >= 0) {
|
|
m->DropColFilter(colt);
|
|
clear = true;
|
|
all = true;
|
|
// colt++;
|
|
}
|
|
}
|
|
if (clear) {
|
|
// m->ApplyFilter();
|
|
fCol.Add(col);
|
|
// wxDataViewColumn* vc = GetColumn(col);
|
|
// vc->SetBitmap(wxNullBitmap);
|
|
}
|
|
}
|
|
if (all) {
|
|
if (!no_apply) m->ApplyFilter();
|
|
for (auto i : fCol) {
|
|
wxDataViewColumn* vc = GetColumn(i);
|
|
vc->SetBitmap(wxNullBitmap);
|
|
}
|
|
}
|
|
if (!no_apply) {
|
|
wxString l = wxString::Format("rows %d", m->GetRowCount());
|
|
st->SetLabelText(l);
|
|
}
|
|
}
|
|
void MyDataViewCtrl::ModUserFilter(wxString FilterName, wxString wxOper, wxComboBox *combo,wxTextCtrl *textctrl) {
|
|
StorageModel* m = dynamic_cast<StorageModel*>(GetModel());
|
|
Storage* st = m->getStorage();
|
|
if (wxOper == "ChangeFilter") {
|
|
int n= combo->GetSelection();
|
|
wxString fn = combo->GetString(n);
|
|
std::deque<LineFilter> rez = st->getFilter(fn);
|
|
textctrl->Clear();
|
|
if (rez.size() > 0) {
|
|
wxString listflt;
|
|
listflt = st->getFilterString(rez);
|
|
smart->SetSelection(n);
|
|
textctrl->AppendText(listflt);
|
|
if (FilterName != "skipapply") {
|
|
ClearAllFilter(true);
|
|
m->setFilterArray(rez, this);
|
|
}
|
|
}
|
|
else {
|
|
textctrl->AppendText("");
|
|
ClearAllFilter(false);
|
|
}
|
|
|
|
}
|
|
if (wxOper == "RemoveFilter") {
|
|
wxString txt = combo->GetValue();
|
|
if (!txt.IsEmpty()) {
|
|
st->removeFilter(txt);
|
|
textctrl->Clear();
|
|
int n = combo->GetSelection();
|
|
combo->Delete(n);
|
|
combo->SetValue("");
|
|
ClearAllFilter(false);
|
|
|
|
}
|
|
}
|
|
if (wxOper == "AddUserFilter") {
|
|
if (!FilterName.IsEmpty()) {
|
|
|
|
AddFilterIgnore(FilterName);
|
|
st->saveFilters();
|
|
wxOper = "Init";
|
|
}
|
|
|
|
}
|
|
if (wxOper == "Init") {
|
|
wxArrayString arr;
|
|
|
|
int j = st->getFilterNames(arr);
|
|
if (j > 0) {
|
|
combo->Clear();
|
|
combo->Append(arr);
|
|
smart->Append(arr);
|
|
combo->SelectNone();
|
|
if (!FilterName.IsEmpty()) {
|
|
int n = combo->FindString(FilterName);
|
|
if (n >= 0) {
|
|
combo->SetSelection(n);
|
|
smart->SetSelection(n);
|
|
ModUserFilter("skipapply", "ChangeFilter", combo, textctrl);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
void MyDataViewCtrl::AddFilterIgnore(wxString Fname) {
|
|
int colt = 0;
|
|
int col = 0;
|
|
bool all = false;
|
|
bool clear = false;
|
|
wxArrayInt fCol;
|
|
StorageModel* m = dynamic_cast<StorageModel*>(GetModel());
|
|
Storage* st = m->getStorage();
|
|
wxString text;
|
|
|
|
for (int j = 0; j < GetColumnCount(); j++) {
|
|
col = j;
|
|
clear = false;
|
|
colt = 0;
|
|
while (colt != -1) {
|
|
colt = m->testFilter(col, colt);
|
|
if (colt >= 0) {
|
|
//m->DropColFilter(colt);
|
|
wxString expr=st->GetStringFilterExpr(colt,true);
|
|
st->addLineFilterStr(expr,Fname);
|
|
Fname = "";
|
|
text = text + expr + "\r\n";
|
|
all = true;
|
|
colt++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (all) {
|
|
st->addLineFilterStr("","");
|
|
wxMessageBox("Create filter\r\n\r\n"+text, _("Warning"), wxICON_INFORMATION | wxOK);
|
|
|
|
}
|
|
else {
|
|
wxMessageBox("Filter empty.", _("Warning"), wxICON_INFORMATION | wxOK);
|
|
}
|
|
|
|
}
|
|
void MyDataViewCtrl::OnEVT_DATAVIEW_CONTEXT_MENU(wxCommandEvent& event) {
|
|
int id = event.GetId();
|
|
wxMenu* mi = static_cast<wxMenu*>(event.GetEventObject());
|
|
wxString label = mi->GetLabelText(id);
|
|
StorageModel* m = dynamic_cast<StorageModel*>(GetModel());
|
|
#ifdef WIN32
|
|
int col = (long long)mi->GetClientData();
|
|
#else
|
|
long nc=(long)mi->GetClientData();
|
|
int col= nc & 0xFFFF;
|
|
#endif
|
|
if (id > 100) {
|
|
int colt = 0;
|
|
bool clear = false;
|
|
//int pos = 0;
|
|
bool all = (label == "Clear All");
|
|
Storage* stor = m->getStorage();
|
|
wxString expr;
|
|
while (colt != -1) {
|
|
colt = m->testFilter(col, colt);
|
|
if (colt >= 0) {
|
|
expr = stor->GetStringFilterExpr(colt);
|
|
if (expr == label || all) {
|
|
m->DropColFilter(colt);
|
|
clear = true;
|
|
} else
|
|
colt++;
|
|
}
|
|
}
|
|
if (clear) {
|
|
m->ApplyFilter();
|
|
if (m->testFilter(col, 0) == -1) {
|
|
wxDataViewColumn* vc = GetColumn(col);
|
|
vc->SetBitmap(wxNullBitmap);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
m->setFilter(col, label.AfterFirst(' '), 0, this);
|
|
//wxDataViewColumn* vc=GetColumn(col);
|
|
//vc->SetBitmap(m->bitmapflt);
|
|
|
|
}
|
|
wxString l = wxString::Format("rows %d", m->GetRowCount());
|
|
st->SetLabelText(l);
|
|
|
|
if (col == StorageModel::Col_User) {
|
|
|
|
|
|
//m->setFilter(col, label.AfterFirst(' '));
|
|
// wxMessageBox("You have selected Item 1", "Your selection", wxOK | wxICON_INFORMATION);
|
|
}
|
|
if (event.GetId() == 2) {
|
|
// wxMessageBox("You have selected Item 2", "Your selection", wxOK | wxICON_INFORMATION);
|
|
}
|
|
|
|
}
|
|
// правая кнопка на ячейке
|
|
void MyDataViewCtrl::OnContextMenu(wxDataViewEvent& event) {
|
|
//wxString title = m_music_model->GetTitle(event.GetItem());
|
|
//wxLogMessage("wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, Item: %s", title);
|
|
int c = event.GetColumn();
|
|
if (c < 0) return;
|
|
StorageModel* m = dynamic_cast<StorageModel*>(GetModel());
|
|
int row = m->GetRow(event.GetItem());
|
|
int ncol;
|
|
wxVariant vr;
|
|
if (row >= 0)
|
|
{
|
|
|
|
//int ncol = GetColumn(event.GetColumn())->GetModelColumn();
|
|
ncol = event.GetColumn();
|
|
m->GetValueByRow(vr, row, ncol);
|
|
if (ncol == 0) {
|
|
wxDataViewIconText ic;
|
|
ic << vr;
|
|
wxString str = ic.GetText();
|
|
vr = str;
|
|
}
|
|
}
|
|
int pos = GetColumnPosition(event.GetDataViewColumn());
|
|
|
|
wxString str = wxString::Format("col: %d row: %d val: %s", pos, row, vr.GetString());
|
|
int flags = 0;
|
|
if (modctrl) flags = FL_REVERSE;
|
|
m->setFilter(ncol, vr.GetString(), flags, this);
|
|
//wxDataViewColumn* vc = GetColumn(event.GetColumn());
|
|
//vc->SetBitmap(m->bitmapflt);
|
|
|
|
//wxMessageBox(str, "Your selection", wxOK | wxICON_INFORMATION);
|
|
|
|
|
|
}
|
|
auto cmp = [](std::pair<std::string, int> const& a, std::pair<std::string, int> const& b)
|
|
{
|
|
return a.second != b.second ? a.second < b.second : a.first < b.first;
|
|
};
|
|
void MyDataViewCtrl::OnEVT_DATAVIEW_COLUMN_HEADER_CLICK(wxDataViewEvent& event) {
|
|
StorageModel* m = dynamic_cast<StorageModel*>(GetModel());
|
|
int col = event.GetColumn();
|
|
if (event.GetColumn() == StorageModel::Col_User)
|
|
{
|
|
}
|
|
const int rowChanged = m->GetRow(event.GetItem());
|
|
wxMenu menu;
|
|
//menu.SetTitle(event.GetDataViewColumn()->GetTitle());
|
|
int i = 1;
|
|
int colt = m->testFilter(col, 0);
|
|
if (colt >= 0) {
|
|
wxMenu* menus = new wxMenu();
|
|
menus->SetClientData((void*)col);
|
|
Storage* stor = m->getStorage();
|
|
menus->Append(101 + i++, "Clear All");
|
|
wxString expr;
|
|
while (colt != -1) {
|
|
expr = stor->GetStringFilterExpr(colt);
|
|
menus->Append(101 + i++, expr);
|
|
colt = m->testFilter(col, colt + 1);
|
|
}
|
|
menu.AppendSubMenu(menus, "Clear filters");
|
|
}
|
|
std::set<std::pair<int, std::string>> items;
|
|
std::pair<int, std::string> v;
|
|
int cc = 0;
|
|
MyHashCount::iterator it;
|
|
for (it = m->freqValues[col].begin(); it != m->freqValues[col].end(); ++it)
|
|
{
|
|
v = std::make_pair(it->second, it->first.ToStdString());
|
|
items.emplace(v);
|
|
//ma.emplace(it->first.ToStdString(), it->second);
|
|
cc++;
|
|
}
|
|
//std::sort(items.begin(), items.end(),cmp);
|
|
cc = cc - 20;
|
|
int cc0 = 0;
|
|
for (auto const& vk : items) {
|
|
cc0++;
|
|
if (cc0 < cc) continue;
|
|
wxString key = wxString(vk.second);
|
|
int value = vk.first;
|
|
wxString str = wxString::Format("%d %s", value, key);
|
|
menu.Append(i++, str);
|
|
|
|
}
|
|
|
|
//for (it = m->freqValues[col].begin(); it != m->freqValues[col].end(); ++it)
|
|
//{
|
|
// wxString key = it->first;
|
|
// int value = it->second;
|
|
// wxString str = wxString::Format("%d %s",value,key);
|
|
// menu.Append(i++, str);
|
|
//}
|
|
|
|
menu.SetClientData((void*)col);
|
|
this->PopupMenu(&menu);
|
|
event.Skip(false);
|
|
return;
|
|
|
|
event.Skip(true);
|
|
}
|
|
void MyDataViewCtrl::OnKEY_UP(wxKeyEvent& event) {
|
|
// goto next state code
|
|
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)) {
|
|
|
|
|
|
StorageModel* m = dynamic_cast<StorageModel*>(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);
|
|
|
|
}
|
|
void MyDataViewCtrl::OnMouseMove(wxMouseEvent& event) {
|
|
|
|
//event.Skip(true);
|
|
if (event.Dragging())
|
|
return;
|
|
|
|
wxClientDC dc(GetMainWindow());
|
|
PrepareDC(dc);
|
|
|
|
//wxPoint logPos(event.GetLogicalPosition(dc));
|
|
//wxPoint mc= GetMainWindow()->ScreenToClient(event.GetPosition());
|
|
wxPoint mc = event.GetPosition();
|
|
wxString position;
|
|
//position = wxString::Format("x=%d y=%d", logPos.x, logPos.y);
|
|
//wxLogMessage("Mouse pos %s", position);
|
|
int dy = 0;
|
|
wxSize sz;
|
|
#ifdef WIN32
|
|
wxHeaderCtrl* const header = GenericGetHeader();
|
|
if (header) {
|
|
sz = header->GetSize();
|
|
//header->Refresh();
|
|
dy = sz.GetHeight();
|
|
}
|
|
mc.y += dy;
|
|
#else
|
|
mc.y+=18; // only linux compile
|
|
#endif
|
|
wxDataViewItem item;
|
|
wxDataViewColumn* column;
|
|
|
|
HitTest(mc, item, column);
|
|
if (item != NULL && column != NULL)
|
|
{
|
|
StorageModel* m;
|
|
m = dynamic_cast<StorageModel*>(GetModel());
|
|
|
|
int row = m->GetRow(item);
|
|
|
|
if (row >= 0)
|
|
{
|
|
wxVariant vr;
|
|
int ncol = column->GetModelColumn();
|
|
if ((lastcol != ncol) || (lastrow != row)) {
|
|
m->GetValueByRow(vr, row, ncol);
|
|
wxSize szext = dc.GetTextExtent(vr.GetString());
|
|
int w = column->GetWidth();
|
|
if (szext.GetWidth() > w)
|
|
{
|
|
GetMainWindow()->SetToolTip(vr.GetString());
|
|
}
|
|
else
|
|
GetMainWindow()->UnsetToolTip();
|
|
lastrow = row;
|
|
lastcol = ncol;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
GetMainWindow()->UnsetToolTip();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GetMainWindow()->UnsetToolTip();
|
|
}
|
|
}
|