mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 14:15:49 -06:00
358 lines
13 KiB
C++
358 lines
13 KiB
C++
#ifndef POPUPHELP_H
|
||
#define POPUPHELP_H
|
||
|
||
#include "wx/popupwin.h"
|
||
#include <wx/html/htmlwin.h>
|
||
#include <wx/clipbrd.h>
|
||
#include "utils/FunctionPGHelper.h"
|
||
#include <wx/regex.h>
|
||
#include <map>
|
||
#include <vector>
|
||
#include "wx/display.h"
|
||
#include "frm/menuServerStatus.h"
|
||
|
||
class popuphelp :
|
||
public wxPopupTransientWindow
|
||
{
|
||
public:
|
||
~popuphelp() {
|
||
delete closeTimer;
|
||
}
|
||
//popuphelp(wxWindow* parent);
|
||
bool ProcessLeftDown(wxMouseEvent& event)
|
||
{
|
||
return false;
|
||
}
|
||
bool IsValid() {
|
||
return isvalid;
|
||
}
|
||
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);
|
||
Layout();
|
||
Fit();
|
||
sizew = sz;
|
||
}
|
||
wxSize GetSizePopup() { return sizew; }
|
||
void keyProcessing(wxKeyEvent& event) {
|
||
if (event.GetKeyCode() == WXK_ESCAPE) {
|
||
Hide();
|
||
event.Skip();
|
||
return;
|
||
}
|
||
if (event.GetKeyCode() == WXK_NUMPAD_ADD) {
|
||
wxSize sz = this->GetSize();
|
||
wxSize szh = htmlWindow->GetSize();
|
||
int xx, yy;
|
||
htmlWindow->GetVirtualSize(&xx, &yy);
|
||
wxPoint p = GetScreenPosition();
|
||
wxSize sizeScreen = getScreenSizeForPoint(p);
|
||
if (yy > szh.y) {
|
||
if (p.y + sz.y + 50 < sizeScreen.y)
|
||
sz.y += 50;
|
||
else
|
||
if (p.y > 50) { p.y = p.y - 50; sz.y += 50; }
|
||
}
|
||
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_PAGEUP) htmlWindow->ScrollPages(-1);
|
||
if (event.GetKeyCode() == WXK_DOWN) htmlWindow->ScrollLines(1);
|
||
if (event.GetKeyCode() == WXK_UP) htmlWindow->ScrollLines(-1);
|
||
if (event.GetKeyCode() == WXK_HOME) 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);
|
||
// fix for linux app crush
|
||
wxSafeYield();
|
||
wxTheClipboard->Close(); // crush app without wxSafeYield();
|
||
|
||
}
|
||
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())
|
||
{
|
||
// Добавляем данные (можно добавить несколько форматов, если нужно)
|
||
wxTheClipboard->SetData(new wxBitmapDataObject(bitmap));
|
||
wxTheClipboard->Close();
|
||
}
|
||
else
|
||
{
|
||
wxLogError("No open clipboard.");
|
||
}
|
||
}
|
||
|
||
|
||
};
|
||
|
||
popuphelp(wxWindow* parent,wxString keyword, FunctionPGHelper *hhelper,wxPoint &posit,wxSize &newSz) : wxPopupTransientWindow(parent, wxPU_CONTAINS_CONTROLS| wxBORDER_NONE) {
|
||
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("<html><body><h1>TEST</h1><span fgcolor=\"#332233\">Set Page Works</span></body></hmtl>");
|
||
|
||
wxString txt;
|
||
txt=hhelper->getDBinfoKeyword(keyword,true);
|
||
if (txt.IsEmpty()) {
|
||
txt = hhelper->getHelpString(keyword.Lower());
|
||
if (txt.empty()) {
|
||
txt = hhelper->getSqlCommandHelp(keyword.Lower());
|
||
if (txt.empty()) {
|
||
isvalid = false;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
SetPage(txt);
|
||
//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()));
|
||
|
||
//SetSize(wxSize(300,150));
|
||
topsizer->Add(htmlWindow, 1, wxEXPAND|wxALL, 1);
|
||
|
||
//wxButton* bu1 = new wxButton(this, wxID_OK, _("OK"));
|
||
//bu1->SetDefault();
|
||
|
||
//topsizer->Add(bu1, 0, wxALL | wxALIGN_RIGHT, 15);
|
||
|
||
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);
|
||
|
||
if (xx > sizeScreen.x) xx = sizeScreen.x - 120;
|
||
if (yy > sizeScreen.y) yy = sizeScreen.y - 120;
|
||
|
||
|
||
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;
|
||
if (name.Len()>1 && name[0]=='#') {
|
||
body=this->hhelper->getTextForAnchor(name);
|
||
if (body.Len()>0) {
|
||
SetPage(body);
|
||
}
|
||
return;
|
||
}
|
||
body=this->hhelper->getDBinfoKeyword(name,false);
|
||
if (body.IsEmpty()) {
|
||
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());
|
||
});
|
||
Bind(wxEVT_CHAR_HOOK, &popuphelp::keyProcessing,this);
|
||
htmlWindow->Bind(wxEVT_RIGHT_DOWN, [&](wxMouseEvent& event) {});
|
||
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()) {
|
||
#ifdef __WXMSW__
|
||
if (wxTheClipboard->Open())
|
||
{
|
||
wxDataObjectComposite* dataobj = new wxDataObjectComposite();
|
||
dataobj->Add(new wxTextDataObject(ctext));
|
||
wxTheClipboard->SetData(dataobj);
|
||
wxTheClipboard->Close();
|
||
}
|
||
#endif
|
||
wxString wname = GetParent()->GetName();
|
||
if (wname == "frmStatus") {
|
||
//CMD_EVENT_FIND_STR
|
||
wxCommandEvent event(wxEVT_MENU, CMD_EVENT_FIND_STR);
|
||
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;
|
||
}
|
||
this->SetPage("", true);
|
||
//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;
|
||
wxLongLong startTimeWin;
|
||
wxSize sizew;
|
||
FunctionPGHelper* hhelper;
|
||
std::vector<wxString> hist;
|
||
std::vector<wxPoint> hist_viewp;
|
||
void SetPage(wxString innerbody,bool gethistory=false) {
|
||
wxString h;
|
||
int p = innerbody.Find("<body>");
|
||
if (innerbody.Find("<html>")>=0) h = innerbody;
|
||
else
|
||
if (p > -1) {
|
||
innerbody.Replace("<body>", "<html><body TEXT=\"#000000\" BGCOLOR=\"#FFFFE0\" LINK=\"#0000FF\" VLINK=\"#FF0000\" ALINK=\"#000088\">", false);
|
||
h = "" + innerbody + "";
|
||
}
|
||
else
|
||
h = "<html><body TEXT=\"#000000\" BGCOLOR=\"#FFFFE0\" LINK=\"#0000FF\" VLINK=\"#FF0000\" ALINK=\"#000088\">" + innerbody + "</body></hmtl>";
|
||
|
||
if (gethistory) {
|
||
if (hist.size() < 2) {
|
||
Hide();
|
||
return;
|
||
}
|
||
hist.pop_back();
|
||
h = hist[hist.size()-1];
|
||
}
|
||
else {
|
||
if (hist.size()>0) {
|
||
wxPoint ps=htmlWindow->GetViewStart();
|
||
hist_viewp.push_back(ps);
|
||
}
|
||
hist.push_back(h);
|
||
}
|
||
htmlWindow->SetPage(h);
|
||
if (gethistory && hist_viewp.size()>0) {
|
||
wxPoint ps=hist_viewp[hist_viewp.size()-1];
|
||
hist_viewp.pop_back();
|
||
htmlWindow->Scroll(ps);
|
||
} else {
|
||
//
|
||
wxPoint ps(0,0);
|
||
htmlWindow->Scroll(ps);
|
||
}
|
||
}
|
||
private:
|
||
wxTimer *closeTimer=NULL;
|
||
};
|
||
#endif
|