update pgadmin3.exe

This commit is contained in:
lsv 2026-03-05 00:13:25 +05:00
commit f362901393
13 changed files with 202 additions and 48 deletions

View file

@ -79,6 +79,15 @@ file(GLOB_RECURSE SOURCES
########################################################## ##########################################################
add_executable(${PROJECT_NAME} ) add_executable(${PROJECT_NAME} )
# После сборки — разделить символы и приложение
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Extracting debug symbols..."
COMMAND objcopy --only-keep-debug ${PROJECT_NAME} ${PROJECT_NAME}.debug
COMMAND objcopy --strip-debug ${PROJECT_NAME}
COMMAND objcopy --add-gnu-debuglink=${PROJECT_NAME}.debug ${PROJECT_NAME}
COMMENT "Split debug symbols into separate .debug file"
VERBATIM
)
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<CONFIG:Debug>:_DEBUG>) target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<CONFIG:Debug>:_DEBUG>)
target_sources(${PROJECT_NAME} PUBLIC pgAdmin3.cpp ${SOURCES}) target_sources(${PROJECT_NAME} PUBLIC pgAdmin3.cpp ${SOURCES})
if(CROSS_COMPILE STREQUAL "Windows") if(CROSS_COMPILE STREQUAL "Windows")

View file

@ -1498,7 +1498,7 @@ std::pair<int,int> ctlSQLBox::SelectQuery(int startposition)
int st = GetStyleAt(pos - 1); int st = GetStyleAt(pos - 1);
int endPos = GetLength(); int endPos = GetLength();
int pend=endPos; int pend=endPos;
int pstart=0; int pstart=pos;
if (ch == ';') { if (ch == ';') {
pend=pos; pend=pos;
@ -1521,7 +1521,9 @@ std::pair<int,int> ctlSQLBox::SelectQuery(int startposition)
int i=IsDBCSLeadByte(ch)? 2 : 1; int i=IsDBCSLeadByte(ch)? 2 : 1;
#else #else
int i=1; int i=1;
if (ch>255) i=2; if (ch>255*255) i=3;
else if (ch>255) i=2;
#endif #endif
pos=pos+i; pos=pos+i;
} }
@ -1547,7 +1549,8 @@ std::pair<int,int> ctlSQLBox::SelectQuery(int startposition)
int i=IsDBCSLeadByte(ch)? 2 : 1; int i=IsDBCSLeadByte(ch)? 2 : 1;
#else #else
int i=1; int i=1;
if (ch>255) i=2; if (ch>255*255) i=3;
else if (ch>255) i=2;
#endif #endif
pos=pos-i; pos=pos-i;

View file

@ -522,7 +522,7 @@ int ctlSQLGrid::CopyTableToHtml(wxString htmlquery) {
if (isRowsArray) rowPos = rows.Item(i); if (isRowsArray) rowPos = rows.Item(i);
if (GetRowSize(rowPos) == 0) continue; if (GetRowSize(rowPos) == 0) continue;
htm += "<tr>\n"; htm += "<tr>\n";
htm += wxString::Format("<td id=\"cn\"><pre>%d</pre></td>", rowPos + 1); htm += wxString::Format("<td id=\"cn\"><pre>%ld</pre></td>", rowPos + 1);
for (int c = 0; c < cols.Count(); c++) { for (int c = 0; c < cols.Count(); c++) {
wxString text = GetCellValue(rowPos, cols[c]); wxString text = GetCellValue(rowPos, cols[c]);
htm += wxString::Format("<td id=\"c%d\"><pre>%s</pre></td>", c, escapeHtml(text, true)); htm += wxString::Format("<td id=\"c%d\"><pre>%s</pre></td>", c, escapeHtml(text, true));
@ -1452,7 +1452,7 @@ retry:
if (pos == wxString::npos) if (pos == wxString::npos)
pos = len; pos = len;
int x=rect.GetRight()-1; int x=rect.GetRight()-1;
int yb=rect.GetTop(); int yb=rect.GetTop()+1; //GRID_TEXT_MARGIN
int c=0; int c=0;
while (pos > 0) while (pos > 0)
{ {

View file

@ -53,11 +53,32 @@ void ctlTreeJSON::OnChar(wxKeyEvent& event) {
} }
} }
if (event.GetKeyCode() == WXK_F1) {
int x=50;
int y=50;
this->ClientToScreen(&x,&y);
wxPoint screenPos(x,y);
wxString helpstr=R"(<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p><b>Ctrl-F</b> - find and colorize nodes</p>
<p><b>F3</b> - next find node</p>
<p><b>Shift-F3</b> - previos find node</p>
<p><b>Insert</b> - copy select node</p>
<p><b>Delete</b> - delete select node</p>
<p><b>Ctrl-Z</b> - Return source context node.</p>
</body>
</html>)";
showHelpHtml((wxWindow *)winMain,helpstr,screenPos, wxSize(450,300));
return;
}
if (event.GetKeyCode() == WXK_CONTROL_F) { if (event.GetKeyCode() == WXK_CONTROL_F) {
wxTextEntryDialog dialog(this, wxTextEntryDialog dialog(this,
wxT("Please enter find string\n") _("Please enter find string\n")
, ,
wxT("Find"), _("Find"),
m_FindString, m_FindString,
wxOK | wxCANCEL); //setName( dlg.GetValue().wc_str() ); wxOK | wxCANCEL); //setName( dlg.GetValue().wc_str() );
if (dialog.ShowModal() == wxID_OK) { if (dialog.ShowModal() == wxID_OK) {

View file

@ -393,7 +393,7 @@ void MyThread::getFilename() {
wxString sql = wxString::Format( wxString sql = wxString::Format(
"select * from ( \ "select * from ( \
select current_setting('log_directory') || '/' || name filename, modification filetime, size len \ select current_setting('log_directory') || '/' || name filename, modification filetime, size len \
FROM pg_ls_logdir() where name ~ %s ORDER BY modification DESC limit %d) l order by filetime ASC", po->conn->qtDbString(mask), limitfiles FROM pg_ls_logdir() where name ~ %s and name !~'db.csv$' ORDER BY modification DESC limit %d) l order by filetime ASC", po->conn->qtDbString(mask), limitfiles
); );

View file

@ -10,6 +10,8 @@
#define PREVIEW_ENDFIELD 16 #define PREVIEW_ENDFIELD 16
#define PREVIEW_ENDROW 32 #define PREVIEW_ENDROW 32
#define PREVIEW_QUOTE 64 #define PREVIEW_QUOTE 64
#define PREVIEW_RAWHTML 128
#define CHKFLAG2(val,par) ((val & par)>0) #define CHKFLAG2(val,par) ((val & par)>0)
enum class fmtpreview { enum class fmtpreview {
AUTO, AUTOVACCUM,CSV,SIMPLE_TEXT AUTO, AUTOVACCUM,CSV,SIMPLE_TEXT
@ -61,8 +63,12 @@ private:
bool saveTokenIfNotEmpty(wxString& savestr, int flag) { bool saveTokenIfNotEmpty(wxString& savestr, int flag) {
if (savestr.Length() > 0) { if (savestr.Length() > 0) {
wxString tmp = savestr; wxString tmp = savestr;
tmp=escapeHtml(tmp,true); if (CHKFLAG2(flag, PREVIEW_RAWHTML)) {
tmp.Replace(" ", "&nbsp;"); // nothing
} else {
tmp=escapeHtml(tmp,true);
tmp.Replace(" ", "&nbsp;");
}
if (CHKFLAG2(flag, PREVIEW_ENDROW)) tmp = "<br>"; if (CHKFLAG2(flag, PREVIEW_ENDROW)) tmp = "<br>";
if (CHKFLAG2(flag, PREVIEW_DIGITS)) { if (CHKFLAG2(flag, PREVIEW_DIGITS)) {
int l = savestr.Length(); int l = savestr.Length();

View file

@ -280,6 +280,8 @@ wxString qtIdent(const wxString &value); // add " if necessary
wxString qtTypeIdent(const wxString &value); // add " if necessary wxString qtTypeIdent(const wxString &value); // add " if necessary
bool make_identifier(const wxString &strname, wxString &s, wxString &n, bool islower); bool make_identifier(const wxString &strname, wxString &s, wxString &n, bool islower);
wxSize getScreenSizeForPoint(const wxPoint screenPos);
void showHelpHtml(wxWindow *parent, const wxString &htmlHelp,wxPoint screenPos, wxSize size);
#endif #endif

View file

@ -27,6 +27,10 @@ public:
return isvalid; return isvalid;
} }
void SetSizePopup(const wxSize& sz) { void SetSizePopup(const wxSize& sz) {
//wxPoint p=this->GetScreenPosition();
//p.x=p.x-50;
//p.y=p.y-50;
//SetSize(p.x,p.y, sz.x,sz.y,wxSIZE_FORCE);
SetSize(sz); SetSize(sz);
Layout(); Layout();
Fit(); Fit();
@ -84,7 +88,7 @@ public:
//htmlWindow->SetInitialSize(wxSize(htmlWindow->GetInternalRepresentation()->GetWidth(), htmlWindow->GetInternalRepresentation()->GetHeight())); //htmlWindow->SetInitialSize(wxSize(htmlWindow->GetInternalRepresentation()->GetWidth(), htmlWindow->GetInternalRepresentation()->GetHeight()));
//SetSize(wxSize(300,150)); //SetSize(wxSize(300,150));
topsizer->Add(htmlWindow, 1, wxALL, 1); topsizer->Add(htmlWindow, 1, wxEXPAND|wxALL, 1);
//wxButton* bu1 = new wxButton(this, wxID_OK, _("OK")); //wxButton* bu1 = new wxButton(this, wxID_OK, _("OK"));
//bu1->SetDefault(); //bu1->SetDefault();
@ -157,21 +161,30 @@ public:
htmlWindow->Bind(wxEVT_KEY_DOWN, [&](wxKeyEvent& event) { htmlWindow->Bind(wxEVT_KEY_DOWN, [&](wxKeyEvent& event) {
if (event.GetKeyCode() == WXK_ESCAPE) { if (event.GetKeyCode() == WXK_ESCAPE) {
Hide(); Hide();
event.Skip();
return; return;
} }
if (event.GetKeyCode() == WXK_NUMPAD_ADD) { if (event.GetKeyCode() == WXK_NUMPAD_ADD) {
wxSize sz=this->GetSize(); wxSize sz=this->GetSize();
wxSize szh=htmlWindow->GetSize(); wxSize szh=htmlWindow->GetSize();
szh.IncBy(50,50); int xx, yy;
htmlWindow->SetSize(szh); htmlWindow->GetVirtualSize(&xx, &yy);
std::cout << sz.GetWidth() << "," << sz.GetHeight() << std::endl; wxPoint p=GetScreenPosition();
sz.IncBy(50,50); wxSize sizeScreen=getScreenSizeForPoint(p);
this->SetSizePopup(sz); if (yy>szh.y) {
wxPoint p; if (p.y+sz.y +50 <sizeScreen.y)
p=this->GetScreenPosition(); sz.y+=50;
p.x=p.x-50; else
p.y=p.y-50; if (p.y>50) {p.y=p.y-50; sz.y+=50;}
//this->Move(p); }
if (p.x+sz.x +50 <sizeScreen.x)
sz.x+=50;
else
if (p.x>50) {p.x=p.x-50; sz.x+=50;}
SetSize(p.x,p.y,sz.x,sz.y,wxSIZE_USE_EXISTING);
Layout();
wxSize newsz=GetSize();
//std::cout << sz.GetWidth() << "," << sz.GetHeight() << " new: " << newsz.GetWidth() << "," << newsz.GetHeight() << std::endl;
} }
if (event.GetKeyCode() == WXK_PAGEDOWN) htmlWindow->ScrollPages(1); if (event.GetKeyCode() == WXK_PAGEDOWN) htmlWindow->ScrollPages(1);
if (event.GetKeyCode() == WXK_PAGEUP) htmlWindow->ScrollPages(-1); if (event.GetKeyCode() == WXK_PAGEUP) htmlWindow->ScrollPages(-1);
@ -179,6 +192,59 @@ public:
if (event.GetKeyCode() == WXK_UP) htmlWindow->ScrollLines(-1); if (event.GetKeyCode() == WXK_UP) htmlWindow->ScrollLines(-1);
if (event.GetKeyCode() == WXK_HOME) htmlWindow->ScrollPages(-1000); if (event.GetKeyCode() == WXK_HOME) htmlWindow->ScrollPages(-1000);
if (event.GetKeyCode() == WXK_END) htmlWindow->ScrollPages(1000); if (event.GetKeyCode() == WXK_END) htmlWindow->ScrollPages(1000);
//std::cout << "key code " << event.GetKeyCode() << " " << std::endl;
if (event.GetKeyCode() == 'C' && hist.size()>0) {
if (wxTheClipboard->Open())
{
wxString h=hist[hist.size()-1];
// Добавляем данные (можно добавить несколько форматов, если нужно)
wxDataObjectComposite* dataobj = new wxDataObjectComposite();
dataobj->Add(new wxHTMLDataObject(h));
wxTheClipboard->SetData(dataobj);
wxTheClipboard->Close();
}
else
{
wxLogError("No open clipboard.");
}
}
if (event.GetKeyCode() == 'S') {
wxSize clientSize = this->GetClientSize();
// Создаём битмап того же размера
wxBitmap bitmap(clientSize.x, clientSize.y, -1); // -1 — лучший формат для экрана
// Создаём DC для рисования в битмап
wxMemoryDC memDC;
memDC.SelectObject(bitmap);
// Очищаем фон (опционально, если окно не полностью перерисовано)
memDC.SetBackground(*wxWHITE_BRUSH);
memDC.Clear();
// Используем wxClientDC для чтения содержимого окна
wxClientDC clientDC(this);
// Переносим данные с clientDC в memDC (копируем прямоугольник)
// Важно: координаты — относительно окна!
memDC.Blit(0, 0, clientSize.x, clientSize.y, &clientDC, 0, 0);
// Освобождаем DC
memDC.SelectObject(wxNullBitmap);
// Открываем буфер обмена
if (wxTheClipboard->Open())
{
// Добавляем данные (можно добавить несколько форматов, если нужно)
wxDataObjectComposite* dataobj = new wxDataObjectComposite();
dataobj->Add(new wxBitmapDataObject(bitmap));
wxTheClipboard->SetData(dataobj);
wxTheClipboard->Close();
}
else
{
wxLogError("No open clipboard.");
}
}
}); });

View file

@ -429,7 +429,7 @@ bool pgAdmin3::OnInit()
dialogTestMode = true; dialogTestMode = true;
// Setup the image handlers and appearance factory before we do any GUI or config stuff // Setup the image handlers and appearance factory before we do any GUI or config stuff
::wxInitAllImageHandlers(); //::wxInitAllImageHandlers();
appearanceFactory = new pgAppearanceFactory(); appearanceFactory = new pgAppearanceFactory();

View file

@ -231,6 +231,10 @@ order by objname;
item = browser->GetNextChild(dbssId, cookie2); item = browser->GetNextChild(dbssId, cookie2);
} // next } // next
} else {
// brower->db close
//return wxEmptyString;
def=_("'The database is closed in the object browser.'");
} }
goto exitloop; goto exitloop;

View file

@ -117,7 +117,7 @@ wxString PreviewHtml::Preview(const wxString& txt, fmtpreview type) {
int flag = 0; int flag = 0;
tokens.clear(); tokens.clear();
bool quote = false; bool quote = false;
wxUniChar prevchar; wxUniChar prevchar,quotechar;
int startstr = -1; int startstr = -1;
while (pos < len) { while (pos < len) {
c = tmpstr[pos++]; c = tmpstr[pos++];
@ -130,18 +130,20 @@ wxString PreviewHtml::Preview(const wxString& txt, fmtpreview type) {
html+=c; html+=c;
continue; continue;
} }
bool isquote = c == '"'; if (!quote && (c=='"' || c=='\'')) quotechar = c;
bool isquote = c == quotechar;
if (quote) { if (quote) {
if (prevchar == c && isquote) { if (prevchar == c && isquote) {
// repeat quote // repeat quote
prevchar = '\0'; prevchar = '\0';
continue; continue;
} }
if (prevchar == '"' && !isquote) { if (prevchar == quotechar && !isquote) {
// end quote string // end quote string
wxString tmp = tmpstr.Mid(startstr, pos - startstr - 1); wxString tmp = tmpstr.Mid(startstr, pos - startstr - 1);
saveTokenIfNotEmpty(tmp, PREVIEW_QUOTE); saveTokenIfNotEmpty(tmp, PREVIEW_QUOTE);
quote = false; quote = false;
quotechar='\0';
} }
else { else {
prevchar = c; prevchar = c;
@ -214,7 +216,19 @@ wxString PreviewHtml::Preview(const wxString& txt, fmtpreview type) {
saveTokenIfNotEmpty(currWord, PREVIEW_WORD); saveTokenIfNotEmpty(currWord, PREVIEW_WORD);
saveTokenIfNotEmpty(currDigits, PREVIEW_DIGITS); saveTokenIfNotEmpty(currDigits, PREVIEW_DIGITS);
saveTokenIfNotEmpty(currSep, PREVIEW_SEP); saveTokenIfNotEmpty(currSep, PREVIEW_SEP);
if (fmt == fmtpreview::AUTO && txt.Len()<256) {
if (txt.IsNumber()) {
wxLongLong l = StrToLongLong(txt);
wxString newtxt;
if ((l>999 || l<-999)) {
newtxt="<hr>";
saveTokenIfNotEmpty(newtxt, PREVIEW_RAWHTML);
newtxt=NumToStrHuman(l);
saveTokenIfNotEmpty(newtxt, PREVIEW_WORD);
}
}
}
// Additonal styled // Additonal styled
wxString findstr = ""; wxString findstr = "";

View file

@ -1483,28 +1483,57 @@ bool make_identifier(const wxString &strname, wxString &s, wxString &n, bool isl
} else {if (islower) s=s.MakeLower();} } else {if (islower) s=s.MakeLower();}
return true; return true;
} }
/*
class DirCopyTraverser: public wxDirTraverser { // Get display for ScreenPoint
public: wxSize getScreenSizeForPoint(const wxPoint screenPos) {
DirCopyTraverser(const wxString &destBase): m_destBase(destBase) {} // screen size
virtual wxDirTraverseResult OnFile(const wxString &file) wxOVERRIDE { wxPoint posScreen;
wxFileName srcFile(file); wxSize sizeScreen;
//wxString relativePath=srcFile.GetPath(wxPATH_DOS,true); const int displayNum = wxDisplay::GetFromPoint(screenPos);
srcFile.MakeRelativeTo(m_destBase); if (displayNum != wxNOT_FOUND)
wxString destFile=m_destBase+wxFileName::GetPathSeparator()+srcFile.GetFullName(); {
wxFileName destDir(destFile); const wxRect rectScreen = wxDisplay(displayNum).GetGeometry();
destDir.RemoveLastDir(); posScreen = rectScreen.GetPosition();
if (!destDir.DirExists()) destDir.Mkdir(wxS_DIR_DEFAULT,wxPATH_MKDIR_FULL); sizeScreen = rectScreen.GetSize();
if (!wxCopyFile(file,destFile,true)) {
wxLogError("Error copy file %s",file);
return wxDIR_STOP;
} }
return wxDIR_CONTINUE; else // outside of any display?
} {
virtual wxDirTraverseResult OnDir(const wxString &file) wxOVERRIDE { // just use the primary one then
return 0; posScreen = wxPoint(0, 0);
} sizeScreen = wxGetDisplaySize();
private: }
wxString m_destBase; return sizeScreen;
} }
*/ //show help window
void showHelpHtml(wxWindow *parent, const wxString &htmlHelp,wxPoint screenPos, wxSize size) {
FunctionPGHelper fh(htmlHelp);
wxString key = "content";
wxSize sizeScreen=getScreenSizeForPoint(screenPos);
wxSize rr(350, 70);
if (size.x!=-1) rr=size;
popuphelp *m_Popup = new popuphelp(parent, key, &fh, screenPos, 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, screenPos, rr);
}
if (m_Popup && m_Popup->IsValid()) {
wxSize top_sz = m_Popup->GetSizePopup();
wxSize top_new(top_sz);
wxPoint p(screenPos);
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_Popup->Popup();
}
//m_Popup->SetFocus();
}

Binary file not shown.