ultimatepp/uppsrc/ide/Goto.cpp
cxl 2ce7d8b106 Removed forgotten DDUMPs
git-svn-id: svn://ultimatepp.org/upp/trunk@671 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2008-11-24 09:41:56 +00:00

267 lines
5.8 KiB
C++

#include "ide.h"
#define LLOG(x) // DLOG(x)
struct GotoDlg : public WithGotoLayout<TopWindow> {
bool global;
Array<CppItemInfo> item;
Index<String> type;
CppBase lbase;
CppBase *gbase;
void SyncList();
int GetLine();
void SyncOk();
void Serialize(Stream& s);
typedef GotoDlg CLASSNAME;
GotoDlg(const String& s);
};
void GotoDlg::SyncList()
{
list.Clear();
String n = ~target;
int typei = Null;
String scope = Null;
Vector<String> h = Split(n, ':');
if(n[0] == ':') {
if(h.GetCount() > 1 && *n.Last() != ':') {
n = h.Top();
h.Drop();
}
else
n.Clear();
scope = Join(h, "::");
}
else
if(h.GetCount() > 1 || h.GetCount() == 1 && *n.Last() == ':') {
if(h.GetCount() > 1 && *n.Last() != ':') {
n = h.Top();
h.Drop();
}
else
n.Clear();
typei = type.Find(Join(h, "::"));
if(typei < 0)
typei = -1;
}
if(IsDigit(*n))
n.Clear();
Index<String> nc;
for(int ci = 0; ci < (n.GetCount() ? 2 : 1); ci++)
for(int i = 0; i < item.GetCount(); i++) {
const CppItemInfo& f = item[i];
int q = memcmp(n, f.name, n.GetLength());
if((n.GetLength() == 0 ||
(ci ? q && memcmp_i(n, f.name, n.GetLength()) == 0 : q == 0)) &&
(IsNull(typei) || typei == f.typei) &&
(IsNull(scope) || scope == f.scope)) {
list.Add(f.scope, RawToValue(f), f.item, f.line, GetCppFile(f.file), f.scope);
nc.FindAdd(f.scope);
}
}
list.HeaderTab(0).SetText(Format("Scope (%d)", nc.GetCount()));
list.HeaderTab(1).SetText(Format("Symbol (%d)", list.GetCount()));
SyncOk();
}
int GotoDlg::GetLine()
{
if(list.IsCursor() && list.HasFocus())
return list.Get(3);
String s = ~target;
if(IsDigit(s[0]))
return atoi(s);
if(list.IsCursor())
return list.Get(3);
if(list.GetCount())
return list.Get(0, 3);
return -1;
}
void GotoDlg::SyncOk()
{
ok.Enable(GetLine() >= 0);
}
int GotoFilter(int c)
{
return IsDigit(c) || IsAlpha(c) || c == '_' || c == ':' ? c : c == '.' ? ':' : 0;
}
void GotoDlg::Serialize(Stream& s)
{
SerializePlacement(s);
list.SerializeHeader(s);
}
struct CppItemInfoSortLine {
bool operator()(const CppItemInfo& a, const CppItemInfo& b) const {
return a.line < b.line;
}
};
struct CppItemInfoSortGlobal {
bool operator()(const CppItemInfo& a, const CppItemInfo& b) const {
return CombineCompare(a.scope, b.scope)
(GetCppFile(a.file), GetCppFile(b.file))
(a.line, b.line) < 0;
}
};
GotoDlg::GotoDlg(const String& s)
{
global = IsNull(s);
if(!global) {
StringStream ss(s);
Parser parser;
parser.Do(ss, IgnoreList(), lbase, Null, CNULL);
}
CtrlLayoutOKCancel(*this, IsNull(s) ? "Go to global" : "Go to line or symbol");
CppBase& base = IsNull(s) ? CodeBase() : lbase;
gbase = &base;
for(int i = 0; i < base.GetCount(); i++) {
Array<CppItem>& n = base[i];
for(int j = 0; j < n.GetCount(); j++) {
const CppItem& m = n[j];
CppItemInfo mf;
(CppItem&)mf = n[j];
mf.scope = base.GetKey(i);
mf.virt = false;
mf.access = m.impl ? (int)WITHBODY : (int)PUBLIC;
mf.item = global ? String().Cat() << GetFileName(GetCppFile(m.file)) << " (" << m.line << ')'
: AsString(m.line);
mf.typei = 0;
item.Add(mf);
}
}
if(global)
Sort(item, CppItemInfoSortGlobal());
else
Sort(item, CppItemInfoSortLine());
target.SetFilter(GotoFilter);
target <<= THISBACK(SyncList);
list.AddColumn("Nesting");
list.AddColumn().SetDisplay(Single<CppItemInfoDisplay>());
list.AddColumn(global ? "Position" : "Line");
list.SetLineCy(BrowserFont().Info().GetHeight() + 3);
if(global)
list.ColumnWidths("181 466 112");
else
list.ColumnWidths("174 516 37");
list.WhenCursor = THISBACK(SyncOk);
list.WhenLeftDouble = Breaker(IDOK);
list.EvenRowColor();
SyncList();
ActiveFocus(target);
Sizeable().Zoomable();
Icon(IdeImg::Navigator());
}
INITBLOCK
{
RegisterGlobalConfig("IdeGoto");
RegisterGlobalConfig("IdeGotoGlobal");
}
void Ide::Goto()
{
if(designer || editor.GetLength() == 0)
return;
GotoDlg dlg(~editor);
LoadFromGlobal(dlg, "IdeGoto");
int c = dlg.Run();
StoreToGlobal(dlg, "IdeGoto");
if(c != IDOK)
return;
int l = dlg.GetLine();
if(l > 0) {
editor.SetCursor(editor.GetPos(l - 1));
editor.TopCursor();
}
}
void Ide::GotoGlobal()
{
SaveFile();
GotoDlg dlg(Null);
LoadFromGlobal(dlg, "IdeGotoGlobal");
int c = dlg.Run();
StoreToGlobal(dlg, "IdeGotoGlobal");
if(c != IDOK)
return;
int l = dlg.GetLine();
if(l > 0 && dlg.list.GetCount()) {
String file = dlg.list.IsCursor() ? dlg.list.Get(4) : dlg.list.Get(0, 4);
GotoPos(file, l);
}
}
void AssistEditor::SwapSContext(Parser& p)
{
int i = GetCursor();
if(Ch(i - 1) == ';')
i--;
else
for(;;) {
int c = Ch(i);
if(c == '{') {
i++;
break;
}
if(c == 0 || c == ';' || c == '}')
break;
i++;
}
Context(p, i);
}
bool Ide::SwapSIf(const char *cref)
{
if(designer || !editor.assist_active)
return false;
Parser p;
editor.SwapSContext(p);
int q = CodeBase().Find(p.current_scope);
LLOG("SwapS scope: " << p.current_scope);
if(q < 0)
return false;
const Array<CppItem>& n = CodeBase()[q];
String qitem = QualifyKey(CodeBase(), p.current_scope, p.current_key);
if(cref && MakeCodeRef(p.current_scope, p.current_key) != cref)
return false;
q = FindItem(n, qitem);
int count = q >= 0 ? GetCount(n, q) : 0;
if(!cref && count < 2) {
for(int i = 0; i < n.GetCount(); i++) {
if(i >= n.GetCount())
return false;
if(i != q && n[i].name == p.current_name) {
GotoCpp(n[i]);
return true;
}
}
return false;
}
int file = GetCppFileIndex(editfile);
int line = p.current.line;
LLOG("SwapS line: " << line);
int i;
for(i = 0; i < count; i++) {
LLOG("file: " << GetCppFile(n[q + i].file) << ", line: " << n[q + i].line);
if(n[q + i].file == file && n[q + i].line == line) {
i++;
break;
}
}
GotoCpp(n[q + i % count]);
return true;
}
void Ide::SwapS()
{
SwapSIf(NULL);
}