mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 06:05:58 -06:00
186 lines
4.6 KiB
C++
186 lines
4.6 KiB
C++
#include "ide.h"
|
|
|
|
bool IsCb(String t) {
|
|
int q = t.Find('<');
|
|
if(q >= 0)
|
|
t.Trim(q);
|
|
if(t.StartsWith("Upp::"))
|
|
t = t.Mid(5);
|
|
return t == "Event<> " || t == "Event<" || t == "Event<> 2" || t == "Event<> 3" ||
|
|
t == "Gate" || t == "Gate1" || t == "Gate";
|
|
}
|
|
|
|
struct ThisbacksDlg : WithThisbacksLayout<TopWindow> {
|
|
struct CbInfo {
|
|
String scope;
|
|
String type;
|
|
String name;
|
|
};
|
|
|
|
Index<String> nname;
|
|
Array<CbInfo> cb;
|
|
|
|
void GatherCallbacks(const String& pfx, Index<String>& done, const String& scope, int access);
|
|
void CbEdit(One<Ctrl>& ctrl);
|
|
void Generate(String& ins, String& clip, const String& scope);
|
|
|
|
typedef ThisbacksDlg CLASSNAME;
|
|
|
|
ThisbacksDlg(const String& scope);
|
|
};
|
|
|
|
int FilterId(int c)
|
|
{
|
|
return iscid(c) ? c : 0;
|
|
}
|
|
|
|
void ThisbacksDlg::CbEdit(One<Ctrl>& ctrl)
|
|
{
|
|
ctrl.Create<EditString>().SetFilter(FilterId);
|
|
}
|
|
|
|
ThisbacksDlg::ThisbacksDlg(const String& scope)
|
|
{
|
|
CppBaseLock __;
|
|
CtrlLayoutOKCancel(*this, "THISBACKs");
|
|
list.AddColumn("Defined in");
|
|
list.AddColumn("Type");
|
|
list.AddColumn("Event<> ");
|
|
list.AddColumn("Insert").Ctrls<Option>();
|
|
list.AddColumn("Method name").Ctrls(THISBACK(CbEdit));
|
|
list.SetLineCy(EditField::GetStdHeight());
|
|
list.ColumnWidths("110 245 157 41 129");
|
|
list.EvenRowColor();
|
|
list.NoCursor();
|
|
Sizeable().Zoomable();
|
|
int q = CodeBase().Find(scope);
|
|
if(q < 0)
|
|
return;
|
|
const Array<CppItem>& n = CodeBase()[q];
|
|
for(int i = 0; i < n.GetCount(); i++)
|
|
nname.FindAdd(n[i].name);
|
|
Index<String> done;
|
|
GatherCallbacks("", done, scope, PRIVATE);
|
|
}
|
|
|
|
void ThisbacksDlg::GatherCallbacks(const String& pfx, Index<String>& done,
|
|
const String& scope, int access)
|
|
{
|
|
CppBaseLock __;
|
|
if(IsNull(scope))
|
|
return;
|
|
String h = pfx + scope;
|
|
if(done.Find(h) >= 0 || list.GetCount() > 300)
|
|
return;
|
|
done.Add(h);
|
|
Vector<String> tparam;
|
|
int q = CodeBase().Find(ParseTemplatedType(scope, tparam));
|
|
if(q < 0)
|
|
return;
|
|
const Array<CppItem>& n = CodeBase()[q];
|
|
for(int i = 0; i < n.GetCount(); i++) {
|
|
const CppItem& m = n[i];
|
|
if(m.IsData() && IsCb(m.qtype) && m.access <= access) {
|
|
String n = m.name;
|
|
String name = pfx + '.' + n;
|
|
if(*name == '.')
|
|
name = name.Mid(1);
|
|
if(name == "WhenAction")
|
|
n = "Action";
|
|
else {
|
|
Vector<String> ss = Split(name, '.');
|
|
for(int i = 0; i < ss.GetCount(); i++) {
|
|
String& s = ss[i];
|
|
if(s == "WhenAction")
|
|
s.Clear();
|
|
else {
|
|
if(memcmp(s, "When", 4) == 0)
|
|
s = s.Mid(4);
|
|
if(s.GetCount())
|
|
s.Set(0, ToUpper(s[0]));
|
|
}
|
|
}
|
|
n = Join(ss, "");
|
|
while(nname.Find(n) >= 0)
|
|
n = "On" + n;
|
|
}
|
|
list.Add(scope, m.type, name, 0, n, m.name);
|
|
}
|
|
}
|
|
for(int i = 0; i < n.GetCount(); i++) {
|
|
const CppItem& m = n[i];
|
|
if(m.IsType() && m.access <= access) {
|
|
Vector<String> b = Split(m.qptype, ';');
|
|
ResolveTParam(b, tparam);
|
|
for(int i = 0; i < b.GetCount(); i++)
|
|
GatherCallbacks(pfx, done, b[i], min(access, (int)PROTECTED));
|
|
}
|
|
}
|
|
for(int i = 0; i < n.GetCount(); i++) {
|
|
const CppItem& m = n[i];
|
|
if(m.kind == INSTANCEVARIABLE && !IsCb(m.qtype)
|
|
&& m.natural.Find('&') < 0 && m.natural.Find('*') < 0
|
|
&& m.access <= access
|
|
&& !m.name.StartsWith("dv___"))
|
|
GatherCallbacks(pfx + "." + m.name, done, m.qtype, min(access, (int)PUBLIC));
|
|
}
|
|
}
|
|
|
|
void ThisbacksDlg::Generate(String& ins, String& clip, const String& scope)
|
|
{
|
|
String ac;
|
|
for(int i = 0; i < list.GetCount(); i++) {
|
|
if((bool)list.Get(i, 3)) {
|
|
String type = list.Get(i, 1);
|
|
String name = list.Get(i, 2);
|
|
String method = list.Get(i, 4);
|
|
int q = name.Find('.');
|
|
if((String)list.Get(i, 5) == "WhenAction" && q >= 0)
|
|
ins << name.Mid(0, q) << " <<= THISFN(" << method;
|
|
else
|
|
ins << name << " = THISFN(" << method;
|
|
ins << ");\n";
|
|
if(nname.Find(method) < 0) {
|
|
String param;
|
|
q = type.Find('<');
|
|
if(q >= 0) {
|
|
int qq = type.ReverseFind('>');
|
|
if(q < qq) {
|
|
param = String(~type + q + 1, ~type + qq);
|
|
type.Trim(q);
|
|
}
|
|
}
|
|
String n = scope;
|
|
if(n[0] == ':' && n[1] == ':')
|
|
n = n.Mid(2);
|
|
String t = (memcmp(type, "Gate", 4) == 0 ? "bool " : "void ");
|
|
clip << t << n << "::" << method << "(" << param << ")\n{\n}\n\n";
|
|
ac << '\t' << t << method << "(" << param << ");\n";
|
|
}
|
|
}
|
|
}
|
|
clip << ac;
|
|
}
|
|
|
|
INITBLOCK
|
|
{
|
|
RegisterGlobalConfig("ThisbacksDlg");
|
|
}
|
|
|
|
void AssistEditor::Thisbacks()
|
|
{
|
|
ParserContext ctx;
|
|
Context(ctx, GetCursor32());
|
|
if(IsNull(ctx.current_scope) || !ctx.IsInBody())
|
|
return;
|
|
ThisbacksDlg dlg(ctx.current_scope);
|
|
LoadFromGlobal(dlg, "ThisbacksDlg");
|
|
int c = dlg.Run();
|
|
StoreToGlobal(dlg, "ThisbacksDlg");
|
|
if(c != IDOK)
|
|
return;
|
|
String a, b;
|
|
dlg.Generate(a, b, ctx.current_scope);
|
|
Paste(a.ToWString());
|
|
WriteClipboardText(b);
|
|
}
|