Using anchors in the function help.

Добавлена возможность использовать файлы справки на прямую, но с учётом структуры справки Postgresql.
This commit is contained in:
lsv 2025-11-28 14:27:46 +05:00
parent 47fda8071f
commit 20e91cda3c
4 changed files with 135 additions and 3 deletions

View file

@ -5,7 +5,7 @@
#include <wx/regex.h>
#include <map>
#include <vector>
struct anchor_src { int start ;int end; wxString id;};
class FunctionPGHelper
{
public:
@ -27,13 +27,17 @@ public:
int GetTimerClose() { return m_interval; }
void Add(const wxString& key, const wxString& v) { body.emplace(key, v); }
wxString getHelpString(wxString fnd, bool isPart = true) ;
// Загружаем файл и формируем якоря
wxString getHelpFile(wxString filename);
wxString getSqlCommandHelp(wxString fnd);
bool isValid();
void setDbConn(pgConn *db);
// Ищем ключевое слово в объектах БД
wxString getDBinfoKeyword(wxString objname,bool islower);
// Ищем файлы справки для команд sql
wxString getSqlCommandHelp(wxString fnd);
// получим текст по якорю
wxString getTextForAnchor(wxString filename);
private:
bool isload = false;
int m_interval = -1;
@ -41,6 +45,9 @@ private:
std::map<wxString, wxString> body;
// db connect
pgConn *dblast;
//
std::vector<anchor_src> an;
wxString filecontext;
void loadfile();
};

View file

@ -136,6 +136,13 @@ public:
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);
@ -152,6 +159,20 @@ public:
Hide();
return;
}
if (event.GetKeyCode() == WXK_NUMPAD_ADD) {
wxSize sz=this->GetSize();
wxSize szh=htmlWindow->GetSize();
szh.IncBy(50,50);
htmlWindow->SetSize(szh);
std::cout << sz.GetWidth() << "," << sz.GetHeight() << std::endl;
sz.IncBy(50,50);
this->SetSizePopup(sz);
wxPoint p;
p=this->GetScreenPosition();
p.x=p.x-50;
p.y=p.y-50;
//this->Move(p);
}
});
htmlWindow->Bind(wxEVT_RIGHT_UP, [&](wxMouseEvent& event) {
wxString name;

View file

@ -6,6 +6,7 @@
#include "db/pgSet.h"
#include "frm/frmMain.h"
#include "ctl/ctlSQLBox.h"
#include <stack>
extern sysSettings* settings;
extern frmMain *winMain;
@ -38,6 +39,10 @@ wxString FunctionPGHelper::getHelpString(wxString fnd, bool isPart)
}
}
//if (i == wxNOT_FOUND) return wxEmptyString;
if (txt.Len()>1 && txt[0]=='@') {
txt=txt.substr(1);
txt=getHelpFile(txt);
}
return txt;
}
void FunctionPGHelper::setDbConn(pgConn *db) {
@ -279,8 +284,25 @@ wxString FunctionPGHelper::getSqlCommandHelp(wxString fnd) {
}
}
wxString FunctionPGHelper::getTextForAnchor(wxString name) {
wxString n;
if (name.Len()>0 && name[0]=='#') n = name.substr(1); else n=name;
for (auto s:an) {
if (s.id==n) {
n=filecontext.substr(s.start,s.end-s.start+1);
return n;
}
}
return wxEmptyString;
}
wxString FunctionPGHelper::getHelpFile(wxString filename) {
wxString a;
int p=filename.Find('#');
if (p>0) {a=filename.substr(p+1); filename=filename.BeforeFirst('#');}
wxString tempDir = path + wxFileName::GetPathSeparator() + filename;
an.clear();
filecontext=wxEmptyString;
if (!wxFileExists(tempDir)) return wxEmptyString;
wxTextFile tfile;
tfile.Open(tempDir);
@ -289,6 +311,8 @@ wxString FunctionPGHelper::getHelpFile(wxString filename) {
sbody = tfile.GetFirstLine();
bool flag = true;
wxRegEx b("(<body .*?>)");
wxString ss;
std::stack<anchor_src> bg;
while (!tfile.Eof())
{
str = tfile.GetNextLine();
@ -299,8 +323,60 @@ wxString FunctionPGHelper::getHelpFile(wxString filename) {
sbody = "<body>";
flag = false;
}
str.Replace(filename,"");
sbody += str;
}
// find ancor
str=sbody;
filecontext=sbody;
int l=str.Len();
int i=0;
while (i<l) {
wxChar c=str[i++];
if (c=='<' && (i+3)<l
&& str[i+0]=='d'
&& str[i+1]=='i'
&& str[i+2]=='v'
) {
anchor_src s {i-1,-1,wxEmptyString};
i=i+3;
// find id="anchor name"
while (i<l && str[i]!='>') {
if (i>3 && str[i]=='"') {
if (str[i-1]=='='
&& str[i-2]=='d'
&& str[i-3]=='i'
) {
wxString n;
i++;
while (i<l && str[i]!='"') n=n+str[i++];
s.id=n;
}
}
i++;
}
i++;
bg.push(s); // end =-1
} else if (c=='<' && (i+6)<l
&& str[i+0]=='/'
&& str[i+1]=='d'
&& str[i+2]=='i'
&& str[i+3]=='v'
&& str[i+4]=='>'
) {
// close
i=i+4;
anchor_src s1=bg.top();
s1.end=i;
if (s1.id.Len()>0) an.push_back(s1);
bg.pop();
if (a.Len()>0 && s1.id==a) sbody=getTextForAnchor(a);
i++;
}
}
return sbody;
}

View file

@ -43,8 +43,29 @@ my %others_func=(
,'FUNCTIONS-SUBQUERY-ANY-SOME'=>'some'
,'some'=>'any'
,'ROW-WISE-COMPARISON' => 'is distinct from'
,'SQL-SYNTAX-TYPE-CASTS' => 'cast'
,'SQL-SYNTAX-COLLATE-EXPRS' => 'collate'
,'SQL-SYNTAX-ARRAY-CONSTRUCTORS' => 'array'
,'SQL-SYNTAX-ROW-CONSTRUCTORS' => 'row'
,'SYNTAX-WINDOW-FUNCTIONS' => 'filter'
,'filter' => 'over'
);
my %keys_to_file=(
'order' => '@queries-order.html'
,'limit' => '@queries-limit.html'
,'offset' => '@queries-limit.html'
,'values' => '@queries-values.html'
,'with' => '@queries-with.html'
,'union' => '@queries-union.html'
,'from' => '@queries-table-expressions.html#QUERIES-FROM'
,'where' => '@queries-table-expressions.html#QUERIES-WHERE'
,'group' => '@queries-table-expressions.html#QUERIES-GROUP'
,'having' => '@queries-table-expressions.html#QUERIES-GROUP'
,'cube' => '@queries-table-expressions.html#QUERIES-GROUPING-SETS'
,'rollup' => '@queries-table-expressions.html#QUERIES-GROUPING-SETS'
);
my %tags=(
'pclass="func_signature"' => '<span style="font-size: 11pt;">',
'pclass="func_signature"/p' => '</span>',
@ -292,7 +313,14 @@ foreach my $key (sort keys %useref) {
#print "section $key\n";
$c0++;
}
print "Add section $c0\n";
my $c1=0;
foreach my $key (sort keys %keys_to_file) {
$function_help{$key}=$keys_to_file{$key};
#print "section $key\n";
$c1++;
}
print "Add section $c0 add file link $c1\n";
foreach my $key (sort keys %function_help) {
#print "$key: $function_help{$key}\n";
print F "#".$key."\n".$function_help{$key}."\n";