mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 14:15:49 -06:00
Added division of digits for thousands. Only integers. Only Result query.
Для результатов запросов для целых чисел добавлено визуальное разделение тысяч. Величина отделения задаётся в точках и храниться в pgadmin3opt.json в параметре "thousandsWidthSeparator" раздела "ctlSQLGrid" разрешенные величины от -15 до 15. Значение по умолчанию 0. В отличии от стандартного разделителя тысяч этот влияет только на отображении чисел.
This commit is contained in:
parent
1dc289a625
commit
979d709843
4 changed files with 233 additions and 156 deletions
|
|
@ -74,13 +74,28 @@ ctlSQLGrid::ctlSQLGrid(wxWindow* parent, wxWindowID id, const wxPoint& pos, cons
|
|||
Bind(wxEVT_THREAD, &ctlSQLGrid::OnShowPopup, this);
|
||||
setresizedpi();
|
||||
SetDefaultCellOverflow(false);
|
||||
//SetDefaultRenderer(new wxGridCellAutoWrapStringRenderer);
|
||||
SetDefaultRenderer(new CursorCellRenderer);
|
||||
// load pgadmin3opt.json
|
||||
wxJSONValue def(wxJSONType::wxJSONTYPE_OBJECT);
|
||||
wxJSONValue opt(wxJSONType::wxJSONTYPE_OBJECT);
|
||||
int t_width=0;
|
||||
def["thousandsWidthSeparator"]=t_width;
|
||||
settings->ReloadJsonFileIfNeed();
|
||||
settings->ReadJsonObect("ctlSQLGrid", opt, def);
|
||||
if (!opt.IsNull()) { // check
|
||||
int tmp=opt["thousandsWidthSeparator"].AsInt();
|
||||
if (tmp<-15 || tmp>15) opt["thousandsWidthSeparator"]=def["thousandsWidthSeparator"];
|
||||
}
|
||||
else
|
||||
opt = def;
|
||||
int thousandsWidthSeparator = opt["thousandsWidthSeparator"].AsInt();
|
||||
|
||||
SetDefaultRenderer(new CursorCellRenderer(thousandsWidthSeparator));
|
||||
//SetUseNativeColLabels(true);
|
||||
//UseNativeColHeader(true);
|
||||
SetCellHighlightColour(wxColor(0, 0, 0));
|
||||
#ifdef __WXGTK__
|
||||
wxColour selbg = GetSelectionBackground();
|
||||
wxColour cbg = GetBackgroundColour();
|
||||
wxColour labbg = GetLabelBackgroundColour();
|
||||
wxString t1 = selbg.GetAsString();
|
||||
wxString t2 = labbg.GetAsString();
|
||||
|
|
@ -93,6 +108,13 @@ ctlSQLGrid::ctlSQLGrid(wxWindow* parent, wxWindowID id, const wxPoint& pos, cons
|
|||
wxColour labbgn(min, min, min);
|
||||
SetLabelBackgroundColour(labbgn);
|
||||
}
|
||||
if (cline.GetRGB() == cbg.GetRGB()) {
|
||||
int min = wxMin(cline.GetBlue(), cline.GetGreen());
|
||||
min = wxMin(min, cline.GetRed());
|
||||
if (min > 200) min = min - 30; else min = min + 30;
|
||||
wxColour newgridclr(min, min, min);
|
||||
SetGridLineColour(newgridclr);
|
||||
}
|
||||
#endif
|
||||
grp = NULL;
|
||||
isSort = false;
|
||||
|
|
@ -300,10 +322,11 @@ wxString ctlSQLGrid::GetExportLine(int row, wxArrayInt cols)
|
|||
head = head + GetColumnName(cols[col]);
|
||||
wxString text;
|
||||
bool isnull=false;
|
||||
int pgtype=0;
|
||||
if ( t && generatesql > 0)
|
||||
{
|
||||
// only insert , in_list and where list
|
||||
text = t->GetValueWithNull( row, cols[col] , &isnull );
|
||||
text = t->GetValueWithNull( row, cols[col] , &isnull, &pgtype );
|
||||
} else text = GetCellValue(row, cols[col]);
|
||||
|
||||
wxString cname = GetColumnName(cols[col]);
|
||||
|
|
@ -1295,4 +1318,194 @@ bool ctlSQLGrid::FullArrayCollapseRowsPlan(bool clear)
|
|||
return true;
|
||||
}
|
||||
|
||||
//// CursorCellRenderer
|
||||
|
||||
void CursorCellRenderer::Draw(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc,
|
||||
const wxRect& rect, int row, int col, bool isSelected)
|
||||
{
|
||||
int hAlign, vAlign;
|
||||
int sPos = -1;
|
||||
bool multiline = false;
|
||||
attr.GetAlignment(&hAlign, &vAlign);
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//CursorCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected); //
|
||||
dc.SetBackgroundMode(wxSOLID);
|
||||
bool istruncateLine=false;
|
||||
wxString text = grid.GetCellValue(row, col);
|
||||
int len= text.length();
|
||||
bool isfirst=true;
|
||||
bool isnumber=(hAlign == wxALIGN_RIGHT && len<20 && text.IsNumber());
|
||||
// grey out fields if the grid is disabled
|
||||
retry:
|
||||
if (grid.IsEnabled())
|
||||
{
|
||||
istruncateLine=text.Right(5)=="(...)";
|
||||
if (isSelected)
|
||||
{
|
||||
wxColour clr;
|
||||
if (wxWindow::FindFocus() == grid.GetGridWindow())
|
||||
clr = grid.GetSelectionBackground();
|
||||
else
|
||||
clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW);
|
||||
|
||||
|
||||
dc.SetBrush(*wxTheBrushList->FindOrCreateBrush(clr));
|
||||
}
|
||||
else
|
||||
{
|
||||
wxColor color;
|
||||
color.Set(239, 228, 176);
|
||||
if ((sPos = text.Find(wxT('\n'))) != wxNOT_FOUND) {
|
||||
dc.SetBrush(*wxTheBrushList->FindOrCreateBrush(color));
|
||||
multiline = true;
|
||||
}
|
||||
else
|
||||
dc.SetBrush(*wxTheBrushList->FindOrCreateBrush(attr.GetBackgroundColour()));
|
||||
}
|
||||
// replace \t to u+2192
|
||||
wxUniChar cc = 8594;
|
||||
text.Replace("\t", cc);
|
||||
}
|
||||
else
|
||||
{
|
||||
dc.SetBrush(*wxTheBrushList->FindOrCreateBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
|
||||
}
|
||||
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.DrawRectangle(rect);
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
SetTextColoursAndFont(grid, attr, dc, isSelected);
|
||||
ctlSQLGrid* ctrl = static_cast<ctlSQLGrid*>(&grid);
|
||||
if (!ctrl->searchStr.IsEmpty()) {
|
||||
int pp;
|
||||
pp = text.Find(ctrl->searchStr);
|
||||
if (pp >= 0) {
|
||||
wxArrayString lines;
|
||||
grid.StringToLines(text, lines);
|
||||
wxRect r;
|
||||
r.y = rect.y;
|
||||
dc.SetBrush(*wxYELLOW_BRUSH);
|
||||
size_t nLines = lines.GetCount();
|
||||
for (size_t l = 0; l < nLines; l++)
|
||||
{
|
||||
const wxString& line = lines[l];
|
||||
pp = line.Find(ctrl->searchStr);
|
||||
if (line.empty() || (pp == -1))
|
||||
{
|
||||
r.y += dc.GetCharHeight();
|
||||
continue;
|
||||
}
|
||||
|
||||
int lineWidth, lineWidthP, lineHeight, start = 0;
|
||||
int dopx=0;
|
||||
wxString pref;
|
||||
if (hAlign == wxALIGN_RIGHT) {
|
||||
start = pp + ctrl->searchStr.Len();
|
||||
pref = line.substr(start);
|
||||
if (isnumber) {
|
||||
int ll=pref.length();
|
||||
int num_sep=ll/3;
|
||||
//if (ll % 3 == 0 && num_sep>0 ) num_sep--;
|
||||
dopx=num_sep*thousands_pixel_sep;
|
||||
}
|
||||
}
|
||||
else
|
||||
pref = line.substr(start, pp);
|
||||
|
||||
dc.GetTextExtent(pref, &lineWidthP, &lineHeight);
|
||||
lineWidthP+=dopx;
|
||||
r.x = rect.x + lineWidthP;
|
||||
pref = line.substr(pp, ctrl->searchStr.Len());
|
||||
dc.GetTextExtent(pref, &lineWidth, &lineHeight);
|
||||
r.width = lineWidth;
|
||||
r.height = lineHeight;
|
||||
if (hAlign == wxALIGN_RIGHT) r.x = rect.x + (rect.width - lineWidth - lineWidthP);
|
||||
if (!(r.y < (rect.y + rect.height))) { r.y = rect.y + rect.height - 5; r.height = 5; }
|
||||
if (!((r.x < (rect.x + rect.width)))) { r.x = rect.x + rect.width - 5; r.width = 5; }
|
||||
dc.DrawRoundedRectangle(r, 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!multiline) {
|
||||
//int textWidth = dc.GetTextExtent(text).GetWidth();
|
||||
wxEllipsizeMode mode(wxELLIPSIZE_END);
|
||||
if (hAlign == wxALIGN_RIGHT) mode = wxELLIPSIZE_START;
|
||||
const wxString& ellipsizedText = wxControl::Ellipsize
|
||||
(
|
||||
text,
|
||||
dc,
|
||||
mode,
|
||||
rect.GetWidth() - 2,
|
||||
wxELLIPSIZE_FLAGS_NONE
|
||||
);
|
||||
if (ellipsizedText != text)
|
||||
text = ellipsizedText; // small width
|
||||
else
|
||||
{
|
||||
bool isDraw=false;
|
||||
if (isnumber && isfirst)
|
||||
/* Add thousands separator */
|
||||
{
|
||||
int pos = text.find('.');
|
||||
if (pos == wxString::npos)
|
||||
pos = len;
|
||||
int x=rect.GetRight()-1;
|
||||
int yb=rect.GetTop();
|
||||
int c=0;
|
||||
while (pos > 0)
|
||||
{
|
||||
pos -= 3;
|
||||
wxString tri;
|
||||
if (pos >= 0)
|
||||
{
|
||||
tri=text.substr(pos,3);
|
||||
} else tri=text.substr(0,pos+3);
|
||||
|
||||
wxSize tripl=dc.GetTextExtent(tri);
|
||||
x=x-tripl.GetX();
|
||||
if (c>0) x-=thousands_pixel_sep;
|
||||
dc.DrawText(tri,x,yb);
|
||||
c++;
|
||||
}
|
||||
int new_width=rect.GetRight()-x;
|
||||
isfirst=!isfirst;
|
||||
if (new_width>=rect.GetWidth()) goto retry; // small width
|
||||
isDraw=true;
|
||||
}
|
||||
if (isDraw) return;
|
||||
}
|
||||
|
||||
} // this draw one line
|
||||
|
||||
grid.DrawTextRectangle(dc, text,
|
||||
rect, hAlign, vAlign);
|
||||
if (istruncateLine) {
|
||||
dc.SetPen(*wxRED_PEN);
|
||||
dc.DrawLine(wxPoint(rect.x,rect.y+rect.GetHeight()-2),wxPoint(rect.x+rect.width,rect.y+rect.GetHeight()-2));
|
||||
}
|
||||
}
|
||||
|
||||
CursorCellRenderer::CursorCellRenderer(int thous_pixel_sep):wxGridCellStringRenderer() {
|
||||
thousands_pixel_sep=thous_pixel_sep;
|
||||
}
|
||||
wxSize CursorCellRenderer::GetBestSize(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
int row, int col){
|
||||
dc.SetFont(attr.GetFont());
|
||||
const wxString text=grid.GetCellValue(row, col);
|
||||
wxSize sz=dc.GetMultiLineTextExtent(text);
|
||||
int len=text.length();
|
||||
if (thousands_pixel_sep !=0 && len<20 && text.IsNumber()) {
|
||||
if (text[0]=='-') len--;
|
||||
int num_sep=len/3;
|
||||
if (len % 3 == 0 && num_sep>0 ) num_sep--;
|
||||
sz.x=sz.x+num_sep*thousands_pixel_sep +1;
|
||||
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -474,7 +474,8 @@ wxString ctlSQLResult::GenerateTemplate(wxString &templ,int action)
|
|||
if (rows.Count()>0) r=rows[r]; else r=r;
|
||||
}
|
||||
bool isnull=false;
|
||||
wxString text = t->GetValueWithNull( r, e.column , &isnull );
|
||||
int pgtype=0;
|
||||
wxString text = t->GetValueWithNull( r, e.column , &isnull, &pgtype );
|
||||
bool needQuote = false;
|
||||
if (qt == 1)
|
||||
{
|
||||
|
|
@ -1330,7 +1331,7 @@ wxString sqlResultTable::GetValueFast(int row, int col)
|
|||
}
|
||||
return "";
|
||||
}
|
||||
wxString sqlResultTable::GetValueWithNull(int row, int col, bool *isnull) {
|
||||
wxString sqlResultTable::GetValueWithNull(int row, int col, bool *isnull, int *pgtype) {
|
||||
wxString s;
|
||||
if (thread && thread->DataValid())
|
||||
{
|
||||
|
|
@ -1340,6 +1341,7 @@ wxString sqlResultTable::GetValueWithNull(int row, int col, bool *isnull) {
|
|||
thread->DataSet()->Locate(row + 1);
|
||||
wxString s = thread->DataSet()->GetVal(col);
|
||||
*isnull = thread->DataSet()->IsNull(col);
|
||||
*pgtype = thread->DataSet()->ColTypClass(col);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue