mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 14:15:49 -06:00
Added the possibility of contextual help on user functions.
Добавлена возможность просмотра скриптов создания пользовательских объектов в контестной помощи. В скриптах имена других объектов заменяются на ссылки. Описание Readme.md
This commit is contained in:
parent
560bf4c080
commit
1f7decd73f
18 changed files with 1016 additions and 159 deletions
|
|
@ -53,7 +53,7 @@ public:
|
|||
void Create(wxWindow *parent, wxWindowID id = -1, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = 0);
|
||||
void HighlightBrace(int start, int len,int indicator);
|
||||
void SetDatabase(pgConn *db);
|
||||
wxString TextToHtml(int start, int end, bool isAddNewLine=false);
|
||||
wxString TextToHtml(int start, int end, bool isAddNewLine=false, const std::vector<FSQL::complite_element> &listobj = {});
|
||||
void Copy();
|
||||
void OnKeyDown(wxKeyEvent &event);
|
||||
void OnAutoComplete(wxCommandEvent &event);
|
||||
|
|
|
|||
|
|
@ -216,6 +216,7 @@
|
|||
#include "schema/gpExtTable.h"
|
||||
#include "schema/gpPartition.h"
|
||||
#include "schema/gpResQueue.h"
|
||||
#include "schema/pgPartition.h"
|
||||
|
||||
#include "slony/dlgRepCluster.h"
|
||||
#include "slony/dlgRepListen.h"
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ namespace FSQL {
|
|||
{ "left", 4, new_line_align_next },
|
||||
{ "full", 4, new_line_align_next },
|
||||
{ "then", 4, none},
|
||||
{ "loop", 4, none}, // for plpgsql
|
||||
{ "into", 4, none},
|
||||
{ "last", 4, none},
|
||||
{ "next", 4, none},
|
||||
|
|
@ -86,6 +87,9 @@ namespace FSQL {
|
|||
{ "sets", 4, none},
|
||||
{ "where", 5, new_line_align_no_pad | end_from},
|
||||
{ "outer", 5, none},
|
||||
{ "grant", 5, none},
|
||||
{ "begin", 5, none}, //plpgsql
|
||||
{ "while", 5, none}, //plpgsql
|
||||
{ "union", 5, new_line_align_no_pad | end_from},
|
||||
{ "order", 5, new_line_align_no_pad | end_from},
|
||||
{ "limit", 5, new_line_align_no_pad | end_from},
|
||||
|
|
@ -106,9 +110,11 @@ namespace FSQL {
|
|||
{ "except", 6, new_line_align_no_pad | end_from},
|
||||
{ "offset", 6, none | end_from},
|
||||
{ "cursor", 6, none},
|
||||
{ "create", 6, none},
|
||||
{ "nothing", 7, none},
|
||||
{ "lateral", 7, none},
|
||||
{ "between", 7, none},
|
||||
{ "comment", 7, none},
|
||||
|
||||
{ "nothing", 7, none},
|
||||
{ "default", 7, none},
|
||||
|
|
@ -149,11 +155,13 @@ namespace FSQL {
|
|||
FormatterSQL(const wxString& sqlsrc) {
|
||||
sql = sqlsrc;
|
||||
}
|
||||
std::vector<complite_element> ParsePLpgsql();
|
||||
void Formating(wxDC& d, wxRect re, bool isTest = false); // draw
|
||||
wxString Formating(wxRect re); //
|
||||
//
|
||||
wxString BuildAutoComplite(int startIndex, int level);
|
||||
wxString GetListTable(int cursorPos);
|
||||
wxString GetListTable(const std::vector<complite_element> &list);
|
||||
wxString GetColsList(wxString what, wxString& listfieldOut, wxString& nameTableOut);
|
||||
/// <summary>
|
||||
/// Возращает количество таблиц слева от курсора и заполняет их имена и псевдонимы.
|
||||
|
|
@ -166,11 +174,13 @@ namespace FSQL {
|
|||
void SetSql(const wxString& sqlsrc) { sql = sqlsrc; lastposition = 0; }
|
||||
int GetIndexItemNextSqlPosition(int sqlPosition);
|
||||
int GetNextPositionSqlParse();
|
||||
|
||||
bool GetItem(int index, FSQL::view_item& item);
|
||||
int next_item_no_space(int& index, int direction = 1);
|
||||
private:
|
||||
wxString get_list_columns(int startindex, union FSQL::Byte zone);
|
||||
|
||||
void _addfunc(const view_item *vi);
|
||||
void _addfunc_in_braket(int start,int end);
|
||||
wxPoint align_level(int start_i, int level, int Xpos, int Ypos, int flag);
|
||||
int check_bracket(int index);
|
||||
int get_prev_value(int indx, wxString keyword);
|
||||
|
|
@ -185,8 +195,10 @@ namespace FSQL {
|
|||
wxRect rect;
|
||||
wxString sql;
|
||||
int lastposition = 0;
|
||||
int errorposition=-1;
|
||||
std::vector<FSQL::view_item> items;
|
||||
std::vector<FSQL::complite_element> listTable; // перечень таблиц синонимов, подзапросов и функций с колонками
|
||||
std::vector<FSQL::complite_element> listFunction; // перечень функций используемых в запросе
|
||||
//int recurse(int level);
|
||||
};
|
||||
}
|
||||
|
|
@ -5,16 +5,11 @@
|
|||
#include <wx/regex.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/textfile.h>
|
||||
#include <wx/filename.h>
|
||||
|
||||
extern sysSettings* settings;
|
||||
|
||||
class FunctionPGHelper
|
||||
{
|
||||
public:
|
||||
FunctionPGHelper() {};
|
||||
FunctionPGHelper() {dblast=NULL;};
|
||||
/// <summary>
|
||||
/// Создать только переданный в конструкторе html текст с именем "content"
|
||||
/// </summary>
|
||||
|
|
@ -23,6 +18,7 @@ public:
|
|||
body.clear();
|
||||
Add("content", content);
|
||||
isload = true;
|
||||
dblast=NULL;
|
||||
};
|
||||
int Size() {
|
||||
return body.size();
|
||||
|
|
@ -30,126 +26,23 @@ public:
|
|||
void SetTimerClose(int ms) { m_interval = ms; }
|
||||
int GetTimerClose() { return m_interval; }
|
||||
void Add(const wxString& key, const wxString& v) { body.emplace(key, v); }
|
||||
wxString getHelpString(wxString fnd, bool isPart = true) {
|
||||
if (!isValid()) return wxEmptyString;
|
||||
auto search = body.find(fnd);
|
||||
wxString txt;
|
||||
|
||||
if (search != body.end())
|
||||
txt = search->second;
|
||||
else
|
||||
{
|
||||
std::vector<wxString> list;
|
||||
int l = fnd.Len();
|
||||
wxString b;
|
||||
for (const auto& e : body) {
|
||||
if (e.first.Len() > l && e.first.StartsWith(fnd)) {
|
||||
list.push_back(e.first);
|
||||
b = e.second;
|
||||
}
|
||||
}
|
||||
if (list.size() == 1) txt = b;
|
||||
else {
|
||||
for (const auto& s : list) {
|
||||
txt += wxString::Format("<a href=\"%s\">%s</a><br>", s, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
//if (i == wxNOT_FOUND) return wxEmptyString;
|
||||
return txt;
|
||||
}
|
||||
wxString getSqlCommandHelp(wxString fnd) {
|
||||
wxUniChar sep = wxFileName::GetPathSeparator();
|
||||
fnd.Replace(" ", "");
|
||||
wxString f = wxFindFirstFile(path + sep + "sql-" + fnd + "*.html");
|
||||
wxString last, txt;
|
||||
|
||||
int c = 0;
|
||||
while (!f.empty())
|
||||
{
|
||||
f = f.AfterLast(sep);
|
||||
last = f;
|
||||
txt += wxString::Format("<a href=\"%s\">%s</a><br>", f, f);
|
||||
f = wxFindNextFile();
|
||||
c++;
|
||||
}
|
||||
if (last.empty()) {
|
||||
return wxEmptyString;
|
||||
}
|
||||
else if (c == 1) {
|
||||
return getHelpFile(last);
|
||||
}
|
||||
else {
|
||||
return txt;
|
||||
}
|
||||
|
||||
}
|
||||
wxString getHelpFile(wxString filename) {
|
||||
wxString tempDir = path + wxFileName::GetPathSeparator() + filename;
|
||||
if (!wxFileExists(tempDir)) return wxEmptyString;
|
||||
wxTextFile tfile;
|
||||
tfile.Open(tempDir);
|
||||
// read the first line
|
||||
wxString str, sbody;
|
||||
sbody = tfile.GetFirstLine();
|
||||
bool flag = true;
|
||||
wxRegEx b("(<body .*?>)");
|
||||
while (!tfile.Eof())
|
||||
{
|
||||
str = tfile.GetNextLine();
|
||||
if (flag && b.Matches(str)) {
|
||||
size_t start, len;
|
||||
b.GetMatch(&start, &len, 0);
|
||||
str = str.Mid(start + len);
|
||||
sbody = "<body>";
|
||||
flag = false;
|
||||
}
|
||||
sbody += str;
|
||||
}
|
||||
return sbody;
|
||||
|
||||
}
|
||||
bool isValid() {
|
||||
if (!isload) loadfile();
|
||||
return isload;
|
||||
}
|
||||
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
|
||||
private:
|
||||
bool isload = false;
|
||||
int m_interval = -1;
|
||||
wxString path;
|
||||
std::map<wxString, wxString> body;
|
||||
void loadfile() {
|
||||
if (isload) return;
|
||||
body.clear();
|
||||
path = settings->GetPgHelpPath();
|
||||
wxString tempDir = path + "_func.txt";
|
||||
//tempDir="C:\\Users\\lsv\\Source\\Repos\\wxHtmlhint\\1";
|
||||
if (!wxFileExists(tempDir)) return;
|
||||
wxTextFile tfile;
|
||||
tfile.Open(tempDir);
|
||||
|
||||
// read the first line
|
||||
wxString str, sbody;
|
||||
wxString name = tfile.GetFirstLine();
|
||||
|
||||
//wxSortedArrayString names;
|
||||
name = name.AfterFirst('#');
|
||||
// read all lines one by one
|
||||
// until the end of the file
|
||||
while (!tfile.Eof())
|
||||
{
|
||||
str = tfile.GetNextLine();
|
||||
if (str.Left(1) == '#') {
|
||||
body.emplace(name, sbody);
|
||||
sbody = "";
|
||||
name = str.AfterFirst('#');
|
||||
}
|
||||
else sbody += str;
|
||||
}
|
||||
body.emplace(name, sbody);
|
||||
isload = true;
|
||||
};
|
||||
// db connect
|
||||
pgConn *dblast;
|
||||
|
||||
void loadfile();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -279,5 +279,7 @@ wxString commandLineCleanOption(const wxString &option, bool schemaObject = fals
|
|||
wxString qtIdent(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);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -60,13 +60,17 @@ public:
|
|||
|
||||
htmlWindow->SetRelatedStatusBar(0);
|
||||
//htmlWindow->SetPage("<html><body><h1>TEST</h1><span fgcolor=\"#332233\">Set Page Works</span></body></hmtl>");
|
||||
wxString txt = hhelper->getHelpString(keyword);
|
||||
|
||||
wxString txt;
|
||||
txt=hhelper->getDBinfoKeyword(keyword,true);
|
||||
if (txt.IsEmpty()) {
|
||||
|
||||
txt = hhelper->getSqlCommandHelp(keyword);
|
||||
txt = hhelper->getHelpString(keyword.Lower());
|
||||
if (txt.empty()) {
|
||||
isvalid = false;
|
||||
return;
|
||||
txt = hhelper->getSqlCommandHelp(keyword.Lower());
|
||||
if (txt.empty()) {
|
||||
isvalid = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
SetPage(txt);
|
||||
|
|
@ -131,9 +135,13 @@ public:
|
|||
this->Bind(wxEVT_HTML_LINK_CLICKED, [&](wxHtmlLinkEvent& event) {
|
||||
wxHtmlLinkInfo i = event.GetLinkInfo();
|
||||
wxString name = i.GetHref();
|
||||
wxString body=this->hhelper->getHelpString(name);
|
||||
wxString body;
|
||||
body=this->hhelper->getDBinfoKeyword(name,false);
|
||||
if (body.IsEmpty()) {
|
||||
body = this->hhelper->getHelpFile(name);
|
||||
body=this->hhelper->getHelpString(name);
|
||||
if (body.IsEmpty()) {
|
||||
body = this->hhelper->getHelpFile(name);
|
||||
}
|
||||
}
|
||||
SetPage(body);
|
||||
//ctext=htmlWindow->SelectionToText();
|
||||
|
|
@ -153,12 +161,15 @@ public:
|
|||
//wxString body = this->hhelper->getHelpString(name);
|
||||
wxString ctext = htmlWindow->SelectionToText();
|
||||
if (!ctext.IsEmpty()) {
|
||||
wxClipboardLocker clip;
|
||||
if (!clip ||
|
||||
!wxTheClipboard->AddData(new wxTextDataObject(ctext)))
|
||||
if (wxTheClipboard->Open())
|
||||
{
|
||||
|
||||
wxDataObjectComposite* dataobj = new wxDataObjectComposite();
|
||||
dataobj->Add(new wxTextDataObject(ctext));
|
||||
//dataobj->Add(new wxHTMLDataObject(str));
|
||||
wxTheClipboard->SetData(dataobj);
|
||||
wxTheClipboard->Close();
|
||||
}
|
||||
|
||||
wxString wname = GetParent()->GetName();
|
||||
if (wname == "frmStatus") {
|
||||
//CMD_EVENT_FIND_STR
|
||||
|
|
@ -203,6 +214,7 @@ private:
|
|||
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>");
|
||||
|
|
@ -224,9 +236,22 @@ private:
|
|||
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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue